Commit Graph

1468 Commits

Author SHA1 Message Date
Maxim e1da79a5ea fix(sdk): fix CancelledError swallow, dispatched_end ordering, add JS args validation
- Re-raise CancelledError after logging in langgraph copilotkit_emit_tool_call
  to honor asyncio cancellation contract (was silently un-cancelling tasks)
- Move dispatched_end flag to after ToolCallEndEvent dispatch in AG-UI agent
  so compensating END fires when END itself throws
- Add dispatched_end tracking to CrewAI variant to prevent double-END on
  partial failure
- Add JSON.stringify(args) validation in JS SDK matching Python parity
- Add 4 CrewAI compensating-END tests and 1 JS serializability test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:24 +02:00
Maxim 4a6d364e2c fix(sdk): harden error handling, revert args strictness, shield sleep
Address code review findings across all three SDK variants:

- Shield asyncio.sleep(0.02) with asyncio.shield() so task cancellation
  doesn't prevent returning the tool_call_id after dispatch
- Revert args validation to original permissiveness (JS: undefined-only
  check, Python: no isinstance check) to avoid breaking existing callers
- Add upfront json.dumps() serializability check in Python variants
- Fix compensating TOOL_CALL_END double-emit by tracking dispatched_end
- Add compensating action_execution_end to CrewAI variant (queue_put is
  non-atomic)
- Use exc_info=True in compensating-END error logging
- Export all exception types from copilotkit package root (__init__.py)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:23 +02:00
Maxim 62a3164aab fix(sdk): add @returns JSDoc and compensating-END test coverage
Add missing @returns tag to JS copilotkitEmitToolCall JSDoc, and add
4 tests for the AG-UI compensating TOOL_CALL_END error-recovery path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:23 +02:00
Maxim be9b60c8a9 fix(sdk): harden AG-UI dispatch, add exception hierarchy, fix docstrings
Address code review findings:
- Wrap AG-UI tool call dispatch in try/except with compensating
  TOOL_CALL_END to prevent clients hanging on partial emission
