Commit Graph

1601 Commits

Author SHA1 Message Date
Jordan Ritter 082016e90d test: add StateManager RunErrorEvent tests
Verify that:
- State is tracked when a run errors (getStateByRun returns error state)
- A new run after an error works correctly (runFinished flag resets,
  second run tracked independently)
2026-04-10 10:25:35 -07:00
Jordan Ritter 01466e5629 fix: handle RunErrorEvent in proxy agent, state manager, angular agent, and node name hook
When the backend emits RunErrorEvent via the AG-UI protocol, several
components did not handle it:

- ProxiedCopilotRuntimeAgent: isRunning stayed true, causing
  data-copilot-running to never transition to false (infinite spinner)
- StateManager: activeRun entries were never cleaned up, runFinished
  flag never set (stale state on subsequent runs)
- Angular CopilotKitAgent: same isRunning bug as the proxy agent
- useAgentNodeName: node name stuck at last step instead of "end"

onRunErrorEvent is distinct from onRunFailed — the former handles
protocol-level RUN_ERROR events from the backend, the latter handles
local exceptions (network errors, deserialization failures).
2026-04-10 10:25:35 -07:00
Martha Kelly Schumann d521b1ff66 Merge branch 'main' into claude/langgraph-tests-cleanup-1jVZ3 2026-04-10 09:31:34 -07:00
Martha Kelly Schumann 445057aa06 fix(react-core): preserve assistant text when multiple tool calls fire in one turn (CPK-7154) (#3622)
## Summary

- **Root cause**: `CopilotChatMessageView` deduplicated messages with
`new Map(messages.map(m => [m.id, m]))`, which keeps only the *last*
occurrence of each ID. During streaming, when an agent fires multiple
tool calls in one turn, the same message ID appears multiple times:
first with text content, then with empty content + tool calls appended.
The last entry wins, wiping the text.
- **Fix**: Replace "keep last" with a **merge** strategy for assistant
messages — recover non-empty `content` from any earlier occurrence while
keeping the latest `toolCalls` (which accumulate). All other message
roles retain "keep last" behavior.
- **Test**: Added a regression test covering the three-occurrence
scenario (text → first tool call → second tool call) to confirm the
merged message renders both the original text and the final tool call
set.

## Test plan

- [x] New test `"preserves assistant text content when later duplicate
has empty content (multi-tool-call scenario)"` passes
- [x] Existing dedup tests (single duplicate, order preservation,
activity rendering) all pass unchanged
- [x] Full `@copilotkit/react-core` test suite: **950 passed, 0 failed**
(baseline was 949)

Closes #3470

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-10 09:13:53 -07:00
Martha Kelly Schumann fd1b060cad Merge branch 'main' into claude/langgraph-tests-cleanup-1jVZ3 2026-04-10 09:07:25 -07:00
Alem Tuzlak c3fc0091a0 fix(runtime): widen TanStack message content type for adapter compat
TanStackChatMessage.content uses any[] for multimodal so
messages are directly passable to any adapter without casts.
Add env.d.ts with vite/client types for CSS imports.
2026-04-10 17:53:43 +02:00
Alem Tuzlak 672d3cf2e1 fix(runtime): preserve empty text parts in TanStack converter
Fix falsy check dropping valid empty-string text parts.
Add tests for unknown part types, null content, and
binary parts with neither data nor url.
2026-04-10 17:29:24 +02:00
Alem Tuzlak 4a69d7a8e3 feat(runtime): add multimodal support to TanStack converter
- Fix convertInputToTanStackAI silently dropping multimodal
  content (images, audio, video, documents) by converting
  AG-UI content parts to TanStack AI ContentPart format
- Switch react-router example from Hono server to a React
  Router resource route using createCopilotRuntimeHandler
- Both agents now use BuiltInAgent factory pattern
- Remove hono/react-router-hono-server deps from example
2026-04-10 17:15:57 +02:00
Martha Kelly Schumann 1e3069e423 Merge branch 'main' into fix/CPK-7154-agent-text-wiped-multiple-tool-calls 2026-04-10 07:49:05 -07:00
Tyler Slaton 214924c7f9 Merge branch 'main' into worktree-fancy-mapping-valley 2026-04-09 20:47:51 -07:00
Martha Kelly Schumann 334d823207 Merge branch 'main' into claude/langgraph-tests-cleanup-1jVZ3 2026-04-09 18:41:05 -07:00
Martha Kelly Schumann fdad548be7 Merge branch 'main' into fix/CPK-7154-agent-text-wiped-multiple-tool-calls 2026-04-09 15:38:55 -07:00
Jordan Ritter 1b01725d40 test: add 18 MCP integration tests with aimock MCPMock
Phase 1 — BasicAgent mcpServers (8 tests):
- HTTP transport tool fetch, SSE error handling
- Tool call round-trip, client cleanup, unreachable server error
- Multiple servers merge tools, error-path cleanup, tool descriptions

Phase 2 — MCPAppsActivityRenderer proxy (5 tests):
- tools/call proxy round-trip, error handling
- ui/open-link handler + missing URL error
- Multiple independent activities

Phase 3 — MCPAppsMiddleware edge cases (5 tests):
- Middleware creation, tools/call proxy, resources/read proxy
- Non-proxied request delegation, wrong serverHash error

All tests use real HTTP connections to aimock MCPMock.
2026-04-09 14:58:32 -07:00
Jordan Ritter 55663ee69f chore(runtime): add @copilotkit/aimock devDependency for MCP integration tests 2026-04-09 14:54:07 -07:00
Martha Kelly Schumann 8e050a2ab7 Merge branch 'main' into fix/CPK-7154-agent-text-wiped-multiple-tool-calls 2026-04-09 14:51:04 -07:00
Jordan Ritter 0096a91717 fix(react-core): invoke agent after MCP ui/message events
The ui/message handler added messages to the chat but never called
runAgent(), so the agent never processed MCP-sent messages.

- Use copilotkit.runAgent({ agent }) through RunHandler for frontend
  tools, context, tool execution, and abort support
- Send JSON-RPC response immediately after addMessage, before agent run
- Agent run is fire-and-forget with error logging
- followUp parameter: true=always, false=skip, default=user messages only

Fixes #3216
2026-04-09 13:50:39 -07:00
Martha Kelly Schumann 14d752c6e0 Merge branch 'main' into fix/CPK-7154-agent-text-wiped-multiple-tool-calls 2026-04-09 12:59:36 -07:00
Alem Tuzlak 3dd17c1c5b Merge branch 'main' into worktree-fancy-mapping-valley 2026-04-09 20:40:27 +02:00
Martha Kelly Schumann 3f314a5776 Merge branch 'main' into claude/langgraph-tests-cleanup-1jVZ3 2026-04-09 11:28:55 -07:00
Martha Kelly Schumann 1a61500dda Merge branch 'main' into fix/CPK-7154-agent-text-wiped-multiple-tool-calls 2026-04-09 11:15:55 -07:00
Martha Kelly Schumann ac0f33884c Merge branch 'main' into claude/langgraph-tests-cleanup-1jVZ3 2026-04-09 11:14:47 -07:00
github-actions[bot] 1bc4786759 chore: version packages (next) 2026-04-09 18:09:30 +00:00
Tyler Slaton 62c604213c chore(a2ui-renderer): bump version for a2ui-middleware to 0.0.4
Signed-off-by: Tyler Slaton <tyler@copilotkit.ai>
2026-04-09 11:05:10 -07:00
Martha Kelly Schumann f65b841885 Merge branch 'main' into fix/CPK-7154-agent-text-wiped-multiple-tool-calls 2026-04-09 08:03:40 -07:00
Martha Schumann 0ba68318fc Merge branch 'fix/CPK-7154-agent-text-wiped-multiple-tool-calls' of https://github.com/CopilotKit/CopilotKit into fix/CPK-7154-agent-text-wiped-multiple-tool-calls 2026-04-09 07:59:15 -07:00
Martha Schumann 22a7f98bcf fix(react-core): address review feedback on deduplicateMessages
- Fix JSDoc: "while keeping the latest toolCalls" was wrong for the ?? case;
  now says "recovers toolCalls from earlier occurrences if the latest is
  undefined" and notes that [] is treated as intentional
- Add @internal annotation to signal export is for testing only
- Remove redundant AssistantMessage casts inside the role-narrowed branch
- Add missing content assertion to "uses latest content" render test
- Add test: [] toolCalls from later chunk is kept (not fallen back from)
- Add test: undefined content on both sides is handled without error
- Add changeset for @copilotkit/react-core patch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 07:58:52 -07:00
Martha Kelly Schumann 1a4ed9d639 Merge branch 'main' into claude/langgraph-tests-cleanup-1jVZ3 2026-04-09 07:27:59 -07:00
github-actions[bot] 0093bdbaa4 chore: version packages 2026-04-09 02:26:42 +00:00
github-actions[bot] c2837a3001 chore: version packages (next) 2026-04-09 01:53:20 +00:00
Tyler Slaton 422f5f55e1 fix(open-gen-ui): correctly import clairinet
Signed-off-by: Tyler Slaton <tyler@copilotkit.ai>
2026-04-08 18:09:03 -07:00
github-actions[bot] 00cace6abf chore: version packages 2026-04-08 23:54:54 +00:00
Ben Taylor ca233aea20 Revert "fix: catch async errors in LangGraphAgent.run() Observable" 2026-04-08 18:40:52 -05:00
Max Korp c5d712f4cf test(runtime): add unit tests for LangGraphAgent.run() async error handling
Verify that async rejections from runAgentStream are routed through the
Observable error channel instead of becoming unhandled promise rejections.
2026-04-08 16:17:55 -07:00
Max Korp cffc4cafe0 fix: catch async errors in LangGraphAgent.run() Observable
The base class @ag-ui/langgraph creates an Observable that calls
runAgentStream() but ignores the returned Promise. Any async rejection
becomes an unhandled promise rejection that crashes the process.

Override run() to properly route async errors through the Observable
error channel so downstream catchError handlers can process them.
2026-04-08 16:17:55 -07:00
Tyler Slaton 02b2638433 fix: generate runtime-client-gql types before tests 2026-04-08 15:32:49 -07:00
Ben Taylor 9181bf9ae0 fix: use plain UUID for thread-naming runs (#3664)
The thread naming creates an additional run, using a thread name that
was something like
"thread-naming:${originalthreadiduuid}:${newrandomuuid}" which
shockingly is not a valid uuid. This just drops the first 2 parts and
keeps the random uuid so langgraph can stop being mad.
2026-04-08 16:22:23 -05:00
Maxim 9ee8e92766 chore: resolve merge conflicts with origin/main
Keep both defaultThrottleMs (our branch) and inspectorDefaultAnchor +
design-skill context registration (main) in CopilotKitProvider.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 22:58:45 +02:00
Max Korp 2142ecea99 fix: use plain UUID for thread-naming runs 2026-04-08 13:52:06 -07:00
Maxim 7a99322e77 fix: harden throttleMs cascade — setter validation, timing fix, JSDoc accuracy, tests
- Core setter rejects invalid values (NaN, Infinity, negative) instead of
  storing them, preventing garbage from reaching downstream consumers.
- Provider initializes defaultThrottleMs synchronously during instance
  creation so child hooks see the correct value on their first render.
- Remove phantom notificationThrottle JSDoc reference (API does not exist).
- Remove dead "default" branch in error source detection.
- Fix misleading @default comments re: 0-vs-undefined semantics and
  cascade direction.
- Replace React-specific "re-renders" language in framework-agnostic core.
- Add test for dynamic provider defaultThrottleMs changes.
- Add tests for core setter validation behavior.
- Add defaultThrottleMs to renderWithCopilotKit test helper.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 22:05:22 +02:00
Markus Ecker a5c1137465 chore: update ag-ui deps and web-inspector styles 2026-04-08 12:51:07 -07:00
Markus Ecker 71c77d4072 feat(cli): add a2ui and opengenui scaffold options 2026-04-08 12:50:37 -07:00
Markus Ecker e6988014f8 feat(runtime): OpenGenerativeUI middleware + A2UI config cleanup
Add OpenGenerativeUIMiddleware (clarinet streaming JSON parser, held event
buffering, activity snapshot/delta conversion), remove a2ui boolean shorthand,
includeBasicCatalog defaults to false, before_agent SystemMessage ID reuse fix.
2026-04-08 12:50:18 -07:00
Markus Ecker 05ddcfc12a feat(react-core): Open Generative UI — sandboxed HTML/CSS/JS rendering via iframe
AI-generated UI streamed into chat via websandbox iframe (allow-scripts only,
no allow-same-origin), progressive HTML preview with throttled updates,
one-shot auto-resize, sandboxFunctions for host-to-iframe calls, designSkill
styling guidelines, A2UI catalog context injection.
2026-04-08 12:49:38 -07:00
Markus Ecker 93d0a76ddc feat(a2ui-renderer): A2UI v0.9 — BYOC catalogs, dark mode, component-neutral guidelines
Replace @a2ui/lit with @a2ui/web_core 0.9, introduce createCatalog() API for
custom component catalogs, add basic (18 components) and minimal (5 components)
built-in catalogs, CSS variable theming for dark mode, eliminate XSS vector
(dangerouslySetInnerHTML removed from Text component).
2026-04-08 12:48:47 -07:00
Maxim cb7bfae188 refactor: move defaultThrottleMs from React context onto CopilotKitCore instance
Addresses Tyler's review comment on #3657 — defaultThrottleMs is configuration
that belongs on the copilotkit instance, not as a sibling field in the React
context value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 21:44:47 +02:00
Maxim a8e05401e7 fix: improve throttleMs validation, JSDoc accuracy, and test coverage
- Add source attribution to error messages (hook-level vs provider-level)
- Add eager validation of defaultThrottleMs in CopilotKitProvider
- Add tests for invalid provider defaultThrottleMs (NaN, Infinity, -1)
- Remove redundant resolved !== 0 guard in validation
- Fix JSDoc: "streaming" → "message change notifications", "passed
  directly" → "forwarded", align @default terminology
- Extract shared mock helpers to reduce test duplication

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 21:31:28 +02:00
Maxim c8db6476a8 test: verify CopilotSidebar/CopilotPopup inherit throttleMs type
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 21:14:51 +02:00
Maxim a7c57cef9c feat: add throttleMs prop to CopilotChat, forwarded to internal useAgent
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 21:11:46 +02:00
Maxim e30d27b46b test: guard throttleMs:0 override of provider defaultThrottleMs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 21:07:57 +02:00
Maxim af98091bda feat: add defaultThrottleMs to CopilotKitProvider, read as fallback in useAgent
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 20:49:57 +02:00