Add comprehensive unit tests for the xecuteConditions rule engine in
packages/shared/src/utils/conditions.ts, which previously had no test
coverage. Covers all 12 comparison/existence rules, logical AND/OR/NOT
nesting, implicit AND across multiple conditions, and dot-path
resolution (including missing-path and whole-value fallback). Uses the
existing vitest setup in the shared package.
Moves the published packages from 0.0.57 to the current AG-UI release across
@ag-ui/client, core, encoder and proto — 27 declarations in 18 packages.
0.0.59 is the first release carrying the subagent protocol surface
(SUBAGENT_STARTED/FINISHED/ERROR, subagentRunId) along with the null-omission
cleanup, so this is the dependency CopilotKit's subagent work needs.
Scope is packages/** plus the release script noted below. The examples and
showcases sit on a spread of older pins (0.0.40 through 0.0.58) and are left
alone.
One behavioural change comes with the bump. channels-core ships
sanitizeAgentEventStream because @ag-ui/client used to reject a TOOL_CALL_START
carrying parentMessageId: null — the shape @ag-ui/langgraph emits for an
interrupt-triggering tool call. 0.0.59 accepts that null and treats it as
absent, so the two tests asserting the run dies WITHOUT the sanitizer no longer
hold. They now assert the run survives, and the one at agent level still checks
the tool call actually arrives so it cannot pass vacuously. The sanitizer is
untouched and its coercion tests are unchanged; it is simply no longer the
thing keeping such a run alive.
The bump also broke the packed Angular consumer matrix. That job generates a
smoke app from scripts/release/lib/angular-package.ts, whose manifest restated
"@ag-ui/client": "0.0.57" as a literal while packages/angular moved to 0.0.59.
pnpm then installed both copies and the app failed to compile:
TS2322: Type 'SmokeAgent' is not assignable to type 'AbstractAgent'.
Types have separate declarations of a private property '_debug'.
The smoke app imports AbstractAgent directly, so it has to resolve the identical
copy the library ships against. Read that version off the packed manifest --
which verify-angular-package.ts already parses for the Angular support contract
-- instead of restating it, so no future AG-UI bump can desynchronise it.
The v2 runtime client gated anonymous events at 5% and let identified
callers through at 100%, then sent without recording which branch the
event took. A quarter of runtime volume — 24.4% in August and roughly
doubling each month — arrived carrying no record of its own sampling, so
it could not be weighted from the data alone. Downstream had to hardcode
a x20 assumption, which both understates real volume and overstates
growth as the sampled/unsampled mix drifts.
Extract the v1 client's sampling block into shared/telemetry/sampling so
the two clients cannot drift again, and call it from both. Identified
events weigh 1, anonymous ones 1/sampleRate.
Carry telemetry_identified explicitly rather than letting consumers infer
identity from sampleWeight === 1: under COPILOTKIT_TELEMETRY_SAMPLE_RATE=1
anonymous events also weigh 1 and the two populations stop being
distinguishable.
The v1 client also sends every capture to both Segment and the lambda
sink, so one request produces two rows with nothing marking them as
copies. Stamp telemetry_emitter, telemetry_transport, and a per-capture
telemetry_event_id shared by both copies, making the dedupe explicit
instead of inferred from $lib. Both transports keep flowing.
Refs OSS-1017, OSS-1018, OSS-1019
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
## What does this PR do?
Adds the CopilotKit consumer side of ENT-1173 across Shared, Runtime,
Core, Web Inspector, and the existing Shell Docs pages.
- Defines and parses optional trusted Inspector metadata for identity,
plan, license, action, usage, and expiry. Runtime proxies it through a
private, failure-isolated route, and Core refreshes it without changing
connection state.
- Groups Inspector navigation into Threads, Agents, and Learning.
Threads renders finite, unlimited, unknown, overage, and expiring usage
states plus matching trusted plan or license actions.
- Keeps explicit `threadEndpoints` as the only authority for Thread
requests. Locked or absent capability states make no list, subscription,
detail, message, event, or state calls.
- Keeps the zero-thread video, three example Threads, detail tabs, and
guided tour in empty and locked states. General Intelligence remains the
default onboarding path; only trusted `team_self_hosted` metadata uses
self-hosted onboarding.
- Gives an active license with missing Runtime routes a short **Finish
setting up Rich Threads** state. Users can copy a safe coding-agent
prompt or open the public Runtime setup guide. The same copy control
appears in that guide, and raw Markdown/LLM views include the full
prompt.
- Keeps finite usage green below 90%, orange from 90% to the limit, and
red at or above the limit. At 90%, a trusted plan action changes from
**Manage Your Plan** to a purple **Upgrade Your Plan** without changing
its trusted URL, action kind, or telemetry contract.
- Adds a deterministic 33-state loopback lab for CopilotKit developers.
It has no production route or export, is absent from public docs and
package metadata, and is excluded from the npm tarball.
`Expiring Soon` is display-only; this PR does not enable the thread
culler. Managed Enterprise receives no manage-plan action, and Team
Self-Hosted receives no hosted plan action. Optional metadata and the
additive expiry field remain compatible across mixed producer, Runtime,
Core, and Inspector versions.
A small Channels test-only change updates fetch mocks for current
TypeScript types. It changes no Slack or Teams docs or runtime behavior.
## Related PRs and issues
- Refs
[ENT-1173](https://linear.app/copilotkit/issue/ENT-1173/ship-plg-ready-inspector-navigation-metadata-and-locked-threads)
- Producer:
[CopilotKit/Intelligence#696](https://github.com/CopilotKit/Intelligence/pull/696)
## Validation
- `@copilotkit/web-inspector`: 20 files and 372 tests passed; typecheck
and production build passed.
- Shell Docs: 57 files and 383 tests passed; lint, typecheck, and
production build passed. The build generated all 222 static pages.
- Browser checks cover the copy-prompt flow, unchanged white **Manage
Your Plan**, purple **Upgrade Your Plan**, orange 4,500/5,000 usage, and
red 5,000/5,000 usage.
- Independent review found no Critical or Important issues.
- The broader Runtime, React Native, Channels, package-quality,
compatibility, and Node-version checks from the prior pushed head remain
green.
## Checklist
- [x] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [x] I updated the relevant documentation
- [ ] "Allow edits by maintainers" is checked
Pressing Stop mid-stream against a CopilotRuntime + HttpAgent proxy aborts
the upstream agent, which emits a live RUN_ERROR while a text message is
still open. finalizeRunEvents then appended a trailing TEXT_MESSAGE_END
*after* that RUN_ERROR. Because the runners stream finalization events
after everything the agent already emitted, the closer landed past the
terminal and the AG-UI verifier rejected it with "the run has already
errored with 'RUN_ERROR'. No further events can be sent." — crashing the
chat.
finalizeRunEvents (in @copilotkit/shared, consumed by the in-memory,
intelligence, and sqlite runners) now returns early and appends nothing
when the stream already contains a terminal event (RUN_FINISHED or
RUN_ERROR): any message or tool call still open is closed by the terminal
on the client. The abrupt-end path (no terminal -> close open streams +
synthesize a terminal) is unchanged.
Tests:
- finalize-events.test.ts: terminal-present appends nothing (both
RUN_FINISHED and RUN_ERROR) + a named #5812 case.
- in-memory-runner.test.ts: end-to-end mid-stream-stop regression that
asserts no events follow RUN_ERROR and the stream passes AG-UI
verifyEvents (the verifier the browser runs).
- intelligence-runner.test.ts: corrected an assertion that had encoded
the buggy post-terminal TEXT_MESSAGE_END.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Syncs the branch with main (304 commits) to resolve CI type-check failure.
main changed extractForwardableHeaders to require a forwarding policy and
added the mergeForwardableHeaders helper (#5712); handle-suggest now uses
mergeForwardableHeaders(agent.headers, request, runtime.forwardHeadersPolicy ??
resolveForwardHeadersPolicy(undefined)) to match the run handler — fixing the
drift and adopting the server-headers-win / infra-header denylist behavior.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>