Commit Graph

12629 Commits

Author SHA1 Message Date
Benjamin Taylor 0254da874e feat(vue): add drawer-awareness fields to CopilotChatConfigurationValue type
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:00:03 -05:00
Benjamin Taylor 1def05e500 test(vue): clear-on-fresh clears messages on new-thread switch, not on mount
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 10:57:50 -05: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
Benjamin Taylor 0fea7a8ccb feat(vue): clear chat messages on fresh non-explicit thread switch
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 10:53:58 -05:00
Benjamin Taylor 60c01eef1d test(vue): cover active-thread setActiveThreadId/startNewThread + authoritative guard
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 10:51:28 -05:00
Benjamin Taylor daf26f22c1 feat(vue): active-thread override + setActiveThreadId/startNewThread in chat config provider
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 10:50:18 -05:00
Benjamin Taylor 6ba86c4027 feat(vue): add active-thread setters to CopilotChatConfigurationValue type
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 10:48:37 -05:00
MikeRyanDev ca836ff920 chore: release monorepo v1.62.0 2026-07-01 15:45:54 +00:00
Benjamin Taylor 259276d795 chore(vue): depend on @copilotkit/web-components for the threads drawer element
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 10:44:32 -05:00
Benjamin Taylor 89837c50fb feat(vue): expose unarchive/refetch/startNewThread/listError/isMutating + enabled gate on useThreads
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 10:43:09 -05:00
Benjamin Taylor 2f85aa7bc1 feat(vue): add isMobileViewport helper for drawer mobile mutual-exclusion
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 10:40:07 -05: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
lukasmoschitz 62c7f11394 feat(web-inspector): rename the Memories tab to Learning (#5787)
## What

Renames the inspector's user-facing feature name from **Memories** to
**Learning**:

- The menu tab label (`Memories` → `Learning`).
- The enabled-state panel heading (`Memory store` → `Learning`).

## What's intentionally left unchanged

- The internal `"memories"` menu key, the `Brain` icon, and the REST
wiring.
- Entry-level copy that refers to individual records (the `Search
memories…` box, the `No memories yet` empty state) — the *feature* is
"Learning" but the *entries* are still memories.

## Notes

- Not touched here: the locked-teaser copy (`Long-term memory` / "isn't
enabled on this deployment") — flagged for a separate decision on
whether the teaser should also say "Learning".
- Updated the tab-presence test accordingly; `web-inspector` tests pass
(71).

Targets `mme/memory-core`.
2026-07-01 14:39:11 +02:00
Lukas Moschitz e481011efa feat(web-inspector): rename the Memories tab to Learning
Rename the inspector's user-facing feature name from Memories to Learning:
the menu tab label and the enabled-state panel heading. The internal
"memories" menu key, the Brain icon, the REST wiring, and entry-level copy
(search box, empty states) are unchanged. Update the tab-presence test.
2026-07-01 14:26:11 +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
Jordan Ritter 7d6a2b2a9a docs(runtime): correct forwardHeaders allowlist JSDoc accuracy
Empty/whitespace-only allow/deny/denyPrefixes entries are trimmed and
dropped before the allowlist-mode decision, so allow: [""] stays in
denylist mode rather than switching on exclusive allowlist mode. Also
document that allowlist mode bypasses the built-in default denylist, so
integrators must not allow-list protected/platform headers unintentionally.
2026-06-30 17:23:05 -07:00
Jordan Ritter dde79d1c89 fix(runtime): make forwardHeaders deny authoritative in allowlist mode
`shouldForwardHeader` returned early on `policy.allow` and silently ignored
the integrator's `deny`/`denyPrefixes`, so a header listed in BOTH `allow`
and `deny` still forwarded — a footgun on a security feature.

Rework the predicate so the integrator's own `deny`/`denyPrefixes` (exact,
case-insensitive, and prefix) always strip, including in allowlist mode:
`allow` selects the candidate set, `deny` subtracts from it. The built-in
default denylist is unchanged and still applies only in denylist mode (an
explicit `allow` is a deliberate opt-in), so only the integrator's OWN deny
subtracts from an allowlist.

Also harden `resolveForwardHeadersPolicy`: trim and drop empty/whitespace-only
entries from `deny`/`denyPrefixes`/`allow`. A stray `denyPrefixes:[""]` made
`startsWith("")` true for every header (silently denying ALL forwarding), and
`allow:[""]`/`allow:[" "]` seeded the exclusive allowlist with an entry that
could never match — both integrator typos that now can't silently break
forwarding. Entries are lowercased consistently with existing handling.
2026-06-30 17:12:55 -07:00
Martha Schumann 5df64923cc fix: stabilize inspector live event caches 2026-06-30 17:03:25 -07:00
Jordan Ritter cf951e04f2 test(runtime): harden header-forwarding coverage — clone isolation, case-collision, allowlist boundary
- agent-utils: assert configureAgentForRequest does not mutate the shared
  registered agent; only the per-request clone carries merged inbound headers
  (guards against a cross-request bearer-token leak, #5712).
- header-utils: direct mergeForwardableHeaders unit test for server Authorization
  vs inbound lowercase authorization with a different value — exactly one
  authorization-family key survives carrying the server value (#5712).
- header-utils: shouldForwardHeader boundary tests for the bare 'x' name and the
  empty-string name under both denylist and allowlist policies.
2026-06-30 16:58:11 -07:00
Jordan Ritter 4cdc1e16f5 fix(runtime): make forwardHeadersPolicy optional on CopilotRuntimeLike
The published CopilotRuntimeLike interface (v2 export surface) added
forwardHeadersPolicy as a REQUIRED field, which breaks any external
implementor of the interface — inconsistent with the minor-release
classification. The /run (agent-utils) and /connect (sse/connect) read
sites dereferenced runtime.forwardHeadersPolicy with no coalesce, so a
policy-less object crashed with "Cannot read properties of undefined
(reading 'allow')".

Make the field optional on the interface and coalesce both read sites to
the default resolved policy (resolveForwardHeadersPolicy(undefined),
default-on denylist) when absent. Concrete runtimes (BaseCopilotRuntime)
still always resolve and set it, so behavior is identical for all real
runtimes; the interface is now non-breaking and crash-proof.

Adds a red-green test driving configureAgentForRequest with a runtime
whose forwardHeadersPolicy is undefined: asserts no throw and that the
default denylist applies (x-forwarded-for dropped, custom x-* and
authorization forwarded).
2026-06-30 16:58:06 -07:00
Jordan Ritter 62ed6fa045 test(runtime): cover header-forwarding denylist + config policy on both paths (#5712)
- header-utils.test.ts: new coverage for the default denylist (exact names +
  prefix families, case-insensitive), custom x-* still forwarding, config
  overrides (useDefaultDenylist:false, deny, denyPrefixes, allow allowlist mode),
  and the breadth/precedence interaction. Migrate the inverting assertions
  (x-request-id / X-Forwarded-For now stripped; extract result drops x-request-id)
  and add the new required policy arg to all call sites.
- agent-utils-header-forwarding.test.ts + sse-connect-agent-id.test.ts: /run and
  /connect integration coverage — denylisted infra/platform headers dropped,
  custom x-* + authorization still forward, and a runtime-supplied forwardHeaders
  policy is actually applied (plumb-through). Swap denylisted filler headers for
  non-denylisted custom headers in the precedence regression tests.
- handle-run / handle-connect / intelligence-run-telemetry / get-runtime-info:
  add the resolved forwardHeadersPolicy to mock runtimes that route through the
  header merge so they satisfy the now-required policy.
2026-06-30 16:40:51 -07:00
Jordan Ritter 462fa7ad58 feat(runtime): configurable inbound-header forwarding policy with default infra/platform denylist
Tighten which inbound HTTP headers the v2 runtime forwards onto the outgoing
agent call. The old `authorization` + `x-*` allowlist leaked infrastructure,
proxy, and platform headers (x-forwarded-*, x-real-ip, x-amzn-trace-id,
x-vercel-*, and the Copilot Cloud platform key x-copilotcloud-public-api-key)
to arbitrary configured agent URLs (#5712, breadth half).

- header-utils.ts: add DEFAULT_DENY_HEADER_NAMES + DEFAULT_DENY_HEADER_PREFIXES
  constants and a policy-aware shouldForwardHeader; thread ResolvedForwardHeadersPolicy
  through extractForwardableHeaders and mergeForwardableHeaders. Add the public
  ForwardHeadersConfig and resolveForwardHeadersPolicy (useDefaultDenylist defaults
  to true; deny/denyPrefixes extend the default; allow switches to allowlist mode).
  Server-wins precedence and server-self case-dedup are unchanged.
- runtime.ts: add forwardHeaders?: ForwardHeadersConfig to BaseCopilotRuntimeOptions,
  resolve it once in the constructor into forwardHeadersPolicy (mirroring the
  debug -> ResolvedDebugConfig resolve-once), expose it on CopilotRuntimeLike /
  BaseCopilotRuntime, and add a passthrough getter on the CopilotRuntime shim.
- Apply the resolved policy at both call sites: /run (configureAgentForRequest)
  and /connect (handleSseConnect), so the two paths can never diverge.

Default-on in a minor with { useDefaultDenylist: false } as the documented opt-out.
2026-06-30 16:40:27 -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
Jordan Ritter 636bcad058 fix(runtime): de-duplicate server-vs-server case-collision headers in mergeForwardableHeaders
When an agent is configured with both case-variants of the same header
in agent.headers (e.g. Authorization and authorization), the prior
{ ...base } spread kept both keys — the exact undici comma-join hazard
the function guards against for inbound collisions. Collapse server-self
case-collisions to a single first-occurrence-wins entry; server-wins-over
-inbound and case-insensitive inbound suppression are unchanged.
2026-06-30 15:00:16 -07:00
Jordan Ritter 8bdb3a1c3f test(runtime): cover header precedence — /run + /connect collision, x-* uniqueness, agent-undefined forwarding
Cover the #5712 header-precedence behavior across both paths:

- agent-header-precedence.test.ts: server-configured agent.headers win
  over forwarded inbound headers on collision (case-insensitive), with
  single-key uniqueness assertions for both authorization and the x-*
  family (exactly one surviving key carrying the SERVER value).
- agent-utils-header-forwarding.test.ts: the /run path merges via
  mergeForwardableHeaders so server values are authoritative and inbound
  headers fill only unset keys.
- sse/__tests__/sse-connect-agent-id.test.ts: the /connect path applies
  the same merge, plus the agent-undefined case (no server agent.headers)
  degrades to forwarding allowlisted inbound headers only and does not
  crash.
2026-06-30 14:39:51 -07:00
Jordan Ritter abb85c727d refactor(runtime): thread merged headers into runner.connect() as forward-looking plumbing
The /connect path now builds the same server-wins merged headers as the
/run path and passes them into runner.connect(). This does NOT fix
connect-path auth: no shipped runner consumes the headers field of
AgentRunnerConnectRequest today. The in-memory, intelligence, telemetry,
and sqlite runners all read only threadId from the connect request and
ignore headers entirely. The real outbound header forwarding lives on the
/run path, where agent.headers is mutated before the agent runs.

Passing merged headers here is the correct argument shape for a future
outbound-connecting runner, and keeps the connect path's merge semantics
consistent with /run. The comments and JSDoc are rewritten to state this
plainly rather than implying an active auth fix: the connect-site
cloneAgentForRequest call is documented as the sole agentId-existence
guard (the intelligence branch never re-validates the id), and
cloneAgentForRequest's AbstractAgent | Response (404) dual-return contract
that both callers depend on is now documented.
2026-06-30 14:39:38 -07:00