Commit Graph

6618 Commits

Author SHA1 Message Date
Sam Julien 3218c54cc1 fix(showcase/shell-docs): remove remaining /docs/ hardcoded hrefs
SidebarLink fallback, framework-scoped backLink, "framework-agnostic
version" banner link, FrameworkLandingPage sidebar, and brand-nav
all still pointed at /docs/* which routes to 404 via the [framework]
catch-all. Switch all to / or /<slug>.
2026-04-21 17:35:01 -07:00
Sam Julien 671ecd1091 fix(showcase/shell-docs): make InlineDemo framework-aware via frameworkOverride
Override InlineDemo in DocsPageView's MDX component map to substitute
defaultFramework for the hardcoded integration prop when a framework
is selected. MDX files don't need to change — the override happens at
the render layer, matching how Snippet already handles this.
2026-04-21 17:35:01 -07:00
Sam Julien 0057d6beb4 fix(showcase/shell-docs): fix broken /docs/* route links in root page
DOCS_SECTIONS, OverviewNavItem, CopilotKit Docs link, backLink, and
slugHrefPrefix all generated /docs/<slug> paths that 404 — the
[framework] catch-all intercepted "docs" as a framework slug and
returned notFound(). Strip the /docs prefix so all root-route links
resolve correctly.
2026-04-21 17:35:01 -07:00
github-actions[bot] b5f60bbf5c style: auto-fix formatting 2026-04-21 17:35:01 -07:00
Sam Julien c730330d0d docs(shell-docs): content audit — fix broken snippets, links, and syntax
Page-by-page audit of showcase/shell-docs MDX content. All changes are
in src/content/docs/.

## Broken snippet region fixed
- generative-ui/a2ui/dynamic-schema.mdx: Step 5 referenced
  `runtime-inject-tool` which does not exist in the declarative-gen-ui
  cell. Replaced with a hardcoded code block showing `injectA2UITool: true`
  (same content already shown on the parent a2ui.mdx page).

## MDX syntax fix
- frontend-actions.mdx: stray closing ``` at end of file (would cause
  a parse/render failure).

## Internal link fixes — /docs/ prefix removed (×14 files)
The docs app routing does not use a /docs/ prefix — pages live at
/<slug>. Links using /docs/<slug> hit the reserved-slug guard in the
[framework] route and 404. Fixed across:
  generative-ui/index.mdx (7 links)
  generative-ui/tool-based.mdx (3 links)
  learn/index.mdx (6 links)
  multi-agent/subagents.mdx (2 links)
  shared-state.mdx (2 links)
  shared-state/streaming.mdx (2 links)
  shared-state/agent-readonly.mdx (4 links)
  troubleshooting/debug-mode.mdx
  troubleshooting/error-debugging.mdx
  troubleshooting/migrate-to-1.10.X.mdx
  troubleshooting/migrate-to-1.8.2.mdx (2 links)
  troubleshooting/observability-connectors.mdx

## Internal link fixes — /unselected/ removed (×2 files)
  backend/copilot-runtime.mdx
  backend/custom-agent.mdx
2026-04-21 17:35:01 -07:00
Jordan Ritter 59a09e3e65 feat(showcase/scripts/generate-starters): encode prod-mode conditionals per framework
Add per-slug Dockerfile emitters that pair with the new
AGENT_BUILD_STEPS / AGENT_BUILD_COPY tokens in Dockerfile.typescript:

- getAgentBuildSteps(fw): runs in the builder stage, after `npm run build`.
  Emits `npx tsc` for claude-sdk-typescript (compiles agent/index.ts →
  /app/dist/agent/index.js with flags that match the sibling package
  Dockerfile), and `npx mastra build --dir src/mastra` for mastra
  (bundles the server into .mastra/output/index.mjs). Returns "" for
  every other slug so their Dockerfile cache stays unchanged.

- getAgentBuildCopy(fw): runs in the runner stage, after the agent-code
  COPY. Moves /app/dist (claude-sdk-ts) or /app/.mastra (mastra) from
  the frontend stage into the runner.

- getEntrypointBlock() prod-mode updates: mastra now boots via
  `node /app/.mastra/output/index.mjs` (not `npx mastra dev`) and
  claude-sdk-typescript via `node /app/dist/agent/index.js` (not
  `npx tsx agent/index.ts`). Cold start is a straight `node`
  invocation on Railway — mirrors PR #4132's fix for langgraph-ts.

- Wire AGENT_BUILD_STEPS / AGENT_BUILD_COPY into the `vars` map in
  generateStarterImpl so the template substitution picks up the new
  tokens, and export the two helpers so the test suite can guard them.

Also refresh the generator header comment to describe the multi-stage
shape (builder toolchain vs. minimal runtime) and the prod-mode emitter
wiring.

Tests:
- Replace the legacy `mastra dev` / `npx tsx` entrypoint expectations
  with prod-mode assertions (`node /app/.mastra/output/index.mjs`,
  `node /app/dist/agent/index.js`), plus not-to-contain guards so a
  future refactor can't accidentally re-enable the tsx/dev path.
- Add a dedicated describe block for getAgentBuildSteps /
  getAgentBuildCopy covering the two opted-in slots, the ""
  fallthrough for langgraph-typescript (which has its own server.mjs
  migration path), and the "" fallthrough for every Python slug
  (Python prod-mode is shared-template, not per-slug).

Full `vitest run` in showcase/scripts is green (1085 tests).
Starter Dockerfile regeneration is deferred to a follow-up commit
block once Task 1's template wiring lands.
2026-04-21 17:20:50 -07:00
Jordan Ritter a32d5752d4 feat(showcase/template): true multi-stage Dockerfile templates with prod-mode tokens
Restructure the shared starter Dockerfile templates so the runtime stage
ships only a minimal base plus built artifacts — no dev toolchains (pip,
pnpm, tsx, *-cli dev) run in the runner stage.

Dockerfile.typescript:
- Add AGENT_BUILD_STEPS / AGENT_BUILD_COPY template tokens so per-slug
  prod-mode compiles (claude-sdk-typescript tsc, mastra `mastra build`)
  can be emitted by the generator. Mirrors PR #4132's langgraph-typescript
  fix for the rest of the TS starter slots — cold start becomes a straight
  `node` call instead of `npx tsx` / `npx mastra dev` on Railway.

Dockerfile.python:
- Split pip install into a dedicated agent-builder stage that carries
  full `python:3.12` (with compilers + dev headers needed for wheels
  that don't ship pre-built for -slim), and produces a self-contained
  /opt/venv. The runner then COPYs /opt/venv as a single opaque tree —
  no pip, no build tools in the final image.

Dockerfile.java and Dockerfile.dotnet already implement the true
multi-stage shape (temurin-21 JDK / dotnet-9 SDK builder + JRE / aspnet
runtime); no structural changes needed.

Regenerating the 17 starter Dockerfiles happens in the next commit
block — this commit is template-authoring only.
2026-04-21 17:20:33 -07:00
github-actions[bot] a912322c4a style: auto-fix formatting 2026-04-22 00:14:21 +00:00
Jordan Ritter 229b3e1da9 fix(showcase/langgraph-typescript): liveness probe on sibling port to break watchdog restart loop
PR #4132 migrated away from `langgraph-cli dev` to the @langchain/langgraph-api
`startServer` Hono server. That server does bind `/ok` via its meta routes, but
only AFTER `registerFromEnv` imports the graph and spawns the N workers — on
Railway that window has been exceeding the watchdog's 180s startup grace plus
the 90s strike budget, producing an infinite restart loop (deploy ddc88ef9 is
currently flapping ~every 4m30s).

Move liveness off the heavy Hono path entirely:

- server.mjs now spins up a bare node:http server on port 8124 (configurable
  via HEALTH_PORT) *synchronously before any await*, answering GET /ok with
  {"status":"ok"}. Always live within ms of `node` boot.
- entrypoint.sh watchdog now probes 127.0.0.1:8124/ok instead of :8123/ok.

The liveness port is independent of whether :8123 has finished graph import,
so the probe reflects what the watchdog actually cares about: is the Node
process alive and its event loop responsive. A true hang (event loop pinned)
still fails the probe and triggers container restart, so the existing
hang-detection behavior is preserved.

Local Docker smoke (amd64): curl /ok returned 200 within 20s of container
start; LangGraph API logged "listening on 0.0.0.0:8123" ~15s later as normal.
2026-04-21 17:12:23 -07:00
Jordan Ritter 4b4923561b feat: VS Code extension — Hook Explorer, AG-UI Inspector, webview-first sidebars (#3935)
## Summary

Three connected features land together so the CopilotKit VS Code
extension becomes a coherent debugger/preview surface:

1. **Hook Explorer** — every V1 + V2 render hook can be discovered and
previewed live with auto-generated controls, an inline `▶️ Preview
Component` CodeLens, and a sidebar that lists every captured site.
2. **AG-UI Event Inspector** — live SSE debug stream of all AG-UI
events, filterable and color-coded, in a sidebar view + editor panel.
3. **A2UI Catalog sidebar → webview** — the last native TreeView gets
replaced with a Tailwind-styled webview that matches the other two, now
with a proper **Go to source** action on components and fixtures.

## Hook Explorer

### Discovery + preview
- oxc-based scanner walks the workspace and finds every call-site of any
hook in the registry (17 across V1 + V2, render + data).
- Preview panel bundles the user's source via Rolldown (IIFE format,
React externalized, CSS collected per `@copilotkit/a2ui-renderer`
pattern), executes it in the webview with a capture-only **stub** for
`@copilotkit/react-core` (+ `/v2`), and mounts the user's component just
long enough to record each hook's config.
- Auto-generated form on the left/top drives the `render` prop's
args/parameters/state/event live. V1 parameter arrays and V2 Zod /
Standard Schema all map through a unified `FormSchema` derived at
runtime from the captured config.
- `useCopilotAction`, `useCopilotAuthenticatedAction_c`,
`useCoAgentStateRender`, `useLangGraphInterrupt`, `useRenderTool`,
`useRenderToolCall`, `useDefaultRenderTool`, `useLazyToolRenderer`,
`useRenderCustomMessages`, `useRenderActivityMessage`,
`useHumanInTheLoop`, `useInterrupt`, `useFrontendTool`, `useComponent`,
`useDefaultTool` all previewable.
- Inline `▶️ Preview Component` CodeLens above every render-hook call
site, backed by the same `copilotkit.hooks.preview` command as the
sidebar.
- Imported render components work: rolldown walks transitive imports
from the hook's `render` prop through any number of sibling files.
- Cross-file hook switches are robust: controls are reset on load,
Harness only mounts once the real HostRoot is ready, a top-level error
boundary auto-recovers when you pick a different hook.

### Why the stub approach
Bundling the real `@copilotkit/react-core` through rolldown's IIFE
output hit a `__commonJSMin` TDZ chain (`require_clipboard`,
`require_graphql`, `require_context_helpers`, …) because the
chat/runtime-client/markdown graph has circular imports. Externalizing
react-core + routing to a Proxy-backed stub that captures hook configs
avoids the whole CJS wrapping problem, shrinks the preview bundle from
~24 MB to ~1.3 KB, and keeps the preview runtime path completely
runnable without a live CopilotKit backend. Tradeoff documented in
`copilotkit-stubs.ts`.

### Weather-themed fixtures
14+ fixtures under `packages/vscode-extension/test-workspace/hooks`,
each a distinct visual scenario (forecast card, severity-palette alerts
with imported CSS, forecast strip, live radar grid, conic-gradient
precipitation gauge, air-quality badge with imported render, pollen
report with a 2-hop import graph, HITL evacuation confirm,
sunrise/sunset gradient, etc.). Used both as regression fixtures and as
the demo surface for video.

### Styling
- Tailwind-via-CDN + VS Code CSS variables for theme-aware chrome.
- User-provided CSS imports collected by rolldown and injected as a
`<style>` tag per load.
- Controls + form fields converted to Tailwind; textarea matches input
styling.
- Framed "Rendered output" card so the render prop is visually
unmistakable.

## AG-UI Event Inspector

### Runtime (`@copilotkit/runtime` + `@copilotkit/shared`)
- `DebugEventBus` — in-memory pub/sub on `BaseCopilotRuntime`, only
instantiated when `NODE_ENV != production`.
- Event tap in `createSseEventResponse` broadcasts every AG-UI event
with metadata (agentId, threadId, runId, timestamp).
- `GET /debug-events` SSE endpoint — returns 404 in production, streams
`DebugEventEnvelope` JSON to connected clients, initial `: connected`
comment flushes headers immediately.

### VSCode Extension
- `DebugStream` — Node SSE client with auto-reconnect, exponential
backoff, URL validation, error surfacing.
- `InspectorPanel` (editor panel, command `CopilotKit: Open AG-UI
Inspector`) and `InspectorViewProvider` (sidebar view) both use a shared
`DebugStream` instance — events persist when switching tabs.
- Inspector React app: `ConnectionBar`, `FilterBar`, `EventList`,
`EventDetail`.
- Color scheme: purple (lifecycle), red (errors), blue (text), orange
(tools), green (reasoning), teal (state), yellow (activity), gray
(unknown).

## A2UI Catalog → webview

- Replaces `ComponentPreviewProvider` (native TreeDataProvider) with
`CatalogListViewProvider` (WebviewViewProvider), matching the Hooks and
Inspector sidebars.
- New React webview with refresh header, component rows (name + relative
path + `auto` badge when no fixture), expandable fixtures list.
- Click a component row → preview (or toggle if it has fixtures); click
a fixture row → preview that fixture.
- Hover action buttons: `▷` preview + `</>` go-to-source on every row.
- "Go to source" opens the component file for component rows; for
fixture rows it opens the fixture file and jumps the cursor to the named
fixture key.

## Test coverage
- Runtime: DebugEventBus unit tests (8), handleDebugEvents endpoint (5),
fetch-router routes (4), integration across Express/Hono/Node/Fetch (9).
- Hooks: scanner + 16 fixture bundle-smoke test, regression guard
against `node_<builtin>` self-references, CSS collector test, stub-based
capture E2E, cross-kind controls remount, FormRenderer defensive
rendering.
- Inspector + webview: DebugStream reconnect (10), inspector components
(17), colors (9).
- Total: **178 tests** passing for the vscode-extension package; runtime
suite unchanged.

## Test plan

- [ ] `pnpm nx run copilotkit-vscode-extension:build` and `pnpm nx run
copilotkit-vscode-extension:test` both green
- [ ] F5 launches the Extension Dev Host with `test-workspace` open
- [ ] Hooks sidebar lists every fixture hook; click a row → preview
opens; `</>` button opens the source
- [ ] `▶️ Preview Component` CodeLens shows above every render hook in a
`.tsx` file; clicking it opens the preview
- [ ] Form controls drive the render live; cross-kind hook switches
(action ↔ custom-message) don't crash; a forced render-prop throw
recovers when a different hook is picked
- [ ] Imported-render fixtures (`ImportedAirQuality`,
`ImportedPollenReport`) bundle and preview correctly
- [ ] A2UI Catalog sidebar is the new webview, refresh works, `</>` on a
fixture opens the fixture file and reveals the named key
- [ ] AG-UI Inspector connects to `GET /debug-events`, filters + detail
work, events survive sidebar/panel switch, invalid URL shows red error
2026-04-21 17:09:45 -07:00
github-actions[bot] 963a06a3ea style: auto-fix formatting 2026-04-21 23:55:37 +00:00
Jordan Ritter 895f9b782b chore(vscode-extension): prep for Marketplace publish
- Remove private flag; add repository, bugs, homepage, pricing, keywords
- Update description to include Hook Explorer and AG-UI Inspector
- Add top-level icon (PNG) for Marketplace listing
- Add .vscodeignore to keep VSIX lean
- Add README.md and LICENSE for Marketplace listing
- Add vscode:prepublish script
2026-04-21 16:53:56 -07:00
Mike Ryan 47cf5182ca refactor(runtime): Support durable compaction of threads (#4130)
<!--
Thank you for sending the PR! We appreciate you spending the time to
work on these changes.

Help us understand your motivation by explaining why you decided to make
this change.


**Please PLEASE reach out to us first before starting any significant
work on new or existing features.**

By the time you've gotten here, you're looking at creating a pull
request so hopefully we're not too late.

We love community contributions! That said, we want to make sure we're
all on the same page before you start.
Investing a lot of time and effort just to find out it doesn't align
with the upstream project feels awful, and we don't want that to happen.
It also helps to make sure the work you're planning isn't already in
progress.

As described in our contributing guide, please file an issue first:
https://github.com/ag-ui-protocol/ag-ui/issues
Or, reach out to us on Discord: https://discord.com/invite/6dffbvGU3D


You can learn more about contributing to copilotkit here:
https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md

Happy contributing!

-->

## What does this PR do?

(Describe the changes introduced in this PR)

## Related PRs and Issues

- (Direct link to related PR or issue, if relevant)

## Checklist

- [ ] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [ ] If the PR changes or adds functionality, I have updated the
relevant documentation
2026-04-21 16:44:57 -07:00
github-actions[bot] cf6d8f463f style: auto-fix formatting 2026-04-21 23:34:40 +00:00
github-actions[bot] 3168c96595 style: auto-fix formatting 2026-04-21 23:26:36 +00:00
github-actions[bot] 58dc1fee62 style: auto-fix formatting 2026-04-21 16:25:11 -07:00
Mike Ryan 219f08ccb9 chore(runtime): clean up connect API and test typing 2026-04-21 16:25:11 -07:00
github-actions[bot] 6a04464bb0 style: auto-fix formatting 2026-04-21 16:25:11 -07:00
Mike Ryan 25f6f15418 refactor(runtime): Support durable compaction of threads 2026-04-21 16:25:11 -07:00
Jordan Ritter 1889c1a209 fix(showcase/shell): drop vestigial COPY of non-existent src/content dir (#4137)
## Summary
- Remove `COPY --from=builder /app/shell/src/content ./src/content` from
`showcase/shell/Dockerfile` — the source dir doesn't exist in the repo
and isn't generated at build time.

## Why
Previously masked by the `generate-search-index.ts` fatal guard (fixed
in #4135). With that guard softened, the build now reaches the runner
stage and fails on this stale COPY. Blocking showcase/shell deploy.

## Test plan
- [ ] `docker build` green locally
- [ ] Showcase deploy green for shell after merge
2026-04-21 16:14:42 -07:00
github-actions[bot] 3f6059c398 style: auto-fix formatting 2026-04-21 23:04:01 +00:00
Jordan Ritter 08ce194c72 fix(showcase/shell): drop vestigial COPY of non-existent src/content dir 2026-04-21 16:02:27 -07:00
Jordan Ritter 9bcc20b3a1 fix(showcase): restore shell build by copying shell-docs content into scan dir (#4136)
## Summary

- The shell app's Docker build ran `generate-search-index.ts` against
`/app/shell-docs/src/content/{reference,ag-ui,docs}`, but the shell
Dockerfile never copied that directory into the build context. The
script's fail-loud guard (refuses to emit a near-empty index when all
scan roots are missing) then aborted the build. Fix copies
`showcase/shell-docs/src/content/` into the builder stage so the scan
finds its input.
- Removed `COPY --from=builder /app/shell/src/content ./src/content`
from the runner stage — that path was left over from the pre-split
layout and never existed under the current tree, so the runner stage
failed before this could ever succeed.

Main was red on `Showcase: Build & Deploy` for both the `shell` and
`shell-dashboard` matrix entries after #4127 merged. `shell-dashboard`
was unblocked separately (GHCR package linkage). `shell` needed this
source fix.

## Test plan

- [x] `depot build --platform linux/amd64 -f showcase/shell/Dockerfile
.` — succeeds end-to-end (prior failure was inside the builder RUN;
runner stage COPY also failed before the fix).
- [ ] After merge: `Showcase: Build & Deploy` `build (shell, ...)` job
green.
- [ ] After merge: Railway redeploys `showcase-shell` from the new
`:latest`; `https://showcase.copilotkit.ai/` returns 200.
2026-04-21 16:02:07 -07:00
Jordan Ritter 4deeb4d0c4 fix(showcase): restore shell build by copying shell-docs content into scan dir
The shell build ran generate-search-index.ts against shell-docs/src/content
but the Dockerfile never copied that directory into the build context,
so the script failed loudly and the whole shell build aborted. Also drop
the runner-stage COPY of shell/src/content — that path was left over from
the pre-split layout and never existed under the current tree.
2026-04-21 15:54:57 -07:00
Jordan Ritter 6d218f4c17 fix(showcase/scripts): allow generate-search-index stub when scan dirs absent (#4135)
## Summary
- `showcase/scripts/generate-search-index.ts` previously fatal-exited
with "all scan directories missing — refusing to emit a near-empty
index" when run inside a Docker build context that doesn't COPY the
`shell-docs/src/content/` tree (e.g. the `shell` package build).
- This PR softens the guard so it emits a stub/warns when all scan dirs
are absent, instead of killing the Docker RUN.

## Why
Regression from #4127 merging on top of generator changes in `c91c7c567`
/ `debfa6600`. Blocking showcase deploy for `shell` right now.

## Test plan
- [ ] showcase deploy green for `shell` after merge
- [ ] Existing search-index output unchanged when scan dirs are present
2026-04-21 15:51:37 -07:00
github-actions[bot] fa65100105 style: auto-fix formatting 2026-04-21 22:41:25 +00:00
Jordan Ritter 53273b96cd fix(showcase/scripts): allow generate-search-index to emit stub when scan dirs missing
The all-dirs-missing guard added in c91c7c567 fataled the shell Docker
build, which intentionally does not COPY shell-docs/src/content/. The
shell only needs the static-pages stub so its header search modal has
something to render (links resolve across to docs.showcase.copilotkit.ai).

Downgrade the fatal to a loud warn + emit the 5-entry static-pages stub.
A misconfigured full build is still visible in logs.

Regression from PR #4127 (8e6991cea) on top of c91c7c567 / debfa6600.
2026-04-21 15:39:41 -07:00
Jordan Ritter 8e6991cea1 Fix showcase dashboard links and dojo langgraph column (#4127)
## Summary

- **shell-dashboard:** dashboard.showcase.copilotkit.ai rendered every
"demo" and "code" link as `http://localhost:3000/...`. Root cause:
`NEXT_PUBLIC_SHELL_URL` was never provided at build time and the source
fell back to `localhost:3000`. Next.js inlines `NEXT_PUBLIC_*` at `next
build`, so a runtime Railway env var could not rescue a bad build. Fix
plumbs the value through as a Docker build arg from
`showcase_deploy.yml` and fails loudly at build if it's unset so this
can't regress silently.
- **shell-dojo:** dojo.showcase.copilotkit.ai was missing items in the
langgraph column (langgraph-python showed 9 demos vs 20+ in the
manifests). Root cause: `shell-dojo/src/data/registry.json` was stale —
the generator only wrote to `shell/`, the dojo Dockerfile never ran the
generator at build, and the CI path filter didn't rebuild the dojo when
manifests changed. Fix dual-emits from `generate-registry.ts` to
`shell/`, `shell-dojo/`, and `shell-docs/`, runs the generator in the
dojo Dockerfile, expands the workflow's path filter to include
`packages/**` and `shared/**`, and refreshes the committed JSON so it
matches what the generator produces today. Langgraph-python demo count 9
→ 32.

## Test plan

- [x] `shell-dashboard` Docker build succeeds with
`NEXT_PUBLIC_SHELL_URL` build arg (Depot `36wlvzkgp1`).
- [x] `shell-dashboard` Docker build fails loudly when the build arg is
omitted (Depot `mbh41c3qtk`).
- [x] `shell-dojo` Docker build succeeds; generator+bundler run at
build; 159 demos bundled (Depot `h7bbq8f8jt`).
- [x] `showcase_deploy.yml` passes YAML validation.
- [ ] After merge + deploy: verify `dashboard.showcase.copilotkit.ai`
links point to `https://showcase.copilotkit.ai/...`.
- [ ] After merge + deploy: verify `dojo.showcase.copilotkit.ai` shows
the full langgraph column (langgraph-python ≥ 20 items).
2026-04-21 15:27:13 -07:00
github-actions[bot] 1fbb0e45c4 style: auto-fix formatting 2026-04-21 22:14:36 +00:00
Jordan Ritter 6bdbb062ff fix(showcase/langgraph-typescript): replace langgraph-cli dev with direct @langchain/langgraph-api server (#4132)
## Summary

Root cause of the 4+ day `langgraph-typescript` flap: `npx
@langchain/langgraph-cli dev` is a dev-mode CLI that compiles TypeScript
on-demand per HTTP request, blocking the single-thread event loop ~5s
per request. On Railway, Studio IPC + `langgraph-api` JIT spawn + graph
compile routinely exceeded the 90s watchdog budget; PR #4123's 180s
grace papered over cold-start but didn't fix steady-state `/schemas`
event-loop blocking.

This PR replaces the CLI with a direct import of `startServer` from
`@langchain/langgraph-api/server` (the same Hono server `dev` wraps,
minus the tsx watcher, Studio handshake, and LangSmith tenant lookup).
Schema extraction runs in a `worker_thread` and is pre-warmed in
parallel with server startup.

Container-tested on `node:22-slim`:
- `/ok` live in <3s (vs. 5-30s dev)
- `/ok` steady-state <10ms
- `/assistants/search` returns the registered `starterAgent` graph
- Pre-warm log: `[server] Pre-warmed schemas in 3402ms`

## Caveats

- Uses `--legacy-peer-deps` for `@langchain/langgraph-sdk` version skew.
- `@langchain/langgraph-api` exports `./server` but it's not officially
public API — exact version pin (`1.1.17`) required.
- `/runs` streaming not end-to-end tested (dummy key);
`/assistants/search` and schema extraction verified.

## Test plan

- [ ] `docker build` of package succeeds (verified locally on
`node:22-slim`, arm64)
- [ ] Railway deploy passes healthcheck within watchdog budget
- [ ] Live probe: `curl
https://showcase-langgraph-typescript-production.up.railway.app/api/health`
returns 200 + `agent: ok`
- [ ] Smoke test run through Studio / demo client end-to-end (real key)

## Related

- Prior attempts: #4116 (watchdog), #4123 (180s grace) — neither
addressed the structural issue
- Proposal context:
https://www.notion.so/3493aa381852814d968df05fc461206d §2c
2026-04-21 15:13:00 -07:00
github-actions[bot] 2f4a1d5c18 style: auto-fix formatting 2026-04-21 22:05:54 +00:00
Martha Kelly Schumann de389ce126 docs(fix): microsoft framework (python) improved docs to support upgraded agent framework (mirror of #4128) (#4129)
Mirror of #4128 by @MalaikaAbb.

The PR changes API identifiers (`ChatAgent`→`Agent`,
`chat_client=`→`client=`, `model_id=`→`model=`, `@ai_function`→`@tool`)
across several pages but leaves other sibling docs
(`human-in-the-loop.mdx`, `frontend-tools.mdx`, `auth.mdx`) on the old
API — this is a partial migration that needs human review to confirm the
new API is correct and to coordinate updating the remaining pages.

**Included:**
-
`docs/content/docs/integrations/microsoft-agent-framework/agent-app-context.mdx`
-
`docs/content/docs/integrations/microsoft-agent-framework/generative-ui/state-rendering.mdx`
-
`docs/content/docs/integrations/microsoft-agent-framework/generative-ui/tool-rendering.mdx`
-
`docs/content/docs/integrations/microsoft-agent-framework/quickstart.mdx`
-
`docs/content/docs/integrations/microsoft-agent-framework/shared-state/in-app-agent-read.mdx`
-
`docs/content/docs/integrations/microsoft-agent-framework/shared-state/in-app-agent-write.mdx`

**Excluded:**
- `docs/lib/integration-features.ts`

Assumed these are unrelated to the docs fix and excluded them from the
mirror. The original #4128 was closed as part of this handoff; if the
excluded changes are required, please open a new PR for them.
2026-04-21 14:38:02 -07:00
Martha Kelly Schumann 34f53dbbe1 docs(mastra): use requestContext in Agent instructions example (#4108)
## Summary
- Restores the `runtimeContext` → `requestContext` rename in the Mastra
agent-app-context docs (both `docs/` and `showcase/shell/` copies).

## Test plan
- [ ] Skim rendered MDX on both pages; confirm the `Agent` example now
uses `requestContext`.
- [ ] QA team (@Abubakar-01) to validate Mastra Readables work against
this doc.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-21 14:37:51 -07:00
Jordan Ritter dce445e6bc fix(showcase/langgraph-typescript): replace langgraph-cli dev with direct @langchain/langgraph-api server
Root cause of the 4+ day langgraph-typescript Railway flap: `npx @langchain/langgraph-cli dev` is a dev-mode CLI that compiles TypeScript on-demand per HTTP request, blocking the single-thread event loop ~5s per /schemas call. On Railway, Studio IPC handshake + langgraph-api JIT spawn + graph compile routinely exceeded the 90s watchdog budget; PR #4123's 180s grace papered over cold-start but didn't fix steady-state event-loop blocking.

Replace the CLI with a direct import of startServer from @langchain/langgraph-api/server (the same Hono server dev wraps, minus the tsx watcher, Studio handshake, and LangSmith tenant lookup). Schema extraction runs in a worker_thread and is pre-warmed in parallel with server startup.

Container-tested on node:22-slim:
- /ok live in <3s (vs. 5-30s dev)
- /ok steady-state <10ms
- /assistants/search returns the registered graph
- Pre-warm log: [server] Pre-warmed schemas in ~1.3-3.4s

Caveats:
- Uses --legacy-peer-deps for @langchain/langgraph-sdk version skew.
- @langchain/langgraph-api exports ./server but it's not officially public API — exact version pin (1.1.17) required.
- /runs streaming not end-to-end tested (dummy key); /assistants/search and schema extraction verified.
2026-04-21 14:34:22 -07:00
Martha Schumann 61321bb66b docs(microsoft-agent-framework): apply API renames to remaining sibling pages
Completes the partial migration in PR #4128 — extends the same
identifier rename pattern (ChatAgent→Agent, ChatClientProtocol→
SupportsChatGetResponse, chat_client=→client=, model_id=→model=,
@ai_function→@tool, Dict→dict) to the four sibling pages the fork
PR left on the old API, and patches one Dict annotation in
state-rendering.mdx that slipped through the original mirror.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 14:34:15 -07:00
claudebot b9964843ee Apply in-scope subset of PR #4128 2026-04-21 13:57:14 -07:00
Martha Schumann bb0a9191bb docs(mastra): simplify AG-UI context access in Agent instructions example
Drops the inline TypeScript typecast from the Mastra agent-app-context
example and uses optional chaining + direct access instead, so the doc
snippet is easier to read and copy. Keeps optional chaining on `.find`
so the example stays safe when the AG-UI context is absent. Also fixes
the `[!code highlight:N]` count after the comment line was removed.

Ports @Abubakar-01's changes from #4125 so they can ship together with
the `requestContext` rename, targeting the new `showcase/shell-docs/`
path after the shell restructure on main.

Co-authored-by: Muhammad Abubakar <abubakaran102025@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:44:58 -07:00
Martha Schumann bcd5a92d32 Merge remote-tracking branch 'origin/main' into fix/restore-mastra-readables-content 2026-04-21 13:16:01 -07:00
github-actions[bot] d0e99e66be style: auto-fix formatting 2026-04-21 20:13:15 +00:00
Jordan Ritter e2a6cc2bfe Regenerate shell-dojo registry at build and expand CI trigger paths
The dojo app was missing items under the langgraph column because
shell-dojo shipped a stale committed registry.json. The generator
only wrote to shell/, the dojo Dockerfile didn't run the generator
at build, and the CI path filter didn't rebuild the dojo when
manifest files changed.

Fix: emit from generate-registry.ts to shell, shell-dojo, and
shell-docs; add the generator step to shell-dojo's Dockerfile;
expand the deploy workflow's path filter to include packages/**
and shared/**; and refresh the committed registry/demo-content
JSON so files on disk match what the generator produces today.
2026-04-21 13:10:52 -07:00
Jordan Ritter aa4af554a0 Fix shell-dashboard shell links by plumbing NEXT_PUBLIC_SHELL_URL through build
The shell-dashboard app baked http://localhost:3000 into every demo and code link because NEXT_PUBLIC_SHELL_URL was never provided at build time and the source defaulted to localhost. Next.js inlines NEXT_PUBLIC_* at next build, so setting the value on Railway at runtime does nothing.

Fix: remove the silent localhost fallback, pass NEXT_PUBLIC_SHELL_URL as a Docker build arg from showcase_deploy.yml, and fail loudly if it's unset at build so this can't regress silently.
2026-04-21 13:09:47 -07:00
Jordan Ritter 30c6811519 chore(ci): add interim keep-alive cron for showcase starters
Adds a GitHub Actions workflow that curls /api/health on each of the
17 showcase starter services every 5 minutes to keep the agent's
in-memory state warm (JIT, module cache, connection pools). Railway
Pro tier doesn't sleep containers, but warm-state decays over idle.

Intentionally minimal: no Slack, no metrics, no state. Observability
is already covered by showcase_smoke-monitor.yml — this is strictly
keep-alive.

INTERIM — will be superseded by showcase-ops smoke probe cadence
once that service lands (see Notion proposal §2a).
2026-04-21 13:01:38 -07:00
Jordan Ritter 2023340c95 fix(showcase): extend watchdog grace to claude-sdk-typescript and mastra (#4124)
## Incident

Two more showcase starters are in a Railway restart loop with the same
shape that #4123 fixed for langgraph-*:

- **`claude-sdk-typescript`** (package, :8000) — restart-looping since
  **04-20 16:54 UTC**. Runs compiled `node /app/agent_server.js`.
- **`mastra`** (starter, :8123/api) — restart-looping since
  **04-20 18:18 UTC**. Runs `npx mastra dev` on :8123 alongside
  Next.js on ${PORT:-10000}.

## Root cause

Same as #4123: PR #4116's watchdog has a 90s (3-strike) kill budget.
For agents whose cold-start path on a fresh Railway container exceeds
90s, the watchdog kills the agent before it ever reports healthy, and
the loop never breaks.

- `node /app/agent_server.js` cold-starts the full
  `@anthropic-ai/claude-agent-sdk` bundle.
- `mastra dev` performs a tsx build + Mastra server boot on first
  request.

Both exceed 90s on cold-start consistently enough to kill-loop in
production.

## Fix

Extend the `getWatchdogGraceSeconds()` mapping in
`showcase/scripts/generate-starters.ts` to return 180s for
`mastra` and `claude-sdk-typescript` in addition to `langgraph-*`.
Regenerate the two starter entrypoints. Also apply the same grace
block inline to the **package-level** `claude-sdk-typescript`
entrypoint (hand-written, not generator-emitted).

## Scope decision

**Per-framework grace, not universal.** Cite the alternative for the
record:

> Universal 180s would avoid future "which framework class needs
> grace" debate and cost basically nothing on fast cold-starts
> (uvicorn < 10s) — a 180s grace just delays the first probe from
> 30s to 180s.

Kept per-framework for this PR:

1. Smaller diff, smaller review surface (4 files vs regenerating all
   17 starters).
2. Matches the existing design comment in
   `getWatchdogGraceSeconds()` which explicitly argues that uvicorn-
   responsive agents should keep 0s so legitimate hangs restart
   quickly.
3. We now have 3 framework classes needing grace; if a 4th appears,
   universalizing becomes cheap and justified on aggregate data.

## Mastra starter — watchdog kept, not dropped

PR #4116's finisher classified **package-level** mastra as N/A
(correct — the package IS the Next.js app, no separate agent). The
**starter** is different: `mastra dev` runs as a legitimate separate
process on :8123 alongside Next.js on :10000. The watchdog there is
correctly supervising that process — grace is the right fix, not a
revert.

## Files

- `showcase/scripts/generate-starters.ts` — mapping + justification
  comment
- `showcase/packages/claude-sdk-typescript/entrypoint.sh` — inline
  grace block (package uses :8000, hand-written entrypoint)
- `showcase/starters/claude-sdk-typescript/entrypoint.sh` —
  regenerated
- `showcase/starters/mastra/entrypoint.sh` — regenerated

Package-level `mastra/entrypoint.sh` is intentionally unchanged
(no watchdog, just `exec npx next start`).

## Test plan

- [x] `bash -n` clean on all 3 modified `.sh` files
- [x] `pnpm -C showcase/scripts test` — 1079/1079 pass
- [x] `npx tsc --noEmit` in `showcase/scripts` — clean
- [x] `npx tsx generate-starters.ts` is idempotent after the regen
      commit (no further diff)
- [x] `validate-pins` — pre-existing failures on main unchanged; no
      new failures introduced by this PR
- [ ] Railway redeploy of `claude-sdk-typescript` package service
      shows `[watchdog] Agent healthy after Ns — arming strike
      counter` and exits the restart loop
- [ ] Railway redeploy of `mastra` starter service shows the same
      grace log line and exits the restart loop

## Refs

- #4123 — prior langgraph grace fix (same pattern)
- #4116 — origin of the generalized watchdog
- #4114 / #4115 — original crewai-crews watchdog
2026-04-21 12:19:07 -07:00
Jordan Ritter ed45135100 chore(showcase): regenerate claude-sdk-typescript + mastra starters
Regenerated via `cd showcase/scripts && npx tsx generate-starters.ts`
after the getWatchdogGraceSeconds() mapping update in the previous
commit. Only these two starters change — every other framework still
returns 0s from the grace mapping, so their entrypoints are byte-for-
byte identical to main.
2026-04-21 11:48:02 -07:00
Jordan Ritter c3ddd92be9 fix(showcase): extend watchdog 180s grace to claude-sdk-typescript + mastra
Two more starters are restart-looping with the same pattern #4123 fixed
for langgraph-*: the 90s (3-strike) watchdog budget is shorter than the
cold-start path on a fresh Railway container, so the agent gets killed
before it ever reports healthy, and the loop never breaks.

Railway evidence:
- claude-sdk-typescript (package, :8000): restart-looping since 04-20
  16:54 UTC. Runs compiled `node /app/agent_server.js` which spins up
  the full @anthropic-ai/claude-agent-sdk. Package entrypoint is hand-
  written (not generator-emitted), so add the same grace block inline
  matching #4123's shape.
- mastra (starter, :8123/api): restart-looping since 04-20 18:18 UTC.
  Runs `mastra dev` on :8123 alongside Next.js on ${PORT:-10000}.
  `mastra dev` performs a tsx build + Mastra server boot on first
  request — legitimate supervised process, grace is the right fix.

Package-level mastra has no watchdog (the entire package IS the Next.js
app; no separate agent to watchdog) — PR #4116's classification of
"N/A" was correct for the package. The starter has a separate Mastra
dev server, so the generator-emitted watchdog is legitimate there.

Per-framework grace (not universal) preserves the #4123 design: uvicorn
and express agents are responsive within the 2-3s sleep before
AGENT_HEALTH_CHECK, so adding grace elsewhere would only delay
legitimate restart on true hangs.

This commit covers the generator mapping + the hand-written package
entrypoint. The regenerated starter entrypoints land in the next commit.
2026-04-21 11:47:57 -07:00
Jordan Ritter 8708095d34 fix(showcase): langgraph watchdog regression — startup grace period (#4123)
## Incident

`langgraph-typescript` is in a restart loop on Railway as of **04-20
17:05 UTC** (deployment `58bbebe8-7a94-4f99-b6e4-ffcbb4eb78b9`),
returning 502 to production traffic.

## Root cause

PR #4116 generalized the silent-hang watchdog from `crewai-crews` to
every showcase starter: poll agent health every 30s, kill after 3
consecutive failures (~90s). That's fine for uvicorn/express agents
(responsive in <5s), but `langgraph-cli dev` does a heavy cold-start:

- Studio browser IPC handshake (`createIpcServer`)
- `@langchain/langgraph-api` JIT spawn (`spawnServer`)
- Graph compile

On cold Railway containers this routinely exceeds 90s — the watchdog was
killing the process before `/ok` ever became reachable, producing a
kill-loop every ~90s.

## Phase 1 findings

Verified the health path is correct — not a path bug:

- `@langchain/langgraph-cli@1.1.17/dist/cli/up.mjs:27` uses `/ok` as its
own probe.
- `@langchain/langgraph-api@1.1.17/dist/api/meta.mjs:64` registers
`api.get("/ok", ...)`.
- `langgraph_cli` (Python) serves `/ok` from the same api surface.

The regression is purely a **timing** issue: 90s strike budget is
insufficient for langgraph cold-start on Railway.

## Fix — Option B (startup grace)

Added per-framework `getWatchdogGraceSeconds()` in the generator:

- `langgraph-*` starters: **180s grace**
- All other starters: **0s grace** (matches pre-#4116 behavior)

The grace loop waits up to 180s for the first healthy `/ok` probe before
arming the strike counter:

- First success → fall through immediately and arm the counter.
- 180s elapsed without success → arm the counter anyway (steady-state
watchdog then handles true hangs on the normal 90s schedule).
- Agent dies during grace → exit grace loop, `wait -n` in main shell
handles it.

**Not a revert of #4116.** The silent-hang vulnerability class remains
covered (still kills after 90s of steady-state failures); the grace only
defers the first strike.

## Per-starter changes

| Starter | Grace | Behavioral change |
|---|---|---|
| langgraph-typescript | 180s | **Fixes restart loop** |
| langgraph-python | 180s | Preemptive |
| langgraph-fastapi | 180s | Preemptive |
| crewai-crews, ag2, agno, claude-sdk-*, google-adk, llamaindex,
langroid, mastra, ms-agent-*, pydantic-ai, spring-ai, strands | 0s |
None (comment-only diff) |

## Files touched

- `showcase/scripts/generate-starters.ts` — new
`getWatchdogGraceSeconds()` + grace block in `getWatchdogBlock()`
- `showcase/starters/*/entrypoint.sh` — regenerated (17 files; grace
block for langgraph-*, comment-only for the other 14)
- `showcase/packages/langgraph-typescript/entrypoint.sh` — hand-edited
grace block (this package uses its own hand-edited entrypoint, not the
template)
- `showcase/packages/langgraph-fastapi/entrypoint.sh` — same
- `showcase/packages/langgraph-python/entrypoint.sh` — same

## Validation

- `bash -n` passes on all 19 edited `entrypoint.sh` files
- 1079/1079 `showcase-scripts` vitest pass (`pnpm --filter
@copilotkit/showcase-scripts test`)

## References

- Regression source: #4116
- Railway deployment: `58bbebe8-7a94-4f99-b6e4-ffcbb4eb78b9`
- Incident window: 04-20 17:05 UTC — ongoing at PR creation

## Test plan

- [ ] CI green
- [ ] Deploy to Railway — watch first boot log for `[watchdog] Startup
grace: waiting up to 180s...` followed by `[watchdog] Agent healthy
after Ns — arming strike counter`
- [ ] Confirm no restart loop on `langgraph-typescript`
2026-04-21 11:01:19 -07:00
Jordan Ritter c4507bccaa fix(examples/crewai-crews): bump ag-ui-crewai pin to 0.2.x (#4122)
## Summary

Bump the Dojo-side `ag-ui-crewai` pin to match the showcase counterpart
([#4115](https://github.com/CopilotKit/CopilotKit/pull/4115)) and close
the validate-pins drift.

- `examples/integrations/crewai-crews/agent/requirements.txt`:
`ag-ui-crewai>=0.1.5` → `ag-ui-crewai>=0.2.0,<0.3.0`

## Why

`ag-ui-crewai` 0.1.5 has three known defects that took down crewai-crews
in prod for 9h on 2026-04-21:

1. Unguarded `.messages` access on state
2. Orphan `asyncio.create_task` (fire-and-forget without tracking)
3. Sync `completion(` call in an async path

All three are fixed upstream in ag-ui PR
[#1550](https://github.com/ag-ui-protocol/ag-ui/pull/1550), shipped as
ag-ui-crewai `0.2.0`.

Showcase already moved to `0.2.x` in
[#4115](https://github.com/CopilotKit/CopilotKit/pull/4115) (merged
today). Dojo is the user-facing reference repo — leaving it on `0.1.5`
means every reader clones the broken version.

## Pre-flight verification

### Pip resolve (Python 3.12 venv, `pip install --dry-run`)

Clean resolution. Picked `ag-ui-crewai-0.2.0` alongside
`ag-ui-protocol-0.1.17`, `crewai-0.130.0`, `crewai-tools-0.47.1`. No
conflicts reported.

Relevant tail of resolver output:

```
Would install ... ag-ui-crewai-0.2.0 ag-ui-protocol-0.1.17 crewai-0.130.0 crewai-tools-0.47.1 ...
```

### Consumer code audit

Grepped `examples/integrations/crewai-crews/` for any pattern matching
the 0.1.5 defect paths:

- `\.state\.messages` / `state\[.messages.\]` → no matches
- `source\.state\.messages` → no matches
- `asyncio\.create_task` → no matches
- `crewai\.completion\(` / `litellm\.completion\(` → no matches
- `messages|create_task|completion` across the whole `agent/` directory
→ no matches

The Dojo integration consists of `server.py`, `crew.py`, `main.py`,
`tools/custom_tool.py` — none of them directly access `.state.messages`,
schedule orphan tasks, or invoke sync `completion()`. The 0.2.0 bump is
purely a transitive fix; no consumer-side code changes are needed.

## Test plan

- [x] `pip install --dry-run -r
examples/integrations/crewai-crews/agent/requirements.txt` resolves
cleanly (Python 3.12)
- [x] Grep confirms no consumer code hits 0.1.5 defect paths
- [ ] validate-pins CI job goes green (drift closed against showcase)
- [ ] Basic CrewAI flow runs in the dev environment against the updated
pin

## Related

- Showcase counterpart:
[#4115](https://github.com/CopilotKit/CopilotKit/pull/4115)
- Upstream fix:
[ag-ui-protocol/ag-ui#1550](https://github.com/ag-ui-protocol/ag-ui/pull/1550)
2026-04-21 11:00:00 -07:00
Jordan Ritter 008d4e58e8 chore(showcase): ratchet validate-pins baseline after Dojo pin bump 2026-04-21 10:51:55 -07:00
Jordan Ritter f5b7a65b3d fix(showcase): langgraph watchdog regression — add startup grace period
PR #4116 introduced a generalized silent-hang watchdog that polls the
agent health endpoint every 30s and kills the agent after 3 consecutive
failures (~90s). This worked for fast-starting agents (uvicorn,
express) but regressed langgraph-typescript on Railway: `langgraph-cli
dev` does a heavy cold-start (Studio IPC setup + @langchain/langgraph-api
JIT spawn + graph compile) that routinely exceeds 90s on a fresh
container, so the watchdog was killing the process before /ok ever
became reachable — producing the 04-20 17:05 UTC restart loop on
deployment 58bbebe8-7a94-4f99-b6e4-ffcbb4eb78b9.

Phase 1 verification:
  - `@langchain/langgraph-cli@1.1.17/dist/cli/up.mjs:27` uses /ok as
    its own health probe, and `@langchain/langgraph-api@1.1.17/dist/
    api/meta.mjs:64` registers `api.get("/ok", ...)` — so the watchdog
    path is correct. The regression is purely timing.
  - Railway logs show no successful /ok probe before kill-loop starts.

Fix (Option B — startup grace): add a per-framework startup-grace
window in getWatchdogGraceSeconds(). For langgraph-* starters, the
watchdog now waits up to 180s for the first healthy /ok probe before
arming the strike counter. If /ok comes up sooner, fall through
immediately. If 180s elapses without success, arm the counter anyway —
the steady-state watchdog will then handle a true hang on the normal
90s schedule.

Non-langgraph starters (crewai-crews, ag2, agno, etc.) have grace=0 and
behave exactly as before PR #4116 — the 2–3s `sleep` before the health
check is sufficient for uvicorn-based agents.

Files changed:
  - showcase/scripts/generate-starters.ts — new getWatchdogGraceSeconds()
    + grace block in getWatchdogBlock()
  - showcase/starters/*/entrypoint.sh — regenerated (grace block for
    langgraph-*, comment-only for all others)
  - showcase/packages/langgraph-typescript/entrypoint.sh — hand-edited
    grace block (this package uses its own hand-edited entrypoint, not
    the template)
  - showcase/packages/langgraph-fastapi/entrypoint.sh — same
  - showcase/packages/langgraph-python/entrypoint.sh — same

Not a revert of #4116: the silent-hang vulnerability class remains
covered (the watchdog still kills after 90s of steady-state failures;
the grace only defers the first strike).

Validated:
  - bash -n on all 19 edited entrypoint.sh files
  - 1079/1079 showcase-scripts vitest pass
2026-04-21 10:48:07 -07:00
Jordan Ritter b60ce9d31b fix(examples/crewai-crews): bump ag-ui-crewai pin to 0.2.x
ag-ui-crewai 0.1.5 contains three defects that took down crewai-crews
in prod for 9h on 2026-04-21: unguarded .messages access, orphan
asyncio.create_task, and sync completion() calls. All three are fixed
in 0.2.0 (ag-ui PR #1550).

Showcase already moved to 0.2.x in PR #4115. Dojo is the user-facing
reference — leaving it on 0.1.5 means every reader clones the broken
version. This closes the validate-pins drift.

Pip dry-run resolves ag-ui-crewai-0.2.0 cleanly with no conflicts.
Grep of examples/integrations/crewai-crews/ confirms no consumer code
touches the 0.1.5 defect paths (.state.messages, create_task,
completion sync).
2026-04-21 10:41:52 -07:00