# Understanding OnboardingChatAgent and SamChatAgent in OpenSEO: Architecture and Purpose

> Discover the roles of OnboardingChatAgent and SamChatAgent in OpenSEO. Understand how these agents provide guided SEO previews and power advanced in-app assistance.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: architecture
- Published: 2026-09-02

---

**The OnboardingChatAgent provides a free, guided SEO preview for new users with limited tools and strict billing controls, while the SamChatAgent powers the full-featured in-app assistant with multi-step research capabilities and project-wide shared memory.**

OpenSEO implements two distinct conversational agents built on Cloudflare’s Think AI framework to handle different stages of the user journey. Both agents operate as Durable Objects but serve fundamentally different architectural roles—one as a lightweight entry point for prospects and the other as a production-grade assistant for active projects.

## OnboardingChatAgent: The SEO Preview Experience

The **OnboardingChatAgent** serves as the entry point for new users, providing a free, guided introduction to SEO concepts and OpenSEO’s capabilities without requiring a paid subscription.

### Durable Object Architecture and State Management

Implemented in [`src/server/features/onboarding/OnboardingChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/onboarding/OnboardingChatAgent.ts), this agent persists chat history using SQLite within a Cloudflare Durable Object. Each project receives its own isolated storage instance, ensuring conversation continuity across worker restarts while maintaining strict data separation.

### Controlled Interaction Design

The agent enforces cost control through several tightly coupled mechanisms:

- **Strict system prompt**: Constructed via `buildSystemPrompt()`, which references [`src/server/features/onboarding/openseo-fact-sheet.md`](https://github.com/every-app/open-seo/blob/main/src/server/features/onboarding/openseo-fact-sheet.md) to ensure responses remain factual and limited to public product information
- **Limited toolset**: Uses `buildOnboardingTools()` providing only essential SEO analysis capabilities
- **Billing gates**: Enforces `FREE_ONBOARDING_QUESTION_LIMIT` and checks `checkUsageCreditsDepleted()` before processing queries

Responses are deliberately concise, markdown-formatted, and avoid exposing internal product details beyond the fact sheet.

### Starting an Onboarding Session

Clients initialize the agent using the project ID as the Durable Object identifier:

```typescript
import { useAgent } from "agents/chat";

// The project ID is used as the Durable Object name
const onboarding = useAgent({ name: projectId });
await onboarding.sendMessage({ 
  role: "user", 
  parts: [{ type: "text", text: "How does SEO work?" }] 
});

```

## SamChatAgent: The Production SEO Assistant

The **SamChatAgent** powers the full-featured in-app assistant available to subscribed users, handling complex multi-step research workflows and project-wide collaboration.

### Session Context and Memory Architecture

Located in [`src/server/features/sam/SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/SamChatAgent.ts), this agent loads comprehensive session context through `loadSamContext()`, which retrieves project data, user permissions, and conversation history. It constructs two specialized context blocks:

- **Identity block**: Generated by `buildSoulPrompt()` to establish the agent's persona
- **Project-memory block**: Rendered via `renderProjectContext()` to inject shared project data into every conversation

### Advanced Tooling and Integration

Unlike the onboarding variant, SamChatAgent assembles a rich toolset via `buildSamMcpTools()`, enabling access to SEO data sources like `get_domain_overview` and `get_serp_results`. The agent operates through OpenRouter using `buildChatAgentModel()` from [`src/server/lib/openrouter.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/openrouter.ts).

### Per-Turn Billing and Credit Management

Each interaction triggers `trackUsageCreditSpend()` to meter usage against the user's credit balance, with `checkUsageCreditsDepleted()` enforcing hard stops when credits expire.

### Creating a Sam Session

Clients use the session row ID created on the server to establish connections:

```typescript
import { useAgent } from "agents/chat";

// `sessionId` is the SAM session row ID created on the server
const sam = useAgent({ name: sessionId });
await sam.sendMessage({ 
  role: "user", 
  parts: [{ type: "text", text: "Analyze my homepage." }] 
});

```

## Shared Infrastructure and Common Patterns

Both agents inherit from the **Think base class**, which handles conversational loops, streaming responses, and persistence mechanics. They share several critical components:

- **Durable Object storage** for state continuity across worker restarts
- **Credit-metering utilities** from [`src/server/billing/subscription.ts`](https://github.com/every-app/open-seo/blob/main/src/server/billing/subscription.ts) (`checkUsageCreditsDepleted`, `trackUsageCreditSpend`)
- **Project-scoped memory** exposed via the `"project_context"` block, ensuring all sessions access consistent shared data through [`ProjectRepository.ts`](https://github.com/every-app/open-seo/blob/main/ProjectRepository.ts)

## Summary

- **OnboardingChatAgent** provides a cost-controlled, free-tier experience using limited tools and strict response guidelines in [`src/server/features/onboarding/OnboardingChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/onboarding/OnboardingChatAgent.ts)
- **SamChatAgent** delivers full SEO capabilities with project memory, MCP tools, and multi-step research in [`src/server/features/sam/SamChatAgent.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/sam/SamChatAgent.ts)
- Both leverage Cloudflare Durable Objects and SQLite for persistence
- Shared billing infrastructure enforces credit limits consistently across both agents
- Client-side integration uses the `useAgent` hook from `"agents/chat"` with distinct initialization patterns for each agent type

## Frequently Asked Questions

### What is the main difference between OnboardingChatAgent and SamChatAgent in OpenSEO?

The OnboardingChatAgent provides a restricted, free preview experience with limited tools and fact-sheet-based responses, while the SamChatAgent offers unrestricted access to the full MCP toolset and project memory for paid users. The onboarding version caps interactions at `FREE_ONBOARDING_QUESTION_LIMIT`, whereas Sam uses per-turn metering via `trackUsageCreditSpend()`.

### How does billing work for these chat agents?

Both agents use `checkUsageCreditsDepleted()` to verify available credits before responding. The OnboardingChatAgent enforces a `FREE_ONBOARDING_QUESTION_LIMIT` for free-tier users, while the SamChatAgent calls `trackUsageCreditSpend()` after each turn to meter usage against paid credits stored in [`src/server/billing/subscription.ts`](https://github.com/every-app/open-seo/blob/main/src/server/billing/subscription.ts).

### Where is the conversation history stored for these agents?

Both agents persist chat history using SQLite within Cloudflare Durable Objects. The OnboardingChatAgent uses the project ID as its Durable Object name, while the SamChatAgent uses a unique session ID. This ensures state continuity even when workers restart or scale.

### Can the OnboardingChatAgent access the same SEO tools as SamChatAgent?

No. The OnboardingChatAgent uses `buildOnboardingTools()` which provides only basic capabilities, whereas SamChatAgent uses `buildSamMcpTools()` to access comprehensive SEO data sources like `get_domain_overview` and `get_serp_results`. This architectural separation prevents free-tier users from consuming expensive API resources.