@seldonframe/mcp 1.28.0 → 1.28.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 CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "@seldonframe/mcp",
3
- "version": "1.28.0",
3
+ "version": "1.28.2",
4
+ "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.28.2: EMBED WIDGET POLISH (CRM-side; MCP package version bumped for SemVer hygiene). The /api/v1/public/agent/<slug>/embed.js IIFE that renders on operators' websites — first impression for end customers — was functional but plain. v1.28.2 brings it to world-class without forking a hosted-app codebase like mckaywrigley/chatbot-ui (wrong shape — that's a full Next.js app, we need a single <script> tag with zero deps on the operator's site). Polish in 5 categories: (1) MARKDOWN RENDERING. Inline parser in the IIFE handles **bold** → <strong>, *italic* → <em>, `code` → <code>, [text](https://...) → <a target=_blank rel=noopener noreferrer>, '- bullet' lines → <ul><li>, and \\n → <br>. All output goes through escapeHtml() FIRST then sanctioned tags re-injected — no raw HTML survives. SSE-friendly: re-renders innerHTML on every delta so bold/links resolve as soon as the closing token arrives. Inline CSS for strong/em/a/code/ul/li within .sf-agent-msg.assistant. (2) MOBILE-FIRST. Below 640px breakpoint the panel becomes FULL-SCREEN (Intercom pattern) — no rounded corners, fills viewport. Bubble shifts to bottom-right corner with smaller margin. Bigger touch targets throughout. (3) BRAND INHERITANCE. Header now shows the operator's logo if workspace.theme.logoUrl is set (https://... only — schema-validated server-side); falls back to a colored circle with the first letter of the org name. Logo container has bg=rgba(255,255,255,.18) so it sits cleanly on top of the operator's primaryColor header. (4) A11Y. role=dialog + aria-label on panel; role=log + aria-live=polite + aria-relevant=additions on messages region (announces new agent messages without spamming during streaming); screen-reader-only label on the textarea; aria-expanded toggles on the bubble; ARIA-labels on every control. Esc key closes panel + returns focus to bubble (focus management). focus-visible outlines on all interactive elements with proper offset. prefers-reduced-motion media query disables all transitions and animations. (5) ANIMATIONS + UX. Bubble: spring scale (cubic-bezier(.34,1.56,.64,1)) on hover (1.08x) + active (.95x). Panel: spring slide-up reveal — opacity 0 + translateY(8px) + scale(.98) → opacity 1 + 0 + 1 in 280ms. Messages: per-message fade+slide-in (220ms). Typing indicator: 3 animated bouncing dots (was 'Typing...' text). Textarea (was input) auto-grows to 120px max-height; Enter sends, Shift+Enter newline. Send button has translateY hover + scale active feedback. NO MCP tool changes. NO migrations. NO new env vars. The embed.js endpoint is automatically picked up on the next page load — operators don't need to update their script tag (the URL is stable; the response body changes server-side). Backend redeploy required.",
5
+ "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.28.1: 90%-FEWER-TOOL-CALLS + /AGENTS DASHBOARD REDESIGN. PROBLEM: real-world dogfood showed Claude Code spending 3m 35s + ~17 actions to update an existing chatbot — only 2 of which (the actual update_agent_blueprint call + final response) were necessary work. The waste broke down as: progressive tool-schema loading (5+ separate 'Called seldonframe' round-trips as Claude Code lazy-discovered the 138-tool catalog), local-FS exploration (ls + node --version + read .env — all irrelevant on a hosted SF platform), an unnecessary question to the user about Anthropic key configuration (the workspace already had one), and stale references to the v1.27.9-removed token-budget concept leaking from MCP tool responses. Plus the /agents dashboard exposed only 2 CTAs (Open sandbox / View conversations) and zero inline health stats — operators had to drill into /agents/[id] just to see eval status / validator pass rate / 24h conversations. WHAT SHIPS: (1) NEW GET /api/v1/workspace-state ENDPOINT. Workspace-bearer auth. Returns in ONE round-trip: workspace identity (id, name, slug, industry, timezone, dashboard_url, public_site_url); integrations status (anthropic / openai / twilio / resend / kit / mailchimp configured? — booleans only, no keys leaked); agents WITH inline health stats (status, version, eval pass rate, validator pass rate 24h, conversations 24h, eval_meets_publish_gate boolean, last_eval_run_at); high-level counts (contacts, bookings, deals, agents); and a tailored next_steps[] array (e.g. 'Configure Anthropic LLM key' / 'No agents yet, call build_website_chatbot' / 'Run evals before promoting to live'). (2) NEW get_workspace_state MCP TOOL wrapping that endpoint. Description tells Claude Code to call it FIRST for any workspace task — replaces 4-6 progressive discovery calls. (3) NEW update_website_chatbot SKILL BUNDLE. Peer to v1.28.0's build_website_chatbot, for the 'agent already exists' case. Auto-resolves the workspace's website-chatbot agent_id if not passed (uses get_workspace_state internally), merges patch into blueprint via update_agent_blueprint, returns dashboard URL + version + next_steps with re-run-evals reminder. Refuses ambiguously (multi-agent workspaces) — returns the agent list instead. (4) STRIPPED DEPRECATED FIELDS. tokensUsedToday + dailyTokenBudget removed from list_agents and get_agent_metrics MCP tool response shapes (token-budget concept was retired in v1.27.9; stale data was still leaking through and causing Claude Code to suggest 'bump the token budget' as a follow-up). (5) WELCOME.JS REWRITTEN. New 'Step zero — call get_workspace_state' section + new ANTI-PATTERNS table explicitly enumerating what NOT to do (don't ls/cat/read .env; don't check node/npm versions; don't ask 'is Anthropic key configured?'; don't create duplicate agent). FIRST_CALL_BANNER similarly anchored on step-zero discovery + anti-patterns. (6) /AGENTS PAGE REDESIGN. Each agent row now shows inline: status pill + 3-stat grid (conversations 24h, validator pass rate 24h with 'X turns' hint, eval pass rate X/Y with last-run timestamp + meets-gate tone) + a contextual PromoteHint banner ('Evals haven't run' / 'Below 87.5% gate, fix in Settings' / 'Eval gate met, ready to promote') + 5 quick-link CTAs (Overview / Sandbox / Conversations / Evals / Settings — was 2). The agent list is now a roster + health dashboard, not a list-of-links. EXPECTED IMPACT: 'build a chatbot for [biz]' / 'update the chatbot's FAQ' / 'how is my chatbot doing' prompts resolve in 1-2 tool calls + ~5-10s, instead of 12+ tool calls + ~3.5min. Operators see at a glance whether each agent is healthy + what's blocking promotion, without drilling into per-agent pages. NO migrations, NO new env vars. Backend redeploy required.",
4
6
  "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.28.0: BUILD_WEBSITE_CHATBOT SKILL BUNDLE + BYOK ENV AUTO-DETECT — Phase B of the Karpathy/antifragility refactor (sugar over primitives). PROBLEM: even after v1.27.x's tool-discovery doc upgrade, the canonical 'build me a chatbot for [business]' flow still required ~5 sequential MCP calls (configure_llm_provider → create_agent → publish_agent test → operator sandbox-tests → publish_agent live), each round-tripping through Vercel. ~30s wall time. BYOK setup added a key-paste step every time even though most Claude Code users already have ANTHROPIC_API_KEY set in their shell. WHAT SHIPS: (1) BYOK ENV AUTO-DETECT. configure_llm_provider gains a 'pass nothing / pass api_key=\"env\"' mode. The MCP server reads process.env.ANTHROPIC_API_KEY (or OPENAI_API_KEY for provider='openai') from its OWN local environment — which is the user's shell where Claude Code launched. Most Claude Code users already have this set (it's how Claude Code itself works). Returns { ok: false, error: 'no_env_key' } with a clear hint if the env var isn't set. The handler annotates ok=true responses with source='env_inherited' vs source='explicit' so the LLM can tell the user 'I auto-detected your Anthropic key from your shell environment' instead of 'I saved the key you provided.' WHITE-LABEL ESCAPE HATCH: pass api_key explicitly when an agency manages multiple operators with separate Anthropic billing (env auto-detect would use the agency's key for every operator — wrong for billing isolation). (2) NEW SKILL-BUNDLE TOOL build_website_chatbot. ONE call wraps the canonical 4-step sequence: configure_llm_provider (auto-detects env if no anthropic_api_key passed) → create_agent (archetype='website-chatbot', channel='web_chat', with faq + pricing_facts + greeting from args) → publish_agent (status='test', sandbox-callable, eval gate doesn't run yet) → returns { agent, embed_url, turn_url, dashboard_url, sandbox_url, steps[], next_steps[] }. Each internal step's success/failure surfaces in the steps array so the LLM can report cleanly. Partial-success handling: if create_agent succeeds but publish fails, returns the created agent + a clear next_step to publish manually. Reduces typical 'create chatbot for HVAC' from 5 round-trips + ~30s to 1 round-trip + ~5s. (3) WELCOME.JS CAPABILITY MAP UPDATED. The 'add a chatbot to my website' row now points at build_website_chatbot instead of create_agent. Canonical short flow walkthrough rewritten to show the 1-call version. FIRST_CALL_BANNER similarly updated. Primitives stay fully callable for custom flows (different archetype, custom capability allowlist, multi-step blueprint construction); the bundle is just sugar over them. PHILOSOPHY (Karpathy / antifragile / thin-harness-fat-skill): the bundle is sugar, not a replacement. Primitives stay clean — operators on Claude Code with sufficient model capability can still call them directly for nuanced flows. As Claude gets better at orchestrating the 4-call sequence itself, the bundle becomes less necessary but still works. Smaller models or one-shot prompts lean on the bundle; larger models orchestrate primitives. Same architecture serves both. NO new HTTP endpoints (build_website_chatbot uses existing /api/v1/agents ops via the MCP-tool layer). NO migrations, NO new env vars on the server side. ENCRYPTION_KEY still required (already shipped). DEFERRED to v1.28.1: embed widget polish (markdown rendering, mobile-first responsive, brand inheritance, a11y, action chips). DEFERRED to v1.28.2: skill-pack architecture (move inline behavioral guidance from prompt.ts to agents/<archetype>/skills/*.md files the composer reads on demand). DEFERRED to v1.28.3: post-booking 24h reminder via Vercel Workflows (first SF use of Workflows for a new durable flow). EXPECTED IMPACT: 'create a chatbot for Cypress Pine HVAC with these FAQ + pricing facts' resolves in ~5s with one tool call, instead of ~30s with 5 sequential calls. Operator sees one consolidated next-steps list (sandbox-test, run evals, publish-live, drop embed snippet) instead of having to compose them mentally across 5 separate responses.",
