Skip to content

Threads 1: Define useThread package contracts - #234

Merged
FranciscoMoretti merged 3 commits into
mainfrom
codex/threads-v2-01-contracts
Jul 23, 2026
Merged

Threads 1: Define useThread package contracts#234
FranciscoMoretti merged 3 commits into
mainfrom
codex/threads-v2-01-contracts

Conversation

@FranciscoMoretti

@FranciscoMoretti FranciscoMoretti commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds the package manifest and public type contracts.
  • Defines tree snapshots, run handles, concurrency, and tree-aware send options.
  • Keeps the active-path surface compatible with AI SDK useChat.

Behavior

Introduces types and package structure only; no orchestration yet.

Verification

  • bun test:types at the stack tip.

Review focus

Are the public contracts minimal and sufficient for later implementation commits?


Summary by cubic

Introduces @chatjs/thread, a type-only package that defines public contracts for a threaded chat engine aligned with ai useChat. No runtime code.

  • New Features

    • Tree snapshots: MessageTreeSnapshot (cursorId, nodes[], version: 1) and ThreadStateSnapshot with maps, rootIds, messages, status, runs, activeRuns, and error.
    • Runs and handles: ThreadRun (id, status, error) and ThreadRunHandle (id, finished, getSnapshot(), stop()).
    • Sending: TreeSendOptions with tree.from and tree.follow; ThreadStartRunOptions with message and request.
    • Concurrency and options: ThreadConcurrency limits; ThreadChatOptions mirrors useChat plus concurrency and either initialTree or messages.
  • Refactors

    • Separated stable run IDs from message IDs; follow selects the user immediately and the assistant on first stream write; no placeholder assistant node.
    • Removed event types to keep the public surface focused on tree, runs, send, and options.

Written for commit e9ae97f. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added the @chatjs/thread npm package for threaded chat experiences.
    • Exposed an expanded public, type-only API for thread runs, run handles, message trees, snapshots, concurrency controls, and chat/thread options.
    • Added strongly typed inputs for sending messages and starting thread runs, including optional tree relationships.
  • Documentation

    • Updated useThread behavioral contract covering cursor following, identity semantics, and how tree context interacts with the request lifecycle and concurrency.
  • Chores

    • Added TypeScript build setup for publishing generated type declarations.
    • Enabled Biome formatting and linting with recommended rules.

Stack

  1. Threads 0: Define the useThread target architecture #233
  2. Threads 22: Adopt AI SDK response identity lifecycle #258
  3. Threads 1: Define useThread package contracts #234 👈 current
  4. Threads 2: Add the canonical message tree #235
  5. Threads 3: Adapt isolated AI SDK runs #236
  6. Threads 4: Orchestrate concurrent tree runs #237
  7. Threads 5: Prove AI SDK behavioral parity #238
  8. Threads 6: Expose the useChat-compatible useThread hook #239
  9. Threads 10: Store ordered thread snapshots in ChatJS #240
  10. Threads 11: Mount useThread in ChatJS #241
  11. Threads 12: Add branch navigation and retry #242
  12. Threads 13: Isolate branch stream lifecycles #243
  13. Threads 14: Stream follow-up parallel responses #244
  14. Threads 16: Gate first-message parallel runs #245
  15. Threads 17: Stop newly provisioned thread runs #246
  16. Threads 18: Show parallel response lifecycle states #247
  17. Threads 19: Publish installable thread sources #248
  18. Threads 20: Add the thread playground model #249
  19. Threads 21: Add the interactive thread playground #250
  20. Threads 22: Publish the threads product page #251
  21. Threads 23: Add the value-first package guide #252
  22. Threads 24: Document ChatJS threaded behavior #253
  23. Threads 25: Prepare the thread package release #254

@cursor

cursor Bot commented Jul 16, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @FranciscoMoretti, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
chat-js-docs Ready Ready Preview, Comment Jul 20, 2026 6:56pm
chat-js-site Ready Ready Preview, Comment Jul 20, 2026 6:56pm
sparka Ready Ready Preview, Comment Jul 20, 2026 6:56pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR establishes the @chatjs/thread package, defines its public thread and message-tree types, re-exports them, configures its toolchain, and documents cursor, run identity, assistant identity, and lifecycle semantics.

Changes

Thread package foundation

