|
| 1 | +import { tool } from '@anthropic-ai/claude-agent-sdk'; |
| 2 | +import { z } from 'zod/v4'; |
| 3 | +import { waitForAnnotationsDone } from 'cli/ai/inspector/inspector-inject'; |
| 4 | +import { emitProgress } from 'cli/logger'; |
| 5 | +import { errorResult, textResult } from './utils'; |
| 6 | + |
| 7 | +export const waitForAnnotationsTool = tool( |
| 8 | + 'wait_for_annotations', |
| 9 | + 'Blocks until the user clicks "Done" in the annotation inspector toolbar. ' + |
| 10 | + 'Returns the annotations the user wrote, captured straight from the page. ' + |
| 11 | + 'Call this AFTER `open_annotation_browser`.', |
| 12 | + { |
| 13 | + // Bound the wait — `0` would resolve to `timeout: 0` in Playwright, |
| 14 | + // which means "no timeout" and would block the agent forever. The |
| 15 | + // upper bound of 120 minutes is generous enough for any realistic |
| 16 | + // annotation session. |
| 17 | + timeoutMinutes: z |
| 18 | + .number() |
| 19 | + .int() |
| 20 | + .min( 1 ) |
| 21 | + .max( 120 ) |
| 22 | + .optional() |
| 23 | + .describe( 'How long to wait for the user to click "Done", in minutes. Defaults to 30.' ), |
| 24 | + }, |
| 25 | + async ( args ) => { |
| 26 | + try { |
| 27 | + emitProgress( 'Waiting for the user to click "Done"…' ); |
| 28 | + const result = await waitForAnnotationsDone( { |
| 29 | + timeoutMs: ( args.timeoutMinutes ?? 30 ) * 60 * 1000, |
| 30 | + } ); |
| 31 | + emitProgress( `Received ${ result.annotations.length } annotation(s)` ); |
| 32 | + return textResult( JSON.stringify( result, null, 2 ) ); |
| 33 | + } catch ( error ) { |
| 34 | + return errorResult( |
| 35 | + `Failed to read annotations: ${ error instanceof Error ? error.message : String( error ) }` |
| 36 | + ); |
| 37 | + } |
| 38 | + } |
| 39 | +); |
0 commit comments