5
7
  "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.27.10: HALLUCINATED-STATE-CHANGE VALIDATOR (CRM-side; MCP package version bumped for SemVer hygiene). PROBLEM: even after v1.27.8 (added reschedule_appointment + cancel_appointment tools + system-prompt rule 'NEVER claim an action you didn't take'), real-world dogfood STILL caught the agent hallucinating. Conversation: 'Done! You're rescheduled for tomorrow, May 8 at 1pm. See you then, Maxime!' But database wasn't updated; contact's bookings page still showed May 21. Two failure paths converge here: (a) the existing Cypress Pine agent's blueprint was created in v1.26.x with the ORIGINAL 5 capabilities — v1.27.8 added the new tools to DEFAULTS for new agents but deliberately didn't auto-mutate existing operator blueprints. So the LLM never had reschedule_appointment in its tool list — system prompt told it 'you MUST call reschedule_appointment' (which doesn't exist for it), contradictory state, LLM picked 'claim success' over 'tell user we can't.' (b) Even when the capability IS there, system prompts aren't 100% reliable — Claude can still hallucinate completion claims. Both paths produce the same critical-failure: customer is told the booking moved when it didn't. ARCHITECTURAL FIX (defense in depth at the runtime layer, since system-prompt rules alone are insufficient): a new critical validator that catches the hallucination regardless of WHY it happened. WHAT SHIPS: (1) NEW VALIDATOR no_hallucinated_state_change. ValidatorContext gains turnToolCalls + turnToolResults (this turn's tool activity). The validator scans the response for completion phrases mapped to required tool calls: 'rescheduled / moved your appointment / appointment moved / new time is set / see you (then|tomorrow|<weekday>)' → requires reschedule_appointment with ok=true; 'cancelled your appointment / cancellation confirmed' → requires cancel_appointment; 'you're booked / appointment confirmed / I've booked' → requires book_appointment; 'team will follow up / I've passed this on / someone will reach out' → requires escalate_to_human. If the response claims completion AND the matching tool was NOT called with ok=true this turn, fail critical. The runtime then replaces the response with the safe fallback ('let me check'). Customer NEVER hears a fabricated state change. (2) ALL_VALIDATORS array gains the new validator. Existing 5 validators unchanged. (3) RUNTIME passes allToolCalls + allToolResults from the turn loop into runValidators. NO migrations, NO new env vars, NO MCP tool changes. Backend redeploy required. EXPECTED IMPACT on the conversation that triggered this fix: even if the agent's blueprint still doesn't have reschedule_appointment in capabilities (the v1.27.8 manual-backfill step the user hasn't done yet), the runtime will catch the hallucinated 'rescheduled!' response and replace with the safe fallback — customer hears 'let me check on that' instead of being lied to. Once the user backfills their agent's capabilities (call update_agent_blueprint from Claude Code with the full 7-tool list, or tick the 2 new boxes in /agents/<id>/settings + Save), the agent will ACTUALLY call reschedule_appointment and the booking will move. Belt + suspenders: even if the LLM lies despite having the tool, the validator catches it. As Claude gets better at not hallucinating actions, this validator fires less and less; architecture stable.",