Layer / File(s) Summary
Thread public type contracts
packages/thread/src/types.ts, packages/thread/src/index.ts
Defines public run, tree, snapshot, concurrency, request, and chat option types, then re-exports them from the package entry point.
Package entry and build wiring
packages/thread/package.json, packages/thread/biome.jsonc, packages/thread/tsconfig.json, packages/thread/tsconfig.build.json
Adds package metadata, ESM exports, scripts, dependencies, Biome settings, strict TypeScript settings, and declaration-only build output.
Documented cursor and run lifecycle
packages/thread/ARCHITECTURE.md
Documents cursor-following defaults, stable run IDs, server-derived assistant IDs, concurrent ordering, request lifecycle, and concurrency rejection behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • FranciscoMoretti/chat-js issue 255 — concerns the @chatjs/thread public contracts for message-tree nodes, snapshots, and runs.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main change: defining the @chatjs/thread package contracts and types.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/threads-v2-01-contracts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d36f512b52

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/thread/src/index.ts Outdated
Comment thread packages/thread/package.json Outdated
@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR bootstraps the @chatjs/thread package with a types-only public contract for a threaded chat engine. No orchestration logic is included — only the TypeScript surface that later implementation commits will implement against.

  • New type contracts: MessageTreeSnapshot/ThreadStateSnapshot capture tree topology and cursor position; ThreadRun/ThreadRunHandle separate public run state from the caller-facing handle with stop() and getSnapshot(); ThreadChatOptions wraps ChatInit with a discriminated union for initialTree vs messages initial state.
  • Build setup: tsconfig.build.json emits declarations to dist/; package.json exports correctly resolve to ./dist/index.d.ts for type consumers and ./src/index.ts under the bun/development conditions.

Confidence Score: 5/5

Safe to merge — pure type additions with no runtime behaviour

The change is entirely additive TypeScript types with no runtime code paths. The package manifest is well-formed, the discriminated union for initial state is correct, and the export map aligns with resolved feedback from previous review rounds. No logic can regress.

No files require special attention; the minor README.md entry in files and the activeRuns/runs redundancy are the only items worth a follow-up before the first publish.

Important Files Changed

Filename Overview
packages/thread/src/types.ts Defines all public TypeScript contracts for the threaded chat engine; types are well-structured and align with AI SDK conventions
packages/thread/src/index.ts Clean barrel re-export of all public types; ThreadInitialState correctly kept internal
packages/thread/package.json Package manifest correctly points types to ./dist/index.d.ts; README.md listed in files but not present in the package
packages/thread/tsconfig.build.json Build tsconfig correctly enables declaration emit to dist/ with emitDeclarationOnly
packages/thread/tsconfig.json Standard strict TypeScript config with Bundler resolution; matches conventions of the rest of the workspace
packages/thread/biome.jsonc Minimal Biome config enabling formatter and recommended linter rules
packages/thread/ARCHITECTURE.md Architecture doc updated to reflect run/message ID separation and revised assistant-node lifecycle

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
  class MessageTreeNode~TMessage~ {
    +TMessage message
    +string|null parentId
  }
  class MessageTreeSnapshot~TMessage~ {
    +string|null cursorId
    +MessageTreeNode[] nodes
    +1 version
  }
  class ThreadStateSnapshot~TMessage~ {
    +ThreadRun[] activeRuns
    +ThreadRun[] runs
    +Record~string,string[]~ childrenByParentId
    +Record~string,TMessage~ messagesById
    +Record~string,string|null~ parentById
    +string[] rootIds
    +TMessage[] messages
    +Error|undefined error
    +ChatStatus status
    +ChatStatus treeStatus
  }
  class ThreadRun {
    +string id
    +ChatStatus status
    +Error|undefined error
  }
  class ThreadRunHandle {
    +string id
    +Promise~void~ finished
    +getSnapshot() ThreadRun|undefined
    +stop() Promise~void~
  }
  class ThreadConcurrency {
    +number maxActiveRuns
    +number maxActiveRunsPerMessage
  }
  class ThreadChatOptions~TMessage~ {
    +ThreadConcurrency concurrency
    +MessageTreeSnapshot initialTree
    +TMessage[] messages
  }
  MessageTreeSnapshot~TMessage~ <|-- ThreadStateSnapshot~TMessage~
  MessageTreeSnapshot~TMessage~ "1" *-- "many" MessageTreeNode~TMessage~
  ThreadStateSnapshot~TMessage~ --> "many" ThreadRun : activeRuns / runs
  ThreadRunHandle --> ThreadRun : getSnapshot()
  ThreadChatOptions~TMessage~ --> ThreadConcurrency
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
classDiagram
  class MessageTreeNode~TMessage~ {
    +TMessage message
    +string|null parentId
  }
  class MessageTreeSnapshot~TMessage~ {
    +string|null cursorId
    +MessageTreeNode[] nodes
    +1 version
  }
  class ThreadStateSnapshot~TMessage~ {
    +ThreadRun[] activeRuns
    +ThreadRun[] runs
    +Record~string,string[]~ childrenByParentId
    +Record~string,TMessage~ messagesById
    +Record~string,string|null~ parentById
    +string[] rootIds
    +TMessage[] messages
    +Error|undefined error
    +ChatStatus status
    +ChatStatus treeStatus
  }
  class ThreadRun {
    +string id
    +ChatStatus status
    +Error|undefined error
  }
  class ThreadRunHandle {
    +string id
    +Promise~void~ finished
    +getSnapshot() ThreadRun|undefined
    +stop() Promise~void~
  }
  class ThreadConcurrency {
    +number maxActiveRuns
    +number maxActiveRunsPerMessage
  }
  class ThreadChatOptions~TMessage~ {
    +ThreadConcurrency concurrency
    +MessageTreeSnapshot initialTree
    +TMessage[] messages
  }
  MessageTreeSnapshot~TMessage~ <|-- ThreadStateSnapshot~TMessage~
  MessageTreeSnapshot~TMessage~ "1" *-- "many" MessageTreeNode~TMessage~
  ThreadStateSnapshot~TMessage~ --> "many" ThreadRun : activeRuns / runs
  ThreadRunHandle --> ThreadRun : getSnapshot()
  ThreadChatOptions~TMessage~ --> ThreadConcurrency
