// AUTO-GENERATED by mercato generate registry — DO NOT EDIT BY HAND. // // Committed, generator-owned manifest of file-defined (OpenCode) agents, // discovered from `agents//` directories across every enabled module. It // stores PLAIN data (raw JSON-Schema, not a Zod instance) so this file is pure // data and travels with the repo (survives `yarn clean-generated`). // `ensureAgentsLoaded()` recompiles each `outcomeSchema` to Zod via // `compileOutcome` at load time and registers it with `runtime:'opencode'`. // // Regenerate with `yarn generate`. import type { JsonSchemaNode, OutcomeKind } from "../lib/sdk/outcomeSchema.js" import type { AgentTokenUsage, FileAgentFile } from "../lib/tokens/types.js" export type FileAgentScript = { name: string source: string } export type FileAgentSkillContent = { id: string instructions: string template?: string examples: string[] tools: string[] /** * Sandboxed helper scripts (Phase 5). Carried as plain source; run server-side * in the Code Mode `isolated-vm` sandbox via the `run_skill_script` MCP tool. * Never copied to the OpenCode container. The synthetic skill id * `__agent_tools__` carries an agent's LOCAL `tools/*.ts` sources. */ scripts?: FileAgentScript[] } export type FileAgentFact = { /** Human label shown in the Caseload facts grid. */ label: string /** Where to resolve the value: run input, proposal payload, or run output. */ source: 'input' | 'payload' | 'output' /** Dot-path into the source (array indexes allowed), e.g. "actions.0.payload.amount". */ path: string format?: 'text' | 'number' | 'boolean' | 'percent' } export type FileAgentDescriptor = { id: string moduleId: string label: string description: string instructions: string resultKind: OutcomeKind outcomeSchema?: JsonSchemaNode tools: string[] skills: string[] subAgents: string[] openCodeAgentName: string skillsContent?: FileAgentSkillContent[] /** * Baked token-usage estimate of the agent's construction files (AGENT.md, * OUTCOME.md, skills, tools, sub-agents), counted with the shared * `o200k_base` tokenizer. Surfaced on the Agent detail page and the * `agent_orchestrator token-usage` CLI. An estimate, not an exact count. */ tokenUsage?: AgentTokenUsage /** * Baked raw content of every construction file (AGENT.md, OUTCOME.md, skills, * tools, sub-agents, and auxiliary SAMPLE.json/FACTS.json), for the read-only * Files tab. Each carries its `o200k_base` token count; paths are relative to * the agent root (sub-agent files prefixed `sub-agents//`). Baked so the * runtime never reads agent dirs from disk. */ sourceFiles?: FileAgentFile[] /** * Nested descriptors for this agent's sub-agents (Phase 4). Each is an * research-kind, non-delegating file agent registered individually (depth cap = * 1). Absent for agents without sub-agents and for sub-agents themselves. */ subAgentDescriptors?: FileAgentDescriptor[] maxSteps?: number provider?: string model?: string /** * Optional example `input` for the Playground "Insert sample" button, read * from `agents//SAMPLE.json`. Any JSON value the agent accepts as input. */ sampleInput?: unknown /** * Optional fact declarations for the Caseload decision panel, read from * `agents//FACTS.json`. Each maps a labelled dot-path into the run * input / proposal payload / run output. */ facts?: FileAgentFact[] } export const fileAgentDescriptors: FileAgentDescriptor[] = [ { id: "deals.company_researcher", moduleId: "agent_examples", label: "Company researcher (file-defined)", description: "Research a company on the public web to qualify it as a sales prospect — size, revenue, funding, and deal fit.", instructions: "You research a company on the public web to help a seller decide whether it is a good, well-paying prospect worth pursuing. You are a propose-only researcher: you gather and summarize public information; you never take an action or mutate any record.\n\nThe input is `{ companyName, companyDomain?, websiteUrl?, industry?, currentAnnualRevenue? }`. Only `companyName` is guaranteed; treat the rest as hints that narrow your searches when present.\n\nWork in this order:\n\n1. Delegate the size-and-money question to the `deals.revenue_estimator` sub-agent (pass it `{ companyName, companyDomain }`). Use its returned `revenueBand`, `employeeEstimate`, `fundingStage`, and `signals` as your starting picture of how large and how well-funded the company is.\n2. Run several focused `open-mercato_agent_orchestrator_web_search` calls — one per signal you still need, not one broad query. Good signals for a paying-prospect assessment: recent funding or profitability, headcount and hiring momentum, notable/enterprise customers, pricing or budget indicators, and any financial-distress red flags (layoffs, missed payments, insolvency).\n3. Pass `includeContent: true` on searches where you expect to need the page text — the tool reads the top results and returns their text inline, so a separate fetch per link is unnecessary. Reserve `open-mercato_agent_orchestrator_web_fetch` for a specific page `includeContent` did not cover.\n4. Apply the `deal_qualification` skill to weigh what you found. Feed the numeric/boolean signals you gathered into its `score` script (via `run_skill_script` with `skillId: \"deal_qualification\", scriptName: \"score\"`) to get a `dealFitScore` and `payingLikelihood`, then sanity-check the script's output against your judgement before reporting it.\n5. Report the assessment plus the concrete findings that back it, each tied to the source it came from.\n\nEach result carries a `confidence` score and the `sources` that surfaced it; prefer results several sources agree on. When the `diagnostics` block reports `degraded: true`, or every adapter came back `blocked` or `unavailable`, the search was thin for an infrastructural reason rather than because the company lacks coverage — do not read a weak signal into it.\n\nEvery finding MUST carry the `sourceUrl` it was drawn from. Do not state anything you cannot tie to a searched or fetched source. If the web tools return nothing useful, say so honestly in `summary`, return an empty `findings` array, set `companySizeBucket` to `unknown` and `payingLikelihood` to `low` — never invent sources or numbers.", resultKind: "research", outcomeSchema: {"type":"object","additionalProperties":false,"required":["companyName","assessment","findings","summary"],"properties":{"companyName":{"type":"string","minLength":1},"assessment":{"type":"object","additionalProperties":false,"required":["revenueBand","companySizeBucket","dealFitScore","payingLikelihood","recommendation"],"properties":{"revenueBand":{"type":"string","minLength":1},"annualRevenueEstimateUsd":{"type":"number","nullable":true,"minimum":0},"employeeEstimate":{"type":"string","nullable":true},"companySizeBucket":{"type":"string","enum":["micro","small","mid_market","enterprise","unknown"]},"fundingStage":{"type":"string","nullable":true},"dealFitScore":{"type":"integer","minimum":0,"maximum":100},"payingLikelihood":{"type":"string","enum":["low","medium","high"]},"recommendation":{"type":"string","minLength":1}}},"findings":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["signal","detail","sourceUrl"],"properties":{"signal":{"type":"string","minLength":1},"detail":{"type":"string","minLength":1},"sourceUrl":{"type":"string","minLength":1}}}},"summary":{"type":"string","minLength":1}}}, tools: ["agent_orchestrator.web_search","agent_orchestrator.web_fetch"], skills: ["deal_qualification"], subAgents: ["deals.revenue_estimator"], openCodeAgentName: "deals_company_researcher", skillsContent: [{"id":"deal_qualification","instructions":"Use this playbook to turn what you found on the public web into a `dealFitScore` (0–100), a `payingLikelihood` (`low`/`medium`/`high`), and a short recommendation.\n\nSignals that make a company a GOOD paying prospect (each is positive):\n\n- **Revenue / profitability** — meaningful and growing revenue, or a public statement of profitability.\n- **Funding** — a recent raise, a well-known investor, or a public listing (durable ability to pay).\n- **Headcount momentum** — growing team, open roles, or a hiring spree (budget and expansion).\n- **Enterprise customers** — recognizable logos or case studies (they buy, and they pay real money).\n- **Budget / pricing fit** — evidence they already pay for comparable tools or services.\n\nRed flags that lower the score (each is negative):\n\n- Layoffs, hiring freezes, or shrinking headcount.\n- Missed payments, lawsuits over unpaid bills, insolvency, or a poor payment reputation.\n- A long silence — no verifiable public activity for a year or more.\n- No sign of budget: tiny team with no revenue, funding, or paying customers.\n\nTurn the signals into a score with the `score` script (invoke it via `run_skill_script` with\n`skillId: \"deal_qualification\", scriptName: \"score\"`). It takes 0..1 signal strengths and returns a\n`dealFitScore` (0–100), `payingLikelihood`, and a `rationale`. Feed it your honest read of each signal:\n\n- `revenueStrength` — how strong the revenue/profitability evidence is (0 = none, 1 = large and growing).\n- `fundingStrength` — funding / public-company strength (0 = none, 1 = well-funded or public).\n- `growthStrength` — headcount / hiring / customer momentum (0 = shrinking, 1 = clearly scaling).\n- `riskLevel` — severity of red flags (0 = none, 1 = severe distress).\n\nMap the size you estimated to `companySizeBucket`: roughly `micro` (<10), `small` (10–50),\n`mid_market` (50–1000), `enterprise` (>1000) employees; use `unknown` when you cannot ground it.\n\nAlways sanity-check the script's number against your own judgement, and justify the score in\n`recommendation` with the specific signals you relied on. When evidence is thin, prefer a conservative\nscore and a `low` or `medium` `payingLikelihood` rather than guessing high.","template":"Company: \nSize: ( employees)\nRevenue: \nFunding: \nDeal-fit score: <0..100>\nPaying likelihood: \nRecommendation: \nKey signals:\n- — ()","examples":["Example: a well-funded scale-up\n\nFindings gathered on the public web:\n- Raised a $150M Series D six months ago from a top-tier investor (funding page + press release).\n- Headcount grew from ~400 to ~700 in a year; dozens of open roles (careers page + jobs board).\n- Publishes enterprise case studies with recognizable logos (customers page).\n- No layoffs, lawsuits, or distress signals found.\n\nSignal strengths fed to the score script:\n`{ revenueStrength: 0.7, fundingStrength: 0.95, growthStrength: 0.9, riskLevel: 0.05 }`\n\nScript result: `dealFitScore ≈ 80`, `payingLikelihood: \"high\"`.\n\nAssessment:\n- companySizeBucket: `mid_market` (~700 employees)\n- revenueBand: \"$80–120M ARR (est.)\"\n- fundingStage: \"Series D\"\n- recommendation: \"Strong, well-funded prospect that is actively scaling and buys enterprise tooling — pursue with a tailored outreach referencing their recent raise.\""],"tools":[],"scripts":[{"name":"score","source":"// Sandboxed skill helper. Pure function of its args — no fs/net/imports.\n// Invoked by the agent via `agent_orchestrator.run_skill_script`\n// ({ skillId: \"deal_qualification\", scriptName: \"score\",\n// args: { revenueStrength, fundingStrength, growthStrength, riskLevel } }).\n// Turns four 0..1 signal strengths into a 0..100 deal-fit score and a paying-likelihood\n// bucket. It can compute, never mutate — propose-only holds in the sandbox.\n\nfunction run(args) {\n const revenue = clamp01(numberOr(args && args.revenueStrength, 0))\n const funding = clamp01(numberOr(args && args.fundingStrength, 0))\n const growth = clamp01(numberOr(args && args.growthStrength, 0))\n const risk = clamp01(numberOr(args && args.riskLevel, 0))\n\n const upside = 0.4 * revenue + 0.35 * funding + 0.25 * growth\n const fit = clamp01(upside * (1 - 0.6 * risk))\n const dealFitScore = Math.round(fit * 100)\n\n const payingLikelihood = dealFitScore >= 66 ? 'high' : dealFitScore >= 33 ? 'medium' : 'low'\n const rationale =\n `fit ${dealFitScore}/100 from revenue=${round2(revenue)}, funding=${round2(funding)}, ` +\n `growth=${round2(growth)}, risk=${round2(risk)}`\n\n return { dealFitScore, payingLikelihood, rationale }\n}\n\nfunction numberOr(value, fallback) {\n return typeof value === 'number' && Number.isFinite(value) ? value : fallback\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value))\n}\n\nfunction round2(value) {\n return Math.round(value * 100) / 100\n}\n"}]}], tokenUsage: {"total":3308,"self":2690,"agent":652,"outcome":760,"skills":[{"id":"deal_qualification","tokens":1278,"files":[{"path":"skills/deal_qualification/SKILL.md","tokens":575},{"path":"skills/deal_qualification/TEMPLATE.md","tokens":81},{"path":"skills/deal_qualification/examples/well-funded-scaleup.md","tokens":219},{"path":"skills/deal_qualification/scripts/score.ts","tokens":403}]}],"tools":[],"subAgents":[{"id":"revenue_estimator","tokens":618}]}, sourceFiles: [{"path":"AGENT.md","content":"---\nid: deals.company_researcher\nlabel: Company researcher (file-defined)\ndescription: Research a company on the public web to qualify it as a sales prospect — size, revenue, funding, and deal fit.\ntools: [agent_orchestrator.web_search, agent_orchestrator.web_fetch]\nskills: [deal_qualification]\nsubAgents: [deals.revenue_estimator]\nmaxSteps: 14\n---\nYou research a company on the public web to help a seller decide whether it is a good, well-paying prospect worth pursuing. You are a propose-only researcher: you gather and summarize public information; you never take an action or mutate any record.\n\nThe input is `{ companyName, companyDomain?, websiteUrl?, industry?, currentAnnualRevenue? }`. Only `companyName` is guaranteed; treat the rest as hints that narrow your searches when present.\n\nWork in this order:\n\n1. Delegate the size-and-money question to the `deals.revenue_estimator` sub-agent (pass it `{ companyName, companyDomain }`). Use its returned `revenueBand`, `employeeEstimate`, `fundingStage`, and `signals` as your starting picture of how large and how well-funded the company is.\n2. Run several focused `open-mercato_agent_orchestrator_web_search` calls — one per signal you still need, not one broad query. Good signals for a paying-prospect assessment: recent funding or profitability, headcount and hiring momentum, notable/enterprise customers, pricing or budget indicators, and any financial-distress red flags (layoffs, missed payments, insolvency).\n3. Pass `includeContent: true` on searches where you expect to need the page text — the tool reads the top results and returns their text inline, so a separate fetch per link is unnecessary. Reserve `open-mercato_agent_orchestrator_web_fetch` for a specific page `includeContent` did not cover.\n4. Apply the `deal_qualification` skill to weigh what you found. Feed the numeric/boolean signals you gathered into its `score` script (via `run_skill_script` with `skillId: \"deal_qualification\", scriptName: \"score\"`) to get a `dealFitScore` and `payingLikelihood`, then sanity-check the script's output against your judgement before reporting it.\n5. Report the assessment plus the concrete findings that back it, each tied to the source it came from.\n\nEach result carries a `confidence` score and the `sources` that surfaced it; prefer results several sources agree on. When the `diagnostics` block reports `degraded: true`, or every adapter came back `blocked` or `unavailable`, the search was thin for an infrastructural reason rather than because the company lacks coverage — do not read a weak signal into it.\n\nEvery finding MUST carry the `sourceUrl` it was drawn from. Do not state anything you cannot tie to a searched or fetched source. If the web tools return nothing useful, say so honestly in `summary`, return an empty `findings` array, set `companySizeBucket` to `unknown` and `payingLikelihood` to `low` — never invent sources or numbers.\n","tokens":652,"inContext":true},{"path":"OUTCOME.md","content":"---\nkind: research\n---\n```json\n{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"companyName\", \"assessment\", \"findings\", \"summary\"],\n \"properties\": {\n \"companyName\": { \"type\": \"string\", \"minLength\": 1 },\n \"assessment\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"revenueBand\", \"companySizeBucket\", \"dealFitScore\", \"payingLikelihood\", \"recommendation\"],\n \"properties\": {\n \"revenueBand\": { \"type\": \"string\", \"minLength\": 1 },\n \"annualRevenueEstimateUsd\": { \"type\": \"number\", \"nullable\": true, \"minimum\": 0 },\n \"employeeEstimate\": { \"type\": \"string\", \"nullable\": true },\n \"companySizeBucket\": { \"type\": \"string\", \"enum\": [\"micro\", \"small\", \"mid_market\", \"enterprise\", \"unknown\"] },\n \"fundingStage\": { \"type\": \"string\", \"nullable\": true },\n \"dealFitScore\": { \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100 },\n \"payingLikelihood\": { \"type\": \"string\", \"enum\": [\"low\", \"medium\", \"high\"] },\n \"recommendation\": { \"type\": \"string\", \"minLength\": 1 }\n }\n },\n \"findings\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"signal\", \"detail\", \"sourceUrl\"],\n \"properties\": {\n \"signal\": { \"type\": \"string\", \"minLength\": 1 },\n \"detail\": { \"type\": \"string\", \"minLength\": 1 },\n \"sourceUrl\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n },\n \"summary\": { \"type\": \"string\", \"minLength\": 1 }\n }\n}\n```\n\nFill `assessment` with your qualified read of the company as a paying prospect:\n\n- `revenueBand` — a short human-readable band, e.g. `\"$40–60M ARR (est.)\"` or `\"Unknown\"`.\n- `annualRevenueEstimateUsd` — a single best-guess number in USD, or `null` when you cannot ground one.\n- `employeeEstimate` — a short range like `\"200–500\"`, or `null`.\n- `companySizeBucket` — one of `micro`, `small`, `mid_market`, `enterprise`, or `unknown`.\n- `fundingStage` — e.g. `\"Series C\"`, `\"Bootstrapped\"`, `\"Public\"`, or `null`.\n- `dealFitScore` — an integer 0–100 (higher = better prospect), consistent with the `deal_qualification` skill.\n- `payingLikelihood` — `low`, `medium`, or `high`: how likely this company can and will pay well.\n- `recommendation` — one or two sentences a seller can act on (pursue, qualify further, or deprioritize, and why).\n\nList every concrete signal in `findings` with a short `signal` label, a one-sentence `detail`, and the `sourceUrl` you drew it from. Return an empty `findings` array (and say so in `summary`) when nothing citable was found. Pass this whole object as the `outcome` argument of the submit_outcome tool (an object, not a string).\n","tokens":760,"inContext":true},{"path":"SAMPLE.json","content":"{\n \"companyName\": \"Vercel\",\n \"companyDomain\": \"vercel.com\",\n \"websiteUrl\": \"https://vercel.com\",\n \"industry\": \"Developer tools / Cloud platform\",\n \"currentAnnualRevenue\": null\n}\n","tokens":53,"inContext":false},{"path":"skills/deal_qualification/SKILL.md","content":"---\nid: deal_qualification\nlabel: Deal qualification playbook\ndescription: How to judge whether a company is a good, well-paying sales prospect from public web signals.\ntools: []\n---\nUse this playbook to turn what you found on the public web into a `dealFitScore` (0–100), a `payingLikelihood` (`low`/`medium`/`high`), and a short recommendation.\n\nSignals that make a company a GOOD paying prospect (each is positive):\n\n- **Revenue / profitability** — meaningful and growing revenue, or a public statement of profitability.\n- **Funding** — a recent raise, a well-known investor, or a public listing (durable ability to pay).\n- **Headcount momentum** — growing team, open roles, or a hiring spree (budget and expansion).\n- **Enterprise customers** — recognizable logos or case studies (they buy, and they pay real money).\n- **Budget / pricing fit** — evidence they already pay for comparable tools or services.\n\nRed flags that lower the score (each is negative):\n\n- Layoffs, hiring freezes, or shrinking headcount.\n- Missed payments, lawsuits over unpaid bills, insolvency, or a poor payment reputation.\n- A long silence — no verifiable public activity for a year or more.\n- No sign of budget: tiny team with no revenue, funding, or paying customers.\n\nTurn the signals into a score with the `score` script (invoke it via `run_skill_script` with\n`skillId: \"deal_qualification\", scriptName: \"score\"`). It takes 0..1 signal strengths and returns a\n`dealFitScore` (0–100), `payingLikelihood`, and a `rationale`. Feed it your honest read of each signal:\n\n- `revenueStrength` — how strong the revenue/profitability evidence is (0 = none, 1 = large and growing).\n- `fundingStrength` — funding / public-company strength (0 = none, 1 = well-funded or public).\n- `growthStrength` — headcount / hiring / customer momentum (0 = shrinking, 1 = clearly scaling).\n- `riskLevel` — severity of red flags (0 = none, 1 = severe distress).\n\nMap the size you estimated to `companySizeBucket`: roughly `micro` (<10), `small` (10–50),\n`mid_market` (50–1000), `enterprise` (>1000) employees; use `unknown` when you cannot ground it.\n\nAlways sanity-check the script's number against your own judgement, and justify the score in\n`recommendation` with the specific signals you relied on. When evidence is thin, prefer a conservative\nscore and a `low` or `medium` `payingLikelihood` rather than guessing high.\n","tokens":575,"inContext":true},{"path":"skills/deal_qualification/TEMPLATE.md","content":"Company: \nSize: ( employees)\nRevenue: \nFunding: \nDeal-fit score: <0..100>\nPaying likelihood: \nRecommendation: \nKey signals:\n- — ()\n","tokens":81,"inContext":true},{"path":"skills/deal_qualification/examples/well-funded-scaleup.md","content":"Example: a well-funded scale-up\n\nFindings gathered on the public web:\n- Raised a $150M Series D six months ago from a top-tier investor (funding page + press release).\n- Headcount grew from ~400 to ~700 in a year; dozens of open roles (careers page + jobs board).\n- Publishes enterprise case studies with recognizable logos (customers page).\n- No layoffs, lawsuits, or distress signals found.\n\nSignal strengths fed to the score script:\n`{ revenueStrength: 0.7, fundingStrength: 0.95, growthStrength: 0.9, riskLevel: 0.05 }`\n\nScript result: `dealFitScore ≈ 80`, `payingLikelihood: \"high\"`.\n\nAssessment:\n- companySizeBucket: `mid_market` (~700 employees)\n- revenueBand: \"$80–120M ARR (est.)\"\n- fundingStage: \"Series D\"\n- recommendation: \"Strong, well-funded prospect that is actively scaling and buys enterprise tooling — pursue with a tailored outreach referencing their recent raise.\"\n","tokens":219,"inContext":true},{"path":"skills/deal_qualification/scripts/score.ts","content":"// Sandboxed skill helper. Pure function of its args — no fs/net/imports.\n// Invoked by the agent via `agent_orchestrator.run_skill_script`\n// ({ skillId: \"deal_qualification\", scriptName: \"score\",\n// args: { revenueStrength, fundingStrength, growthStrength, riskLevel } }).\n// Turns four 0..1 signal strengths into a 0..100 deal-fit score and a paying-likelihood\n// bucket. It can compute, never mutate — propose-only holds in the sandbox.\n\nfunction run(args) {\n const revenue = clamp01(numberOr(args && args.revenueStrength, 0))\n const funding = clamp01(numberOr(args && args.fundingStrength, 0))\n const growth = clamp01(numberOr(args && args.growthStrength, 0))\n const risk = clamp01(numberOr(args && args.riskLevel, 0))\n\n const upside = 0.4 * revenue + 0.35 * funding + 0.25 * growth\n const fit = clamp01(upside * (1 - 0.6 * risk))\n const dealFitScore = Math.round(fit * 100)\n\n const payingLikelihood = dealFitScore >= 66 ? 'high' : dealFitScore >= 33 ? 'medium' : 'low'\n const rationale =\n `fit ${dealFitScore}/100 from revenue=${round2(revenue)}, funding=${round2(funding)}, ` +\n `growth=${round2(growth)}, risk=${round2(risk)}`\n\n return { dealFitScore, payingLikelihood, rationale }\n}\n\nfunction numberOr(value, fallback) {\n return typeof value === 'number' && Number.isFinite(value) ? value : fallback\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value))\n}\n\nfunction round2(value) {\n return Math.round(value * 100) / 100\n}\n","tokens":403,"inContext":true},{"path":"sub-agents/revenue_estimator/AGENT.md","content":"---\nid: deals.revenue_estimator\nlabel: Company revenue estimator (sub-agent)\ndescription: Estimate a company's revenue, headcount, and funding stage from public web signals.\ntools: [agent_orchestrator.web_search, agent_orchestrator.web_fetch]\nmaxSteps: 8\n---\nYou are a read-only sub-agent that estimates how large and how well-funded a company is, using only the public web.\n\nThe input is `{ companyName, companyDomain? }`.\n\nRun focused `open-mercato_agent_orchestrator_web_search` calls for the specific numbers you need — annual revenue or ARR, employee/headcount, and funding rounds or public-company status. Pass `includeContent: true` so the tool reads the top results and returns their text inline; that is usually enough to confirm a figure without a separate `open-mercato_agent_orchestrator_web_fetch`. Prefer primary or reputable sources (the company's own site, funding databases, credible news) over guesses.\n\nYou only inform the primary agent — you never propose actions and never assess deal fit. Report a concise, structured estimate. Every signal you list MUST carry the `sourceUrl` it came from; leave a field `null` (and say nothing you cannot cite) rather than inventing a number. If the web tools return nothing useful — including when the `diagnostics` block shows every adapter `blocked` or `unavailable` — return an empty `signals` array and set the estimate fields to `null`.\n","tokens":303,"inContext":true},{"path":"sub-agents/revenue_estimator/OUTCOME.md","content":"---\nkind: research\n---\n```json\n{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"revenueBand\", \"signals\"],\n \"properties\": {\n \"revenueBand\": { \"type\": \"string\", \"minLength\": 1 },\n \"annualRevenueEstimateUsd\": { \"type\": \"number\", \"nullable\": true, \"minimum\": 0 },\n \"employeeEstimate\": { \"type\": \"string\", \"nullable\": true },\n \"fundingStage\": { \"type\": \"string\", \"nullable\": true },\n \"signals\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"detail\", \"sourceUrl\"],\n \"properties\": {\n \"detail\": { \"type\": \"string\", \"minLength\": 1 },\n \"sourceUrl\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n }\n }\n}\n```\n\nReport `revenueBand` as a short human-readable band, e.g. `\"$40–60M ARR (est.)\"`, or `\"Unknown\"` when\nyou found nothing citable. `annualRevenueEstimateUsd`, `employeeEstimate`, and `fundingStage` are\noptional single best guesses — use `null` when you cannot ground them. `signals` is the list of\nconcrete observations you relied on, each with the `sourceUrl` it came from.\n","tokens":315,"inContext":true},{"path":"sub-agents/revenue_estimator/SAMPLE.json","content":"{\n \"companyName\": \"Vercel\",\n \"companyDomain\": \"vercel.com\"\n}\n","tokens":22,"inContext":false}], subAgentDescriptors: [ { id: "deals.revenue_estimator", moduleId: "", label: "Company revenue estimator (sub-agent)", description: "Estimate a company's revenue, headcount, and funding stage from public web signals.", instructions: "You are a read-only sub-agent that estimates how large and how well-funded a company is, using only the public web.\n\nThe input is `{ companyName, companyDomain? }`.\n\nRun focused `open-mercato_agent_orchestrator_web_search` calls for the specific numbers you need — annual revenue or ARR, employee/headcount, and funding rounds or public-company status. Pass `includeContent: true` so the tool reads the top results and returns their text inline; that is usually enough to confirm a figure without a separate `open-mercato_agent_orchestrator_web_fetch`. Prefer primary or reputable sources (the company's own site, funding databases, credible news) over guesses.\n\nYou only inform the primary agent — you never propose actions and never assess deal fit. Report a concise, structured estimate. Every signal you list MUST carry the `sourceUrl` it came from; leave a field `null` (and say nothing you cannot cite) rather than inventing a number. If the web tools return nothing useful — including when the `diagnostics` block shows every adapter `blocked` or `unavailable` — return an empty `signals` array and set the estimate fields to `null`.", resultKind: "research", outcomeSchema: {"type":"object","additionalProperties":false,"required":["revenueBand","signals"],"properties":{"revenueBand":{"type":"string","minLength":1},"annualRevenueEstimateUsd":{"type":"number","nullable":true,"minimum":0},"employeeEstimate":{"type":"string","nullable":true},"fundingStage":{"type":"string","nullable":true},"signals":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["detail","sourceUrl"],"properties":{"detail":{"type":"string","minLength":1},"sourceUrl":{"type":"string","minLength":1}}}}}}, tools: ["agent_orchestrator.web_search","agent_orchestrator.web_fetch"], skills: [], subAgents: [], openCodeAgentName: "deals_revenue_estimator", skillsContent: [], tokenUsage: {"total":618,"self":618,"agent":303,"outcome":315,"skills":[],"tools":[],"subAgents":[]}, sourceFiles: [{"path":"AGENT.md","content":"---\nid: deals.revenue_estimator\nlabel: Company revenue estimator (sub-agent)\ndescription: Estimate a company's revenue, headcount, and funding stage from public web signals.\ntools: [agent_orchestrator.web_search, agent_orchestrator.web_fetch]\nmaxSteps: 8\n---\nYou are a read-only sub-agent that estimates how large and how well-funded a company is, using only the public web.\n\nThe input is `{ companyName, companyDomain? }`.\n\nRun focused `open-mercato_agent_orchestrator_web_search` calls for the specific numbers you need — annual revenue or ARR, employee/headcount, and funding rounds or public-company status. Pass `includeContent: true` so the tool reads the top results and returns their text inline; that is usually enough to confirm a figure without a separate `open-mercato_agent_orchestrator_web_fetch`. Prefer primary or reputable sources (the company's own site, funding databases, credible news) over guesses.\n\nYou only inform the primary agent — you never propose actions and never assess deal fit. Report a concise, structured estimate. Every signal you list MUST carry the `sourceUrl` it came from; leave a field `null` (and say nothing you cannot cite) rather than inventing a number. If the web tools return nothing useful — including when the `diagnostics` block shows every adapter `blocked` or `unavailable` — return an empty `signals` array and set the estimate fields to `null`.\n","tokens":303,"inContext":true},{"path":"OUTCOME.md","content":"---\nkind: research\n---\n```json\n{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"revenueBand\", \"signals\"],\n \"properties\": {\n \"revenueBand\": { \"type\": \"string\", \"minLength\": 1 },\n \"annualRevenueEstimateUsd\": { \"type\": \"number\", \"nullable\": true, \"minimum\": 0 },\n \"employeeEstimate\": { \"type\": \"string\", \"nullable\": true },\n \"fundingStage\": { \"type\": \"string\", \"nullable\": true },\n \"signals\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"detail\", \"sourceUrl\"],\n \"properties\": {\n \"detail\": { \"type\": \"string\", \"minLength\": 1 },\n \"sourceUrl\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n }\n }\n}\n```\n\nReport `revenueBand` as a short human-readable band, e.g. `\"$40–60M ARR (est.)\"`, or `\"Unknown\"` when\nyou found nothing citable. `annualRevenueEstimateUsd`, `employeeEstimate`, and `fundingStage` are\noptional single best guesses — use `null` when you cannot ground them. `signals` is the list of\nconcrete observations you relied on, each with the `sourceUrl` it came from.\n","tokens":315,"inContext":true},{"path":"SAMPLE.json","content":"{\n \"companyName\": \"Vercel\",\n \"companyDomain\": \"vercel.com\"\n}\n","tokens":22,"inContext":false}], maxSteps: 8, sampleInput: {"companyName":"Vercel","companyDomain":"vercel.com"}, }, ], maxSteps: 14, sampleInput: {"companyName":"Vercel","companyDomain":"vercel.com","websiteUrl":"https://vercel.com","industry":"Developer tools / Cloud platform","currentAnnualRevenue":null}, }, { id: "deals.health_check_file", moduleId: "agent_examples", label: "Deal health check (file-defined)", description: "Assess a sales deal's health and propose the next stage.", instructions: "You assess the health of a single sales deal and propose the most appropriate next stage.\n\nGiven the deal context provided as input, reason about momentum, risk signals, and where the deal sits in the pipeline. Decide on exactly one `set_stage` action that moves the deal to the stage you believe is correct.\n\nExpress your confidence as a number between 0 and 1 (1 = certain) and give a concise rationale that a sales manager could act on. Be decisive but honest about uncertainty: a low confidence is acceptable when the signal is weak.", resultKind: "proposal", outcomeSchema: {"type":"object","additionalProperties":false,"required":["actions","confidence","rationale"],"properties":{"actions":{"type":"array","minItems":1,"items":{"type":"object","additionalProperties":false,"required":["type","payload"],"properties":{"type":{"const":"set_stage"},"payload":{"type":"object","additionalProperties":false,"required":["stage"],"properties":{"stage":{"type":"string","minLength":1}}}}}},"confidence":{"type":"number","minimum":0,"maximum":1},"rationale":{"type":"string","minLength":1}}}, tools: [], skills: ["stage_playbook"], subAgents: ["deals.activity_scan"], openCodeAgentName: "deals_health_check_file", skillsContent: [{"id":"stage_playbook","instructions":"Use this playbook to pick the single most appropriate next stage for a deal.\n\nPipeline stages, in order:\n\n1. `lead` — initial interest, no qualification yet.\n2. `qualified` — budget, authority, need, and timeline (BANT) confirmed.\n3. `proposal` — a quote or proposal has been sent.\n4. `negotiation` — terms are actively being discussed.\n5. `won` — the deal is closed and signed.\n6. `lost` — the deal is dead; record the reason.\n\nDecision rules:\n\n- Advance one stage at a time unless a strong signal justifies a jump.\n- Strong forward signals: a signed document, a scheduled close date, an\n explicit verbal commitment, or procurement engagement.\n- Risk signals that hold a deal back: no reply for two or more weeks, the\n champion leaving, or repeated reschedules.\n- When momentum is unclear, prefer the conservative stage and lower your\n confidence rather than guessing high.\n\nAlways justify the chosen stage in the rationale with the specific signal you\nrelied on.","template":"Recommended next stage: \nConfidence: <0..1>\nPrimary signal: \nRationale: ","examples":["Deal: Acme renewal, currently in `proposal`. The buyer replied yesterday asking\nto discuss discount tiers and contract length, and looped in their procurement\nlead.\n\nRecommended next stage: negotiation\nConfidence: 0.8\nPrimary signal: procurement engaged and terms (discount, contract length) are\nactively under discussion.\nRationale: an active terms discussion with procurement involved is a strong\nforward signal; advance one stage from proposal to negotiation."],"tools":[],"scripts":[{"name":"score","source":"// Sandboxed skill helper (Phase 5). Pure function of its args — no fs/net/imports.\n// Invoked by the agent via `agent_orchestrator.run_skill_script`\n// ({ skillId: \"stage_playbook\", scriptName: \"score\", args: { momentum, risk } }).\n// Returns a 0..1 health score from two 0..1 signals; the agent folds it into its\n// confidence. It can compute, never mutate — propose-only holds in the sandbox.\n\nfunction run(args) {\n const momentum = clamp01(numberOr(args && args.momentum, 0.5))\n const risk = clamp01(numberOr(args && args.risk, 0.5))\n const score = clamp01(0.6 * momentum + 0.4 * (1 - risk))\n return { score: Math.round(score * 100) / 100, momentum, risk }\n}\n\nfunction numberOr(value, fallback) {\n return typeof value === 'number' && Number.isFinite(value) ? value : fallback\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value))\n}\n"}]}], tokenUsage: {"total":1499,"self":1169,"agent":164,"outcome":375,"skills":[{"id":"stage_playbook","tokens":630,"files":[{"path":"skills/stage_playbook/SKILL.md","tokens":259},{"path":"skills/stage_playbook/TEMPLATE.md","tokens":41},{"path":"skills/stage_playbook/examples/advance-to-negotiation.md","tokens":91},{"path":"skills/stage_playbook/scripts/score.ts","tokens":239}]}],"tools":[],"subAgents":[{"id":"activity_scan","tokens":330}]}, sourceFiles: [{"path":"AGENT.md","content":"---\nid: deals.health_check_file\nlabel: Deal health check (file-defined)\ndescription: Assess a sales deal's health and propose the next stage.\nskills: [stage_playbook]\nsubAgents: [deals.activity_scan]\nmaxSteps: 12\n---\nYou assess the health of a single sales deal and propose the most appropriate next stage.\n\nGiven the deal context provided as input, reason about momentum, risk signals, and where the deal sits in the pipeline. Decide on exactly one `set_stage` action that moves the deal to the stage you believe is correct.\n\nExpress your confidence as a number between 0 and 1 (1 = certain) and give a concise rationale that a sales manager could act on. Be decisive but honest about uncertainty: a low confidence is acceptable when the signal is weak.\n","tokens":164,"inContext":true},{"path":"OUTCOME.md","content":"---\nkind: proposal\n---\n```json\n{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"actions\", \"confidence\", \"rationale\"],\n \"properties\": {\n \"actions\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"type\", \"payload\"],\n \"properties\": {\n \"type\": { \"const\": \"set_stage\" },\n \"payload\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"stage\"],\n \"properties\": {\n \"stage\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n }\n }\n },\n \"confidence\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 },\n \"rationale\": { \"type\": \"string\", \"minLength\": 1 }\n }\n}\n```\n\nUse this EXACT shape — `actions` is an ARRAY and the stage is nested under `payload`:\n\n```json\n{ \"actions\": [{ \"type\": \"set_stage\", \"payload\": { \"stage\": \"negotiation\" } }], \"confidence\": 0.8, \"rationale\": \"…\" }\n```\n\nCommon mistakes to avoid: do NOT use a singular `action` object, and do NOT put `stage` at the top of the action (it must be `payload.stage`). Return exactly one action. `confidence` must be between 0 and 1; `rationale` must be a non-empty, manager-readable justification. Pass this object as the `outcome` argument of the submit_outcome tool (an object, not a string).\n","tokens":375,"inContext":true},{"path":"SAMPLE.json","content":"{\n \"deal\": {\n \"id\": \"demo-deal-1\",\n \"name\": \"Acme Corp — Enterprise plan\",\n \"stage\": \"Proposal\",\n \"value\": 48000,\n \"probability\": 0.65,\n \"daysInStage\": 12,\n \"recentActivity\": \"Sent revised pricing; awaiting procurement sign-off.\"\n }\n}\n","tokens":81,"inContext":false},{"path":"skills/stage_playbook/SKILL.md","content":"---\nid: stage_playbook\nlabel: Deal stage playbook\ndescription: How to choose the next pipeline stage for a deal from its momentum and risk signals.\ntools: []\n---\nUse this playbook to pick the single most appropriate next stage for a deal.\n\nPipeline stages, in order:\n\n1. `lead` — initial interest, no qualification yet.\n2. `qualified` — budget, authority, need, and timeline (BANT) confirmed.\n3. `proposal` — a quote or proposal has been sent.\n4. `negotiation` — terms are actively being discussed.\n5. `won` — the deal is closed and signed.\n6. `lost` — the deal is dead; record the reason.\n\nDecision rules:\n\n- Advance one stage at a time unless a strong signal justifies a jump.\n- Strong forward signals: a signed document, a scheduled close date, an\n explicit verbal commitment, or procurement engagement.\n- Risk signals that hold a deal back: no reply for two or more weeks, the\n champion leaving, or repeated reschedules.\n- When momentum is unclear, prefer the conservative stage and lower your\n confidence rather than guessing high.\n\nAlways justify the chosen stage in the rationale with the specific signal you\nrelied on.\n","tokens":259,"inContext":true},{"path":"skills/stage_playbook/TEMPLATE.md","content":"Recommended next stage: \nConfidence: <0..1>\nPrimary signal: \nRationale: \n","tokens":41,"inContext":true},{"path":"skills/stage_playbook/examples/advance-to-negotiation.md","content":"Deal: Acme renewal, currently in `proposal`. The buyer replied yesterday asking\nto discuss discount tiers and contract length, and looped in their procurement\nlead.\n\nRecommended next stage: negotiation\nConfidence: 0.8\nPrimary signal: procurement engaged and terms (discount, contract length) are\nactively under discussion.\nRationale: an active terms discussion with procurement involved is a strong\nforward signal; advance one stage from proposal to negotiation.\n","tokens":91,"inContext":true},{"path":"skills/stage_playbook/scripts/score.ts","content":"// Sandboxed skill helper (Phase 5). Pure function of its args — no fs/net/imports.\n// Invoked by the agent via `agent_orchestrator.run_skill_script`\n// ({ skillId: \"stage_playbook\", scriptName: \"score\", args: { momentum, risk } }).\n// Returns a 0..1 health score from two 0..1 signals; the agent folds it into its\n// confidence. It can compute, never mutate — propose-only holds in the sandbox.\n\nfunction run(args) {\n const momentum = clamp01(numberOr(args && args.momentum, 0.5))\n const risk = clamp01(numberOr(args && args.risk, 0.5))\n const score = clamp01(0.6 * momentum + 0.4 * (1 - risk))\n return { score: Math.round(score * 100) / 100, momentum, risk }\n}\n\nfunction numberOr(value, fallback) {\n return typeof value === 'number' && Number.isFinite(value) ? value : fallback\n}\n\nfunction clamp01(value) {\n return Math.max(0, Math.min(1, value))\n}\n","tokens":239,"inContext":true},{"path":"sub-agents/activity_scan/AGENT.md","content":"---\nid: deals.activity_scan\nlabel: Deal activity scan (sub-agent)\ndescription: Scan a deal's recent activity and summarize momentum signals.\nmaxSteps: 6\n---\nYou are a read-only sub-agent that scans a single sales deal's recent activity.\n\nGiven the deal context provided as input, identify the most recent meaningful touchpoints (calls, emails, meetings, stage changes) and judge whether momentum is increasing, steady, or stalling. Note any risk signals such as long gaps since the last contact or a stuck stage.\n\nYou only inform the primary agent — you never propose actions. Return a concise, structured summary the primary can use to decide the next stage.\n","tokens":136,"inContext":true},{"path":"sub-agents/activity_scan/OUTCOME.md","content":"---\nkind: research\n---\n```json\n{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"momentum\", \"signals\"],\n \"properties\": {\n \"momentum\": { \"type\": \"string\", \"enum\": [\"increasing\", \"steady\", \"stalling\"] },\n \"lastTouchpoint\": { \"type\": \"string\", \"minLength\": 1 },\n \"signals\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n}\n```\n\nReport `momentum` as one of `increasing`, `steady`, or `stalling`. `signals` is a list of short, concrete momentum/risk observations (e.g. \"no contact in 21 days\", \"moved to negotiation last week\"). `lastTouchpoint` is an optional brief description of the most recent activity.\n","tokens":194,"inContext":true},{"path":"sub-agents/activity_scan/SAMPLE.json","content":"{\n \"deal\": {\n \"id\": \"demo-deal-1\",\n \"name\": \"Acme Corp — Enterprise plan\",\n \"stage\": \"Proposal\",\n \"value\": 48000,\n \"probability\": 0.65,\n \"daysInStage\": 12,\n \"activities\": [\n { \"type\": \"email\", \"at\": \"2026-06-18\", \"summary\": \"Sent revised pricing proposal.\" },\n { \"type\": \"call\", \"at\": \"2026-06-20\", \"summary\": \"Procurement asked about volume discounts.\" },\n { \"type\": \"meeting\", \"at\": \"2026-06-23\", \"summary\": \"Demo with the security team.\" }\n ]\n }\n}\n","tokens":163,"inContext":false}], subAgentDescriptors: [ { id: "deals.activity_scan", moduleId: "", label: "Deal activity scan (sub-agent)", description: "Scan a deal's recent activity and summarize momentum signals.", instructions: "You are a read-only sub-agent that scans a single sales deal's recent activity.\n\nGiven the deal context provided as input, identify the most recent meaningful touchpoints (calls, emails, meetings, stage changes) and judge whether momentum is increasing, steady, or stalling. Note any risk signals such as long gaps since the last contact or a stuck stage.\n\nYou only inform the primary agent — you never propose actions. Return a concise, structured summary the primary can use to decide the next stage.", resultKind: "research", outcomeSchema: {"type":"object","additionalProperties":false,"required":["momentum","signals"],"properties":{"momentum":{"type":"string","enum":["increasing","steady","stalling"]},"lastTouchpoint":{"type":"string","minLength":1},"signals":{"type":"array","items":{"type":"string","minLength":1}}}}, tools: [], skills: [], subAgents: [], openCodeAgentName: "deals_activity_scan", skillsContent: [], tokenUsage: {"total":330,"self":330,"agent":136,"outcome":194,"skills":[],"tools":[],"subAgents":[]}, sourceFiles: [{"path":"AGENT.md","content":"---\nid: deals.activity_scan\nlabel: Deal activity scan (sub-agent)\ndescription: Scan a deal's recent activity and summarize momentum signals.\nmaxSteps: 6\n---\nYou are a read-only sub-agent that scans a single sales deal's recent activity.\n\nGiven the deal context provided as input, identify the most recent meaningful touchpoints (calls, emails, meetings, stage changes) and judge whether momentum is increasing, steady, or stalling. Note any risk signals such as long gaps since the last contact or a stuck stage.\n\nYou only inform the primary agent — you never propose actions. Return a concise, structured summary the primary can use to decide the next stage.\n","tokens":136,"inContext":true},{"path":"OUTCOME.md","content":"---\nkind: research\n---\n```json\n{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"momentum\", \"signals\"],\n \"properties\": {\n \"momentum\": { \"type\": \"string\", \"enum\": [\"increasing\", \"steady\", \"stalling\"] },\n \"lastTouchpoint\": { \"type\": \"string\", \"minLength\": 1 },\n \"signals\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n}\n```\n\nReport `momentum` as one of `increasing`, `steady`, or `stalling`. `signals` is a list of short, concrete momentum/risk observations (e.g. \"no contact in 21 days\", \"moved to negotiation last week\"). `lastTouchpoint` is an optional brief description of the most recent activity.\n","tokens":194,"inContext":true},{"path":"SAMPLE.json","content":"{\n \"deal\": {\n \"id\": \"demo-deal-1\",\n \"name\": \"Acme Corp — Enterprise plan\",\n \"stage\": \"Proposal\",\n \"value\": 48000,\n \"probability\": 0.65,\n \"daysInStage\": 12,\n \"activities\": [\n { \"type\": \"email\", \"at\": \"2026-06-18\", \"summary\": \"Sent revised pricing proposal.\" },\n { \"type\": \"call\", \"at\": \"2026-06-20\", \"summary\": \"Procurement asked about volume discounts.\" },\n { \"type\": \"meeting\", \"at\": \"2026-06-23\", \"summary\": \"Demo with the security team.\" }\n ]\n }\n}\n","tokens":163,"inContext":false}], maxSteps: 6, sampleInput: {"deal":{"id":"demo-deal-1","name":"Acme Corp — Enterprise plan","stage":"Proposal","value":48000,"probability":0.65,"daysInStage":12,"activities":[{"type":"email","at":"2026-06-18","summary":"Sent revised pricing proposal."},{"type":"call","at":"2026-06-20","summary":"Procurement asked about volume discounts."},{"type":"meeting","at":"2026-06-23","summary":"Demo with the security team."}]}}, }, ], maxSteps: 12, sampleInput: {"deal":{"id":"demo-deal-1","name":"Acme Corp — Enterprise plan","stage":"Proposal","value":48000,"probability":0.65,"daysInStage":12,"recentActivity":"Sent revised pricing; awaiting procurement sign-off."}}, }, { id: "deals.web_researcher", moduleId: "agent_examples", label: "Deal web researcher (file-defined)", description: "Research a prospect on the public web and summarize deal-relevant signals with sources.", instructions: "You research a prospect company on the public web to surface signals relevant to an open sales deal. You are a propose-only researcher: you gather and summarize public information; you never take an action or mutate any record.\n\nThe input is `{ companyName, companyDomain? }`.\n\nWork in this order:\n\n1. Call the `open-mercato_agent_orchestrator_web_search` tool with a focused query — the company name plus one signal you need (for example \"funding\", \"layoffs\", \"acquisition\", \"leadership change\", \"pricing\"). Run several searches, one per signal, rather than a single broad query.\n2. Pass `includeContent: true` when you expect to need the page text. The tool then reads the top results for you and returns their text inline, so you do NOT need a separate fetch per link.\n3. Only call `open-mercato_agent_orchestrator_web_fetch` for a specific page that `includeContent` did not cover — a link found inside a result you already read, for example.\n4. Summarize what you found as concise findings, each tied to the source it came from.\n\nEach result carries a `confidence` score and the `sources` that surfaced it; prefer results several sources agree on. The response also carries a `diagnostics` block — when it reports `degraded: true`, or every adapter came back `blocked` or `unavailable`, the search was thin for an infrastructural reason, not because the company has no coverage. Say so rather than reading meaning into an empty result set.\n\nEvery finding MUST carry the `sourceUrl` it was drawn from. Do not state anything you cannot tie to a searched or fetched source. If the web tools return nothing useful, say so honestly in `summary` and return an empty `findings` array — never invent sources.", resultKind: "research", outcomeSchema: {"type":"object","additionalProperties":false,"required":["summary","findings"],"properties":{"summary":{"type":"string","minLength":1},"findings":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["signal","detail","sourceUrl"],"properties":{"signal":{"type":"string","minLength":1},"detail":{"type":"string","minLength":1},"sourceUrl":{"type":"string","minLength":1}}}}}}, tools: ["agent_orchestrator.web_search","agent_orchestrator.web_fetch"], skills: [], subAgents: [], openCodeAgentName: "deals_web_researcher", skillsContent: [], tokenUsage: {"total":700,"self":700,"agent":439,"outcome":261,"skills":[],"tools":[],"subAgents":[]}, sourceFiles: [{"path":"AGENT.md","content":"---\nid: deals.web_researcher\nlabel: Deal web researcher (file-defined)\ndescription: Research a prospect on the public web and summarize deal-relevant signals with sources.\ntools: [agent_orchestrator.web_search, agent_orchestrator.web_fetch]\nmaxSteps: 12\n---\nYou research a prospect company on the public web to surface signals relevant to an open sales deal. You are a propose-only researcher: you gather and summarize public information; you never take an action or mutate any record.\n\nThe input is `{ companyName, companyDomain? }`.\n\nWork in this order:\n\n1. Call the `open-mercato_agent_orchestrator_web_search` tool with a focused query — the company name plus one signal you need (for example \"funding\", \"layoffs\", \"acquisition\", \"leadership change\", \"pricing\"). Run several searches, one per signal, rather than a single broad query.\n2. Pass `includeContent: true` when you expect to need the page text. The tool then reads the top results for you and returns their text inline, so you do NOT need a separate fetch per link.\n3. Only call `open-mercato_agent_orchestrator_web_fetch` for a specific page that `includeContent` did not cover — a link found inside a result you already read, for example.\n4. Summarize what you found as concise findings, each tied to the source it came from.\n\nEach result carries a `confidence` score and the `sources` that surfaced it; prefer results several sources agree on. The response also carries a `diagnostics` block — when it reports `degraded: true`, or every adapter came back `blocked` or `unavailable`, the search was thin for an infrastructural reason, not because the company has no coverage. Say so rather than reading meaning into an empty result set.\n\nEvery finding MUST carry the `sourceUrl` it was drawn from. Do not state anything you cannot tie to a searched or fetched source. If the web tools return nothing useful, say so honestly in `summary` and return an empty `findings` array — never invent sources.\n","tokens":439,"inContext":true},{"path":"OUTCOME.md","content":"---\nkind: research\n---\n```json\n{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"summary\", \"findings\"],\n \"properties\": {\n \"summary\": { \"type\": \"string\", \"minLength\": 1 },\n \"findings\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"signal\", \"detail\", \"sourceUrl\"],\n \"properties\": {\n \"signal\": { \"type\": \"string\", \"minLength\": 1 },\n \"detail\": { \"type\": \"string\", \"minLength\": 1 },\n \"sourceUrl\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n }\n }\n}\n```\n\nWrite a one-paragraph `summary` of what the public web says about the prospect that a\nseller should know before the next conversation. List each concrete signal in `findings`\nwith a short `signal` label, a one-sentence `detail`, and the `sourceUrl` you drew it from.\nReturn an empty `findings` array (and say so in `summary`) when nothing citable was found.\n","tokens":261,"inContext":true},{"path":"SAMPLE.json","content":"{\n \"companyName\": \"Acme Corp\",\n \"companyDomain\": \"acme.example\"\n}\n","tokens":22,"inContext":false}], maxSteps: 12, sampleInput: {"companyName":"Acme Corp","companyDomain":"acme.example"}, }, { id: "support.resolution_advisor", moduleId: "agent_examples", label: "Support resolution advisor (file-defined)", description: "Look up a customer's support history and propose one resolution action.", instructions: "You advise a support agent on the single best next action for an inbound ticket. You are propose-only: you recommend ONE action; you never execute it.\n\nThe input is a ticket: `subject`, `body`, and the reporter's `customerEmail`.\n\nWork in this order:\n\n1. Read the customer's recent support history by calling the `open-mercato_agent_orchestrator_run_skill_script` tool with `{ skillId: \"__agent_tools__\", scriptName: \"lookup_ticket_history\", args: { customerEmail } }`. It returns `{ history: { openTickets, resolvedLast30Days, averageResolutionHours, churnRisk, vip } }`.\n2. Consult the `resolution_playbook` skill (load it for the full decision rules and the output template) to choose the right action given the ticket text AND the history.\n3. Propose exactly ONE action — one of `set_priority` (with `payload.priority`), `assign_specialist` (with `payload.team`), or `send_macro` (with `payload.macroId`).\n\nSet `confidence` between 0 and 1 (lower it when the signal is weak), and write a one-sentence `rationale` a support lead can act on, naming the specific history or ticket signal that drove the decision.", resultKind: "proposal", outcomeSchema: {"type":"object","additionalProperties":false,"required":["actions","confidence","rationale"],"properties":{"actions":{"type":"array","minItems":1,"items":{"type":"object","additionalProperties":false,"required":["type","payload"],"properties":{"type":{"type":"string","enum":["set_priority","assign_specialist","send_macro"]},"payload":{"type":"object","additionalProperties":false,"properties":{"priority":{"type":"string","enum":["low","medium","high","urgent"]},"team":{"type":"string","minLength":1},"macroId":{"type":"string","minLength":1}}}}}},"confidence":{"type":"number","minimum":0,"maximum":1},"rationale":{"type":"string","minLength":1}}}, tools: [], skills: ["resolution_playbook"], subAgents: [], openCodeAgentName: "support_resolution_advisor", skillsContent: [{"id":"resolution_playbook","instructions":"Use this playbook to pick the single best action for a support ticket, combining the ticket\ntext with the history returned by the `lookup_ticket_history` local tool.\n\nActions you may propose:\n\n- `set_priority` — `payload.priority` one of `low | medium | high | urgent`.\n- `assign_specialist` — `payload.team` (e.g. `billing`, `security`, `infra`, `success`).\n- `send_macro` — `payload.macroId` (a canned reply, e.g. `password-reset`, `refund-status`).\n\nDecision rules:\n\n1. Outage, data loss, security, or money-at-risk wording → `set_priority: urgent` (this beats\n every other signal).\n2. `vip: true` OR `churnRisk: high` with an unresolved problem → `assign_specialist` to the\n most relevant team; do not let a VIP wait in the general queue.\n3. A routine, well-understood request (password reset, \"where is my refund\", how-to) with\n `churnRisk: low` and no open tickets → `send_macro` with the matching canned reply.\n4. Everything else → `set_priority` at the level the ticket severity and history justify\n (more open tickets / slower average resolution → raise it).\n\nWhen the history and ticket disagree, prefer the safer (higher-touch) action and LOWER your\nconfidence rather than guessing. Always name the deciding signal in the rationale.","template":"Proposed action: \nPayload: \nConfidence: <0..1>\nDeciding signal: \nRationale: ","examples":["Ticket — subject: \"Still can't process payouts\", body: \"Third day our payouts are stuck and\nsupport hasn't replied.\" customerEmail: vip@acme.test\n\nHistory (from the `lookup_ticket_history` local tool): openTickets 3, resolvedLast30Days 1,\naverageResolutionHours 41, churnRisk high, vip true.\n\nProposed action: assign_specialist\nPayload: team=billing\nConfidence: 0.85\nDeciding signal: VIP with high churn risk and 3 open tickets on a money-blocking payout issue.\nRationale: a VIP whose payouts are blocked and who is already at high churn risk must go\nstraight to the billing specialists rather than wait in the general queue."],"tools":[]},{"id":"__agent_tools__","instructions":"","examples":[],"tools":[],"scripts":[{"name":"lookup_ticket_history","source":"// Local sandboxed tool file (Phase 5). Pure function of its args — no fs/net/imports.\n// The agent calls it via the MCP tool `agent_orchestrator.run_skill_script`\n// ({ skillId: \"__agent_tools__\", scriptName: \"lookup_ticket_history\",\n// args: { customerEmail } }). It runs server-side in the isolated-vm sandbox and\n// returns a canned support-history snapshot, so the example is self-contained (no DB\n// and no app-module MCP tool, which the standalone MCP server cannot load). It can\n// compute, never mutate — propose-only holds.\n\nfunction run(args) {\n const email = String((args && args.customerEmail) || '').trim().toLowerCase()\n const canned = {\n 'vip@acme.test': { openTickets: 3, resolvedLast30Days: 1, averageResolutionHours: 41, churnRisk: 'high', vip: true },\n 'casual@example.test': { openTickets: 0, resolvedLast30Days: 2, averageResolutionHours: 6, churnRisk: 'low', vip: false },\n }\n const history = canned[email] || {\n openTickets: 1,\n resolvedLast30Days: 1,\n averageResolutionHours: 18,\n churnRisk: 'medium',\n vip: false,\n }\n return { customerEmail: email, history }\n}\n"}]}], tokenUsage: {"total":1513,"self":1513,"agent":308,"outcome":355,"skills":[{"id":"resolution_playbook","tokens":557,"files":[{"path":"skills/resolution_playbook/SKILL.md","tokens":344},{"path":"skills/resolution_playbook/TEMPLATE.md","tokens":66},{"path":"skills/resolution_playbook/examples/escalate-vip.md","tokens":147}]}],"tools":[{"name":"lookup_ticket_history","path":"tools/lookup_ticket_history.ts","tokens":293}],"subAgents":[]}, sourceFiles: [{"path":"AGENT.md","content":"---\nid: support.resolution_advisor\nlabel: Support resolution advisor (file-defined)\ndescription: Look up a customer's support history and propose one resolution action.\nskills: [resolution_playbook]\nmaxSteps: 12\n---\nYou advise a support agent on the single best next action for an inbound ticket. You are propose-only: you recommend ONE action; you never execute it.\n\nThe input is a ticket: `subject`, `body`, and the reporter's `customerEmail`.\n\nWork in this order:\n\n1. Read the customer's recent support history by calling the `open-mercato_agent_orchestrator_run_skill_script` tool with `{ skillId: \"__agent_tools__\", scriptName: \"lookup_ticket_history\", args: { customerEmail } }`. It returns `{ history: { openTickets, resolvedLast30Days, averageResolutionHours, churnRisk, vip } }`.\n2. Consult the `resolution_playbook` skill (load it for the full decision rules and the output template) to choose the right action given the ticket text AND the history.\n3. Propose exactly ONE action — one of `set_priority` (with `payload.priority`), `assign_specialist` (with `payload.team`), or `send_macro` (with `payload.macroId`).\n\nSet `confidence` between 0 and 1 (lower it when the signal is weak), and write a one-sentence `rationale` a support lead can act on, naming the specific history or ticket signal that drove the decision.\n","tokens":308,"inContext":true},{"path":"OUTCOME.md","content":"---\nkind: proposal\n---\n```json\n{\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"actions\", \"confidence\", \"rationale\"],\n \"properties\": {\n \"actions\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"required\": [\"type\", \"payload\"],\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"set_priority\", \"assign_specialist\", \"send_macro\"]\n },\n \"payload\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"priority\": {\n \"type\": \"string\",\n \"enum\": [\"low\", \"medium\", \"high\", \"urgent\"]\n },\n \"team\": { \"type\": \"string\", \"minLength\": 1 },\n \"macroId\": { \"type\": \"string\", \"minLength\": 1 }\n }\n }\n }\n }\n },\n \"confidence\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 },\n \"rationale\": { \"type\": \"string\", \"minLength\": 1 }\n }\n}\n```\n\nPropose exactly one action in `actions`. Fill only the `payload` field that matches the\naction `type` (`set_priority` → `priority`, `assign_specialist` → `team`, `send_macro` →\n`macroId`). `confidence` is 0..1 and `rationale` is one non-empty, support-lead-readable\nsentence naming the deciding signal.\n","tokens":355,"inContext":true},{"path":"SAMPLE.json","content":"{\n \"subject\": \"Still can't process payouts\",\n \"body\": \"Third day our payouts are stuck and support hasn't replied. This is blocking our whole finance team.\",\n \"customerEmail\": \"vip@acme.test\"\n}\n","tokens":48,"inContext":false},{"path":"skills/resolution_playbook/SKILL.md","content":"---\nid: resolution_playbook\nmoduleId: agent_examples\nlabel: Support resolution playbook\ndescription: How to choose one resolution action from a ticket and its customer history.\n---\nUse this playbook to pick the single best action for a support ticket, combining the ticket\ntext with the history returned by the `lookup_ticket_history` local tool.\n\nActions you may propose:\n\n- `set_priority` — `payload.priority` one of `low | medium | high | urgent`.\n- `assign_specialist` — `payload.team` (e.g. `billing`, `security`, `infra`, `success`).\n- `send_macro` — `payload.macroId` (a canned reply, e.g. `password-reset`, `refund-status`).\n\nDecision rules:\n\n1. Outage, data loss, security, or money-at-risk wording → `set_priority: urgent` (this beats\n every other signal).\n2. `vip: true` OR `churnRisk: high` with an unresolved problem → `assign_specialist` to the\n most relevant team; do not let a VIP wait in the general queue.\n3. A routine, well-understood request (password reset, \"where is my refund\", how-to) with\n `churnRisk: low` and no open tickets → `send_macro` with the matching canned reply.\n4. Everything else → `set_priority` at the level the ticket severity and history justify\n (more open tickets / slower average resolution → raise it).\n\nWhen the history and ticket disagree, prefer the safer (higher-touch) action and LOWER your\nconfidence rather than guessing. Always name the deciding signal in the rationale.\n","tokens":344,"inContext":true},{"path":"skills/resolution_playbook/TEMPLATE.md","content":"Proposed action: \nPayload: \nConfidence: <0..1>\nDeciding signal: \nRationale: \n","tokens":66,"inContext":true},{"path":"skills/resolution_playbook/examples/escalate-vip.md","content":"Ticket — subject: \"Still can't process payouts\", body: \"Third day our payouts are stuck and\nsupport hasn't replied.\" customerEmail: vip@acme.test\n\nHistory (from the `lookup_ticket_history` local tool): openTickets 3, resolvedLast30Days 1,\naverageResolutionHours 41, churnRisk high, vip true.\n\nProposed action: assign_specialist\nPayload: team=billing\nConfidence: 0.85\nDeciding signal: VIP with high churn risk and 3 open tickets on a money-blocking payout issue.\nRationale: a VIP whose payouts are blocked and who is already at high churn risk must go\nstraight to the billing specialists rather than wait in the general queue.\n","tokens":147,"inContext":true},{"path":"tools/lookup_ticket_history.ts","content":"// Local sandboxed tool file (Phase 5). Pure function of its args — no fs/net/imports.\n// The agent calls it via the MCP tool `agent_orchestrator.run_skill_script`\n// ({ skillId: \"__agent_tools__\", scriptName: \"lookup_ticket_history\",\n// args: { customerEmail } }). It runs server-side in the isolated-vm sandbox and\n// returns a canned support-history snapshot, so the example is self-contained (no DB\n// and no app-module MCP tool, which the standalone MCP server cannot load). It can\n// compute, never mutate — propose-only holds.\n\nfunction run(args) {\n const email = String((args && args.customerEmail) || '').trim().toLowerCase()\n const canned = {\n 'vip@acme.test': { openTickets: 3, resolvedLast30Days: 1, averageResolutionHours: 41, churnRisk: 'high', vip: true },\n 'casual@example.test': { openTickets: 0, resolvedLast30Days: 2, averageResolutionHours: 6, churnRisk: 'low', vip: false },\n }\n const history = canned[email] || {\n openTickets: 1,\n resolvedLast30Days: 1,\n averageResolutionHours: 18,\n churnRisk: 'medium',\n vip: false,\n }\n return { customerEmail: email, history }\n}\n","tokens":293,"inContext":true}], maxSteps: 12, sampleInput: {"subject":"Still can't process payouts","body":"Third day our payouts are stuck and support hasn't replied. This is blocking our whole finance team.","customerEmail":"vip@acme.test"}, }, ]