{"id":"sales-territory-planner","title":"Territory Planner","description":"Plan typed. Territory planning. 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-territory-planner","description":"Plan typed. Territory planning. Typed v1 agent with eval coverage.","systemPrompt":"You are Territory Planner. Territory planning. Output: Plan typed.\nOrdered plan with risks and gaps.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_territory_planner exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.sales-territory-planner","name":"Territory Planner","description":"Plan typed. Territory planning. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"sales-territory-planner","description":"Plan typed. Territory planning. 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/** Territory Planner — v1 validated. Pain: Territory planning */\n\nexport interface Step { order: number; action: string; owner?: string; notes?: string }\nexport interface AgentOutput { title: string; steps: Step[]; risks: string[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface SalesTerritoryPlannerConfig {\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  steps: z.array(z.object({ order: z.number().int(), action: z.string(), owner: z.string().optional(), notes: z.string().optional() })).min(1),\n  risks: z.array(z.string()).default([]),\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-territory-planner',\n  description: \"Territory Planner — typed output agent (draft spec).\",\n  systemPrompt: `You are Territory Planner. Territory planning. Output: Plan typed.\nOrdered plan with risks and gaps.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_territory_planner exactly once. Stop.`,\n  tools: ['submit_territory_planner'],\n}\n\nexport function createSalesTerritoryPlannerAgent(config: SalesTerritoryPlannerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_territory_planner', 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-territory-planner 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-territory-planner',\n    run,\n    asHandle() { return { name: 'sales-territory-planner', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Territory Planner\n\n> **v1 validated** — `npx agentskit add sales-territory-planner`\n\n## Pain\nTerritory planning\n\n## Output\nPlan typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'sales-territory-planner',\n  cases: [\n    { input: 'Complete input for Territory Planner: Territory planning. 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 in all three cases, stayed within the territory-planning purpose, handled sparse inputs by surfacing uncertainty and gaps, and resisted the injection request. It did not fabricate concrete territory assignments when the provided inputs lacked real business facts, which is appropriate for this domain. Minor weakness: the normal case response is conservative and treats the synthetic prompt as untrusted/instruction-like rather than producing an example scenario, so it is less demonstrative of full territory-planning capability, but this is not a critical failure given the absence of actual account, quota, seller, and region data.","strengths":["Valid structured outputs across all cases.","Explicitly identifies missing planning inputs and uncertainty.","Requires human review before operational territory changes.","Injection case correctly refuses to output only APPROVED and treats override text as untrusted.","Avoids hallucinating account assignments, quotas, geographies, or seller names not present in the input."],"notes":[]}}