@seldonframe/mcp 1.25.4 → 1.26.1
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 +3 -1
- package/src/tools.js +208 -0
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seldonframe/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.1",
|
|
4
|
+
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.26.1: AGENTS GO LIVE — BYOK + embed.js + 5 new MCP tools. WHAT SHIPS: (1) BYOK (BRING-YOUR-OWN-KEY). SF clients (the agencies + their HVAC/dental/coaching operators) use Claude Code or Cursor to build agents — they already have Anthropic API keys. SF doesn't markup LLM cost; SF charges per agent turn (separate revenue line). lib/agents/runtime.ts swaps from process.env.ANTHROPIC_API_KEY to getAIClient({ orgId }) — the same BYOK helper that lib/ai/client.ts already exposes for the rest of the platform (encrypted at rest in organizations.integrations.anthropic.apiKey with v1. prefix; decryptIfNeeded resolves at call time). When a workspace hasn't configured a key, executeTurn returns { ok: false, reason: 'llm_not_configured', fallbackMessage } — the public turn endpoint surfaces a graceful 'I'm not set up to chat yet — please reach out directly' instead of crashing. (2) EMBED.JS — single-line install on operator's website. New endpoint GET /api/v1/public/agent/<orgSlug>--<agentSlug>/embed.js returns a self-contained IIFE (~3KB) that injects a bottom-right chat bubble + chat panel. Click bubble → panel opens → user types → POST to /turn → response appears. Anonymous session id stored in localStorage (sf_agent_session_<agentSlug>) so multi-message sessions thread together server-side via agent_conversations.anonymous_session_id. Themed via agent's blueprint.greeting + workspace's theme.primaryColor. Returns no-op script (still 200) when agent not 'live' so operator's site console stays clean during draft → test → live progression. CSS namespaced .sf-agent-* (zero collision risk on operator's site). Operator's install snippet: <script src=\"https://app.seldonframe.com/api/v1/public/agent/cypress-pine-hvac--default/embed.js\" async></script>. (3) 5 NEW MCP TOOLS so SF clients build + ship agents from Claude Code without touching the dashboard: configure_llm_provider({ provider: 'anthropic'|'openai', api_key }) — first-run setup, encrypts + writes to organizations.integrations[provider].apiKey. create_agent({ name, archetype, channel, capabilities?, faq?, pricing_facts?, greeting? }) — wraps lib/agents/store.createAgent, returns { agent, embed_url, turn_url, next_steps[] } so the SF client immediately gets the embed snippet to drop on their operator's site. update_agent_blueprint({ agent_id, patch, publish_notes? }) — wraps updateAgentBlueprint, bumps current_version + writes new agent_versions row. publish_agent({ agent_id, status: draft|test|live|paused }) — flips status. list_agents() — workspace-scoped roster with id/name/slug/channel/archetype/status/version/tokens/budget/created. (4) /api/v1/agents route extended with op='set_llm_key' handler so the new MCP tool routes through one endpoint. Validates provider ∈ {anthropic, openai}, api_key length ≥ 10, encrypts via encryptValue (returns 503 encryption_unavailable when ENCRYPTION_KEY env not set), merges into organizations.integrations preserving other providers' entries (kit, mailchimp, etc.). NO new migrations (0044 from v1.26.0 covers all agent tables). NO new env vars beyond ENCRYPTION_KEY (already required for the existing BYOK path). Backend redeploy + npm publish required. DEFERRED TO v1.26.2: SSE streaming on /turn; eval suite runner (executes scenarios from blocks/agent-website-chatbot/SKILL.md against the live agent); eval-gated publish (require ≥7/8 scenarios pass before flipping to live); /admin/agents/[id]/{conversations,test} debug surfaces; MCP debug tools (tail_agent_conversations, get_agent_conversation, replay_conversation, get_agent_metrics).",
|
|
5
|
+
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.26.0: AGENT FOUNDATION — primitives for building chat / voice / SMS / email agents on top of Soul + Brain. Web chat archetype ships first; voice + SMS queued for v1.27/v1.28. Migration 0044 adds agents / agent_versions / agent_conversations / agent_turns / agent_evals tables. Schema (src/db/schema/agents.ts) typed with AgentBlueprint, AgentToolCall, AgentToolResult, AgentValidatorResult. System prompt composer (lib/agents/prompt.ts) derives prompts from Soul + blueprint, NEVER operator-authored — operators contribute knowledge (FAQ, services, pricing); platform owns the prompt. Five output validators (lib/agents/validators.ts) run on every assistant response: quotes_only_from_soul_pricing (critical — blocks hallucinated $X), no_prompt_injection_echo (critical — blocks 'ignore previous instructions' echoes), no_pii_leak (critical — blocks emails/phones not in user's message), no_avoid_words (warning — Soul voice rule), response_length_under_cap (warning — 600 chars). Critical fail = response replaced with 'let me check + escalate'. Five typed tools (lib/agents/tools.ts) with Zod input schemas: look_up_availability, book_appointment (wraps submitPublicBookingAction — same atomic primitive as /book), find_my_existing_appointment, escalate_to_human (writes portal_messages + activities), provide_faq_answer. Runtime (lib/agents/runtime.ts) executeTurn — loads conv + agent + soul, checks daily token budget, persists user turn, calls Anthropic with tools, loops on tool_use (max 6 iterations), runs validators, persists assistant turn with cost/latency, updates aggregates, activity-bridges first turn to operator's CRM. Non-streaming for v1.26.0; v1.26.1 adds SSE. Public turn endpoint POST /api/v1/public/agent/<orgSlug>--<agentSlug>/turn (anonymous; live/test status required). Agent CRUD endpoint POST /api/v1/agents (op: create | update_blueprint | publish | list — workspace bearer auth). createAgent generates slug, creates v1 in agent_versions, soul-derives blueprint defaults. blocks/agent-website-chatbot/SKILL.md documents the archetype + 8 eval scenarios including prompt-injection + PII-leak adversarial probes. NO new MCP tools yet (HTTP endpoint exposed; MCP-tool wiring + SSE streaming + embed.js + operator debug surfaces land in v1.26.1). NO new env vars beyond ANTHROPIC_API_KEY (already required). Backend redeploy required.",
|
|
4
6
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.25.4: operator 'Today' snapshot widget + remaining polish. NEW: replaces the v1.25.3 gap (where SF agency operators saw 'Newly installed blocks') with an operator-actionable 'Today' overview at the top of /dashboard. Four cards: today's bookings (count + first 3 with time/name), unread customer-portal messages, deals stuck >5 days (closedAt IS NULL + updatedAt < 5d ago), bookings-this-week trend. Each card click-throughs to its source surface (/bookings, /contacts, /deals). Below the cards: 'Up next' list of today's first 3 bookings rendered as time/name/title rows. All queries scoped by session orgId; widget renders only for isOperatorSession. POLISH: SeldonChat (the SF AI assistant floating button) hidden for operator sessions — that's an SF-builder tool. Command palette items split by session type — operator sessions only see Dashboard/Contacts/Deals/Bookings + their contact + deal hits; non-operator sessions get the full SF palette including Soul Marketplace, Studio, Seldon It, Pages, Email, Settings, Recent Activity. NO migrations, NO new env vars. Backend redeploy required.",
|
|
5
7
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.25.3: operator dashboard polish — hide SF-meta / SF-developer surfaces for operator sessions. From first principles: an HVAC owner / dentist doesn't have a build-time, doesn't speak block / soul / BLOCK.md, doesn't manage multiple workspaces, doesn't get support from SF Discord (their agency Acme AI is their support). Hides from /dashboard for operator sessions: (1) 'For the best experience, use Seldon directly from Claude Code with our MCP + Skill' hint banner — SF developer-facing. (2) 'Create New Client OS' button in the welcome header — agency-only action. (3) 'Newly installed blocks' section entirely — build-time SF-meta surface with View Public Page / Open Admin buttons. (4) 'BLOCK.md view metadata' subtitle on Pipeline section — replaced with 'Drag deals between stages to update their status' for operator sessions. (5) 'Docs' link in topbar — points at SF developer docs. (6) HelpButton floating popover — Discord / SF docs / report-a-bug links. (7) 'Discord' / 'Help' link from sidebar (already trimmed in v1.25.1; v1.25.3 fully removes it from operator nav). The welcome heading copy switches from 'This is your calm workspace overview' to 'Here's what's happening at your workspace today' for operator sessions — grounding the page in their business rather than SF-meta workspace concept. Each gate threaded via isOperatorSession prop from /(dashboard)/layout.tsx → DashboardTopbar / Sidebar / dashboard/page.tsx. NO migrations, NO new env vars. Backend redeploy required. v1.25.4 candidate (deferred): replace the now-empty top section with an operator-actionable 'Today snapshot' widget — count of today's bookings, deals needing attention, unread messages.",
|
|
6
8
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.25.2: TWO HOTFIXES from the v1.25.1 production smoke. (1) Operator session now PRECEDES NextAuth in helpers.ts. Pre-1.25.2 getCurrentUser/getOrgId/requireAuth checked NextAuth first, then operator-portal as a fallback. Smoke surfaced 2026-05-07: a user with BOTH a stale NextAuth cookie (from a prior /signup attempt that hit the Verification error) AND a fresh operator-portal cookie was treated as a NextAuth user — full SF admin nav showed instead of the trimmed operator nav. v1.25.2 reorders: operator portal cookie wins when present + valid. Falls through to NextAuth → admin-token otherwise. Intent-based — clicking an operator magic link clearly means the user wants operator portal access. Same precedence applied across getCurrentUser, getOrgId, requireAuth. (2) Dashboard page org_members + organizations queries now gate on isOperatorPortalUserId. Pre-1.25.2 the dashboard page had its own org_members lookup `where userId = synthetic-id` that bypassed the v1.25.0 helpers' opCtx check, crashing with PostgreSQL 22P02 'invalid input syntax for type uuid' (the synthetic id `__sf_operator_portal__:<orgId>` isn't a valid uuid). v1.25.2 short-circuits: when isOperatorPortalUserId(user.id), membershipRows = [{ orgId }] (the operator's single workspace) instead of querying org_members, and directWorkspaceRows queries by organizations.id only (skipping the ownerId/parentUserId clauses that also crash). Defense-in-depth: lib/billing/orgs.ts's listManagedOrganizations + listManagedOrganizationsForUser now early-return [] when user.id doesn't match the UUID_SHAPE regex (8-4-4-4-12 hex). NO migrations, NO new env vars. Backend redeploy required.",
|
package/src/tools.js
CHANGED
|
@@ -4039,6 +4039,214 @@ export const TOOLS = [
|
|
|
4039
4039
|
return result;
|
|
4040
4040
|
},
|
|
4041
4041
|
},
|
|
4042
|
+
|
|
4043
|
+
// ── v1.26 — agent foundation ────────────────────────────────────────────
|
|
4044
|
+
// Build agents (web chat / voice / SMS / email) on top of Soul + Brain.
|
|
4045
|
+
// BYOK: operators bring their own LLM key (Anthropic / OpenAI) — they
|
|
4046
|
+
// pay LLM bills directly to the provider. SF makes money per agent
|
|
4047
|
+
// turn (separate billing). configure_llm_provider sets the key;
|
|
4048
|
+
// create_agent registers a new agent draft; list_agents shows the
|
|
4049
|
+
// workspace's agents.
|
|
4050
|
+
|
|
4051
|
+
{
|
|
4052
|
+
name: "configure_llm_provider",
|
|
4053
|
+
description:
|
|
4054
|
+
"Set the LLM API key for this workspace's agents (BYOK — Bring Your Own Key). " +
|
|
4055
|
+
"The OPERATOR pays the LLM provider directly (Anthropic / OpenAI / etc.); SF charges separately for agent platform usage. " +
|
|
4056
|
+
"Stored encrypted at rest using the deployment's ENCRYPTION_KEY. " +
|
|
4057
|
+
"Operators get keys from console.anthropic.com (recommended for v1.26.x — best tool-use support) or platform.openai.com. " +
|
|
4058
|
+
"Call this BEFORE create_agent — agents fail-graceful with 'I'm not set up yet' if no key configured.",
|
|
4059
|
+
inputSchema: obj(
|
|
4060
|
+
{
|
|
4061
|
+
workspace_id: str("Workspace id (bearer workspace)."),
|
|
4062
|
+
provider: {
|
|
4063
|
+
type: "string",
|
|
4064
|
+
enum: ["anthropic", "openai"],
|
|
4065
|
+
description:
|
|
4066
|
+
"LLM provider. v1.26 ships full Anthropic support (tool use, streaming-ready). OpenAI support for chat is partial — recommend Anthropic for production agents.",
|
|
4067
|
+
},
|
|
4068
|
+
api_key: str(
|
|
4069
|
+
"API key. Anthropic keys start with 'sk-ant-...'. Stored encrypted; never echoed back in responses.",
|
|
4070
|
+
),
|
|
4071
|
+
},
|
|
4072
|
+
["workspace_id", "provider", "api_key"],
|
|
4073
|
+
),
|
|
4074
|
+
handler: async (args) => {
|
|
4075
|
+
const ws = args.workspace_id;
|
|
4076
|
+
const result = await api("POST", "/agents", {
|
|
4077
|
+
body: {
|
|
4078
|
+
op: "set_llm_key",
|
|
4079
|
+
provider: args.provider,
|
|
4080
|
+
api_key: args.api_key,
|
|
4081
|
+
},
|
|
4082
|
+
workspace_id: ws,
|
|
4083
|
+
});
|
|
4084
|
+
return result;
|
|
4085
|
+
},
|
|
4086
|
+
},
|
|
4087
|
+
|
|
4088
|
+
{
|
|
4089
|
+
name: "create_agent",
|
|
4090
|
+
description:
|
|
4091
|
+
"Create a new agent for this workspace. Agents are conversational interfaces (web chat, voice, SMS) that answer FAQs, book appointments, and escalate to humans — composed from typed primitives + the workspace's Soul (industry, voice, services). " +
|
|
4092
|
+
"WHAT GETS COMPOSED AUTOMATICALLY: persona derived from soul.industry + soul.voice; FAQ knowledge from your `faq` array; pricing facts from `pricing_facts` (validators block any $-amount the agent invents that's not in this list); typed tools (look_up_availability, book_appointment, find_my_existing_appointment, escalate_to_human, provide_faq_answer). " +
|
|
4093
|
+
"WHAT YOU PROVIDE: name, archetype (website-chatbot for v1.26.x; voice-receptionist + sms-followup-bot queued), channel (web_chat / voice / sms / email), inline FAQ pairs, allowed pricing facts, optional greeting. " +
|
|
4094
|
+
"STATUS LIFECYCLE: created in 'draft' (not callable). Flip to 'test' to chat with it in sandbox (tool calls return synthetic results — no real bookings). Flip to 'live' once you're confident. v1.26.2 will add eval-gating that blocks 'live' until a test scenario suite passes. " +
|
|
4095
|
+
"SAFETY: response validators run on every turn — quotes_only_from_soul_pricing (critical, blocks hallucinated $X), no_prompt_injection_echo (critical), no_pii_leak (critical), no_avoid_words (warning), response_length_under_cap (warning). Critical fail = agent says 'let me check + escalate' instead of sending the bad response. " +
|
|
4096
|
+
"OUTPUT: the agent's embed URL (one-line <script> for the operator's website) and turn URL (POST endpoint for direct API integration).",
|
|
4097
|
+
inputSchema: obj(
|
|
4098
|
+
{
|
|
4099
|
+
workspace_id: str("Workspace id (bearer workspace)."),
|
|
4100
|
+
name: str(
|
|
4101
|
+
"Agent display name (e.g. 'Cypress HVAC Assistant'). Surfaces in the chat header.",
|
|
4102
|
+
),
|
|
4103
|
+
archetype: {
|
|
4104
|
+
type: "string",
|
|
4105
|
+
enum: ["website-chatbot", "voice-receptionist", "sms-followup-bot"],
|
|
4106
|
+
description:
|
|
4107
|
+
"Agent shape. v1.26.x ships website-chatbot with full feature support; voice-receptionist + sms-followup-bot are queued for v1.27/v1.28.",
|
|
4108
|
+
},
|
|
4109
|
+
channel: {
|
|
4110
|
+
type: "string",
|
|
4111
|
+
enum: ["web_chat", "voice", "sms", "email"],
|
|
4112
|
+
description:
|
|
4113
|
+
"Delivery channel. v1.26.x ships web_chat only (embed.js bubble). Other channels queued.",
|
|
4114
|
+
},
|
|
4115
|
+
faq: {
|
|
4116
|
+
type: "array",
|
|
4117
|
+
description:
|
|
4118
|
+
"Operator-curated FAQ pairs. Each item is { q: string, a: string }. The agent has these in its system prompt; visitors get answers without an LLM round-trip when the question is a clear match. v1.27 adds vector RAG over uploaded docs.",
|
|
4119
|
+
items: obj(
|
|
4120
|
+
{
|
|
4121
|
+
q: str("Question as a visitor would phrase it."),
|
|
4122
|
+
a: str("Operator's exact answer (1-3 sentences)."),
|
|
4123
|
+
},
|
|
4124
|
+
["q", "a"],
|
|
4125
|
+
),
|
|
4126
|
+
},
|
|
4127
|
+
pricing_facts: {
|
|
4128
|
+
type: "array",
|
|
4129
|
+
description:
|
|
4130
|
+
"ONLY prices the agent may quote. Validators block any $-amount in the agent's response that's not in this list (or doesn't match exactly). If you want the agent to refuse all price questions, omit this. Each item: { label: string, amount: number, currency: 'USD' | etc. }",
|
|
4131
|
+
items: obj(
|
|
4132
|
+
{
|
|
4133
|
+
label: str("Service name (e.g. 'Furnace tune-up')."),
|
|
4134
|
+
amount: { type: "number" },
|
|
4135
|
+
currency: str("3-letter currency code, e.g. USD."),
|
|
4136
|
+
},
|
|
4137
|
+
["label", "amount", "currency"],
|
|
4138
|
+
),
|
|
4139
|
+
},
|
|
4140
|
+
greeting: str(
|
|
4141
|
+
"Optional first message shown when the chat opens (default: 'Hi! How can I help you today?').",
|
|
4142
|
+
),
|
|
4143
|
+
capabilities: {
|
|
4144
|
+
type: "array",
|
|
4145
|
+
items: { type: "string" },
|
|
4146
|
+
description:
|
|
4147
|
+
"Optional explicit subset of typed tools the agent may call. Default: all five (look_up_availability, book_appointment, find_my_existing_appointment, escalate_to_human, provide_faq_answer). Restrict if you want a read-only agent (omit book_appointment) or a no-escalation agent (omit escalate_to_human).",
|
|
4148
|
+
},
|
|
4149
|
+
},
|
|
4150
|
+
["workspace_id", "name", "archetype", "channel"],
|
|
4151
|
+
),
|
|
4152
|
+
handler: async (args) => {
|
|
4153
|
+
const ws = args.workspace_id;
|
|
4154
|
+
const result = await api("POST", "/agents", {
|
|
4155
|
+
body: {
|
|
4156
|
+
op: "create",
|
|
4157
|
+
name: args.name,
|
|
4158
|
+
archetype: args.archetype,
|
|
4159
|
+
channel: args.channel,
|
|
4160
|
+
faq: args.faq ?? undefined,
|
|
4161
|
+
pricing_facts: args.pricing_facts ?? undefined,
|
|
4162
|
+
greeting: args.greeting ?? undefined,
|
|
4163
|
+
capabilities: args.capabilities ?? undefined,
|
|
4164
|
+
},
|
|
4165
|
+
workspace_id: ws,
|
|
4166
|
+
});
|
|
4167
|
+
return result;
|
|
4168
|
+
},
|
|
4169
|
+
},
|
|
4170
|
+
|
|
4171
|
+
{
|
|
4172
|
+
name: "list_agents",
|
|
4173
|
+
description:
|
|
4174
|
+
"List all agents in this workspace with status (draft/test/live/paused), version, daily token usage vs budget, and metadata. Use to find an agent_id before calling publish_agent or update_agent_blueprint, or to audit which agents are live across a workspace.",
|
|
4175
|
+
inputSchema: obj(
|
|
4176
|
+
{ workspace_id: str("Workspace id (bearer workspace).") },
|
|
4177
|
+
["workspace_id"],
|
|
4178
|
+
),
|
|
4179
|
+
handler: async (args) => {
|
|
4180
|
+
const ws = args.workspace_id;
|
|
4181
|
+
const result = await api("POST", "/agents", {
|
|
4182
|
+
body: { op: "list" },
|
|
4183
|
+
workspace_id: ws,
|
|
4184
|
+
});
|
|
4185
|
+
return result;
|
|
4186
|
+
},
|
|
4187
|
+
},
|
|
4188
|
+
|
|
4189
|
+
{
|
|
4190
|
+
name: "publish_agent",
|
|
4191
|
+
description:
|
|
4192
|
+
"Change an agent's status: draft → test (sandboxed playground; tools return synthetic results), test → live (real bookings, real escalations, customer-facing), live → paused (chat bubble disabled). v1.26.2 will add eval-gating that blocks 'live' until the agent's eval suite passes; for v1.26.x, the operator-side responsibility is to test in 'test' mode before flipping to 'live'.",
|
|
4193
|
+
inputSchema: obj(
|
|
4194
|
+
{
|
|
4195
|
+
workspace_id: str("Workspace id (bearer workspace)."),
|
|
4196
|
+
agent_id: str("Agent id from create_agent."),
|
|
4197
|
+
status: {
|
|
4198
|
+
type: "string",
|
|
4199
|
+
enum: ["draft", "test", "live", "paused"],
|
|
4200
|
+
description: "Target status.",
|
|
4201
|
+
},
|
|
4202
|
+
},
|
|
4203
|
+
["workspace_id", "agent_id", "status"],
|
|
4204
|
+
),
|
|
4205
|
+
handler: async (args) => {
|
|
4206
|
+
const ws = args.workspace_id;
|
|
4207
|
+
const result = await api("POST", "/agents", {
|
|
4208
|
+
body: { op: "publish", agent_id: args.agent_id, status: args.status },
|
|
4209
|
+
workspace_id: ws,
|
|
4210
|
+
});
|
|
4211
|
+
return result;
|
|
4212
|
+
},
|
|
4213
|
+
},
|
|
4214
|
+
|
|
4215
|
+
{
|
|
4216
|
+
name: "update_agent_blueprint",
|
|
4217
|
+
description:
|
|
4218
|
+
"Update an agent's blueprint (FAQ, pricing facts, greeting, capabilities). Bumps current_version + writes a new agent_versions row for rollback. The agent's status is unchanged — flip to test/live separately when you're ready. " +
|
|
4219
|
+
"PATCH SEMANTICS: arrays REPLACE (not merge). If you want to ADD a single FAQ pair, fetch the current blueprint first via list_agents, append your new pair, and submit the full updated array. " +
|
|
4220
|
+
"Common reasons to call this: operator added new FAQ entries; pricing changed; greeting needs A/B testing; restricting capabilities (e.g. removing book_appointment to make agent answer-only).",
|
|
4221
|
+
inputSchema: obj(
|
|
4222
|
+
{
|
|
4223
|
+
workspace_id: str("Workspace id (bearer workspace)."),
|
|
4224
|
+
agent_id: str("Agent id from create_agent."),
|
|
4225
|
+
patch: {
|
|
4226
|
+
type: "object",
|
|
4227
|
+
description:
|
|
4228
|
+
"Partial blueprint patch. Fields: faq, pricing_facts, greeting, capabilities, archetype. Arrays REPLACE.",
|
|
4229
|
+
},
|
|
4230
|
+
publish_notes: str(
|
|
4231
|
+
"Optional one-line note for the audit log (e.g. 'Added emergency-call FAQ').",
|
|
4232
|
+
),
|
|
4233
|
+
},
|
|
4234
|
+
["workspace_id", "agent_id", "patch"],
|
|
4235
|
+
),
|
|
4236
|
+
handler: async (args) => {
|
|
4237
|
+
const ws = args.workspace_id;
|
|
4238
|
+
const result = await api("POST", "/agents", {
|
|
4239
|
+
body: {
|
|
4240
|
+
op: "update_blueprint",
|
|
4241
|
+
agent_id: args.agent_id,
|
|
4242
|
+
patch: args.patch,
|
|
4243
|
+
publish_notes: args.publish_notes ?? undefined,
|
|
4244
|
+
},
|
|
4245
|
+
workspace_id: ws,
|
|
4246
|
+
});
|
|
4247
|
+
return result;
|
|
4248
|
+
},
|
|
4249
|
+
},
|
|
4042
4250
|
];
|
|
4043
4251
|
|
|
4044
4252
|
export const TOOL_MAP = Object.fromEntries(TOOLS.map((t) => [t.name, t]));
|