12349 Commits

Author SHA1 Message Date
Mike Ryan 5bcc1d1ce0 chore: release monorepo v1.62.1 (#5791)
## Release monorepo v1.62.1

**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.62.1`
   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.62.1`
   - Creates git tag `monorepo/v1.62.1`
   - 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.
v1.62.1
2026-07-01 10:10:06 -07:00
tylerslaton 617e88a069 chore: release monorepo v1.62.1 2026-07-01 17:07:44 +00:00
Tyler Slaton 018f64b2db fix(release): include web-components in monorepo scope (#5790)
## Summary
- Include `@copilotkit/web-components` in the shared `monorepo` release
scope.
- Remove the standalone `web-components` release scope from workflow
dispatch options and type definitions.
- Keep notification package counts aligned with the 16-package monorepo
scope.

## Why
`@copilotkit/web-components` should move with the rest of the shared
monorepo packages after its initial manual publish, not be released as a
separate scope.

## How
- Added `@copilotkit/web-components` to `release.config.json` under
`monorepo`.
- Removed standalone scope dropdown/options and npm URL handling.
- Verified dropdown parity, monorepo dry run, standalone-scope
rejection, and notification tests.
2026-07-01 10:02:33 -07:00
Austin Merrick f54e99697b fix(build): replace Unix-only commands in package.json scripts with Node.js equivalents (#5602)
## What does this PR do?

This PR fixes build failures on Windows by replacing Unix-only shell
commands (`rm -rf`, `cp`, `mkdir -p`) in `package.json` scripts with
cross-platform Node.js `fs` built-in commands.

This follows the project's existing codebase pattern for cross-platform
operations, as seen in `packages/react-ui/package.json` (line 45).

### 🛠️ Changes:
- **`packages/runtime`**: Replaced `rm -rf` in `generate-graphql-schema`
with `fs.rmSync`.
- **`packages/vue`**: Replaced `cp` in `build:types` and `rm -rf` in
`clean` with `fs.cpSync` and `fs.rmSync`.
- **`packages/angular`**: Replaced `mkdir -p` and `cp` in `build:css`
with `fs.mkdirSync` and `fs.cpSync`.
- **`examples/v1/next-openai`, `next-pages-router`, `state-machine`**:
Replaced `rm -rf` clean commands with a single Node.js loop that deletes
`.turbo`, `node_modules`, `dist`, and `.next`.

All modified packages now build successfully on Windows.

## Related PRs and Issues

- Closes #5601

## 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 (lets us help iterate on
your PR directly — faster turnaround for everyone)
2026-07-01 09:56:00 -07:00
Tyler Slaton 7527ee64d0 fix(release): fold web-components into monorepo scope 2026-07-01 09:54:51 -07:00
Austin Merrick 66de791b40 fix(vue): inherit chat configuration agent id in useAgent (#5695)
## Summary

- Make Vue `useAgent` resolve agent IDs from explicit prop, then
surrounding chat configuration, then `DEFAULT_AGENT_ID`.
- Add regression coverage for bare `useAgent()` inside a non-default
configured chat and for explicit prop precedence.
- Update the Vue parity matrix note for the `useAgent` precedence
behavior.

Fixes #5656

## Verification

- `pnpm nx run @copilotkit/vue:test --
src/v2/hooks/__tests__/use-agent.test.ts` (failed before the fix with
`Received: "default"`, passes after)
- `pnpm --dir packages/vue exec eslint src/v2/hooks/use-agent.ts
src/v2/hooks/__tests__/use-agent.test.ts`
- `pnpm nx run @copilotkit/vue:check-types`
- `pnpm nx run @copilotkit/vue:test` (94 files / 1007 tests)
- `lefthook pre-commit test-and-check-packages` (ran `@copilotkit/vue`
test, build, publint, and attw)
- `git diff --check upstream/main...HEAD`

## Notes

- `pnpm nx run @copilotkit/vue:lint` still fails on pre-existing
unrelated Vue lint errors across untouched files; the changed files pass
eslint directly.
2026-07-01 09:54:41 -07:00
Tyler Slaton 9ed48a9dc3 fix(web-components): keep generated tokens formatted 2026-07-01 09:44:46 -07:00
Tyler Slaton 3e8e409f1f chore(release): add web-components release scope 2026-07-01 09:43:04 -07:00
Mike Ryan 25040e4d7c chore: release monorepo v1.62.0 (#5788)
## Release monorepo v1.62.0

**Scope:** `monorepo` | **Bump:** `minor`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.62.0`
   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.62.0`
   - Creates git tag `monorepo/v1.62.0`
   - 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.
v1.62.0
2026-07-01 08:56:39 -07:00
MikeRyanDev ca836ff920 chore: release monorepo v1.62.0 2026-07-01 15:45:54 +00:00
Ran Shemtov 01354148b1 fix(react-core): render nothing for unhandled tool calls instead of auto default card (#5769)
## What

Revert the v2 tool-call resolver so an **unhandled** tool call (no
per-tool or wildcard renderer registered) renders **nothing** again,
instead of auto-painting the built-in `DefaultToolCallRenderer` card.

Showing the card is opt-in, exactly as before:

| Call | Result |
|---|---|
| `useDefaultRenderTool()` | built-in default tool-call card |
| `useDefaultRenderTool({ render })` | the caller's custom UI |
| neither | nothing renders |

## Why

The auto-card default was introduced in commit `ba60df5d33`
(2026-05-07), buried as the **last bullet** of a commit titled
`feat(showcase/langgraph-python): add per-tool testids`. It shipped
silently in **v1.57.2** with **no CHANGELOG entry** and is still live
through 1.61.2.

Effect: in v2, **every** agent tool call that surfaces in chat without a
registered renderer paints a card exposing the tool name, raw arguments
JSON, and raw result JSON — in production, for all customers. This is
how internal A2UI plumbing tools (`generate_a2ui`, `render_a2ui`,
`log_a2ui_event`) leaked into deployed showcase demos, and it equally
leaks any customer's own un-rendered tools.

Pre-1.57.2 behavior was `return null` (invisible). This restores that
opt-in contract.

## Changes

- `use-render-tool-call.tsx`: resolver returns `null` when no
per-tool/wildcard renderer matches.
- Removed the now-dead `defaultToolCallRenderAdapter` + `__testOnly_`
export + unused imports.
- Rewrote `use-render-tool-call.test.tsx` to drive the real
`useDefaultRenderTool` → real `useRenderToolCall` through a notifying
mock core, asserting all 3 states (card / custom / nothing).

## Showcase impact

None required. The opt-in `tool-rendering-*-catchall` demos already call
`useDefaultRenderTool()`, so their cards (and e2e specs) are unchanged.
No a2ui/declarative spec asserts the card — those demos simply stop
leaking it in prod.

## Verification

- `nx test react-core`: 1368 pass (107 files), incl. the new 3-scenario
suite.
- `nx check-types react-core`: clean.
- `nx build react-core`: clean.
- oxfmt `--check`: clean.
2026-07-01 16:48:26 +02:00
Ran Shemtov d0f4f27458 Merge branch 'main' into claude/happy-dirac-f6ed5e 2026-07-01 16:48:12 +02:00
Ran Shemtov c26b89dc51 fix: inspector shows no AG-UI events for per-thread agent clones (#5784)
Fixes #5773, a regression of #3872. The inspector event timeline stays
empty during runs — no `RUN_STARTED`, `TEXT_MESSAGE_*`, `TOOL_CALL_*`,
etc. — while connection status, agents, context and tools still
populate.

The cause is the same one #3872 fixed and that has since been dropped:
`useAgent` runs a per-thread *clone* of the registry agent, and clones
are never added to the registry. The inspector only subscribes to AG-UI
events via `onAgentsChanged`, so it never sees the clone that actually
runs, and every `recordAgentEvent` sits on the wrong instance. The
`onAgentRunStarted` bridge #3872 added is no longer declared on
`CopilotKitCoreSubscriber`.

Re-landing it against the current run path: `RunHandler` fires
`onAgentRunStarted` with the real run instance at the start of
`runAgent` (top-level only, so recursive tool follow-ups don't
re-subscribe) and `connectAgent`, and the inspector subscribes to that
instance. `subscribeToAgent` already keys by `agentId` and replaces, so
the clone cleanly supersedes the registry subscription and there's no
leak. Per-thread cloning is untouched.

Added a core regression test driving a run on a clone that isn't in the
registry and asserting the event fires once with that instance, plus
that recursive follow-up runs don't re-notify. Core and web-inspector
both typecheck; core suite green.
2026-07-01 10:29:29 +02:00
Ran Shemtov 55e0a884b3 Merge branch 'main' into fix/inspector-subscribe-per-thread-clone-events 2026-07-01 10:10:12 +02:00
Ran Shemtov e1321406bc fix(vue): enable A2UI via catalog-on-provider path (#5777) 2026-07-01 08:33:53 +02:00
Ben Taylor cbb24952c5 feat(web-inspector): add unified thread debugger (#5768)
## Summary
- Adds the unified web-inspector thread debugger surface as a standalone
`cpk-thread-inspector` custom element backed by a
`ThreadDebuggerProvider` contract for thread metadata, messages, AG-UI
events, and state.
- Keeps the existing full Web Inspector shell compatible by making the
internal `cpk-thread-details` element extend the new shared inspector
implementation.
- Normalizes persisted AG-UI event history into a first-class Timeline
view with run/message/tool/state/raw rows, source-event links into the
Raw AG-UI Events tab, metadata pills, and raw-event preservation for
top-level fields.
- Improves timeline/state loading behavior for standalone and
runtime-backed usage: state stays lazy-loaded, provider/runtime/header
swaps refetch safely, stale async responses are ignored, and
message-backed or raw-only threads no longer show an empty first tab.
- Adds a standalone web-inspector dev harness with AG-UI events,
Messages only, and Raw event only scenarios for shared UI validation
outside an app shell.
- Updates package/dev configuration for the harness (`dev:standalone`,
Vite dev dependency/config allowlist) and bumps
`@copilotkit/web-inspector` to `1.61.3`.

## Tests and Checks
- Expanded `packages/web-inspector` tests for the provider contract,
normalized timelines, raw event rendering, lazy state loading, stale
request handling, header-driven refetches, runtime fallbacks, and
first-tab timeline population.
- PR checks currently passing include build, check-types, format,
oxlint, package-quality, unit on Node 20/22/24, Python unit tests, shell
script tests, Validate Showcase, bundle-size, config/binary checks, and
integration starter/showcase jobs.
- Manual validation path documented in
`packages/web-inspector/README.md`: `pnpm nx run
@copilotkit/web-inspector:dev:standalone`, then validate AG-UI events,
Messages only, Raw event only, source-event navigation, and State at
`http://127.0.0.1:5177/`.

## Companion PR
- Intelligence managed debugger integration:
https://github.com/CopilotKit/Intelligence/pull/461

<img width="928" height="724" alt="Screenshot 2026-06-29 at 2 50 47 PM"
src="https://github.com/user-attachments/assets/c7936f1c-0780-4c0c-b5d2-1890db611460"
/>
<img width="927" height="1325" alt="Screenshot 2026-06-29 at 2 49 50 PM"
src="https://github.com/user-attachments/assets/48134189-7def-4312-b4d1-4bad28a93a12"
/>
e733" />
<img width="927" height="408" alt="Screenshot 2026-06-29 at 2 49 58 PM"
src="https://github.com/user-attachments/assets/1773b1f7-10a1-4905-ab6e-418d13031a49"
/>
<img width="929" height="583" alt="Screenshot 2026-06-29 at 2 50 07 PM"
src="https://github.com/user-attachments/assets/8f38f91d-296b-41dd-8b50-8c60739b387d"
/>
2026-06-30 21:50:44 -05:00
serhiizghama f9bba02c20 fix(web-inspector): subscribe to the running clone via onAgentRunStarted
The inspector subscribed to AG-UI events only through onAgentsChanged, which
skips per-thread clones, leaving the event timeline empty during runs
(regression of #3872). Subscribe to the run instance reported by
onAgentRunStarted so its events are recorded.
2026-07-01 08:23:53 +07:00
serhiizghama 7f0ca7eabf fix(core): notify subscribers of the agent instance at run start
Add an onAgentRunStarted subscriber event fired from RunHandler.runAgent and
connectAgent with the instance that actually runs. Per-thread clones (from
useAgent) are not in the agent registry, so onAgentsChanged never fires for
them and subscribers that only track registry agents can't observe their run.
2026-07-01 08:23:53 +07:00
Martha Schumann 5df64923cc fix: stabilize inspector live event caches 2026-06-30 17:03:25 -07:00
Martha Kelly Schumann f0eb837dad Merge branch 'main' into codex/unified-thread-debugger 2026-06-30 15:53:41 -07:00
Mike Ryan 2d318c6937 feat: CopilotThreadsDrawer + active-thread configuration (#5746)
## What

The **Angular `<CopilotDrawer>` feature** for the CopilotKit SDK — a
ready, usable threads drawer for Angular apps, plus the active-thread
foundation it sits on. (This PR merges the originally-staged PR1+PR2 so
it ships a working feature, not just plumbing.)

**Foundation — active-thread coordination (no new store):**
1. **`CopilotChatConfiguration`** — an injectable, signal-based service
mirroring React's `CopilotChatConfigurationProvider`: owns
`agentId`/`threadId` resolution (controlled prop → override → minted
fallback) + the `hasExplicitThreadId` welcome flag; `setActiveThreadId`
/ `startNewThread` setters that no-op when host-controlled;
single-instance via `useExisting`.
2. **`connectActiveThread`** (internal connector) — reactively pins the
resolved thread onto `agent.threadId` and owns the connect lifecycle
(per-run `AbortController` on `HttpAgent`s, a single caught connect
chain, a staleness-guarded loading cursor, abort+`detachActiveRun()`
teardown), mirroring the standalone `connectToAgent` path. Clears
messages only on a genuine new-thread transition (never on
mount/agent-swap).
3. **`CopilotChat`** consumes the ambient config when present
(input-first precedence: `[agentId]`/`[threadId]` win), seeds the config
from a set `[threadId]`; standalone `[threadId]` usage unchanged when no
provider is present.

**The drawer — `<copilot-drawer>`:**
4. A standalone `OnPush` wrapper around the framework-agnostic
`copilotkit-drawer` Lit element (`@copilotkit/web-components`). Events
bind declaratively; element properties are set imperatively via
`viewChild`+`effect` (the `a2ui-activity-renderer` precedent). Routes
the element's events
(`thread-selected`/`new-thread`/`archive`/`unarchive`/`delete`/`filter-change`/`retry`)
to the config + `injectThreads` mutations (delete-of-active resets to a
fresh thread).
5. **`CopilotDrawerRow`** directive for per-row custom content
(`slot="row:{id}"`), `onThreadSelect`/`onNewThread` host escape-hatch
callbacks, and `<ng-content>` slot passthrough
(`launcher-icon`/`memories`).
6. **`listError`** added to `injectThreads` — a filtered error (genuine
list/mutation errors only, excluding developer/config errors like
"Runtime URL is not configured") so the drawer's error panel never shows
dev strings to end users. Mirrors react-core's `useThreads`.

**Always-licensed:** Angular SDK licensing is no longer a thing, so the
wrapper does not wire the element's `licensed`/`upsell` — no upsell
path. **Inline-chat-only:** no Layer-2 open-state coordination (the
element self-provides its mobile launcher).

## Why

Angular had no active-thread provider (only `injectThreads`) and no
drawer component. This lands both so Angular apps get thread switching +
a usable threads drawer at parity with the React vertical, reinterpreted
for Angular's inline-chat-only surface.

## Testing

`@copilotkit/angular`: tsc clean, `oxlint` 0 errors, `ng-packagr` build
green, **152 tests pass** (full package suite). New coverage: config
precedence/controlled-vs-uncontrolled + single-instance identity;
connector connect-on-switch / clear-only-on-real-transition / cursor
staleness / no-unhandled-rejection / abort+detach teardown (verified
against a real `HttpAgent`); drawer prop binding, all 7 event routings
(incl. delete-active reset), escape-hatch overrides, `renderRow`
projection, `<ng-content>` slot passthrough, and the `listError`
dev-error-exclusion.

Hardened through a full `cr-loop` (foundation: 5 rounds; wrapper: 2
rounds) — the wrapper CR caught + fixed a real bug (the error panel was
leaking dev/config errors; fixed via the filtered `listError`).

## Dependency / release gate

Depends on `@copilotkit/web-components` (the `copilotkit-drawer`
element) being published — the same release gate as the React drawer
work (#5707). `packages/angular` publishes alongside.

## Follow-ups (out of scope, tracked)

- A demo `routes/threads` in `examples/v2/angular/demo` (kept separate
to keep this a clean SDK-only change).
- Pre-existing OSS packaging: `zod` is in `devDependencies` but imported
by production source — should move to `dependencies`/`peerDependencies`.
- `packages/angular/src/lib/threads.spec.ts` uses `describe/it` vs the
flat-`test` convention of sibling specs (pre-existing).
- Minor polish backlog from CR (renderRow multi-row tests, a docblock
tidy) — non-blocking.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-30 15:46:35 -07:00
Benjamin Taylor 74b8a1981f feat(drawer): default Upgrade CTA URL + Angular license gate
Add a `licenseUrl` property to the shared element (default
https://docs.copilotkit.ai/intelligence). The locked view's Upgrade CTA now
dispatches a cancelable `licensed` event carrying the url and, unless the
host calls preventDefault(), opens it in a new tab; a blank url suppresses
navigation. React and Angular wrappers expose an optional `licenseUrl` prop.

License-gate the Angular drawer like React: surface `licenseStatus` as a
signal on the CopilotKit service and gate the wrapper on
status valid|expiring && checkFeature("threads"), skipping the thread fetch
while unlicensed and showing the loading state (not the locked view) until
the status resolves. Reverses the earlier always-licensed Angular call.

Closes ENT-1027.
2026-06-30 17:34:39 -05:00
Benjamin Taylor f53a70c691 refactor(drawer): rename to CopilotThreadsDrawer / copilotkit-threads-drawer
Final naming decision. Renames the public component + element across the
board: React/Angular CopilotDrawer -> CopilotThreadsDrawer, the Lit element
copilotkit-drawer -> copilotkit-threads-drawer (tag, CopilotKitThreadsDrawer
class, COPILOTKIT_THREADS_DRAWER_TAG, defineCopilotKitThreadsDrawer), the
@copilotkit/web-components/drawer subpath -> /threads-drawer (+ src dir),
the CopilotThreadsDrawerRow directive / copilotThreadsDrawerRow input, and
all prose/test references. Generic types (DrawerThread, DrawerFilter),
--cpk-drawer-* tokens, and ::part names are unchanged. Behavior unchanged.
2026-06-30 17:34:39 -05:00
Benjamin Taylor eb3c20e865 refactor(drawer): rename unlicensed -> licensed across the public surface
Per review, settle the locked-view affordance on a neutral 'license'
name. Renames the event (unlicensed -> licensed), React prop
(onUnlicensed -> onLicensed), slot/part/class (licensed, licensed-cta),
LicensedDetail type, data-testid, render method, and identifier-referencing
comments/test names. The existing 'licensed' boolean gate is unchanged;
prose describing the not-licensed state still reads 'unlicensed'/'locked
view'. Behavior unchanged; Angular unaffected.
2026-06-30 17:34:39 -05:00
Benjamin Taylor d7cb0fded1 refactor(drawer): rename upsell -> unlicensed across the public surface
Per review, drop the 'upsell' monetization jargon. Renames the event
(upsell -> unlicensed), the React prop (onUpsell -> onUnlicensed), the
slot/part/class (upsell -> unlicensed, upsell-cta -> unlicensed-cta),
the UnlicensedDetail type, the data-testid, and all comments/test names.
Behavior unchanged. Angular is unaffected (always-licensed, no gate).
2026-06-30 17:34:39 -05:00
Benjamin Taylor cf4f00ecc1 feat(drawer): activate thread pagination (Load more + limit prop)
Wires up the previously-dormant pagination plumbing (ENT-1016):

- Element: render a 'Load more' button at the list bottom when hasMore
  (and not fetching / not errored), emitting a new load-more event
  (LoadMoreDetail). Distinct from retry{scope:'fetch-more'} (error
  recovery); both advance pagination.
- React CopilotDrawer: add a limit prop (forwarded to useThreads) and
  route load-more to fetchMoreThreads.
- Angular CopilotDrawer: add a limit input (forwarded to injectThreads)
  and route load-more to fetchMoreThreads.

Tests: element load-more render + emit + precedence; React limit
forwarding + load-more routing; Angular load-more routing.
2026-06-30 17:34:38 -05:00
Benjamin Taylor f1cc30cda0 feat(react): add configurable label prop to CopilotDrawer
Mirrors the Angular wrapper + the copilotkit-drawer element's label
property: sets the drawer region aria-label and default header text,
defaulting to the element's built-in "Threads" when omitted.
2026-06-30 17:34:38 -05:00
Benjamin Taylor 0183a30369 fix(web-components): scroll the drawer thread list when it overflows (:host height + .list min-height:0) 2026-06-30 17:34:38 -05:00
github-actions[bot] 3c8e330fcb style: auto-fix formatting 2026-06-30 17:34:38 -05:00
Benjamin Taylor 10a5315c10 feat(angular): forward a label input to the drawer element 2026-06-30 17:34:38 -05:00
Benjamin Taylor 787b9ad382 feat(web-components): make the drawer label/aria-label configurable (label property, defaults to Threads) 2026-06-30 17:34:37 -05:00
github-actions[bot] b5580e32b8 style: auto-fix formatting 2026-06-30 17:34:37 -05:00
Benjamin Taylor d8a8dd4fe6 feat(angular): add <CopilotDrawer> wrapper for the copilotkit-drawer element
Standalone OnPush Angular component wrapping the framework-agnostic
copilotkit-drawer Lit element. Binds live thread state from injectThreads onto
the element (imperative viewChild+effect, per the a2ui-activity-renderer
precedent) and routes the element's DOM events to the ambient
CopilotChatConfiguration + thread mutations. Ships a CopilotDrawerRow directive
for per-row slot projection, host onThreadSelect/onNewThread escape-hatch
callbacks, and <ng-content> slot passthrough (launcher-icon/memories). Uses the
filtered listError for the error panel. Always-licensed (no licensed/upsell
wiring); inline-chat-only (no Layer-2 open-state coordination). Exported from
public-api.
2026-06-30 17:34:37 -05:00
Benjamin Taylor a7c25d9800 feat(angular): expose filtered listError from injectThreads
Adds a listError signal that returns only genuine list/mutation errors,
excluding developer/config errors (missing runtime URL, runtime without thread
endpoints) so consumer error UIs do not surface dev strings to end users.
Mirrors react-core's useThreads listError; `error` is unchanged (additive).
2026-06-30 17:34:37 -05:00
Benjamin Taylor 7a08fa2cc0 chore(angular): add @copilotkit/web-components dependency
Adds the workspace dep (consumed by the <CopilotDrawer> wrapper) and allows it
as a non-peer dependency in ng-package.json so ng-packagr packages cleanly.
2026-06-30 17:34:37 -05:00
Benjamin Taylor 01cd9eeabc feat(angular): CopilotChat consumes ambient CopilotChatConfiguration
CopilotChat reads the ambient config when a provideCopilotChatConfiguration
provider is in scope: input-first precedence ([agentId]/[threadId] win over the
config, matching React), seeding the config from a set [threadId], and driving
the connector with loading-cursor hooks. Standalone <copilot-chat [threadId]>
usage is unchanged when no provider is present. Exports CopilotChatConfiguration
from the package entry point.
2026-06-30 17:34:36 -05:00
Benjamin Taylor 4400a7c081 feat(angular): active-thread connector wiring config to the live agent
connectActiveThread reactively pins the resolved thread onto agent.threadId.
On an explicit switch it connects the agent, owning the loading-cursor + abort
+ detach lifecycle of the standalone connectToAgent path (per-run AbortController
on HttpAgents, a single caught connect chain so a rejecting connect never leaks
an unhandled rejection, and a staleness-guarded cursor settle). On a fresh /
non-explicit switch it clears messages only on a genuine new-thread transition,
never on mount or a same-thread agent swap. Injection-context-only; not exported
on the public surface.
2026-06-30 17:34:36 -05:00
Benjamin Taylor 35671a688f feat(angular): CopilotChatConfiguration service for active-thread resolution
Injectable service mirroring React's CopilotChatConfigurationProvider. Owns
agentId/threadId resolution (controlled prop > override > options > minted
fallback) and the hasExplicitThreadId welcome-screen flag, exposes
setActiveThreadId/startNewThread setters that no-op when the config is
host-controlled, and reserves drawerOpen/registerDrawer hooks for a future
popup/sidebar layer. provideCopilotChatConfiguration aliases the token to a
single instance via useExisting.
2026-06-30 17:34:36 -05:00
Mike Ryan ac703dc6d1 fix(chat): keep message padding in sub-viewport panes via container query (ENT-1020) (#5778)
## What & why

Fixes **ENT-1020**. In a side-by-side layout (the threads drawer rail
next to the chat), at iPad-portrait / tablet widths the chat **message
text sat flush against both pane edges** — no horizontal padding — while
the input stayed correctly inset. Surfaced while manually testing the
Angular `CopilotDrawer` (#5746), but it is **not a drawer bug**: it
reproduces in any layout that puts `CopilotChat` in a pane narrower than
the viewport.

### Root cause
The message column is `max-w-3xl` (768px) centered; its wrappers used
`cpk:px-4 cpk:sm:px-0` — 16px below 640px, then **0 at viewport
≥640px**. There was no `container-type` on the chat root, so the `sm:`
variant keyed on the **viewport**, not the chat's own width. In a
sub-viewport pane (~580px chat on an 820px viewport) `sm:px-0` still
fired (viewport ≥640) while the 768px column overflowed the pane
edge-to-edge → flush text.

## The fix (robust / container-relative)
- Add `cpk:@container` (`container-type: inline-size`) to the chat root
(React ×2 render paths, Angular, Vue).
- Switch every message / input / suggestion wrapper from viewport
`cpk:sm:px-0` to the **container** variant `cpk:@3xl:px-0`.

Padding now tracks the chat's **own** width and drops to 0 only once the
container is at least as wide as the column's `max-w-3xl`, i.e. once the
column has real side gutters. In any narrower pane the `px-4` inner
padding is retained. **React, Angular, and Vue kept in lockstep.**

### Why `@3xl`, not the `@sm` the ticket suggested
Tailwind v4 **container-query** breakpoints are a *different scale* from
viewport breakpoints: `@sm` = **24rem/384px** (viewport `sm` = 640px). A
mechanical `sm:` → `@sm:` swap would still collapse the ~580px repro
pane (580 ≥ 384). `@3xl` = **48rem/768px**, which exactly matches the
column's `max-w-3xl` — the width at which gutters first appear — so it
is the semantically correct breakpoint.

> Vue was not named in the ticket scope but shares the identical
`sm:px-0` pattern; left unfixed it would reproduce the bug there, so it
is included for true framework lockstep. web-components only *hosts* the
chat (no `sm:px-0`), so it is correctly untouched.

## Testing

**Browser behavior — real built CSS, exact DOM
(`copilotKitChat`/`@container` root → `cpk:max-w-3xl cpk:mx-auto` →
`cpk:px-4 cpk:@3xl:px-0` message wrapper),
`getComputedStyle().paddingLeft`:**

| Scenario | Result | Expectation |
|---|---|---|
| **580px narrow pane** (the repro) | `padding-left: 16px` | ✅ `px-4`
retained — text no longer flush |
| **900px wide pane** (full desktop) | `padding-left: 0px` | ✅ `px-0` —
column has gutters, behavior preserved |
| **No `@container` ancestor** (render-prop path) | `padding-left: 16px`
| ✅ graceful `px-4`, no flush |

**Generated CSS confirmed** (Tailwind v4.1.18): root emits
`container-type: inline-size`; wrapper emits `@container (min-width:
48rem) { padding-inline: 0 }` (verified in both react-core and angular
builds — a true container query, not a media query).

**Unit/component tests (pass):**
- react-core — full chat suite: **645 tests / 39 files** green (incl.
`CopilotChatCssClasses`).
- angular — `copilot-chat-view` + `copilot-chat-input` specs: **10**
green.
- vue — `CopilotChatView.connectingGate` +
`CopilotChatSuggestionView.slots.e2e`: **30** green.
- pre-commit `test-and-check-packages` (test + publint + attw across all
4 affected projects) passed.

No tests assert these class strings and no snapshots capture them, so
nothing needed regenerating.

## Acceptance criteria
- [x] Messages retain horizontal padding when the chat is in a narrow
(<~768px) pane at viewports ≥640px.
- [x] Full-width chat behavior preserved (container ≥768px → `px-0`),
verified in React, Angular, Vue.
- [x] No regression to input / disclaimer / suggestion alignment with
the message column (all share the same `@3xl` switch).

Closes ENT-1020

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-06-30 14:37:04 -07:00
Martha Kelly Schumann 08ed19f96f Merge branch 'main' into codex/unified-thread-debugger 2026-06-30 13:06:42 -07:00
github-actions[bot] 097d734bab style: auto-fix formatting 2026-06-30 14:26:15 -05:00
Benjamin Taylor 79276a2d4f fix(chat): keep message padding in sub-viewport panes via container query
CopilotChat message wrappers used viewport-keyed `cpk:sm:px-0`, collapsing
horizontal padding to 0 at any viewport >=640px. The message column is
`max-w-3xl` (768px) centered; the design assumes the chat fills the viewport,
so at >=640px the column has side gutters and inner padding can drop to 0.

But when the chat lives in a sub-viewport-width pane (e.g. the threads drawer
rail beside the chat, ~580px on an 820px iPad-portrait viewport), `sm:px-0`
still fires on viewport width while the 768px column overflows the narrow
pane and sits flush against both edges. The input wrapper looked fine because
it is visually inset by its own pill, so only message text appeared broken.

Make the padding container-relative instead of viewport-relative:
- add `cpk:@container` (container-type: inline-size) to the chat root, and
- switch the message/input/suggestion wrappers from `cpk:sm:px-0` to the
  container variant `cpk:@3xl:px-0`.

Padding now tracks the chat's own width and drops to 0 only once the container
is at least as wide as the column's own max-width, so the column has real
gutters; in any narrower pane the `px-4` inner padding is retained. React,
Angular, and Vue kept in lockstep.

Note on the breakpoint: Tailwind v4 container-query breakpoints differ from
viewport breakpoints (`@sm` = 24rem/384px, not 640px). A mechanical
`sm:` -> `@sm:` swap would still collapse the ~580px repro pane. `@3xl`
(48rem/768px) is used because it exactly matches the column's `max-w-3xl`,
which is the width at which side gutters first appear.

Verified: full-width desktop chat unchanged (container >=768px -> px-0);
580px pane retains 16px padding; render-prop layouts without a container
ancestor degrade safely to `px-4`; sidebar/popup `data-*` padding overrides
are unaffected.

ENT-1020

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 14:26:15 -05:00
Austin Merrick 6f49f69725 fix(angular): skip chat input submit during IME composition (#5764)
### What

The Angular `CopilotChatInput.handleKeyDown` submits the message when
Enter is pressed without Shift, but it never checks whether an IME
composition is in progress. When typing CJK text (Japanese, Chinese,
Korean), the Enter that confirms an IME candidate also fires a
`keydown`, so the half-composed text gets sent instead of the candidate
being committed.

The React and Vue bindings of the same v2 `CopilotChatInput` already
guard against this; Angular was the one binding still missing it:

- `packages/react-core/src/v2/components/chat/CopilotChatInput.tsx` —
`handleKeyDown` returns early on `e.nativeEvent.isComposing || e.keyCode
=== 229`
- `packages/vue/src/v2/components/chat/CopilotChatInput.vue` —
`handleKeydown` returns early on `isComposing.value || event.isComposing
|| event.keyCode === 229`, and has a test asserting it does not submit
while composing

### Change

Add the same early return to the Angular `handleKeyDown`, using the
native `KeyboardEvent` (`event.isComposing || event.keyCode === 229`),
which matches the Vue binding's idiom.

### Notes

When composition is not active `isComposing` is `false`, so Enter
submits exactly as before and Shift+Enter still inserts a newline. The
most visible case is Safari with a Japanese IME, where the confirming
Enter reports `key === "Enter"` with `isComposing === true`; the
`keyCode === 229` arm mirrors the sibling guards for browsers that
report the composing key that way.

I verified the handler logic in isolation (Enter while composing no
longer submits; plain Enter and Shift+Enter are unchanged). I did not
run the full Angular suite locally.
2026-06-30 11:23:18 -07:00
Martha Schumann 7f61d628fd fix(web-inspector): address debugger review feedback 2026-06-30 11:12:56 -07:00
Ran Shemtov 5ae980fbdc Merge branch 'main' into claude/happy-dirac-f6ed5e 2026-06-30 17:52:59 +02:00
Ran Shem Tov 5693a60625 feat(vue-demo): add A2UI catalog-on-provider demo + fix DemoButtonAgent
Adds /a2ui-catalog page and a runtime endpoint with NO a2ui config, so
A2UI switches on purely from the provider's a2ui.catalog (the #5774
path). Also fixes DemoButtonAgent, which never actually rendered: it
emitted the wrong activity content key (operations -> a2ui_operations)
and a non-canonical operation/component format. Rewritten to the A2UI
v0.9 wire format (createSurface/updateComponents, flat components, root
id "root") so the surface paints and the Confirm round-trip works.
2026-06-30 16:33:24 +02:00
Ran Shem Tov 258cdce49a feat(vue): export vueBasicCatalog for the catalog-on-provider path
A2UI's catalog-on-provider path needs a catalog to pass to
`a2ui.catalog`, but the library build tree-shook the nested barrel
re-export so vueBasicCatalog was unreachable at runtime (present only in
the .d.ts). Re-export it explicitly from the v2 entry, mirroring React's
`basicCatalog` export from @copilotkit/a2ui-renderer. Add an export test
guarding against the regression.
2026-06-30 16:33:12 +02:00
Ben Taylor 2b27fb0a2f feat(examples): enrich AIMock fixtures so keyless demo suggestions return scripted replies (#5728)
## Why

The 6 OpenAI drop-in integration examples enabled for the CLI's
**keyless AIMock mock mode** (`langgraph-python`, `langgraph-js`,
`mastra`, `llamaindex`, `agno`, `pydantic-ai`) shipped
`fixtures/default.json` files that **did not cover the prompts each
starter's own UI suggests**. AIMock matches `userMessage` as a
**case-sensitive substring, first-match-wins**, so a keyless first-run
user who clicked the demo's suggestion chips mostly fell through to the
generic catch-all ("I only have scripted replies…") instead of getting a
scripted demo reply.

Two root issues found (audit at `origin/main`):
- **`langgraph-python` was mis-keyed** — fixtures keyed on suggestion
*titles* (`"Pie Chart"`, `"Toggle Theme"`, `"Task Manager"`) while the
UI sends long *message* strings that don't contain those substrings →
all 9 suggestions missed.
- The other 5 shipped only a generic `Hello` (+ a `weather` fixture in
langgraph-js/mastra) → 0–1 of each starter's chips covered.

This PR re-keys/extends each example's fixtures so the surfaced
suggestions return scripted replies. Ordering preserved:
most-specific-first, `{}` catch-all last (unchanged text).

> Tracking: **ENT-1003** (CopilotKit/Intelligence). Sibling to ENT-989
(fixtures for *not-yet-enabled* frameworks). This PR covers the
*already-enabled* 6.

## What changed (per template)

| Template | Suggestions now covered | Tool-call replies | Text replies
|
|---|---|---|---|
| langgraph-python | 9/9 (3 re-keyed) | pie/bar chart
(`query_data`→component), `scheduleTime`, `toggleTheme`, `manage_todos`
| Search Flights, Excalidraw, Calculator, Sales-Dashboard A2UI step |
| langgraph-js | 9/9 | `query_data`, `search_flights`, `generate_a2ui`,
`manage_todos` (schemas verified vs agent) | scheduleTime, Excalidraw,
generateSandboxedUi, toggleTheme |
| mastra | 6/6 | `get-weather`, `setThemeColor`, `go_to_moon` (HITL) | 3
proverb chips (proverbs are agent shared-state, not a tool) |
| llamaindex | 3/3 | — | theme / proverb / weather |
| agno | 4/4 | — | weather / theme / stock / proverb |
| pydantic-ai | n/a (UI surfaces no chips) | — | best-effort free-typer
fixtures: "what can you do" / "proverb" / "weather" |

## Honest caveats (best-effort; draft)

- **Tool-call shapes only where evidenced.** Where a suggestion drives
A2UI streaming, an MCP app (Excalidraw), or a frontend-only tool
(`generateSandboxedUi`, `scheduleTime` in some templates) whose call
shape isn't defined in the template, I used an **on-topic text reply**
rather than fabricating a tool envelope. Those replies beat the
catch-all but won't trigger the live generative UI under mock mode — a
follow-up could record the real shapes.
- **`pydantic-ai` surfaces no suggestion chips** in its UI, so there's
nothing to key on; the real fix is a small UI change (add `suggestions`
to `CopilotSidebar`), which is out of scope for a fixtures-only PR. The
added fixtures are a fallback for free-typing users.
- **Not verified end-to-end here** (authored against `origin/main`, not
run live). Each template's `docker-compose.test.yml` AIMock smoke should
stay green; note its `@chat` test only sends `"Hello"` and asserts a
non-empty reply, so it does **not** validate suggestion-chip coverage —
extending it to assert a non-catch-all reply for a real suggestion would
close that blind spot (also noted in ENT-1003).

## Test plan
- [ ] Per-template `docker-compose.test.yml` AIMock smoke still green.
- [ ] Manual: scaffold/run each keyless, click each suggestion chip,
confirm a scripted reply (not the catch-all).
2026-06-30 09:28:03 -05:00
Benjamin Taylor bc24d62cec fix(examples): langgraph-js scheduleTime emits the tool call (+ terminate HITL turn)
Same class as the toggle-theme fix: langgraph-js's 'schedule a meeting' chip
returned text, so the meeting picker never rendered, while langgraph-python emits
the scheduleTime tool call. scheduleTime is a registered langgraph-js frontend
tool (reasonForScheduling/meetingDuration) — swap text -> tool call, mirroring
langgraph-python. Because scheduleTime is Human-in-the-Loop (the user's pick
returns as a tool result and re-invokes the LLM), add a terminating
call_schedule_time_001 result fixture in BOTH templates so the turn doesn't
re-match the user message and loop (langgraph-python lacked it too — latent).
Verified both terminate at 2 steps (tool call -> terminating text).
2026-06-30 09:21:50 -05:00
Benjamin Taylor 3c206d3d61 fix(examples): langgraph-js toggle-theme emits the toggleTheme tool call
The langgraph-js Toggle Theme chip returned a text response claiming it toggled
the theme, but emitted no tool call -- so the theme never changed, while the same
chip in langgraph-python emits the toggleTheme frontend tool call and works.
Identical chip, different outcome by template. Swap the text response for the
toggleTheme tool call, mirroring langgraph-python (frontend tool, no terminating
result fixture needed -> no loop). Verified aimock now returns the toggleTheme
tool call for the chip.
2026-06-30 09:09:49 -05:00