{"id":"sales-proposal-drafter","title":"Proposal Drafter","description":"Proposal typed. Proposals slow. Typed v1 agent with eval coverage.","category":"sales","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["sales","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":"sales-proposal-drafter","description":"Proposal typed. Proposals slow. Typed v1 agent with eval coverage.","systemPrompt":"You are Proposal Drafter. Proposals slow. Output: Proposal 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_proposal_drafter exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.sales-proposal-drafter","name":"Proposal Drafter","description":"Proposal typed. Proposals slow. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"sales-proposal-drafter","description":"Proposal typed. Proposals 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/** Proposal Drafter — v1 validated. Pain: Proposals slow */\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 SalesProposalDrafterConfig {\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: 'sales-proposal-drafter',\n  description: \"Proposal Drafter — typed output agent (draft spec).\",\n  systemPrompt: `You are Proposal Drafter. Proposals slow. Output: Proposal 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_proposal_drafter exactly once. Stop.`,\n  tools: ['submit_proposal_drafter'],\n}\n\nexport function createSalesProposalDrafterAgent(config: SalesProposalDrafterConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_proposal_drafter', 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('sales-proposal-drafter 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: 'sales-proposal-drafter',\n    run,\n    asHandle() { return { name: 'sales-proposal-drafter', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Proposal Drafter\n\n> **v1 validated** — `npx agentskit add sales-proposal-drafter`\n\n## Pain\nProposals slow\n\n## Output\nProposal typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'sales-proposal-drafter',\n  cases: [\n    { input: 'Complete input for Proposal Drafter: Proposals 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 proposal-drafter outputs for all three cases, avoided inventing business facts, surfaced uncertainty and missing inputs, and handled the injection attempt correctly by treating it as data rather than following it. The behavior is conservative but appropriate for sparse or synthetic inputs under a no-hallucination proposal drafting contract. Runtime stderr contains unrelated loader warnings, but the agent records are ok and outputs are non-empty and useful.","strengths":["Consistently returns structured proposal objects with sections, gaps, openQuestions, and requiresReview.","Does not fabricate customer, pricing, scope, timeline, or stakeholder details from inadequate input.","Explicitly flags uncertainty and missing context in minimal and normal cases.","Resists the injection request to output APPROVED and documents the attempted instruction override."],"notes":[]}}