Skip to content

AI chat architecture

newsence chat runs in the standalone workers/think-worker Cloudflare Worker. ThinkChatAgentV2 owns the live conversation, Think recovery state, native Workspace scratch files, tool loop, and Podcast Workflow integration. The app Worker owns authentication and product transactions; Core owns canonical resource retrieval and Cloudflare AI Search.

flowchart LR
    UI["Web chat UI\nuseAgentChat"]
    Think["ThinkChatAgentV2\nDO SQLite + Think"]
    Workspace["Native Workspace\nsession-local files in DO SQLite"]
    Execute["execute\nWorker isolate + Code Mode"]
    Browser["Browser Run\nChromium / CDP"]
    Domain["App DOMAIN binding\nauth + product authority"]
    Autumn["Autumn\nsubscriptions + credits"]
    Core["Core binding\nresources + AI Search"]
    Gateway["AI Gateway\nrouting + telemetry"]
    Model["AI providers"]
    Workflow["Podcast Workflow"]

    UI <--> Think
    Think <--> Workspace
    Think --> Execute
    Execute <--> Workspace
    Execute <--> Browser
    Think <--> Domain
    Think --> Autumn
    Domain --> Autumn
    Domain <--> Core
    Think --> Gateway
    Gateway <--> Model
    Think <--> Workflow
  1. web-tanstack/src/components/chat/ChatPanel.tsx opens the authenticated Think agent route and submits ordinary AI SDK UI messages. Optional typed context refs are persisted in the user message metadata.
  2. The app proxy admits the session and forwards to ThinkChatAgentV2. Postgres stores the session catalog, reconnect allocation, and deletion fence; Think Session/DO SQLite stores the transcript and resumable runtime state.
  3. beforeTurn() reads AI feature flags and credit admission directly from Autumn, then resolves the model, product workspace, and user-message context. Read-only product retrieval and the plan-allowed native actions are exposed directly to Think.
  4. The knowledge tool calls one app-owned Domain RPC. Search uses Core AI Search, read uses live document/resource authorization, and workspace listing returns flattened document/resource refs from direct workspace memberships. Each read is continuation-based and capped at 16 KiB.
  5. Native Workspace stores session-local files in DO SQLite. read supports text, images, and PDFs; other scratch operations use virtual bash or execute with state.*. Duplicate top-level file tools are excluded. Bash is rooted at / with networking disabled. execute runs JavaScript in a Worker isolate; scratch is never product truth.
  6. When the user has the web-search entitlement, execute also exposes cdp.* through the Browser Run binding. The product prompt restricts browser use to public, read-only access. Explicit product actions publish documents and media.
  7. Think persists native tool/action parts. Podcast Workflow events upsert terminal podcast data into the transcript without replacing the native tool call/result pair.
  8. The turn starts only after Think’s direct Autumn credit check. Text models use Autumn’s official AI SDK middleware to report provider token usage after each completed generation. Image, speech, and raw-binding calls check for a positive balance before dispatch and report measured tokens directly afterward. Gateway records remain operational telemetry only.
Tool Responsibility
knowledge Public-corpus search, authorized source read, current-workspace source listing
ask_user Pause for one to three material user decisions and resume from typed client output
read Read session-local text and provide images/PDFs to multimodal models
bash Virtual Bash over Workspace files, rooted at /, with networking disabled
execute Worker-isolated JavaScript with state.* filesystem operations and entitlement-gated cdp.* browser operations
create-document Generate Markdown and persist an app-owned document
edit-document Edit an authorized document with app-side snapshot semantics
generate-image Generate, meter, and persist an image resource
create-podcast Start the durable workspace audio workflow

Image generation is entitlement-gated, and document and podcast creation are exposed only for workspace-scoped chats. Think and the model decide among currently active tools from their descriptions and schemas; the system prompt does not encode a fixed routing sequence.

The old /corpus virtual filesystem no longer exists. Product resources, documents, and workspaces are typed database objects, not paths. Message metadata already contains attachment refs and the runtime already carries the current workspace scope, so no context-discovery round trip is required.

Native Workspace does not mirror or mount Postgres product data. Every product read rechecks current authority. Code Mode’s direct outbound networking is disabled; public web access goes through its entitlement-gated browser connector.

The application does not configure a Container or Sandbox binding. bash is virtual Bash, and execute uses a Worker isolate rather than a Linux container. The browser connector uses Chromium/CDP; Kitesurf is not enabled by the current session options. There are no separately registered exec or browser_* tools.

Code Mode returns nested connector operations in execute.output.calls after each execution pass. These are native execution-log entries, not separate chat tool calls. The current ChatPanel displays generic tool markers without expanding those entries or streaming individual connector operations.

Think Actions provide the local action ledger and native persisted result parts. App Domain methods revalidate product ownership; Postgres mutations use transactions and constraints, while the app owns R2 write and cleanup lifecycle. Long-running Podcast work remains a Workflow with a stable podcast/workflow identity. Manual Autumn token events carry stable idempotency keys. The official text middleware is deliberately best-effort after provider completion; it logs a tracking failure but does not discard the generated result or persist a separate application billing outbox.

File Responsibility
components/chat/ChatPanel.tsx Session allocation, Think connection, send/retry, state/cache synchronization, and page/embedded shell
components/chat/ChatConversation.tsx Message tree, empty state, retry and streaming affordances
components/chat/ChatMessageContent.tsx Ordered text, reasoning, native tool/action progress and results, and Podcast data parts
components/chat/PromptComposer.tsx Input, model, typed context, audio shortcut, submit/stop
  • web-tanstack/autumn.config.ts defines subscriptions, recurring monetary grants, reset cadence, product flags, and numeric plan capacities. Autumn is the subscription and entitlement authority; Stripe remains the payment processor behind it.
  • workers/think-worker/src/ai/autumn-billing.ts reads the authoritative Autumn customer, checks AI credits and product flags, and tracks provider usage. Web server modules read the same customer’s plan capacities when enforcing transactional product limits; PostgreSQL owns actual resource counts, not a parallel billing ledger.
  • workers/think-worker/src/ai/model.ts wraps text models with Autumn’s official AI SDK middleware. Autumn resolves provider/model token pricing and records usage after a completed generate or stream.
  • Image, podcast-script, TTS, and the raw Workers AI title path use a positive balance check followed by trackTokens. Tracking failures are observable but intentionally do not replace a provider result with an error.
  • workers/think-worker/src/ai/model.ts creates trusted Gateway correlation metadata. product-ai logs omit prompt/response payloads and remain operational telemetry only.

See Prompt construction and AI usage for the prompt, admission, and observability contracts.