@sellable/mcp 0.1.861 → 0.1.862-wip.phase187.20260811.3
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/dist/agent-opportunity-sequence-context.d.ts +26 -0
- package/dist/agent-opportunity-sequence-context.js +48 -0
- package/dist/agent-tool-names.d.ts +2 -2
- package/dist/agent-tool-names.js +7 -0
- package/dist/server.js +48 -8
- package/dist/tools/opportunity-sequences.d.ts +232 -0
- package/dist/tools/opportunity-sequences.js +181 -0
- package/dist/tools/registry.d.ts +198 -0
- package/dist/tools/registry.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { McpAgentServiceContext } from "./agent-service-auth.js";
|
|
2
|
+
export declare const OPPORTUNITY_SEQUENCE_TOOL_NAMES: readonly ["opportunity_sequence_next_page", "opportunity_sequence_enroll", "opportunity_sequence_record"];
|
|
3
|
+
export type OpportunitySequenceToolName = (typeof OPPORTUNITY_SEQUENCE_TOOL_NAMES)[number];
|
|
4
|
+
export type AgentOpportunitySequenceContext = Readonly<{
|
|
5
|
+
workspaceId: string;
|
|
6
|
+
agentId: string;
|
|
7
|
+
credentialId: string;
|
|
8
|
+
credentialGeneration: number;
|
|
9
|
+
runtimeGeneration: number;
|
|
10
|
+
adminGenerationId: string;
|
|
11
|
+
adminGenerationFence: string;
|
|
12
|
+
}>;
|
|
13
|
+
export declare const OPPORTUNITY_SEQUENCE_CONTEXT_REQUIRED_ERROR = "opportunity_sequence_current_admin_context_required";
|
|
14
|
+
export declare function isOpportunitySequenceTool(name: string): name is OpportunitySequenceToolName;
|
|
15
|
+
/**
|
|
16
|
+
* Actorless is deliberate for these three tools only. Authority is the
|
|
17
|
+
* credential-bound home Agent plus the immutable ADMIN runtime tuple; no tool
|
|
18
|
+
* argument participates in this resolution.
|
|
19
|
+
*/
|
|
20
|
+
export declare function agentOpportunitySequenceContext(name: string, principal: McpAgentServiceContext | null | undefined, env?: Record<string, string | undefined>): {
|
|
21
|
+
required: false;
|
|
22
|
+
context: null;
|
|
23
|
+
} | {
|
|
24
|
+
required: true;
|
|
25
|
+
context: AgentOpportunitySequenceContext | null;
|
|
26
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const OPPORTUNITY_SEQUENCE_TOOL_NAMES = Object.freeze([
|
|
2
|
+
"opportunity_sequence_next_page",
|
|
3
|
+
"opportunity_sequence_enroll",
|
|
4
|
+
"opportunity_sequence_record",
|
|
5
|
+
]);
|
|
6
|
+
export const OPPORTUNITY_SEQUENCE_CONTEXT_REQUIRED_ERROR = "opportunity_sequence_current_admin_context_required";
|
|
7
|
+
export function isOpportunitySequenceTool(name) {
|
|
8
|
+
return OPPORTUNITY_SEQUENCE_TOOL_NAMES.includes(name);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Actorless is deliberate for these three tools only. Authority is the
|
|
12
|
+
* credential-bound home Agent plus the immutable ADMIN runtime tuple; no tool
|
|
13
|
+
* argument participates in this resolution.
|
|
14
|
+
*/
|
|
15
|
+
export function agentOpportunitySequenceContext(name, principal, env = process.env) {
|
|
16
|
+
if (!isOpportunitySequenceTool(name)) {
|
|
17
|
+
return { required: false, context: null };
|
|
18
|
+
}
|
|
19
|
+
const runtimeGeneration = Number(env.SELLABLE_AGENT_RUNTIME_GENERATION ??
|
|
20
|
+
env.SELLABLE_RUNTIME_GENERATION ??
|
|
21
|
+
"");
|
|
22
|
+
const adminGenerationId = env.SELLABLE_AGENT_ADMIN_GENERATION_ID?.trim() ?? "";
|
|
23
|
+
const adminGenerationFence = env.SELLABLE_AGENT_ADMIN_GENERATION_FENCE?.trim() ?? "";
|
|
24
|
+
const current = principal?.kind === "agent_service" &&
|
|
25
|
+
env.SELLABLE_AGENT_SERVER_AUTHENTICATED_KIND?.trim().toUpperCase() ===
|
|
26
|
+
"ADMIN" &&
|
|
27
|
+
env.SELLABLE_AGENT_WORKSPACE_ID?.trim() === principal.workspaceId &&
|
|
28
|
+
env.SELLABLE_AGENT_ID?.trim() === principal.agentId &&
|
|
29
|
+
Number(env.SELLABLE_AGENT_CREDENTIAL_GENERATION) === principal.generation &&
|
|
30
|
+
Number.isSafeInteger(runtimeGeneration) &&
|
|
31
|
+
runtimeGeneration > 0 &&
|
|
32
|
+
/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(adminGenerationId) &&
|
|
33
|
+
/^[1-9][0-9]{0,19}$/.test(adminGenerationFence);
|
|
34
|
+
return {
|
|
35
|
+
required: true,
|
|
36
|
+
context: current
|
|
37
|
+
? {
|
|
38
|
+
workspaceId: principal.workspaceId,
|
|
39
|
+
agentId: principal.agentId,
|
|
40
|
+
credentialId: principal.credentialId,
|
|
41
|
+
credentialGeneration: principal.generation,
|
|
42
|
+
runtimeGeneration,
|
|
43
|
+
adminGenerationId,
|
|
44
|
+
adminGenerationFence,
|
|
45
|
+
}
|
|
46
|
+
: null,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* manifests. Keep this free of tool implementation imports so Next can bundle
|
|
4
4
|
* it; registry parity is enforced in sellable-agent-tool-policy.test.ts.
|
|
5
5
|
*/
|
|
6
|
-
export declare const SELLABLE_MCP_TOOL_NAMES: readonly ["add_column", "add_on_demand_leads", "add_rubric_item", "add_teammate", "add_to_comment_campaign", "add_to_connection_campaign", "add_to_inmail_campaign", "archive_campaign", "attach_recommended_sequence", "attach_sequence", "bootstrap_create_campaign", "bootstrap_engage", "bootstrap_engage_multi", "bootstrap_find_leads", "bulk_enrich_with_prospeo", "calculate_linkedin_hook_preview", "cancel_campaign_message_preparation", "cancel_find_leads", "cancel_lead_import", "capture_post_idea", "check_inbox_reply_eligibility", "check_rubric", "commit_blueprint", "complete_sender_research", "confirm_harvest_job_companies", "confirm_lead_list", "confirm_prospeo_company_accounts", "copy_sender_config", "create_campaign", "create_on_demand_campaign", "create_on_demand_table", "create_workflow_table", "create_workspace", "decide_agent_endpoint_proposal", "delete_column", "delete_rubric_item", "draft_rubrics", "duplicate_campaign", "enrich_with_prospeo", "export_table_csv", "export_workspace_csv", "fetch_company", "fetch_company_posts", "fetch_linkedin_posts", "fetch_linkedin_profile", "fetch_post_engagers", "fill_campaign_horizon", "get_active_workspace", "get_agent_endpoint_run", "get_agent_soul", "get_auth_status", "get_campaign", "get_campaign_context", "get_campaign_framework", "get_campaign_message_preparation_status", "get_campaign_messages_preview", "get_campaign_navigation_state", "get_campaign_refill_state", "get_campaign_table_schema", "get_campaign_waterfall", "get_campaigns", "get_column_schema", "get_company_info", "get_engage_memory", "get_engage_state", "get_engaged_posts", "get_find_leads_run", "get_inbox_thread", "get_integration_connection_status", "get_linkedin_profile", "get_or_create_direct_campaign_table", "get_post_draft", "get_post_find_leads_scout_registry", "get_post_idea", "get_prospeo_credits", "get_provider_prompt", "get_published_post", "get_refill_target_plan", "get_rows", "get_rows_minimal", "get_runtime_identity", "get_scheduler_fill_capacity", "get_sender", "get_sender_routing", "get_source_scout_registry", "get_subskill_asset", "get_subskill_prompt", "get_table_rows", "get_user_posts", "get_workspace", "import_leads", "init_on_demand_sequence", "integrations_call_tool", "integrations_describe_tool", "integrations_list_tools", "list_agent_endpoint_runs", "list_agent_endpoints", "list_column_types", "list_dnc_entries", "list_post_draft_iterations", "list_post_drafts", "list_post_ideas", "list_published_posts", "list_senders", "list_subskill_prompts", "list_tables", "list_workspaces", "load_csv_dnc_entries", "load_csv_domains", "load_csv_linkedin_leads", "lookup_sales_nav_filter", "mark_post_published", "migrate_flat_configs", "pause_campaign", "pause_direct_campaign", "pause_on_demand_campaign", "preflight_find_leads_provider", "prepare_campaign_ab_test", "publish_agent_endpoint", "queue_campaign_cells", "queue_cells", "record_campaign_review_batch", "record_engage_proven_search", "refill_sends", "refill_v3_advance", "refill_v3_continue", "refill_v3_edit_selected_campaign", "refill_v3_fill_ready", "refill_v3_world_state", "refresh_paid_inmail_credits", "refresh_sender_engagement", "reissue_find_leads_watch_link", "render_linkedin_post_preview", "reorder_columns", "resolve_campaign_fill_route", "revise_message_template_and_rerun", "rotate_agent_endpoint_key", "run_scheduler_sweep", "save_domain_filters", "save_hook_research", "save_post_draft", "save_rubrics", "search_apollo", "search_available_integrations", "search_engagement_posts", "search_harvest_jobs", "search_inbox_threads", "search_prospeo", "search_prospeo_companies", "search_sales_nav", "search_signals", "search_subskill_prompts", "select_campaign_cells", "select_necessary_rubrics", "select_promising_posts", "send_inbox_draft", "send_inbox_manual_reply", "set_active_workspace", "set_campaign_waterfall_order", "set_company_info", "set_engage_state", "set_engage_style_guide", "set_headline_icp_criteria", "set_sender_calendar_link", "set_sender_routing", "setup_evergreen_campaigns", "start_campaign", "start_campaign_message_preparation", "start_cli_login", "start_direct_campaign", "start_integration_connection", "start_on_demand_campaign", "stop_agent_endpoint_run", "update_agent_soul", "update_campaign", "update_campaign_brief", "update_cell", "update_column", "update_find_leads_run", "update_inbox_draft", "update_post_draft", "update_published_post_metrics", "update_rubric_item", "upsert_engage_tracked_person", "upsert_rubric", "validate_campaign1_kickoff_handoff", "verify_table_row", "wait_for_campaign_processing", "wait_for_campaign_table_ready", "wait_for_cli_login", "wait_for_find_leads_run", "wait_for_lead_list_ready", "wait_for_rubric_results"];
|
|
6
|
+
export declare const SELLABLE_MCP_TOOL_NAMES: readonly ["add_column", "add_on_demand_leads", "add_rubric_item", "add_teammate", "add_to_comment_campaign", "add_to_connection_campaign", "add_to_inmail_campaign", "archive_campaign", "attach_recommended_sequence", "attach_sequence", "bootstrap_create_campaign", "bootstrap_engage", "bootstrap_engage_multi", "bootstrap_find_leads", "bulk_enrich_with_prospeo", "calculate_linkedin_hook_preview", "cancel_campaign_message_preparation", "cancel_find_leads", "cancel_lead_import", "capture_post_idea", "check_inbox_reply_eligibility", "check_rubric", "commit_blueprint", "complete_sender_research", "confirm_harvest_job_companies", "confirm_lead_list", "confirm_prospeo_company_accounts", "copy_sender_config", "create_campaign", "create_on_demand_campaign", "create_on_demand_table", "create_workflow_table", "create_workspace", "decide_agent_endpoint_proposal", "delete_column", "delete_rubric_item", "draft_rubrics", "duplicate_campaign", "enrich_with_prospeo", "export_table_csv", "export_workspace_csv", "fetch_company", "fetch_company_posts", "fetch_linkedin_posts", "fetch_linkedin_profile", "fetch_post_engagers", "fill_campaign_horizon", "get_active_workspace", "get_agent_endpoint_run", "get_agent_soul", "get_auth_status", "get_campaign", "get_campaign_context", "get_campaign_framework", "get_campaign_message_preparation_status", "get_campaign_messages_preview", "get_campaign_navigation_state", "get_campaign_refill_state", "get_campaign_table_schema", "get_campaign_waterfall", "get_campaigns", "get_column_schema", "get_company_info", "get_engage_memory", "get_engage_state", "get_engaged_posts", "get_find_leads_run", "get_inbox_thread", "get_integration_connection_status", "get_linkedin_profile", "get_or_create_direct_campaign_table", "get_post_draft", "get_post_find_leads_scout_registry", "get_post_idea", "get_prospeo_credits", "get_provider_prompt", "get_published_post", "get_refill_target_plan", "get_rows", "get_rows_minimal", "get_runtime_identity", "get_scheduler_fill_capacity", "get_sender", "get_sender_routing", "get_source_scout_registry", "get_subskill_asset", "get_subskill_prompt", "get_table_rows", "get_user_posts", "get_workspace", "import_leads", "init_on_demand_sequence", "integrations_call_tool", "integrations_describe_tool", "integrations_list_tools", "list_agent_endpoint_runs", "list_agent_endpoints", "list_column_types", "list_dnc_entries", "list_post_draft_iterations", "list_post_drafts", "list_post_ideas", "list_published_posts", "list_senders", "list_subskill_prompts", "list_tables", "list_workspaces", "load_csv_dnc_entries", "load_csv_domains", "load_csv_linkedin_leads", "lookup_sales_nav_filter", "mark_post_published", "migrate_flat_configs", "opportunity_sequence_enroll", "opportunity_sequence_next_page", "opportunity_sequence_record", "pause_campaign", "pause_direct_campaign", "pause_on_demand_campaign", "preflight_find_leads_provider", "prepare_campaign_ab_test", "publish_agent_endpoint", "queue_campaign_cells", "queue_cells", "record_campaign_review_batch", "record_engage_proven_search", "refill_sends", "refill_v3_advance", "refill_v3_continue", "refill_v3_edit_selected_campaign", "refill_v3_fill_ready", "refill_v3_world_state", "refresh_paid_inmail_credits", "refresh_sender_engagement", "reissue_find_leads_watch_link", "render_linkedin_post_preview", "reorder_columns", "resolve_campaign_fill_route", "revise_message_template_and_rerun", "rotate_agent_endpoint_key", "run_scheduler_sweep", "save_domain_filters", "save_hook_research", "save_post_draft", "save_rubrics", "search_apollo", "search_available_integrations", "search_engagement_posts", "search_harvest_jobs", "search_inbox_threads", "search_prospeo", "search_prospeo_companies", "search_sales_nav", "search_signals", "search_subskill_prompts", "select_campaign_cells", "select_necessary_rubrics", "select_promising_posts", "send_inbox_draft", "send_inbox_manual_reply", "set_active_workspace", "set_campaign_waterfall_order", "set_company_info", "set_engage_state", "set_engage_style_guide", "set_headline_icp_criteria", "set_sender_calendar_link", "set_sender_routing", "setup_evergreen_campaigns", "start_campaign", "start_campaign_message_preparation", "start_cli_login", "start_direct_campaign", "start_integration_connection", "start_on_demand_campaign", "stop_agent_endpoint_run", "update_agent_soul", "update_campaign", "update_campaign_brief", "update_cell", "update_column", "update_find_leads_run", "update_inbox_draft", "update_post_draft", "update_published_post_metrics", "update_rubric_item", "upsert_engage_tracked_person", "upsert_rubric", "validate_campaign1_kickoff_handoff", "verify_table_row", "wait_for_campaign_processing", "wait_for_campaign_table_ready", "wait_for_cli_login", "wait_for_find_leads_run", "wait_for_lead_list_ready", "wait_for_rubric_results"];
|
|
7
7
|
/**
|
|
8
8
|
* Explicit mutation classification lives beside (but outside) the flat tool
|
|
9
9
|
* registry. Neither this list nor `isMutatingTool` is an input to
|
|
10
10
|
* `compileAgentToolPolicy`, so editing it cannot move the fleet-pinned
|
|
11
11
|
* `policyHash`.
|
|
12
12
|
*/
|
|
13
|
-
export declare const MUTATING_TOOL_NAMES: readonly ["publish_agent_endpoint", "rotate_agent_endpoint_key", "decide_agent_endpoint_proposal", "stop_agent_endpoint_run", "pause_campaign", "archive_campaign", "update_campaign", "fill_campaign_horizon", "set_campaign_waterfall_order", "set_sender_routing", "send_inbox_draft", "send_inbox_manual_reply", "load_csv_dnc_entries", "update_cell", "queue_cells", "check_rubric", "queue_campaign_cells", "start_campaign_message_preparation", "refill_v3_fill_ready", "refill_v3_edit_selected_campaign", "refill_v3_advance", "refill_v3_continue"];
|
|
13
|
+
export declare const MUTATING_TOOL_NAMES: readonly ["publish_agent_endpoint", "rotate_agent_endpoint_key", "decide_agent_endpoint_proposal", "stop_agent_endpoint_run", "pause_campaign", "archive_campaign", "update_campaign", "fill_campaign_horizon", "set_campaign_waterfall_order", "set_sender_routing", "send_inbox_draft", "send_inbox_manual_reply", "load_csv_dnc_entries", "update_cell", "queue_cells", "check_rubric", "queue_campaign_cells", "start_campaign_message_preparation", "opportunity_sequence_enroll", "opportunity_sequence_record", "refill_v3_fill_ready", "refill_v3_edit_selected_campaign", "refill_v3_advance", "refill_v3_continue"];
|
|
14
14
|
export declare function isMutatingTool(name: string): boolean;
|
|
15
15
|
export declare const CROSS_WORKSPACE_EXPLICIT_WORKSPACE_REQUIRED: {
|
|
16
16
|
readonly code: "cross_workspace_explicit_workspace_required";
|
package/dist/agent-tool-names.js
CHANGED
|
@@ -117,6 +117,9 @@ export const SELLABLE_MCP_TOOL_NAMES = [
|
|
|
117
117
|
"lookup_sales_nav_filter",
|
|
118
118
|
"mark_post_published",
|
|
119
119
|
"migrate_flat_configs",
|
|
120
|
+
"opportunity_sequence_enroll",
|
|
121
|
+
"opportunity_sequence_next_page",
|
|
122
|
+
"opportunity_sequence_record",
|
|
120
123
|
"pause_campaign",
|
|
121
124
|
"pause_direct_campaign",
|
|
122
125
|
"pause_on_demand_campaign",
|
|
@@ -225,6 +228,10 @@ export const MUTATING_TOOL_NAMES = [
|
|
|
225
228
|
"check_rubric",
|
|
226
229
|
"queue_campaign_cells",
|
|
227
230
|
"start_campaign_message_preparation",
|
|
231
|
+
// Phase 187: these two mutations are home-bound to the current ADMIN
|
|
232
|
+
// service principal. server.ts exempts only them from caller workspace proof.
|
|
233
|
+
"opportunity_sequence_enroll",
|
|
234
|
+
"opportunity_sequence_record",
|
|
228
235
|
// Phase 146.5 Plan 08: the bounded Refill V3 mutation. Its sibling
|
|
229
236
|
// `refill_v3_world_state` is an OBSERVATION and deliberately stays out.
|
|
230
237
|
"refill_v3_fill_ready",
|
package/dist/server.js
CHANGED
|
@@ -5,6 +5,7 @@ import { HttpAgentApprovalEffectPort } from "./agent-approval-effect-port.js";
|
|
|
5
5
|
import { AGENT_INTEGRATION_CONTEXT_REQUIRED_ERROR, agentIntegrationRequestActor, } from "./agent-integration-request-context.js";
|
|
6
6
|
import { ensureAgentScope, getAgentScope, hasRecordedAgentScope, } from "./agent-scope.js";
|
|
7
7
|
import { createMcpCredentialBoundary, resolveMcpCredentialIntent, } from "./agent-service-auth.js";
|
|
8
|
+
import { agentOpportunitySequenceContext } from "./agent-opportunity-sequence-context.js";
|
|
8
9
|
import { crossWorkspaceMutationRefusal } from "./agent-tool-names.js";
|
|
9
10
|
import { compileAgentToolPolicy, createAgentMcpAuthorizationHandlers, } from "./agent-tool-policy.js";
|
|
10
11
|
import { getApi } from "./api.js";
|
|
@@ -50,6 +51,7 @@ import { cancelLeadImport, confirmLeadList, confirmProspeoCompanyAccounts, getPr
|
|
|
50
51
|
import { fetchCompany, fetchCompanyPosts, fetchLinkedInPosts, fetchLinkedInProfile, fetchPostEngagers, getLinkedInProfile, getUserPosts, } from "./tools/linkedin.js";
|
|
51
52
|
import { getCampaignNavigationState } from "./tools/navigation.js";
|
|
52
53
|
import { addOnDemandLeads, createOnDemandCampaign, createOnDemandTable, initOnDemandSequence, pauseOnDemandCampaign, startOnDemandCampaign, } from "./tools/one-off.js";
|
|
54
|
+
import { opportunitySequenceEnroll, opportunitySequenceNextPage, opportunitySequenceRecord, } from "./tools/opportunity-sequences.js";
|
|
53
55
|
import { upsertRubric } from "./tools/processing.js";
|
|
54
56
|
import { completeSenderResearch, getPostFindLeadsScoutRegistry, getSourceScoutRegistry, getSubskillAsset, getSubskillPrompt, listSubskillPrompts, searchSubskillPrompts, } from "./tools/prompts.js";
|
|
55
57
|
import { preflightFindLeadsProvider } from "./tools/provider-preflight.js";
|
|
@@ -201,6 +203,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
201
203
|
],
|
|
202
204
|
};
|
|
203
205
|
}
|
|
206
|
+
const sequenceResolution = agentOpportunitySequenceContext(name, boundary.mode === "agent_service" &&
|
|
207
|
+
boundary.context?.principal?.kind === "agent_service"
|
|
208
|
+
? boundary.context.principal
|
|
209
|
+
: null);
|
|
210
|
+
if (sequenceResolution.required && !sequenceResolution.context) {
|
|
211
|
+
return {
|
|
212
|
+
isError: true,
|
|
213
|
+
content: [
|
|
214
|
+
{
|
|
215
|
+
type: "text",
|
|
216
|
+
text: JSON.stringify({
|
|
217
|
+
ok: false,
|
|
218
|
+
error: "opportunity_sequence_current_admin_context_required",
|
|
219
|
+
decision: "DENY",
|
|
220
|
+
}),
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
};
|
|
224
|
+
}
|
|
204
225
|
let agentEffectId;
|
|
205
226
|
if (boundary.mode === "agent_service") {
|
|
206
227
|
const authorization = boundary.authorization;
|
|
@@ -223,15 +244,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
223
244
|
};
|
|
224
245
|
}
|
|
225
246
|
if (boundary.context?.principal?.kind !== "endpoint_run") {
|
|
226
|
-
|
|
227
|
-
|
|
247
|
+
// These two mutations are pinned to the credential-derived home ADMIN
|
|
248
|
+
// context above. No model workspace selector exists, so only this exact
|
|
249
|
+
// pair bypasses the generic cross-workspace explicit-selector guard.
|
|
250
|
+
const homeBoundSequenceMutation = sequenceResolution.context !== null &&
|
|
251
|
+
(name === "opportunity_sequence_enroll" ||
|
|
252
|
+
name === "opportunity_sequence_record");
|
|
253
|
+
if (!homeBoundSequenceMutation) {
|
|
254
|
+
if (!hasRecordedAgentScope()) {
|
|
255
|
+
await ensureAgentScope(() => getApi().get("/api/v3/workspaces"));
|
|
256
|
+
}
|
|
228
257
|
}
|
|
229
|
-
const workspaceRefusal =
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
258
|
+
const workspaceRefusal = homeBoundSequenceMutation
|
|
259
|
+
? null
|
|
260
|
+
: crossWorkspaceMutationRefusal({
|
|
261
|
+
scope: getAgentScope(),
|
|
262
|
+
toolName: name,
|
|
263
|
+
workspaceBinding: authorization.policy?.workspaceBinding,
|
|
264
|
+
args,
|
|
265
|
+
});
|
|
235
266
|
if (workspaceRefusal) {
|
|
236
267
|
return {
|
|
237
268
|
isError: true,
|
|
@@ -733,6 +764,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
733
764
|
case "init_one_off_sequence":
|
|
734
765
|
result = await initOnDemandSequence(args);
|
|
735
766
|
break;
|
|
767
|
+
case "opportunity_sequence_next_page":
|
|
768
|
+
result = await opportunitySequenceNextPage(args, sequenceResolution.context);
|
|
769
|
+
break;
|
|
770
|
+
case "opportunity_sequence_enroll":
|
|
771
|
+
result = await opportunitySequenceEnroll(args, sequenceResolution.context);
|
|
772
|
+
break;
|
|
773
|
+
case "opportunity_sequence_record":
|
|
774
|
+
result = await opportunitySequenceRecord(args, sequenceResolution.context);
|
|
775
|
+
break;
|
|
736
776
|
case "add_to_inmail_campaign":
|
|
737
777
|
result = await addToInmailCampaign(args);
|
|
738
778
|
break;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import type { AgentOpportunitySequenceContext } from "../agent-opportunity-sequence-context.js";
|
|
2
|
+
export declare const OPPORTUNITY_SEQUENCE_RESULT_SCHEMA: {
|
|
3
|
+
readonly type: "object";
|
|
4
|
+
readonly properties: {
|
|
5
|
+
readonly ok: {
|
|
6
|
+
readonly type: "boolean";
|
|
7
|
+
};
|
|
8
|
+
readonly error: {
|
|
9
|
+
readonly type: readonly ["string", "null"];
|
|
10
|
+
};
|
|
11
|
+
readonly result: {};
|
|
12
|
+
};
|
|
13
|
+
readonly required: readonly ["ok", "error", "result"];
|
|
14
|
+
readonly additionalProperties: false;
|
|
15
|
+
};
|
|
16
|
+
export declare const opportunitySequenceToolDefinitions: readonly [{
|
|
17
|
+
readonly name: "opportunity_sequence_next_page";
|
|
18
|
+
readonly description: "Read one bounded page of server-selected Lightfield sequence candidates, due work, and exact inbound transitions. Finish a returned continuation before starting a new checkpoint scan.";
|
|
19
|
+
readonly inputSchema: {
|
|
20
|
+
readonly type: "object";
|
|
21
|
+
readonly properties: {
|
|
22
|
+
readonly continuation: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly minLength: 1;
|
|
25
|
+
readonly maxLength: 8192;
|
|
26
|
+
};
|
|
27
|
+
readonly checkpoint: {
|
|
28
|
+
readonly type: "string";
|
|
29
|
+
readonly minLength: 1;
|
|
30
|
+
readonly maxLength: 8192;
|
|
31
|
+
};
|
|
32
|
+
readonly limit: {
|
|
33
|
+
readonly type: "integer";
|
|
34
|
+
readonly minimum: 1;
|
|
35
|
+
readonly maximum: 50;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
readonly required: readonly [];
|
|
39
|
+
readonly additionalProperties: false;
|
|
40
|
+
};
|
|
41
|
+
readonly outputSchema: {
|
|
42
|
+
readonly type: "object";
|
|
43
|
+
readonly properties: {
|
|
44
|
+
readonly ok: {
|
|
45
|
+
readonly type: "boolean";
|
|
46
|
+
};
|
|
47
|
+
readonly error: {
|
|
48
|
+
readonly type: readonly ["string", "null"];
|
|
49
|
+
};
|
|
50
|
+
readonly result: {};
|
|
51
|
+
};
|
|
52
|
+
readonly required: readonly ["ok", "error", "result"];
|
|
53
|
+
readonly additionalProperties: false;
|
|
54
|
+
};
|
|
55
|
+
readonly annotations: {
|
|
56
|
+
readonly title: "Read next Opportunity sequence page";
|
|
57
|
+
readonly readOnlyHint: true;
|
|
58
|
+
readonly destructiveHint: false;
|
|
59
|
+
readonly idempotentHint: true;
|
|
60
|
+
readonly openWorldHint: true;
|
|
61
|
+
};
|
|
62
|
+
}, {
|
|
63
|
+
readonly name: "opportunity_sequence_enroll";
|
|
64
|
+
readonly description: "Idempotently enroll exactly one server-issued Lightfield candidate. The token binds opportunity, contact, trigger, playbook, and source facts; no caller selector is accepted.";
|
|
65
|
+
readonly inputSchema: {
|
|
66
|
+
readonly type: "object";
|
|
67
|
+
readonly properties: {
|
|
68
|
+
readonly candidateToken: {
|
|
69
|
+
readonly type: "string";
|
|
70
|
+
readonly minLength: 1;
|
|
71
|
+
readonly maxLength: 8192;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
readonly required: readonly ["candidateToken"];
|
|
75
|
+
readonly additionalProperties: false;
|
|
76
|
+
};
|
|
77
|
+
readonly outputSchema: {
|
|
78
|
+
readonly type: "object";
|
|
79
|
+
readonly properties: {
|
|
80
|
+
readonly ok: {
|
|
81
|
+
readonly type: "boolean";
|
|
82
|
+
};
|
|
83
|
+
readonly error: {
|
|
84
|
+
readonly type: readonly ["string", "null"];
|
|
85
|
+
};
|
|
86
|
+
readonly result: {};
|
|
87
|
+
};
|
|
88
|
+
readonly required: readonly ["ok", "error", "result"];
|
|
89
|
+
readonly additionalProperties: false;
|
|
90
|
+
};
|
|
91
|
+
readonly annotations: {
|
|
92
|
+
readonly title: "Enroll Opportunity sequence candidate";
|
|
93
|
+
readonly readOnlyHint: false;
|
|
94
|
+
readonly destructiveHint: false;
|
|
95
|
+
readonly idempotentHint: true;
|
|
96
|
+
readonly openWorldHint: true;
|
|
97
|
+
};
|
|
98
|
+
}, {
|
|
99
|
+
readonly name: "opportunity_sequence_record";
|
|
100
|
+
readonly description: "Validate one bounded Hermes output against a server-issued work token, reconcile the provider artifact/event identity, append structured Lightfield history first, and then repair the Opportunity projection.";
|
|
101
|
+
readonly inputSchema: {
|
|
102
|
+
readonly type: "object";
|
|
103
|
+
readonly properties: {
|
|
104
|
+
readonly workToken: {
|
|
105
|
+
readonly type: "string";
|
|
106
|
+
readonly minLength: 1;
|
|
107
|
+
readonly maxLength: 8192;
|
|
108
|
+
};
|
|
109
|
+
readonly output: {
|
|
110
|
+
readonly type: "object";
|
|
111
|
+
readonly properties: {
|
|
112
|
+
readonly playbook_ref: {
|
|
113
|
+
readonly type: "string";
|
|
114
|
+
readonly minLength: 1;
|
|
115
|
+
readonly maxLength: 256;
|
|
116
|
+
};
|
|
117
|
+
readonly playbook_hash: {
|
|
118
|
+
readonly type: "string";
|
|
119
|
+
readonly pattern: "^[a-f0-9]{64}$";
|
|
120
|
+
};
|
|
121
|
+
readonly step_id: {
|
|
122
|
+
readonly type: "string";
|
|
123
|
+
readonly minLength: 1;
|
|
124
|
+
readonly maxLength: 128;
|
|
125
|
+
};
|
|
126
|
+
readonly source_event_ids: {
|
|
127
|
+
readonly type: "array";
|
|
128
|
+
readonly minItems: 1;
|
|
129
|
+
readonly maxItems: 100;
|
|
130
|
+
readonly uniqueItems: true;
|
|
131
|
+
readonly items: {
|
|
132
|
+
readonly type: "string";
|
|
133
|
+
readonly minLength: 1;
|
|
134
|
+
readonly maxLength: 128;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
readonly source_fingerprint: {
|
|
138
|
+
readonly type: "string";
|
|
139
|
+
readonly pattern: "^[a-f0-9]{64}$";
|
|
140
|
+
};
|
|
141
|
+
readonly artifact_type: {
|
|
142
|
+
readonly type: "string";
|
|
143
|
+
readonly enum: readonly ["email", "linkedin", "call_request", "same_channel_reply"];
|
|
144
|
+
};
|
|
145
|
+
readonly target: {
|
|
146
|
+
readonly type: "object";
|
|
147
|
+
readonly properties: {
|
|
148
|
+
readonly contact_id: {
|
|
149
|
+
readonly type: "string";
|
|
150
|
+
readonly minLength: 1;
|
|
151
|
+
readonly maxLength: 128;
|
|
152
|
+
};
|
|
153
|
+
readonly channel: {
|
|
154
|
+
readonly type: "string";
|
|
155
|
+
readonly enum: readonly ["email", "linkedin", "phone"];
|
|
156
|
+
};
|
|
157
|
+
readonly address: {
|
|
158
|
+
readonly type: "string";
|
|
159
|
+
readonly minLength: 1;
|
|
160
|
+
readonly maxLength: 320;
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
readonly required: readonly ["contact_id", "channel"];
|
|
164
|
+
readonly additionalProperties: false;
|
|
165
|
+
};
|
|
166
|
+
readonly due_at: {
|
|
167
|
+
readonly type: "string";
|
|
168
|
+
readonly format: "date-time";
|
|
169
|
+
};
|
|
170
|
+
readonly subject: {
|
|
171
|
+
readonly type: "string";
|
|
172
|
+
readonly minLength: 1;
|
|
173
|
+
readonly maxLength: 200;
|
|
174
|
+
};
|
|
175
|
+
readonly body: {
|
|
176
|
+
readonly type: "string";
|
|
177
|
+
readonly minLength: 1;
|
|
178
|
+
readonly maxLength: 4000;
|
|
179
|
+
};
|
|
180
|
+
readonly rationale_summary: {
|
|
181
|
+
readonly type: "string";
|
|
182
|
+
readonly minLength: 1;
|
|
183
|
+
readonly maxLength: 600;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
readonly required: readonly ["playbook_ref", "playbook_hash", "step_id", "source_event_ids", "source_fingerprint", "artifact_type", "target", "due_at", "body", "rationale_summary"];
|
|
187
|
+
readonly additionalProperties: false;
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
readonly required: readonly ["workToken", "output"];
|
|
191
|
+
readonly additionalProperties: false;
|
|
192
|
+
};
|
|
193
|
+
readonly outputSchema: {
|
|
194
|
+
readonly type: "object";
|
|
195
|
+
readonly properties: {
|
|
196
|
+
readonly ok: {
|
|
197
|
+
readonly type: "boolean";
|
|
198
|
+
};
|
|
199
|
+
readonly error: {
|
|
200
|
+
readonly type: readonly ["string", "null"];
|
|
201
|
+
};
|
|
202
|
+
readonly result: {};
|
|
203
|
+
};
|
|
204
|
+
readonly required: readonly ["ok", "error", "result"];
|
|
205
|
+
readonly additionalProperties: false;
|
|
206
|
+
};
|
|
207
|
+
readonly annotations: {
|
|
208
|
+
readonly title: "Record Opportunity sequence work";
|
|
209
|
+
readonly readOnlyHint: false;
|
|
210
|
+
readonly destructiveHint: false;
|
|
211
|
+
readonly idempotentHint: true;
|
|
212
|
+
readonly openWorldHint: true;
|
|
213
|
+
};
|
|
214
|
+
}];
|
|
215
|
+
type SequenceEnvelope = {
|
|
216
|
+
ok: boolean;
|
|
217
|
+
error: string | null;
|
|
218
|
+
result: unknown;
|
|
219
|
+
};
|
|
220
|
+
export declare function opportunitySequenceNextPage(args: {
|
|
221
|
+
continuation?: string;
|
|
222
|
+
checkpoint?: string;
|
|
223
|
+
limit?: number;
|
|
224
|
+
}, context: AgentOpportunitySequenceContext | null): Promise<SequenceEnvelope>;
|
|
225
|
+
export declare function opportunitySequenceEnroll(args: {
|
|
226
|
+
candidateToken: string;
|
|
227
|
+
}, context: AgentOpportunitySequenceContext | null): Promise<SequenceEnvelope>;
|
|
228
|
+
export declare function opportunitySequenceRecord(args: {
|
|
229
|
+
workToken: string;
|
|
230
|
+
output: Record<string, unknown>;
|
|
231
|
+
}, context: AgentOpportunitySequenceContext | null): Promise<SequenceEnvelope>;
|
|
232
|
+
export {};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { getApi, SellableApiError } from "../api.js";
|
|
2
|
+
const PATH = "/api/v3/sellable-agent/opportunity-sequences";
|
|
3
|
+
const TIMEOUT_MS = 25_000;
|
|
4
|
+
const MAX_RESPONSE_BYTES = 256_000;
|
|
5
|
+
export const OPPORTUNITY_SEQUENCE_RESULT_SCHEMA = {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
ok: { type: "boolean" },
|
|
9
|
+
error: { type: ["string", "null"] },
|
|
10
|
+
result: {},
|
|
11
|
+
},
|
|
12
|
+
required: ["ok", "error", "result"],
|
|
13
|
+
additionalProperties: false,
|
|
14
|
+
};
|
|
15
|
+
export const opportunitySequenceToolDefinitions = [
|
|
16
|
+
{
|
|
17
|
+
name: "opportunity_sequence_next_page",
|
|
18
|
+
description: "Read one bounded page of server-selected Lightfield sequence candidates, due work, and exact inbound transitions. Finish a returned continuation before starting a new checkpoint scan.",
|
|
19
|
+
inputSchema: {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
continuation: { type: "string", minLength: 1, maxLength: 8192 },
|
|
23
|
+
checkpoint: { type: "string", minLength: 1, maxLength: 8192 },
|
|
24
|
+
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
25
|
+
},
|
|
26
|
+
required: [],
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
},
|
|
29
|
+
outputSchema: OPPORTUNITY_SEQUENCE_RESULT_SCHEMA,
|
|
30
|
+
annotations: {
|
|
31
|
+
title: "Read next Opportunity sequence page",
|
|
32
|
+
readOnlyHint: true,
|
|
33
|
+
destructiveHint: false,
|
|
34
|
+
idempotentHint: true,
|
|
35
|
+
openWorldHint: true,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "opportunity_sequence_enroll",
|
|
40
|
+
description: "Idempotently enroll exactly one server-issued Lightfield candidate. The token binds opportunity, contact, trigger, playbook, and source facts; no caller selector is accepted.",
|
|
41
|
+
inputSchema: {
|
|
42
|
+
type: "object",
|
|
43
|
+
properties: {
|
|
44
|
+
candidateToken: { type: "string", minLength: 1, maxLength: 8192 },
|
|
45
|
+
},
|
|
46
|
+
required: ["candidateToken"],
|
|
47
|
+
additionalProperties: false,
|
|
48
|
+
},
|
|
49
|
+
outputSchema: OPPORTUNITY_SEQUENCE_RESULT_SCHEMA,
|
|
50
|
+
annotations: {
|
|
51
|
+
title: "Enroll Opportunity sequence candidate",
|
|
52
|
+
readOnlyHint: false,
|
|
53
|
+
destructiveHint: false,
|
|
54
|
+
idempotentHint: true,
|
|
55
|
+
openWorldHint: true,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "opportunity_sequence_record",
|
|
60
|
+
description: "Validate one bounded Hermes output against a server-issued work token, reconcile the provider artifact/event identity, append structured Lightfield history first, and then repair the Opportunity projection.",
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {
|
|
64
|
+
workToken: { type: "string", minLength: 1, maxLength: 8192 },
|
|
65
|
+
output: {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
playbook_ref: { type: "string", minLength: 1, maxLength: 256 },
|
|
69
|
+
playbook_hash: {
|
|
70
|
+
type: "string",
|
|
71
|
+
pattern: "^[a-f0-9]{64}$",
|
|
72
|
+
},
|
|
73
|
+
step_id: { type: "string", minLength: 1, maxLength: 128 },
|
|
74
|
+
source_event_ids: {
|
|
75
|
+
type: "array",
|
|
76
|
+
minItems: 1,
|
|
77
|
+
maxItems: 100,
|
|
78
|
+
uniqueItems: true,
|
|
79
|
+
items: { type: "string", minLength: 1, maxLength: 128 },
|
|
80
|
+
},
|
|
81
|
+
source_fingerprint: {
|
|
82
|
+
type: "string",
|
|
83
|
+
pattern: "^[a-f0-9]{64}$",
|
|
84
|
+
},
|
|
85
|
+
artifact_type: {
|
|
86
|
+
type: "string",
|
|
87
|
+
enum: [
|
|
88
|
+
"email",
|
|
89
|
+
"linkedin",
|
|
90
|
+
"call_request",
|
|
91
|
+
"same_channel_reply",
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
target: {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: {
|
|
97
|
+
contact_id: { type: "string", minLength: 1, maxLength: 128 },
|
|
98
|
+
channel: {
|
|
99
|
+
type: "string",
|
|
100
|
+
enum: ["email", "linkedin", "phone"],
|
|
101
|
+
},
|
|
102
|
+
address: { type: "string", minLength: 1, maxLength: 320 },
|
|
103
|
+
},
|
|
104
|
+
required: ["contact_id", "channel"],
|
|
105
|
+
additionalProperties: false,
|
|
106
|
+
},
|
|
107
|
+
due_at: { type: "string", format: "date-time" },
|
|
108
|
+
subject: { type: "string", minLength: 1, maxLength: 200 },
|
|
109
|
+
body: { type: "string", minLength: 1, maxLength: 4000 },
|
|
110
|
+
rationale_summary: {
|
|
111
|
+
type: "string",
|
|
112
|
+
minLength: 1,
|
|
113
|
+
maxLength: 600,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
required: [
|
|
117
|
+
"playbook_ref",
|
|
118
|
+
"playbook_hash",
|
|
119
|
+
"step_id",
|
|
120
|
+
"source_event_ids",
|
|
121
|
+
"source_fingerprint",
|
|
122
|
+
"artifact_type",
|
|
123
|
+
"target",
|
|
124
|
+
"due_at",
|
|
125
|
+
"body",
|
|
126
|
+
"rationale_summary",
|
|
127
|
+
],
|
|
128
|
+
additionalProperties: false,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
required: ["workToken", "output"],
|
|
132
|
+
additionalProperties: false,
|
|
133
|
+
},
|
|
134
|
+
outputSchema: OPPORTUNITY_SEQUENCE_RESULT_SCHEMA,
|
|
135
|
+
annotations: {
|
|
136
|
+
title: "Record Opportunity sequence work",
|
|
137
|
+
readOnlyHint: false,
|
|
138
|
+
destructiveHint: false,
|
|
139
|
+
idempotentHint: true,
|
|
140
|
+
openWorldHint: true,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
function refusal(code) {
|
|
145
|
+
return { ok: false, error: code, result: null };
|
|
146
|
+
}
|
|
147
|
+
async function call(body, context) {
|
|
148
|
+
if (!context) {
|
|
149
|
+
return refusal("opportunity_sequence_current_admin_context_required");
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
return await getApi().post(PATH, { ...body, runtimeContext: context }, {
|
|
153
|
+
workspaceId: context.workspaceId,
|
|
154
|
+
timeoutMs: TIMEOUT_MS,
|
|
155
|
+
maxResponseBytes: MAX_RESPONSE_BYTES,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
if (error instanceof SellableApiError) {
|
|
160
|
+
try {
|
|
161
|
+
const parsed = JSON.parse(error.body);
|
|
162
|
+
return refusal(typeof parsed.error === "string"
|
|
163
|
+
? parsed.error
|
|
164
|
+
: "opportunity_sequence_request_failed");
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return refusal("opportunity_sequence_request_failed");
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return refusal("opportunity_sequence_request_failed");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export function opportunitySequenceNextPage(args, context) {
|
|
174
|
+
return call({ action: "NEXT_PAGE", ...args }, context);
|
|
175
|
+
}
|
|
176
|
+
export function opportunitySequenceEnroll(args, context) {
|
|
177
|
+
return call({ action: "ENROLL", candidateToken: args.candidateToken }, context);
|
|
178
|
+
}
|
|
179
|
+
export function opportunitySequenceRecord(args, context) {
|
|
180
|
+
return call({ action: "RECORD", workToken: args.workToken, output: args.output }, context);
|
|
181
|
+
}
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -10185,6 +10185,204 @@ export declare const allTools: ({
|
|
|
10185
10185
|
};
|
|
10186
10186
|
required: string[];
|
|
10187
10187
|
};
|
|
10188
|
+
} | {
|
|
10189
|
+
readonly name: "opportunity_sequence_next_page";
|
|
10190
|
+
readonly description: "Read one bounded page of server-selected Lightfield sequence candidates, due work, and exact inbound transitions. Finish a returned continuation before starting a new checkpoint scan.";
|
|
10191
|
+
readonly inputSchema: {
|
|
10192
|
+
readonly type: "object";
|
|
10193
|
+
readonly properties: {
|
|
10194
|
+
readonly continuation: {
|
|
10195
|
+
readonly type: "string";
|
|
10196
|
+
readonly minLength: 1;
|
|
10197
|
+
readonly maxLength: 8192;
|
|
10198
|
+
};
|
|
10199
|
+
readonly checkpoint: {
|
|
10200
|
+
readonly type: "string";
|
|
10201
|
+
readonly minLength: 1;
|
|
10202
|
+
readonly maxLength: 8192;
|
|
10203
|
+
};
|
|
10204
|
+
readonly limit: {
|
|
10205
|
+
readonly type: "integer";
|
|
10206
|
+
readonly minimum: 1;
|
|
10207
|
+
readonly maximum: 50;
|
|
10208
|
+
};
|
|
10209
|
+
};
|
|
10210
|
+
readonly required: readonly [];
|
|
10211
|
+
readonly additionalProperties: false;
|
|
10212
|
+
};
|
|
10213
|
+
readonly outputSchema: {
|
|
10214
|
+
readonly type: "object";
|
|
10215
|
+
readonly properties: {
|
|
10216
|
+
readonly ok: {
|
|
10217
|
+
readonly type: "boolean";
|
|
10218
|
+
};
|
|
10219
|
+
readonly error: {
|
|
10220
|
+
readonly type: readonly ["string", "null"];
|
|
10221
|
+
};
|
|
10222
|
+
readonly result: {};
|
|
10223
|
+
};
|
|
10224
|
+
readonly required: readonly ["ok", "error", "result"];
|
|
10225
|
+
readonly additionalProperties: false;
|
|
10226
|
+
};
|
|
10227
|
+
readonly annotations: {
|
|
10228
|
+
readonly title: "Read next Opportunity sequence page";
|
|
10229
|
+
readonly readOnlyHint: true;
|
|
10230
|
+
readonly destructiveHint: false;
|
|
10231
|
+
readonly idempotentHint: true;
|
|
10232
|
+
readonly openWorldHint: true;
|
|
10233
|
+
};
|
|
10234
|
+
} | {
|
|
10235
|
+
readonly name: "opportunity_sequence_enroll";
|
|
10236
|
+
readonly description: "Idempotently enroll exactly one server-issued Lightfield candidate. The token binds opportunity, contact, trigger, playbook, and source facts; no caller selector is accepted.";
|
|
10237
|
+
readonly inputSchema: {
|
|
10238
|
+
readonly type: "object";
|
|
10239
|
+
readonly properties: {
|
|
10240
|
+
readonly candidateToken: {
|
|
10241
|
+
readonly type: "string";
|
|
10242
|
+
readonly minLength: 1;
|
|
10243
|
+
readonly maxLength: 8192;
|
|
10244
|
+
};
|
|
10245
|
+
};
|
|
10246
|
+
readonly required: readonly ["candidateToken"];
|
|
10247
|
+
readonly additionalProperties: false;
|
|
10248
|
+
};
|
|
10249
|
+
readonly outputSchema: {
|
|
10250
|
+
readonly type: "object";
|
|
10251
|
+
readonly properties: {
|
|
10252
|
+
readonly ok: {
|
|
10253
|
+
readonly type: "boolean";
|
|
10254
|
+
};
|
|
10255
|
+
readonly error: {
|
|
10256
|
+
readonly type: readonly ["string", "null"];
|
|
10257
|
+
};
|
|
10258
|
+
readonly result: {};
|
|
10259
|
+
};
|
|
10260
|
+
readonly required: readonly ["ok", "error", "result"];
|
|
10261
|
+
readonly additionalProperties: false;
|
|
10262
|
+
};
|
|
10263
|
+
readonly annotations: {
|
|
10264
|
+
readonly title: "Enroll Opportunity sequence candidate";
|
|
10265
|
+
readonly readOnlyHint: false;
|
|
10266
|
+
readonly destructiveHint: false;
|
|
10267
|
+
readonly idempotentHint: true;
|
|
10268
|
+
readonly openWorldHint: true;
|
|
10269
|
+
};
|
|
10270
|
+
} | {
|
|
10271
|
+
readonly name: "opportunity_sequence_record";
|
|
10272
|
+
readonly description: "Validate one bounded Hermes output against a server-issued work token, reconcile the provider artifact/event identity, append structured Lightfield history first, and then repair the Opportunity projection.";
|
|
10273
|
+
readonly inputSchema: {
|
|
10274
|
+
readonly type: "object";
|
|
10275
|
+
readonly properties: {
|
|
10276
|
+
readonly workToken: {
|
|
10277
|
+
readonly type: "string";
|
|
10278
|
+
readonly minLength: 1;
|
|
10279
|
+
readonly maxLength: 8192;
|
|
10280
|
+
};
|
|
10281
|
+
readonly output: {
|
|
10282
|
+
readonly type: "object";
|
|
10283
|
+
readonly properties: {
|
|
10284
|
+
readonly playbook_ref: {
|
|
10285
|
+
readonly type: "string";
|
|
10286
|
+
readonly minLength: 1;
|
|
10287
|
+
readonly maxLength: 256;
|
|
10288
|
+
};
|
|
10289
|
+
readonly playbook_hash: {
|
|
10290
|
+
readonly type: "string";
|
|
10291
|
+
readonly pattern: "^[a-f0-9]{64}$";
|
|
10292
|
+
};
|
|
10293
|
+
readonly step_id: {
|
|
10294
|
+
readonly type: "string";
|
|
10295
|
+
readonly minLength: 1;
|
|
10296
|
+
readonly maxLength: 128;
|
|
10297
|
+
};
|
|
10298
|
+
readonly source_event_ids: {
|
|
10299
|
+
readonly type: "array";
|
|
10300
|
+
readonly minItems: 1;
|
|
10301
|
+
readonly maxItems: 100;
|
|
10302
|
+
readonly uniqueItems: true;
|
|
10303
|
+
readonly items: {
|
|
10304
|
+
readonly type: "string";
|
|
10305
|
+
readonly minLength: 1;
|
|
10306
|
+
readonly maxLength: 128;
|
|
10307
|
+
};
|
|
10308
|
+
};
|
|
10309
|
+
readonly source_fingerprint: {
|
|
10310
|
+
readonly type: "string";
|
|
10311
|
+
readonly pattern: "^[a-f0-9]{64}$";
|
|
10312
|
+
};
|
|
10313
|
+
readonly artifact_type: {
|
|
10314
|
+
readonly type: "string";
|
|
10315
|
+
readonly enum: readonly ["email", "linkedin", "call_request", "same_channel_reply"];
|
|
10316
|
+
};
|
|
10317
|
+
readonly target: {
|
|
10318
|
+
readonly type: "object";
|
|
10319
|
+
readonly properties: {
|
|
10320
|
+
readonly contact_id: {
|
|
10321
|
+
readonly type: "string";
|
|
10322
|
+
readonly minLength: 1;
|
|
10323
|
+
readonly maxLength: 128;
|
|
10324
|
+
};
|
|
10325
|
+
readonly channel: {
|
|
10326
|
+
readonly type: "string";
|
|
10327
|
+
readonly enum: readonly ["email", "linkedin", "phone"];
|
|
10328
|
+
};
|
|
10329
|
+
readonly address: {
|
|
10330
|
+
readonly type: "string";
|
|
10331
|
+
readonly minLength: 1;
|
|
10332
|
+
readonly maxLength: 320;
|
|
10333
|
+
};
|
|
10334
|
+
};
|
|
10335
|
+
readonly required: readonly ["contact_id", "channel"];
|
|
10336
|
+
readonly additionalProperties: false;
|
|
10337
|
+
};
|
|
10338
|
+
readonly due_at: {
|
|
10339
|
+
readonly type: "string";
|
|
10340
|
+
readonly format: "date-time";
|
|
10341
|
+
};
|
|
10342
|
+
readonly subject: {
|
|
10343
|
+
readonly type: "string";
|
|
10344
|
+
readonly minLength: 1;
|
|
10345
|
+
readonly maxLength: 200;
|
|
10346
|
+
};
|
|
10347
|
+
readonly body: {
|
|
10348
|
+
readonly type: "string";
|
|
10349
|
+
readonly minLength: 1;
|
|
10350
|
+
readonly maxLength: 4000;
|
|
10351
|
+
};
|
|
10352
|
+
readonly rationale_summary: {
|
|
10353
|
+
readonly type: "string";
|
|
10354
|
+
readonly minLength: 1;
|
|
10355
|
+
readonly maxLength: 600;
|
|
10356
|
+
};
|
|
10357
|
+
};
|
|
10358
|
+
readonly required: readonly ["playbook_ref", "playbook_hash", "step_id", "source_event_ids", "source_fingerprint", "artifact_type", "target", "due_at", "body", "rationale_summary"];
|
|
10359
|
+
readonly additionalProperties: false;
|
|
10360
|
+
};
|
|
10361
|
+
};
|
|
10362
|
+
readonly required: readonly ["workToken", "output"];
|
|
10363
|
+
readonly additionalProperties: false;
|
|
10364
|
+
};
|
|
10365
|
+
readonly outputSchema: {
|
|
10366
|
+
readonly type: "object";
|
|
10367
|
+
readonly properties: {
|
|
10368
|
+
readonly ok: {
|
|
10369
|
+
readonly type: "boolean";
|
|
10370
|
+
};
|
|
10371
|
+
readonly error: {
|
|
10372
|
+
readonly type: readonly ["string", "null"];
|
|
10373
|
+
};
|
|
10374
|
+
readonly result: {};
|
|
10375
|
+
};
|
|
10376
|
+
readonly required: readonly ["ok", "error", "result"];
|
|
10377
|
+
readonly additionalProperties: false;
|
|
10378
|
+
};
|
|
10379
|
+
readonly annotations: {
|
|
10380
|
+
readonly title: "Record Opportunity sequence work";
|
|
10381
|
+
readonly readOnlyHint: false;
|
|
10382
|
+
readonly destructiveHint: false;
|
|
10383
|
+
readonly idempotentHint: true;
|
|
10384
|
+
readonly openWorldHint: true;
|
|
10385
|
+
};
|
|
10188
10386
|
} | {
|
|
10189
10387
|
name: "refill_v3_advance";
|
|
10190
10388
|
description: string;
|
package/dist/tools/registry.js
CHANGED
|
@@ -35,6 +35,7 @@ import { leadToolDefinitions } from "./leads.js";
|
|
|
35
35
|
import { linkedinToolDefinitions } from "./linkedin.js";
|
|
36
36
|
import { navigationToolDefinitions } from "./navigation.js";
|
|
37
37
|
import { onDemandToolDefinitions } from "./one-off.js";
|
|
38
|
+
import { opportunitySequenceToolDefinitions } from "./opportunity-sequences.js";
|
|
38
39
|
import { processingToolDefinitions } from "./processing.js";
|
|
39
40
|
import { promptToolDefinitions } from "./prompts.js";
|
|
40
41
|
import { findLeadsProviderPreflightToolDefinitions } from "./provider-preflight.js";
|
|
@@ -117,6 +118,7 @@ export const allTools = [
|
|
|
117
118
|
...promptToolDefinitions,
|
|
118
119
|
...linkedinToolDefinitions,
|
|
119
120
|
...onDemandToolDefinitions,
|
|
121
|
+
...opportunitySequenceToolDefinitions,
|
|
120
122
|
...directCampaignToolDefinitions,
|
|
121
123
|
...companyInfoToolDefinitions,
|
|
122
124
|
...senderRoutingToolDefinitions,
|
package/package.json
CHANGED