Matt
77928207+mattzcarey@users.noreply.github.com
90d · built 2026-05-28
90-day totals
- Commits
- 34
- Grow
- 9.3
- Maintenance
- 7.0
- Fixes
- 1.9
- Total ETV
- 18.1
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Bug flow over time
Monthly bug flow attributed to this developer. The left bar (red) is bug impact this dev authored that was addressed in the given month — combining bugs others fixed for them and bugs they fixed themselves. The right bar is fixes they personally shipped that month, split between self-fixes (overlap with the red bar) and fixes done for someone else. X-axis is fix-time, not introduction-time — the Navigara API attributes bugs backward to the author at the moment the fix lands.
- Self-fix share
- 35%
- Bugs you introduced
- 5.6
- Bugs you fixed
- 4.5
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
| Repo | Commits | ETV |
|---|---|---|
| agents | 28 | 17.4 |
| workers-sdk | 2 | 0.5 |
| cloudflare-docs | 4 | 0.2 |
Most impactful commits
Top 20 by ETV in the 90-day window.
- 4.1ETVfeat(experimental): Postgres session providers with Hyperdrive support (#1297) * feat(experimental): PlanetScale SessionProvider + async interface * fix(session): address PR #1297 review feedback Responses to @mattzcarey review on PR #1297. Covers all 13 comments: 1. Drop wrapPgClient boilerplate — Postgres providers now accept raw pg.Client directly via new providers/postgres-adapter.ts. The adapter normalises pg.Client-style (`query`) into the internal PostgresConnection shape (`execute`) and rewrites `?` placeholders to `$1, $2, …` so providers keep a driver-agnostic SQL dialect. 2. appendMessage parentId semantics — both PostgresSessionProvider and AgentSessionProvider were using `parentId ?? latestLeaf`, which collapsed undefined (auto-detect) with null (explicit root). Fixed to honour the documented contract: - undefined / omitted → auto-detect - explicit null → root with no parent SessionProvider JSDoc now documents this. New tests cover both cases for both providers. 3. extractText — renamed to extractSearchableText, added JSDoc explaining it feeds text_content for FTS while the full JSON stays in `content`. 4/6/8. Restored `enum` on label params across set_context, load_context, unload_context, search_context — schema-level enforcement instead of free-text description hints so smaller models can't hallucinate invalid labels. 5. set_context metadata shape — switched from flat `title` to nested `metadata: { title?, description? }`. Tool description now explains metadata is optional and useful for longer loadable entries (skills). setSkill() receives description ?? title so behaviour is preserved when only title is passed. 7. Dropped 'e.g. memory' example from search_context description — avoids seeding models with a non-existent block name. 9. Renamed Session.create(storageOrAgent) → Session.create(provider). 10. Async skill restore — _ensureReady() now kicks off restoration as a background _restorePromise; a new _ensureRestored() awaits it. Every async Session public method awaits _ensureRestored() before touching storage or skill state. unloadSkill / getLoadedSkillKeys are now async (internal callers only). Async SessionProviders (Postgres) now correctly rehydrate loaded-skill tracking after DO hibernation instead of silently dropping it. 11. Added JSDoc to _reclaimLoadedSkill explaining it reclaims context-window tokens by collapsing a load_context tool result to a short marker (kept the name per review feedback). 12. Clarified addContext JSDoc: it's a builder/host API, not an LLM tool; the LLM writes via set_context. 13. Added a comment on the Think._cachedMessages in-place patch explaining why it's not a full _syncMessages() call (in-flight streaming messages would be dropped — see commits 3f615a24, 6e76bd49). Example server.ts + docs/sessions.md updated for the new API and fixed the Devin-flagged premature client-caching bug (client is only assigned after connect() resolves). Tests: +4 in postgres-providers.test.ts (parentId null/undefined, raw pg.Client adapter for session/context/search providers), +2 in provider.test.ts (same parentId semantics for AgentSessionProvider). 161/161 session-related tests pass. * chore(session-planetscale): align kumo + ai dep versions with workspace Bump @cloudflare/kumo from ^1.18.0 to ^1.19.0 and ai from ^6.0.159 to ^6.0.168 so the session-planetscale example matches every other package in the monorepo. Makes `npm run check` (sherif) pass without multiple-dependency-versions errors. * fix(session): resolve postgres provider rebase fallout Align the new PlanetScale example with the rebased workspace dependencies and update Think async-session call sites/tests so the branch stays typecheck- and lint-clean on current main. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(session): harden postgres provider follow-ups Tighten the Postgres session provider for shared database usage by scoping message id conflicts to (session_id, id) and validating explicit parent ids against the current session before storing them. This keeps caller-provided message ids safe across sessions and preserves the SQLite provider's fallback-to-root behavior for invalid parents. Make generated keys for keyed context writes deterministic but collision-resistant when the model omits metadata.title. Title-based writes remain stable update keys, while content-derived keys now include a short hash so long shared prefixes and non-Latin content do not silently overwrite unrelated skill or search entries. Clean up the new PlanetScale example and docs for merge readiness: remove committed Cloudflare account/resource IDs, document the required Hyperdrive placeholder, use raw pg.Client in examples, initialize the client/session from onStart instead of request-created promises, update Session docs for the async API, document the Postgres composite message primary key, and add the relevant changeset for the new public providers and async session surface. Tests cover cross-session duplicate message ids, foreign-session parent fallback, and generated key collision cases. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(think): keep session message cache coherent Teach Session to notify internal listeners after message mutations so cache-owning framework code can mirror durable storage changes without widening the public API. Think now registers that hook during startup, treats `messages` as its live cached view, and routes writes through history helpers that sanitize and enforce row-size limits before delegating to Session. This avoids full storage rereads during active streaming turns, while still refreshing at safe boundaries for duplicate appends, branch writes, deletes, clears, and compaction overlays. It also makes direct `this.session.appendMessage()` calls from advanced Think subclasses update the live cache through the same observer path. Add regression coverage for duplicate message IDs, compaction-triggered refreshes, direct Session appends, subclass append helpers, `getMessages()` copy semantics, and host-injected messages. Update the Session docs and PlanetScale example README for async APIs, Postgres-backed search/storage wording, Durable Object persistence semantics, and mark the changeset as a minor bump because the async Session API is breaking for 0.x consumers. Co-authored-by: Cursor <cursoragent@cursor.com> * Render skill blocks and label keyed block kinds Treat empty skill blocks as renderable in ContextBlocks so the LLM can discover loadable skill collections (add !block.isSkill to the skip logic). Include a human-readable kind for keyed/writable blocks in the set_context description ("skill collection, keyed entries", "searchable, keyed entries", or "writable"). Add unit tests and small test providers (EmptySkillProvider, WritableSkillProvider, WritableSearchProvider) to verify empty skill block rendering and that tools().set_context lists keyed block kinds and metadata fields. * Normalize Postgres timestamps and patch cache Normalize created_at values returned from Postgres to ISO strings (handle Date objects and other types) in PostgresSessionProvider and add a unit test for this behavior. In Think, replace an upsert on session update events with a patch-only _patchCachedMessage implementation so updateMessage no longer inserts messages that are missing from the live cache; add a test helper and a test to ensure missing messages are not appended. These changes prevent Date objects from leaking into API fields and stop update events from creating unexpected cached entries. --------- Co-authored-by: Matt <matt@test.com> Co-authored-by: Sunil Pai <spai@cloudflare.com> Co-authored-by: Cursor <cursoragent@cursor.com>github.com-cloudflare-agents · d151e6d6 · 2026-05-19
- 2.1ETVfeat(experimental): Session API with chainable builder (#1166) Core session primitives for the agents package: - Session class with tree-structured messages, compaction overlays, context blocks, FTS5 search - Chainable builder: Session.create(agent).withContext(...).withCachedPrompt() - AgentSessionProvider: SQLite-backed with session_id scoping, content column (Think-compatible) - AgentContextProvider: key-value block storage - ContextProvider interface for custom backends (R2, KV, etc.) - Compaction utilities with head/tail protection - Iterative compaction: newer overlays supersede older ones at same fromId - session-memory example with builder APIgithub.com-cloudflare-agents · 82cd489f · 2026-03-26
- 1.2ETVfix(experimental): session API better compaction helpers (#1210) * fix(experimental): session API edge cases + compaction improvements Edge case fixes: - freezeSystemPrompt: use !== null so empty prompts are persisted - Remove double-prefix in compaction summaries - SearchResult.createdAt now optional (FTS5 can't populate it) - Session.search() return type matches SearchResult - appendMessage validates parentId belongs to current session - Depth guard (10000) in recursive CTEs - createCompactFunction reads previousSummary from history not closure Compaction API improvements: - createCompactFunction returns CompactResult { fromMessageId, toMessageId, summary } instead of UIMessage[] - Session.compact() uses CompactResult directly — no more prefix searching or message diffing - Single COMPACTION_PREFIX constant + isCompactionMessage() helper - onCompaction() builder method registers compaction function - compactAfter(tokenThreshold) builder method for auto-compaction - appendMessage auto-compacts when estimated tokens exceed threshold - Removed needsCompaction(maxMessages) — replaced by token-based approach Status broadcasting: - Session broadcasts cf_agent_session events during compaction (phase, tokenEstimate, tokenThreshold) - Session broadcasts cf_agent_session_error on compaction failure - MessageType.CF_AGENT_SESSION + CF_AGENT_SESSION_ERROR added to enum - MessageType exported from agents package - Auto-compact failure is non-fatal — message still appended Example updates: - session-memory uses onCompaction() + compactAfter() builder API - Streaming chat via @callable({ streaming: true }) + streamText - Client shows token usage badge (% of threshold or raw estimate) - Client auto-refreshes messages after compaction overlay appears - Compaction uses @cf/zai-org/glm-4.7-flash (fast model for summarization) * fix(experimental): filter overlay messages from compaction range During iterative compaction, middleMessages could include compaction overlay messages with virtual IDs (compaction_<uuid>). This caused: 1. Virtual IDs stored as toMessageId, breaking future overlays since applyCompactions can't find virtual IDs in the message list 2. The previous summary appearing twice in the LLM prompt — once as PREVIOUS SUMMARY and again as a conversation turn in middleMessages Fix: filter compaction overlay messages from middleMessages before summarization. Use filtered message IDs for fromMessageId/toMessageId. Return null if no real messages remain after filtering. * fix(experimental): return correct fromMessageId from compact() compact() extends fromMessageId for iterative compactions (using the earliest existing compaction's start), but returned the original CompactResult with the un-extended fromMessageId. The public API now returns the actual persisted fromMessageId. * fix(session-memory): prevent double-click on compact button Set isCompacting immediately on click to disable the button before the server broadcasts the compacting status via WebSocket. Reset on error only — the server broadcast handles the success case. * fix(experimental): async appendMessage wrapper + iterative compaction test 1. TestSessionAgent.appendMessage is now async and awaits the Session call, so auto-compaction promises are not silently dropped in tests. 2. New test exercises iterative compaction where getHistory() returns overlay messages with virtual IDs, verifying that Session.compact() stores real message IDs and extends fromMessageId correctly. * fix(session-memory): reset isCompacting on success path Move setIsCompacting(false) from catch-only to a finally block. Without this, if Session.compact() returns null (e.g. fewer than 4 messages due to a race), no broadcast is sent and the button stays stuck in loading state permanently. * chore: add changeset for session API edge cases * fix(experimental): use nullish check for tokenThreshold A threshold of 0 is falsy in JS, so `if (this._tokenThreshold)` would skip auto-compaction. Use `!= null` to distinguish 'not set' from 'set to 0'. * fix: CI type errors — import UIMessage, fix Badge variant, drop createdAt - Add missing `import type { UIMessage } from 'ai'` in session.test.ts - Replace invalid 'warning' Badge variant with 'destructive' in client.tsx - Remove createdAt from overlay test fixture (not in UIMessage type) * fix(experimental): don't rethrow after broadcasting error, validate toMessageId 1. compact() no longer rethrows after broadcasting cf_agent_session_error. Callers get null instead of a dual signal (error broadcast + exception). 2. Validate toMessageId exists in history before storing compaction. Prevents silent data corruption from custom compaction functions returning non-existent message IDs. * chore: remove changeset (experimental, not needed) * fix(experimental): rewrite compaction prompt to prevent hallucination The summary prompt was structured for coding workflows — it asked for 'file paths, commands run, results obtained' and had a 'Relevant Files' section. When the conversation wasn't about code, the LLM hallucinated file paths and technical artifacts to fill the template. Replaced with a content-agnostic prompt structure (Topic, Key Points, Current State, Open Items) with explicit instruction to only include information that was discussed in the conversation. * fix(experimental): session API edge cases + compaction improvements * fix(tests): update compact test for removed history.length guard The history.length < 4 guard was removed from compact() — the minimum message check is now the compaction function's responsibility. Updated the test to use a compaction function that returns null instead of expecting compact() to short-circuit. * test: add createCompactFunction tests for minimum-messages guard The history.length < 4 guard was removed from Session.compact() — the check now lives in createCompactFunction (protectHead + minTailMessages). Added tests to cover both the rejection and acceptance paths. * fix(experimental): broadcast token estimate on every mutation Added _broadcastTokens() helper that broadcasts cf_agent_session with the current token estimate. Now called from updateMessage, deleteMessages, and clearMessages in addition to appendMessage and compact(). The client always has an up-to-date token count. * refactor(experimental): clean up session broadcast with _emitStatus/_emitError Replace ad-hoc _broadcastSession calls with two focused helpers: - _emitStatus(phase, extra?) — broadcasts phase + token estimate + threshold - _emitError(error) — broadcasts error Removes duplicated broadcast objects throughout compact(). The compacted event now uses tokenEstimate (current) + compacted.tokensBefore instead of redundant tokensBefore/tokensAfter fields. * fix(experimental): scale summary budget to tail token budget The summary budget had a fixed minimum of 2000 tokens, which exceeded the entire context window for small compactAfter thresholds (e.g. 1000). Now the budget is capped at 50% of tailTokenBudget, with a minimum of 100 tokens. For the example config (tailTokenBudget=150), the summary budget is ~75 tokens instead of 2000. * fix(experimental): token budget takes priority over minTailMessages Previously minTailMessages overrode tailTokenBudget — when the token budget was small, the token walk gave up quickly but the fallback forced exactly minTailMessages in the tail regardless. With tailTokenBudget=150, the budget was effectively ignored. Now the tail protects whichever is larger: the token-based cut or minTailMessages. The token budget is respected when it protects more messages than the minimum. * feat(session-memory): stop button, tail budget edge case, README 1. Send button becomes a stop button while streaming. Uses a stopped flag to ignore further chunks/done events from the server. 2. Tail budget edge case: if a single message at the tail exceeds the entire tailTokenBudget, it's still included (at least 1 tail message is always protected). Previously this would leave an empty tail. 3. Full README rewrite covering the complete Session API, compaction configuration, context blocks, WebSocket events, and truncation. * fix(session-memory): set minTailMessages to 1 for small context window Default minTailMessages (4) is too high for a 1000-token window — it forces 4 tail messages regardless of tailTokenBudget. Set to 1 so the token budget is actually respected. Updated README table. * fix(experimental): remove tail budget cap from summary budget The summary replaces the compressed middle — it doesn't compete with the tail for space. Capping at 50% of tailTokenBudget was wrong for small windows (e.g. 75 tokens for a 150-token tail budget). Now uses the same approach as Hermes: 20% of compressed content with a minimum of 100 tokens, no artificial ceiling. * fix(experimental): change default minTailMessages from 4 to 2, format README protectHead defaults to 3, minTailMessages now defaults to 2. 4 tail messages was too aggressive for small context windows. --------- Co-authored-by: Matt <matt@test.com>github.com-cloudflare-agents · 938f30fc · 2026-03-27
- 1.2ETVfeat(experimental): SessionManager with compaction propagation and multichat example (#1242) * feat(experimental): SessionManager with chainable builder and multi-session example Registry of named sessions with lifecycle, branching, compaction, search, and tools. **Chainable API**: `SessionManager.create(agent).withContext(...).withCachedPrompt()` auto-wires per-session namespaced providers via `Session.create().forSession(id)`. **Lifecycle**: create, get, list, delete, rename with metadata tracking. **Branching**: `fork(sessionId, atMessageId, name)` with parentSessionId lineage. **Compaction**: needsCompaction, addCompaction, compactAndSplit. **Search**: cross-session FTS via `manager.tools()` → `session_search`. **Tool separation**: session.tools() → update_context, manager.tools() → session_search. **multi-session-agent example** — sidebar with chat list, create/delete, cross-session search. Uses SessionManager builder with Workers AI (Kimi K2.5). * feat(experimental): SessionManager compaction propagation, streaming, and rename - Add onCompaction() and compactAfter() builder methods to SessionManager so all sessions inherit compaction config automatically - Rename multi-session-agent → session-multichat example - Switch example from generateText to streamText with text-delta streaming - Remove manual compact() callable — auto-compaction handles it via Session - Fix needsCompaction() calling non-existent Session method * fix: use agents/vite plugin instead of removed decorator script * fix: extend agents/tsconfig instead of removed tsconfig.base.json * fix: remove @cloudflare/agents-ui dep, inline ConnectionIndicator and ModeToggle * fix: remove ThemeProvider from agents-ui in index.tsx * fix: only show loading dots before stream starts, matching session-memory * fix: align kumo and ai dependency versions with workspace * fix: sanitize FTS5 query input and add error handling in search() * fix: format README.md * fix: use per-word quoting in FTS5 search to preserve AND semantics * fix: await async appendMessage calls to prevent concurrent auto-compactions * fix: await async manager methods in test filegithub.com-cloudflare-agents · befe241e · 2026-04-01
- 1.1ETVfeat: add skills system for on-demand document loading (#1243) * feat: add skills system for on-demand document loading via session API Adds SkillProvider interface and R2SkillProvider for loading skills from R2 on demand. Skill metadata is injected into the system prompt so the model knows what's available, and a load_skill tool lets it fetch full content when needed. * chore: rename catalog.ts to skills.ts * chore: update package-lock.json for session-skills example * fix: R2 pagination, lint and formatting fixes * refactor: unified context provider hierarchy, remove readonly flag and initialContent - ContextProvider (get only) → readonly block - WritableContextProvider extends ContextProvider (get+set) → writable via set_context - SkillProvider extends ContextProvider (get+load+set?) → on-demand via load_context - Provider shape determines behavior, no readonly flag needed - Remove initialContent — use provider.get() instead - Rename update_context → set_context - Add load_context tool for skill blocks - All 81 tests passing * fix: clean up skill block header rendering with description * fix: use R2 bucket directly for sidebar CRUD, not provider interface * docs: update READMEs and doc comments for new context provider API * docs: add README for session-skills example * fix: use R2SkillProvider.set() for sidebar skill saves * fix: include customMetadata in R2 list calls for skill descriptions * fix: add labels to description and content fields in skill editor * feat: show skill description as badge, add metadata persistence tests * chore: reformat with oxfmt to match CI * fix: remove unused ContextProvider import from session.ts * fix: typecheck and lint errors across all projects - Update session-memory and session-multichat examples for new API - Fix manager.ts to use WritableContextProvider - Fix kumo component props (aria-label, className) - Cast R2 list options for include: customMetadata - Fix JSON schema type in context.tsgithub.com-cloudflare-agents · e843d9b4 · 2026-04-01
- 1.0ETVfeat: add SearchProvider with AgentSearchProvider (FTS5) and search_context tool (#1245) * feat: add SearchProvider with AgentSearchProvider (FTS5) and search_context tool - SearchProvider extends ContextProvider with search(query) and keyed set(key, content) - AgentSearchProvider: DO SQLite FTS5-backed implementation - search_context tool auto-wired when any block has a SearchProvider - set_context handles keyed writes for search blocks (same as skills) - Searchable blocks render in system prompt even when empty - 10 new tests for search provider detection, system prompt, search_context, and set_context integration - experimental/session-search example with searchable knowledge block - 94 total tests passing, all 72 projects typecheck * fix: remove hardcoded account_id from example wrangler configs * refactor: add init(label) lifecycle to ContextProvider, remove redundant label params Providers no longer need the block label at construction time. The context system passes it via init(label) during load(). Eliminates the pattern of passing the same label to both withContext() and the provider constructor. - Add optional init?(label) to ContextProvider interface - AgentSearchProvider: constructor takes just SqlProvider, label via init - AgentContextProvider: label now optional, falls back to init - ContextBlocks.load() calls init before first provider use * test: add 11 init(label) lifecycle tests for all provider types * feat: add withSearchableHistory() to SessionManager for cross-session search Adds a builder method that creates a readonly SearchProvider context block backed by the manager's cross-session FTS5 message search. The model can use search_context to find relevant messages from any session. - SessionManager.withSearchableHistory(label) builder method - Internal ManagerHistorySearchProvider (no public class needed) - Updated session-multichat example to use it * fix: bump ai dep to ^6.0.142 in session-search to match workspace * fix: add compact() callable, fix FTS5 multi-word search - Add missing compact() method to session-search example - Use word-level quoting for FTS5 search (matches non-adjacent terms) * test: add DO-backed FTS5 integration tests for AgentSearchProvider - TestSearchAgent with index/search, init lifecycle, and update/replace tests - Verifies single-word, multi-word non-adjacent, cross-key, and no-results queries - Verifies init(label) lifecycle with real DO SQLite - Verifies FTS5 entry replacement on update - 108 total tests passing * docs: comprehensive READMEs for session-search, session-multichat, and session-memory - session-search: full docs on SearchProvider interface, AgentSearchProvider, FTS5 storage, cross-session search, generated tools, usage examples - session-multichat: add withSearchableHistory docs, builder methods, lifecycle - session-memory: add SearchProvider to provider hierarchy tablegithub.com-cloudflare-agents · 703dfa47 · 2026-04-02
- 0.9ETVfeat(codemode): add browser iframe executor (#1468) * feat(codemode): add browser iframe executor Add IframeSandboxExecutor, a browser-native executor that runs LLM-generated code in a sandboxed iframe using postMessage for tool dispatch. Available via @cloudflare/codemode/browser. Also adds createBrowserCodeTool(), a zero-dependency equivalent of createCodeTool that accepts JSON Schema tools (object or array) and returns a plain tool descriptor with inputSchema, outputSchema, and execute. No ai or zod peer deps required. The iframe uses sandbox="allow-scripts" with a restrictive CSP. Tool calls flow through postMessage; the iframe is torn down after each execution. dist/browser.js: 11.3 KB raw, 3.77 KB gzip. Zero new dependencies. Closes #1111 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(codemode): align browser executor behavior * test(codemode): cover browser executor provider paths * docs(codemode): add browser webmcp client example * docs(codemode): keep browser example client-tool agnostic * docs(codemode): align browser example with ai chat tools * test(codemode): update browser vitest provider config * example(codemode): run browser iframe executor * example(codemode): allow choosing executor * Revert "example(codemode): allow choosing executor" This reverts commit 57a40acc5a64a18ce2dcdaf580b38c9b8dd38ce6. * Revert "example(codemode): run browser iframe executor" This reverts commit 50ba67c9f1f6bd2244ecc21d7f00732ca490125a. * example(codemode): add browser iframe example * example(codemode-browser): polish UI * example(codemode-browser): match footer layout * changeset: add codemode browser patch * fix(codemode): pass repo checks * fix(lockfile): include rolldown wasm deps --------- Co-authored-by: Alex Nahas <alexmnahas@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>github.com-cloudflare-agents · 186a2a45 · 2026-05-06
- 0.9ETVfeat(shell): add isomorphic-git integration (#1136) * feat(shell): add isomorphic-git integration for workspace filesystem Pure JS git implementation via isomorphic-git with a custom fs adapter that bridges the shell FileSystem interface. Includes a ToolProvider for codemode sandbox with auto-injected auth tokens (LLM never sees secrets). - git/index.ts: CLI-matching commands (clone, status, add, commit, log, branch, checkout, fetch, pull, push, diff, init, remote) - git/fs-adapter.ts: bridges FileSystem to isomorphic-git's FS API - git/provider.ts: ToolProvider with positionalArgs and token injection - workspace.ts: ENOENT errors now include code property for isomorphic-git - Tests for init, commit, status, branch, checkout, add, diff * chore: update lockfile for isomorphic-git * Add isomorphic-git integration and move examples Introduce a new @cloudflare/shell/git export providing pure-JS git operations backed by the Workspace filesystem (createGit(filesystem) and gitTools(workspace) ToolProvider). Integrate git into WorkspaceChatAgent: wire up a WorkspaceFileSystem-backed git instance, inject gitTools into the runStateCode sandbox, and add agent tools for common git operations (gitInit, gitStatus, gitAdd, gitCommit, gitLog, gitDiff). Move experimental example apps into examples/ (worker-bundler-playground, workspace-chat) and update related docs and example code. Add a changeset entry for the shell minor feature. * Fix git status mappings and add tests Correct git status label mappings (swap deleted staged/unstaged and mark 121 as modified, unstaged) and add unit tests that verify workdir-only modified and deleted states. Also add example workspace favicon.ico. These changes align status strings with expected git status behavior and add coverage to prevent regressions. * Increase test delay from 150ms to 1000ms Update the simulated delay in client tools continuation tests from 150ms to 1000ms to reduce flakiness and give pending/continuation logic more time to execute. Modified three request bodies in packages/ai-chat/src/tests/client-tools-continuation.test.ts where delayMs was set to 150. * Update client-tools-continuation.test.ts * Preserve fs error codes and add status 113 Replace the simple enoent() helper with fsError() that preserves an existing error.code (if present) and otherwise defaults to ENOENT so isomorphic-git can dispatch on .code. Update readFile/stat/lstat/readlink callers to throw fsError. Also add git status mapping for code "113" => "modified, staged". --------- Co-authored-by: Sunil Pai <spai@cloudflare.com>github.com-cloudflare-agents · b5450792 · 2026-03-24
- 0.8ETVdocs + refactor: Session API documentation and AI SDK decoupling (#1280) * docs: add Session API documentation Comprehensive guide covering Session, SessionManager, context blocks, compaction, AI tools, search, storage, and custom providers. * chore: remove dead session API surface - Remove MessageQueryOptions (exported type, never accepted by any method) - Remove needsCompaction (redundant with compactAfter auto-compaction) - Remove maxContextMessages builder method and field (only fed needsCompaction) - Update docs to reflect removals * Update sessions.md * refactor(session): decouple Session API from AI SDK runtime dependency Replace all runtime imports from the `ai` package in the Session module with library-agnostic alternatives: Message types: - Define minimal SessionMessage/SessionMessagePart types that capture only what the Session internals actually access at runtime - Replace all `import type { UIMessage } from "ai"` with SessionMessage across 7 session source files, 2 test files - UIMessage from the AI SDK is structurally compatible — it can be passed directly without conversion - Clean up `as Record<string, unknown>` casts in session.ts since SessionMessagePart now has the fields directly Tool schemas: - Swap `jsonSchema()` from `ai` to `z.fromJSONSchema()` from zod in context.ts and manager.ts, matching the pattern from MCPClientManager - Keep `import type { ToolSet } from "ai"` as type-only (zero runtime cost, erased at compile time) Consumer boundary casts: - Add `as UIMessage[]` casts in Think, experimental session examples, and test agents where SessionMessage[] flows into UIMessage[] sites - Safe because underlying objects round-trip through JSON unchanged Documentation fixes: - Fix getBranches() doc: returns children, not siblings - Add sessions.md to docs/index.md - Remove stale maxContextMessages reference from session-multichat README - Update doc to describe SessionMessage type and structural compatibility - Add SessionMessage/SessionMessagePart to exports listing Made-with: Cursor --------- Co-authored-by: Sunil Pai <spai@cloudflare.com>github.com-cloudflare-agents · fdafa432 · 2026-04-10
- 0.8ETVfeat(codemode): extract utilities into AI-free main entry point (#1102) * feat(codemode): extract utilities into AI-free main entry point Move sanitizeToolName, JSON Schema conversion utilities, and a new generateTypesFromJsonSchema function into a separate sanitize.ts module with zero AI SDK dependencies. The main entry point (import from "@cloudflare/codemode") no longer requires the ai or zod peer dependencies — they are now optional and only needed when importing from "@cloudflare/codemode/ai". BREAKING: generateTypes and ToolDescriptor/ToolDescriptors types moved from the main entry to "@cloudflare/codemode/ai". * Extract AI-free utilities from @cloudflare/codemode Split the package so the main entry point has zero dependency on `ai`/`zod`: - `utils.ts` — sanitizeToolName, toCamelCase, and string helpers - `json-schema-types.ts` — JSON Schema → TypeScript type generation - `tool-types.ts` — AI SDK dependent type generation (moved from types.ts) The main entry (`@cloudflare/codemode`) now exports sanitizeToolName, normalizeCode, generateTypesFromJsonSchema, jsonSchemaToType, and the executor classes. The `/ai` entry point keeps createCodeTool and generateTypes which require the ai/zod peer deps. Also fixes duplicate type declarations when extractParamDescriptions throws, and moves json-schema from runtime deps to @types/json-schema in devDependencies.github.com-cloudflare-agents · f07ef51e · 2026-03-13
- 0.6ETVfix: route RPC MCP responses by request id (#1558) * fix: serialize rpc mcp messages * fix: preserve rpc transport type narrowing * fix: route rpc mcp responses by request id * test: preserve rpc continuation scenario * fix: keep rpc mcp waits alive * docs: explain rpc mcp keepalivegithub.com-cloudflare-agents · 67ff1ba1 · 2026-05-27
- 0.5ETVfix: preserve binary values across codemode tools (#1521) * fix: preserve binary values across codemode tools * chore: shorten codemode binary tag * changeset: fix codemode binary tool values * test: cover codemode binary edge cases * fix: reserve codemode codec globalsgithub.com-cloudflare-agents · 2911bae6 · 2026-05-14
- 0.5ETV[wrangler] add artifacts binding support (#13326) Co-authored-by: Dario Piotrowicz <dario@cloudflare.com> Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>github.com-cloudflare-workers-sdk · 4a9ba90b · 2026-04-17
- 0.5ETVfeat(codemode): add `./mcp` export with `codeMcpServer` and `openApiMcpServer` (#1114) * feat(codemode): add /mcp barrel export with codeMcpServer and openApiMcpServer Two new functions exported from @cloudflare/codemode/mcp: - codeMcpServer(server, executor) — wraps an MCP server with a single `code` tool. Each upstream tool becomes a typed method on `codemode.*`. The LLM gets a full typed SDK in the description. - openApiMcpServer({ spec, executor, request }) — creates search + execute MCP tools from an OpenAPI spec. Search injects the spec as a global, execute injects a host-side request() function via RPC so auth never enters the sandbox. Also extends the Executor interface with an optional `globals` parameter for injecting top-level constants and functions into the sandbox, and adds a configurable `name` parameter to generateTypesFromJsonSchema/generateTypes. Includes 11 end-to-end tests and two examples (codemode-mcp, codemode-mcp-openapi). * revert name parameter from type generators, extract openapi spec to json file * add comment to request function in openapi example * simplify globals: single dispatcher with prefix instead of separate one * remove globals from executor, unify everything under codemode.* * use generic placeholders in openapi tool descriptions, not hardcoded paths * use extraDescription in openapi example to show spec-specific examples * rewrite skill.md to focus on wrapping a normal MCP server with codeMcpServer * add snapshot tests for search and execute tool descriptions * replace processSpec with resolveRefs, use standard OpenAPI types, GitHub API example - resolveRefs now exported and handles JSON Pointer escaping (~0, ~1) - Spec types in description use standard OpenAPI 3.x structure - Example now fetches GitHub API spec at runtime instead of bundling petstore * switch openapi example to Cloudflare API, accept token via auth header * fix check: formatting, dep version, add changeset * fix resolveRefs seen set cleanup, add READMEs for examples * update lockfile, make resolveRefs private * consistent options objects: codeMcpServer({ server, executor }), rename extraDescription to description * fix truncateResponse crash when content is undefined * add tests for undefined/null return and non-existent tool * remove duplicate normalize/sanitize from mcp.ts — executor handles both internally now * Refine MCP OpenAPI examples and types Update .changeset to reflect new codeMcpServer signature (codeMcpServer({ server, executor })). Expand and clarify the codemode-mcp and codemode-mcp-openapi example READMEs with usage, run instructions, and key patterns. Revise examples/codemode-mcp-openapi/src/server.ts to improve the example description and demo calls (retrieve zones, derive account_id for Workers scripts, and show creating a DNS record). Remove the now-redundant examples/codemode-mcp/skill.md. Tighten types in packages/codemode/src/mcp.ts by changing OpenApiMcpServerOptions.spec from unknown to JSONSchema7 and remove the appended description string in the generated tool template. * revert non-codemode changes: remove cursor state file, restore shell test --------- Co-authored-by: Sunil Pai <spai@cloudflare.com>github.com-cloudflare-agents · 5d88b810 · 2026-03-17
- 0.4ETVrefactor(codemode): dispatch all tool calls positionally (#1547)github.com-cloudflare-agents · f739ec9c · 2026-05-18
- 0.3ETVfix(codemode): remove zod-to-ts (#1074) * refactor: remove zod-to-ts, DRY schema tests with dual JSON Schema + Zod coverage - Replace zod-to-ts with AI SDK's asSchema() for Zod→JSON Schema conversion, routing both paths through jsonSchemaToTypeString() - Fix extractDescriptions to unwrap ZodOptional/ZodNullable/ZodDefault wrappers when extracting .description for @param JSDoc generation - Refactor schema-conversion.test.ts with testBoth() helper generating dual it() blocks (JSON Schema + Zod) with shared assertions - Trim types.test.ts by removing 9 tests now covered by dual tests - Reorganize tests by feature (basic types, descriptions, unions, output schemas, $ref, edge cases, etc.) * fix: remove unused z import from types.test.ts * Update nx.json * Refactor jsonSchemaToTypeString and zod imports Replace deprecated 'zod/v4' imports with 'zod' in tests and e2e worker. Heavily refactor jsonSchemaToTypeString: use in-place seen set management with try/finally to ensure cleanup, reorder and consolidate handling of $ref, anyOf/oneOf/allOf, enum/const, primitives, arrays, and objects, and improve tuple/items and JSDoc generation. These changes simplify recursion, avoid creating many copied sets, and make type conversion more robust for complex/circular JSON Schemas. --------- Co-authored-by: Sunil Pai <spai@cloudflare.com>github.com-cloudflare-agents · 33b92d52 · 2026-03-09
- 0.2ETVfix(codemode): resolve OpenAPI specs inside sandbox (#1470)github.com-cloudflare-agents · 1033fa28 · 2026-05-06
- 0.2ETVAdd R2SkillProvider key allowlist (#1477) * Add R2 skill provider key allowlist * Remove changeset for experimental R2 key allowlistgithub.com-cloudflare-agents · acedb8ac · 2026-05-07
- 0.1ETVrefactor(codemode): omit source code from tool results (#1523) * refactor(codemode): omit source code from tool results * chore: add codemode result changeset * style(codemode): simplify tool output construction * refactor(codemode): share code execution helper * refactor(codemode): standardize browser code output * test(codemode): assert logs in tool output * chore: mark codemode result changeset as patch * chore(codemode): remove unused CodeOutput import * test(codemode): update browser output expectation * test(codemode): expect empty browser logs * fix(codemode): omit empty logs from code outputgithub.com-cloudflare-agents · 5f1376fe · 2026-05-14
- 0.1ETVfeat(codemode): normalize code and sanitize tool names inside executor (#1117) * feat(codemode): normalize code and sanitize tool names inside executor DynamicWorkerExecutor.execute() now calls normalizeCode() on the input code and sanitizeToolName() on fns keys internally. Users no longer need to do this themselves — pass raw code and raw tool names. * docs(codemode): note that executor internalizes normalize and sanitizegithub.com-cloudflare-agents · 9837adc9 · 2026-03-17