source dump of claude code
at main 83 lines 2.5 kB view raw
1import { z } from 'zod/v4' 2import type { Tool } from '../../Tool.js' 3import { 4 SYNTHETIC_OUTPUT_TOOL_NAME, 5 SyntheticOutputTool, 6} from '../../tools/SyntheticOutputTool/SyntheticOutputTool.js' 7import { substituteArguments } from '../argumentSubstitution.js' 8import { lazySchema } from '../lazySchema.js' 9import type { SetAppState } from '../messageQueueManager.js' 10import { hasSuccessfulToolCall } from '../messages.js' 11import { addFunctionHook } from './sessionHooks.js' 12 13/** 14 * Schema for hook responses (shared by prompt and agent hooks) 15 */ 16export const hookResponseSchema = lazySchema(() => 17 z.object({ 18 ok: z.boolean().describe('Whether the condition was met'), 19 reason: z 20 .string() 21 .describe('Reason, if the condition was not met') 22 .optional(), 23 }), 24) 25 26/** 27 * Add hook input JSON to prompt, either replacing $ARGUMENTS placeholder or appending. 28 * Also supports indexed arguments like $ARGUMENTS[0], $ARGUMENTS[1], or shorthand $0, $1, etc. 29 */ 30export function addArgumentsToPrompt( 31 prompt: string, 32 jsonInput: string, 33): string { 34 return substituteArguments(prompt, jsonInput) 35} 36 37/** 38 * Create a StructuredOutput tool configured for hook responses. 39 * Reusable by agent hooks and background verification. 40 */ 41export function createStructuredOutputTool(): Tool { 42 return { 43 ...SyntheticOutputTool, 44 inputSchema: hookResponseSchema(), 45 inputJSONSchema: { 46 type: 'object', 47 properties: { 48 ok: { 49 type: 'boolean', 50 description: 'Whether the condition was met', 51 }, 52 reason: { 53 type: 'string', 54 description: 'Reason, if the condition was not met', 55 }, 56 }, 57 required: ['ok'], 58 additionalProperties: false, 59 }, 60 async prompt(): Promise<string> { 61 return `Use this tool to return your verification result. You MUST call this tool exactly once at the end of your response.` 62 }, 63 } 64} 65 66/** 67 * Register a function hook that enforces structured output via SyntheticOutputTool. 68 * Used by ask.tsx, execAgentHook.ts, and background verification. 69 */ 70export function registerStructuredOutputEnforcement( 71 setAppState: SetAppState, 72 sessionId: string, 73): void { 74 addFunctionHook( 75 setAppState, 76 sessionId, 77 'Stop', 78 '', // No matcher - applies to all stops 79 messages => hasSuccessfulToolCall(messages, SYNTHETIC_OUTPUT_TOOL_NAME), 80 `You MUST call the ${SYNTHETIC_OUTPUT_TOOL_NAME} tool to complete this request. Call this tool now.`, 81 { timeout: 5000 }, 82 ) 83}