@vruum/mcp 0.12.1 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/tools.json +78 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vruum/mcp",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"mcpName": "ai.vruum/mcp",
|
|
5
5
|
"description": "Stdio MCP bridge for the hosted Vruum revenue-platform MCP (https://api.vruum.ai/mcp): serves the advertised tool surface for credential-free introspection and proxies tool calls with your Vruum token.",
|
|
6
6
|
"license": "MIT",
|
package/tools.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "GENERATED by backend/scripts/dump_member_tools.py — do not edit. The member-visible tool surface of the hosted Vruum MCP (https://api.vruum.ai/mcp), served statically by @vruum/mcp for credential-free introspection.",
|
|
3
3
|
"server": "ai.vruum/mcp",
|
|
4
|
-
"tool_count":
|
|
4
|
+
"tool_count": 36,
|
|
5
5
|
"tools": [
|
|
6
6
|
{
|
|
7
7
|
"annotations": {
|
|
@@ -905,7 +905,7 @@
|
|
|
905
905
|
"readOnlyHint": false,
|
|
906
906
|
"title": "Import Prospects"
|
|
907
907
|
},
|
|
908
|
-
"description": "Import Prospects\n\nSource and import prospects — the consolidated import tool.\n\nLinkedIn and Sales Navigator people searches (linkedin_people_search,\nsales_nav_search) are on research_lookup.\n\nSales Navigator import actions:\n- sales_nav_preview: preview a Sales Nav search against your pipeline\n ({search?, count?, objective?}).\n- sales_nav_import: import people or accounts. For account imports, use\n {search, target: \"accounts\"}; `search` is a saved account search name or\n ID, and do not pass objective or auto_enroll. A unique match returns a\n job_id to poll with fetch type='job'; no_match, ambiguous, and error\n responses do not return a job. People imports accept {search?, count?,\n profiles_json?, auto_enroll?, objective?}.\n `profiles_json` accepts research_lookup action=sales_nav_search output\n directly: each object\n needs linkedin_url plus either first_name/last_name or a single `name`\n field (mode=basic results); `headline` is used as a title fallback.\n- sales_nav_dismiss: dismiss profiles from future imports\n ({linkedin_urls} — comma-separated).\n- sales_nav_searches: list seats with {action: \"accounts\"}; each config_id\n can be passed as search_account_id. Actions list and create support saved\n people or account searches. Use search_type=\"company\" to create an\n account search; create requires name and filters_json, where filters_json\n is a JSON-encoded array string. Register attaches replay filters to an\n existing account search and requires search_id, name, and filters_json.\n Actions update and delete support people searches only. Other fields are {name?, keywords?, search_type?:\n \"lead\"|\"company\", search_account_id?, frequency?, search_id?}.\n\nCSV actions:\n- csv_preview: parse + preview a CSV
|
|
908
|
+
"description": "Import Prospects\n\nSource and import prospects — the consolidated import tool.\n\nLinkedIn and Sales Navigator people searches (linkedin_people_search,\nsales_nav_search) are on research_lookup.\n\nSales Navigator import actions:\n- sales_nav_preview: preview a Sales Nav search against your pipeline\n ({search?, count?, objective?}).\n- sales_nav_import: import people or accounts. For account imports, use\n {search, target: \"accounts\"}; `search` is a saved account search name or\n ID, and do not pass objective or auto_enroll. A unique match returns a\n job_id to poll with fetch type='job'; no_match, ambiguous, and error\n responses do not return a job. People imports accept {search?, count?,\n profiles_json?, auto_enroll?, objective?}.\n `profiles_json` accepts research_lookup action=sales_nav_search output\n directly: each object\n needs linkedin_url plus either first_name/last_name or a single `name`\n field (mode=basic results); `headline` is used as a title fallback.\n- sales_nav_dismiss: dismiss profiles from future imports\n ({linkedin_urls} — comma-separated).\n- sales_nav_searches: list seats with {action: \"accounts\"}; each config_id\n can be passed as search_account_id. Actions list and create support saved\n people or account searches. Use search_type=\"company\" to create an\n account search; create requires name and filters_json, where filters_json\n is a JSON-encoded array string. Register attaches replay filters to an\n existing account search and requires search_id, name, and filters_json.\n Actions update and delete support people searches only. Other fields are {name?, keywords?, search_type?:\n \"lead\"|\"company\", search_account_id?, frequency?, search_id?}.\n\nCSV actions:\n- csv_preview: parse + preview a CSV before importing ({file_content}).\n `file_content` is the CSV file's bytes, base64-encoded; raw CSV text\n is rejected.\n- csv_start: start an import job ({file_content (base64, as for\n csv_preview), column_mapping, objective_id?, skip_research?}). Returns\n a job id — poll it with fetch type='csv_import'.\n\nPayloads are validated by the underlying route's own schema, so a bad\nfield returns that route's precise 422.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json",
|
|
909
909
|
"inputSchema": {
|
|
910
910
|
"properties": {
|
|
911
911
|
"action": {
|
|
@@ -969,6 +969,77 @@
|
|
|
969
969
|
"name": "import_prospects",
|
|
970
970
|
"title": "Import Prospects"
|
|
971
971
|
},
|
|
972
|
+
{
|
|
973
|
+
"annotations": {
|
|
974
|
+
"destructiveHint": false,
|
|
975
|
+
"openWorldHint": false,
|
|
976
|
+
"readOnlyHint": true,
|
|
977
|
+
"title": "Read Assistant Conversations"
|
|
978
|
+
},
|
|
979
|
+
"description": "Inspect Assistant\n\nRead private revenue conversations and their exact saved work. Read-only.\n\n- list: no id; optional payload={before_updated_at, before_id, limit}.\n Follow both returned next_before_updated_at and next_before_id for the\n next page. Only the current user's permitted conversations are returned.\n- read: id=conversation UUID; optional payload={before_sequence, limit}.\n Returns the current conversation revision, message content references,\n and linked Actions. Follow next_before_sequence for earlier messages.\n Conversation revision is separate from an Action or proposal revision.\n- read_message: id=conversation UUID; payload={message_id, offset?, limit?}.\n Use a message UUID from read. Retrieve every Unicode content page by\n following next_offset until has_more is false. The current conversation\n and source policy control access; a reference is not permission.\n- read_events: id=conversation UUID;\n payload={action_id, after_sequence?, limit?}. Use a linked Action UUID\n from read. Follow next_after_sequence until has_more is false. This\n checks the current conversation and source policies for every page.\n Events expose safe journal metadata, not provider-step content. Retrieve\n complete saved answers with read_message.\n Do not use legacy task-event reads for conversation-derived work.\n- locate_action: id=existing Action UUID; no payload. Returns its permitted\n conversation and message without creating or restarting any work.\n\nReads do not purchase models, claim execution, import history, or transfer\nactor or sender authority. They retain complete content or report denied\naccess; never infer an empty answer from unavailable content. Native chat\nand the harness inspect the same conversation and Actions.\n\nA linked email's review_message_id identifies its retained proposal. Use\nget_outreach_review with that message_ids value and content_length='full'.\nShow the exact sender, recipient, subject and complete body. After explicit\napproval, use scalar manage_messages with its current retained_email_decision\ntoken. A conversational message alone does not approve or send. Re-read the\nlinked Action's delivery state and receipt; approval does not prove delivery.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n\nPersistent private revenue conversations support (assistant_conversations):\nProduct support is not permission. Inspect current work and follow the domain's authorization and review rules.\n- start_conversation: manage_assistant action=start_conversation. Save the complete request and authorize paid preparation. Retry the same request UUID and arguments. A branch inherits permitted context, never execution or approval authority.\n- append_message: manage_assistant action=append_message. Save a new message at the current conversation revision. The same request UUID recovers accepted work. Messages cannot approve or send.\n- list: inspect_assistant action=list. Page the current user's permitted conversations without starting work.\n- read: inspect_assistant action=read. Read saved messages, current conversation revision and linked Actions. Follow next_before_sequence for earlier messages.\n- read_message: inspect_assistant action=read_message. Read every content page under current conversation and source access. Follow next_offset until the complete message is retrieved.\n- read_events: inspect_assistant action=read_events. Read a linked Action's journal under current conversation and source access. Follow next_after_sequence for every event page.\n- locate_action: inspect_assistant action=locate_action. Resolve an old Action link to its permitted conversation. Reopening does not replace work, approve an effect, or retry delivery.\n- sharing: unsupported. No shared participants, private-source publication, or actor transfer.",
|
|
980
|
+
"inputSchema": {
|
|
981
|
+
"properties": {
|
|
982
|
+
"action": {
|
|
983
|
+
"description": "The operation to perform — see the tool description for the action vocabulary and each action's id/payload semantics.",
|
|
984
|
+
"title": "action",
|
|
985
|
+
"type": "string"
|
|
986
|
+
},
|
|
987
|
+
"for_company": {
|
|
988
|
+
"description": "Optional company ID or name (UUID, or case-insensitive EXACT name match — partial / substring matches are NOT supported; ambiguous names raise 400) to execute this tool as. Use get_operator_companies, or get_operator_overview with view='companies', to list available companies. Only needed if you manage multiple companies. Access is enforced server-side: the tool resolves the value to a user_company_id and verifies the caller's membership in `company_users` — a 403 'Company not found or access denied' means EITHER the value did not match a known company OR the caller is not a member of it. The MCP operator role itself is NOT auto-granted — operators get this access by being members of each client company via `company_users` (the same row that grants any normal user access).",
|
|
989
|
+
"title": "for_company",
|
|
990
|
+
"type": "string"
|
|
991
|
+
},
|
|
992
|
+
"id": {
|
|
993
|
+
"anyOf": [
|
|
994
|
+
{
|
|
995
|
+
"type": "string"
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
"items": {
|
|
999
|
+
"type": "string"
|
|
1000
|
+
},
|
|
1001
|
+
"type": "array"
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
"type": "null"
|
|
1005
|
+
}
|
|
1006
|
+
],
|
|
1007
|
+
"description": "Target entity id, or an ARRAY of ids to apply the same action+payload to each (max 100; see the tool description for which entity the id names per action).",
|
|
1008
|
+
"title": "id"
|
|
1009
|
+
},
|
|
1010
|
+
"items": {
|
|
1011
|
+
"description": "For create-like actions only: an array of per-item payloads processed in order with per-item results (max 100). Mutually exclusive with `id` and `payload`.",
|
|
1012
|
+
"items": {
|
|
1013
|
+
"additionalProperties": true,
|
|
1014
|
+
"type": "object"
|
|
1015
|
+
},
|
|
1016
|
+
"title": "items",
|
|
1017
|
+
"type": "array"
|
|
1018
|
+
},
|
|
1019
|
+
"payload": {
|
|
1020
|
+
"anyOf": [
|
|
1021
|
+
{
|
|
1022
|
+
"additionalProperties": true,
|
|
1023
|
+
"type": "object"
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
"type": "null"
|
|
1027
|
+
}
|
|
1028
|
+
],
|
|
1029
|
+
"description": "Action-specific fields, validated by the underlying route's own schema (a bad field 422s with that route's precise errors). See the tool description per action.",
|
|
1030
|
+
"title": "payload",
|
|
1031
|
+
"type": "object"
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
"required": [
|
|
1035
|
+
"action"
|
|
1036
|
+
],
|
|
1037
|
+
"title": "inspect_assistantArguments",
|
|
1038
|
+
"type": "object"
|
|
1039
|
+
},
|
|
1040
|
+
"name": "inspect_assistant",
|
|
1041
|
+
"title": "Read Assistant Conversations"
|
|
1042
|
+
},
|
|
972
1043
|
{
|
|
973
1044
|
"annotations": {
|
|
974
1045
|
"destructiveHint": false,
|
|
@@ -1138,9 +1209,9 @@
|
|
|
1138
1209
|
"destructiveHint": false,
|
|
1139
1210
|
"openWorldHint": true,
|
|
1140
1211
|
"readOnlyHint": false,
|
|
1141
|
-
"title": "Manage
|
|
1212
|
+
"title": "Manage Assistant Conversations and Work"
|
|
1142
1213
|
},
|
|
1143
|
-
"description": "Manage Assistant\n\nStart
|
|
1214
|
+
"description": "Manage Assistant\n\nStart or continue a private revenue conversation and its reviewed work.\n\n- start_conversation: no id; payload={request_id (UUID), message,\n parent_conversation_id?, parent_message_id?}. Call after the user requests\n this work. The server saves the complete message and starts paid model\n work. It can analyze permitted records, ask for clarification, or prepare\n one email for separate exact review. A branch requires both parent IDs;\n it reuses permitted context without copying execution or approval authority.\n- append_message: id=conversation UUID; payload={request_id, message,\n expected_revision, parent_message_id?}. Read the conversation revision\n with inspect_assistant first. The server saves the new instruction in the\n same conversation. A message does not approve or send an email. Keep the\n exact request UUID, conversation, revision, parent and message on retries,\n including after uncertainty. Recover accepted work before creating any\n replacement request. Conversation revisions are separate from Action and\n email proposal revisions. Read results and complete message pages with\n inspect_assistant; do not import this harness's other conversation history.\n\n- start_analysis: no id; payload={request_id (UUID), message}. Call only\n after the user requests this analysis. This call explicitly grants\n revenue_operator.read_analysis.v1: paid model work using permitted reads,\n without tool writes or external effects. Keep the exact request UUID and\n message on retries; the saved task journal owns request identity and\n recovery. An uncertain response never authorizes a replacement task.\n- start_email: no id; payload={request_id (UUID), message, person_id,\n sender_config_id}. Call only after the user requests this email work.\n Authorizes paid model work, permitted reads and one retained email draft\n for that workspace contact and an eligible mailbox available to the\n current actor. It does not approve or send. Read the returned email_scope\n and linked review_message_id. Review the exact sender, recipient, subject\n and complete body through the existing message review before approving.\n Keep the same request UUID, message, person and mailbox on retries;\n uncertain acknowledgement never authorizes another task or delivery.\n- cancel: id=the saved task's Action UUID; payload={expected_version} from\n a fresh fetch assistant_task. The original current actor or a current\n workspace owner/operator may cancel future continuation. An in-flight\n effect or provider call may still finish; cancellation cannot recall it.\n- follow_up: id=the latest eligible saved Action UUID; payload={request_id,\n expected_version, message}. Only its current original actor/login can\n continue. This buys a new Action in the same private conversation. Completed\n analysis or email can continue. Revising an unapproved email atomically\n retires that draft; the new draft requires its own exact approval. Contact,\n sender and the complete email envelope stay fixed. Approved, dispatching,\n unresolved, cancelled or blocked work cannot continue. Keep the exact UUID,\n parent, revision and message on retries, including an uncertain response.\n The server reconstructs permitted history and refreshes company context.\n Historical answers and delivery receipts never authorize another send.\n\nAll actions are scalar: no id arrays or items. No caller history, imported\nthread, email-scope edits, additional effects, actor transfer, or worker\ncontrol fields are accepted. This facade adds no authority to its target.\nThe task is private to its original current actor and login; owner/operator\noversight gives metadata and cancellation, never another member's content.\nExisting retained email work uses its exact linked review without changing\nthe sender. Inspect fetch assistant_task, page fetch assistant_task_events,\nand retrieve full content with fetch assistant_task_content. Read prior\nturns by following previous_action_id from fetch assistant_task until it is\nnull, then order by conversation_turn. Follow next_action_id to newer work.\nThese older task controls do not append to a running task. Use the separate\nconversation commands for new chat messages. Shared participants and\nexecutor transfer remain unsupported.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n\nPersistent private revenue conversations support (assistant_conversations):\nProduct support is not permission. Inspect current work and follow the domain's authorization and review rules.\n- start_conversation: manage_assistant action=start_conversation. Save the complete request and authorize paid preparation. Retry the same request UUID and arguments. A branch inherits permitted context, never execution or approval authority.\n- append_message: manage_assistant action=append_message. Save a new message at the current conversation revision. The same request UUID recovers accepted work. Messages cannot approve or send.\n- list: inspect_assistant action=list. Page the current user's permitted conversations without starting work.\n- read: inspect_assistant action=read. Read saved messages, current conversation revision and linked Actions. Follow next_before_sequence for earlier messages.\n- read_message: inspect_assistant action=read_message. Read every content page under current conversation and source access. Follow next_offset until the complete message is retrieved.\n- read_events: inspect_assistant action=read_events. Read a linked Action's journal under current conversation and source access. Follow next_after_sequence for every event page.\n- locate_action: inspect_assistant action=locate_action. Resolve an old Action link to its permitted conversation. Reopening does not replace work, approve an effect, or retry delivery.\n- sharing: unsupported. No shared participants, private-source publication, or actor transfer.\n\nPrivate saved email support (assistant_saved_email):\nProduct support is not permission. Inspect current work and follow the domain's authorization and review rules.\n- start_email: manage_assistant action=start_email. An explicit request grants paid model work, permitted reads and one retained draft for the exact workspace person and eligible mailbox. Keep the request UUID and all inputs unchanged on retry. Inspect email_scope and review_message_id on the saved task. The exact sender, recipient, subject and body require separate human review before sending. Approval does not prove delivery.\n- scope_edit: unsupported. No sender or recipient changes after start. Cancel unused work and create a new request for changed scope.\n- delivery_replacement: unsupported. An unknown model or delivery outcome never authorizes replacement work. The original saved task owns recovery and receipt checks.\n\nPrivate saved conversations support (assistant_saved_conversations):\nProduct support is not permission. Inspect current work and follow the domain's authorization and review rules.\n- follow_up: manage_assistant action=follow_up. Continue completed private analysis or email, or revise an unapproved email. Its contact and full envelope stay fixed. A revision retires the old draft and requires a new approval. Exact request UUID retries recover the same child Action. Historical receipts never approve a send.\n- active_steering: unsupported. A running task cannot accept new messages. Complete it before following up.\n- sharing: unsupported. No shared participants, source publication, or actor transfer.\n\nSaved assistant tasks support (assistant_saved_tasks):\nProduct support is not permission. Inspect current work and follow the domain's authorization and review rules.\n- start: manage_assistant action=start_analysis. An explicit request grants paid read_analysis.v1 only. Exact request UUID retries recover the same task.\n- list: fetch type=assistant_tasks. Page own work or authorized workspace metadata with next_cursor.\n- inspect: fetch type=assistant_task. Read current state, Action version and exact review links.\n- events: fetch type=assistant_task_events. Page journal events by sequence; no raw worker state or hidden reasoning.\n- content: fetch type=assistant_task_content. Read complete immutable content pages under the original current actor and login.\n- cancel: manage_assistant action=cancel. Cancel at the current Action version; in-flight effects may still finish.\n- conversation_import: unsupported. No caller history, thread import, or appended task messages.\n- email_activation: unsupported. This analysis capability cannot start email work. Use the separate assistant_saved_email start_email capability for one reviewed email.\n- executor_transfer: unsupported. No actor, sender, or harness/worker authority transfer.",
|
|
1144
1215
|
"inputSchema": {
|
|
1145
1216
|
"properties": {
|
|
1146
1217
|
"action": {
|
|
@@ -1202,7 +1273,7 @@
|
|
|
1202
1273
|
"type": "object"
|
|
1203
1274
|
},
|
|
1204
1275
|
"name": "manage_assistant",
|
|
1205
|
-
"title": "Manage
|
|
1276
|
+
"title": "Manage Assistant Conversations and Work"
|
|
1206
1277
|
},
|
|
1207
1278
|
{
|
|
1208
1279
|
"annotations": {
|
|
@@ -1904,7 +1975,7 @@
|
|
|
1904
1975
|
"readOnlyHint": false,
|
|
1905
1976
|
"title": "Manage Person"
|
|
1906
1977
|
},
|
|
1907
|
-
"description": "Manage Person\n\nCreate and manage people in your pipeline — the consolidated person writer.\n\nActions (id = person UUID unless noted):\n- create: add a person manually (no id; `payload` =
|
|
1978
|
+
"description": "Manage Person\n\nCreate and manage people in your pipeline — the consolidated person writer.\n\nActions (id = person UUID unless noted):\n- create: add a person manually (no id; `payload` = {first_name,\n last_name, company_name, email and/or linkedin_url (at least one),\n title?, company_website?, phone?, location?, objective_id?,\n skip_research?}); bulk via `items` (one payload per person).\n- update_contact: override contact fields (`payload` = contact overrides).\n- set_position: set the primary position (`payload` = position fields).\n- note: add a timeline note (`payload` = {body}).\n- log_interaction: log a manual touch that happened outside an automated\n sequence — a call (with disposition + what was said), or an\n email/LinkedIn/other touch made elsewhere. `payload` =\n {interaction_kind: call|email|linkedin|meeting|other, direction?:\n outbound|inbound, summary?, disposition? (calls only), occurred_at?\n (ISO, backdatable), deal_id?}. Lands on the person's timeline attributed\n to you (performed_by_user_id).\n- archive: soft-delete one or many people — stops outreach plans and\n rejects pending drafts (id or id array; no payload). DESTRUCTIVE.\n- unarchive: restore archived people (id or id array; no payload).\n- meeting_booked: mark a meeting booked with this person (`payload` =\n {idempotency_key: UUID}; reuse it when retrying the same booking).\n- save_discovered: THE creator — save a researched prospect into the\n pipeline, atomically (no id; bulk via `items`). Two shapes:\n NEW prospect: `payload` = {person: {first_name, last_name,\n linkedin_url|email, company_id (from research action=save_company) or\n company_name plus company_domain/company_website/company_linkedin_url,\n ...research fields}, assessment: {match_score\n 0-100, match_summary, alignment_points?, concerns?, why_now?,\n recommended_approach?, overall_confidence?, scored_by?}, objective_id or\n assessment_objective_id}. Person + research + pipeline membership land\n in ONE transaction — a rejected or failed save persists nothing.\n EXISTING person: `payload` = {person_id, company_id, objective_id?,\n assessment_objective_id?, assessment?}; if company_id is unavailable,\n pass company_name plus at least one top-level company_domain,\n company_website, or company_linkedin_url. Never send a bare person_id:\n the binding atomically adds/promotes the current position and pins the\n pipeline membership while the assessment is applied update-in-place\n (THE path to score an existing stub). Pass exactly one of `person` /\n `person_id`. Use assessment_objective_id to preserve\n objective-scoring provenance without assigning the person. Your\n assessment is AUTHORITATIVE: the backend records it with provenance and\n never re-scores it. Backend floor stays mechanical: dedupe first\n (anchors resolving to an existing person continue as a duplicate\n update); new rows require a LinkedIn URL or email and stay within the\n per-tenant discovery-volume cap; the `person` shape requires\n `assessment` + an objective ref (did no fit analysis? use action=create\n instead). Duplicates do not consume or re-check the new-row cap. The\n response includes `company_id` and `company_bound`; require\n `company_bound=true` before treating the save as company-complete or\n calling manage_outreach action=start. If false, do not enroll—repair the\n company binding and retry save_discovered.\n- set_persona: set a contact's buying-center role (Revenue Architecture\n Table 8.2) — initiator / user / champion / decider / gatekeeper /\n influencer / executive_buyer / approver / purchaser / unknown\n (`payload` = {persona, reasoning?}).\n- set_meeting_purpose: say what a meeting was for (`id` = the meeting id,\n or `li:<interaction id>` for a logged meeting; `payload` = {purpose}\n — discovery / demo / proposal / negotiation / commit / kickoff /\n impact_review / renewal / expansion / winback / internal / other, or\n null to clear). The seller's word outlives the calendar title; a held\n meeting's timeline event moves to the new purpose's practice. The harness classifies buying role at touch time and\n writes it here; there is no backend classifier.\n- adopt_directory: add an existing shared canonical person to this tenant's\n CRM (id = directory person UUID; no payload). This copies no tenant-private\n notes, activity, objective, score, or outreach state. It is free for the\n tenant.\n\nBulk: `id` arrays apply the same action to each person (archive/unarchive\nroute to the native bulk endpoints; others loop with per-item status —\npartial failure is reported per item, never silent). `items` is for\ncreate-like actions, max 100 per call. Payloads are validated by the\nunderlying route's own schema, so a bad field returns that route's\nprecise 422.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json",
|
|
1908
1979
|
"inputSchema": {
|
|
1909
1980
|
"properties": {
|
|
1910
1981
|
"action": {
|
|
@@ -2303,7 +2374,7 @@
|
|
|
2303
2374
|
"readOnlyHint": false,
|
|
2304
2375
|
"title": "Research"
|
|
2305
2376
|
},
|
|
2306
|
-
"description": "Research\n\nRun prospect/company research and save the results — the consolidated research tool.\n\n- start_account_brief: explicitly delegate one objective/account brief to\n Vruum's durable worker. First fetch research_work_list with\n objective_id and company_id filters; inspect existing work and use the\n returned scope planning_version. Payload requires {objective_id,\n company_id, request_id (UUID), expected_planning_version (positive integer),\n source_mode (saved_public or refresh_public)}.\n Paid search and model work runs after this call and survives leaving the page.\n A matching active or unresolved job is reused; retain request_id on retries.\n Start only after the user requests this exact scope. A model suggestion\n is not approval. The native assistant uses its write approval card;\n an external harness must obtain its user's authorization before calling.\n saved_public uses permitted saved public sources and business configuration.\n refresh_public also authorizes one public-domain search and live verification\n of up to three company pages before synthesis. Search excerpts are not evidence.\n Retain the exact source_mode on retries; existing work with another mode\n conflicts. Failed or partial refreshes remain visible in source coverage.\n Neither mode grants private source access, transcript persistence, browser\n credential storage, or external-harness execution handoff.\n Poll fetch research_work; read Claims and citations with fetch account_brief,\n both id=returned Action UUID. The worker automatically recovers saved\n provider response IDs and terminal receipts after interruption.\n A missing or unavailable provider response needs operator investigation;\n manual repair is unsupported and a fresh request_id cannot authorize replay.\n- cancel_account_brief: id=Action UUID; payload={expected_version} from\n the current saved work. Stops continuation and requests cancellation of\n pending saved model responses. A dispatched search or model call may still cost\n money; cancellation does not prove the provider stopped.\n Both account-brief writes accept one request only, without items or batches.\n- preview_gaps: READ ONLY assignment, no research or spend. id=objective UUID;\n payload={subjects:[{type,person_id?,company_id?,deal_id?}], question_ids?,\n stage?, use_public_web?:true, use_history?:false}. Up to 20 subjects and\n 40 unique gaps. Reuses current account answers across people.\n Equivalent reviewed fact definitions also reuse original observations across\n objectives when their subject, schema, sources, quality and freshness match.\n Reused answers retain original evidence IDs; do not save duplicate copies.\n Read gaps, question definitions, source permissions and limits before choosing work.\n- stop_gaps: id=objective UUID, payload={action_id}. Stop future calls and\n answer writes. Already sent provider work can finish.\n- propose_gaps: same input; saves an Action without executing research.\n- approve_gaps: id=objective UUID, payload={action_id}. Only after the user\n approves that exact saved assignment. Starts bounded Vruum research.\n Poll fetch research_run id=action UUID. Never repeat approval to retry.\n For research on YOUR compute, use preview_gaps, fetch research_sources,\n your permitted tools, then save_answer. Do not approve Vruum research as\n a substitute for external research. Your harness pays its own compute.\n Use the exact subject, question ID and definition fingerprint from the\n assignment. Public URL excerpts remain reported. Never assert customer\n confirmation without an explicit operator attestation.\n- save_answer: record one answer for a saved objective research question\n (id = objective UUID; payload = {idempotency_key, question_id,\n definition_fingerprint, subject: {type, person_id?, company_id?, deal_id?},\n state: answered|unknown|unavailable, value, source: {kind, reference?,\n excerpt, observed_at}, note?, supersedes_evidence_id?}). Read the question\n and answer_schema through fetch research_answers first. Source kinds:\n operator_report, public_url (reported only), activity, evidence, meeting,\n customer_confirmation (explicit operator attestation). Existing references\n must match the tenant, subject, excerpt and original observation time.\n Exact retries retain their UUID; changed content needs a new UUID.\n Corrections explicitly supersede one observation. Answers never authorize\n outreach. Generic save_evidence/save_claim cannot write research answers.\n\nLookup and enrichment actions (results are returned, not stored unless\nnoted). Synchronous lookups without a saved result (find_email,\nlinkedin_fetch, enrich_company, careers_parse) are on research_lookup.\n- find_linkedin: locate a person's LinkedIn URL (id = person UUID;\n `payload` optional {name_override?, company_override?, auto_save?} —\n auto_save stores a high-confidence match).\n- enrich_account: acquire a bounded first-party evidence bundle for a\n tenant-visible account (id = canonical company UUID). The response also\n carries canonical company fields, cached shared research, and freshness\n metadata for the harness to combine with its own web and MCP sources.\n Persist sourced conclusions with save_company. research_lookup\n action=enrich_company remains the domain/page website-fetch primitive.\n- enrich_person: enrich each person according to missing contact and profile\n fields (id = person UUID, or an array of up to 100;\n `payload` optional {force_refresh?}). Returns a job_id; poll it with\n fetch type=job. Outcomes report a stable reason code, and jobs with any\n errored outcome terminate as completed_with_failures. Successful outcomes\n report readiness=email_ready, incomplete, or manual_review plus the\n canonical employer binding.\n Vruum applies separate monthly profile and Hunter-credit soft limits.\n Harness web search and other MCP tools remain complementary for deeper\n research. The legacy enrich_profile name is an alias.\n- enrich: canonical scoped enrichment. It inspects each person and runs\n only the needed profile or verified-email work. Pass `payload` with exactly one of\n `{person_ids: [...]}`, `{objective_id: ...}`, or `{list_id: ...}`.\n Returns a job_id; poll it with fetch type=job. The enrich_emails action\n remains as a compatibility alias for the same scoped planner.\n\nSave actions (write research rows):\n- save_person: UPDATE research on an EXISTING person — pass the person UUID\n as `payload.person_id` (preferred; refreshes researched_at and the\n research fields in place), or matching email/linkedin anchors. Cannot\n create: new prospects go through manage_person action=save_discovered\n with `payload.person` + `payload.assessment`. Never pass the person UUID\n as `id` — this action takes no id.\n- save_company: atomically patch sourced public company research. Pass\n `payload={company_id?, allow_create?, idempotency_key, name, industry, person_id?, website?, linkedin_url?,\n company_summary?, company_stage?, current_priorities?, funding_data?,\n growth_metrics?, sources_by_field}`.\n `industry` is required and must be one CanonicalIndustry value:\n Agriculture, Construction, Consumer Goods, Consumer Services, Education,\n Energy & Utilities, Financial Services, Government, Healthcare,\n Hospitality & Travel, Legal Services, Manufacturing, Marketing & Advertising,\n Media & Entertainment, Nonprofit, Professional Services, Real Estate,\n Retail & E-commerce, Software & Technology, Staffing & Recruiting,\n Telecommunications, Transportation & Logistics, Wholesale & Distribution,\n or Other. Provider labels and Unspecified are rejected.\n Omitted research fields are preserved; explicit null clears. When\n researching a specific person's employer,\n ALWAYS pass their UUID as `payload.person_id` — the response's\n `person_link` confirms the write landed on that person's linked company\n (repointing an anchorless duplicate link when needed); a `mismatch`\n status means the person's touches will NOT see this research, and a\n `conflict` status is a transient race — replay the identical payload\n (person_id is exempt from the idempotency hash, so adding it to a\n replay is the supported repair).\n For a researched-prospect save, save_company is also the company identity resolution step.\n For an existing account, ALWAYS pass payload.company_id, including the ID\n returned by enrich_account. Updates never create or merge a company.\n Otherwise call save_company with allow_create=true plus name and website\n and/or linkedin_url. Never combine company_id with allow_create=true.\n Conflicts require identity reconciliation; never retry by dropping the ID.\n Identity selection, missing native identifiers, and research commit together.\n Call it even\n with no new research fields, and capture the returned company_id for\n manage_person action=save_discovered. A company name alone is not a save identity.\n `sources_by_field` must contain exactly every\n supplied non-null research field, with entries\n `{url, title?, observed_at}`. Example:\n `{\"allow_create\":true,\"idempotency_key\":\"pipeline/example.com/save-v1\",\"name\":\"Example\",\n \"industry\":\"Software & Technology\",\"website\":\"https://example.com\",\n \"company_summary\":\"Example sells …\",\n \"sources_by_field\":{\"company_summary\":[{\"url\":\"https://example.com/about\",\n \"title\":\"About\",\"observed_at\":\"2026-07-30T20:00:00Z\"}]}}`.\n\nHypothesis-ledger actions (VRU-840 — beliefs with scoreboards, never prose):\n- save_claim: record one falsifiable belief. `payload` = {statement,\n scope ({person_id|company_id|deal_id|objective_id|segment|tenant}),\n origin (diagnostic|system|operator|pin|experiment),\n invalidating_conditions?: [..], evidence?: [{kind, payload, source,\n method?, staleness_class (durable|slow|fast|volatile),\n trust? (first_party|untrusted_capture|third_party), stance?\n (supports|contradicts), weight?, person_id?|company_id?|\n deal_id?|objective_ref?|tenant_scoped? (accounts are the tenant-company\n pair — link company_id)}]}. Confidence is derived from the\n linked evidence and cannot be asserted; identical evidence payloads\n dedupe. `origin='diagnostic'` requires non-empty evidence and\n invalidating_conditions, so a diagnostic cannot save unsupported prose.\n Positioning-diagnostic scopes (`scope.surface='positioning_diagnostic'`)\n always need evidence + invalidating_conditions (any origin) and must\n carry tenant=true, a `dimension`, a trimmed `segment`, and — for\n icp_reachability / price_plausibility / motion_fit only — a cohort\n `objective_id` anchor plus a structured\n `scope.test` ({version:'viability_test.v1', metric, comparator,\n threshold, min_sample>=20, window_days}) that the viability loop\n evaluates from spine outcomes. Returns the claim with its full\n scoreboard. Use `items` to save a batch (e.g. a positioning\n diagnostic's claim set).\n- save_evidence: mint one observation with provenance, optionally linking\n it to an existing claim (`payload.claim_id` + stance/weight).\n- record_claim_verdict: append a verdict (id = claim UUID; `payload` =\n {status, basis, confidence?, note?, experiment_id?, superseded_by?}).\n basis='causal' requires experiment_id — the laboratory honesty rule.\n A `retired` verdict may name `superseded_by` (the LIVE replacement\n claim's UUID) so readers can follow a retired scope to its successor;\n any non-retired verdict clears the pointer.\nRead claims with search type='claims' and fetch type='claim'.\n\nBatch research returns per-item results (partial failure is reported per\nitem, never silent). The facade's backward-compatible request cap is 100;\nenrich_account accepts up to 10 accounts per request. Operators should execute the smaller policy waves\ndocumented by pipeline-fill (10 companies or 5 people at a time) so\nprogress and retries stay bounded. find_linkedin also takes person-id\narrays. Payloads are validated by the underlying route's own schema.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n\nObjective/account brief support (objective_account_brief):\nProduct support is not permission. Inspect current work and follow the domain's authorization and review rules.\n- start: research action=start_account_brief. Delegate paid synthesis with explicit saved_public or refresh_public source scope for the exact objective/account and planning version. Refresh includes one company-domain search and live page verification. Reuse matching active or unresolved work; different modes conflict. Saved response IDs and terminal receipts recover automatically without another purchase.\n- list: fetch type=research_work_list. Read saved work and current scope eligibility before starting; no model execution.\n- inspect: fetch type=research_work. Read current Action state and result availability without retrying execution.\n- cancel: research action=cancel_account_brief. Stop continuation at the expected Action version. The worker cancels pending saved provider responses and records their observed usage; in-flight work may still incur cost.\n- brief: fetch type=account_brief. Read open Claims, server-copied citations and coverage from the saved artifact.\n- new_source_acquisition: research action=start_account_brief. Explicit refresh_public scope authorizes one paid company-domain search, durable receipt capture, and up to three live verified public pages. No private sources or automatic replay of unknown search purchases.\n- executor_transfer: unsupported. External-harness preparation, execution transfer and result handback are not accepted.\n- reconcile_provider_effect: unsupported. Manual repair of missing or unavailable provider responses is unsupported. Saved response IDs and terminal receipts recover automatically; new request IDs cannot replay an unknown purchase.\n- business_outcome_measurement: unsupported. A completed brief establishes saved research, not replies, opportunities or revenue.",
|
|
2377
|
+
"description": "Research\n\nRun prospect/company research and save the results — the consolidated research tool.\n\n- start_account_brief: explicitly delegate one objective/account brief to\n Vruum's durable worker. First fetch research_work_list with\n objective_id and company_id filters; inspect existing work and use the\n returned scope planning_version. Payload requires {objective_id,\n company_id, request_id (UUID), expected_planning_version (positive integer),\n source_mode (saved_public or refresh_public)}.\n Paid search and model work runs after this call and survives leaving the page.\n A matching active or unresolved job is reused; retain request_id on retries.\n Start only after the user requests this exact scope. A model suggestion\n is not approval. The native assistant uses its write approval card;\n an external harness must obtain its user's authorization before calling.\n saved_public uses permitted saved public sources and business configuration.\n refresh_public also authorizes one public-domain search and live verification\n of up to three company pages before synthesis. Search excerpts are not evidence.\n Retain the exact source_mode on retries; existing work with another mode\n conflicts. Failed or partial refreshes remain visible in source coverage.\n Neither mode grants private source access, transcript persistence, browser\n credential storage, or external-harness execution handoff.\n Poll fetch research_work; read Claims and citations with fetch account_brief,\n both id=returned Action UUID. The worker automatically recovers saved\n provider response IDs and terminal receipts after interruption.\n A missing or unavailable provider response needs operator investigation;\n manual repair is unsupported and a fresh request_id cannot authorize replay.\n- cancel_account_brief: id=Action UUID; payload={expected_version} from\n the current saved work. Stops continuation and requests cancellation of\n pending saved model responses. A dispatched search or model call may still cost\n money; cancellation does not prove the provider stopped.\n Both account-brief writes accept one request only, without items or batches.\n- preview_gaps: READ ONLY assignment, no research or spend. id=objective UUID;\n payload={subjects:[{type, company_id}], question_ids?, stage?,\n use_public_web?:true, use_history?:false}. Each subject names its type\n and exactly that type's ids: company {company_id}, person {person_id},\n person_at_company {person_id, company_id}, deal {deal_id}. Up to 20\n subjects and 40 unique gaps. Reuses current account answers across people.\n Equivalent reviewed fact definitions also reuse original observations across\n objectives when their subject, schema, sources, quality and freshness match.\n Reused answers retain original evidence IDs; do not save duplicate copies.\n Read gaps, question definitions, source permissions and limits before choosing work.\n- stop_gaps: id=objective UUID, payload={action_id}. Stop future calls and\n answer writes. Already sent provider work can finish.\n- propose_gaps: same input; saves an Action without executing research.\n- approve_gaps: id=objective UUID, payload={action_id}. Only after the user\n approves that exact saved assignment. Starts bounded Vruum research.\n Poll fetch research_run id=action UUID. Never repeat approval to retry.\n For research on YOUR compute, use preview_gaps, fetch research_sources,\n your permitted tools, then save_answer. Do not approve Vruum research as\n a substitute for external research. Your harness pays its own compute.\n Use the exact subject, question ID and definition fingerprint from the\n assignment. Public URL excerpts remain reported. Never assert customer\n confirmation without an explicit operator attestation.\n- save_answer: record one answer for a saved objective research question\n (id = objective UUID; payload = {idempotency_key, question_id,\n definition_fingerprint, subject (one preview_gaps subject),\n state: answered|unknown|unavailable, value, source: {kind, reference?,\n excerpt, observed_at}, note?, supersedes_evidence_id?}). Read the question\n and answer_schema through fetch research_answers first. Source kinds:\n operator_report, public_url (reported only), activity, evidence, meeting,\n customer_confirmation (explicit operator attestation). Existing references\n must match the tenant, subject, excerpt and original observation time.\n Exact retries retain their UUID; changed content needs a new UUID.\n Corrections explicitly supersede one observation. Answers never authorize\n outreach. Generic save_evidence/save_claim cannot write research answers.\n\nLookup and enrichment actions (results are returned, not stored unless\nnoted). Synchronous lookups without a saved result (find_email,\nlinkedin_fetch, enrich_company, careers_parse) are on research_lookup.\n- find_linkedin: locate a person's LinkedIn URL (id = person UUID;\n `payload` optional {name_override?, company_override?, auto_save?} —\n auto_save stores a high-confidence match).\n- enrich_account: acquire a bounded first-party evidence bundle for a\n tenant-visible account (id = canonical company UUID). The response also\n carries canonical company fields, cached shared research, and freshness\n metadata for the harness to combine with its own web and MCP sources.\n Persist sourced conclusions with save_company. research_lookup\n action=enrich_company remains the domain/page website-fetch primitive.\n- enrich_person: enrich each person according to missing contact and profile\n fields (id = person UUID, or an array of up to 100;\n `payload` optional {force_refresh?}). Returns a job_id; poll it with\n fetch type=job. Outcomes report a stable reason code, and jobs with any\n errored outcome terminate as completed_with_failures. Successful outcomes\n report readiness=email_ready, incomplete, or manual_review plus the\n canonical employer binding.\n Vruum applies separate monthly profile and Hunter-credit soft limits.\n Harness web search and other MCP tools remain complementary for deeper\n research. The legacy enrich_profile name is an alias.\n- enrich: canonical scoped enrichment. It inspects each person and runs\n only the needed profile or verified-email work. Pass `payload` with exactly one of\n `{person_ids: [...]}`, `{objective_id: ...}`, or `{list_id: ...}`.\n Returns a job_id; poll it with fetch type=job. The enrich_emails action\n remains as a compatibility alias for the same scoped planner.\n\nSave actions (write research rows):\n- save_person: UPDATE research on an EXISTING person — pass the person UUID\n as `payload.person_id` (preferred; refreshes researched_at and the\n research fields in place), or matching email/linkedin anchors. Cannot\n create: new prospects go through manage_person action=save_discovered\n with `payload.person` + `payload.assessment`. Never pass the person UUID\n as `id` — this action takes no id.\n- save_company: atomically patch sourced public company research. Pass\n `payload={company_id?, allow_create?, idempotency_key, name, industry, person_id?, website?, linkedin_url?,\n company_summary?, company_stage?, current_priorities?, funding_data?,\n growth_metrics?, sources_by_field}`.\n `industry` is required and must be one CanonicalIndustry value:\n Agriculture, Construction, Consumer Goods, Consumer Services, Education,\n Energy & Utilities, Financial Services, Government, Healthcare,\n Hospitality & Travel, Legal Services, Manufacturing, Marketing & Advertising,\n Media & Entertainment, Nonprofit, Professional Services, Real Estate,\n Retail & E-commerce, Software & Technology, Staffing & Recruiting,\n Telecommunications, Transportation & Logistics, Wholesale & Distribution,\n or Other. Provider labels and Unspecified are rejected.\n Omitted research fields are preserved; explicit null clears. When\n researching a specific person's employer,\n ALWAYS pass their UUID as `payload.person_id` — the response's\n `person_link` confirms the write landed on that person's linked company\n (repointing an anchorless duplicate link when needed); a `mismatch`\n status means the person's touches will NOT see this research, and a\n `conflict` status is a transient race — replay the identical payload\n (person_id is exempt from the idempotency hash, so adding it to a\n replay is the supported repair).\n For a researched-prospect save, save_company is also the company identity resolution step.\n For an existing account, ALWAYS pass payload.company_id, including the ID\n returned by enrich_account. Updates never create or merge a company.\n Otherwise call save_company with allow_create=true plus name and website\n and/or linkedin_url. Never combine company_id with allow_create=true.\n Conflicts require identity reconciliation; never retry by dropping the ID.\n Identity selection, missing native identifiers, and research commit together.\n Call it even\n with no new research fields, and capture the returned company_id for\n manage_person action=save_discovered. A company name alone is not a save identity.\n `sources_by_field` must contain exactly every\n supplied non-null research field, with entries\n `{url, title?, observed_at}`. Example:\n `{\"allow_create\":true,\"idempotency_key\":\"pipeline/example.com/save-v1\",\"name\":\"Example\",\n \"industry\":\"Software & Technology\",\"website\":\"https://example.com\",\n \"company_summary\":\"Example sells …\",\n \"sources_by_field\":{\"company_summary\":[{\"url\":\"https://example.com/about\",\n \"title\":\"About\",\"observed_at\":\"2026-07-30T20:00:00Z\"}]}}`.\n\nHypothesis-ledger actions (VRU-840 — beliefs with scoreboards, never prose):\n- save_claim: record one falsifiable belief. `payload` = {statement,\n scope ({person_id|company_id|deal_id|objective_id|segment|tenant}),\n origin (diagnostic|system|operator|pin|experiment),\n invalidating_conditions?: [..], evidence?: [{kind, payload, source,\n method?, staleness_class (durable|slow|fast|volatile),\n trust? (first_party|untrusted_capture|third_party), stance?\n (supports|contradicts), weight?, person_id?|company_id?|\n deal_id?|objective_ref?|tenant_scoped? (accounts are the tenant-company\n pair — link company_id)}]}. Confidence is derived from the\n linked evidence and cannot be asserted; identical evidence payloads\n dedupe. `origin='diagnostic'` requires non-empty evidence and\n invalidating_conditions, so a diagnostic cannot save unsupported prose.\n Positioning-diagnostic scopes (`scope.surface='positioning_diagnostic'`)\n always need evidence + invalidating_conditions (any origin) and must\n carry tenant=true, a `dimension`, a trimmed `segment`, and — for\n icp_reachability / price_plausibility / motion_fit only — a cohort\n `objective_id` anchor plus a structured\n `scope.test` ({version:'viability_test.v1', metric, comparator,\n threshold, min_sample>=20, window_days}) that the viability loop\n evaluates from spine outcomes. Returns the claim with its full\n scoreboard. Use `items` to save a batch (e.g. a positioning\n diagnostic's claim set).\n- save_evidence: mint one observation with provenance, optionally linking\n it to an existing claim (`payload.claim_id` + stance/weight).\n- record_claim_verdict: append a verdict (id = claim UUID; `payload` =\n {status, basis, confidence?, note?, experiment_id?, superseded_by?}).\n basis='causal' requires experiment_id — the laboratory honesty rule.\n A `retired` verdict may name `superseded_by` (the LIVE replacement\n claim's UUID) so readers can follow a retired scope to its successor;\n any non-retired verdict clears the pointer.\nRead claims with search type='claims' and fetch type='claim'.\n\nBatch research returns per-item results (partial failure is reported per\nitem, never silent). The facade's backward-compatible request cap is 100;\nenrich_account accepts up to 10 accounts per request. Operators should execute the smaller policy waves\ndocumented by pipeline-fill (10 companies or 5 people at a time) so\nprogress and retries stay bounded. find_linkedin also takes person-id\narrays. Payloads are validated by the underlying route's own schema.\n\n### Responses:\n\n**200**: Successful Response (Success Response)\nContent-Type: application/json\n\nObjective/account brief support (objective_account_brief):\nProduct support is not permission. Inspect current work and follow the domain's authorization and review rules.\n- start: research action=start_account_brief. Delegate paid synthesis with explicit saved_public or refresh_public source scope for the exact objective/account and planning version. Refresh includes one company-domain search and live page verification. Reuse matching active or unresolved work; different modes conflict. Saved response IDs and terminal receipts recover automatically without another purchase.\n- list: fetch type=research_work_list. Read saved work and current scope eligibility before starting; no model execution.\n- inspect: fetch type=research_work. Read current Action state and result availability without retrying execution.\n- cancel: research action=cancel_account_brief. Stop continuation at the expected Action version. The worker cancels pending saved provider responses and records their observed usage; in-flight work may still incur cost.\n- brief: fetch type=account_brief. Read open Claims, server-copied citations and coverage from the saved artifact.\n- new_source_acquisition: research action=start_account_brief. Explicit refresh_public scope authorizes one paid company-domain search, durable receipt capture, and up to three live verified public pages. No private sources or automatic replay of unknown search purchases.\n- executor_transfer: unsupported. External-harness preparation, execution transfer and result handback are not accepted.\n- reconcile_provider_effect: unsupported. Manual repair of missing or unavailable provider responses is unsupported. Saved response IDs and terminal receipts recover automatically; new request IDs cannot replay an unknown purchase.\n- business_outcome_measurement: unsupported. A completed brief establishes saved research, not replies, opportunities or revenue.",
|
|
2307
2378
|
"inputSchema": {
|
|
2308
2379
|
"properties": {
|
|
2309
2380
|
"action": {
|