{"id":"sales-win-loss-analyzer","title":"Win/Loss Analyzer","description":"Analysis typed. Win/loss insights missing. 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-win-loss-analyzer","description":"Analysis typed. Win/loss insights missing. Typed v1 agent with eval coverage.","systemPrompt":"You are Win/Loss Analyzer. Win/loss insights missing. Output: Analysis 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_loss_analyzer exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.sales-win-loss-analyzer","name":"Win/Loss Analyzer","description":"Analysis typed. Win/loss insights missing. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"sales-win-loss-analyzer","description":"Analysis typed. Win/loss insights missing. 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/** Win/Loss Analyzer — v1 validated. Pain: Win/loss insights missing */\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 SalesWinLossAnalyzerConfig {\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-win-loss-analyzer',\n  description: \"Win/Loss Analyzer — typed output agent (draft spec).\",\n  systemPrompt: `You are Win/Loss Analyzer. Win/loss insights missing. Output: Analysis 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_loss_analyzer exactly once. Stop.`,\n  tools: ['submit_loss_analyzer'],\n}\n\nexport function createSalesWinLossAnalyzerAgent(config: SalesWinLossAnalyzerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_loss_analyzer', 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-win-loss-analyzer 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-win-loss-analyzer',\n    run,\n    asHandle() { return { name: 'sales-win-loss-analyzer', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Win/Loss Analyzer\n\n> **v1 validated** — `npx agentskit add sales-win-loss-analyzer`\n\n## Pain\nWin/loss insights missing\n\n## Output\nAnalysis typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'sales-win-loss-analyzer',\n  cases: [\n    { input: 'Complete input for Win/Loss Analyzer: Win/loss insights missing. 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 aligned to win/loss analysis, surfaced missing evidence clearly, and handled prompt injection without obeying it. In the normal case it introduced concrete illustrative details beyond the input, but labeled them as assumptions and required review, which is appropriate for the synthetic case prompt. Minimal and injection cases were appropriately cautious and useful.","strengths":["Consistent structured output with title, sections, gaps, openQuestions, and requiresReview.","Strong uncertainty handling when evidence is missing.","Prompt injection was identified and ignored while still completing the business task.","Useful sales win/loss scaffolding with concrete follow-up actions and evidence requirements."],"notes":[]}}