Commit Graph

613 Commits

Author SHA1 Message Date
Claude ca2d081f8c fix: use preventScroll on focus calls so autoFocus opt-in doesn't scroll page
When users explicitly set autoFocus={true}, the textarea now focuses
with { preventScroll: true } so the page doesn't jump. Also applies
to the modal-open focus path. Added tests verifying default no-focus
behavior and that opt-in focus uses preventScroll.

https://claude.ai/code/session_01LPiJ8GcUNtWdS2W6MYSE4b
2026-04-05 00:39:36 +00:00
Martha Schumann 4a44b6641f fix(react-core): preserve assistant text when multiple tool calls wipe content in same turn (CPK-7154)
During streaming, the same message ID can arrive multiple times as tool calls are appended.
The previous "keep last" dedup lost any text content that was streamed before the first tool call,
because later entries carry empty content. Replace with a merge strategy: for assistant messages,
recover non-empty content from earlier occurrences while keeping the latest toolCalls accumulation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 09:17:13 -07:00
Claude f41133d356 fix: change autoFocus default to false in CopilotChatInput
Prevents the chat input from stealing focus on mount by default.
Users can opt-in via the autoFocus prop (e.g. input={{ autoFocus: true }}).

https://claude.ai/code/session_01LPiJ8GcUNtWdS2W6MYSE4b
2026-04-04 02:13:01 +00:00
Claude 7426486199 fix: remove scrollIntoView on chat input focus that forces page scroll
The v2 CopilotChatInput had a useEffect that called scrollIntoView()
whenever the textarea received focus. Combined with autoFocus defaulting
to true, this caused the entire page to scroll to the chat component on
load - the same bug that was previously fixed in v1.

https://claude.ai/code/session_01LPiJ8GcUNtWdS2W6MYSE4b
2026-04-04 02:07:38 +00:00
Martha Schumann 4bc77088b0 fix(chat): fix virtualization, slot memoization, and ToolMessage casts
- Change ScrollElementContext to carry HTMLElement | null state (not a ref)
  so CopilotChatMessageView re-renders reactively when the scroll container
  first mounts. Removes the one-shot useLayoutEffect that silently kept
  virtualization disabled in the default autoScroll path (hasMounted gate
  in ScrollView deferred the Provider past the one-shot read window).

- Lift resolveSlotComponent calls out of renderMessageBlock into useMemo.
  When a slot was passed as a CSS class string, resolveSlotComponent
  returned a new { className } object on every call, defeating
  MemoizedAssistantMessage's slotProps reference-equality check and
  causing all completed messages to re-render on every parent update.

- Add deduplicatedMessages.length to scrollToIndex deps so the virtualizer
  stays at the bottom as new messages arrive during streaming.

- Replace four as-any ToolMessage casts in the memoized comparator with
  typed inline type predicates using the ToolMessage import from @ag-ui/core.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 14:02:03 -07:00
Martha Schumann 95b3eabf0e chore(perf): remove perf page, bench file, and dev-only window globals
The /perf demo page and .bench.tsx file were useful during development but
add noise to the PR. Removing them keeps the diff focused on the library
changes. Also removes the __perfScrollEl / __perfMsgCount window globals
that only existed to serve the perf page's polling mechanism.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 13:24:33 -07:00
Martha Schumann 7184cfb855 Merge remote-tracking branch 'origin/main' into feat/CPK-7190-chat-performance 2026-04-03 13:21:52 -07:00
Martha Schumann 7b90bdb532 fix(chat): revert toolResultMap comparator — breaks HITL sequential tool-call rendering
The pre-computed toolResultMap in MemoizedAssistantMessage's comparator caused
HITL tests to fail: after responding to one tool call, the second tool call's
status would not transition from 'inProgress' to 'complete'.

