Commit Graph

11932 Commits

Author SHA1 Message Date
Jordan Ritter 4ae564f2f9 fix(cvdiag): applyByteCap must not mutate caller metadata or overload _metadata_dropped for size drops (M1 CR B2)
buildEnvelope's accounting branch aliased args.metadata into the
envelope; applyByteCap's in-place trims (Steps 1/2) then mutated the
caller's object as a side effect of pure instrumentation. Shallow-clone
the accounting bag before it enters the envelope (data-plane events
already get a fresh `survivor` from validateMetadata, so only the
accounting branch needed the clone).

applyByteCap Step 3's full-bag size-drop stamped _metadata_dropped, but
that flag is the §6 PII closed-world signal (set by buildEnvelope when
validateMetadata drops unknown keys); overloading it for a SIZE drop
pollutes PB drift queries. A size-drop is already observable via the
_truncated flag stamped earlier, so Step 3 now drops the bag without
touching _metadata_dropped. The genuine PII stamp is unchanged.

Call sites (both private, in-module only):
  buildEnvelope: emit() (emit.ts:309), flush() accounting (emit.ts:514).
  applyByteCap:  buildEnvelope() (emit.ts:388).
No external callers.
2026-06-18 15:45:28 -07:00
Jordan Ritter fd99348fe3 fix(cvdiag): scrub modern hyphenated sk-proj-/sk-ant- API keys (M1 CR B3)
The old SK_KEY_REGEX /sk-[A-Za-z0-9]{16,}/ stopped its character class at
the first hyphen, so modern hyphenated-prefix keys leaked into PocketBase:
the `proj` (4) / `ant` (3) / `api03` (5) prefix segments never reached the
required 16-char run, so `sk-proj-…` and `sk-ant-api03-…` never matched and
were stored verbatim — defeating the §6 secret-scrub guarantee for the two
most common real-world key formats.

New pattern: /sk-(?:[A-Za-z0-9]+-)*[A-Za-z0-9]{16,}/g
  `sk-` then zero-or-more hyphen-terminated alnum SEGMENTS (the prefix words)
  followed by a ≥16-char alnum entropy TAIL.

Why it does not over-redact ordinary hyphenated prose: the mandatory 16+
alphanumeric tail is the entropy gate. Words like "ask-me-later" or
"task-list" have no 16+ contiguous alnum run after an `sk-`, so they never
match (negative test asserts the phrase is returned unchanged). The legacy
`sk-<16+ alnum>` form is preserved as the zero-segment case.

SCRUB_REPLACEMENT and scrubSecrets structure unchanged. Four new tests
(sk-proj-, sk-ant-api03-, legacy sk-<16+>, negative over-redaction);
RED on the two hyphenated cases pre-fix, GREEN after. Full cvdiag suite
110/110.
2026-06-18 15:45:27 -07:00
Jordan Ritter ce2c5daa7f fix(cvdiag): flush() leaves queue intact when no PB writer is configured (M1 CR B1)
Move the `pbWriter === undefined` early-return to the TOP of flush(), before
the queue.splice and the drop-accounting block. Previously, with no writer,
flush() spliced the queue into `batch` and discarded it on the trailing
early-return while resetting droppedSinceFlush to 0 — silently losing all
queued telemetry every flush window. Under { autoFlush: true } with no writer
this was continuous data loss, contradicting the documented pbWriter contract
("When absent, events stay queued").

flush() callers: the startBackgroundFlush() interval timer and any manual
flush() call. With a writer present, the A3 drop-accounting + reset-only-
after-landing behavior is unchanged.
2026-06-18 15:45:27 -07:00
Jordan Ritter f4b735169b fix(cvdiag): flush() builds queue_dropped accounting event directly into batch, never loses drop count (M1 CR A3)
flush() previously zeroed droppedSinceFlush BEFORE confirming the accounting
emit() landed, then recovered the just-enqueued event via a fragile second
splice of the whole queue (which APPENDS despite the "prepend" docstring). If
that emit() returned null (validateEnvelope failure / exception) the drop count
AND the cvdiag.queue_dropped record were permanently lost.

