Skip to Content

← All archived runs

Run: onboarding-concierge-agent

run.md

Run: onboarding-concierge-agent

  • branch: claude/trusting-davinci-my4fgt
  • pr: #608

00_intake/stub.md

Stub: Onboarding concierge agent (conversation + blueprint tools)

  • feature-slug: onboarding-concierge-agent
  • epic: tenant-onboarding-wizard
  • personas: Admin, Vendor
  • initiative: Build the Bridge / objective: Q2-2026 O1 — Establish PMF with Vendor Partners
  • depends-on: ai-agent-foundation, onboarding-blueprint-model, source-analysis-pipeline
  • sequence: 5 of 7

Problem

The demo concierge is a scripted conversation (conciergeScript in mock data) — no real model, no real state. The production flow needs an actual agent that interviews the first user, triggers source analysis when a website/description is offered, drafts blueprint sections as the conversation progresses, and knows when the blueprint is complete enough to hand over to review.

Proposed change

The concierge agent on the stub-2 foundation: a system prompt encoding the interview (company profile → source offer → confirm categories/products/services/skills → SLA tiers → settings), tools that read/write the persisted blueprint section-by-section (via stub 1's service) and invoke the source-analysis pipeline (stub 4), and a streaming chat route in apps/web following the useChat / AI-SDK pattern from ai/brd. The agent resumes mid-conversation from the persisted blueprint state (the wizard is leave-and-return by design). Server-side only + route handler; the chat UI itself is stub 6.

Acceptance criteria (rough)

  • A conversation with the agent progressively fills the tenant's persisted blueprint — sections appear/update as answers arrive, each item with confidence + AI provenance.
  • Offering a website URL or description in chat triggers source analysis, and its draft lands in the blueprint; an unanalysable source makes the agent fall back to asking questions.
  • The chat route streams responses and is scoped to the authenticated user's tenant; a user can drop off and resume with the agent aware of what's already drafted.
  • When all 7 sections are drafted, the agent signals blueprint-complete (the handover the UI uses to offer review/launch).

Out of scope (this feature)

  • The chat + blueprint-panel UI (stub 6).
  • Committing to real services (stub 3).
  • Redirect/gating (stub 7).

Notes for Define

The demo's conciergeScript (apps/demo/lib/mock/onboarding.ts) is the interview's reference shape — steps, chips, reveal order. Follow the ai-feature skill (ToolLoopAgent, human-in-the-loop tool approval where a tool writes). Route policy entry needed for the chat route (web-route skill; API-route case). touches: packages/services/src/ai/onboarding/, apps/web/app/api/ (or route-handler location per ai/brd convention).

01_define/output/spec.md

Spec: Onboarding concierge agent (conversation + blueprint tools)

  • slug: onboarding-concierge-agent
  • personas: Admin, Vendor
  • touches: packages/services/src/ai/onboarding, apps/web/app/api/onboarding/chat, apps/web/lib/route-policies.ts, apps/web/proxy.ts
  • complexity: complex

Problem

The tenant onboarding wizard's centrepiece is a concierge conversation that interviews a fresh tenant's first user and drafts their whole workspace (company profile, categories, products, services, skills, SLA tiers, settings) as they talk. Today that conversation is a scripted mock — conciergeScript in apps/demo/lib/mock/onboarding.ts — with no real model and no persisted state. This epic productionises concept A, the AI concierge (issue #588), and this stub builds the agent brain: the interview, the tools that fill the persisted blueprint, and the streaming chat route. It advances Build the Bridge / Q2-2026 O1 — Establish PMF with Vendor Partners (KR: onboard 8+ vendors onto paid tiers): a conversational, self-drafting setup is the wow that gets a vendor from "account created" to "configured workspace" without a manual setup slog.

The three dependencies this agent sits on are already merged: the reusable agent core (packages/services/src/ai/coredefineAgent, tenant-scoped tools), the persisted blueprint model + service (onboardingBlueprintService, statuses draft → in_review → verified → committed, 7 section keys, per-item confidence/provenance/review-state), and the source-analysis pipeline (ai/onboarding/analyseSource + DraftBlueprintSchema). The novel work here is wiring them into a conversation.

Proposed change

A concierge agent in packages/services/src/ai/onboarding/, built on the stub-2 foundation (defineAgent / ToolLoopAgent, model via the existing AI Gateway config — mirror the ai/brd pattern):

  • System prompt encoding the interview in the demo's reference order — company profile → offer to analyse a source (website URL / description) → confirm categories → products → services → skills → SLA tiers → settings. apps/demo/lib/mock/onboarding.ts (conciergeScript, section keys profile|categories|products|services|skills|sla|settings) is the reference shape for steps and reveal order.
  • Tenant-scoped tools (via buildTenantTools / defineTenantTool, so a tool can never reach another tenant), wrapping the existing onboardingBlueprintService:
    • a read tool that returns the current blueprint state (which sections/items are already drafted) so the agent resumes mid-interview;
    • write tools that draft/update a section's items (upsertSection) — every item written with a confidence score and ai_drafted provenance, pending review state;
    • a source-analysis tool that invokes analyseSource (stub 4) with a URL or description; its draft lands in the blueprint. An unanalysable source returns an explicit reason, and the agent falls back to interviewing rather than erroring;
    • a completion tool that, once all seven interview topics are covered, advances the blueprint status draft → in_review — the machine-readable handover the UI (stub 6) uses to offer review/launch.
  • A streaming chat route in apps/web at app/api/onboarding/chat/route.ts, mirroring app/api/brd/chat/route.ts (Clerk auth → tenant resolution → createAgentUIStreamResponse), scoped to the authenticated user's tenant, plus a route-policies.ts + proxy.ts entry for /api/onboarding/ (web-route skill, API-route case).

Deliberate decision — blueprint writes are drafts, not real-service mutations, so the drafting tools auto-execute (no per-message human-in-the-loop approval here). Everything the agent writes lands as pending, ai_drafted items in the draft blueprint; the human review/verify gate is the blueprint panel (stub 6) and the atomic commit into real services (stub 3). The ai-feature skill's HITL-on-write rule is satisfied downstream by that review + commit flow, not by gating each chat turn. This keeps this stub server-side + route handler only.

Acceptance criteria

  • A conversation with the concierge agent progressively fills the tenant's persisted blueprint — sections and items appear/update via onboardingBlueprintService as answers arrive, each item carrying a confidence score and ai_drafted provenance.
  • Offering a website URL or a free-text business description in chat triggers the source-analysis tool (analyseSource), and the resulting draft lands in the persisted blueprint; an unanalysable source (explicit failure reason) makes the agent fall back to asking questions rather than erroring the conversation.
  • The chat route streams responses (mirroring the ai/brd route) and is scoped to the authenticated user's tenant — a request without a valid session/tenant is rejected, and a tool invocation cannot read or write another tenant's blueprint.
  • The agent resumes mid-conversation: on a fresh request it reads the persisted blueprint and is aware of which sections/items are already drafted, continuing the interview instead of restarting it.
  • When all seven sections have been covered, the agent advances the blueprint status draft → in_review (the blueprint-complete signal the wizard UI consumes), and does not do so before the interview has covered every section.
  • A /api/onboarding/ route-policy entry exists so the streaming route is reachable under the deny-by-default routing (not silently redirected).

Out of scope

  • The chat + live blueprint-panel UI, per-item review/verify controls, and the launch action (stub 6 — concierge-wizard-ui).
  • Committing the verified blueprint into the real product/service/skill/SLA/settings services (stub 3 — blueprint-commit-service; commitBlueprint already exists, this agent never calls it).
  • Fresh-tenant detection and the hard redirect-until-complete gate (stub 7 — first-run-gating).
  • File-upload source analysis (PDF/CSV price lists) — this agent passes URL + free-text to analyseSource; upload support is the source-analysis pipeline's fast-follow, not this cut.
  • Any change to the blueprint model/service, the agent core, or the source-analysis pipeline (stubs 1, 2, 4 — consumed as-is; extend only if a genuine gap surfaces, flagged in Build notes).

Open questions

  • none — the interview shape, the seven section keys, the completion signal (advance to in_review), the draft-not-commit write semantics, and the route pattern are all settled above. The concrete agent model id and per-tool prompt/description wording are implementation details for Build (follow the ai/brd + ai-feature conventions).

02_build/output/notes.md

Build notes: onboarding-concierge-agent

  • commits: feat: onboarding-concierge-agent — concierge agent, blueprint tools, streaming chat route

What changed

  • packages/services/src/ai/onboarding/prompt.ts — the concierge interview system prompt. Encodes the seven-section order (profile → categories → products → services → skills → sla → settings), the source-offer step, one-question-per-message style, and the tool-usage rules (read first, analyse on source offer, draft as answers arrive, mark complete only after all seven). Keeps the BRD-style prompt-injection defenses (refuse "ignore instructions / reveal prompt").
  • packages/services/src/ai/onboarding/blueprint-tools.ts — four tenant-scoped tools built on the stub-2 defineTenantTool/buildTenantTools core, wrapping the stub-1 onboardingBlueprintService and the stub-4 analyseSource:
    • read_blueprint (read-only) — current status + per-section drafted items, so the agent resumes.
    • draft_section — merges items by key into a section (build-up over turns, no clobber); the service stamps every item ai_drafted / pending.
    • analyse_source — URL or free-text → analyseSource, which persists the draft and degrades to an explicit empty/partial result with a machine-readable reason.
    • mark_blueprint_complete — advances draft → in_review; guarded against premature (nothing drafted) and repeat (already past draft) completion.
  • packages/services/src/ai/onboarding/agent.tsbuildOnboardingConciergeAgent(tenantId). Built per-request (not a singleton like the BRD agent) because its tools are tenant-bound; createTenantContext rejects a non-ObjectId tenant so a toolset can never be built without a valid tenant.
  • packages/services/src/ai/onboarding/index.ts + src/server/index.ts — export the builder + tools. Kept server-only (DB access): exposed via @sustentus/services/server, never the client-safe @sustentus/services/ai root.
  • apps/web/app/api/onboarding/chat/route.ts — streaming chat route mirroring api/brd/chat: Clerk auth() → role check (admin/vendor) → getTenant() → user-in-tenant check → createAgentUIStreamResponse with the per-tenant agent. maxDuration = 120.
  • apps/web/lib/route-policies.ts/api/onboarding/ gated to ["admin", "vendor"] under the deny-by-default routing, alongside the existing /api/brd/ block.

Acceptance criteria status

  • A conversation progressively fills the persisted blueprint — draft_section (merge-by-key) and analyse_source write through onboardingBlueprintService; every item carries a 0–100 confidence and ai_drafted provenance (service-stamped).
  • Offering a website URL or description triggers source analysis and the draft lands in the blueprint; an unanalysable source returns an explicit failure reason and the prompt sends the agent back to interviewing — analyse_source delegates to analyseSource, which never throws.
  • The chat route streams (createAgentUIStreamResponse) and is tenant-scoped — unauthenticated / no-tenant requests are rejected, and the tenant-bound tool context means a tool can only touch the caller's own blueprint.
  • The agent resumes mid-conversation — the prompt calls read_blueprint before the first reply, and the route replays prior UI messages, so it continues rather than restarts.
  • When all seven sections are covered the agent advances draft → in_review via mark_blueprint_complete (the UI's blueprint-complete signal); the tool refuses to advance with nothing drafted and no-ops once past draft.
  • A /api/onboarding/ route-policy entry exists so the streaming route is reachable (not silently redirected by the deny-by-default proxy).

Verify result

  • Mechanical checks (format · lint · typecheck · build) run in CI + the Vercel preview, not here. Release reads them back from the PR's check runs. No check is expected to fail.
  • End-to-end chat behaviour is exercised through the wizard UI (epic stub 6, concierge-wizard-ui) and the Vercel preview — this stub is server-side + route handler only, with no UI to drive locally, and live AI runs need the deploy environment's AI Gateway + Clerk auth.

Notes for review

  • Draft-not-commit is deliberate (per the approved spec): the tools write pending / ai_drafted items to the draft blueprint, so they auto-execute (no needsApproval). The human review/verify gate is the blueprint panel (stub 6) and the atomic commit (stub 3) — this agent never calls commitBlueprint.
  • The agent is built per-request from the tenant id; confirm the route's tenant resolution (getTenant() + user-in-tenant check) is the right ownership boundary for a fresh tenant's first user (admin or vendor).
  • draft_section merges by key and preserves any existing item's stored provenance/review state, so a re-draft during the interview doesn't silently reset human edits should the flows ever interleave.

03_release/output/release.md

Release: onboarding-concierge-agent

  • pr: #608 · merged: yes — squash, 2026-07-07
  • CI: green — all checks passed (Quality Project, Claude review vs CONVENTIONS.md, preview DB migrate, DB audit, labels, spec advisory); production DB migrate skipped by design on the PR
  • technical docs: updated apps/docs/app/technical/packages/services/page.mdx — the ai/onboarding/ entry now documents the concierge agent (buildOnboardingConciergeAgent) alongside source analysis, and names the apps/web /api/onboarding/chat route
  • business docs: no business docs impact — this stub is server-side + route handler only; no persona gains a reachable capability until the wizard UI (stub 6) and first-run gating (stub 7) land, so feature-role-matrix / service-journey / platform-overview still describe the product accurately
  • release notes: none — internal building block. No end-user changelog (nothing users can reach yet) and no investor update (no shippable outcome to announce); the user-facing onboarding wizard and its announcement land with stubs 6–7
  • deploy: verified post-merge via poll-deploy.sh (web + help) — result reported at close-out; no investor email is gated on it (audience cut = none)
  • sent: none — internal change, no investor email this run

Review summary

  • CI Claude Code Review (diff vs CONVENTIONS.md) passed with zero review comments; no findings to triage. Manual diff scan clean — no stray debug, TODOs, or dead code.
  • Draft-not-commit design (tools auto-execute, writing pending/ai_drafted draft items) is the approved spec decision, not an oversight — the human review/commit gate is stubs 6 + 3.

Acceptance check (vs spec)

  • Conversation progressively fills the persisted blueprint — draft_section (merge-by-key) + analyse_source write via onboardingBlueprintService; items carry confidence + ai_drafted.
  • URL / description triggers source analysis; unanalysable source returns an explicit reason and the agent falls back to interviewing — analyse_source delegates to analyseSource.
  • Chat route streams and is tenant-scoped; unauthenticated / no-tenant requests rejected; tools bound to the caller's tenant context.
  • Agent resumes mid-conversation — prompt reads the blueprint first; route replays prior messages.
  • All seven sections covered → mark_blueprint_complete advances draft → in_review, guarded against premature / repeat completion.
  • /api/onboarding/ route-policy entry added (gated to admin/vendor) under deny-by-default routing.