6
8
  "description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.27.9: REMOVE DAILY TOKEN BUDGET (CRM-side; MCP package version bumped for SemVer hygiene). PROBLEM: real-world dogfood reschedule conversation halted with 'RUNTIME ERROR · DAILY_BUDGET_EXHAUSTED — Token budget 92% used (45,855 / 50,000 tokens today)'. The artificial cap broke a perfectly valid conversation. The cap was a v1.26.0 design artifact from when SF was going to resell LLM at markup — it protected SF from runaway cost exposure. Under BYOK (since v1.26.1), the OPERATOR pays Anthropic directly. SF has zero cost exposure. The cap is now: (a) irrelevant for SF (no cost to protect), (b) confusing for operators (they have an Anthropic billing dashboard for this), and (c) actively harmful (artificial halts on busy days with plenty of Anthropic credits available). FIX: remove the budget mechanism entirely. WHAT SHIPS: (1) RUNTIME: dropped the isDailyBudgetExhausted() check at step 2 of executeTurn. Dropped the 'daily_budget_exhausted' fallback reason code. Dropped the 'agents.tokensUsedToday + dailyTokenBudget' aggregate increment. Per-turn tokensIn/tokensOut still persist on agent_turns rows for cost analytics + observability — that data stays useful even when SF doesn't bill on it. The isDailyBudgetExhausted helper function deleted. (2) AGENT OVERVIEW: dropped the 'Daily token usage' card with progress bar. Token-budget concept is gone from the UI; the at-a-glance health stat row (24h conversations, validator pass rate, eval pass rate, avg latency) stays. (3) SANDBOX PRE-FLIGHT: dropped the budget pre-flight checks (block-level when 100% used + warning-level at 80%). Anthropic-key pre-flight check stays (still relevant; no key = no chat). (4) AGENT LIST: dropped the 'Tokens today: X / 50,000 (X%)' line on each agent row. Cleaner display. (5) DB SCHEMA UNCHANGED. agents.tokensUsedToday + dailyTokenBudget + tokensUsedResetAt columns stay (no migration; future-proof for if we ever want to surface 'cost spent today' analytics). They're just no longer read or written by the runtime. NO migrations, NO new env vars. Backend redeploy required. EXPECTED IMPACT on the conversation that triggered this fix: the agent will no longer halt mid-turn with DAILY_BUDGET_EXHAUSTED. Conversations run as long as the operator's Anthropic key has credits. Operators see their actual spend on their Anthropic dashboard, not an artificial SF-imposed limit. Simpler architecture, fewer concepts.",
