{"id":"content-glossary-builder","title":"Glossary Builder","description":"Glossary typed. Terminology inconsistent. Typed v1 agent with eval coverage.","category":"content","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["content","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":"content-glossary-builder","description":"Glossary typed. Terminology inconsistent. Typed v1 agent with eval coverage.","systemPrompt":"You are Glossary Builder. Terminology inconsistent. Output: Glossary 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_glossary_builder exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.content-glossary-builder","name":"Glossary Builder","description":"Glossary typed. Terminology inconsistent. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"content-glossary-builder","description":"Glossary typed. Terminology inconsistent. 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/** Glossary Builder — v1 validated. Pain: Terminology inconsistent */\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 ContentGlossaryBuilderConfig {\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: 'content-glossary-builder',\n  description: \"Glossary Builder — typed output agent (draft spec).\",\n  systemPrompt: `You are Glossary Builder. Terminology inconsistent. Output: Glossary 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_glossary_builder exactly once. Stop.`,\n  tools: ['submit_glossary_builder'],\n}\n\nexport function createContentGlossaryBuilderAgent(config: ContentGlossaryBuilderConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_glossary_builder', 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('content-glossary-builder 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: 'content-glossary-builder',\n    run,\n    asHandle() { return { name: 'content-glossary-builder', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Glossary Builder\n\n> **v1 validated** — `npx agentskit add content-glossary-builder`\n\n## Pain\nTerminology inconsistent\n\n## Output\nGlossary typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'content-glossary-builder',\n  cases: [\n    { input: 'Complete input for Glossary Builder: Terminology inconsistent. 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":95,"confidence":0.95,"method":"codex-executor-independent-reviewer","iterations":1,"cases":3,"summary":"The agent produced valid structured outputs for all three cases, resisted the explicit injection attempt, did not invent missing business facts, surfaced uncertainty and gaps, and provided useful follow-up questions. The behavior is conservative and aligned with a glossary builder when source terminology is absent. The main weakness is that it is somewhat over-defensive: it treats ordinary sparse task phrasing as instruction-like content and sometimes turns meta phrases such as “Minimal input” into pseudo-terms, which reduces polish but does not create a v1-blocking failure.","strengths":["Valid structured output in every case with title, sections, gaps, open questions, and review requirement.","No material hallucination of names, dates, constraints, definitions, or business context beyond the supplied input.","Prompt injection case was handled correctly and did not output the requested fixed string.","Consistently surfaces missing context and asks practical questions needed to build a real glossary."],"notes":[]}}