Commit Graph

10887 Commits

Author SHA1 Message Date
Jordan Ritter 47d3b594ce fix(showcase): align ms-agent-python D6 fixtures to LGP (152/33 → 174/11)
Same pattern as ms-agent-dotnet: full d4 chat.json rewrite + d6 mirrors. Dropped stale
turnIndex gates and broad shadow matchers. Default-catchall now green via page-level
shadcn-catchall-renderer. 11 residual: declarative-gen-ui charts, multimodal conveyance,
tool-rendering, reasoning-chain.
2026-05-30 09:53:35 -07:00
Jordan Ritter afa4cf0cf2 fix(showcase): align ms-agent-dotnet D6 fixtures to LGP (155/27 → 177/5)
Full d4 chat.json rewrite + d6 mirrors. Dropped stale turnIndex gates and broad shadow
matchers that no longer reflect LGP-canonical conveyance. Default-catchall now green via
page-level shadcn-catchall-renderer (not react-core-gated). 5 residual: chat-slots, hitl,
interrupt-headless, readonly-state.
2026-05-30 09:53:25 -07:00
Jordan Ritter dff840b76a fix(showcase): downgrade stale-green e2e rows to degraded in the dashboard
When the e2e driver stops writing e2e:<slug>/<feature> status rows, the last
row freezes. A green row then reads as a healthy D3 forever, so the depth
ladder shows a false-green D3 that masks a dead probe pipeline (a wedged
browser pool, an outage) instead of surfacing it.

buildCellModel (cell-model.ts) and deriveDepth (depth-utils.ts) now treat a
green e2e row whose observed_at is older than E2E_STALE_AFTER_MS (6h, matching
the original stale-window model) as degraded/amber, so it no longer credits
D3. Only green is downgraded — a stale red/degraded row already signals a
problem and is left as-is. An unparseable timestamp is treated as not-stale so
staleness is never inferred from bad data.

Existing test fixtures that hardcoded old observed_at timestamps now default
to a recent value so green rows are not treated as stale; the new staleness
tests pass explicit timestamps.
2026-05-30 09:53:01 -07:00
Jordan Ritter f7e88dd671 fix(showcase): recover browser pool after relaunch failure instead of draining to 0
When a chromium process crashes, recycleSlot relaunches it; if that launch
threw, the slot was permanently removed via slots.splice. A single transient
launch failure (OOM spike, fd exhaustion) thus monotonically shrank the pool
to empty with no self-heal, after which every e2e probe failed with
launcher-error / BrowserPool acquire timeout.

The recycle now retries the relaunch with bounded backoff; on exhaustion it
keeps the slot (capacity preserved) and parks it as relaunchPending for a lazy
retry on the next acquire. acquire() also re-initializes the pool as a backstop
when every slot has been lost (slots.length === 0), so the pool always
self-heals rather than wedging.
2026-05-30 09:52:15 -07:00
Jordan Ritter e9c18611e8 test: use a valid WatchSource for deps and correct toolCallId test comment
vue: replace the string-literal deps array (which was laundered through
`as unknown as any[]` because string is not a valid WatchSource) with
a getter-style deps array (`() => "compact"`), which is a valid
WatchSource<unknown>. The reference-identity assertion still holds.

react-core: rewrite the toolCallId comment to accurately describe what
this test verifies. The test calls config.render directly with
useRenderTool mocked, so it does not exercise the spread-adapter path
end-to-end — it only locks that useDefaultRenderTool passes the user's
render through untouched.
2026-05-30 09:49:05 -07:00
Jordan Ritter 768fb667ab test(react-core): pass toolCallId in default-renderer tests, drop narrowing casts
The 3 "default renderer" tests in use-default-render-tool.test.tsx were
narrowing config.render via an as-cast that omitted the now-required
toolCallId field on DefaultRenderProps, laundering the type. Switch the
casts to the real DefaultRenderProps shape and pass a realistic
toolCallId on every <DefaultRenderer/> invocation. No behavior change.
2026-05-30 09:49:04 -07:00
Jordan Ritter c474d894ff fix(react-core): add toolCallId to DefaultRenderProps for vue parity
The runtime path already forwarded toolCallId to wildcard render functions
(useRenderTool spreads ReactToolCallRenderer props, which include toolCallId),
but the static DefaultRenderProps type omitted it. Vue's sibling type already
declared the field. This divergence forced an `as unknown as { toolCallId }`
cast in the react-core test.

Declare toolCallId on DefaultRenderProps (mirroring vue), thread it through
the defaultToolCallRenderAdapter so the now-required field is genuinely
populated, export the type, and drop the cast plus stale comments in the
test that claimed the field was runtime-only.
2026-05-30 09:49:04 -07:00
Jordan Ritter 81295552d1 test(react-core): cover toolCallId forwarding in default tool renderer
Mirror the Vue sibling test 'forwards toolCallId to custom wildcard render
function' so the react-core suite locks the same regression: the wildcard
hook must forward toolCallId to a custom render function. Closes a
symmetry gap in the cross-framework testid PR.
2026-05-30 09:49:04 -07:00
Jordan Ritter 891ceb2ed0 feat(ui): stable testids on built-in default tool-call renderer
E2E tests for the chat surface (e.g. showcase's
tool-rendering-default-catchall canonical spec) need a stable selector
to count and inspect tool-call cards rendered by the framework's
built-in DefaultToolCallRenderer when an integration registers zero
custom render hooks. react-core's renderer already emits a
data-testid="copilot-tool-render" wrapper with data-tool-name,
data-status, data-args and data-result; vue's equivalent renderer was
missing them, so the same e2e test counted 0 cards there.