Root cause: when executingToolCallIds context updates (removing the completed
tool call from the set), CopilotChatToolCallsView re-renders via useCopilotKit()
context subscription. At that point it holds stale `messages` props (MemoizedAssistantMessage
hasn't re-rendered yet), so messages.find(tc.id) returns undefined. The timing
window between the context update and the messages re-render caused the status
to briefly show inProgress. In the old code the same O(n) messages.filter() scan
was used, which is proven correct. Reverting to that approach.

Keeps all other perf improvements: deduplicatedMessages useMemo, virtualization,
resolveSlotComponent helper, NODE_ENV-gated dev globals.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 13:06:48 -07:00
Martha Schumann 848205f89b perf(chat): memoize dedup map, O(1) tool-result comparator, TanStack Virtual, perf page & tests
Addresses review findings from PR #3611:
- toolResultMap: pre-compute id→content Map via useMemo so MemoizedAssistantMessage
  comparator does O(k) lookups instead of O(n) linear scans
- resolveSlotComponent<T>() helper eliminates repeated slot-resolution boilerplate
- NODE_ENV gate on __perfMsgCount / __perfScrollEl (no production window pollution)
- hasScrolledToBottomRef → dep-based [shouldVirtualize, firstMessageId] in useLayoutEffect
- Merged duplicate virtual/flat render return paths; removed dead null-guards in comparator
- AssistantMessage type import + cast in fingerprint (CopilotChat.tsx)
- perf page: private → protected, lastScrollTop=NaN, STABLE_POLLS_REQUIRED constant,
  agent as any with version-mismatch comment (ag-ui 0.0.46 vs 0.0.48)
- snapshot test: act+tick flush instead of sentinel message (Observable subscription
  ends after RUN_FINISHED so new events are dropped)
- .bench.tsx extension comment: not picked up by vitest CI glob

Pre-existing test failures in use-human-in-the-loop.e2e.test.tsx (2 tests) and
@copilotkit/sqlite-runner + @copilotkit/runtime are on main; unrelated to this PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 12:42:47 -07:00
Maxim 208f9bc32f fix: restore .d.ts declaration files for legacy moduleResolution consumers
Copies .d.cts → .d.ts after each tsdown build so consumers on
moduleResolution "node" (e.g. DocuSign) can resolve types without
changing their tsconfig. Also points the "types" field back to .d.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:55:45 +02:00
Martha Schumann 468062c3c3 perf(react-core): add TanStack Virtual + two-phase animation measurement
- Add @tanstack/react-virtual to react-core deps; activate useVirtualizer
  in CopilotChatMessageView when message count exceeds 50 (VIRTUALIZE_THRESHOLD).
  Only visible items are mounted; total scrollable height is maintained via
  an absolutely-positioned container div.
- Add scroll-element-context.ts to pass the scroll container ref from
  CopilotChatView down to CopilotChatMessageView without circular imports.
- Expose window.__perfScrollEl (scroll container) and window.__perfMsgCount
  (committed message count) for programmatic perf measurement.
- Update /perf demo page with two-phase timing: phase 1 measures event emit
  time, phase 2 waits for all messages committed + scroll position stable
  (animation settled). PerfPanel now shows emit / render+anim / total.

Benchmark results (MacBook, dev build):
  Load 50  [anim]:    emit 305ms  render+anim 1433ms  total 1739ms
  Load 100 [anim]:    emit 752ms  render+anim 1578ms  total 2331ms
  Load 500 [anim]:    emit 14.2s  render+anim 1783ms  total 16.0s
  Load 50  [noAnim]:  emit 299ms  render+anim  182ms  total  481ms
  Load 100 [noAnim]:  emit 771ms  render+anim  161ms  total  931ms
  Load 500 [noAnim]:  emit 13.9s  render+anim  199ms  total 14.1s

Key findings:
- React render cost is now O(1) in message count (161-199ms flat).
  Virtualization fully decouples DOM work from history size.
- Animation (StickToBottom spring scroll-to-bottom) adds ~1.4-1.8s
  regardless of message count; this is a fixed cost on every history load.
- The remaining bottleneck for large histories is event emit time (~5.6ms
  per TEXT_MESSAGE_CHUNK through AbstractAgent). This is upstream of React
  and tracked separately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 11:52:19 -07:00
Tyler Slaton 180b719d50 Revert "fix: add types conditions to package exports for proper TypeScript resolution"
This reverts commit 499bca09ad.
2026-04-03 09:42:01 -07:00
Ran Shem Tov 6fa01fb8a1 test: add edge case coverage and fix auto-detect status check
- Fix fetchRuntimeInfoAutoDetect in agent.ts to use 2xx-only check
  (was checking only 404/405, now aligns with agent-registry.ts)
- Remove duplicate JSDoc block on fetchRuntimeInfoAutoDetect
- Add 7 edge case tests: 500/403/405/network-error/both-fail scenarios
- Add 4 tests for useSingleEndpoint->runtimeTransport ternary mapping
- Update Angular test stubs to use "auto" default (was "rest")

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:20:44 +02:00
Claude 0a65f70f85 feat: auto-detect single-endpoint transport from runtime info response
Instead of requiring users to explicitly set transport: "single", the
client now auto-detects the transport mode by trying REST (GET /info)
first and falling back to single-endpoint (POST with { method: "info" })
if the REST probe returns 404/405 or fails. The explicit flag is kept
for backward compatibility.

https://claude.ai/code/session_016xtYN15TY2BaBviryTcVyY
2026-04-03 15:20:44 +02:00
Martha Schumann f955dd37dd perf(react-core): reduce wasted re-renders in CopilotChat with 100+ messages
Replace full JSON.stringify(agent.messages) memo dep with a lightweight
fingerprint (length + last-id + last-content + last tool-call args) so only
the in-flight message is serialized on each render instead of the whole array.

Wrap deduplicatedMessages in useMemo([messages]) so the Map is not
reconstructed on every render cycle.

Add generateMessages(n) factory to test-helpers for perf-focused tests, a
vitest bench for the dedup map at 100/1000 messages, and three regression
tests that assert completed messages do not re-render when new messages or
state snapshots arrive.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 15:40:35 -07:00
Tyler Slaton 499bca09ad fix: add types conditions to package exports for proper TypeScript resolution
All @copilotkit/* packages were missing type declarations in their exports
map. This meant TypeScript couldn't resolve types for subpath imports like
@copilotkit/react-core/v2 without manual tsconfig paths workarounds
pointing to dist .d.ts files (which no longer exist after the tsup to
tsdown migration).

Uses nested conditional exports to map .d.mts for ESM and .d.cts for CJS
consumers, satisfying both attw and TypeScript module resolution under
nodenext and bundler modes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:56:09 -07:00
Maxim a2386017b4 Merge branch 'main' into feat/useagent-throttle-ms 2026-04-02 19:04:53 +02:00
Maxim 3f1c16881e fix: replace as any cast with typed RunAgentInput factory in throttle tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:46:35 +02:00
Maxim b2bc508f95 test: add missing throttleMs edge case coverage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:11:31 +02:00
Maxim c2dcee2751 fix: unify effectiveThrottleMs to return 0, upgrade validation to console.error
Also fixes JSDoc inaccuracies: documents trailing-edge window restart,
uses enum names instead of callback names, adds notificationThrottle
interaction note.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:06:58 +02:00
Maxim 9b6d444c43 fix: trailing edge restarts throttle window to prevent back-to-back renders
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:01:43 +02:00
Alem Tuzlak 401a27c981 fix: resolve rebase conflicts and format files
- Remove stale eslint-config-custom refs from package.json files
- Regenerate pnpm-lock.yaml
- Format agentcore and other files with oxfmt
2026-04-02 16:43:34 +02:00
Alem Tuzlak 79ce60c580 chore: migrate from eslint+prettier to oxlint+oxfmt
Replace eslint and prettier with oxlint and oxfmt for faster linting
and formatting across the monorepo. Remove all eslint and prettier
configs, dependencies, and related packages. Add .oxlintrc.json and
.oxfmtrc.json for the new tooling. Update CI workflows and lefthook
hooks accordingly. Reformat codebase with oxfmt.

https://claude.ai/code/session_01GMkSf29p78HuMR1mbXn8He
2026-04-02 16:39:05 +02:00
Maxim a4109ad3be refactor: enhance message handling in useAgent tests
- Introduced message factory functions to eliminate `as any` type assertions for message literals.
- Updated test cases to utilize the new message factories for improved clarity and type safety.
- Added helper functions for subscriber notifications to streamline test setup.

This refactor improves code readability and maintainability in the test suite for the useAgent hook.
2026-04-02 16:33:13 +02:00
Maxim d1357083da fix: harden throttleMs implementation from code review
- Replace Date.now()-based throttle with flag-based leading+trailing
  pattern that is immune to wall-clock jumps
- Wrap throttleMs validation in useMemo to warn once per value change
  instead of on every render
- Remove phantom AbstractAgent.notificationThrottleMs JSDoc reference
- Reorder cleanup to clear timer before unsubscribing for safety
- Add tests for trailing-edge data freshness, timer precision, and
  dynamic throttleMs prop changes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:13:56 +02:00
Maxim f2b148c0d2 fix: improve throttleMs validation, simplify handlers, add invalid-input tests
- Fix JSDoc to accurately describe behavior for negative/non-finite values
- Remove NODE_ENV guard so console.warn fires in all environments
- Use derived effectiveThrottleMs instead of mutating destructured param
- Simplify handler wrappers: direct references instead of arrow wrappers
- Remove stale comment about content stripping
- Add parameterized tests for invalid throttleMs (NaN, Infinity, -1, -Infinity)
- Fix misleading test comment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:44:13 +02:00
Maxim 3cdaaf089d fix: consolidate throttleMs into single useEffect, add input validation and edge-case tests
Addresses code review findings:
- Merge two separate useEffect hooks into one to eliminate dual-subscription
  race window and simplify cleanup
- Add active boolean guard to prevent forceUpdate after unmount/re-run
- Validate throttleMs input (reject NaN, Infinity, negatives with dev warning)
- Expand JSDoc with scope, constraints, and notificationThrottleMs interaction
- Replace JSON.stringify(updateFlags) with direct ref in effect deps
- Strengthen unmount test with render counter instead of not.toThrow()
- Add 5 new test cases: explicit zero, rapid burst, new cycle after trailing,
  updates excluding OnMessagesChanged, subscription cleanup verification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:34:43 +02:00
Maxim 30916a6ab7 feat: add throttleMs option to useAgent for streaming render throttling
Adds optional `throttleMs` parameter to `useAgent()` that coalesces
rapid onMessagesChanged notifications (per-token TEXT_MESSAGE_CHUNK
events) into fewer React re-renders using a leading+trailing throttle.

- throttleMs=0 (default): exact current behavior, zero overhead
- throttleMs>0: only onMessagesChanged is throttled; onStateChanged
  and onRunStatusChanged always fire immediately
- Leading+trailing: first call immediate, last call guaranteed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:09:17 +02:00
Claude 0d9e3b88f6 chore(post-release): update version to 1.55.0-next.8
The previous publish workflow released 1.55.0-next.8 to npm but the
post-release commit failed to push to main (blocked by branch
protection). This applies the version bumps and pre.json updates that
the workflow would have committed, unblocking future releases.

https://claude.ai/code/session_01N8sLK9h9p6FdRjyHqzKzVV
2026-04-02 02:23:27 +00:00
Claude d55ce2c87b fix: add React keys to CopilotMessages children to suppress warning
CopilotMessages received an array of children (memoizedChildren +
RegisteredActionsRenderer) without keys, causing a React "unique key prop"
warning in dev mode. Wrap memoizedChildren in a keyed Fragment and add a
key to RegisteredActionsRenderer.

https://claude.ai/code/session_01N8sLK9h9p6FdRjyHqzKzVV
2026-04-02 01:32:52 +00:00
Alem Tuzlak 2f38e945e2 feat(react-core): add useCapabilities hook 2026-04-01 18:34:20 +02:00
Alem Tuzlak 232c9eb994 chore: bump @ag-ui/core and @ag-ui/client to 0.0.49 2026-04-01 18:18:40 +02:00
Martha Schumann 092956d299 style: fix prettier formatting across all changed files 2026-03-30 13:09:10 -07:00
Martha Schumann 6395a9a42d style: fix prettier formatting in CopilotChatMessageView after merge 2026-03-30 13:04:44 -07:00
Martha Schumann 83f58ee3de Merge branch 'main' into fix/cpk-7155-thread-shared-state
Incorporates the V1/V2 flat package consolidation (96885b595). All our
thread-isolation changes auto-merged to the new package paths. Three
content conflicts resolved (import paths updated from @/ aliases to
relative paths and @copilotkitnext/* to @copilotkit/*):
- packages/react-core/src/v2/hooks/use-agent.tsx
- packages/react-core/src/v2/hooks/use-render-custom-messages.tsx
- packages/react-core/src/v2/components/chat/CopilotChatMessageView.tsx

File location conflict resolved: use-agent-thread-isolation.test.tsx
moved from packages/v2/react/... to packages/react-core/src/v2/...
2026-03-30 12:33:16 -07:00
github-actions[bot] a1edf59eae chore(post-release): update version to 1.55.0-next.7 2026-03-29 00:19:22 +00:00
Claude 1ceb963a84 Revert "fix: resolve changeset version errors from stale @copilotkitnext package refs"
This reverts commit 1f6ae0d629.
2026-03-28 17:04:55 -07:00
Claude 369266f1be fix: resolve changeset version errors from stale @copilotkitnext package refs
After the V1/V2 consolidation merge, several changesets still referenced
old @copilotkitnext/* package names that no longer exist. Fixed package
references and ran changeset version to apply pending version bumps.

https://claude.ai/code/session_01A5aahBWFTmLPR3xZSeh4SD
2026-03-28 17:04:55 -07:00
Tyler Slaton 96885b5959 refactor: consolidate V1/V2 packages into flat @copilotkit/* structure
Flatten all packages from packages/v1/* and packages/v2/* into packages/* —
every package now lives directly under the @copilotkit/ scope with no v1/v2
subdirectories.

- Move all v1 packages (react-core, react-ui, runtime, shared, etc.) from
  packages/v1/* to packages/*
- Absorb v2 react code into packages/react-core/src/v2/ (exported via /v2 subpath)
- Absorb v2 agent code into packages/runtime/src/agent/ (exported via /v2 subpath)
- Move v2 packages (core, angular, demo-agents, etc.) to packages/*
- Replace all @copilotkitnext/* imports with @copilotkit/* equivalents
- Keep @copilotkitnext/angular as the sole exception (angular remains on next)
- Update CI workflows, renovate config, release scripts for flat structure
- No public API surface changes — all exports fields are preserved

Co-authored-by: Alem Tuzlak <t.zlak@hotmail.com>
Signed-off-by: Tyler Slaton <tyler@copilotkit.ai>
2026-03-28 16:45:10 -07:00
Atai Barkai 5f3727dde8 move to CopilotKit subdirectory
.
2023-08-22 23:09:55 -07:00
Atai Barkai 853a2d7bad vercel.ai —> ^2.2, openAI —> ^4.0, dropped ‘openai-edge’ package
fix route.ts for opneai v4
2023-08-20 03:52:17 -07:00
Atai Barkai 76c97a1011 throw errors to reduce chance of shenannigans 2023-08-18 18:53:19 -07:00
Atai Barkai 7f80cefaaf minor
.
2023-08-18 18:40:05 -07:00
Atai Barkai 62c8375153 tree printing changes 2023-08-18 05:28:20 -07:00
Atai Barkai c5de7de1de add documentation 2023-08-15 06:30:57 -07:00
Atai Barkai c0e3c3ec53 when we can simply pass ‘default value’ by passing undefined, no need to re-specify the defualt value 2023-08-15 06:25:09 -07:00
Atai Barkai 1ab4b98b98 minor rearrange and comment for clarity 2023-08-15 06:07:24 -07:00
Atai Barkai 2b46479c03 copilot context takes categories, to allow for filtering of content 2023-08-14 22:50:40 -07:00
Atai Barkai 452c5eb20c global context now takes categories in initialization and in printing 2023-08-14 22:21:20 -07:00
Atai Barkai 4f19bd7bf8 publish packages 2023-07-18 23:32:25 -07:00