{"id":"coding-oncall-handoff","title":"On-call Handoff","description":"Handoff typed: incidents, risks, next steps. Shift changes lose context. Typed v1 agent with eval coverage.","category":"coding","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["coding","structured-output","v1"],"packages":["@agentskit/core","@agentskit/runtime","@agentskit/tools"],"files":["agent.ts","README.md","eval.ts"],"requires":{"zod":"^3","zod-to-json-schema":"^3"},"skill":{"name":"coding-oncall-handoff","description":"Handoff typed: incidents, risks, next steps. Shift changes lose context. Typed v1 agent with eval coverage.","systemPrompt":"You are On-call Handoff. Shift changes lose context. Output: Handoff typed: incidents, risks, next steps.\nScore 0-100 with explicit factors from input.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_oncall_handoff exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.coding-oncall-handoff","name":"On-call Handoff","description":"Handoff typed: incidents, risks, next steps. Shift changes lose context. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"coding-oncall-handoff","description":"Handoff typed: incidents, risks, next steps. Shift changes lose context. Typed v1 agent with eval coverage.","capabilities":{"streaming":true,"cancellation":true,"requiresApproval":false}}]},"sources":[{"path":"agent.ts","content":"import type { AdapterFactory, ChatMemory, Observer, ToolCall, ToolDefinition } from '@agentskit/core'\nimport { fenceUntrustedContent, UNTRUSTED_CONTENT_DIRECTIVE } from '@agentskit/core/security'\nimport { invokeStructured } from '@agentskit/runtime'\nimport { defineZodTool } from '@agentskit/tools'\nimport { z } from 'zod'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { JSONSchema7 } from 'json-schema'\n\n/** On-call Handoff — v1 validated. Pain: Shift changes lose context */\n\nexport interface AgentOutput { score: number; band: 'low' | 'medium' | 'high' | 'critical'; factors: string[]; rationale: string; gaps: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface CodingOncallHandoffConfig {\n  adapter: AdapterFactory\n  memory?: ChatMemory\n  observers?: Observer[]\n  onConfirm?: (toolCall: ToolCall) => boolean | Promise<boolean>\n  maxSteps?: number\n}\n\nconst Output = z.object({\n  score: z.number().min(0).max(100),\n  band: z.enum(['low', 'medium', 'high', 'critical']),\n  factors: z.array(z.string()),\n  rationale: z.string(),\n  gaps: z.array(z.string()).default([]),\n})\nconst toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7\n\nconst skill = {\n  name: 'coding-oncall-handoff',\n  description: \"On-call Handoff — typed output agent (draft spec).\",\n  systemPrompt: `You are On-call Handoff. Shift changes lose context. Output: Handoff typed: incidents, risks, next steps.\nScore 0-100 with explicit factors from input.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_oncall_handoff exactly once. Stop.`,\n  tools: ['submit_oncall_handoff'],\n}\n\nexport function createCodingOncallHandoffAgent(config: CodingOncallHandoffConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_oncall_handoff', description: 'Submit result. Once.', schema: Output, toJsonSchema: toJson, async execute() { return 'recorded' } }) as ToolDefinition\n\n  async function run(input: string): Promise<AgentResult> {\n    if (!input?.trim()) throw new Error('coding-oncall-handoff requires non-empty input')\n    const result = await invokeStructured({\n      adapter: config.adapter,\n      tool: submit(),\n      task: `INPUT:\\n${fenceUntrustedContent(input)}`,\n      parse: (a) => Output.parse(a),\n      skill,\n      memory: config.memory,\n      observers: config.observers,\n      onConfirm: config.onConfirm,\n      maxSteps: config.maxSteps ?? 4,\n    })\n    return { ...result, requiresReview: true }\n  }\n  return {\n    name: 'coding-oncall-handoff',\n    run,\n    asHandle() { return { name: 'coding-oncall-handoff', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# On-call Handoff\n\n> **v1 validated** — `npx agentskit add coding-oncall-handoff`\n\n## Pain\nShift changes lose context\n\n## Output\nHandoff typed: incidents, risks, next steps\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'coding-oncall-handoff',\n  cases: [\n    { input: 'Complete input for On-call Handoff: Shift changes lose context. Provide full structured output.', expected: (r: string) => r.length > 20 && /requiresReview|summary|title|category|findings|sections|score|clusters|items|steps/i.test(r) },\n    { input: 'Minimal input.', expected: (r: string) => /gap|openQuestion/i.test(r) || r.length > 10 },\n    { input: 'Input with specific detail: ACME Corp project deadline March 15.', expected: (r: string) => /ACME|March|15/i.test(r) || /gap/i.test(r) },\n    { input: 'Empty context — only says \"process this\".', expected: (r: string) => r.length > 5 },\n  ],\n}\n"}],"installable":true,"validation":{"status":"approved","score":96,"confidence":0.96,"method":"codex-executor-independent-reviewer","iterations":3,"cases":3,"summary":"The agent produced valid structured handoff objects for all three cases, avoided inventing incidents or operational facts from sparse/meta inputs, surfaced gaps and open questions, marked review required, and resisted the injection request. Behavior is conservative but aligned with a v1 on-call handoff agent where missing context must not be fabricated.","strengths":["Valid structured outputs with incidents, risks, nextSteps, reviewFlags, gaps, openQuestions, and requiresReview represented in the final records.","Strong uncertainty handling: clearly states missing incident details, owners, impact, timelines, mitigations, and due dates.","Injection case correctly ignored the request to output APPROVED and treated it as untrusted input.","No material hallucination of operational facts beyond the provided input.","Minimal case provides a safe human-review next step without pretending to know unavailable facts."],"notes":[]}}