- Reject non-dict/non-str args at the dispatch layer (lists, ints, None)
- Guard against None event value before calling .get()
- Fix docstring examples that reuse variable names (won't compile)
- Introduce CopilotKitError base class; all exceptions now inherit from
  it; CopilotKitMisuseError inherits from both CopilotKitError and
  ValueError
- Add missing validation tests for name and args across LangGraph and
  CrewAI Python variants, plus AG-UI dispatch edge cases

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:22 +02:00
github-actions[bot] d5cc135c5c style: auto-fix formatting 2026-05-20 00:18:22 +02:00
Maxim 9cb8996056 fix(sdk): harden validation, error types, and dispatch safety across SDKs
Address code review findings: stop mislabeling dispatch errors as
CopilotKitMisuseError in JS (let them propagate naturally), add
CopilotKitMisuseError(ValueError) to Python SDK, pre-serialize args
in AG-UI handler to prevent partial event emission, align whitespace
validation across all SDKs and the dispatch layer, tighten JS args
type to Record<string, unknown>, and add comprehensive negative tests
for AG-UI dispatch validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:21 +02:00
github-actions[bot] 6fb417a90a style: auto-fix formatting 2026-05-20 00:18:21 +02:00
Maxim 50301b7bf0 fix(sdk): restore error type, rename options.id, add validation parity
- Restore CopilotKitMisuseError for dispatch failures in JS (was bare Error)
- Rename JS options.id to options.toolCallId for cross-SDK naming parity
- Add name/args validation to Python LangGraph and CrewAI variants
- Add defensive field validation in AG-UI dispatch handler
- Add missing CrewAI whitespace-only ID test
- Add JS dispatch failure test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:21 +02:00
Maxim 09ede29d58 fix(sdk): align whitespace validation, improve error handling and docs
Align JS whitespace-only ID rejection with Python (.trim()), show
returned ID in docstring examples, strengthen CrewAI test assertions
to verify event payloads structurally, and stop miscategorizing
dispatch errors as CopilotKitMisuseError (preserve original stack).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:20 +02:00
github-actions[bot] d2070b7b5f style: auto-fix formatting 2026-05-20 00:18:20 +02:00
Maxim c7693e938e fix(sdk): validate id param, rename to tool_call_id, use options bag in JS
Address review feedback on copilotkit_emit_tool_call:
- Add non-empty string validation for the tool call ID in all 3 SDKs
- Rename Python `id` param to `tool_call_id` to avoid shadowing the builtin
- Refactor JS 4th positional arg to options bag `{ id?: string }` for extensibility
- Document that the ID is also used as parentMessageId in AG-UI events
- Add JS tests for the new parameter (generated ID, custom ID, validation)
- Add Python validation tests (empty string, whitespace rejection)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:20 +02:00
Maxim 865991b463 feat(sdk): add optional id parameter to copilotkit_emit_tool_call
Allow callers to supply a custom tool call ID for correlation,
idempotency, and observability. Falls back to uuid4 when omitted.
Applied consistently across Python LangGraph, Python CrewAI, and JS SDK.
Also returns the tool call ID from all variants for downstream reference.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:19 +02:00
tylerslaton efae3dfb5b chore: release monorepo v1.57.3 2026-05-19 15:59:44 +00:00
Claude ce3084700c fix(release): swallow tanstack/virtual rAF teardown error in perf test
The release-PR workflow's pre-commit hook ran the full test suite and
failed because @tanstack/virtual-core 3.13.18 has a latent bug — its
scrollToIndex schedules a nested rAF that calls
`this.targetWindow.requestAnimationFrame(verify)` with no null-check.
The virtualizer's cleanup nulls `targetWindow` on React unmount, so the
queued rAF fires post-unmount and throws. All 1170 tests passed, but
vitest exited non-zero from the unhandled error.

Wrap rAF on both globalThis and window (separate bindings in
vitest+jsdom; tanstack uses `targetWindow.rAF` which resolves to
`window.rAF`) so callbacks hitting this specific error are swallowed.

Also fix the lint-fix lefthook command — `[ -n "{staged_files}" ]`
broke on multi-file expansion ("[: <path>: unexpected operator")
because lefthook interpolates files as space-separated words, not a
quoted string. Use `set --` to put them in positional args.
2026-05-19 15:28:07 +00:00
Tyler Slaton ca86c3623e chore(vue): bump package version to match mono-repo
Signed-off-by: Tyler Slaton <tyler@copilotkit.ai>
2026-05-18 21:21:05 -07:00
Austin Merrick 784b365d4f feat(react-core): forward followUp option through useComponent 2026-05-18 10:53:20 -07:00
Tyler Slaton 3db4f85d6d Revert "fix(web-inspector): polyfill localStorage in vitest env for Node 22.4+"
This reverts commit 63d1d9e02c.
2026-05-15 15:56:18 -07:00
Tyler Slaton b5d59e72a8 feat(showcase/shell-dojo): category headers in sidebar + rename built-in agent (#4823)
## Summary

Two small dojo design tweaks, plus an unrelated test fix required to
commit.

**Dojo sidebar — categories as headers**
(`showcase/shell-dojo/src/app/page.tsx`)
- Replace the single static "Demos" label with the feature category
names already present in the registry, so navigation reflects how demos
are grouped instead of presenting one flat list (Dev Ex, Chat & UI,
Platform, Controlled Generative UI, …).
- Bump shared `SectionTitle` to 11px / weight 600 / primary text color
for a touch more prominence. Affects the "Integrations" and "View"
headers above as well — consistent treatment across all sidebar
sections.

**Built-in agent name**
(`showcase/integrations/built-in-agent/manifest.yaml`)
- Renamed "Built-in Agent (TanStack AI)" → "CopilotKit Built-in Agent"
in both display name and description, so users aren't pushed to think
about the LLM backend in the integration name. (Note: the internal
source file `src/lib/factory/tanstack-factory.ts` is unchanged — that's
a real filename surfaced in the code viewer; renaming it is a bigger
refactor.)

**Test fix — vitest localStorage polyfill** (`packages/web-inspector/`)
- Pre-existing failure on `main`: Node 22.4+ ships an experimental
built-in `localStorage` global that is installed before vitest's jsdom
env runs, leaving `window.localStorage` as an uninitialized stub. All 22
telemetry persistence tests crash with `window.localStorage.clear is not
a function` on Node 25.
- Added `vitest.setup.ts` that installs a minimal in-memory `Storage`
shim on `globalThis.{localStorage,sessionStorage}`. Works on Node
18/20/22/25+ without depending on `--no-experimental-webstorage`. All 29
tests now pass on Node 25.
- This is in its own commit (`fix(web-inspector): …`) so it's easy to
cherry-pick out if you'd prefer it as a separate PR.

## Test plan
- [ ] Visual review of dojo sidebar at `localhost:3001` — categories
render as headers above their demos
- [ ] Built-in agent appears as "CopilotKit Built-in Agent" in the
integration dropdown
- [ ] `pnpm nx run @copilotkit/web-inspector:test` passes on Node 25
- [ ] Full lefthook pre-commit passes (already verified locally on both
commits)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-15 10:22:06 -07:00
Alem Tuzlak 6d49ecbb7b fix(showcase, runtime): subagents fixtures, voice mic format, fine-grained shared-state gating
Three follow-ups on top of PR #4837 that I had on the same branch but
didn't make it into the squash merge.

1. **packages/runtime: stamp `audio/webm` on empty-type Blobs in the
   transcription handler.** Browser MediaRecorder writes the audio as
   webm/opus, but the Blob's `type` field is often empty by the time it
   hits the server. `isValidAudioType` lets empty / octet-stream through
   for compatibility, but OpenAI Whisper then rejects the upload with
   `502 Invalid file format. Supported formats: ['flac', 'm4a', 'mp3',
   'mp4', 'mpeg', 'mpga', 'oga', 'ogg', 'wav', 'webm']` because it
   can't pick a decoder. Reconstructing the File with an explicit
   `audio/webm` type (and a `.webm` filename fallback) makes Whisper
   accept the bytes that were already valid. Monorepo-wide — applies to
   every integration using `/api/copilotkit-voice/transcribe`.

2. **showcase/aimock/feature-parity.json: port 12 subagents fixtures
   from d5-all.json** so the three pills (cold-exposure blog, LLM
   tool-calling explanation, reusable-rockets summary) work in
   production. d5-all.json already has the full research → writing →
   critique chain with substantive content; feature-parity only had the
   single LP remote-work pill. Production aimock loads both files but
   any case where feature-parity wins first-match needs the same
   content. Verbatim port — no fabricated text. Net result: no more
   `[sub-agent error] the writing agent...` on the demo's pills.

3. **showcase/aimock both files: scope shared-state-read-write Greet +
   Plan-a-weekend fixtures with a true all-defaults systemMessage
   gate.** The PR #4837 gate (`systemMessage: "tone: casual"`) only
   caught tone changes — name / language / interests changes still hit
   the canned fixture. Replaced with a two-element array gate (aimock
   supports all-present substring matching, verified in
   `/app/dist/router.js`):
     - `preferences:\n- Preferred tone: casual\n` — breaks if name is
       set (Name line inserts between signature and tone) or tone changes.
     - `- Preferred language: English\nTailor every response` — breaks
       if language changes or interests are added (Interests line
       inserts between language and Tailor).
   With `--provider-gemini` already wired in both local docker-compose
   and Railway prod, any state change now proxies to real Gemini and
   returns a personalised reply.

4. **showcase/aimock/feature-parity.json: re-remove bare 'plan' /
   'steps' / 'mars' / 'dashboard' / 'report' substring catch-alls + the
   bare 'alice' / 'Alice' fixtures.** These were removed in commit
   `ddc2e179` on the PR #4837 branch but didn't survive the squash
   merge, so they're back in main and still hijacking hitl-in-app
   downgrade-#12346 ('plan'), shared-state-rw weekend pill ('plan'),
   subagents 'rockets' pills, hitl-in-chat Schedule-1:1 with Alice
   ('alice'). Replace the alice pair with a single scoped
   `Hi, my name is Alice` fixture for the showcase-assistant
   introduction flow.

Local verification:
- `bin/showcase test google-adk --d5` → 38/38 green, 165s.
- Paired curl on shared-state-read-write:
  - Default state → canned fixture ("Hi — I'm your shared-state co-pilot…")
  - `name=alem` → real Gemini ("Hi there! …")
  - `interests=[Cooking, Travel]` weekend pill → real Gemini ("Hey
    there! Since you're into cooking and travel, how about a weekend
    plan that combines both?")

Production deploys this PR will pick up the aimock fixture changes
(prod loads feature-parity.json from GitHub raw at boot — no image
rebuild needed for that file) plus the runtime change once the
packages/runtime build is republished.
2026-05-15 15:57:31 +02:00
Atai Barkai 11db8e89bf refactor(showcase/shell-dojo, web-inspector): post-review cleanup
Findings from a self-review pass on this PR:

- code-block.tsx: hoist the seven per-row inline-style objects to module
  scope so the file-render hot path stops re-allocating ~3 fresh objects
  per line per render. ~500-line demos previously allocated ~1.5k style
  objects on every parent re-render.
- page.tsx URL-sync effect: add a same-value guard before
  history.replaceState so unrelated re-renders don't write the same
  query string back to the address bar.
- page.tsx FileTreeRow: collapse the color ternary chain — both selected
  and highlighted leaves resolve to the same primary color, so
  `isSelected || isHighlighted ? primary : disabled` reads cleaner than
  the nested `?:?:`.
- page.tsx: trim the restated WHAT-comment above the reset-on-demo
  effect (the function body already says what the comment said).
- vitest.setup.ts MemoryStorage: coerce keys in getItem/removeItem to
  match setItem and the real Storage spec (all key args coerce to string).

Deferred to a follow-up PR (would also touch showcase/shell/* and
showcase/shell-docs/*): hoisting `escapeHtml` (5 copies in the repo
today), the hljs `try { highlight } catch { escapeHtml }` pattern (also
copied), and the file-tree build/sort utilities the dojo duplicates from
showcase/shell/.../code/page.tsx.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:16:42 -07:00
Atai Barkai 63d1d9e02c fix(web-inspector): polyfill localStorage in vitest env for Node 22.4+
Node 22.4+ ships an experimental built-in `localStorage` global that is
installed before vitest's jsdom environment runs, leaving
`window.localStorage` as an uninitialized stub without `getItem` /
`setItem` / `clear`. The telemetry persistence tests all crash with
"window.localStorage.clear is not a function" on Node 25.

Add a vitest setup file that installs a minimal in-memory `Storage`
shim on `globalThis.{localStorage,sessionStorage}` so tests behave the
same on Node 18/20/22/25+ without depending on
`--no-experimental-webstorage`. All 29 web-inspector tests now pass on
Node 25.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:16:09 -07:00
Jordan Ritter b6ad624c94 style: apply formatter to vue package and other unformatted files 2026-05-13 17:06:47 -07:00
Jordan Ritter 99ed0c7c95 fix(vue): use absolute GitHub URLs in README for npm compatibility 2026-05-13 16:54:42 -07:00
Tyler Slaton cf0b032d58 chore: release monorepo v1.57.2 (#4787)
## Release monorepo v1.57.2

**Scope:** `monorepo` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.57.2`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.57.2`
   - Creates git tag `monorepo/v1.57.2`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
2026-05-13 16:43:11 -07:00
Tyler Slaton 74447ffd66 fix(vue): CR correctness fixes for v1 hooks and A2UI catalog
Fix use-copilot-action and use-copilot-readable v1 hook
implementations and A2UI catalog registration logic based
on code review findings.
2026-05-13 15:50:13 -07:00
Jordan Ritter a187e6b64c fix(react-core): fix flaky CopilotChatPerf e2e test
Harden rAF cleanup and timing assertions in the performance
test to prevent intermittent failures on Node 20.
2026-05-13 15:50:13 -07:00
Jordan Ritter 91dd4b13fa feat(vue): add v1 wrappers, A2UI Vue-native renderer, and
CR parity fixes

V1 CopilotKit.vue provider wrapper with backward-compatible
API, A2UI adapter/surface/catalog context/built-in tool-call
renderer for Vue-native rendering, capability and custom
message hooks, config allowlist and release config updates.
2026-05-13 15:50:13 -07:00
enekesabel 913c36b8b5 test(vue): add comprehensive test suite
Unit, integration, and e2e tests covering hooks, components,
providers, types, and utilities with mock agent context,
mount helpers, and web-inspector stubs for full React
parity verification.
2026-05-13 15:50:12 -07:00
enekesabel 90b3c2f0c0 feat(vue): implement providers, types, lib, and utility
components

CopilotKit and chat configuration providers with injection
keys, type definitions for tools/HITL/interrupts/renderers,
HTML processing and transcription utilities, inspector,
license warning, activity renderers, and barrel exports.
2026-05-13 15:50:12 -07:00
enekesabel 28d07ccaa4 feat(vue): implement chat components with React parity
Full chat UI component suite: CopilotChat, CopilotPopup,
CopilotSidebar, message views, suggestion pills, toggle
buttons, audio recorder, tool calls view, modal headers,
welcome screens, and auto-scroll normalization.
2026-05-13 15:50:12 -07:00
enekesabel 63b23f9c1f feat(vue): implement core hooks and composables
Vue 3 composition API hooks matching React hook parity:
agents, attachments, suggestions, frontend tools, HITL,
interrupts, threads, keyboard/katex utilities, and
pin-to-send.
2026-05-13 15:50:12 -07:00
enekesabel 92c0f0ec25 feat(vue): add @copilotkit/vue package scaffolding and config
Package skeleton with build tooling (Vite, Vitest, ESLint),
TypeScript configuration, styles, workspace integration, and
documentation scaffolding.
2026-05-13 15:50:11 -07:00
Jordan Ritter 47ceb39588 test(react-native): comprehensive test suite — 155 tests across 10 files
useAttachments unit tests, CopilotChat attachment integration,
Popup/Sidebar prop forwarding, headless integration, full
pick-to-submit flow.
2026-05-13 15:39:00 -07:00
Jordan Ritter 20184e1324 feat(react-native): export full v2 API surface with attachment support
15+ type re-exports from headless layer. expo-document-picker and
expo-file-system as optional peer deps. InterruptEvent,
ReactFrontendTool, ReactHumanInTheLoop added to headless.ts.
2026-05-13 15:38:55 -07:00
Jordan Ritter 018a696c05 feat(react-native): add useAttachments hook with NativeFileInput type
React Native attachment hook using expo-document-picker and
expo-file-system. Replaces web FileReader/HTMLInputElement APIs.
2026-05-13 15:38:49 -07:00
Jordan Ritter ec5ef21f9e feat(react-native): add CopilotChat with attachment support and CopilotPopup
CopilotChat: headless chat with useAttachments integration,
useCopilotChatContext hook, submitMessage with InputContent[].
CopilotPopup: floating overlay with FAB, attachment prop forwarding.
2026-05-13 15:38:45 -07:00
Maxim c3959a57a0 chore(react-native): build config and README updates 2026-05-13 15:38:40 -07:00
Maxim d09618a00e feat(react-native): add CopilotModal and CopilotSidebar components 2026-05-13 15:38:34 -07:00
Maxim 73431de037 fix(react-native): streaming crash fix and agentId consistency
XHR callbacks deferred to JS thread to prevent iOS crash. agentId
prop added for consistency with web SDK. Dynamic headers function
and credentials prop on CopilotKitProvider.
2026-05-13 15:38:30 -07:00
tylerslaton 1b14504788 chore: release monorepo v1.57.2 2026-05-13 00:40:27 +00:00
Jordan Ritter f06cca0cb1 feat: add X-AIMock-Strict header propagation across SDKs and integrations (#4773)
## Summary

Per-request `X-AIMock-Strict` header propagation through the full
CopilotKit stack — from Playwright browser contexts through AG-UI to
outgoing LLM API calls. Enables the same aimock instance to serve both
strict fixture-only probes and live demo traffic simultaneously.

- **Harness**: All probe browser contexts send `X-AIMock-Strict: true`
via `extraHTTPHeaders` (9 sites across 5 driver files)
- **Python SDK**: `ContextVar` + `httpx` event hook — incoming
`x-aimock-*` headers forwarded to outgoing LLM calls automatically via
FastAPI integration (covers 12/17 showcase integrations)
- **TypeScript SDK**: `AsyncLocalStorage` + per-call headers merged into
`wrapModelCall` middleware (covers 3 more, 15/17 total)
- **.NET integration**: `AsyncLocal` + ASP.NET middleware +
`PipelinePolicy` stopgap — all 12 agent factories wired through
`CreateOpenAIClientOptions()`. TODO markers for migration to
copilotkit-sdk-dotnet when Microsoft delivers it.
- **Java/Spring integration**: `InheritableThreadLocal` +
`HandlerInterceptor` + `ClientHttpRequestInterceptor` + WebClient
`ExchangeFilterFunction` — covers both RestClient and WebClient paths

## Test plan

- [x] Python SDK: 14 new tests (ContextVar isolation, httpx hook
injection, key lowercasing, warning on bad client), 116 total pass
- [x] TypeScript SDK: 8 new tests (AsyncLocalStorage isolation, header
filtering, concurrent requests), 92 total pass
- [x] Harness: 1590 tests pass (1 pre-existing failure unrelated)
- [x] CR converged: 2 rounds × 14 agents, 6 bucket(a) findings fixed, 0
remaining
2026-05-12 16:54:21 -07:00
github-actions[bot] fd5e8e7c20 style: auto-fix formatting 2026-05-12 16:33:44 +00:00
Alem Tuzlak cdb5f44fb5 test(reasoning-chain): add regression coverage at runtime, harness, and e2e layers
Three layers of regression guards for the runtime reasoning-role filter and
the chained demo behavior:

1. Runtime unit test — packages/runtime/.../run-message-filtering.test.ts:
   - Verifies `LangGraphAgent.run` strips `role:"reasoning"` from
     `input.messages` before delegating to super.run.
   - Verifies user/assistant/system/tool messages pass through in order.
   - Verifies empty + missing messages arrays are tolerated.
   - Verifies pre-existing forwardedProps.streamSubgraphs default + override
     behavior is preserved.
   - 6/6 tests pass against the runtime package's vitest config.

2. D5 harness probe — showcase/harness/.../d5-tool-rendering-reasoning-chain.ts:
   - Expanded from one chained turn (flights→weather) to all three chained
     pills in a single thread (stocks AAPL→MSFT, dice d20→d6, flights→weather).
   - This is the canonical multi-pill regression at the harness layer:
     without the runtime reasoning-role filter, the second pill would crash
     before the model was called.
   - Each turn asserts the per-turn delta of reasoning-block mounts (idx+1),
     the minimum card count for each tool group, and unique transcript
     substrings that scope to that turn.

3. Playwright e2e spec — showcase/integrations/langgraph-python/tests/e2e/
   tool-rendering-reasoning-chain.spec.ts:
   - Mirrors the pattern of the sibling tool-rendering-default-catchall spec
     (notably its multi-pill regression at lines 162-212).
   - Page-loads test verifies the 3 pills mount and no cards leak from a
     prior session.
   - One test per chained pill (stocks, dice, flights+weather) asserts the
     full chain renders with reasoning-block + correct per-tool cards +
     narration matching the aimock fixture text.
   - Sequential-pills regression test clicks all 3 pills in one thread,
     asserts each chain renders independently AND the reasoning-block count
     increases monotonically across turns.

Agent: extend `get_stock_price` to accept optional `price_usd` and
`change_pct` arguments (mirrors the basic tool-rendering agent's signature
introduced in #4770). The aimock fixtures script the chained AAPL/MSFT
comparison by passing deterministic prices via these args; without the
wider signature, pydantic rejects the tool call and the card never mounts.

The runtime unit test is the strongest guard — it would catch any
regression on the role-filter logic without depending on the full Docker
stack. The harness probe and Playwright spec catch end-to-end regressions
in the canonical CI environment.
2026-05-12 18:29:27 +02:00
Alem Tuzlak e4764324c5 fix(runtime/langgraph): filter reasoning-role messages before AG-UI converter
`@ag-ui/langgraph`'s message converter handles only user/assistant/system/tool
roles and throws `"message role is not supported."` on anything else. Agents
that stream reasoning summaries (OpenAI Responses API + `reasoning={summary:
"detailed"}`) emit AG-UI messages with `role: "reasoning"` that the AG-UI
client replays in the next turn's `input.messages`; the converter then crashes
before the model is ever called and the second pill click in a multi-turn
thread produces an `INCOMPLETE_STREAM` error.

Strip `role: "reasoning"` from `input.messages` inside CopilotKit's
LangGraphAgent.run subclass before delegating to super. This is the narrowest
fix at the runtime/AG-UI boundary — only the inbound message list is filtered,
the outbound event stream still carries reasoning summaries to the client, so
the `<ReasoningBlock>` slot continues to render on the active turn.
2026-05-12 17:21:21 +02:00
github-actions[bot] 6931bc914c style: auto-fix formatting 2026-05-12 03:56:58 +00:00
Jordan Ritter a260ffe106 feat: widen header forwarding from x-aimock-* to all x-* headers
Matches the CopilotKit runtime's extractForwardableHeaders() which
already forwards all x-* prefixed headers. Enables any custom
x-* header to propagate from browser through AG-UI to LLM calls.
2026-05-11 20:55:33 -07:00
github-actions[bot] d54ec8b1d6 style: auto-fix formatting 2026-05-11 21:33:25 +00:00
Martha Schumann bd968fabaf fix(inspector/telemetry): fix banner_viewed race and dead opt-out check
- Defer trackBannerViewed until runtime connection is established via
  pendingBannerViewed + flushPendingBannerViewed(), preventing the race
  where the CDN response beats the /info handshake and fires the event
  before core.telemetryDisabled is known
- Remove dead isTelemetryOptedOut() short-circuit from track(); opt-out
  is enforced at call sites via core.telemetryDisabled, not localStorage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 14:31:36 -07:00
Martha Schumann aee390ab4d refactor(inspector): remove internal gap labels from code comments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 15:43:17 -05:00
Martha Schumann fa75abf23c fix(inspector/telemetry): address code review findings
- Don't fire banner_clicked on copy-button clicks (move track call to
  the non-copy-button branch of handleAnnouncementContentClick)
- Defer ensureTelemetryDistinctId() to runtime connection so no UUID
  is written to localStorage when COPILOTKIT_TELEMETRY_DISABLED is set
- Remove setTelemetryOptOut re-export from telemetry.ts (no production
  caller; tests already import directly from persistence.ts)
- Fix docs: replace Privacy tab toggle description with env var opt-out

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 15:43:17 -05:00