Render a per-turn persistent intelligence indicator that stays stable
across multi-step turns and settles into a "finished" tag. Splits the
component into IntelligenceIndicator (logic) + IntelligenceIndicatorView
(presentation), wires it into CopilotChatView / CopilotChatMessageView,
adds the slot styles to globals.css, and a Storybook story plus
timer-free logic tests.
## What does this PR do?
Adds a `position?: \"left\" | \"right\"` prop to the v2 `CopilotSidebar`
(and the underlying `CopilotSidebarView`), letting consumers anchor the
sidebar to either side of the viewport. Defaults to `\"right\"` so
existing usage is unchanged.
```tsx
<CopilotSidebar position=\"left\" />
```
### What changes when `position` flips
- **Anchor:** `cpk:right-0` ↔ `cpk:left-0`
- **Border side:** `cpk:border-l` ↔ `cpk:border-r`
- **Off-screen translate (closed state):** `cpk:translate-x-full` ↔
`cpk:-translate-x-full`
- **Body push margin:** `document.body.style.marginInlineEnd` ↔
`marginInlineStart` (with the matching `transition` CSS property name)
- **Aside element:** picks up a `data-position` attribute for
styling/test hooks
`position` is in the `useLayoutEffect` deps, so toggling it at runtime
cleans up the prior side's body margin before applying the new one.
### Tests
New `CopilotSidebarView.position.test.tsx` (7 cases) —
default/right/left class assertions, off-screen translate direction, and
verification that the wrapper forwards through to the view. All 32
sidebar-area tests pass; full react-core suite (1167 tests) green with
no regressions.
### Storybook
Added `RightPosition` and `LeftPosition` stories under
`UI/CopilotSidebarView` for visual diffing.
## Related PRs and Issues
- N/A
## Checklist
- [x] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [ ] If the PR changes or adds functionality, I have updated the
relevant documentation
- [x] \"Allow edits by maintainers\" is checked
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The toggle button is hardcoded right-anchored (cpk:bottom-6 cpk:right-6).
When the sidebar sits on the left, the button should mirror to the left
so it lives behind/under the chat panel — otherwise it floats on the
opposite side from the sidebar it controls.
CopilotSidebarView now passes a position-aware className override into
the toggle slot (left-6 + right-auto, merged via tailwind-merge so the
default right-6 is dropped). Behavior on the right is unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lets consumers anchor the v2 CopilotSidebar to either side of the
viewport instead of the hardcoded right side. The prop flips the fixed
anchor, the border side, the off-screen translate direction, and the
body push margin (marginInlineStart vs marginInlineEnd) so the layout
mirrors correctly. Defaults to "right" for backward compatibility.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reverts the cloning design from #3525 (useAgent per-thread clones, getThreadClone,
globalThreadCloneMap, cloneForThread) and #3630 (clone routing in activity renderers),
plus the inspector machinery that existed only to handle clones (onAgentRunStarted
subscriber + run-handler emissions from #3869, the connect-time emission from #3872,
and the agentRunThreadId map that read from it).
State-manager isClone composite-key path and SuggestionEngine consumerAgent param —
both added in #3525 to keep clones visible to bookkeeping — are gone too.
Restores agent.threadId = resolvedThreadId in CopilotChat (pre-#3525 behavior) and
swaps the inspector's agentRunThreadId map for a direct agent.threadId read.
Removes the DemoButtonAgent and /a2ui-demo page from the demo (added by #3630 as a
clone-fix repro).
Re-opens the original issue #2957 (CPK-7155): two CopilotChat instances with the same
agentId and different threadIds will share message state again. The follow-up is a
public registerProxiedAgent API so callers can opt into multiple frontend agents
proxying to the same runtime agent, without implicit per-thread cloning.
The button hit DELETE /threads, which the runtime router resolves to
"threads/list" (a GET-only route) and returns 405. The intended endpoint
is POST /threads/clear (defined at fetch-router.ts:175). Add try/catch
and surface non-ok HTTP status via console.error so the click no longer
silently appears to succeed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 examples bumped from various 15.0-15.4 versions to 15.5.15.
chat-with-your-data bumped from 15.6.0-canary to 16.1.7.
next-openai: moved OpenAI client init into handlers (15.5 evaluates
edge routes at build time).
Remaining on 14.x: next-pages-router(v1), state-machine, travel,
banking, enterprise-brex, presentation, todo — require major rewrite.
Phase 2: upgrade existing overrides to higher patched versions
Phase 3: add 36 new safe overrides for all resolvable transitive deps
Phase 4: bump storybook devDeps, vite in react-router, vitest in demo-agents, next canary
Remaining 3 are truly unfixable:
- parse-git-config: no patch exists (danger devDep)
- elliptic: no patch exists (storybook crypto chain)
- next: example on 15.x canary, advisory needs 16.x
Part of CPK-7320
Replaces the Angular-backed cpk-thread-list / cpk-thread-details custom
elements with native Lit implementations inside @copilotkit/web-inspector,
so React, Vanilla, and any other non-Angular consumer of the inspector
gets full functionality without pulling the Angular runtime. The
@copilotkit/web-inspector-angular package is deleted entirely, and the
Angular demo no longer calls defineInspectorElements.
Backend: adds GET /threads/:id/events and GET /threads/:id/state to the
runtime (in-memory runner path). The Intelligence path returns 501 with
a clear "not yet supported on this runtime" empty state — coordination
with the Intelligence team is tracked separately (CPK-7453).
Also guards attachToCore's getThreadStores call so consumers on an older
@copilotkit/core don't throw when assigning inspector.core, and drops
two unrelated showcase-whitelist lines that landed in
scripts/hooks/check-binaries.sh during a prior merge.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`CopilotChatView` rendered the attachment queue + input as flex siblings
beneath the scroll area, so long messages hit the input's flat top edge
and were sliced mid-line. Most visible in pin-to-send mode where the user
reads at their own pace. The previously-shipped feather gradient masked
this but clashed with host themes whose `--background` didn't match its
hard-coded white/near-black (b621e96ee defaulted it to an empty div).
Wrap attachments + input in a single absolute-positioned overlay so the
scroll content fills full height and passes behind the rounded pill. Pad
scroll-content bottom by the measured overlay height so the last line
clears the pill. Welcome-screen input is unchanged (stays inline). The
`feather` slot remains — hosts who want a themed fade supply their own
gradient.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- hooks.ts: keep both threads/clear and cpk-debug-events in RouteInfo
- use-threads.tsx: keep registerThreadStore effect + adopt main's
runtimeStatus gating for context dispatch
- use-threads.test.tsx: keep both our register/unregister test and
main's new runtimeConnectionStatus=Connected gating test
- scripts/hooks/check-binaries.sh: add shell-docs and shell-dojo
demo-content.json exclusions (main introduced these >1MB files without
updating the exclusion list)
- lefthook.yml, pnpm-lock.yaml: accept main's version
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix the long-standing typo across the example directory name + module
identifiers, align imports + package names. Also touches examples/integrations/adk
docker-compose fixtures and examples/e2e agents reference doc.
The headless demo component imports from @copilotkit/web-inspector-angular
but the package was missing from package.json and the tsconfig paths,
causing the Angular build to fail with TS2307.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Excludes showcase/shell-docs and showcase/shell-dojo demo-content.json from
the size check in lefthook.yml — these data files were added by main but
weren't in the exemption list, causing the pre-commit hook to reject them.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
- Widen `TanStackChatMessage.content` from `TanStackContentPart[]`
to `any[]` so messages from `convertInputToTanStackAI` are directly
passable to any TanStack AI adapter without `as any` casts
- Split `TanStackContentPart` into a proper discriminated union with
separate variants per modality
- Add `env.d.ts` with `vite/client` reference for CSS import types
- Fix `onError` callback shape in the example
## Test plan
- [x] All 17 multimodal TanStack tests pass
- [x] All 294 agent tests pass
- [ ] Verify no TS errors in react-router example IDE
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- CopilotKitCore gains a ThreadStoreRegistry (register/unregister by agentId)
and a new onAgentRunStarted subscriber event so the inspector can subscribe
before agent.runAgent() snapshots the subscriber list
- Runtime gains handleListThreads, handleUpdateThread, handleArchiveThread,
handleDeleteThread, handleSubscribeToThreads, and handleGetThreadMessages
handlers; all mutations are authenticated via identifyUser (request body
userId is ignored)
- InMemoryAgentRunner now stores thread history for the local-dev fallback
path; debug console.log removed; InMemoryThread uses literal types for
constant-value fields (organizationId: "", createdById: "", archived: false)
- useThreads hook registers its store with CopilotKitCore on mount and
unregisters on unmount so the inspector can read thread state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
- 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
- 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
Adds a minimal demo at /a2ui-demo that uses the demo-button agent to
reproduce and validate the A2UI thread-clone bug fix. The agent renders
an A2UI surface with a Confirm button on first run; clicking it fires a
second run that emits a text confirmation message.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Attachment queue & previews:
- Image lightbox with View Transition API morph animation
- Video lightbox with native controls and play button overlay
- Document lightbox (PDF via blob URL, text inline, info card fallback)
- Drop zone overlay with upload icon
- Filename preservation via InputContent metadata
- Proper video thumbnail sizing and play/pause indicator
- Fix attachment queue positioning (max-w-3xl constraint)
- Padding between X button and content for audio/document cards
- Document filenames wrap instead of truncating
Attachments config:
- onUploadFailed callback for validation/upload errors (file-too-large, invalid-type, upload-failed)
- onUpload accepts sync or async returns
- AttachmentUploadResult discriminated union with explicit interfaces
- Metadata field on Attachment and onUpload return type
AG-UI version bump:
- Bump @ag-ui/client, @ag-ui/core, @ag-ui/encoder, @ag-ui/proto to 0.0.51
- Remove process.env Vite workaround (fixed upstream in 0.0.51)
Deprecation lifecycle:
- @deprecated JSDoc on all legacy image upload APIs
- ImageRenderer, ImageRendererProps, ImageUpload type, imageUploadsEnabled prop,
inputFileAccept prop, ImageRenderer prop, AIMessage.image, ImageData
- Codemod at codemods/migrate-attachments.ts (15 tests)
- Migration guide updated with codemod instructions and new type shapes
Docs:
- New guide: docs/(root)/multimodal-attachments.mdx
- Updated migration guide with onUpload return type, metadata, codemod section
- Cross-links from prebuilt-components and migration guide
- Label change: "Add photos or files" → "Add attachments"
Tests:
- CopilotChat.attachments.test.tsx — 5 tests for onUploadFailed
- migrate-attachments codemod — 15 tests
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
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
## Summary
- Adds a new example app at `examples/v2/react-router` demonstrating
CopilotKit with React Router v7 (SSR/framework mode) and TanStack AI as
the default agent
- `TanStackAIAgent` wraps TanStack AI's `chat()` via a factory callback
pattern, giving users full type safety over adapter/model configuration
- CopilotKit runtime is mounted as a Hono route on the same server that
serves React Router SSR
## Key files
| File | Purpose |
|------|---------|
| `app/agent.ts` | `TanStackAIAgent` — thin `AbstractAgent` wrapping a
`chat()` factory, with AG-UI event normalization |
| `app/server.ts` | Hono server config mounting CopilotKit endpoint +
React Router SSR |
| `app/routes/_index.tsx` | Full-page `CopilotChat` UI |
## Notes
Discovered that TanStack AI's AG-UI events have subtle differences from
`@ag-ui/core` spec (extra fields, own type definitions instead of
importing from `@ag-ui/core`, own `runId`/no `threadId`). The
`TanStackAIAgent` normalizes these by consuming only text/tool deltas
from the stream and re-emitting clean `@ag-ui/client`-compatible events.
Will follow up with TanStack AI team on aligning their event types with
`@ag-ui/core`.
## Test plan
- [x] `pnpm build` passes
- [x] Dev server starts and serves the app
- [x] CopilotChat renders and streams responses from TanStack AI via
CopilotKit runtime
- [x] TypeScript type checks pass with zero errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add a new example app at examples/v2/react-router demonstrating CopilotKit
with React Router v7 (SSR/framework mode) and TanStack AI as the default agent.
- React Router v7 SSR with Hono server via react-router-hono-server
- CopilotKit runtime mounted as a Hono route on the same server
- TanStackAIAgent: thin AbstractAgent wrapper that accepts a chat() factory
callback, giving users full type safety over TanStack AI's adapter/model config
- Proper AG-UI event normalization bridging TanStack AI's event format to
what CopilotKit's @ag-ui/client pipeline expects
- Full-page CopilotChat UI with Tailwind CSS v4
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/...
With per-thread agent clones, the registry agent has empty messages.
reloadSuggestions was checking messageCount on the registry agent, so
dynamic suggestions (which require messageCount > 0) never fired after
the first message. Fix by passing the thread clone (with actual messages)
through reloadSuggestions → generateSuggestions.
Also updates the demo to use claude-3-7-sonnet (extended thinking support)
when ANTHROPIC_API_KEY is set.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>