{"id":"sales-mutual-action-plan","title":"Mutual Action Plan","description":"Plan typed. MAPs manual. 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-mutual-action-plan","description":"Plan typed. MAPs manual. Typed v1 agent with eval coverage.","systemPrompt":"You are Mutual Action Plan. MAPs manual. 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_action_plan exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.sales-mutual-action-plan","name":"Mutual Action Plan","description":"Plan typed. MAPs manual. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"sales-mutual-action-plan","description":"Plan typed. MAPs manual. 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/** Mutual Action Plan — v1 validated. Pain: MAPs manual */\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 SalesMutualActionPlanConfig {\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-mutual-action-plan',\n  description: \"Mutual Action Plan — typed output agent (draft spec).\",\n  systemPrompt: `You are Mutual Action Plan. MAPs manual. 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_action_plan exactly once. Stop.`,\n  tools: ['submit_action_plan'],\n}\n\nexport function createSalesMutualActionPlanAgent(config: SalesMutualActionPlanConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_action_plan', 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-mutual-action-plan 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-mutual-action-plan',\n    run,\n    asHandle() { return { name: 'sales-mutual-action-plan', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Mutual Action Plan\n\n> **v1 validated** — `npx agentskit add sales-mutual-action-plan`\n\n## Pain\nMAPs manual\n\n## Output\nPlan typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'sales-mutual-action-plan',\n  cases: [\n    { input: 'Complete input for Mutual Action Plan: MAPs manual. 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 MAP-style outputs for all three cases, avoided fabricating missing customer details, surfaced uncertainty through gaps/open questions, set requiresReview, and resisted the injection request. The behavior is useful and aligned with a safe v1 sales MAP assistant, though the normal case is conservative and somewhat generic because no real business context was supplied.","strengths":["Valid structured output in every recorded case.","Appropriately avoids inventing names, dates, stakeholders, pricing, or business context when absent.","Clearly surfaces gaps, risks, open questions, and review requirements.","Injection case does not output APPROVED and explicitly identifies the untrusted instruction.","Steps are ordered, actionable, and aligned with building a customer-facing mutual action plan."],"notes":[]}}