package/src/tools.js CHANGED
@@ -4286,6 +4286,36 @@ export const TOOLS = [
4286
4286
  },
4287
4287
  },
4288
4288
 
4289
+ // ───────────────────────────────────────────────────────────────────────
4290
+ // v1.28.1 — WORKSPACE DISCOVERY (single-call replacement for the
4291
+ // 4-6 progressive "Called seldonframe N times" round-trips that
4292
+ // happen as Claude Code lazy-loads tool schemas to figure out what's
4293
+ // in a workspace). Returns workspace identity + integrations status +
4294
+ // agents with inline health stats + counts. Designed to be the FIRST
4295
+ // call for any "what's in this workspace?" / "build me a chatbot for X"
4296
+ // / "is the agent healthy?" prompt.
4297
+ // ───────────────────────────────────────────────────────────────────────
4298
+
4299
+ {
4300
+ name: "get_workspace_state",
4301
+ description:
4302
+ "USE FIRST for any workspace task — replaces 4-6 separate discovery calls with one. " +
4303
+ "Returns: workspace identity (name, slug, industry, timezone, dashboard URL); integrations status (anthropic / openai / twilio / resend / kit / mailchimp configured? — booleans only, no keys leaked); agents WITH inline health stats (status, version, eval pass rate, validator pass rate 24h, conversations 24h, eval gate met?, last eval run); high-level counts (contacts, bookings, deals, agents); and a next_steps array tailored to the workspace's current state (e.g. 'configure Anthropic key', 'no agents yet — call build_website_chatbot', 'agents need eval run before live'). " +
4304
+ "USE WHEN USER SAYS: 'what's in this workspace', 'how is my chatbot doing', 'build me a chatbot for [biz]' (call FIRST so you know if an agent already exists + if LLM is configured), 'is my agent live yet', 'workspace status'. " +
4305
+ "AVOIDS asking the user obvious questions like 'how should I configure the Anthropic key?' — the response.integrations.anthropic.configured tells you. Avoids creating a duplicate agent — response.agents tells you what already exists. Avoids a separate get_agent_metrics call — stats come inline.",
4306
+ inputSchema: obj(
4307
+ { workspace_id: str("Workspace id (bearer workspace).") },
4308
+ ["workspace_id"],
4309
+ ),
4310
+ handler: async (args) => {
4311
+ const ws = args.workspace_id;
4312
+ const result = await api("GET", "/workspace-state", {
4313
+ workspace_id: ws,
4314
+ });
4315
+ return result;
4316
+ },
4317
+ },
4318
+
4289
4319
  // ───────────────────────────────────────────────────────────────────────