Fix: extract the envelope-construction + validateEnvelope + applyByteCap logic
of emit() into a private buildEnvelope() helper (no enqueue side effect). flush()
now calls buildEnvelope() for the accounting event and pushes the result DIRECTLY
into the outgoing batch (no queue round-trip / re-splice). droppedSinceFlush is
reset to 0 ONLY after the accounting envelope is in the batch, so a null/throw
retains the count for the next flush. Docstring updated to "append" (event order
in a best-effort batch is not load-bearing — the classifier re-sorts by mono_ns/ts).

Call sites of the extracted buildEnvelope(): emit() (enqueues result, still
resolves/returns CvdiagEnvelope|null) and flush() (appends to batch, still
resolves/never-rejects). Public method signatures unchanged.

Red-green: src/cvdiag/emit.test.ts. Loss-path test forces the accounting build
to return null and asserts the drop count is retained (lands on the next flush);
RED on original = 0 queue_dropped events land (count silently lost), GREEN after
fix = exactly 1 lands with _dropped_count preserved.
2026-06-18 15:34:03 -07:00
Jordan Ritter 0ca29a4fc4 fix(cvdiag): applyByteCap enforces tier byte cap for scalar/short-string-heavy envelopes (M1 CR A2)
applyByteCap previously stamped _truncated:true and trimmed only >64-char
string values / nested objects in metadata. An envelope over the tier byte
cap due to many short-string or numeric/boolean metadata values (none
reachable by that pass) was stamped truncated yet still enqueued OVER cap,
violating spec §7 R5-F3 ("the whole serialized envelope must fit the tier
byte cap").

Fix escalates while still over cap: (1) legacy >64-char/object trim, then
(2) clamp ALL string values progressively, then (3) drop metadata to {}
(stamping _metadata_dropped). Fixed scalar envelope fields are bounded by
construction, so an empty metadata bag is the hard guarantee the enqueued
row fits any realistic cap. Method stays pure-instrumentation: it never
throws.

Call sites: applyByteCap is private; emit() (emit.ts:361) is the sole caller
and already wraps it in try/catch. Post-condition holds: on return the
serialized envelope is <= cap OR metadata is already {}.
2026-06-18 15:32:52 -07:00
Jordan Ritter b9ff5a49fd fix(cvdiag): scrub secrets in metadata values + bare-token URL userinfo (M1 CR A1)
validateMetadata kept surviving metadata VALUES verbatim and never scrubbed
them, so Bearer/sk-/URL-userinfo secrets in free-text fields (e.g.
*.message_scrubbed, probe.*.url) reached PocketBase unscrubbed — violating
spec §6 (the field is literally named message_scrubbed). Now every SURVIVING
string metadata value is run through scrubSecrets; non-string values are left
untouched.

Also tighten URL_USERINFO_REGEX: the old pattern required a user:password@
colon, so a bare-token userinfo (scheme://token@, e.g. https://ghp_xxx@host)
was NOT redacted. The new pattern matches any non-/, non-@, non-ws run before
@, covering BOTH the colon and no-colon forms; the $1[REDACTED]@ replacement
shape is unchanged and the / exclusion confines the match to the authority.

Import-cycle avoidance (approach a): moved scrubSecrets + its regex constants
into a new leaf module scrub.ts that has NO intra-cvdiag imports. Applying the
scrub inside validateMetadata required schema.ts to call scrubSecrets, but
edge-headers.ts already imports EDGE_HEADER_KEYS from schema.ts, so importing
scrubSecrets from edge-headers into schema would form a schema -> edge-headers
-> schema cycle. The leaf module is imported by both; edge-headers re-exports
the symbols so the historical public surface is preserved.

scrubSecrets call-site enumeration (all still resolve):
  - src/probes/drivers/d4-chat-roundtrip.ts (imports from ./cvdiag/index.js;
    index.ts does `export * from ./edge-headers.js`, which re-exports scrub.ts)
  - src/cvdiag/raw-byte-capture.ts (imports from ./edge-headers.js — re-export)
  - src/cvdiag/index.ts (`export *` from edge-headers — re-export intact)
2026-06-18 15:32:52 -07:00
Jerel Velarde 4d2b1584f4 docs(cookbook): flatten showcase paths to examples/showcases/oracle-agent-memory layout 2026-06-18 15:30:27 -07:00
Martha Kelly Schumann 7eb40b0524 docs(showcase): fix shared randomUUID imports (#5456)
## Summary
- fix Showcase docs snippets that import `randomUUID` from non-existent
`@copilotkit/shared/v2`
- use the published `@copilotkit/shared` entrypoint instead
- move the fix to the publishing Showcase docs source under
`showcase/shell-docs`

## Linear
- FAC-65

## Verification
- `rg -n "@copilotkit/shared/v2" showcase/shell-docs/src/content`
returns no matches
- `pnpm validate:model-names`
- `npm ci --ignore-scripts` in `showcase/shell-docs`
- `npm run build` in `showcase/shell-docs`
- `git diff --check`
- pre-commit passed after refreshing root dependencies with `pnpm
install`
2026-06-18 15:21:56 -07:00
Martha Kelly Schumann 7f73f2c4ac docs(showcase): fix Deep Agents state streaming schema (#5556)
## Summary
- wrap the Deep Agents TypeScript `observed_steps` custom state field in
`zodState`
- clarify that `step_progress_tool.steps` intentionally maps into the
`observed_steps` state field
- move the fix to the publishing Showcase docs source under
`showcase/shell-docs`

## Why
The QA report called out a mismatch between `steps` and
`observed_steps`. That mapping is intentional via `stateItem`; the
actual issue is that the custom state field was declared as plain Zod.
In LangGraph JS, fields that are not wrapped with `zodState` can be
filtered out of the AG-UI state snapshot, so the tool call can happen
while the UI never receives the rendered state.

## Verification
- `pnpm validate:model-names`
- `npm ci --ignore-scripts` in `showcase/shell-docs`
- `npm run build` in `showcase/shell-docs`
- `git diff --check`
2026-06-18 15:21:45 -07:00
Jordan Ritter 8aecedcc6e chore(cvdiag): merge --ab-report subcommand wiring into integration 2026-06-18 15:11:59 -07:00
Jordan Ritter 8b86e9a877 feat(cvdiag): wire --ab-report subcommand into cvdiag CLI 2026-06-18 15:11:38 -07:00
Mike Ryan e183d2fa43 chore: release monorepo v1.61.0 (#5560)
## Summary
- bump monorepo package versions to 1.61.0
- keep plugin metadata versions aligned with the runtime package

## Validation
- pnpm check:plugin-skills
- pre-commit hook ran package test, publint, and attw targets
v1.61.0
2026-06-18 15:09:20 -07:00
Jerel Velarde 09c192ea37 docs(cookbook): live demo embed + point source links at examples/showcases/oracle-agent-memory 2026-06-18 15:09:06 -07:00
Jordan Ritter 02e8e205f1 chore(cvdiag): merge L3-A internal-routing A/B into integration 2026-06-18 15:06:49 -07:00
Jordan Ritter 1248461eba feat(cvdiag): Railway-internal routing A/B — HMAC guard + dual-run + ab-report (L3-A) 2026-06-18 15:06:13 -07:00
Martha Kelly Schumann f8beaf787f Merge branch 'main' into docs/FAC-77-state-streaming-schema 2026-06-18 15:04:23 -07:00
Mike Ryan a296c57ef4 fix: sync plugin metadata before release PR creation 2026-06-18 15:03:10 -07:00
Jordan Ritter 1ccd782b58 chore(cvdiag): merge L2-B cvdiag CLI into integration 2026-06-18 15:01:33 -07:00
Jordan Ritter ca84419656 feat(cvdiag): showcase cvdiag CLI — timeline/classify/replay/purge (L2-B) 2026-06-18 15:01:04 -07:00
Mike Ryan b094156537 chore: release monorepo v1.61.0 2026-06-18 15:00:19 -07:00
github-actions[bot] 20cd06f62e style: auto-fix formatting 2026-06-18 21:55:16 +00:00
Jordan Ritter 1994d930e5 chore(cvdiag): merge L2-C raw-byte capture pipeline into integration 2026-06-18 14:54:33 -07:00
Sam Julien 4c311ac3fb chore(docs): add shell-docs symlink 2026-06-18 14:54:25 -07:00
Jordan Ritter 73ad95a3db feat(cvdiag): raw-byte capture pipeline (decode→scrub→html-strip→cap, DEBUG-only) (L2-C) 2026-06-18 14:54:02 -07:00
Jordan Ritter 08a7b3cdff chore(cvdiag): merge L2-A flap classifier into integration 2026-06-18 14:51:27 -07:00
Jordan Ritter e7bf4fa3fd feat(cvdiag): full 8-class flap classifier + synthetic ground-truth suite (L2-A) 2026-06-18 14:50:47 -07:00
Martha Schumann 72007b1d6a docs(showcase): move shared import fix to shell docs 2026-06-18 14:49:58 -07:00
Jordan Ritter e56ae02eab chore(cvdiag): merge L2-D CI perf-regression gate into integration 2026-06-18 14:48:23 -07:00
Jordan Ritter 07915f3c1c feat(cvdiag): CI perf-regression gate for emit cost (100µs median / 250µs p99) (L2-D) 2026-06-18 14:47:33 -07:00
Martha Schumann c6028bbdab Merge remote-tracking branch 'origin/main' into docs/FAC-65-shared-v2-imports 2026-06-18 14:44:08 -07:00
Martha Schumann 597690fd3a Merge remote-tracking branch 'origin/docs/FAC-77-state-streaming-schema' into docs/FAC-77-state-streaming-schema 2026-06-18 14:43:22 -07:00
Martha Schumann bdaba9aeca docs(showcase): move state streaming fix to shell docs 2026-06-18 14:42:54 -07:00
Mike Ryan f5c72d246e chore(deps): bump @copilotkit/license-verifier to ~0.5.0 (#5552)
## What

Bumps `@copilotkit/license-verifier` from `0.4.2` to `0.5.0`:
- `packages/runtime/package.json`: `~0.4.2` → `~0.5.0`
- `packages/shared/package.json`: `~0.4.2` → `~0.5.0`
- root `package.json` `pnpm.overrides`: `~0.4.2` → `~0.5.0` (this
override was the effective version gate — without bumping it the
lockfile stayed pinned at 0.4.2)
- `pnpm-lock.yaml`: regenerated, now resolves `0.5.0`
- `.npmrc`: added `@copilotkit/license-verifier` to
`minimum-release-age-exclude[]` (same treatment as `@ag-ui/langgraph`)
so the freshly-published 0.5.0 could be locked before clearing the 24h
`minimum-release-age` guard

## Status

0.5.0 is published and the lockfile resolves it cleanly. The earlier
"blocked on publish" state is resolved. Ready to come out of draft
pending CI.

Linear: ENT-938
2026-06-18 14:41:30 -07:00
Jordan Ritter 03f33fca48 chore(cvdiag): merge L1-D3 Python backend instrumentation into integration 2026-06-18 14:41:10 -07:00
Jordan Ritter a74f423ef4 chore(cvdiag): merge L1-D2 Python backend instrumentation into integration 2026-06-18 14:41:09 -07:00
Jordan Ritter 0bfdc75dff chore(cvdiag): merge L1-D1 Python backend instrumentation into integration 2026-06-18 14:41:09 -07:00
Martha Schumann c1e2566c58 Merge remote-tracking branch 'origin/main' into docs/FAC-77-state-streaming-schema 2026-06-18 14:40:55 -07:00
Jordan Ritter 24de3d1710 feat(cvdiag): backend instrumentation for google-adk + langroid + langgraph-fastapi (L1-D3) 2026-06-18 14:40:32 -07:00
Jordan Ritter 84369d5887 feat(cvdiag): backend instrumentation for llamaindex + ms-agent-python + claude-sdk-python (L1-D1) 2026-06-18 14:37:47 -07:00
Jordan Ritter 9d66761064 feat(cvdiag): backend instrumentation for pydantic-ai + crewai-crews + agno (L1-D2) 2026-06-18 14:37:10 -07:00
Austin Merrick 4dab6d38f8 fix(shell-docs): align callout accent colors to brand
Fumadocs' default callout palette (generic blue/amber/green) renders the
docs <Callout> accent and left bar off-brand against the purple-anchored
theme — and on the main docs route the info/success tokens weren't emitted
at all, falling back to the near-white muted color.

Define --color-fd-info/warning/success as plain :root custom properties
(not @theme tokens, which Tailwind v4 tree-shakes when no utility class
references them — the Callout reads them only via inline var()). Map info
-> brand accent (purple), warning -> the existing docs --warning orange,
success -> brand mint (new --success token, mint/800 light, mint/400 dark).
All theme-aware; error stays mapped to --destructive via shadcn.css.
2026-06-18 14:35:43 -07:00
Benjamin Taylor b71583c41e Merge remote-tracking branch 'origin/main' into chore/ent-938-bump-license-verifier 2026-06-18 16:35:20 -05:00
Benjamin Taylor 73b6713b69 Merge remote-tracking branch 'origin/main' into chore/ent-938-bump-license-verifier
# Conflicts:
#	.npmrc
#	packages/shared/package.json
#	pnpm-lock.yaml
2026-06-18 16:32:30 -05:00
Sam Julien cd40146d82 fix(react-core): honor selfManagedAgents in CopilotKit wrapper validation (#5551)
## Summary

Fixes #5417. The v1 `<CopilotKit>` wrapper's `validateProps` threw
`ConfigurationError: Missing required prop: 'runtimeUrl' or
'publicApiKey' or 'publicLicenseKey'` whenever neither `runtimeUrl` nor
a public key was supplied — without considering self-managed agents.
This rejected the documented self-managed-agent setup, even though the
underlying v2 `CopilotKitProvider` accepts it via its `hasLocalAgents`
gate.

- **Fix:** `validateProps` now mirrors the provider's `hasLocalAgents`
check, so `selfManagedAgents` and `agents__unsafe_dev_only` satisfy the
requirement without a `runtimeUrl` or Cloud key.
- **Test:** new rendering test pins the behavior — still throws when
nothing is configured, no longer throws when local agents are supplied.
- **Docs:** the showcase error-reference "v1 behaves differently"
callout claimed the wrapper throws unconditionally and rejects
`selfManagedAgents` (both now false); corrected, and dropped the "(v2
only)" label on the self-managed example.

## Test plan

- [x] `nx test react-core` — 1284 passing, 0 failing
- [x] New test fails before the fix (red) and passes after (green)
- [x] No new type errors introduced (pre-existing `tsc` noise unchanged
vs `main`)
2026-06-18 14:32:14 -07:00
Jordan Ritter 6d72936fcb chore(cvdiag): merge L1-I backend instrumentation into integration 2026-06-18 14:30:51 -07:00
Jordan Ritter 4cfa10d5eb chore(cvdiag): merge L1-G backend instrumentation into integration 2026-06-18 14:30:51 -07:00
Jordan Ritter ac4f582721 chore(cvdiag): merge L1-F backend instrumentation into integration 2026-06-18 14:30:50 -07:00
Jordan Ritter 04e2a19e3c chore(cvdiag): merge L1-E backend instrumentation into integration 2026-06-18 14:30:50 -07:00
Jordan Ritter c9d6e0dc36 chore(cvdiag): merge L1-C backend instrumentation into integration 2026-06-18 14:30:50 -07:00
Jordan Ritter 44ddd1220a chore(cvdiag): merge L1-A backend instrumentation into integration 2026-06-18 14:30:49 -07:00