Replace `RUN curl -LsSf https://astral.sh/uv/install.sh | sh` across all
starter Dockerfiles with `COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx
/usr/local/bin/`. The curl|sh form has a pipe-swallow latent bug: when
astral.sh returns a 5xx, curl fails but `sh` gets no stdin and exits 0,
so the layer "succeeds" with no uv binary. A later `RUN uv sync` then
crashes with `uv: not found` (exit 127). This already bit the agno
starter today (run 24809910399) when astral.sh had a transient outage;
upstream recovered on its own so this is latent-bug cleanup, not a
hotfix.
Using the official uv image is uv's own recommended pattern: it's
cache-friendly, network-free at build time, and sidesteps the pipe
failure mode entirely.
Scope: all 20 Dockerfiles under examples/integrations/*/Dockerfile,
examples/integrations/*/docker/Dockerfile.agent, and
examples/showcases/scene-creator/agent/Dockerfile.
Verified locally: `docker build -f docker/Dockerfile.agent ./agent`
for agno succeeds against the new pattern.
- langgraph-python: replace ephemeral pkg.pr.new URLs with stable @copilotkit/*@1.56.2
- mastra: wire dev to run ui + agent via concurrently (was only starting UI)
- Restore `|| scripts\setup-agent.bat` / `|| scripts\run-agent.bat` fallback across
12 starter templates so npm install + npm run dev work on Windows without Git Bash
- Add --validate-on-load to all aimock invocations (4 workflows/scripts
+ 13 integration docker-compose files)
- Replace hardcoded 2-file fixture list with dynamic discovery across
showcase/, examples/integrations/*/, scripts/doc-tests/ (16 fixtures)
- Add sanity check to prevent silent zero-test pass when discovery fails
- Extend showcase_validate.yml path filter to trigger on
examples/integrations/**/fixtures/** and scripts/doc-tests/fixtures/**
- Import and use ValidationResult type for callback parameters
- Fix scripts/doc-tests/fixtures/default.json to use { fixtures: [...] }
envelope shape
Playwright install stderr is diagnostic signal — version/network errors,
missing system libs, or browser download failures all surface here. Only
suppress stderr on the noisy npm install step. Also pin the image-tag /
client-version relationship with a code comment on one compose file so
future bumps know to keep them aligned.
The Playwright Docker image (mcr.microsoft.com/playwright:v1.52.0-noble)
ships with all Chromium system libraries and browsers pre-installed, so
`--with-deps` adds no runtime value — it only forces a redundant
`apt-get update && apt-get install` inside the tests container.
That apt-get call is the sole source of the intermittent
"Installation process exited with code: 100" / "Failed to install
browsers" failures that rotate across the 12 smoke matrix entries. The
underlying cause is transient Ubuntu archive mirror hash/size mismatches
("File has unexpected size ... Mirror sync in progress?", "Hash Sum
mismatch"), which cause apt to abort with exit 100. Because each matrix
job races apt against archive.ubuntu.com independently, the failing
subset rotates per run (run 24526747926 hit 5 starters; run 24509673514
hit a different 5; run 24495760568 hit 3) — classic flake, not a per-
starter regression.
Dropping --with-deps eliminates the apt-get call entirely. The browsers
themselves are already present at /ms-playwright/chromium-* in the base
image, and `npx playwright install chromium` remains as a cheap no-op
that self-heals if the pinned Playwright version ever drifts from the
image's bundled browser build.
- Remove '|| .bat' fallback from all starter package.json scripts so
real errors on Linux/macOS are not masked by a failing .bat attempt
- Fix typos: 'isseus' -> 'issues', 'interactin' -> 'interacting'
- Fix crewai-crews README title/body saying 'Flow' instead of 'Crew'
- Fix a2a-a2ui README wrong agent name and file path
- Remove phantom lint/dev:debug scripts from README Available Scripts
sections where those scripts don't exist in package.json
- Add missing dev:ui and dev:agent to mastra README
Reorder package manager instructions to show npm first as the default.
Remove stale 'ignores lock files' notes since lock file entries were
removed from .gitignore. All starters now work with npm, pnpm, yarn,
or bun — user's choice.
Starters should not constrain users to a specific package manager.
The .gitignore gets cloned into the user's project, so ignoring
certain lock files would prevent them from committing their chosen
package manager's lock file.
Templates were pinned at old @ag-ui/client versions (0.0.40–0.0.46).
@copilotkit/runtime@1.55.2 ships 0.0.52, which added private fields to
AbstractAgent. The version split caused a nominal type error on build.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Templates had stale pinned versions ranging from 1.9.3 to 1.52.1.
The CLI does a verbatim sparse checkout of these files, so users
scaffolding via `copilotkit create` were getting old versions installed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
Adds **factory mode** to `BuiltInAgent`, enabling backend-agnostic LLM
integration without introducing a new class. Users provide a factory
function that creates the LLM stream — CopilotKit handles lifecycle
events, stream-to-AG-UI conversion, error handling, and
abort/cancellation.
### What's included
- **Three backend types**: `aisdk` (Vercel AI SDK), `tanstack` (TanStack
AI), and `custom` (raw AG-UI events)
- **Stream converters**: `convertAISDKStream` and
`convertTanStackStream` extract AG-UI events from backend-native streams
- **Input helpers**: `convertInputToTanStackAI` and
`convertMessagesToVercelAISDKMessages` for message/prompt conversion
- **State management**: Automatic `STATE_SNAPSHOT`/`STATE_DELTA` event
extraction from tool results
- **Reasoning support**: Auto-close logic for providers that never emit
`reasoning-end` (e.g. `@ai-sdk/anthropic`)
- **273 tests** across 16 test files covering all backend types,
converters, state tools, multimodal, and edge cases
- **Docs**: Comprehensive factory mode guide with 16 examples covering
tools, reasoning, state, forwardedProps, structured output
- **Example app**: React Router example migrated to factory mode
### Architecture
Factory mode is a discriminated union on `BuiltInAgentConfiguration`:
```typescript
const agent = new BuiltInAgent({
type: "aisdk", // or "tanstack" | "custom"
factory: ({ input, abortSignal }) =>
streamText({ model: openai("gpt-4o"), messages: ..., abortSignal }),
});
```
No new public classes — `BuiltInAgent` handles both simple mode (model
string) and factory mode (user-owned LLM call).
## PR feedback addressed
### Critical fixes
- **C1/M3**: Fixed TOCTOU window — `abortController` now set
synchronously before Observable creation in classic `run()`, with
concurrent run guard
- **C2/M2**: Classic `tool-result` now checks both `output` and `result`
property names, with `try/catch` on `JSON.stringify`
- **C3**: Error case safely handles `undefined` `p.error` with proper
fallback chain
### Important fixes
- **I2**: `RUN_ERROR` events now include `threadId` and `runId` in
classic mode (matching factory mode)
- **I3**: State tool events guarded against `undefined` snapshot/delta
before emitting
- **I4**: `JSON.stringify` wrapped in try/catch with descriptive
fallback message
- **M1**: `assignToolsToAgents` now skips factory-mode agents (prevents
config corruption)
- **M5**: TanStack converter's dropped event types documented with clear
limitation note
### Suggestions addressed
- **S1**: `@ts-expect-error` on `clone()` middlewares documented with
rationale
- **M4**: `AgentFactoryContext.abortController` kept (needed by TanStack
AI) but JSDoc added discouraging direct `.abort()` calls
## Test plan
- [x] 273 unit tests pass across all 3 backend types
- [x] Build succeeds
- [x] React Router example compiles
- [x] Docs render correctly (Vercel preview)
## Summary
Adds a `/health` GET endpoint returning `{"status": "ok"}` to all 11
starter integration examples. This is a best practice for any deployed
service — health checks enable platform health monitoring, load balancer
probes, and container lifecycle management.
**11 starters updated:**
- adk, agent-spec, agno, crewai-crews, crewai-flows, langgraph-fastapi,
llamaindex, ms-agent-framework-dotnet, ms-agent-framework-python,
pydantic-ai, strands-python
**1 skipped:**
- langgraph-python — uses `langgraph dev` which provides its own `/ok`
endpoint
All `/health` endpoints are registered before any catch-all mount to
ensure they take priority (lesson learned from the pydantic-ai showcase
bug).
## Test plan
- [ ] Each starter builds successfully
- [ ] `curl localhost:8000/health` returns `{"status": "ok"}` on each
Every starter's route.ts now reads process.env.AGENT_URL as the
primary agent endpoint, with framework-specific vars as fallback:
- AGENT_URL || "http://localhost:8000" (pydantic-ai, adk, agno, crewai,
ms-agent-python, ms-agent-dotnet, strands-python)
- AGENT_URL || LANGGRAPH_DEPLOYMENT_URL || "http://localhost:8123"
(langgraph-python, langgraph-js)
- AGENT_URL || "http://localhost:9000" (llamaindex)
Also adds .env.example with AGENT_URL to all starters.
Replace eslint and prettier with oxlint and oxfmt for faster linting
and formatting across the monorepo. Remove all eslint and prettier
configs, dependencies, and related packages. Add .oxlintrc.json and
.oxfmtrc.json for the new tooling. Update CI workflows and lefthook
hooks accordingly. Reformat codebase with oxfmt.
https://claude.ai/code/session_01GMkSf29p78HuMR1mbXn8He
Run prettier on ~1,865 files across examples/ to match the monorepo's
formatting standards. These files were imported as-is from standalone
repos that used different prettier configs.
SVG files are text-based XML averaging ~218 bytes each. LFS tracking
adds per-file HTTP fetch overhead with no storage benefit, suppresses
git diff output, and breaks tutorial clone instructions that use
GIT_LFS_SKIP_SMUDGE=1 (users get LFS pointers instead of icons).