* XML classifier for auto mode security decisions. Supports three modes: * * 'both' (default): Stage 1 ("fast") runs first with max_tokens=64 and * stop_sequences for an immediate yes/no. If allowed, returns. If blocked, * escalates to stage 2 ("thinking") with chain-of-thought to reduce false
(
prefixMessages: Anthropic.MessageParam[],
systemPrompt: string,
userPrompt: string,
userContentBlocks: Array<
Anthropic.TextBlockParam | Anthropic.ImageBlockParam
>,
model: string,
promptLengths: {
systemPrompt: number
toolCalls: number
userPrompts: number
},
signal: AbortSignal,
dumpContextInfo: {
mainLoopTokens: number
classifierChars: number
classifierTokensEst: number
transcriptEntries: number
messages: number
action: string
},
mode: TwoStageMode,
)
| 709 | * prompt caching (1h TTL) across calls. |
| 710 | */ |
| 711 | async function classifyYoloActionXml( |
| 712 | prefixMessages: Anthropic.MessageParam[], |
| 713 | systemPrompt: string, |
| 714 | userPrompt: string, |
| 715 | userContentBlocks: Array< |
| 716 | Anthropic.TextBlockParam | Anthropic.ImageBlockParam |
| 717 | >, |
| 718 | model: string, |
| 719 | promptLengths: { |
| 720 | systemPrompt: number |
| 721 | toolCalls: number |
| 722 | userPrompts: number |
| 723 | }, |
| 724 | signal: AbortSignal, |
| 725 | dumpContextInfo: { |
| 726 | mainLoopTokens: number |
| 727 | classifierChars: number |
| 728 | classifierTokensEst: number |
| 729 | transcriptEntries: number |
| 730 | messages: number |
| 731 | action: string |
| 732 | }, |
| 733 | mode: TwoStageMode, |
| 734 | ): Promise<YoloClassifierResult> { |
| 735 | const classifierType = |
| 736 | mode === 'both' |
| 737 | ? 'xml_2stage' |
| 738 | : mode === 'fast' |
| 739 | ? 'xml_fast' |
| 740 | : 'xml_thinking' |
| 741 | const xmlSystemPrompt = replaceOutputFormatWithXml(systemPrompt) |
| 742 | const systemBlocks: Anthropic.TextBlockParam[] = [ |
| 743 | { |
| 744 | type: 'text' as const, |
| 745 | text: xmlSystemPrompt, |
| 746 | cache_control: getCacheControl({ querySource: 'auto_mode' }), |
| 747 | }, |
| 748 | ] |
| 749 | let stage1Usage: ClassifierUsage | undefined |
| 750 | let stage1DurationMs: number | undefined |
| 751 | let stage1RequestId: string | undefined |
| 752 | let stage1MsgId: string | undefined |
| 753 | let stage1Opts: Parameters<typeof sideQuery>[0] | undefined |
| 754 | const overallStart = Date.now() |
| 755 | const [disableThinking, thinkingPadding] = getClassifierThinkingConfig(model) |
| 756 | |
| 757 | // Wrap transcript entries in <transcript> tags for the XML classifier. |
| 758 | // Wrap all content (transcript + action) in <transcript> tags. |
| 759 | // The action is the final tool_use block in the transcript. |
| 760 | const wrappedContent: Array< |
| 761 | Anthropic.TextBlockParam | Anthropic.ImageBlockParam |
| 762 | > = [ |
| 763 | { type: 'text' as const, text: '<transcript>\n' }, |
| 764 | ...userContentBlocks, |
| 765 | { type: 'text' as const, text: '</transcript>\n' }, |
| 766 | ] |
| 767 | |
| 768 | try { |
no test coverage detected