Skip to content

think: align generics with Agent/AIChatAgent + multi-session RFC#1350

Merged
threepointone merged 3 commits intomainfrom
think-generics-state-props
Apr 21, 2026
Merged

think: align generics with Agent/AIChatAgent + multi-session RFC#1350
threepointone merged 3 commits intomainfrom
think-generics-state-props

Conversation

@threepointone
Copy link
Copy Markdown
Contributor

@threepointone threepointone commented Apr 21, 2026

Two related changes to @cloudflare/think in one branch.

1. Align Think generics with Agent / AIChatAgent

Think<Env, Config> becomes Think<Env, State, Props> extending Agent<Env, State, Props>, so subclasses get properly typed this.state, this.setState(), initialState, and this.ctx.props — the same way AIChatAgent does.

The old Config class generic was occupying the slot where Agent / AIChatAgent put State, and only ever typed a single row in the internal assistant_config k/v table. It's replaced with method-level generics on configure<T>() / getConfig<T>() so the config shape lives at the call site instead of consuming a class generic.

Migration:

// Before
export class MyAgent extends Think<Env, MyConfig> {
  getModel() {
    const tier = this.getConfig()?.modelTier ?? "fast";
  }
}

// After
export class MyAgent extends Think<Env> {
  getModel() {
    const tier = this.getConfig<MyConfig>()?.modelTier ?? "fast";
  }
}

Tests, the assistant example, docs, and the cloudflare-docs think.mdx page updated to match. Breaking change captured in a changeset.

2. RFC: Think multi-session via composition (design/rfc-think-multi-session.md)

Proposes how to do multi-session in Think before we ship 1.0, while we still have room for breaking changes:

  • One Think DO = one conversation (already how Think is built).
  • New Chats parent Agent for the session index + shared state; one directory DO per user/tenant, one Think DO per conversation.
  • New generic RemoteContextProvider / RemoteSearchProvider in agents/experimental/memory/session/providers so a Session on one DO can read/write a context block on another DO via RPC.
  • New Think#parentAgent<P>() helper.
  • New useChats() React hook and examples/chats reference.
  • Cleanup: drop the unused _sessionId() stub and session_id column from assistant_config.

Supersedes the unimplemented SessionManager-inside-Think plan from design/think-sessions.md. SessionManager stays available as an advanced primitive in agents/experimental but Think itself will not use it.

Rationale: DOs are single-threaded, so hosting many Sessions inside one DO would serialize inference across a user's chats. Per-chat DOs get true parallelism and scale horizontally; the rest is composition.

Includes an explicit Follow-ups section for everything intentionally left out of v1 (forks, indexed cross-chat search, LLM titles, GC/export, multi-tenant-per-directory, shared workspace across chats, the AgentContextProviderSqliteContextProvider rename, etc.) so none of it is forgotten.

Status: proposed. Looking for feedback on the shape before any implementation commits.

Test plan

  • npm run check — all 74 projects typecheck, oxfmt/oxlint/sherif/exports clean
  • @cloudflare/think tests: 249/249 passing
  • examples/assistant tsconfig typechecks
  • @cloudflare/ai-chat programmatic-turns.test.ts — flaked once in parallel nx run-many test on my machine; passes 3/3 when run in isolation. Unrelated package to my changes; CI will give the final word.

Made with Cursor


Open in Devin Review

Change `Think<Env, Config>` to `Think<Env, State, Props>` so it threads State
and Props through to `Agent<Env, State, Props>`. Subclasses now get properly
typed `this.state`, `setState()`, `initialState`, and `this.ctx.props` like
they do with `Agent` / `AIChatAgent`.

The `Config` class generic was in the slot where `Agent`/`AIChatAgent` put
`State`, and only ever typed a single key in the internal `assistant_config`
k/v table. Replace it with method-level generics on `configure<T>` /
`getConfig<T>()` so the type lives at the call site instead of occupying a
class generic slot.

Update tests, the assistant example, and all docs (README, docs/think,
design/think, cloudflare-docs think.mdx) to the new signature. Breaking
change is captured in a changeset.

Made-with: Cursor
Propose making multi-session support in Think a composition pattern
rather than an internal feature. Core choices:

- Ship a `Chats` parent Agent for the session index + shared state;
  one directory DO per user/tenant, one Think DO per conversation.
- Ship generic `RemoteContextProvider` / `RemoteSearchProvider` so a
  Session on one DO can read/write a context block on another DO via
  RPC.
- Add `Think#parentAgent<P>()` as a thin helper to obtain a typed
  stub of the immediate facet parent.
- Ship a `useChats()` React hook and an `examples/chats` reference.
- Cleanup: drop the unused `_sessionId()` stub and `session_id`
  column from `assistant_config`.

Supersedes the unimplemented `SessionManager`-inside-Think plan from
think-sessions.md. `SessionManager` stays available as an advanced
primitive in agents/experimental but Think itself doesn't use it.

Rationale: Durable Objects are single-threaded, so hosting many
Sessions inside one DO serializes inference across a user's chats.
Per-chat DOs get true parallelism and scale horizontally; the rest
is composition.

Status: proposed. Includes explicit follow-ups list for everything
intentionally left out of v1 (forks, indexed cross-chat search,
LLM titles, GC/export, multi-tenant-per-directory, etc.).

Made-with: Cursor
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 21, 2026

🦋 Changeset detected

Latest commit: 4c6e75a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cloudflare/think Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Formatting-only: realigned a markdown table in docs/think/index.md
and converted *italic* to _italic_ in the multi-session RFC. No
content changes.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 21, 2026

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@1350

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@1350

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@1350

hono-agents

npm i https://pkg.pr.new/hono-agents@1350

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@1350

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@1350

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@1350

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@1350

commit: 4c6e75a

@threepointone threepointone merged commit 3a1140f into main Apr 21, 2026
2 checks passed
@threepointone threepointone deleted the think-generics-state-props branch April 21, 2026 13:19
@github-actions github-actions Bot mentioned this pull request Apr 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant