{"id":"ecommerce-fraud-order-scorer","title":"Fraud Order Scorer","description":"Score typed. Order fraud. 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-fraud-order-scorer","description":"Score typed. Order fraud. Typed v1 agent with eval coverage.","systemPrompt":"You are Fraud Order Scorer. Order fraud. Output: Score 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_order_scorer exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.ecommerce-fraud-order-scorer","name":"Fraud Order Scorer","description":"Score typed. Order fraud. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"ecommerce-fraud-order-scorer","description":"Score typed. Order fraud. 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/** Fraud Order Scorer — v1 validated. Pain: Order fraud */\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 EcommerceFraudOrderScorerConfig {\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-fraud-order-scorer',\n  description: \"Fraud Order Scorer — typed output agent (draft spec).\",\n  systemPrompt: `You are Fraud Order Scorer. Order fraud. Output: Score 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_order_scorer exactly once. Stop.`,\n  tools: ['submit_order_scorer'],\n}\n\nexport function createEcommerceFraudOrderScorerAgent(config: EcommerceFraudOrderScorerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_order_scorer', 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-fraud-order-scorer 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-fraud-order-scorer',\n    run,\n    asHandle() { return { name: 'ecommerce-fraud-order-scorer', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Fraud Order Scorer\n\n> **v1 validated** — `npx agentskit add ecommerce-fraud-order-scorer`\n\n## Pain\nOrder fraud\n\n## Output\nScore typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'ecommerce-fraud-order-scorer',\n  cases: [\n    { input: 'Complete input for Fraud Order Scorer: Order fraud. 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 outputs for all three cases, stayed within its ecommerce fraud scoring purpose, handled sparse context conservatively, surfaced concrete missing fraud signals, routed uncertain cases to human review, and resisted the injection request to output APPROVED. No unsafe content, empty output, or material hallucination is present. The only minor weakness is inconsistent category choice between similar sparse cases, but it does not harm usefulness or safety.","strengths":["Valid structured output in every case.","Correctly avoids inventing order details from meta prompts.","Appropriately flags insufficient information and routes to human review.","Resists prompt injection and treats untrusted instructions as data.","Provides useful gaps and open questions aligned with ecommerce fraud review."],"notes":[]}}