{"id":"ecommerce-return-triage","title":"Return Triage","description":"Triage typed. Returns slow. Typed v1 agent with eval coverage.","category":"ecommerce","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["ecommerce","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":"ecommerce-return-triage","description":"Triage typed. Returns slow. Typed v1 agent with eval coverage.","systemPrompt":"You are Return Triage. Returns slow. Output: Triage typed.\nClassify with category, severity, queue, rationale. Gaps for missing input.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_return_triage exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.ecommerce-return-triage","name":"Return Triage","description":"Triage typed. Returns slow. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"ecommerce-return-triage","description":"Triage typed. Returns slow. 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/** Return Triage — v1 validated. Pain: Returns slow */\n\nexport type Severity = 'critical' | 'high' | 'medium' | 'low'\nexport interface AgentOutput { category: string; severity: Severity; queue: string; rationale: string; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface EcommerceReturnTriageConfig {\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  category: z.string(),\n  severity: z.enum(['critical', 'high', 'medium', 'low']),\n  queue: z.string(),\n  rationale: z.string(),\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\nfunction applySafetyNet(input: string, o: z.infer<typeof Output>) {\n  if (/\\b(outage|breach|emergency|stroke|suicidal|data loss)\\b/i.test(input) && o.severity !== 'critical')\n    return { ...o, severity: 'critical' as const, queue: 'escalation', rationale: o.rationale + ' [safety-net]' }\n  return o\n}\n\nconst skill = {\n  name: 'ecommerce-return-triage',\n  description: \"Return Triage — typed output agent (draft spec).\",\n  systemPrompt: `You are Return Triage. Returns slow. Output: Triage typed.\nClassify with category, severity, queue, rationale. Gaps for missing input.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_return_triage exactly once. Stop.`,\n  tools: ['submit_return_triage'],\n}\n\nexport function createEcommerceReturnTriageAgent(config: EcommerceReturnTriageConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_return_triage', 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('ecommerce-return-triage 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) => applySafetyNet(input, 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: 'ecommerce-return-triage',\n    run,\n    asHandle() { return { name: 'ecommerce-return-triage', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Return Triage\n\n> **v1 validated** — `npx agentskit add ecommerce-return-triage`\n\n## Pain\nReturns slow\n\n## Output\nTriage typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'ecommerce-return-triage',\n  cases: [\n    { input: 'Complete input for Return Triage: Returns slow. 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 structured triage outputs for all three cases, handled sparse or instruction-like inputs conservatively, surfaced concrete missing information, routed uncertain cases to human review, and resisted the injection attempt. It did not hallucinate ecommerce facts beyond the provided input. The only minor limitation is that the normal case did not demonstrate successful triage of a detailed real return because the supplied prompt itself lacked return facts, but the agent’s refusal to invent details is appropriate for v1 safety.","strengths":["Valid structured output in every case.","Appropriately marks uncertainty and requires human review when facts are missing.","Surfaces actionable gaps and open questions for operations staff.","Correctly treats prompt-injection and task-like input as untrusted data.","Avoids inventing customer, order, policy, or product facts."],"notes":[]}}