File size: 2,616 Bytes
064bfd6 | 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 | import { z } from 'zod/v4'
import type { ValidationResult } from '../../Tool.js'
import { buildTool, type ToolDef } from '../../Tool.js'
import {
getCronFilePath,
listAllCronTasks,
removeCronTasks,
} from '../../utils/cronTasks.js'
import { lazySchema } from '../../utils/lazySchema.js'
import { getTeammateContext } from '../../utils/teammateContext.js'
import {
buildCronDeletePrompt,
CRON_DELETE_DESCRIPTION,
CRON_DELETE_TOOL_NAME,
isDurableCronEnabled,
isKairosCronEnabled,
} from './prompt.js'
import { renderDeleteResultMessage, renderDeleteToolUseMessage } from './UI.js'
const inputSchema = lazySchema(() =>
z.strictObject({
id: z.string().describe('Job ID returned by CronCreate.'),
}),
)
type InputSchema = ReturnType<typeof inputSchema>
const outputSchema = lazySchema(() =>
z.object({
id: z.string(),
}),
)
type OutputSchema = ReturnType<typeof outputSchema>
export type DeleteOutput = z.infer<OutputSchema>
export const CronDeleteTool = buildTool({
name: CRON_DELETE_TOOL_NAME,
searchHint: 'cancel a scheduled cron job',
maxResultSizeChars: 100_000,
shouldDefer: true,
get inputSchema(): InputSchema {
return inputSchema()
},
get outputSchema(): OutputSchema {
return outputSchema()
},
isEnabled() {
return isKairosCronEnabled()
},
toAutoClassifierInput(input) {
return input.id
},
async description() {
return CRON_DELETE_DESCRIPTION
},
async prompt() {
return buildCronDeletePrompt(isDurableCronEnabled())
},
getPath() {
return getCronFilePath()
},
async validateInput(input): Promise<ValidationResult> {
const tasks = await listAllCronTasks()
const task = tasks.find(t => t.id === input.id)
if (!task) {
return {
result: false,
message: `No scheduled job with id '${input.id}'`,
errorCode: 1,
}
}
// Teammates may only delete their own crons.
const ctx = getTeammateContext()
if (ctx && task.agentId !== ctx.agentId) {
return {
result: false,
message: `Cannot delete cron job '${input.id}': owned by another agent`,
errorCode: 2,
}
}
return { result: true }
},
async call({ id }) {
await removeCronTasks([id])
return { data: { id } }
},
mapToolResultToToolResultBlockParam(output, toolUseID) {
return {
tool_use_id: toolUseID,
type: 'tool_result',
content: `Cancelled job ${output.id}.`,
}
},
renderToolUseMessage: renderDeleteToolUseMessage,
renderToolResultMessage: renderDeleteResultMessage,
} satisfies ToolDef<InputSchema, DeleteOutput>)
|