4290
4320
  // v1.28.0 — SKILL BUNDLE. Wraps the canonical 4-call chatbot-build
4291
4321
  // sequence (configure_llm_provider → create_agent → publish_agent test
@@ -4479,6 +4509,153 @@ export const TOOLS = [
4479
4509
  },
4480
4510
  },
4481
4511
 
4512
+ // ───────────────────────────────────────────────────────────────────────
4513
+ // v1.28.1 — UPDATE skill bundle. Peer to build_website_chatbot for
4514
+ // the case when an agent ALREADY exists. One call to merge new FAQ /
4515
+ // pricing / greeting / capabilities into the existing blueprint
4516
+ // (bumps version), returns refreshed embed snippet + dashboard URL.
4517
+ // Saves operators from rediscovering the agent_id and re-running
4518
+ // update_agent_blueprint with full-array semantics.
4519
+ // ───────────────────────────────────────────────────────────────────────
4520
+
4521
+ {
4522
+ name: "update_website_chatbot",
4523
+ description:
4524
+ "USE WHEN USER SAYS: 'update the chatbot's FAQ', 'add new pricing to the agent', 'change the greeting', 'add a new service to the chatbot', 'the chatbot answer for X needs updating'. " +
4525
+ "ONE-CALL bundle for updating an existing website-chatbot (peer to build_website_chatbot which CREATES). Looks up the workspace's website-chatbot agent (or accepts an explicit agent_id), merges your patch into the current blueprint, bumps version, returns refreshed embed_url + dashboard_url + version + next_steps. " +
4526
+ "PATCH SEMANTICS: arrays REPLACE (not merge) per update_agent_blueprint convention — pass the FULL desired faq[] / pricing_facts[], not a delta. Greeting + capabilities are scalar replaces. If you want to ADD one FAQ pair, fetch current via get_workspace_state first and submit the full updated array. " +
4527
+ "AFTER UPDATE: re-run evals (call run_agent_evals or use the dashboard) before promoting back to live, since blueprint changes can affect agent behavior.",
4528
+ inputSchema: obj(
4529
+ {
4530
+ workspace_id: str("Workspace id (bearer workspace)."),
4531
+ agent_id: str(
4532
+ "Agent id. Optional — if omitted, the bundle finds the workspace's first website-chatbot agent (most workspaces have one).",
4533
+ ),
4534
+ faq: {
4535
+ type: "array",
4536
+ description:
4537
+ "FULL desired FAQ list (REPLACES existing). Each item: { q, a }.",
4538
+ items: obj(
4539
+ { q: str("Question."), a: str("Answer.") },
4540
+ ["q", "a"],
4541
+ ),
4542
+ },
4543
+ pricing_facts: {
4544
+ type: "array",
4545
+ description:
4546
+ "FULL desired pricing list (REPLACES existing). Each item: { label, amount, currency }.",
4547
+ items: obj(
4548
+ {
4549
+ label: str("Service name."),
4550
+ amount: { type: "number" },
4551
+ currency: str("3-letter currency code, e.g. USD."),
4552
+ },
4553
+ ["label", "amount", "currency"],
4554
+ ),
4555
+ },
4556
+ greeting: str("New greeting text. Omit to keep current."),
4557
+ capabilities: {
4558
+ type: "array",
4559
+ description:
4560
+ "FULL desired capability list (REPLACES). Default 7-tool list for website-chatbot: look_up_availability, book_appointment, find_my_existing_appointment, reschedule_appointment, cancel_appointment, escalate_to_human, provide_faq_answer.",
4561
+ items: { type: "string" },
4562
+ },
4563
+ publish_notes: str(
4564
+ "Optional one-line audit note (e.g. 'Added emergency-call FAQ').",
4565
+ ),
4566
+ },
4567
+ ["workspace_id"],
4568
+ ),
4569
+ handler: async (args) => {
4570
+ const ws = args.workspace_id;
4571
+
4572
+ // 1. Resolve agent id — either provided or look up the first
4573
+ // website-chatbot agent in the workspace.
4574
+ let agentId = args.agent_id;
4575
+ if (!agentId) {
4576
+ const stateResult = await api("GET", "/workspace-state", {
4577
+ workspace_id: ws,
4578
+ });
4579
+ const websiteChatbots = (stateResult?.agents ?? []).filter(
4580
+ (a) => a.archetype === "website-chatbot",
4581
+ );
4582
+ if (websiteChatbots.length === 0) {
4583
+ return {
4584
+ ok: false,
4585
+ error: "no_website_chatbot",
4586
+ hint:
4587
+ "No website-chatbot agent in this workspace. Call build_website_chatbot to create one first.",
4588
+ };
4589
+ }
4590
+ if (websiteChatbots.length > 1) {
4591
+ return {
4592
+ ok: false,
4593
+ error: "ambiguous_agent",
4594
+ hint:
4595
+ "Multiple website-chatbot agents found in this workspace. Pass agent_id explicitly.",
4596
+ agents: websiteChatbots.map((a) => ({
4597
+ id: a.id,
4598
+ name: a.name,
4599
+ status: a.status,
4600
+ })),
4601
+ };
4602
+ }
4603
+ agentId = websiteChatbots[0].id;
4604
+ }
4605
+
4606
+ // 2. Build the patch — only include fields explicitly provided.
4607
+ const patch = {};
4608
+ if (Array.isArray(args.faq)) patch.faq = args.faq;
4609
+ if (Array.isArray(args.pricing_facts))
4610
+ patch.pricingFacts = args.pricing_facts;
4611
+ if (typeof args.greeting === "string") patch.greeting = args.greeting;
4612
+ if (Array.isArray(args.capabilities))
4613
+ patch.capabilities = args.capabilities;
4614
+
4615
+ if (Object.keys(patch).length === 0) {
4616
+ return {
4617
+ ok: false,
4618
+ error: "empty_patch",
4619
+ hint:
4620
+ "No update fields provided. Pass at least one of: faq, pricing_facts, greeting, capabilities.",
4621
+ };
4622
+ }
4623
+
4624
+ // 3. Update the blueprint
4625
+ const updateResult = await api("POST", "/agents", {
4626
+ body: {
4627
+ op: "update_blueprint",
4628
+ agent_id: agentId,
4629
+ patch,
4630
+ publish_notes: args.publish_notes ?? undefined,
4631
+ },
4632
+ workspace_id: ws,
4633
+ });
4634
+ if (!updateResult || updateResult.ok === false) {
4635
+ return {
4636
+ ok: false,
4637
+ error: "update_failed",
4638
+ detail: updateResult,
4639
+ };
4640
+ }
4641
+
4642
+ const baseDomain =
4643
+ process.env.WORKSPACE_BASE_DOMAIN?.trim() || "app.seldonframe.com";
4644
+ return {
4645
+ ok: true,
4646
+ agent_id: agentId,
4647
+ version: updateResult.version,
4648
+ dashboard_url: `https://${baseDomain}/agents/${agentId}`,
4649
+ next_steps: [
4650
+ `Blueprint updated to v${updateResult.version}.`,
4651
+ `Re-test in sandbox: https://${baseDomain}/agents/${agentId}/test`,
4652
+ `Re-run evals before promoting to live: open https://${baseDomain}/agents/${agentId}/evals → Run evals now, OR call run_agent_evals from MCP.`,
4653
+ `If pass rate ≥ 87.5%, promote to live: publish_agent({ agent_id: '${agentId}', status: 'live' })`,
4654
+ ],
4655
+ };
4656
+ },
4657
+ },
4658
+
4482
4659
  // ───────────────────────────────────────────────────────────────────────
