- Remove '|| .bat' fallback from all starter package.json scripts so
real errors on Linux/macOS are not masked by a failing .bat attempt
- Fix typos: 'isseus' -> 'issues', 'interactin' -> 'interacting'
- Fix crewai-crews README title/body saying 'Flow' instead of 'Crew'
- Fix a2a-a2ui README wrong agent name and file path
- Remove phantom lint/dev:debug scripts from README Available Scripts
sections where those scripts don't exist in package.json
- Add missing dev:ui and dev:agent to mastra README
Tests the /debug-events SSE endpoint across Express, Hono, Node, and
Fetch Direct adapters. Verifies SSE response format, event flow through
the DebugEventBus, envelope structure (timestamp, agentId, threadId,
runId, event), full event sequence, HTTP method validation (405 for
POST), and NODE_ENV=production guard (404).
Key implementation detail: reader.cancel() must NOT be awaited on
tee'd ReadableStreams (created by response.clone() in the fetch
handler) because Node.js blocks until the other tee branch is also
consumed/cancelled.
- chmod +x all new .sh scripts so they work on Linux/macOS
- Use --ignore-scripts in langgraph-js Dockerfiles to avoid postinstall
failure (agent/ dir not yet copied during npm install stage)
- Install agent deps in production Dockerfile after COPY agent/
- Fix hardcoded pnpm commands in agent-spec README
Reorder package manager instructions to show npm first as the default.
Remove stale 'ignores lock files' notes since lock file entries were
removed from .gitignore. All starters now work with npm, pnpm, yarn,
or bun — user's choice.
Starters should not constrain users to a specific package manager.
The .gitignore gets cloned into the user's project, so ignoring
certain lock files would prevent them from committing their chosen
package manager's lock file.
Flatten langgraph-python, langgraph-js, and mcp-apps starters so
npm install && npm run dev works out of the box. Replace Turborepo
with concurrently, move apps/* to root, update Dockerfiles, READMEs,
and entrypoints. Also remove stray pnpm-lock.yaml from a2a-a2ui and
ms-agent-framework-dotnet starters.
## Summary
- Fixes#2986
- `reqOrRequest instanceof Request` fails when `@hono/node-server`
polyfills the Request class with a different prototype
- Replaced with a duck-type check (`isRequestLike`) that verifies `url`,
`method`, and `headers` properties exist
- The `!res` guard ensures IncomingMessage objects (which always come
with a ServerResponse) are still routed correctly
## Test plan
- [x] Added `request-duck-type.test.ts` covering native Request,
polyfilled Request, null/undefined, and missing properties
- [x] All 1225 existing runtime tests pass
- [x] Build passes
## Summary
Ports 3 proven patterns from ag-ui's release system to CopilotKit.
### C1: Registry error vs 404 distinction
`getPublishedVersion` in `publish-release.ts` now distinguishes between
npm E404 (package genuinely not published — proceed) and real errors
(network timeout, auth failure, rate limit — stop). Previously all
errors returned `null`, silently bypassing the version guard.
### C2: Pre-existing tag check
Added a check in `publish-release.yml` that verifies the tag doesn't
already exist before attempting to create it. Prevents the "published
but no tag" state on retries.
### C3: Pre-publish tests in prerelease
Added `pnpm run test` between build and publish in the canary workflow.
A broken canary erodes trust in the prerelease channel.
**Cross-pollination context:** [Notion
page](https://www.notion.so/3413aa38185281828aa1dfa014808ddc)
The ag-ui side (strict version ordering, AI release notes, atomic PR
creation) ships via ag-ui PR #1487.
## Test plan
- [ ] Verify `getPublishedVersion` returns null on E404 but throws on
network errors
- [ ] Verify pre-existing tag check fails fast before publish
- [ ] Verify prerelease workflow runs tests before canary publish
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Three React components for the AG-UI event inspector webview:
- FilterBar: category toggles, text search, agent/run dropdowns
- EventList: scrollable event stream with sticky auto-scroll and event summaries
- EventDetail: side panel with metadata display and collapsible JSON tree viewer
## Summary
- `sendMessage` returns `Promise<void>` but `usePushToTalk` accessed
`.id` on the result, causing a `TypeError` crash during push-to-talk
transcription
- Added guard to check if `sendFunction` returns a message before
accessing `.id`
- Updated `SendFunction` type to accept `Promise<Message | void>`
Fixes#3011
## Test plan
- [x] Added unit tests verifying void return handling
- [x] Added unit tests verifying message-with-id return handling
- [x] All react-ui tests pass
## Summary
- `.copilotKitMessagesFooter` used `width: 97%` which caused horizontal
overflow in constrained containers
- Changed to `width: 100%` with `box-sizing: border-box` so padding is
included in the width calculation
Fixes#2325
## Test plan
- [x] All react-ui tests pass
- [ ] Visual verification: render CopilotKit chat in a constrained
container (e.g. 300px sidebar) and confirm no horizontal scrollbar
appears
## Summary
Fixes#2194
`CopilotModal` and `CopilotModalProps` were not exported from
`@copilotkit/react-ui`, making them inaccessible to consumers. Adds both
exports to the chat barrel file.
## Test plan
- [ ] Verify `CopilotModal` and `CopilotModalProps` are importable from
`@copilotkit/react-ui`
## Summary
- `Button` component wrapped with `React.forwardRef` to fix ref warning
from Radix UI's `DropdownMenuTrigger asChild` pattern
Closes#2947
## Test plan
- [x] All affected packages build successfully
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- The loading spinner only appeared when the last message had role
"user"
- During tool execution the last message can have role "tool", hiding
the indicator
- Now also show it when the trailing message is a tool result
Closes#3055
## Summary
- Skips keydown handling during IME composition (e.g. CJK input) by
checking `isComposing`/`keyCode 229`
- Guards textarea measurement from resetting value mid-composition,
which would break the composition session
Closes#3318
## Summary
- Always calls `onChange("")` after send in controlled mode so the
parent component is notified to clear its state
- Previously `onChange` was only called inside the `!isControlled`
branch, leaving controlled parents unaware the input was submitted
Closes#3593
Closes#1921
The Markdown component accepted `components` but not `urlTransform`,
preventing users from customizing URL sanitization. Added `urlTransform`
as an optional prop with passthrough to `MemoizedReactMarkdown`.
Split from #3838.
## Summary
- `buildFrontendTools` only checked `tool.available !== false` but the
`available` field can also be the string `"disabled"`, which is truthy
- Added `tool.available !== "disabled"` to the filter so disabled tools
are properly excluded
- Added test verifying tools with `available: "disabled"` are filtered
out
## Test plan
- [x] New test: tool with `available: "disabled"` is excluded from
`buildFrontendTools`
- [x] All existing available-filtering tests still pass
- [x] Full core test suite passes (338 tests)
## Summary
- onThumbsUp/onThumbsDown/onReadAloud/onRegenerate callbacks on
CopilotChatAssistantMessage were receiving the browser SyntheticEvent
instead of the AssistantMessage object
- Wrapped the onClick handlers to pass the message explicitly:
`onClick={() => onThumbsUp(message)}`
- Same fix applied to onReadAloud and onRegenerate for consistency
## Test plan
- [x] Red-green verified: test confirms callback arg has `id`, `role`,
`content` and NOT `nativeEvent`/`target`
- [x] Full react-core test suite passes (1071 tests)
- [x] Build passes
Closes#3457
## Summary
- useRenderCustomMessages threw "Agent not found" when the agent was
undefined during the connecting state
- Changed the throw to return null, allowing the component to render
gracefully while the agent is being resolved
## Test plan
- [x] Red-green verified: test calls hook with nonexistent agent,
asserts returns null not throws
- [x] Full react-core test suite passes (1071 tests)
- [x] Build passes
Closes#3497
## Summary
- CopilotListeners called useAgent() unconditionally, which throws when
no agents are registered and no runtimeUrl is configured
- Split into CopilotListeners (outer, handles error subscription) and
CopilotListenersAgentSubscription (inner, uses useAgent)
- Inner component only renders when agents exist or a runtime is
configured
## Test plan
- [x] Red-green verified: render CopilotListeners with no agents, assert
no throw
- [x] Full react-core test suite passes (1071 tests)
- [x] Build passes
Closes#3249
## Summary
- `checkForUpdates()` in dev console is now gated on `showDevConsole`,
preventing unnecessary network requests when the console is disabled
Closes#2751
## Test plan
- [x] `@copilotkit/react-core` tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- LangChain adapter now always uses `randomId()` for message stream IDs
instead of relying on `lc_kwargs.id` (which GoogleGenerativeAI sets to
`"0"` for all messages)
Closes#2929
## Test plan
- [x] `@copilotkit/runtime` tests pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- Default `max_tokens` was hardcoded to 1024, causing truncated
responses for most use cases
- Increased default from 1024 to 4096 while still respecting
user-provided `maxTokens`
Fixes#2354
## Test plan
- [x] Added test verifying default max_tokens is 4096 when not specified
- [x] Added test verifying user-provided maxTokens is passed through
- [x] All existing anthropic adapter tests pass
## Summary
- Providers like `@ai-sdk/openai-compatible` emit sequential IDs
(`txt-0`, `reasoning-0`, `msg-0`) that are treated as unique but collide
across requests
- The existing check only caught the literal `"0"` — expanded to match
the `^(txt|reasoning|msg)-0$` pattern
- Both `text-start` and `reasoning-start` event handlers now use
`randomUUID()` for these non-unique IDs
## Test plan
- [x] Added `provider-id-collision.test.ts` with 4 tests covering txt-0,
reasoning-0, msg-0, and legitimate ID preservation
- [x] All 1226 runtime tests pass (including existing
config-tools-execution tests)
Fixes#3410, #3623
## Summary
- `onAfterRequest` middleware callback was called with `{}` instead of
actual hook parameters
- Now forwards `threadId`, `runId`, `inputMessages`, `outputMessages`,
and `url` from the v2 runtime's `hookParams`
- The `onBeforeRequest` handler at line 566 already did this correctly;
this fix makes `onAfterRequest` consistent
## Test plan
- [x] Added `on-after-request.test.ts` verifying the callback receives
threadId and runId (not empty object)
- [x] All 1226 runtime tests pass
Fixes#2124
## Summary
Fixes#2450
Token trimming in the Anthropic adapter could remove assistant messages
containing `tool_use` blocks while keeping the corresponding user
messages with `tool_result` blocks. Anthropic's API rejects orphaned
`tool_result` messages. This adds a post-processing step that removes
orphaned `tool_result` blocks after trimming.
## Test plan
- [ ] Verify token trimming preserves tool_use/tool_result pairing
- [ ] Verify orphaned tool_result blocks are removed
- [ ] Verify messages with mixed content (tool_result + text) retain
non-orphaned content
## Summary
Fixes#2405
Both OpenAI and Anthropic adapters used a hardcoded token limit for
message trimming. This adds an optional `maxInputTokens` constructor
parameter to both adapter classes, allowing consumers to override the
default context window limit.
## Test plan
- [ ] Verify default behavior unchanged when `maxInputTokens` not
provided
- [ ] Verify custom `maxInputTokens` is passed through to
`limitMessagesToTokenCount`
## Summary
Fixes#2504
When Anthropic returns a `tool_use` block for a tool not registered in
the current action set, the adapter would crash trying to process it.
This adds a check against known action names and skips unknown tool_use
blocks gracefully.
## Test plan
- [ ] Verify known tools are still processed normally
- [ ] Verify unknown tool_use blocks are skipped without crashing
## Summary
- langchain-mcp-adapters sends tool call result content as an array of
`{type:"text", text:string}` objects
- Extracts and joins text parts so downstream consumers always receive a
plain string
Closes#2922
Closes#3141
`applyCredentialsToAgents`/`applyCredentialsToAgent` were defined but
never called from `initialize()`, `setAgents__unsafe_dev_only()`, or
`addAgent__unsafe_dev_only()`. Only remote agents received credentials
via constructor. Local agents now receive credentials alongside headers.
Split from #3838.
Closes#3741
Add `toolCallId` prop to all three status branches (InProgress,
Executing, Complete) of the ToolCallRenderer, and update the
`ReactToolCallRenderer` type to include it in the discriminated union.
Split from #3838.