Resolve the single conflict in packages/web-inspector/src/index.ts by keeping
both additions: this branch's CpkMemoryList memory-tab element and main's
ɵCpkThreadDetails back-compat alias (independent top-level declarations).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
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.
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.
Three snapshot tests (lines 751/771/789) call test() while the file uses
explicit vitest named imports. They pass at runtime via vitest's global
but fail tsc check-types (TS2593). Add test to the import.
Memory, NewMemory, MemoryChanges, MemoryKind, and MemoryScope are the
memory types surfaced by the useMemories / injectMemories hook result
shapes, so export them unprefixed as supported public API instead of
behind the ɵ "internal" marker. Internal memory plumbing (MemoryStore,
the selectMemories* selectors, state/context/event types,
createMemoryStore) keeps the ɵ prefix.
Updates the react-core and angular hook signatures, the web-inspector
Memories tab, and the affected tests to the unprefixed names.
Add three flat test cases verifying the silent-degrade contract:
404/501 list response sets available:false with no error; 500 response
sets error and keeps available:true; 404 subscribe response is silent
with no console.warn emitted.
Adds listUnavailable and credentialsUnavailable to memoryRestEvents, adds
available: boolean to MemoryState (defaulting to true), resets available to
true on contextChanged and listRequested, and handles listUnavailable by
clearing memories and setting available: false with a session guard.
The memory store's socket effect created the `user_meta:memories:<code>`
channel and observed its events, but never subscribed the join-outcome
stream — and `ɵphoenixChannel$` only calls `channel.join()` when that stream
is subscribed. So the socket connected but no `phx_join` was ever sent: the
gateway saw the connection, the channel was never joined, and saved memories
never pushed to the client (REST snapshot worked; live deltas silently never
arrived). The thread store joins because its merged `joinOutcome$` subscribes
the stream.
Merge `ɵjoinPhoenixChannel$(channel$)` into the socket effect's output so the
join actually fires; swallow a failed/timed-out join so a transient rejection
doesn't tear down the metadata stream (Phoenix re-attempts on reconnect). Add
a `joinCount` spy to MockChannel and assert the realtime test actually joins —
this regression passed before because the mock delivered events without a join.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The @copilotkit/core build (tsdown with dts generation) has a working set
of about 3.45GB. Node's default old-space ceiling is roughly 4GB and CI pins
NODE_OPTIONS to 4096, leaving almost no headroom. Under nx run-many the build
competes for CPU with sibling builds, GC falls behind, and the process tips
over the heap limit. nx flags it as a flaky task and pre-commit/CI builds fail
intermittently with a V8 heap OOM.
Bake the ceiling into the core build script with cross-env so every invocation
path gets consistent headroom: local lefthook hooks, nx run-many, CI, and
direct pnpm build, on every platform including Windows. 8192 matches the value
already used by the e2e workflow and gives roughly 2x headroom over the working
set.
Scoped to core only; it is the single package that OOMs.
Add the thread store (optimistic add/rename/archive/delete with delete
rollback-on-reject, session-guarded results, startNewThread/refetchThreads,
getServerState/getServerSnapshot, per-store memoized selectors, and non-fatal
realtime diagnostics for channel-join and metadata-credential failures) and
register the "threads" feature so the SDK can gate thread management.
ɵMemoryStore exposes addMemory(input: NewMemory) and
updateMemory(id, changes: MemoryChanges), but those input types were
internal — a thin framework binding (useMemories / injectMemories) had
no way to name them when wrapping the store. Export them alongside the
existing ɵMemory / ɵMemoryKind / ɵMemoryScope.
refresh() now returns a promise that rejects when the re-pull fails
(listFailed) or the store is stopped mid-flight, instead of resolving
silently as if it succeeded — symmetric with the mutation methods. The
error still lands in the error selector for declarative consumers.
toMutationBody no longer defaults scope to "user"; it forwards scope only
when the caller supplies it, so the platform owns the single default.
refresh() now resolves once the re-pulled snapshot settles (listSucceeded/
listFailed) for the current session, or immediately when no context is set —
so a useMemories-style binding can expose refresh(): Promise<void>. Mirrors
trackMutation's completion handling.
Fixes#5635.
## What
Headers set directly on an `HttpAgent` registered via
`agents__unsafe_dev_only` were silently replaced by the provider
headers. Per-agent auth headers (like an `Authorization` for a
self-hosted backend) got dropped, causing 401s.
## Why
`AgentRegistry.applyHeadersToAgent` did `agent.headers = {
...core.headers }`, a full overwrite. The run handler and the react-core
`useAgent` hook did the same. So an agent built with its own headers
lost them on registration, on every `setHeaders`, and before each
request.
## Fix
Merge instead of replace. The registry captures each agent's own headers
once (in a WeakMap, before the first apply) and rebuilds `{
...ownHeaders, ...coreHeaders }`. Core wins on key conflicts, which
keeps the existing "provider headers are authoritative" and logout/clear
behavior. All header application now routes through one method,
`CopilotKitCore.applyHeadersToAgent`, so runs never clobber per-agent
headers.
Vue and Angular benefit too: they dispatch runs through `core.runAgent`
/ `connectAgent`, so the merge is re-applied before every request.
## Tests
- core: 3 new cases in `core-headers.test.ts` (preserve, merge,
retain-across-setHeaders); existing overwrite and clear tests still
pass.
- react-core: new `use-agent-provider-headers.e2e.test.tsx` with a real
provider and an HttpAgent that has its own headers.
Verified locally: format, lint, full core + react-core suites, and both
builds.