fix(plugin): repair anthropic assistant prefill tails
This commit is contained in:
@@ -419,7 +419,48 @@ describe("createMessagesTransformHandler", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("#given models that still allow assistant prefill or missing model metadata #when messages transform runs #then it keeps the assistant tail unchanged", async () => {
|
it("#given any Anthropic Claude history ends with an assistant tail #when messages transform runs #then it appends a synthetic user recovery turn", async () => {
|
||||||
|
//#given
|
||||||
|
const messages: TestMessage[] = [
|
||||||
|
{
|
||||||
|
info: {
|
||||||
|
id: "msg_user_any_anthropic",
|
||||||
|
role: "user",
|
||||||
|
sessionID: "ses_any_anthropic_prefill",
|
||||||
|
agent: "sisyphus",
|
||||||
|
model: { providerID: "anthropic", modelID: "claude-sonnet-4-5" },
|
||||||
|
},
|
||||||
|
parts: [{ type: "text", text: "continue" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
info: {
|
||||||
|
id: "msg_assistant_any_anthropic",
|
||||||
|
role: "assistant",
|
||||||
|
sessionID: "ses_any_anthropic_prefill",
|
||||||
|
},
|
||||||
|
parts: [{ type: "text", text: "done" }],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await runHandler(makeHooks({}), messages)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(messages).toHaveLength(3)
|
||||||
|
expect(messages.at(-1)?.info).toMatchObject({
|
||||||
|
role: "user",
|
||||||
|
sessionID: "ses_any_anthropic_prefill",
|
||||||
|
agent: "sisyphus",
|
||||||
|
model: { providerID: "anthropic", modelID: "claude-sonnet-4-5" },
|
||||||
|
})
|
||||||
|
expect(messages.at(-1)?.parts[0]).toMatchObject({
|
||||||
|
type: "text",
|
||||||
|
text: "[internal] Continue from the previous assistant state.",
|
||||||
|
synthetic: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("#given non-Anthropic models or missing model metadata #when messages transform runs #then it keeps the assistant tail unchanged", async () => {
|
||||||
//#given
|
//#given
|
||||||
const scenarios: Array<{ name: string; userInfo: TestMessage["info"] }> = [
|
const scenarios: Array<{ name: string; userInfo: TestMessage["info"] }> = [
|
||||||
{
|
{
|
||||||
@@ -429,13 +470,6 @@ describe("createMessagesTransformHandler", () => {
|
|||||||
model: { providerID: "openai", modelID: "gpt-5.4" },
|
model: { providerID: "openai", modelID: "gpt-5.4" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "anthropic allowed",
|
|
||||||
userInfo: {
|
|
||||||
role: "user",
|
|
||||||
model: { providerID: "anthropic", modelID: "claude-sonnet-4-5" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "missing model",
|
name: "missing model",
|
||||||
userInfo: { role: "user" },
|
userInfo: { role: "user" },
|
||||||
|
|||||||
@@ -9,12 +9,6 @@ const ASSISTANT_PREFILL_UNSUPPORTED_PROVIDERS = new Set([
|
|||||||
"anthropic",
|
"anthropic",
|
||||||
"google-vertex-anthropic",
|
"google-vertex-anthropic",
|
||||||
])
|
])
|
||||||
const ASSISTANT_PREFILL_UNSUPPORTED_MODEL_PREFIXES = [
|
|
||||||
"claude-opus-4-7",
|
|
||||||
"claude-opus-4-6",
|
|
||||||
"claude-sonnet-4-6",
|
|
||||||
"claude-mythos",
|
|
||||||
]
|
|
||||||
|
|
||||||
type MessageWithParts = {
|
type MessageWithParts = {
|
||||||
info: Message
|
info: Message
|
||||||
@@ -101,8 +95,7 @@ function shouldRepairAssistantPrefillForModel(model: ModelIdentifier | undefined
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
const modelID = normalizeModelID(model.modelID.toLowerCase())
|
return normalizeModelID(model.modelID.toLowerCase()).startsWith("claude-")
|
||||||
return ASSISTANT_PREFILL_UNSUPPORTED_MODEL_PREFIXES.some((prefix) => modelID.startsWith(prefix))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isCompactionContinuationPart(part: unknown): boolean {
|
function isCompactionContinuationPart(part: unknown): boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user