@@ -13,6 +13,61 @@ function createSseResponse(events: Array<{ event: string; data: string }>): Resp
|
||||
});
|
||||
}
|
||||
|
||||
const minimalAnthropicEvents = [
|
||||
{
|
||||
event: "message_start",
|
||||
data: JSON.stringify({
|
||||
type: "message_start",
|
||||
message: {
|
||||
id: "msg_test",
|
||||
usage: {
|
||||
input_tokens: 12,
|
||||
output_tokens: 0,
|
||||
cache_read_input_tokens: 0,
|
||||
cache_creation_input_tokens: 0,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
event: "content_block_start",
|
||||
data: JSON.stringify({
|
||||
type: "content_block_start",
|
||||
index: 0,
|
||||
content_block: { type: "text", text: "" },
|
||||
}),
|
||||
},
|
||||
{
|
||||
event: "content_block_delta",
|
||||
data: JSON.stringify({
|
||||
type: "content_block_delta",
|
||||
index: 0,
|
||||
delta: { type: "text_delta", text: "Hello" },
|
||||
}),
|
||||
},
|
||||
{
|
||||
event: "content_block_stop",
|
||||
data: JSON.stringify({ type: "content_block_stop", index: 0 }),
|
||||
},
|
||||
{
|
||||
event: "message_delta",
|
||||
data: JSON.stringify({
|
||||
type: "message_delta",
|
||||
delta: { stop_reason: "end_turn" },
|
||||
usage: {
|
||||
input_tokens: 12,
|
||||
output_tokens: 5,
|
||||
cache_read_input_tokens: 0,
|
||||
cache_creation_input_tokens: 0,
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
event: "message_stop",
|
||||
data: JSON.stringify({ type: "message_stop" }),
|
||||
},
|
||||
];
|
||||
|
||||
function createFakeAnthropicClient(response: Response): Anthropic {
|
||||
return {
|
||||
messages: {
|
||||
@@ -110,4 +165,25 @@ describe("Anthropic raw SSE parsing", () => {
|
||||
text: "col1\tcol2",
|
||||
});
|
||||
});
|
||||
|
||||
it("ignores unknown SSE events after message_stop", async () => {
|
||||
const model = getModel("anthropic", "claude-haiku-4-5");
|
||||
const context: Context = {
|
||||
messages: [{ role: "user", content: "Say hello.", timestamp: Date.now() }],
|
||||
};
|
||||
const response = createSseResponse([
|
||||
...minimalAnthropicEvents,
|
||||
{ event: "done", data: "[DONE]" },
|
||||
{ event: "proxy.stats", data: "not json" },
|
||||
]);
|
||||
|
||||
const stream = streamAnthropic(model, context, {
|
||||
client: createFakeAnthropicClient(response),
|
||||
});
|
||||
const result = await stream.result();
|
||||
|
||||
expect(result.stopReason).toBe("stop");
|
||||
expect(result.errorMessage).toBeUndefined();
|
||||
expect(result.content).toEqual([{ type: "text", text: "Hello" }]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@ const oauthToken = await resolveApiKey("anthropic");
|
||||
* - Result: tool call has name "Glob" but no tool exists with that name
|
||||
*/
|
||||
describe.skipIf(!oauthToken)("Anthropic OAuth tool name normalization", () => {
|
||||
const model = getModel("anthropic", "claude-sonnet-4-20250514");
|
||||
const model = getModel("anthropic", "claude-sonnet-4-6");
|
||||
|
||||
it("should normalize user-defined tool matching CC name (todowrite -> TodoWrite -> todowrite)", async () => {
|
||||
// User defines a tool named "todowrite" (lowercase)
|
||||
|
||||
@@ -113,7 +113,7 @@ describe("Context overflow error handling", () => {
|
||||
|
||||
describe.skipIf(!process.env.ANTHROPIC_OAUTH_TOKEN)("Anthropic (OAuth)", () => {
|
||||
it("claude-sonnet-4 - should detect overflow via isContextOverflow", async () => {
|
||||
const model = getModel("anthropic", "claude-sonnet-4-20250514");
|
||||
const model = getModel("anthropic", "claude-sonnet-4-6");
|
||||
const result = await testContextOverflow(model, process.env.ANTHROPIC_OAUTH_TOKEN!);
|
||||
logResult(result);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ describe("google-shared convertMessages — Gemini 3 unsigned tool calls", () =>
|
||||
],
|
||||
api: "google-gemini-cli",
|
||||
provider: "google-antigravity",
|
||||
model: "claude-sonnet-4-20250514",
|
||||
model: "claude-sonnet-4-6",
|
||||
usage: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
@@ -146,7 +146,7 @@ describe("google-shared convertMessages — Gemini 3 unsigned tool calls", () =>
|
||||
],
|
||||
api: "google-gemini-cli",
|
||||
provider: "google-antigravity",
|
||||
model: "claude-sonnet-4-20250514",
|
||||
model: "claude-sonnet-4-6",
|
||||
usage: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
|
||||
@@ -72,7 +72,7 @@ describe("lazy provider module loading", () => {
|
||||
it("loads only the Anthropic SDK when calling the root lazy wrapper", () => {
|
||||
const result = runProbe(`
|
||||
const model = {
|
||||
id: "claude-sonnet-4-20250514",
|
||||
id: "claude-sonnet-4-6",
|
||||
name: "Claude Sonnet 4",
|
||||
api: "anthropic-messages",
|
||||
provider: "anthropic",
|
||||
@@ -92,7 +92,7 @@ describe("lazy provider module loading", () => {
|
||||
|
||||
it("loads only the Anthropic SDK when dispatching through streamSimple", () => {
|
||||
const result = runProbe(`
|
||||
const model = mod.getModel("anthropic", "claude-sonnet-4-20250514");
|
||||
const model = mod.getModel("anthropic", "claude-sonnet-4-6");
|
||||
const context = { messages: [{ role: "user", content: "hi" }] };
|
||||
await mod.streamSimple(model, context).result();
|
||||
`);
|
||||
|
||||
@@ -879,8 +879,8 @@ describe("Generate E2E Tests", () => {
|
||||
// Tokens are resolved at module level (see oauthTokens above)
|
||||
// =========================================================================
|
||||
|
||||
describe("Anthropic OAuth Provider (claude-sonnet-4-20250514)", () => {
|
||||
const model = getModel("anthropic", "claude-sonnet-4-20250514");
|
||||
describe("Anthropic OAuth Provider (claude-sonnet-4-6)", () => {
|
||||
const model = getModel("anthropic", "claude-sonnet-4-6");
|
||||
|
||||
it.skipIf(!anthropicOAuthToken)("should complete basic text generation", { retry: 3 }, async () => {
|
||||
await basicTextGeneration(model, { apiKey: anthropicOAuthToken });
|
||||
|
||||
@@ -132,7 +132,7 @@ describe("totalTokens field", () => {
|
||||
"claude-sonnet-4 - should return totalTokens equal to sum of components",
|
||||
{ retry: 3, timeout: 60000 },
|
||||
async () => {
|
||||
const llm = getModel("anthropic", "claude-sonnet-4-20250514");
|
||||
const llm = getModel("anthropic", "claude-sonnet-4-6");
|
||||
|
||||
console.log(`\nAnthropic OAuth / ${llm.id}:`);
|
||||
const { first, second } = await testTotalTokensWithCache(llm, { apiKey: anthropicOAuthToken });
|
||||
|
||||
Reference in New Issue
Block a user