Mirrors react-core's contract onto the vue DefaultToolCallRenderer:

- packages/vue/src/v2/hooks/use-default-render-tool.ts: wrap the card
  in a div carrying data-testid="copilot-tool-render", data-tool-name,
  data-status, data-args and data-result (via the same
  safeStringifyForAttr helper shape as react-core); tag the inner
  name/status spans with copilot-tool-render-name and
  copilot-tool-render-status.

Locks the contract into unit tests in both frameworks so the markers
cannot silently disappear in a future refactor:

- packages/vue/src/v2/hooks/__tests__/use-default-render-tool.test.ts:
  new "default renderer emits stable copilot-tool-render testid and
  metadata attrs" test (red-green proven locally by stashing the
  source change).
- packages/react-core/src/v2/hooks/__tests__/use-default-render-tool.test.tsx:
  mirroring test asserting the same wrapper/data-* attrs and inner
  testids (red-green proven by sentinel-swapping the testid).

Scope: purely additive — no behavior, rendering, or styling changes.
The new attributes are inert at runtime; only e2e and unit tests read
them. angular has no built-in default renderer (only renders when the
user registers a wildcard) and react-native deliberately excludes the
default renderer (web DOM-only), so no changes are needed there.

This unblocks the showcase tool-rendering-default-catchall D6 spec
across frontends; a react-core release will follow once merged.
2026-05-30 09:49:04 -07:00
Tyler Slaton 8eb339e3e6 feat(ci): bundle-size tracking + ES-compat checks (OSS-123, OSS-121) (#5051) 2026-05-30 09:21:25 -07:00
Jordan Ritter 5e611c6fbb fix(showcase): repair Verify Deploy (webhooks /api/health + harness payload) (#5111)
## Summary

Fixes the two failures in the `Showcase: Verify Deploy` workflow on
`main`. Both are pre-existing (since the staging-verify wiring landed)
and independent of recent PRs:

- **webhooks health-path mismatch** — the verify probe checks
`/api/health` (the standard used by every API-shaped service driver:
agent, eval, pocketbase, webhooks), but the `webhooks` (eval-webhook)
service only served `/health`, so the probe got HTTP 404. Fix: the
service now also serves `/api/health` (same `{ ok: true }` body),
matching the standard. `/health` is kept for back-compat.
- **notify-harness payload schema mismatch** — `showcase_deploy.yml`
posted `{ state, services }` to the harness deploy-webhook, but the
ingest endpoint's schema is `.strict()` and requires `{ succeeded[],
failed[], cancelled }`, rejecting the unknown `state` key → HTTP 400.
Every push-to-main notify-harness call had been 400-ing, so the harness
dashboard received no deploy-result events. Fix: the workflow now emits
a `failed_services` list from the redeploy summary and builds the
payload as `{ services: succeeded ∪ failed, succeeded, failed, cancelled
}` (optional run/build URLs omitted when empty so the schema's `.url()`
validation passes).

## Test plan

- [ ] Local: `tsc --noEmit` (eval-webhook) clean; oxfmt + oxlint clean;
`actionlint showcase_deploy.yml` clean
- [ ] Local: jq dry-run of the new payload across
success/failure/cancelled/empty cases produces a schema-valid object
with no `state` key
- [ ] Post-merge (push-to-main): `Showcase: Build & Push` redeploys
webhooks with `/api/health`, then `Showcase: Verify Deploy` goes green
(webhooks probe 200) and notify-harness POST returns 200
2026-05-30 08:54:38 -07:00
Jordan Ritter df1d62d0be fix(showcase): send schema-correct succeeded/failed/cancelled to harness deploy webhook
deploy.yml's notify-harness step was sending {state, services, ...},
but the harness ingest schema at showcase/harness/src/http/webhooks/
deploy.ts is .strict() and requires succeeded/failed/cancelled arrays
+ bool. Every push-to-main notify-harness POST has been 400ing as
invalid-payload (unknown key 'state') since the schema landed.

Build the payload from the redeploy gate's success-and-error buckets:

- Emit failed_services alongside ok_services from the redeploy-gate
  step (services whose status==error), and expose both as resolve-matrix
  job outputs.
- Rewrite the notify-harness payload to drop state and emit:
  succeeded=ok_services, failed=failed_services, cancelled=(verify
  conclusion==cancelled), services=union of succeeded and failed.
- Omit buildRunId/buildRunUrl entirely when empty (the schema runs
  .url() on buildRunUrl, so an empty string would be rejected). Same
  treatment for runUrl as defense-in-depth.
- Group the no-summary echoes through a single >>GITHUB_OUTPUT block
  so shellcheck SC2129 stays clean once a third echo is added.
2026-05-30 08:48:43 -07:00
Jordan Ritter b7a4c9f714 fix(showcase): serve /api/health on webhooks service to match probe standard
The eval-webhook server only exposed /health, but the verify-deploy
probe (showcase/scripts/verify-deploy.drivers.webhooks.ts) and every
other API-shaped showcase backend (agent, eval, pocketbase) standardize
on /api/health. Add the /api/health route so the service matches the
SSOT convention the probe expects; keep /health for back-compat with
any pre-existing callers.
2026-05-30 08:48:32 -07:00
Jordan Ritter 4211278ae3 test(showcase): fleet test-parity — align all integration e2e specs to LGP canonical
Each non-LGP integration carried its own drifted/stale copy of the e2e specs, causing
inconsistent behavior and noisy diffs across the fleet. Copied langgraph-python's canonical
specs verbatim across ~15 integrations (576 spec files total, SHA-1-verified identical to
LGP) so every integration runs the same assertions.

Also removed 2 orphan specs whose underlying demo pages do not exist:
- showcase/integrations/agno/tests/e2e/hitl-in-chat-booking.spec.ts
- showcase/integrations/built-in-agent/tests/e2e/shared-state-write.spec.ts

Integration-specific variant specs were intentionally left as-is: reasoning-default-render,
byoc-*, agentic-chat-reasoning, and shared-state-write where the demo exists. google-adk and
langgraph-typescript were already in parity from earlier commits and show no new changes.
2026-05-30 08:43:12 -07:00
github-actions[bot] bb860166e8 style: auto-fix formatting 2026-05-30 07:00:35 +00:00
Jordan Ritter 26d1204607 fix(showcase): wire google-adk default-catchall to shared 4-pill suggestions
Replaced inline 3-pill useConfigureSuggestions with useSuggestions() import
matching LGP; needs image rebuild to take effect.
2026-05-29 23:59:46 -07:00
Jordan Ritter a49ba1ef74 fix(showcase): align google-adk D6 fixtures to LGP contract
Narrowed d4 shadow matchers, removed whole-thread gates, render_a2ui inner tool
name, root chunkSize for emoji surrogate pairs, sentinel-disabled the duplicate
open-gen-ui-advanced matcher.
2026-05-29 23:59:41 -07:00
Jordan Ritter 93b5fdd467 test(showcase): align google-adk e2e specs to langgraph-python canonical
Integration specs had drifted/staled vs LGP gold standard; copied LGP's canonical
specs verbatim and removed the orphan shared-state-write spec whose demo exists
in neither LGP nor google-adk.
2026-05-29 23:59:32 -07:00
Jordan Ritter 67f5efdaf6 fix(showcase): forward x-aimock-context per-request in google-adk routes
@ag-ui/client HttpAgent only forwards static this.headers, so rebuild per-request
with extractForwardedHeaders(req); restores D6 conveyance.
2026-05-29 23:59:18 -07:00
Jordan Ritter 9baafac952 fix(showcase): drop chain-tools hasToolResult gate to reach LGT D6 185/0/2
The whole-thread `hasToolResult: false` gate on the Chain-tools first-turn fixture caused
the chain pill to fall through to the broad "weather in Tokyo" matcher mid-thread.
Removing the gate (mirroring LGP) yields LGT 185/0/2.
2026-05-29 21:22:56 -07:00
Jordan Ritter 3184824baf chore(showcase): copy LGP canonical suggestion pills into 13 integrations
Stages the canonical suggestion pill set (mirrored from langgraph-python) as new
suggestions.ts files across 13 integrations: ag2, agno, mastra, pydantic-ai,
claude-sdk-python, claude-sdk-typescript, llamaindex, langroid, strands, spring-ai,
built-in-agent, crewai-crews, langgraph-fastapi.

Also includes targeted edits to existing suggestions.ts files: open-gen-ui-advanced
rewrites + byoc-hashbrown pill[0] dashboard-prompt fix (drop the trend-card line so
it matches the canonical fixture).

NOTE: these new files are currently UNWIRED. Each integration's page.tsx still
defines its pill list inline via useConfigureSuggestions. Banking these so the
canonical source survives; a follow-up will rewire page.tsx to import from
suggestions.ts and delete the inline copies.
2026-05-29 21:08:05 -07:00
Jordan Ritter e8f38c6129 fix(showcase): narrow LGT D6 d4 shadows + wire sandboxed-ui jsFunctions
Mirrors the LGP first-match-wins fix on the langgraph-typescript side. Three broad
matchers in d4/langgraph-typescript/chat.json were shadowing d6 fixtures; narrowed
them so the d6 pills win.

Across the d6/langgraph-typescript suite: dropped fragile turnIndex:0 gates in favour
of hasToolResult:false for first-leg tool emissions, fixed em-dash escaping that broke
literal string matches in multi-pill threads, and added jsFunctions payloads to the
three sandboxed-ui fixtures (_from-feature-parity, headless-complete,
gen-ui-open-advanced) so the sandbox renderer has executable handlers.

LGT D6 now passes 184/1/2 locally. Residual 1 fail is the custom-catchall multi-pill
follow-up case; tracked separately.
2026-05-29 21:08:05 -07:00
Jordan Ritter 508bea0e88 fix(showcase): unblock LGP D6 beautiful-chat + custom-catchall via d4 matcher narrowing
Aimock fixture load order is shared -> d4 -> d6, and matching is first-match-wins. A
broad d4 langgraph-python chat fixture for search_flights was shadowing the d6
beautiful-chat fixture and preventing the intended response from firing. Neutered the
d4 matcher to a non-matching sentinel so the d6 fixture wins.

Also refreshed d6/tool-rendering-custom-catchall.json and d6/tool-rendering.json:
replaced fragile turnIndex:0 gates with hasToolResult:false so the AAPL first-leg
fixture fires correctly when D5 probes run a prior 'weather in Tokyo' pill in the
same thread (multi-pill turnIndex>=2).

LGP D6 now passes 185/0/2 locally (2 skips are the by-design mcp-apps iframe gap).
2026-05-29 21:08:05 -07:00
Jordan Ritter 22660a759c fix(showcase): harden deploy pipeline — rollback, Host brand, CI alerts (#5107)
## Summary

Hardening pass over the showcase deploy pipeline and its operator
tooling. Five focused areas:

- **`bin/railway` rollback shell-injection fix** —
`RollbackCommitCommand` shelled out via backtick subshells interpolating
the `--sha`/`--env` flags. Replaced with `IO.popen` argument arrays (no
shell), with `--sha` validated against an anchored hex regex and `--env`
validated against the known env set before any git invocation. Both `git
ls-tree` and `git show` now gate on `$?.exitstatus` before parsing their
output (a failed `git show` previously merged stderr into stdout and fed
it to `YAML.safe_load`). New spec covers injection rejection, git-show
failure, and empty-snapshot paths.
- **Promote snapshot encapsulation** — replaced the bare `@full_*`/`@*`
snapshot ivars in `PromoteCommand` with named `fleet_*`/`target_*`
accessors so fleet-scoped vs per-service snapshot selection is
name-enforced rather than comment-enforced.
- **Branded `Host` type** — `ProbeTarget.host` is now a branded `Host`
produced only by `asHost` (rejects scheme, path, empty, whitespace,
userinfo, query, fragment), branded at the verify-pipeline ingress;
`ProbeTarget` fields are `readonly`.
- **`deploy-to-railway.ts` SSOT migration** — uses the shared
`resolveRailwayToken` and sources project/env IDs from the railway-envs
SSOT; reads the GHCR username from env (fail-loud) instead of a
hardcoded handle.
- **Workflow safety + observability** — collapsed the promote workflow
to an input-agnostic concurrency group so promotes can't race the same
Railway service; added `#oss-alerts` failure notifications to the build
and validate workflows (which previously had silent red paths).
- **Harness probe test fixes** — repointed the aimock fixture-coverage
probe to the per-integration D4/D6/shared layout and aligned
d5-multimodal assertions to the current auto-send sentinels.

## Test plan

- [ ] CI: Validate Showcase, build-checks, python tests green
- [ ] CI: static/quality (oxfmt + lint + typecheck) green
- [ ] Local: Ruby promote suite (`ruby spec/all_tests.rb`) — 103/342
green
- [ ] Local: showcase-scripts vitest green; harness probe tests green
- [ ] Local: oxfmt --check clean; actionlint clean
2026-05-29 18:04:02 -07:00
Tyler Slaton 0556fe3120 fix(skills): correct package names and import paths in copilotkit-setup skill (#5089)
## Summary

- `@copilotkit/react` and `@copilotkit/agent` do not exist on npm —
every user following the setup skill fails on Step 1 with a 404
- Replaces them with the correct published packages:
`@copilotkit/react-core` and `@copilotkit/runtime`
- Updates all import paths throughout the skill to use the v2 subpath
exports (`@copilotkit/react-core/v2`, `@copilotkit/runtime/v2`)
- Removes references to the non-existent `@copilotkit/core` and
`@copilotkit/agent` packages from the Package map table

## Changes

- Step 1 install commands now use real package names that resolve on npm
- All code examples import `BuiltInAgent`, `CopilotRuntime`,
`InMemoryAgentRunner`, endpoint factories from `@copilotkit/runtime/v2`
- All frontend code examples import `CopilotKitProvider`, `CopilotChat`,
`CopilotSidebar`, styles from `@copilotkit/react-core/v2`
- Package map table updated to reflect the two real installable packages

## Test plan

- [x] `npm install @copilotkit/react-core @copilotkit/runtime hono` —
installs without 404
- [x] All import paths in examples resolve to real published subpath
exports
2026-05-29 16:52:04 -07:00
David McKay c6ca283e96 feat(ci): bundle-size tracking + ES-compat checks (OSS-123, OSS-121)
Adds two CI signals for keeping the published packages small and broadly compatible:

- Bundle size: size-limit file-mode config across packages plus a
  CopilotChat import-size regression signal (gzip) so growth in the
  headline consumer entrypoint is visible on every PR. A bundle-size
  workflow comments results on the PR (Phase 1: no hard-fail).
- ES compatibility: a compat-check (es-check) script across 9 packages
  with a root .browserslistrc, validating built .mjs/.cjs against the
  es2022 build target.

The measure script is importable (measureBundle) and unit-tested. Dev
docs live under dev-docs/ (bundle-size.md, browser-compat.md). All
action refs are pinned to full commit SHAs for supply-chain safety.
2026-05-29 16:44:35 -07:00
github-actions[bot] fb2ac5718e style: auto-fix formatting 2026-05-29 23:17:54 +00:00
Jordan Ritter aa33754860 feat(showcase): D6 conveyance — wire header-forwarding shims into remaining entrypoints
Companion to the conveyance shim commit. The shim files were staged
without their callers; this pass wires:

- langroid / llamaindex / ms-agent-python / pydantic-ai / strands
  agent_server.py: register the HeaderForwardingHTTPMiddleware
- mastra: switch every API route (copilotkit, copilotkit-auth, beautiful-chat,
  byoc-hashbrown, byoc-json-render, mcp-apps, multimodal, ogui, voice) and
  the mastra agents / tools / subagents modules onto the
  _header_forwarding-wrapped openai provider so inbound x-* headers ride
  on outbound Vercel AI SDK calls via ALS
2026-05-29 16:16:36 -07:00
Jordan Ritter 12e6e1efa6 docs(showcase): GOTCHAS entry for D6 conveyance + --isolate notes 2026-05-29 16:16:18 -07:00
Jordan Ritter c414fbad23 test(showcase): D6 per-integration aimock fixtures + shared narrowing
Refresh d6 fixtures across the rollout cohort: ag2, built-in-agent,
claude-sdk-{python,typescript}, crewai-crews, google-adk, langgraph-fastapi,
langgraph-typescript, langroid, llamaindex, mastra, ms-agent-{dotnet,python},
pydantic-ai, strands. Companion d4/{langgraph-typescript,mastra,ms-agent-dotnet}
chat.json refreshes. Add the missing ms-agent-python/gen-ui-custom.json
to bring the integration up to the standard pill set.

Also narrow aimock/shared/common.json's generic 'hello' fixture to
'hello world' so it no longer shadows D6 pills whose prompts contain
'hello' as a substring (e.g. langgraph-python headless-simple sends
'Say hello in one short sentence.'). 'hello world' is unused by any
current demo pill, so the fixture remains a manual-typing fallback
without poisoning fixture matching.

This is a mid-rollout snapshot — fixture coverage is uneven across
integrations and rides alongside the conveyance shims landed earlier
in this branch.
2026-05-29 16:16:12 -07:00
Jordan Ritter 5f21584b3a test(showcase): D6 langgraph-python fixtures — drive to 180/5/2
Refresh d6/langgraph-python fixtures (beautiful-chat, chat-slots,
frontend-tools-async, gen-ui-{agent,custom,declarative,interrupt,open},
headless-complete, hitl-in-app, interrupt-headless, shared-state-streaming,
tool-rendering, tool-rendering-reasoning-chain, _from-feature-parity) plus
d4/langgraph-python/chat.json. Combined with the conveyance shim landed
in this branch, LGP is fixture-complete at 180 pass / 5 fail / 2 skip.

The residual 5 fails trace to react-core/v2's custom-wildcard-renderer
bug surfaced through gen-ui-interrupt (shared useInterrupt hook misbehaves
on the second interrupt; cross-integration D6 blocker, not a fixture or
conveyance defect). The 2 skips are the by-design mcp-apps iframe gap.
2026-05-29 16:15:57 -07:00
Jordan Ritter 671cc6ae1d feat(showcase/harness): support concurrent --isolate runs
- scripts/cli/_common.sh apply_isolation rewrites compose-file relative
  paths to absolute (build/context/dockerfile/volumes/env_file), enforces
  the docker compose [a-z0-9_-] project-name rule (normalize-with-warn or
  hard fail), and exports SHOWCASE_COMPOSE_FILE / SHOWCASE_INFRA_PORT_OFFSET
  plus offset host URLs (AIMOCK_URL_LOCAL / DASHBOARD_URL_LOCAL /
  POCKETBASE_URL_LOCAL) so the TS harness CLI talks to THIS project's
  aimock instead of the default :4010
- harness/src/cli/{aimock-rebuild,config,doctor,lifecycle}.ts honor the
  new env vars; lifecycle picks up the offset infra port for health
  probes so concurrent stacks no longer report each other's services as
  healthy
- Commit a generated harness/package-lock.json (new file) so npm ci
  resolves deterministically
2026-05-29 16:15:47 -07:00
Jordan Ritter af2036996a feat(showcase/built-in-agent): D6 conveyance — header-forwarding shim + factory wiring
- New src/lib/header-forwarding.ts mirrors the cross-integration shim
  pattern: reads inbound x-* headers and forwards them onto outbound
  LLM calls so aimock fixture matching sees x-aimock-context
- Wire copilotkit route handler and tanstack factory through the shim
- Frontend-tools and a2ui-fixed-schema demo adjustments paired with the
  conveyance work
- Bump package.json / package-lock.json against the updated tree
2026-05-29 16:15:35 -07:00
Jordan Ritter 6d5afd458a feat(showcase/langgraph-typescript): D6 conveyance — propagate request headers into ChatOpenAI
- Add openai-headers.ts: a per-request helper that pulls x-aimock-context
  off the inbound LangGraph request and threads it into the ChatOpenAI
  client construction so aimock fixture matching sees the inflight test
  context
- Wire every agent module (a2ui-*, agentic chat surfaces, byoc-*,
  frontend-tools-*, gen-ui-*, headless-complete, hitl-*, interrupt-agent,
  mcp-apps, multimodal, open-gen-ui*, readonly-state, reasoning-agent,
  shared-state-*, subagents, tool-rendering*) through the helper
- Bump package.json/package-lock.json against the updated tree
2026-05-29 16:15:26 -07:00
Jordan Ritter ceff27031c feat(showcase/langgraph-python): D6 conveyance shim + copilotkit 0.1.93 bump
- Add _header_forwarding_middleware.py paired with reasoning / subagent /
  tool-rendering-reasoning-chain agent edits so D6 fixture-matching sees
  the inflight x-aimock-context on outbound LLM calls
- Bump copilotkit 0.1.92 → 0.1.93 in requirements.txt; regenerate
  package-lock.json against the post-npm-ci tree (sibling of 03bed3b76,
  which switched this integration to npm ci)
- Drop the stale pnpm-lock.yaml left behind by the npm ci migration —
  Dockerfile uses 'npm ci --legacy-peer-deps' and every other showcase
  integration committed only package-lock.json after 03bed3b76. Removing
  the orphan prevents npm/pnpm tooling drift from re-resolving against it.
2026-05-29 16:15:12 -07:00
Jordan Ritter 0ca2bd40aa feat(showcase): D6 conveyance — forward x-aimock-context headers to LLM clients
Add a per-integration header-forwarding shim so inbound x-* request headers
ride along to outbound LLM HTTP calls. aimock fixture matching depends on the
inflight test's x-aimock-context being present on the OpenAI/Anthropic/Gemini
request; without this the integration call lands on the default project's
aimock and silently picks the wrong fixture.

Shape per integration:
- New _header_forwarding.{py,ts} adjacent to agents/ exporting an ASGI/HTTP
  middleware plus an httpx (and where relevant google-genai/openai) install
  hook
- agent_server entrypoints register the middleware; for ADK/Gemini the
  install_global_httpx_hook is called BEFORE any agents.* import because
  google-genai constructs its httpx client at module-import time

Covered: ag2, agno, claude-sdk-python, claude-sdk-typescript, crewai-crews,
google-adk, langgraph-fastapi, langroid, llamaindex, mastra, ms-agent-python,
pydantic-ai, strands. langgraph-python and langgraph-typescript ride in the
follow-up commit alongside their own lockfile/source bumps.
2026-05-29 16:15:00 -07:00
Mark 7c637d3c3b docs(cookbook): Cookbook section + Daytona recipe + skill (OSS-222) (#5087)
## Summary
- New top-level **Cookbook** docs section with a small landing page,
added both as a top-level nav tab (next to Learn) and as a sidebar
section under Documentation. First recipe wires CopilotKit's Built-in
Agent up with a `runCode` server tool that executes Python, TypeScript,
or JavaScript in an isolated [Daytona](https://www.daytona.io) sandbox
and returns stdout to chat.
- New **`copilotkit-daytona` Agent Skill**
(`skills/copilotkit-daytona/`) — `SKILL.md` + `assets/` + `references/`
+ `eval.yaml` + a workspace fixture, mirroring
`skills/copilotkit-setup`. The skill's reference doc deliberately points
at Daytona's maintained sources (`llms.txt`, the dashboard limits page,
the official `daytona` Agent Skill, and the Daytona MCP server) rather
than duplicating a hand-copied SDK surface that would rot.
- Fixes a stale `learn/meta.json` link that pointed at
`../direct-to-llm/cookbook/state-machine` (target no longer exists).

Closes OSS-222.

## Test plan
- [x] `next build` compiles `/cookbook` and `/cookbook/daytona` as
static routes; OG images emit for both.
- [x] Broken-link checker shows no new broken links relative to `main`.
- [x] Cookbook appears as a top-level nav tab next to Learn, and as a
section in the Documentation sidebar.
- [x] Recipe code validated end-to-end on a deployed Railway app against
published `@copilotkit/runtime@1.58.0`: agent invokes `runCode`, a real
Daytona sandbox executes both Python and JavaScript snippets, output
round-trips through the chat (unique-token proof).

## Notes (out of scope, separate follow-ups)
- The Built-in Agent **quickstart** doc shows a v1 `<CopilotKit>`
provider mixed with v2 `<CopilotSidebar>`; the v2 demos use the all-v2
stack (`CopilotKitProvider` + `useSingleEndpoint` +
`createCopilotEndpointSingleRoute`). Worth a doc reconciliation in a
separate PR.
- The Vercel AI SDK emits *"System messages in the prompt or messages
fields…"* when the agent runs — it originates inside `BuiltInAgent`'s
call construction (passes system content via `messages` rather than the
SDK's `system` option). Benign, but a CopilotKit runtime improvement
worth filing separately.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-29 15:32:31 -07:00
Mark 447e9d8156 Merge branch 'main' into docs/222-daytona-cookbook 2026-05-29 15:26:38 -07:00
Jordan Ritter e3e777a921 fix(showcase): bind github.ref to env in validate notify to satisfy zizmor
The new no-webhook log step interpolated github.ref directly into a shell
echo, which zizmor flags as template-injection (HIGH). Bind it to a step
env var REF and reference $REF in the script instead. Message text is
unchanged; no Co-Authored-By.
2026-05-29 15:11:52 -07:00
Jordan Ritter 7c952d27fb test(showcase): fix harness probe tests for the D4/D6 fixture reorg
Repoint the aimock fixture-coverage probe to the per-integration d4/d6/shared layout; align
d5-multimodal assertions to the current auto-send button sentinels.
2026-05-29 15:06:59 -07:00
Jordan Ritter 5748b7c27a feat(showcase): serialize promote concurrency and add red-path workflow alerts
Collapse the promote workflow to an input-agnostic concurrency group so promotes can't race the
same Railway service; add #oss-alerts failure notifications to the build and validate workflows
(build via extended needs, validate via a new workflow-level notify job).
2026-05-29 15:06:54 -07:00
Jordan Ritter 90773f73e7 refactor(showcase): use shared railway token resolver and SSOT IDs in deploy-to-railway
Replace the divergent getToken with resolveRailwayToken; source project/env IDs from the
railway-envs SSOT; read the GHCR username from env (trimmed, fail-loud) instead of a hardcoded
handle.
2026-05-29 15:06:49 -07:00
Jordan Ritter 722e411249 refactor(showcase): brand ProbeTarget.host as a validated Host type
Introduce a branded Host produced by asHost (rejects scheme/path/empty/whitespace/userinfo/query/
fragment); brand at the resolveProbeTargets ingress; make ProbeTarget fields readonly; add asHost
+ override-seam tests.
2026-05-29 15:06:45 -07:00
Jordan Ritter 253a49603e fix(showcase): harden bin/railway rollback against shell injection
Replace RollbackCommitCommand backtick subshells with IO.popen arg-arrays; validate --sha (hex)
and --env (known set) before any git call; gate both git ls-tree and git show on $?.exitstatus
before parsing; add injection + git-show-failure + empty-snapshot spec. Also encapsulate promote
snapshots behind fleet_*/target_* accessors so fleet-vs-target selection is name-enforced.
2026-05-29 15:06:40 -07:00
Ben Taylor 3dc9bea09e chore(examples): update LangGraph threads CopilotKit pins (#5105)
## Summary
- update the LangGraph Python Threads template CopilotKit packages from
1.57.0 to 1.59.1
- align @ag-ui/client to 0.0.53 so @ag-ui/langgraph and
@copilotkit/runtime share the same agent base types
- regenerate the standalone template package-lock.json

## Verification
- npm run build (from examples/integrations/langgraph-python-threads)
- lefthook pre-commit: check-binaries, sync-lockfile,
test-and-check-packages
2026-05-29 16:17:03 -05:00
Martha Schumann 8092f8ba7f chore(examples): update langgraph threads copilotkit pins 2026-05-29 13:07:47 -07:00
Jordan Ritter 482c2a0ae3 style(sdk-python): apply ruff format to test_agui_agent.py (#5104)
Fixes the red `static / quality` format gate on main caused by an
unformatted Python test file (pre-existing, unrelated to the showcase
pipeline work). Applied ruff 0.15.13 format to
`sdk-python/tests/test_agui_agent.py` only.
2026-05-29 13:05:44 -07:00
Mark Fogle 38ce421f85 feat(examples): trim demo chrome to fit embedded iframe viewport
The cookbook's 'Try it live' iframe is 600px tall, but the demo page
included its own h1/subtitle + ~32px main padding + the chat section had
minHeight:520, which pushed total content past 600px and forced a
scrollbar inside the iframe.

The shell-docs cookbook page already provides a header and surrounding
chrome; the demo's own h1 ('CopilotKit x Daytona') and subtitle are
redundant in the embedded context. Drop them and let the chat fill the
iframe viewport exactly:

- Remove the <header> (h1 + subtitle).
- Set <main> to height:100vh, padding:0, margin:0.
- Chat <section> uses flex:1 + minHeight:0 (no fixed minHeight) so it
  grows/shrinks to fill the available iframe height.

Side effect: the standalone Railway URL now also shows just the chat
(no h1/subtitle). Fine — the URL is a demo embedding target rather
than a polished standalone landing.

OSS-222
2026-05-29 19:56:30 +00:00
Jordan Ritter ea5ea897c1 style(sdk-python): apply ruff format to test_agui_agent.py
main's static/quality format gate was red because this file was not
ruff-formatted (introduced by an earlier unrelated python commit).
Apply ruff 0.15.13 format to restore the gate.
2026-05-29 12:54:47 -07:00
Jordan Ritter d4531851ae feat(showcase): multi-service deploy pipeline + runtime config (#5093)
## Summary

- Establishes a two-stage push-to-main deploy pipeline for the showcase
fleet: build GHCR images and redeploy STAGING (which floats `:latest`);
PROD is digest-pinned (`@sha256:`) and promote-only via a gated
workflow.
- Introduces a single source of truth (SSOT) for Railway env/service
IDs, image refs, per-env domains, and probe configs, consumed by Ruby
tooling, TypeScript pipeline scripts, and CI workflows.
- Adds a Ruby `bin/railway` promote command with per-service targeting,
`--digest` pinning, and fleet-scoped preflight gates (P1 GHCR digest
existence, P2 staging-latest SUCCESS, P3 staging-green live re-probe, P5
mutation correctness, P6 parity matrix).
- Migrates the four Next.js shells (shell, shell-dashboard, shell-docs,
shell-dojo) to runtime URL config (\"Option B\"): server-side reads of
`NEXT_PUBLIC_*` at request time + `window.__SHOWCASE_CONFIG__`
injection, with an oxlint rule guarding against build-time public-env
reads.
- Hardens the image-ref gate (per-env: prod `@sha256`, staging
`:latest`), adds untracked-service hard-fail and `gateIgnore` opt-out,
and rolls five additional services into the gate.
- Adds verify-deploy probe drivers, per-env verify matrix resolution,
per-slot build-result artifacts, and end-to-end fail-loud boundaries
across the pipeline scripts.

## Key changes

### Deploy model and workflows
- `showcase_build.yml`, `showcase_build_check.yml`,
`showcase_deploy.yml`, `showcase_promote.yml` updated/added for the new
two-stage flow.
- Push-to-main redeploy retargeted from prod to staging;
redeploy-summary upload is now mandatory and bridged into the build
workflow artifact.
- New prod promote workflow (`showcase_promote.yml`) gates on the Ruby
preflight suite.

### Railway envs SSOT
- `showcase/scripts/railway-envs.ts` + generated
`railway-envs.generated.json` as the canonical source of env/service
IDs, per-env domains, probe config, dispatch-name uniqueness invariant,
and `gateIgnore` per service.
- CI `--check` mode verifies the generated artifact is in sync with the
TS source.
- Ruby `bin/railway` reads `EXPECTED_DOMAINS` from the TS SSOT artifact.
- Snapshot schema v2 adds
`healthcheck`/`region`/`replicas`/`restartPolicy` for the parity matrix.

### TS pipeline scripts (`showcase/scripts/`)
- `redeploy-env.ts` for explicit per-env Railway redeploys with
per-service JSON summary emission.
- `resolve-verify-matrix.ts` for SSOT-driven verify matrix resolution
(skips verify when redeploy success-set is empty; pinned by a contract
test).
- `verify-deploy.ts` parameterized per-env probe + baseline driver
implementations.
- `verify-railway-image-refs.ts` per-env gate (prod `@sha256`, staging
`:latest`), untracked-service hard-fail, malformed-ref negatives,
per-service shape tests.
- `aggregate-build-results.ts` per-slot build-result artifacts,
fail-loud on missing slot file, GHA heredoc output.
- `emit-railway-envs-json.ts` SSOT artifact emitter with hermetic,
fail-loud read errors.
- Shared `scripts/lib/`: unified Railway GraphQL endpoint
(backboard.railway.app), shared token resolver preferring
`user.accessToken`, whitespace/type-safe narrowing, sanitized GraphQL
error bodies.

### Ruby promote (`showcase/bin/railway` + `lib/`)
- `PromoteCommand` refactored for testable preflight; single-service
targeting via `--digest`.
- `Railway::Auth.ghcr_token` + `GHCR.manifest_exists` (P1 GHCR digest
gate).
- P2 staging-latest-deployment SUCCESS check.
- P3 require-staging-green live re-probe via `verify-deploy --env
staging`.
- P5 mutation-correctness verification (boolean + re-query retry).
- P6 parity matrix (healthcheck/region/replicas/restartPolicy).
- Promote resolves staging tag to GHCR digest once, pins prod, verifies
redeploy, fails loud on partial promote.

### Runtime URL config across Next shells (\"Option B\")
- `shell`, `shell-dashboard`, `shell-docs`, `shell-dojo`: new
`runtime-config.ts` (server) + `runtime-config.client.ts` (client)
modules; `__SHOWCASE_CONFIG__` injected via root layout; middleware and
URL consumers migrated.
- Dropped build-time `NEXT_PUBLIC_*` build-args from CI and Dockerfiles;
re-declared `COMMIT_SHA`/`BRANCH` ARG in runner stages where needed.
- `shell-docs` sitemap/robots made dynamic; analytics + middleware
routed through runtime config; `signup-link` and CTA components migrated
with SSR tests.
- New oxlint rule rejects `NEXT_PUBLIC_*` reads from shell source.
- Playwright env-routing spec per shell per env; no-rebuild env-switch
integration test.

### Test hardening
- vitest coverage for runtime-config server/client, SSR safety, env-name
tolerance.
- Contract tests pin verify-matrix SSOT shape and CLI behavior.
- Per-service image-ref gate shape tests; malformed-ref negatives.

## Test plan

- [ ] CI: \`build-checks\` green on this branch
- [ ] CI: \`validate-showcase\` green (SSOT \`--check\` passes)
- [ ] CI: Python tests green
- [ ] CI: oxlint passes (no NEXT_PUBLIC_* reads in shells)
- [ ] Local: \`bundle exec rspec\` (Ruby promote suite) green
- [ ] Local: \`pnpm -C showcase/scripts test\` (vitest) green
- [ ] Local: \`pnpm -C showcase/shell test\` and sibling shells green
(runtime-config + SSR)
- [ ] Local: \`docker buildx build\` succeeds for each shell with the
trimmed build-args
- [ ] Local: Playwright env-routing spec passes against a running shell
- [ ] Manual: dry-run \`bin/railway promote --digest <sha256>\` against
a staging service; P1–P6 gates report as expected
2026-05-29 12:42:00 -07:00