@seldonframe/mcp 1.27.10 → 1.28.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 +403 -3
- package/src/welcome.js +50 -19
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seldonframe/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.1",
|
|
4
|
+
"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.",
|
|
5
|
+
"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.",
|
|
4
6
|
"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.",
|
|
5
7
|
"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.",
|
|
6
8
|
"description": "MCP server for SeldonFrame — AI-native Business OS platform. v1.27.8: RESCHEDULE/CANCEL TOOLS + ANTI-HALLUCINATION RULE (CRM-side; MCP package version bumped for SemVer hygiene). PROBLEM: real-world dogfood reschedule conversation went perfectly UX-wise — agent asked the right questions, resolved 'next Monday at 2pm', confirmed, said 'Perfect! Your appointment has been rescheduled to Monday, May 12 at 2:00 PM. You'll receive a confirmation email at dresslikeag@gmail.com.' But the database wasn't actually updated. Customer's contact-detail page in the operator's CRM still showed the OLD May 21 booking. The agent had hallucinated success. WHY: the website-chatbot archetype's default capabilities were [look_up_availability, book_appointment, find_my_existing_appointment, escalate_to_human, provide_faq_answer]. There was NO reschedule_appointment OR cancel_appointment tool. The agent, when asked to reschedule, found the booking via find_my_existing_appointment, then had no actual mutation path — but rather than escalate, it confidently fabricated the completion. ARCHITECTURAL FIX (two layers): the missing tools AND the missing constraint. WHAT SHIPS: (1) reschedule_appointment TOOL. New agent tool that ACTUALLY mutates bookings.startsAt + endsAt + updatedAt, atomic UPDATE WHERE id=booking_id AND orgId=ctx.orgId AND email=customer_email. The customer_email arg is a security check — a hallucinated bookingId from a different workspace can't slip through because the email won't match. Preserves duration (computes newEndsAt = newStartsAt + (oldEndsAt - oldStartsAt)). Returns { ok, bookingId, newStartsAt } on success, { ok: false, reason } on email mismatch / missing booking / invalid date. (2) cancel_appointment TOOL. New agent tool. UPDATE bookings SET status='cancelled' WHERE same triple-match (id, orgId, email). Same security model. (3) UPDATED DEFAULT CAPABILITIES. DEFAULT_CAPABILITIES_BY_ARCHETYPE in store.ts adds reschedule_appointment + cancel_appointment to website-chatbot, voice-receptionist, and sms-followup-bot. New agents created from v1.27.8 onwards include them automatically. (4) SETTINGS UI EXPOSES NEW CAPS. ALL_CAPABILITIES in /agents/[id]/settings/page.tsx adds the two new toggles. Existing agents (created pre-v1.27.8) need their operator to check the new boxes + Save to enable the tools — auto-mutation of existing blueprints is intentionally avoided. (5) ANTI-HALLUCINATION SYSTEM PROMPT RULE. The 'Be smart by default' section in composeSystemPrompt gains a new rule #6: 'NEVER claim an action you didn't actually take.' Explicit list: 'I rescheduled it' / 'Done, you're booked' / 'I cancelled it' / 'I let the team know' all REQUIRE the corresponding tool call (reschedule_appointment / book_appointment / cancel_appointment / escalate_to_human) with ok=true returned BEFORE the agent confirms to the visitor. Operator never authors this — platform owns it. As Claude gets better at avoiding action hallucinations, this rule becomes a hint instead of a crutch; architecture stable. NO migrations, NO new env vars. Backend redeploy required. EXISTING-AGENT MIGRATION: operators of pre-v1.27.8 agents need ONE manual step — open /agents/<id>/settings, tick the two new capability boxes (reschedule_appointment + cancel_appointment), Save. Or call update_agent_blueprint from Claude Code with the full new capabilities array. EXPECTED IMPACT on the conversation that triggered this fix: agent calls reschedule_appointment(booking_id=..., new_starts_at_iso='2026-05-12T14:00:00Z', customer_email='dresslikeag@gmail.com'), gets ok=true, THEN tells the visitor 'Done — you're now booked for Monday, May 12 at 2:00 PM.' The booking row actually moves. Operator's CRM contact-detail page reflects the new time.",
|
package/src/tools.js
CHANGED
|
@@ -4056,6 +4056,7 @@ export const TOOLS = [
|
|
|
4056
4056
|
"The OPERATOR pays the LLM provider directly (Anthropic / OpenAI / etc.); SF charges separately for agent platform usage. " +
|
|
4057
4057
|
"Stored encrypted at rest using the deployment's ENCRYPTION_KEY. " +
|
|
4058
4058
|
"Operators get keys from console.anthropic.com (recommended for v1.26.x — best tool-use support) or platform.openai.com. " +
|
|
4059
|
+
"v1.28+ AUTO-DETECT: pass api_key='env' (or omit api_key entirely) and the MCP server will read process.env.ANTHROPIC_API_KEY / OPENAI_API_KEY from its own environment. Most Claude Code users already have this set (it's how Claude Code works), so this lets a solo SF client onboard with zero key-paste step. Returns { ok: false, error: 'no_env_key' } if the env var isn't set; in that case the user must paste the key explicitly. " +
|
|
4059
4060
|
"Skip if the workspace already has a key — agents fail-graceful with 'I'm not set up yet' if no key configured, so a 'not configured' chatbot response means CALL THIS TOOL.",
|
|
4060
4061
|
inputSchema: obj(
|
|
4061
4062
|
{
|
|
@@ -4067,21 +4068,50 @@ export const TOOLS = [
|
|
|
4067
4068
|
"LLM provider. v1.26 ships full Anthropic support (tool use, streaming-ready). OpenAI support for chat is partial — recommend Anthropic for production agents.",
|
|
4068
4069
|
},
|
|
4069
4070
|
api_key: str(
|
|
4070
|
-
"API key. Anthropic keys start with 'sk-ant-...'. Stored encrypted; never echoed back
|
|
4071
|
+
"API key. Anthropic keys start with 'sk-ant-...'. Stored encrypted; never echoed back. v1.28+ AUTO-DETECT: pass 'env' (literal string) or omit entirely to read process.env.{ANTHROPIC,OPENAI}_API_KEY from the MCP server's local environment.",
|
|
4071
4072
|
),
|
|
4072
4073
|
},
|
|
4073
|
-
["workspace_id", "provider"
|
|
4074
|
+
["workspace_id", "provider"],
|
|
4074
4075
|
),
|
|
4075
4076
|
handler: async (args) => {
|
|
4076
4077
|
const ws = args.workspace_id;
|
|
4078
|
+
let apiKey = args.api_key;
|
|
4079
|
+
|
|
4080
|
+
// v1.28 — auto-detect from MCP server's local environment.
|
|
4081
|
+
// Triggered by: omitted api_key, empty string, or literal 'env'.
|
|
4082
|
+
const wantsEnv = !apiKey || apiKey === "env" || apiKey === "$ENV";
|
|
4083
|
+
if (wantsEnv) {
|
|
4084
|
+
const envName =
|
|
4085
|
+
args.provider === "openai" ? "OPENAI_API_KEY" : "ANTHROPIC_API_KEY";
|
|
4086
|
+
apiKey = process.env[envName];
|
|
4087
|
+
if (!apiKey) {
|
|
4088
|
+
return {
|
|
4089
|
+
ok: false,
|
|
4090
|
+
error: "no_env_key",
|
|
4091
|
+
hint:
|
|
4092
|
+
`${envName} not set in the MCP server's environment. ` +
|
|
4093
|
+
`Either: (a) set ${envName} in your shell before launching Claude Code (most Claude Code users already have this), ` +
|
|
4094
|
+
`or (b) pass api_key='sk-ant-...' explicitly. ` +
|
|
4095
|
+
`For platform-deployment scenarios where keys differ per workspace (e.g. agency managing multiple HVAC clients with separate Anthropic billing), always pass api_key explicitly — env auto-detect is for solo-operator convenience.`,
|
|
4096
|
+
envName,
|
|
4097
|
+
};
|
|
4098
|
+
}
|
|
4099
|
+
}
|
|
4100
|
+
|
|
4077
4101
|
const result = await api("POST", "/agents", {
|
|
4078
4102
|
body: {
|
|
4079
4103
|
op: "set_llm_key",
|
|
4080
4104
|
provider: args.provider,
|
|
4081
|
-
api_key:
|
|
4105
|
+
api_key: apiKey,
|
|
4082
4106
|
},
|
|
4083
4107
|
workspace_id: ws,
|
|
4084
4108
|
});
|
|
4109
|
+
// v1.28 — annotate the response so the LLM knows whether env was used
|
|
4110
|
+
// (so it can tell the user 'I auto-detected your key from your shell env'
|
|
4111
|
+
// vs 'I saved the key you provided').
|
|
4112
|
+
if (result && typeof result === "object" && result.ok) {
|
|
4113
|
+
return { ...result, source: wantsEnv ? "env_inherited" : "explicit" };
|
|
4114
|
+
}
|
|
4085
4115
|
return result;
|
|
4086
4116
|
},
|
|
4087
4117
|
},
|
|
@@ -4256,6 +4286,376 @@ export const TOOLS = [
|
|
|
4256
4286
|
},
|
|
4257
4287
|
},
|
|
4258
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
|
+
|
|
4319
|
+
// ───────────────────────────────────────────────────────────────────────
|
|
4320
|
+
// v1.28.0 — SKILL BUNDLE. Wraps the canonical 4-call chatbot-build
|
|
4321
|
+
// sequence (configure_llm_provider → create_agent → publish_agent test
|
|
4322
|
+
// → return embed snippet) into ONE call. Reduces ~30s + 4 round-trips
|
|
4323
|
+
// to ~5s + 1 round-trip. Primitives stay fully callable for power users
|
|
4324
|
+
// who need a custom flow; this is sugar.
|
|
4325
|
+
// ───────────────────────────────────────────────────────────────────────
|
|
4326
|
+
|
|
4327
|
+
{
|
|
4328
|
+
name: "build_website_chatbot",
|
|
4329
|
+
description:
|
|
4330
|
+
"USE WHEN USER SAYS: 'build me a chatbot for [business]', 'add a chatbot to my website', 'create a website chatbot', 'put a chat widget on my homepage', 'set up an AI assistant for my landing page'. " +
|
|
4331
|
+
"ONE-CALL skill bundle that does the canonical chatbot setup end-to-end: " +
|
|
4332
|
+
"(1) auto-configures the workspace's Anthropic LLM key from process.env.ANTHROPIC_API_KEY if no key is configured yet (most Claude Code users already have this set), or accepts an explicit anthropic_api_key arg; " +
|
|
4333
|
+
"(2) creates a website-chatbot agent with the FAQ + pricing facts + greeting you provide; " +
|
|
4334
|
+
"(3) publishes to status='test' so the operator can sandbox-test before going live (the eval gate runs only on 'live'); " +
|
|
4335
|
+
"(4) returns the embed snippet, dashboard URL, and clear next-steps. " +
|
|
4336
|
+
"USE THIS as the default for natural-language 'create a chatbot' requests. Fall back to the primitive tools (configure_llm_provider + create_agent + publish_agent) only when you need a custom flow (e.g. agency managing multiple operators with separate Anthropic billing — pass anthropic_api_key explicitly per workspace).",
|
|
4337
|
+
inputSchema: obj(
|
|
4338
|
+
{
|
|
4339
|
+
workspace_id: str("Workspace id (bearer workspace)."),
|
|
4340
|
+
name: str(
|
|
4341
|
+
"Agent display name (e.g. 'Cypress & Pine HVAC Assistant'). Surfaces in chat header.",
|
|
4342
|
+
),
|
|
4343
|
+
faq: {
|
|
4344
|
+
type: "array",
|
|
4345
|
+
description:
|
|
4346
|
+
"Operator-curated FAQ pairs. Each item is { q, a }. Pass at least 3-5 covering the top customer questions: hours, service area, common issues, what to expect.",
|
|
4347
|
+
items: obj(
|
|
4348
|
+
{
|
|
4349
|
+
q: str("Question as a visitor would phrase it."),
|
|
4350
|
+
a: str("Operator's exact answer (1-3 sentences)."),
|
|
4351
|
+
},
|
|
4352
|
+
["q", "a"],
|
|
4353
|
+
),
|
|
4354
|
+
},
|
|
4355
|
+
pricing_facts: {
|
|
4356
|
+
type: "array",
|
|
4357
|
+
description:
|
|
4358
|
+
"ONLY prices the agent may quote. Critical for safety — without this, agent refuses ALL price questions (safer default). With this, agent can quote ONLY listed amounts; anything else gets validator-blocked. Each item: { label, amount, currency }.",
|
|
4359
|
+
items: obj(
|
|
4360
|
+
{
|
|
4361
|
+
label: str("Service name (e.g. 'Service call', 'AC tune-up')."),
|
|
4362
|
+
amount: { type: "number" },
|
|
4363
|
+
currency: str("3-letter code, e.g. USD."),
|
|
4364
|
+
},
|
|
4365
|
+
["label", "amount", "currency"],
|
|
4366
|
+
),
|
|
4367
|
+
},
|
|
4368
|
+
greeting: str(
|
|
4369
|
+
"First message shown when chat opens (~120 chars). E.g. 'Hi! Asking about HVAC service in Phoenix? I can book you in or answer common questions.' Default if omitted: 'Hi! How can I help you today?'",
|
|
4370
|
+
),
|
|
4371
|
+
anthropic_api_key: str(
|
|
4372
|
+
"Optional explicit Anthropic API key (sk-ant-...). If omitted, reads from process.env.ANTHROPIC_API_KEY in the MCP server's environment. Pass explicitly for white-label scenarios (different operator = different Anthropic billing). Skipped entirely if the workspace already has a key configured.",
|
|
4373
|
+
),
|
|
4374
|
+
},
|
|
4375
|
+
["workspace_id", "name"],
|
|
4376
|
+
),
|
|
4377
|
+
handler: async (args) => {
|
|
4378
|
+
const ws = args.workspace_id;
|
|
4379
|
+
const steps = [];
|
|
4380
|
+
|
|
4381
|
+
// 1. Configure LLM (auto-detect from env if no explicit key)
|
|
4382
|
+
// We try this BEFORE create_agent so failures surface clearly.
|
|
4383
|
+
// If a key is already configured for this workspace, the set_llm_key
|
|
4384
|
+
// op is idempotent (overwrites); harmless to call. If neither
|
|
4385
|
+
// explicit nor env key is available, fail fast with a clear error
|
|
4386
|
+
// so the user can paste a key.
|
|
4387
|
+
const explicitKey = args.anthropic_api_key;
|
|
4388
|
+
const envKey = process.env.ANTHROPIC_API_KEY;
|
|
4389
|
+
const keyToUse = explicitKey || envKey;
|
|
4390
|
+
if (!keyToUse) {
|
|
4391
|
+
return {
|
|
4392
|
+
ok: false,
|
|
4393
|
+
error: "no_anthropic_key",
|
|
4394
|
+
hint:
|
|
4395
|
+
"No Anthropic key available. Either: (a) set ANTHROPIC_API_KEY in your shell before launching Claude Code (most Claude Code users already have this), " +
|
|
4396
|
+
"or (b) pass anthropic_api_key='sk-ant-...' explicitly to this tool, " +
|
|
4397
|
+
"or (c) configure via the dashboard at /settings/integrations/llm before calling create_agent. " +
|
|
4398
|
+
"Without a key, the agent will be created in draft but every customer turn will return 'I'm not set up yet'.",
|
|
4399
|
+
steps,
|
|
4400
|
+
};
|
|
4401
|
+
}
|
|
4402
|
+
const configResult = await api("POST", "/agents", {
|
|
4403
|
+
body: {
|
|
4404
|
+
op: "set_llm_key",
|
|
4405
|
+
provider: "anthropic",
|
|
4406
|
+
api_key: keyToUse,
|
|
4407
|
+
},
|
|
4408
|
+
workspace_id: ws,
|
|
4409
|
+
});
|
|
4410
|
+
if (!configResult || configResult.ok === false) {
|
|
4411
|
+
return {
|
|
4412
|
+
ok: false,
|
|
4413
|
+
error: "llm_config_failed",
|
|
4414
|
+
detail: configResult,
|
|
4415
|
+
steps,
|
|
4416
|
+
};
|
|
4417
|
+
}
|
|
4418
|
+
steps.push({
|
|
4419
|
+
step: "configure_llm_provider",
|
|
4420
|
+
ok: true,
|
|
4421
|
+
source: explicitKey ? "explicit" : "env_inherited",
|
|
4422
|
+
});
|
|
4423
|
+
|
|
4424
|
+
// 2. Create the agent
|
|
4425
|
+
const createResult = await api("POST", "/agents", {
|
|
4426
|
+
body: {
|
|
4427
|
+
op: "create",
|
|
4428
|
+
name: args.name,
|
|
4429
|
+
archetype: "website-chatbot",
|
|
4430
|
+
channel: "web_chat",
|
|
4431
|
+
faq: args.faq ?? [],
|
|
4432
|
+
pricing_facts: args.pricing_facts ?? [],
|
|
4433
|
+
greeting:
|
|
4434
|
+
args.greeting ?? "Hi! How can I help you today?",
|
|
4435
|
+
},
|
|
4436
|
+
workspace_id: ws,
|
|
4437
|
+
});
|
|
4438
|
+
if (!createResult || createResult.ok === false) {
|
|
4439
|
+
return {
|
|
4440
|
+
ok: false,
|
|
4441
|
+
error: "create_agent_failed",
|
|
4442
|
+
detail: createResult,
|
|
4443
|
+
steps,
|
|
4444
|
+
};
|
|
4445
|
+
}
|
|
4446
|
+
steps.push({
|
|
4447
|
+
step: "create_agent",
|
|
4448
|
+
ok: true,
|
|
4449
|
+
agent_id: createResult.agent?.id,
|
|
4450
|
+
});
|
|
4451
|
+
|
|
4452
|
+
const agentId = createResult.agent?.id;
|
|
4453
|
+
if (!agentId) {
|
|
4454
|
+
return {
|
|
4455
|
+
ok: false,
|
|
4456
|
+
error: "create_agent_returned_no_id",
|
|
4457
|
+
detail: createResult,
|
|
4458
|
+
steps,
|
|
4459
|
+
};
|
|
4460
|
+
}
|
|
4461
|
+
|
|
4462
|
+
// 3. Publish to test (sandbox-callable; eval gate doesn't run yet)
|
|
4463
|
+
const publishResult = await api("POST", "/agents", {
|
|
4464
|
+
body: {
|
|
4465
|
+
op: "publish",
|
|
4466
|
+
agent_id: agentId,
|
|
4467
|
+
status: "test",
|
|
4468
|
+
},
|
|
4469
|
+
workspace_id: ws,
|
|
4470
|
+
});
|
|
4471
|
+
if (!publishResult || publishResult.ok === false) {
|
|
4472
|
+
// Created but not published. Return partial success so the user
|
|
4473
|
+
// can publish manually.
|
|
4474
|
+
return {
|
|
4475
|
+
ok: false,
|
|
4476
|
+
error: "publish_failed_but_agent_created",
|
|
4477
|
+
agent: createResult.agent,
|
|
4478
|
+
embed_url: createResult.embed_url,
|
|
4479
|
+
turn_url: createResult.turn_url,
|
|
4480
|
+
publish_detail: publishResult,
|
|
4481
|
+
steps,
|
|
4482
|
+
next_steps: [
|
|
4483
|
+
`Agent ${agentId} was created but couldn't be published to test. Call publish_agent({ agent_id: '${agentId}', status: 'test' }) manually, or check the dashboard at /agents/${agentId}`,
|
|
4484
|
+
],
|
|
4485
|
+
};
|
|
4486
|
+
}
|
|
4487
|
+
steps.push({ step: "publish_agent_test", ok: true });
|
|
4488
|
+
|
|
4489
|
+
// 4. Compose the operator-friendly final response.
|
|
4490
|
+
const baseDomain =
|
|
4491
|
+
process.env.WORKSPACE_BASE_DOMAIN?.trim() || "app.seldonframe.com";
|
|
4492
|
+
const dashboardUrl = `https://${baseDomain}/agents/${agentId}`;
|
|
4493
|
+
|
|
4494
|
+
return {
|
|
4495
|
+
ok: true,
|
|
4496
|
+
agent: createResult.agent,
|
|
4497
|
+
embed_url: createResult.embed_url,
|
|
4498
|
+
turn_url: createResult.turn_url,
|
|
4499
|
+
dashboard_url: dashboardUrl,
|
|
4500
|
+
sandbox_url: `${dashboardUrl}/test`,
|
|
4501
|
+
steps,
|
|
4502
|
+
next_steps: [
|
|
4503
|
+
`1. Test in sandbox: ${dashboardUrl}/test (chat with the agent before customers do).`,
|
|
4504
|
+
`2. Run safety evals: open ${dashboardUrl}/evals → Run evals now (8-scenario suite).`,
|
|
4505
|
+
`3. When ready, publish to live: call publish_agent({ agent_id: '${agentId}', status: 'live' }) — auto-runs eval gate, requires ≥87.5% pass.`,
|
|
4506
|
+
`4. Drop on the operator's website: <script src="${createResult.embed_url}" async></script>`,
|
|
4507
|
+
],
|
|
4508
|
+
};
|
|
4509
|
+
},
|
|
4510
|
+
},
|
|
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
|
+
|
|
4259
4659
|
// ───────────────────────────────────────────────────────────────────────
|
|
4260
4660
|
// v1.26.2 — agent debug + observability tools.
|
|
4261
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.
|
|
11
|
+
export const VERSION = "1.28.1";
|
|
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
|
|
@@ -30,7 +57,7 @@ tool that doesn't exist in that primitive.
|
|
|
30
57
|
| Operator says… | Primitive | Entry-point tools |
|
|
31
58
|
| -------------------------------------------------------------- | -------------------- | --------------------------------------------------------------------- |
|
|
32
59
|
| "Build me a website / business / CRM" | **WORKSPACE** | \`create_workspace_v2\` then block tools |
|
|
33
|
-
| "Add an AI chatbot to my website / landing page" | **AGENT** (web chat) | \`
|
|
60
|
+
| "Add an AI chatbot to my website / landing page" | **AGENT** (web chat) | \`build_website_chatbot\` (one call: configure_llm + create + publish-test) |
|
|
34
61
|
| "Build me a 24/7 AI receptionist for my phone" | AGENT (voice) | (v1.28+ — voice archetype shipping soon) |
|
|
35
62
|
| "Reply to inbound customer SMS / email automatically" | **CONVERSATION** | \`send_conversation_turn\` (one-shot Soul-aware reply) |
|
|
36
63
|
| "Add a hero / services / FAQ / CTA section to a page" | **BLOCK** | \`get_block_skill\` + \`persist_block\` |
|
|
@@ -61,19 +88,13 @@ when shipping) and SMS auto-reply (use the CONVERSATION primitive's
|
|
|
61
88
|
|
|
62
89
|
## Build a website chatbot — the canonical short flow
|
|
63
90
|
|
|
64
|
-
Most operators asking for "AI on my website" want this exact flow.
|
|
65
|
-
|
|
91
|
+
Most operators asking for "AI on my website" want this exact flow. As
|
|
92
|
+
of v1.28.0 this is **ONE tool call**:
|
|
66
93
|
|
|
67
94
|
\`\`\`
|
|
68
|
-
1.
|
|
69
|
-
// Skip if workspace already has a key. SF uses BYOK — operator pays
|
|
70
|
-
// Anthropic directly for the LLM; SF charges per agent turn separately.
|
|
71
|
-
|
|
72
|
-
2. create_agent({
|
|
95
|
+
1. build_website_chatbot({
|
|
73
96
|
workspace_id,
|
|
74
97
|
name: "Cypress Pine HVAC Helper",
|
|
75
|
-
archetype: "website-chatbot",
|
|
76
|
-
channel: "web_chat",
|
|
77
98
|
greeting: "Hi! Asking about HVAC service in Phoenix? I can book you in.",
|
|
78
99
|
faq: [
|
|
79
100
|
{ q: "What areas do you service?", a: "Phoenix, Scottsdale, Tempe..." },
|
|
@@ -83,19 +104,29 @@ Most operators asking for "AI on my website" want this exact flow.
|
|
|
83
104
|
{ label: "Service call", amount: 89, currency: "USD" },
|
|
84
105
|
{ label: "AC tune-up", amount: 149, currency: "USD" }
|
|
85
106
|
]
|
|
107
|
+
// anthropic_api_key omitted → auto-detected from
|
|
108
|
+
// process.env.ANTHROPIC_API_KEY in the MCP server's environment
|
|
109
|
+
// (most Claude Code users already have this set).
|
|
86
110
|
})
|
|
87
|
-
// → returns { agent, embed_url, turn_url, next_steps }
|
|
88
|
-
|
|
89
|
-
3. publish_agent({ workspace_id, agent_id, status: "test" })
|
|
90
|
-
// Sandbox-test the agent in the dashboard before flipping to live.
|
|
111
|
+
// → returns { agent, embed_url, turn_url, dashboard_url, next_steps }
|
|
112
|
+
// Internally: configures LLM key, creates agent, publishes to test.
|
|
91
113
|
|
|
92
|
-
|
|
114
|
+
2. (Operator sandbox-tests at /agents/[id]/test.)
|
|
93
115
|
|
|
94
|
-
|
|
95
|
-
//
|
|
116
|
+
3. publish_agent({ agent_id, status: "live" })
|
|
117
|
+
// Auto-runs the 8-scenario eval gate. Requires ≥87.5% pass rate.
|
|
96
118
|
// Surfaces failing scenarios so the operator can fix in /agents/[id]/settings.
|
|
97
119
|
\`\`\`
|
|
98
120
|
|
|
121
|
+
If the operator manages multiple workspaces with separate Anthropic
|
|
122
|
+
billing (e.g. Acme AI agency managing Cypress Pine HVAC + Sunset
|
|
123
|
+
Dental), pass anthropic_api_key explicitly per workspace instead of
|
|
124
|
+
relying on env auto-detect.
|
|
125
|
+
|
|
126
|
+
For custom flows (different archetype, custom capability allowlist,
|
|
127
|
+
multi-step blueprint construction), drop down to the primitives:
|
|
128
|
+
configure_llm_provider + create_agent + publish_agent + update_agent_blueprint.
|
|
129
|
+
|
|
99
130
|
Then the operator drops the embed snippet onto their site, OR you can
|
|
100
131
|
help them edit a block on the SF-hosted landing page to include it.
|
|
101
132
|
|
|
@@ -402,4 +433,4 @@ admin dashboard. Pre-fills their email automatically.
|
|
|
402
433
|
<https://seldonframe.com> · **Discord:** <https://discord.gg/sbVUu976NW>
|
|
403
434
|
`;
|
|
404
435
|
|
|
405
|
-
export const FIRST_CALL_BANNER = `🚀 SeldonFrame v1.
|
|
436
|
+
export const FIRST_CALL_BANNER = `🚀 SeldonFrame v1.28.1 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.`;
|