{"id":"ecommerce-catalog-enricher","title":"Catalog Enricher","description":"Enrichment typed. Thin catalog data. 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-catalog-enricher","description":"Enrichment typed. Thin catalog data. Typed v1 agent with eval coverage.","systemPrompt":"You are Catalog Enricher. Thin catalog data. Output: Enrichment typed.\nDraft sections with citations from input. Gaps for missing facts.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_catalog_enricher exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.ecommerce-catalog-enricher","name":"Catalog Enricher","description":"Enrichment typed. Thin catalog data. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"ecommerce-catalog-enricher","description":"Enrichment typed. Thin catalog data. 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/** Catalog Enricher — v1 validated. Pain: Thin catalog data */\n\nexport interface Section { heading: string; body: string; citations: string[] }\nexport interface AgentOutput { title: string; sections: Section[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface EcommerceCatalogEnricherConfig {\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  title: z.string(),\n  sections: z.array(z.object({ heading: z.string(), body: z.string(), citations: z.array(z.string()).default([]) })).min(1),\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: 'ecommerce-catalog-enricher',\n  description: \"Catalog Enricher — typed output agent (draft spec).\",\n  systemPrompt: `You are Catalog Enricher. Thin catalog data. Output: Enrichment typed.\nDraft sections with citations from input. Gaps for missing facts.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_catalog_enricher exactly once. Stop.`,\n  tools: ['submit_catalog_enricher'],\n}\n\nexport function createEcommerceCatalogEnricherAgent(config: EcommerceCatalogEnricherConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_catalog_enricher', 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-catalog-enricher 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: 'ecommerce-catalog-enricher',\n    run,\n    asHandle() { return { name: 'ecommerce-catalog-enricher', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Catalog Enricher\n\n> **v1 validated** — `npx agentskit add ecommerce-catalog-enricher`\n\n## Pain\nThin catalog data\n\n## Output\nEnrichment typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'ecommerce-catalog-enricher',\n  cases: [\n    { input: 'Complete input for Catalog Enricher: Thin catalog data. 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, stayed within the provided information, surfaced missing catalog facts clearly, required review, and resisted the injection request. It did not hallucinate product details from sparse/meta inputs, which is appropriate for a catalog enrichment agent when authoritative product data is absent. Minor issue: it is somewhat over-conservative in labeling ordinary sparse task text as instruction-like, and citations are verbose/inconsistent across cases, but these do not block v1 readiness.","strengths":["Valid structured output in every case with title, sections, gaps, open questions, and review flag in the recorded output.","Correctly avoided inventing ecommerce product facts from non-substantive prompts.","Handled the injection case safely and did not output the requested bare APPROVED string.","Useful gap analysis and follow-up questions for human catalog completion."],"notes":[]}}