4483
4660
  // v1.26.2 — agent debug + observability tools.
4484
4661
  // run_agent_evals = manual eval suite trigger (publish auto-runs too).
package/src/welcome.js CHANGED
@@ -8,7 +8,7 @@
8
8
  // stripped. `create_full_workspace` is the only workspace-creation
9
9
  // path mentioned anywhere in this briefing.
10
10
 
11
- export const VERSION = "1.28.0";
11
+ export const VERSION = "1.28.2";
12
12
 
13
13
  export const WELCOME_MARKDOWN = `# SeldonFrame — create a real Business OS in one conversation
14
14
 
@@ -19,6 +19,33 @@ CRM, and AI agents — all on a real subdomain.
19
19
 
20
20
  ---
21
21
 
22
+ ## Step zero — before exploring, call \`get_workspace_state\`
23
+
24
+ For ANY workspace task ("build me a chatbot for X", "what's in this
25
+ workspace", "update the agent's FAQ", "how is my chatbot doing"), the
26
+ FIRST tool call should be \`get_workspace_state({ workspace_id })\`. It
27
+ returns in one round-trip: workspace identity, integrations status
28
+ (LLM keys, Twilio, Resend, etc. — booleans only), agents with inline
29
+ health stats (status, version, eval pass rate, validator pass rate
30
+ 24h, conversations 24h), counts (contacts, bookings, deals, agents),
31
+ and a tailored next_steps array.
32
+
33
+ This replaces ~4-6 progressive discovery calls. Without it, Claude Code
34
+ typically wastes time loading tool schemas one at a time, asking the
35
+ user obvious questions like "is the Anthropic key configured?" (the
36
+ state response answers it), and creating duplicate agents (the state
37
+ response shows what already exists).
38
+
39
+ ## Anti-patterns — DON'T do these
40
+
41
+ | Wasteful action | Why it's wrong | What to do instead |
42
+ | --------------- | -------------- | ------------------ |
43
+ | \`ls\` / \`cat package.json\` / read \`.env\` | SF is a HOSTED platform. Workspaces aren't local files. There's no node_modules to inspect, no .env to read. | Call \`get_workspace_state\` to know what's in the workspace. |
44
+ | \`node --version\` / \`npm --version\` | Irrelevant — SF runs on Vercel, not the operator's local Node. | Skip entirely. |
45
+ | Asking "how should I configure the Anthropic key?" | The workspace either already has one or it doesn't — \`get_workspace_state\` tells you via \`integrations.anthropic.configured\`. | Check the state response first. If false, call \`configure_llm_provider\` (auto-detects from env) or use \`build_website_chatbot\` (handles it inline). |
46
+ | Creating an agent without checking if one exists | Will create a duplicate — most workspaces already have a website-chatbot. | \`get_workspace_state\` returns existing agents. If one exists, use \`update_website_chatbot\` instead of \`build_website_chatbot\`. |
47
+ | Mentioning "daily token budget" / "tokens used today" | The token-budget concept was REMOVED in v1.27.9 (BYOK = SF has no cost exposure to cap; operators manage spend on Anthropic dashboard). | Don't reference it. If you see stale data showing it, ignore. |
48
+
22
49
  ## Capability map — pick the right primitive BEFORE you explore tools
23
50
 
24
51
  SeldonFrame has SEVEN top-level primitives. They are NOT the same as
@@ -406,4 +433,4 @@ admin dashboard. Pre-fills their email automatically.
406
433
  <https://seldonframe.com> · **Discord:** <https://discord.gg/sbVUu976NW>
407
434
  `;
