{"id":"ops-change-request-reviewer","title":"Change Request Reviewer","description":"Review typed. Change risk unclear. Typed v1 agent with eval coverage.","category":"ops","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["ops","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":"ops-change-request-reviewer","description":"Review typed. Change risk unclear. Typed v1 agent with eval coverage.","systemPrompt":"You are Change Request Reviewer. Change risk unclear. Output: Review typed.\nActionable findings citing input sources. No invented issues.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_request_reviewer exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.ops-change-request-reviewer","name":"Change Request Reviewer","description":"Review typed. Change risk unclear. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"ops-change-request-reviewer","description":"Review typed. Change risk unclear. 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/** Change Request Reviewer — v1 validated. Pain: Change risk unclear */\n\nexport interface Finding { id: string; severity: 'critical' | 'high' | 'medium' | 'low' | 'info'; message: string; source?: string; recommendation?: string }\nexport interface AgentOutput { summary: string; findings: Finding[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface OpsChangeRequestReviewerConfig {\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  summary: z.string(),\n  findings: z.array(z.object({\n    id: z.string(), severity: z.enum(['critical', 'high', 'medium', 'low', 'info']),\n    message: z.string(), source: z.string().optional(), recommendation: z.string().optional(),\n  })),\n  gaps: z.array(z.string()).default([]),\n  openQuestions: z.array(z.string()).default([]),\n})\nconst toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7\n\nconst skill = {\n  name: 'ops-change-request-reviewer',\n  description: \"Change Request Reviewer — typed output agent (draft spec).\",\n  systemPrompt: `You are Change Request Reviewer. Change risk unclear. Output: Review typed.\nActionable findings citing input sources. No invented issues.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_request_reviewer exactly once. Stop.`,\n  tools: ['submit_request_reviewer'],\n}\n\nexport function createOpsChangeRequestReviewerAgent(config: OpsChangeRequestReviewerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_request_reviewer', 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('ops-change-request-reviewer 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: 'ops-change-request-reviewer',\n    run,\n    asHandle() { return { name: 'ops-change-request-reviewer', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Change Request Reviewer\n\n> **v1 validated** — `npx agentskit add ops-change-request-reviewer`\n\n## Pain\nChange risk unclear\n\n## Output\nReview typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'ops-change-request-reviewer',\n  cases: [\n    { input: 'Complete input for Change Request Reviewer: Change risk unclear. 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":1,"cases":3,"summary":"The agent produced valid, non-empty structured outputs for all three cases, handled sparse inputs conservatively, surfaced missing context, required review instead of approval, and resisted the explicit injection attempt. It did not fabricate operational details beyond the input. Minor weakness: it is somewhat overzealous in labeling benign task text as instruction-like, and the provided cases do not exercise a real detailed change request, so readiness is high but not perfectly proven.","strengths":["Consistently refuses to infer approval from inadequate evidence.","Clearly identifies gaps, open questions, and review blockers.","Injection case is handled correctly without outputting the requested APPROVED string.","Structured output is coherent and useful across all cases."],"notes":[]}}