Skip to content

Default Workspace, Knowledge Base & Agent

This document is the single source of truth for how every new user gets a default workspace, a default knowledge base, and a default agent, how those defaults are represented in the codebase today (MVP), and what the future multi-KB / multi-agent model will look like.


#RuleScope
1Every user account is provisioned with exactly one default workspace ("My Workspace", id ws-1) at account creation.MVP
2That default workspace contains exactly one default knowledge base ("My Knowledge Base", id kb-default-1).MVP
3That default workspace also contains exactly one default agent ("My Agent", id agent-default-1).MVP
4Every channel connection added during Get Started Step 2 is automatically linked to the default KB by setting knowledgeBaseId = "kb-default-1" on the connection.MVP
5Step 3 (Train AI) configures that same default KB. The user never selects a KB during onboarding — it is implicit.MVP
6For agent-managed channel families (FB Messenger, Web Chat, WhatsApp, SMS), the workspace’s default agent is the default destination for new channel assignments. Changing the default agent affects only future assignments; existing channels stay on their current agent.MVP
7After onboarding, users will be able to create additional KBs within a workspace and reassign individual channel connections to any KB in the same workspace.Future
8Every workspace must have at least one knowledge base and one agent. When a user adds or duplicates a workspace, the platform automatically creates a blank knowledge base and a default agent connected to that workspace.MVP
9If a workspace has only one KB, that KB cannot be deleted. The delete action (e.g. KB card overflow menu or dedicated delete control) must be disabled or hidden when the workspace’s KB count is 1. This preserves the invariant that every workspace has at least one KB.MVP
10Incomplete KB and channel assignment: When a channel is assigned to a workspace (via Connection settings: user selects a KB that belongs to that workspace), if that knowledge base is incomplete (e.g. status === "incomplete"), the platform must show a sonner (toast) warning that the KB is incomplete and must be configured for AI to handle the channel. There is no need to show a toast for “workspace has no KBs” because every workspace always has at least one KB (see rule 8).MVP

2.1 Constants (single source of truth for ids)

Section titled “2.1 Constants (single source of truth for ids)”

All default ids live in one place so they can be imported without magic strings:

File: src/constants/defaults.ts

/** Id of the default workspace provisioned for every new user. */
export const DEFAULT_WORKSPACE_ID = "ws-1";
/** Id of the default knowledge base inside the default workspace. */
export const DEFAULT_KB_ID = "kb-default-1";
/** Display name of the default knowledge base. */
export const DEFAULT_KB_NAME = "My Knowledge Base";

DEFAULT_KB_NAME already exists in src/types/kb-draft.ts. Move or re-export from src/constants/defaults.ts so both the onboarding store and the KB editor share the same value.

File: src/app/account/workspaces/_data/seed.ts

The existing SEED_WORKSPACES entry for ws-1 must be extended with an explicit defaultKbId field so any code that needs the default KB id can derive it from the workspace record:

export const SEED_WORKSPACES: Workspace[] = [
{
id: DEFAULT_WORKSPACE_ID, // "ws-1"
name: DEFAULT_WORKSPACE_NAME,
defaultKbId: DEFAULT_KB_ID, // NEW — "kb-default-1"
defaultAgentId: DEFAULT_AGENT_ID, // NEW — "agent-default-1"
groupId: "default",
ownerId: "user-current",
description: "...",
numberOfKnowledgeBases: 1,
numberOfUsers: 1,
connectedApps: [],
appsActivated: false,
},
];

Add defaultKbId?: string and defaultAgentId?: string to the Workspace type in src/types/workspaces.ts.

File: src/app/account/workspaces/_data/seed.ts (or a co-located kb-seed.ts)

import type { KnowledgeBase } from "@/types/knowledge-bases";
export const SEED_KNOWLEDGE_BASES: KnowledgeBase[] = [
{
id: DEFAULT_KB_ID, // "kb-default-1"
name: DEFAULT_KB_NAME, // "My Knowledge Base"
workspaceId: DEFAULT_WORKSPACE_ID, // "ws-1"
status: "incomplete",
linkage: "independent",
},
];
Section titled “2.4 add-connection mutation — auto-link to default KB”

File: src/server/setup-status-store.ts

When a connection is created via the add-connection mutation (which is the only path used during Get Started Step 2), knowledgeBaseId must be set to DEFAULT_KB_ID:

import { DEFAULT_KB_ID } from "@/constants/defaults";
case "add-connection": {
const id = `${mutation.channelType}-${mutation.platform.toLowerCase().replace(/\s+/g, "-")}-${Date.now()}`;
const next: ChannelConnection = {
id,
channelType: mutation.channelType,
platform: mutation.platform,
label: mutation.label,
active: true,
commentType: "not-selected",
listening: false,
knowledgeBaseId: DEFAULT_KB_ID, // AUTO-LINKED to default KB
...(mutation.addedVia !== undefined && { addedVia: mutation.addedVia }),
};
status.connections = [...status.connections, next];
status.dismissedForSession = false;
break;
}

No changes to the SetupStatusMutation type or the add-connection call-sites are needed — the store sets the value internally.

File: src/server/user-store.ts

The default user payload includes a default agent tied to the default KB and the default workspace:

{
id: DEFAULT_AGENT_ID, // "agent-default-1"
name: DEFAULT_AGENT_NAME, // "My Agent"
workspaceId: DEFAULT_WORKSPACE_ID,
knowledgeBaseId: DEFAULT_KB_ID,
status: "draft",
channelIds: [],
}

Existing persisted workspaces that predate defaultAgentId are backfilled on load by resolving the current default agent for each workspace. New workspaces persist defaultAgentId directly on creation.