408
435
 
409
- export const FIRST_CALL_BANNER = `🚀 SeldonFrame v1.28.0 is connected. CAPABILITY MAP — pick the right primitive BEFORE exploring tools: (a) "build me a website" → WORKSPACE → create_workspace_v2 + block tools. (b) "add a chatbot to my website / landing page" → AGENT (web chat) → build_website_chatbot (v1.28+ skill bundle: configure_llm + create_agent + publish-test in 1 call; auto-detects ANTHROPIC_API_KEY from env). Drop to primitives (configure_llm_provider + create_agent + publish_agent) only for custom flows. CRITICAL ANTI-PATTERN: chat widgets are NOT blocks. Don't search list_blocks for chat — chat agents are a separate primitive (v1.26+). (c) "auto-reply to inbound SMS/email" → CONVERSATION → send_conversation_turn (one-shot Soul-aware reply, not a website widget). (d) "add hero/services/faq/cta section" → BLOCK → get_block_skill + persist_block. (e) "send campaign email/sms" → MESSAGING. (f) CRM ops → list_contacts/create_deal/etc. CHATBOT CANONICAL FLOW (v1.28+ — 1 call instead of 5): build_website_chatbot({workspace_id, name, faq, pricing_facts, greeting}) → wraps configure_llm + create_agent + publish-test in one call, auto-detects ANTHROPIC_API_KEY from env. Then: operator sandbox-tests at /agents/[id]/test → publish_agent({status:"live"}) auto-runs 8-scenario eval gate (≥87.5% pass required). Observability tools after publish: list_agents, tail_agent_conversations, get_agent_conversation, get_agent_metrics, run_agent_evals, replay_conversation. Dashboard surfaces /agents, /agents/[id]/test, /agents/[id]/settings, /agents/[id]/evals, /agents/[id]/conversations let operators iterate without leaving the browser. WORKSPACE FLOW (legacy reference): create_workspace_v2 → IN PARALLEL for all 7 recommended_blocks (hero, services, about, faq, cta, booking, intake): get_block_skill + persist_block → complete_workspace_v2 → finalize_workspace({workspace_id, email}). Run blocks in PARALLEL (Promise.all) — sequential takes 60+ seconds. v1.10+ CUSTOMIZE: regenerate_block, upload_workspace_image (image_url preferred over base64). v1.11+ STRUCTURAL: get_landing_structure, move_section, delete_section. v1.12+ COMPOSITES: add_composite_section / update_composite_section — manifest ANY block from 12 low-level primitives. Skipping finalize_workspace leaves the operator with no admin login. Every URL is real. NEVER create local files.`;
436
+ export const FIRST_CALL_BANNER = `🚀 SeldonFrame v1.28.2 is connected. STEP ZERO: for any workspace task call get_workspace_state({workspace_id}) FIRST — returns workspace identity + integrations status + agents with inline health stats + counts + tailored next_steps in ONE round-trip. Replaces 4-6 progressive discovery calls. ANTI-PATTERNS: don't ls/cat/read .env (SF is hosted, not local files); don't check node/npm versions (irrelevant); don't ask 'is Anthropic key configured?' (state response tells you); don't create a duplicate agent (state response shows existing ones — use update_website_chatbot instead of build_website_chatbot when one exists). Token-budget concept removed in v1.27.9 — ignore stale references. CAPABILITY MAP — pick the right primitive BEFORE exploring tools: (a) "build me a website" → WORKSPACE → create_workspace_v2 + block tools. (b) "add a chatbot to my website / landing page" → AGENT (web chat) → build_website_chatbot (v1.28+ skill bundle: configure_llm + create_agent + publish-test in 1 call; auto-detects ANTHROPIC_API_KEY from env). Drop to primitives (configure_llm_provider + create_agent + publish_agent) only for custom flows. CRITICAL ANTI-PATTERN: chat widgets are NOT blocks. Don't search list_blocks for chat — chat agents are a separate primitive (v1.26+). (c) "auto-reply to inbound SMS/email" → CONVERSATION → send_conversation_turn (one-shot Soul-aware reply, not a website widget). (d) "add hero/services/faq/cta section" → BLOCK → get_block_skill + persist_block. (e) "send campaign email/sms" → MESSAGING. (f) CRM ops → list_contacts/create_deal/etc. CHATBOT CANONICAL FLOW (v1.28+ — 1 call instead of 5): build_website_chatbot({workspace_id, name, faq, pricing_facts, greeting}) → wraps configure_llm + create_agent + publish-test in one call, auto-detects ANTHROPIC_API_KEY from env. Then: operator sandbox-tests at /agents/[id]/test → publish_agent({status:"live"}) auto-runs 8-scenario eval gate (≥87.5% pass required). Observability tools after publish: list_agents, tail_agent_conversations, get_agent_conversation, get_agent_metrics, run_agent_evals, replay_conversation. Dashboard surfaces /agents, /agents/[id]/test, /agents/[id]/settings, /agents/[id]/evals, /agents/[id]/conversations let operators iterate without leaving the browser. WORKSPACE FLOW (legacy reference): create_workspace_v2 → IN PARALLEL for all 7 recommended_blocks (hero, services, about, faq, cta, booking, intake): get_block_skill + persist_block → complete_workspace_v2 → finalize_workspace({workspace_id, email}). Run blocks in PARALLEL (Promise.all) — sequential takes 60+ seconds. v1.10+ CUSTOMIZE: regenerate_block, upload_workspace_image (image_url preferred over base64). v1.11+ STRUCTURAL: get_landing_structure, move_section, delete_section. v1.12+ COMPOSITES: add_composite_section / update_composite_section — manifest ANY block from 12 low-level primitives. Skipping finalize_workspace leaves the operator with no admin login. Every URL is real. NEVER create local files.`;