Loading

Reviews (9): Last reviewed commit: "refactor(thread): separate public run st..." | Re-trigger Greptile

Comment thread packages/thread/src/types.ts Outdated
Comment thread packages/thread/src/types.ts
Comment thread packages/thread/package.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/thread/package.json (1)

43-44: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Include the test directory in formatting and linting.

The test directory is referenced in the test script and tsconfig.json, but it is excluded from the Biome scripts. Adding it ensures consistent code quality across both source and test files.

🛠️ Proposed fix
-		"format": "bunx `@biomejs/biome`@2.4.10 check --write src *.md package.json tsconfig.json tsconfig.build.json biome.jsonc",
-		"lint": "bunx `@biomejs/biome`@2.4.10 check src ARCHITECTURE.md package.json tsconfig.json tsconfig.build.json biome.jsonc",
+		"format": "bunx `@biomejs/biome`@2.4.10 check --write src test *.md package.json tsconfig.json tsconfig.build.json biome.jsonc",
+		"lint": "bunx `@biomejs/biome`@2.4.10 check src test ARCHITECTURE.md package.json tsconfig.json tsconfig.build.json biome.jsonc",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/thread/package.json` around lines 43 - 44, Update the format and
lint scripts in package.json to include the test directory alongside src, so
Biome checks and formats both production and test files consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/thread/package.json`:
- Around line 23-31: Update the package exports and top-level types field in
package.json to reference the generated declaration files under dist rather than
src/index.ts. Keep the existing runtime conditions and default JavaScript export
unchanged, and align the types paths with the declarations emitted by
tsconfig.build.json.

---

Nitpick comments:
In `@packages/thread/package.json`:
- Around line 43-44: Update the format and lint scripts in package.json to
include the test directory alongside src, so Biome checks and formats both
production and test files consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bb575fba-607c-4a5b-a717-38531b4b4ade

📥 Commits

Reviewing files that changed from the base of the PR and between f9844ee and c9ec33d.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • packages/thread/biome.jsonc
  • packages/thread/package.json
  • packages/thread/src/index.ts
  • packages/thread/src/types.ts
  • packages/thread/tsconfig.build.json
  • packages/thread/tsconfig.json

Comment thread packages/thread/package.json Outdated
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