Account creation
└─ Default workspace provisioned (id: ws-1)
└─ Default KB provisioned (id: kb-default-1, status: incomplete)
└─ Default agent provisioned (id: agent-default-1, kb: kb-default-1)
Get Started Step 1 — user selects channel types
Get Started Step 2 — user connects channels
└─ add-connection mutation
└─ ChannelConnection.knowledgeBaseId = "kb-default-1" ← auto-set by store
Get Started Step 3 — user trains AI
└─ User fills in brand personality fields for kb-default-1 (draft in Step 3 UI)
└─ User clicks "Complete" → draft is persisted to the default KB in the app's KB store
└─ Default KB is updated: name = draft.name, status = "complete" (if validateKbDraft(draft).isComplete) or "incomplete"
└─ SetupStatus.kbPublished = true → onboarding complete
└─ KB card (workspace open, knowledge bases list) reads from same store → shows updated name and status

3.1 Step 3 completion must update the default KB (MVP)

Section titled “3.1 Step 3 completion must update the default KB (MVP)”

When the user completes Get Started Step 3 (clicks Complete), the platform must persist the Step 3 draft into the default knowledge base so that:

  • The default KB in the app’s KB store (e.g. WorkspacesContext.knowledgeBases, keyed by DEFAULT_KB_ID) is updated with at least:
    • name: from the draft’s name field (user may have renamed “My Knowledge Base”).
    • status: "complete" if validateKbDraft(draft).isComplete === true, otherwise "incomplete".
  • Any UI that displays the default KB (workspace open page KB card, knowledge bases list, Channels connection settings) reads from that same store, so the user sees the same name and status they set in Step 3.

Implementation contract:

  • The onboarding overlay must have access to the Step 3 draft when the user clicks Complete (e.g. draft state lifted to the overlay or provided via callback).
  • The overlay calls onComplete(draft) (or equivalent) so the shell (or provider) can update the default KB before or after calling postMutation({ type: "complete-onboarding" }).
  • The app’s KB store must support updating an existing KB by id (e.g. updateKnowledgeBase(id, { name, status }) in the workspaces/knowledge-bases context).
  • The workspace open page (and any list that shows the default KB) must render KB cards from the context KB list (e.g. getKnowledgeBasesForWorkspace(workspaceId)) rather than a hardcoded single card, so the updated default KB is displayed.
  • Single WorkspacesProvider: Get Started, Account, and Profile routes must share one WorkspacesProvider instance (e.g. at root/Providers). If each route layout mounts its own provider, Step 3 updates apply only to the Get Started tree; after navigation to Account, a fresh provider re-initializes from seed and the KB card does not reflect the update.

Storing the full draft content (brand personality, objectives, etc.) for later editing is optional for MVP; at minimum, name and status must be persisted so the card reflects Step 3.


4. Future: multiple KBs and channel reassignment

Section titled “4. Future: multiple KBs and channel reassignment”

The following is not in scope for MVP and must not be built until explicitly scheduled.

CapabilityDescription
Create additional KBsUser can create more KBs inside a workspace (no limit per data model).
Reassign a channel connection to a different KBUser picks a KB from a workspace-scoped list; ChannelConnection.knowledgeBaseId is updated.
KB selector in channel settingsUI on the Channels page (or KB detail) to change which KB a connection uses.
Multiple KBs in Get StartedNot planned; onboarding always targets the default KB.

When the reassignment feature is built:

  • The add-connection mutation should accept an optional knowledgeBaseId override; if omitted it still defaults to DEFAULT_KB_ID.
  • The Channels page will need a KB-picker control per connection row.
  • The KB used-by section (currently display-only) will become an interactive reassignment surface.

The onboarding target resolver ensures Get Started always has a valid destination for connections and KB training, even if the original defaults were modified or deleted.

SetupStatus gains an optional onboardingTarget field:

interface OnboardingTarget {
groupId: string;
workspaceId: string;
knowledgeBaseId: string;
agentId: string;
}
interface SetupStatus {
// ... existing fields ...
onboardingTarget?: OnboardingTarget;
persistentlyHidden?: boolean;
}

On overlay open (or before any Step 2/3 mutation), the resolver runs:

  1. Check existing target: if onboardingTarget is set and all referenced entities still exist in the user’s data, use them.
  2. Recreate missing entities: if any entity is missing:
    • Create group "Get Started" if no group with the stored groupId exists.
    • Create workspace "Get Started Workspace" in that group if the workspace is missing.
    • Create a blank KB in that workspace if the KB is missing.
    • Create a default agent in that workspace linked to the KB if the agent is missing.
  3. Persist the resolved target: write the (possibly new) ids back to onboardingTarget so subsequent operations use stable references.
  • The resolver uses persistent ids from onboardingTarget, not display names.
  • Display names ("Get Started", "Get Started Workspace") are used only when creating new entities.
  • Users may rename the onboarding workspace or KB without breaking the resolver.

When the user clicks Complete on Step 3, the draft is persisted to onboardingTarget.knowledgeBaseId (not the legacy DEFAULT_KB_ID). The shell calls updateKnowledgeBase(onboardingTarget.knowledgeBaseId, { name, status }).

  • Resolver logic: src/lib/onboarding-target-resolver.ts
  • Called from: OnboardingOverlay (on mount and before step mutations)
  • Server-side: src/app/api/setup-status/route.ts — new mutation type resolve-onboarding-target

SetupStatus.persistentlyHidden (boolean, default false) controls whether the Get Started overlay auto-opens and the nav item is visible.

MutationEffect
{ type: "set-persistent-hide", hidden: true }Sets persistentlyHidden = true. Overlay stops auto-opening; nav item hidden.
{ type: "set-persistent-hide", hidden: false }Sets persistentlyHidden = false. Overlay auto-opens again; nav item restored.

Only Chatti Live can set hidden: false (restore path).