- 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>
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.
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.
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>
- 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>
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).
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>
Extract renderAndWarmCache() and installBoundingRectSpy() helpers to
eliminate duplicated setup across 4 tests. Add justifying comments on
all necessary type casts (MockResizeObserver, CSSStyleDeclaration,
TextMetrics, canvas getContext overloads).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Self-inflicted resizes (compact↔expanded) were clearing the cache before
the ignoreResizeRef guard, forcing a full re-measurement on the very next
keystroke. Move the guard ahead of invalidation so layout toggles keep the
cache warm — container dimensions don't change during these transitions.
Also reject compactWidth <= 0 from being cached, preventing a zero-width
entry from silently disabling text-width expansion until the next resize.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Merge two ResizeObserver instances into one; inspect entry.target to
decide cache invalidation. Eliminates the ignoreResizeRef race where
two observers could consume the guard independently.
- Move textarea font read out of the cache into evaluateLayout so CSS/
theme changes are picked up without a container resize.
- Return { compactWidth } | null from updateContainerCache; callers use
the value directly instead of the two-step "call then check ref" pattern.
- Hoist cache invalidation above the ignoreResizeRef guard to remove
duplicated containerCacheRef.current = null.
- Add zero-width guard in updateContainerCache to avoid caching
compactWidth: 0 when the container is hidden.
- Replace vi.fn() as any ResizeObserver mock with a class-based
MockResizeObserver that tracks observed targets, enabling per-target
resize triggers in tests.
- Fix empty-font and null-canvas tests to assert data-layout="compact"
(verifying the fallback path) instead of just non-null.
- Add tests: warm-cache keystroke perf (getBoundingClientRect not called),
textarea-only vs container resize invalidation, ignoreResizeRef + cache
invalidation during layout toggle.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix all doc imports to use @copilotkit/runtime/v2 (symbols only
exported from v2 entry point)
- Replace v1 copilotRuntimeNextJSAppRouterEndpoint with v2 pattern
(CopilotRuntime + createCopilotEndpoint + InMemoryAgentRunner)
- Add warning callout on TanStack reasoning example (reasoning events
not surfaced by TanStack converter)
- Fix randomUUID imports in converters: use @copilotkit/shared instead
of Node.js crypto to match codebase convention
- Fix collectEvents timer leak in test-helpers.ts (add clearTimeout)
- Fix JSDoc/comments: convertInputToTanStackAI accurately describes
role allowlist, TanStackInputResult.messages comment updated
- Close TOCTOU window: set abortController synchronously before Observable
creation in classic run(), matching factory run() pattern (M3)
- Add concurrent run guard to classic run() (C1)
- Add threadId/runId to RUN_ERROR events in classic mode (I2)
- Check both 'output' and 'result' property names in classic tool-result (C2/M2)
- Add try/catch around JSON.stringify in classic tool-result (I4/M2)
- Add undefined guards before emitting state snapshot/delta events (I3)
- Guard assignToolsToAgents against factory-mode agent configs (M1)
- Improve error handling in classic error case with proper fallback (C3)
- Improve TanStack converter TODO comment with known gap details (M5)
- Document @ts-expect-error on clone() middlewares access (S1)
- Add JSDoc to AgentFactoryContext.abortController (M4)
- Fix duplicate import and clean up react-router example
- Update docs AgentFactoryContext reference
- Add converter imports (convertAISDKStream, convertTanStackStream) to agent/index.ts
- Update canOverride() to return false for factory configs
- Add factory-path early return in run() that delegates to runFactory()
- Add private runFactory() method that handles aisdk/tanstack/custom factory configs
with full lifecycle management (RUN_STARTED, RUN_FINISHED, RUN_ERROR, abort support)
- Fix copilot-runtime.ts: change BuiltInAgentConfiguration["tools"] indexed access
types to BuiltInAgentClassicConfig["tools"] since tools only exist on classic configs
Source fixes:
- Fix TOCTOU race in concurrent run guard — set abortController
synchronously before Observable creation, closing the window where
two run() calls could both pass the guard
- Add JSON.stringify try/catch in TanStack TOOL_CALL_RESULT handler
(matching existing aisdk.ts protection against circular refs)
- Use role allowlist (user/assistant/tool) instead of denylist in
convertInputToTanStackAI to exclude activity/reasoning roles
- Change error+abort handler from break to return in aisdk converter
to stop processing after error during abort
- Fix version-pinned comments (remove "AI SDK 5.0" reference)
Test fixes:
- Add timedOut flag to collectEventsIncludingErrors to distinguish
hung observables from normal completion
- Add clearTimeout on success/error to prevent timer leaks
- Remove timing-dependent setTimeout in concurrent run guard test
Docs fixes:
- Split imports: copilotRuntimeNextJSAppRouterEndpoint from
@copilotkit/runtime, Agent/converters from @copilotkit/runtime/v2
- Fix forwardedProps example: use CopilotKit properties prop
- Fix useCopilotChat → useCoAgent for state management reference
- Fix model syntax colon → slash (openai/gpt-4o)
Critical fixes:
- Guard concurrent run() calls — throw if agent is already running
- Check both "output" and "result" properties on AI SDK tool-result events
for compatibility with older AI SDK versions
- Handle undefined/missing error in AI SDK error events with proper
Error wrapping instead of throwing undefined
Important fixes:
- Add TOOL_CALL_RESULT handling to TanStack converter (was silently dropped)
- Include threadId and runId in RUN_ERROR events for run correlation
- Guard state tool events (STATE_SNAPSHOT/STATE_DELTA) against undefined
snapshot/delta fields before emitting
- Wrap JSON.stringify in tool-result with try/catch to handle circular refs
- Fix collectEventsIncludingErrors to distinguish error vs normal completion
Test coverage:
- Add tests for convertInputToTanStackAI (message filtering, tool call
mapping, context injection, state serialization)
- Add tests for state management tool results in AI SDK converter
- Add tests for async factory (Promise-returning) paths
- Add tests for tool-result property compatibility (output vs result)
- Add tests for error event handling edge cases
- Add tests for concurrent run guard and RUN_ERROR correlation fields
- Replace flaky setTimeout-based abort test with signal-based sync
Other:
- Add exhaustiveness check (default: never) in config type switch
- Document clone() @ts-expect-error coupling with AbstractAgent.middlewares
- Fix docs: remove incorrect "v6" version reference, fix wrong hook name