File size: 2,478 Bytes
fdc8b59 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | import { z } from 'zod'
import { buildTool, type ToolDef } from '../../Tool.js'
import { lazySchema } from '../../utils/lazySchema.js'
import { jsonStringify } from '../../utils/slowOperations.js'
import {
formatElapsed,
formatGoalStatus,
} from '../../utils/goal.js'
import {
DESCRIPTION,
GET_GOAL_TOOL_NAME,
GET_GOAL_TOOL_PROMPT,
} from './prompt.js'
import { renderToolResultMessage, renderToolUseMessage } from './UI.js'
const inputSchema = lazySchema(() => z.strictObject({}))
type InputSchema = ReturnType<typeof inputSchema>
const goalInfoSchema = z.object({
id: z.string(),
objective: z.string(),
status: z.string(),
elapsed_ms: z.number(),
elapsed_formatted: z.string(),
continuation_count: z.number(),
})
const outputSchema = lazySchema(() =>
z.object({
goal: goalInfoSchema.nullable(),
message: z.string(),
}),
)
type OutputSchema = ReturnType<typeof outputSchema>
export type Output = z.infer<OutputSchema>
export const GoalGetTool = buildTool({
name: GET_GOAL_TOOL_NAME,
searchHint: 'get current thread goal status and budget',
maxResultSizeChars: 4_000,
userFacingName: () => 'Get Goal',
get inputSchema(): InputSchema {
return inputSchema()
},
get outputSchema(): OutputSchema {
return outputSchema()
},
isReadOnly() {
return true
},
isConcurrencySafe() {
return true
},
toAutoClassifierInput() {
return ''
},
async description() {
return DESCRIPTION
},
async prompt() {
return GET_GOAL_TOOL_PROMPT
},
mapToolResultToToolResultBlockParam(output, toolUseID) {
return {
tool_use_id: toolUseID,
type: 'tool_result',
content: jsonStringify(output),
}
},
renderToolUseMessage,
renderToolResultMessage,
async call(_input, { getAppState }) {
const goal = getAppState().goal
if (!goal) {
return {
data: {
goal: null,
message: 'No active goal.',
},
}
}
const now = Date.now()
const elapsed = now - goal.startedAt
return {
data: {
goal: {
id: goal.id,
objective: goal.objective,
status: formatGoalStatus(goal.status),
elapsed_ms: elapsed,
elapsed_formatted: formatElapsed(elapsed),
continuation_count: goal.continuationCount,
},
message: `Current goal: ${goal.objective} (${formatGoalStatus(goal.status)})`,
},
}
},
} satisfies ToolDef<InputSchema, Output>) |