Commit Graph

14820 Commits

Author SHA1 Message Date
Maxim 9c6d5b138e fix(react-native): correct SeededAgent.run return type and restore tool-call coverage
- SeededAgent.run now declares Observable<BaseEvent> return (via
  ReturnType<AbstractAgent["run"]>) so check-types passes; throw-only body
  avoids a runtime rxjs import the RN bundler cannot resolve.
- TestCopilotKit accepts optional executingToolCallIds.
- Restore executing-status, empty-string-args, and unrepairable-JSON-args
  coverage as tests driven through the real CopilotKitCoreReact.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-08 16:00:58 +02:00
Maxim 296cd4461c fix(react-native): stream tool-call renders and pass results through, via react-core's renderer
Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-08 15:53:08 +02:00
Atai Barkai 2328062960 docs(channels): clarify the custom channel runner path (#6437)
Small docs clarification for the Channels SDK.

- **Channels overview** (`/channels`): adds a short note under the
architecture diagram that you can build your own channel runner on the
open-source SDK, with no CopilotKit Intelligence dependency — a
supported path where the team owns state, persistence, concurrency,
locking, retries, and race-condition handling. Intelligence remains the
managed runner; analytics, learning, and governance come in addition.
- **Self-hosting section**: Enterprise Intelligence can be fully
self-hosted today; onboarding guides are still to come, and we're happy
to help in the meantime.
- **Package READMEs** (`channels`, `channels-core`, and the five
adapters): removes the "there is no standalone / DIY runner" phrasing,
which contradicted the above, in favor of the same managed-vs-custom
framing.

Intentionally does **not** add any implementation guidance for custom
runners (no state-store interface details, no persistence examples).

Follow-up (not in this PR): swap in the updated architecture diagram
assets (light + dark) that show the "Build Your Own Channel Runner" box
alongside Enterprise Intelligence.

Refs
[FAC-155](https://linear.app/copilotkit/issue/FAC-155/channels-docs-lack-a-clear-supported-path-without-intelligence)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-08 06:35:45 -07:00
Atai Barkai 47a4a84896 docs(channels): re-export architecture diagram at 4000px
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 06:07:15 -07:00
Maxim 2bb1473207 ci(react-native): reframe useRenderToolCall omission as pending, not by design
The prior comment framed useRenderToolCall's absence from the size probe's
import list as a permanent design fact ("DOM-dependent … would fail the
build"). That is the same permanent-sounding rationale that let the stale
claim in src/index.ts go unrevisited for months. The export is missing only
because RN's headless entry does not export it yet; the render-tool
convergence on this branch adds it. Reframe the comment as TEMPORARY — REVISIT
so a future engineer restores the symbol and re-baselines the number once RN
headless exports it. Comment-only; measured size unchanged at 92.8 kB.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-08 14:57:27 +02:00
Maxim f34b7aa23c ci: measure @copilotkit/react-native bundle size (was absent from the glob)
react-native was missing from static_bundle_size.yml's package glob, so its
dist/ has never been measured despite being the consumer most exposed to the
#4893 regression (Metro does not tree-shake). This adds coverage:

- Extend the compressed-size-action glob to include react-native.
- New scripts/measure-headless.mjs: an esbuild-driven gzip signal for the
  @copilotkit/react-native/headless entry, mirroring react-core's
  measure-copilotchat.mjs (stdin + resolveDir, gzip sum, job-summary output).
- Wire a build + measure step into the copilotchat-import-size CI job.

First baseline: @copilotkit/react-native/headless = 92.8 kB gzip
(esbuild regression signal, not a Metro figure).

No limit fields (Phase 1 policy — see dev-docs/bundle-size.md).

esbuild added as a react-native devDependency (^0.27.0, matching react-core);
the root ">=0.25.4" override keeps the monorepo on a single esbuild (0.27.3).

Two corrections to the drafted script, verified by running it:
- Fed the entry via esbuild stdin with resolveDir=pkgRoot; a temp-dir entry
  cannot resolve @copilotkit/react-native/headless through workspace node_modules.
- Dropped useRenderToolCall from the import list — the RN headless surface
  deliberately does not export it (DOM-dependent; see src/index.ts).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-08 14:51:55 +02:00
Maxim 68a30c2535 test(react-core): hard-fail if the /v2/headless chunk links the render stack (#4893) 2026-08-08 14:36:45 +02:00
Maxim ebf0f94fb8 refactor(react-native): register render tools into core's registry, derive props from react-core 2026-08-08 14:27:02 +02:00
Maxim d5ace8b2ce feat(react-core): export ReactToolCallRenderer from the /v2/headless entry 2026-08-08 14:16:21 +02:00
Maxim 94b8357f3c test(react-native): lock the #4893 fat-entry ban in the import-graph guard 2026-08-08 14:07:43 +02:00
Atai Barkai e705704889 docs(channels): update architecture diagram to the runner-emphasis version
New export from Figma: two runner paths (managed Intelligence runner or
build your own), durable-data emphasis, Any Agent framework list, and
channel platforms with the +4 more row. Used for both themes until a
dark export exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 23:28:52 -07:00
Atai Barkai e06b762b3e docs(channels): explain the durable-data dividing line
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 23:22:26 -07:00
Atai Barkai af78563beb docs(channels): self-hosting note covers the Channels SDK
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 23:12:38 -07:00
Atai Barkai 271614573d docs(channels): drop the channels-core pointer from adapter READMEs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 23:07:22 -07:00
Atai Barkai 6e0e1de049 docs(channels): state lifecycle positively across READMEs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 22:56:58 -07:00
Atai Barkai 049bd2bdcc docs(channels-core): drop the phantom-negation phrasing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 22:55:32 -07:00
Atai Barkai a0007c21fe docs(channels): polish the runner note and self-hosting copy
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 22:54:09 -07:00
Atai Barkai adbdf65263 docs(channels): state the free plan plainly
Drop the defensive parentheticals around Intelligence pricing; say
"available on a free plan" and move on.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 22:52:33 -07:00
Atai Barkai cb4439b241 docs(channels): clarify the custom channel runner path
Note in the Channels overview and package READMEs that building your own
channel runner on the open-source SDK primitives is a supported path with
no CopilotKit Intelligence dependency; teams choosing it own their state,
persistence, concurrency, locking, retries, and race-condition handling.
Intelligence remains the managed runner, with analytics, learning, and
governance in addition.

Also updates the production self-hosting note: Enterprise Intelligence can
be fully self-hosted today, onboarding guides are still to come.

Refs FAC-155

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 22:35:13 -07:00
Benjamin Taylor ec06d87fb4 fix(react-core): repair useCopilotReadable effect deps, convert args, and dependencies
Four defects in `useCopilotReadable` were introduced together in 80dffec4e7
(v1.50.0), when the hook was repointed from the v1 context tree onto the v2
flat context store. The pre-1.50 implementation was correct on every count.

- `available` was missing from the effect's dependency array, so toggling it
  between "enabled" and "disabled" after mount did nothing. It is back in the
  deps, alongside the restored `available = "enabled"` default.
- `convert` was invoked as `convert(value)` against its declared
  `(description, value)` signature, so a user's function received the value as
  `description` and `undefined` as `value`. The branches are now split, because
  `JSON.stringify(description, value)` would treat the value as a replacer.
- The `dependencies` positional argument was destructured but never reached the
  deps array, matching the pattern already used by
  `useCopilotAdditionalInstructions`.
- The `found` dedup branch is removed. It compared a raw value against a stored
  entry whose value had already been serialized by `addContext`, so it never
  matched and its early return was unreachable. Repairing the comparison rather
  than deleting it would newly let one component's unmount remove a context
  entry another component still depends on.

`parentId` and `categories` are marked @deprecated: both were dropped from the
hook body by the same commit but left in the options type and the JSDoc, which
advertised a nested-context feature that has been a no-op since v1.50.0. The
JSDoc example is rewritten to document behavior that actually exists. Real
hierarchy support needs parent/child modelling in the v2 context store and is
tracked separately.

Adds the hook's first test file: 12 tests, five of which fail against the
pre-fix implementation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: jwgrsol <wefhio1985@gmail.com>
2026-08-07 16:14:13 -05:00
Austin Merrick b32b5539cc feat: add Inspector navigation, usage, and locked Threads (refs ENT-1173) (#6275)
## What does this PR do?

Adds the CopilotKit consumer side of ENT-1173 across Shared, Runtime,
Core, Web Inspector, and the existing Shell Docs pages.

- Defines and parses optional trusted Inspector metadata for identity,
plan, license, action, usage, and expiry. Runtime proxies it through a
private, failure-isolated route, and Core refreshes it without changing
connection state.
- Groups Inspector navigation into Threads, Agents, and Learning.
Threads renders finite, unlimited, unknown, overage, and expiring usage
states plus matching trusted plan or license actions.
- Keeps explicit `threadEndpoints` as the only authority for Thread
requests. Locked or absent capability states make no list, subscription,
detail, message, event, or state calls.
- Keeps the zero-thread video, three example Threads, detail tabs, and
guided tour in empty and locked states. General Intelligence remains the
default onboarding path; only trusted `team_self_hosted` metadata uses
self-hosted onboarding.
- Gives an active license with missing Runtime routes a short **Finish
setting up Rich Threads** state. Users can copy a safe coding-agent
prompt or open the public Runtime setup guide. The same copy control
appears in that guide, and raw Markdown/LLM views include the full
prompt.
- Keeps finite usage green below 90%, orange from 90% to the limit, and
red at or above the limit. At 90%, a trusted plan action changes from
**Manage Your Plan** to a purple **Upgrade Your Plan** without changing
its trusted URL, action kind, or telemetry contract.
- Adds a deterministic 33-state loopback lab for CopilotKit developers.
It has no production route or export, is absent from public docs and
package metadata, and is excluded from the npm tarball.

`Expiring Soon` is display-only; this PR does not enable the thread
culler. Managed Enterprise receives no manage-plan action, and Team
Self-Hosted receives no hosted plan action. Optional metadata and the
additive expiry field remain compatible across mixed producer, Runtime,
Core, and Inspector versions.

A small Channels test-only change updates fetch mocks for current
TypeScript types. It changes no Slack or Teams docs or runtime behavior.

## Related PRs and issues

- Refs
[ENT-1173](https://linear.app/copilotkit/issue/ENT-1173/ship-plg-ready-inspector-navigation-metadata-and-locked-threads)
- Producer:
[CopilotKit/Intelligence#696](https://github.com/CopilotKit/Intelligence/pull/696)

## Validation

- `@copilotkit/web-inspector`: 20 files and 372 tests passed; typecheck
and production build passed.
- Shell Docs: 57 files and 383 tests passed; lint, typecheck, and
production build passed. The build generated all 222 static pages.
- Browser checks cover the copy-prompt flow, unchanged white **Manage
Your Plan**, purple **Upgrade Your Plan**, orange 4,500/5,000 usage, and
red 5,000/5,000 usage.
- Independent review found no Critical or Important issues.
- The broader Runtime, React Native, Channels, package-quality,
compatibility, and Node-version checks from the prior pushed head remain
green.

## Checklist

- [x] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [x] I updated the relevant documentation
- [ ] "Allow edits by maintainers" is checked
2026-08-07 14:08:23 -07:00
Maxim a60cc771e4 feat(reskinnable-demo): add the people skin (Rowan), a demo-complete People Ops desk (#6432) 2026-08-07 18:56:21 +02:00
Maxim db9b9205b0 Merge branch 'main' into feat/reskinnable-demo-people-skin 2026-08-07 18:51:35 +02:00
Maxim 8d25b6bf07 fix(reskinnable-demo): resolve thread-list identity from the query-string agentId (#6431)
## The bug

`agentIdFromUrl` in `src/app/api/copilotkit/[[...slug]]/route.ts` only
read the target agent from the URL **path** (`/agent/:agentId/run`).
Thread routes carry it in the **query string** instead
(`/threads?agentId=<id>`), so every thread-list request looked
agentId-less and fell through to `defaultSkinId`'s `identifyUser` —
banking's.

That split identity for every non-default skin:

| path | resolves via | result |
| --- | --- | --- |
| `POST /agent/people/run` | `people`'s resolver ✅ | thread created
under `rowan-demo-user` |
| `GET /threads?agentId=people` | **banking's** resolver ❌ | asks for
`northwind-demo-user`, gets `[]` |

## Why it was hard to see

Nothing errors. The thread rail just reads *"No conversations yet"*
forever and reopening a conversation after a reload is impossible —
which reads to a viewer as "this product doesn't persist threads", the
exact opposite of what the demo exists to prove. **Banking was immune
only because it IS `defaultSkinId`.**

## The fix

Fall back to `?agentId=` from the query string when the path carries no
`/agent/<id>` segment.

## Verification

Against a local Intelligence stack, thread counts from `GET
/api/copilotkit/threads?agentId=<id>`:

| skin | before | after |
| --- | --- | --- |
| people | 0 | 11 |
| airline | 0 | 1 |
| logistics | 0 | 3 |
| banking | 7 | 7 (unchanged) |

Confirmed the backend held those threads all along — they were being
listed under the wrong end-user id.

Skins with no `identifyUser` (airline) still fall through to
`genericIdentity()` via the existing `if (!resolve)` guard, so this
widens correct resolution without adding a failure mode.

`pnpm build`, `pnpm lint`, `pnpm test:unit` (335/335) green.

## Skill-staleness check

Per the app's standing rule: **checked, no skill impact.** This is
shell-internal identity plumbing; `.claude/skills/reskin/` documents the
`identifyUser` contract, which is unchanged — a skin still contributes
the same resolver in the same place.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-07 18:51:18 +02:00
Maxim 37988e90b6 Merge branch 'main' into fix/reskinnable-demo-thread-agent-id 2026-08-07 18:51:05 +02:00
Maxim 3d4de1cedd feat(reskinnable-demo): add the people skin (Rowan), a demo-complete People Ops desk
Rowan is a People Operations command center and the second skin built against
the full nine-beat bar in `.claude/skills/reskin/demo-beats.md` (banking was the
first). Pages: Roster (index), Compensation, Requests, Onboarding.

REST-backed like banking and logistics: `/api/people/v1/*` serves one `ledger`
snapshot read plus the write paths, a generated `offer-letter` PDF, and a
presenter-gated `dev/reset`. Components read the ledger through the skin's own
`usePeopleLedger()` context, so `useData` is omitted. That context is mounted in
`RuntimeProviders` rather than `Providers`, which lets the single fetch also feed
`useRuntimeProperties`.

The signature element is the band ladder: one rail per level, each normalized to
its OWN band, so "halfway up L3" and "halfway up L7" line up at the same height
and become comparable. Anyone outside their band is drawn outside the rail, in
the negative colour, always labelled.

Beats, all walked in a browser against a live Intelligence stack:

  1  face          showCompBands renders the ladder + a two-sentence answer
  2  rich thread   gen-UI replays intact on reopen after a hard reload
  3a drive the app setBaseSalary — the figure is typed into a chat card and
                   goes straight to REST; it appears nowhere in the transcript
  3b sees screen   route readable + per-page on-screen readables on all four
                   pages; Roster and Requests give different, correct answers
  3c levers        HITL confirm naming the levers, then
                   ?status=pending&sort=aging_desc&top=10 with the Status, Sort
                   and Show controls visibly tinted, "TOP 10 OF 11"
  3d multimodal    an offer-letter PDF rides the pill, and the filed packet
                   survives deleting the thread and reloading
  4  memory        seeded preference recalled AND named in the component's
                   `note` slot
  5  stored skill  one vague sentence fires three visible writes in order, no
                   confirmations, amid four distractor tools
  6  teach a skill 422 OUT_OF_BAND (symptom only) -> decline -> record the
                   demonstration -> save -> apply unaided to a DIFFERENT person
                   in a fresh thread

Notes for reviewers:

- The beat-6 gate is deliberately discriminating. Decoy exception codes file and
  finalize successfully and still do not lift it, and an unknown code is refused
  without enumerating the catalogue — so "the agent filed an exception" is not
  the same as "the agent cleared the gate". Two out-of-band comp requests are
  seeded so the case taught on stage and the unaided replay are different people.
- Seed dates are relative offsets materialized at store init, not absolute ISO
  strings, so request aging and the generated offer letter stay coherent years
  from now and a Reset genuinely re-freshens the queue.
- Memories are seeded and saved at `user` scope, not `project`. Verified against
  the running stack: a project-scoped row is returned for EVERY user id in the
  instance, so with several skins sharing one backend it is not a per-skin
  boundary. For the same reason this skin's `forgetAllMemories` skips
  project-scoped rows rather than deleting data it does not own, and `dev/reset`
  reports the skipped count.
- `temperature` is not set. gpt-5.4 rejects it and the value is discarded, so
  carrying it alongside a comment claiming determinism would be misleading.
- Beat 2 additionally requires the thread-list identity fix sent separately; the
  skin merges and runs fine without it, it just cannot demo thread reopen.

Docs updated for the fifth skin per the app's standing skill-staleness rule:
CLAUDE.md (skin list, substrate split, beat matrix), README.md,
docs/teach-mode/README.md (teach-mode is now per-skin, not banking-only), and
`.claude/skills/reskin/{SKILL,demo-beats,templates}.md` — including six
"only banking does this" claims that are no longer true.

Verified: pnpm build, pnpm lint, pnpm test:unit (335/335) on this base.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 18:43:44 +02:00
Maxim d7ab8ce2a8 fix(reskinnable-demo): resolve thread-list identity from the query-string agentId
`agentIdFromUrl` only read the target agent from the URL PATH
(`/agent/:agentId/run`). Thread routes carry it in the QUERY STRING instead
(`/threads?agentId=<id>`), so every thread-list request looked agentId-less and
fell through to `defaultSkinId`'s `identifyUser` — banking's.

The result was a split identity for every non-default skin: runs created threads
under the skin's own end-user id (the run path resolves correctly), while the
list asked for banking's id and got an empty array back. The thread rail read
"No conversations yet" forever and reopening a conversation after a reload was
impossible.

Nothing errored, which is what made it hard to see — and it reads to a viewer as
"this product doesn't persist threads", the opposite of what the demo exists to
show. Banking was immune only because it IS `defaultSkinId`.

Verified against a local Intelligence stack; thread counts returned by
`GET /api/copilotkit/threads?agentId=<id>` before → after:

  people      0 → 11
  airline     0 → 1
  logistics   0 → 3
  banking     7 → 7   (unchanged; it was already resolving correctly)

Skins with no `identifyUser` (airline) still fall through to `genericIdentity()`
via the existing guard, so this widens correct resolution without introducing a
new failure mode.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 18:41:28 +02:00
Ben Taylor ea3e3fbfa6 fix(react-ui): let sidebar children fill the viewport height (#6410)
Fixes #261 (open since March 2024). Supersedes #4622 — @ashish4143
diagnosed the same wrappers and is credited as co-author on the commit.

## The bug

`CopilotSidebar` wraps consumer content in two divs:

- `.copilotKitSidebarContentWrapper` (`Sidebar.tsx`) — only sets
`overflow`, `margin-right`, `transition`
- `.copilotKitModalChildrenWrapper` (`Modal.tsx`) — **has no CSS rule
anywhere in the repo**

Both are auto-height blocks, so a child's `height: 100%` has no definite
containing block to resolve against and collapses to content height.

## The fix

An opt-in `fullHeightChildren` prop on `CopilotSidebar` that adds a
modifier class to the content wrapper. Two deliberate choices, both from
the review on #4622:

- **Opt-in, not default.** The content wrapper wraps the *entire*
consumer app. Making it a fixed-height flex column for everyone would
reflow apps that never asked for it.
- **A viewport unit, not `height: 100%`.** `100%` only resolves if every
ancestor (`html`/`body`/`#root`) also declares a height — react-ui
neither sets that nor can guarantee it, so `100%` would silently no-op
in a stock Next.js app. `min-height: 0` on the children wrapper clears
the flex-item `min-height: auto` floor so tall content scrolls inside
the child rather than stretching the wrapper past the viewport.

```tsx
<CopilotSidebar fullHeightChildren>
  <div style={{ height: "100%" }}>...</div>
</CopilotSidebar>
```

## Testing

**Unit** — `packages/react-ui/src/css/sidebar-full-height.test.ts` (4
tests), in the repo's existing CSS-contract style. Guards both halves:
the escape hatch's rules, and that the default wrapper stays
auto-height. Also asserts the height is *not* `100%`, since that's the
regression that would make the whole feature a silent no-op.

```
✓ src/css/sidebar-full-height.test.ts (4 tests)
Test Files  9 passed (9)   Tests  58 passed (58)     # full react-ui suite
```
`npx tsc --noEmit` → exit 0. `oxlint` on changed files → 0 warnings, 0
errors.

**Live in Chrome** — the acceptance criterion from the #4622 review: a
stock app where **nothing** declares a height on `html`/`body`/`#root`,
loading the real built `dist/index.css` (not the source CSS), standards
mode, 762px viewport. DOM per `Sidebar.tsx:92` + `Modal.tsx:143`.

| case | child `height:100%` measures |
|---|---|
| default (no opt-in) | **17px** — collapsed, i.e. behavior unchanged
for existing consumers |
| `fullHeightChildren` | **762px** — exactly the viewport |
| `fullHeightChildren`, content 3000px tall | **762px**, scrolls inside
the child (`min-height: 0` holds) |

Also confirmed on the opt-in path: `.copilotKitSidebar` stays `position:
fixed`, and the expanded push-aside `margin-right` is still `448px`
(28rem), so the sidebar's own layout is untouched.

**Docs** — `CopilotSidebar.mdx` is auto-generated from `Sidebar.tsx`;
regenerated via `scripts/docs/gen.ts` and committed only the new
`fullHeightChildren` entry (the generator also surfaces unrelated
pre-existing drift in other reference pages, left out of this PR).

## Not covered

The issue mentions a "works in Safari, not Chrome" symptom. I verified
in Chromium only — the mechanism above is spec behavior rather than a
Chrome quirk, but I haven't measured WebKit.
2026-08-07 11:36:09 -05:00
Ben Taylor e010786d5c docs(langgraph): replace broken self-hosted auth snippets with a working pattern (#6403)
Fixes #5961 (OSS-609).

## The bug

Both LangGraph auth pages told self-hosted readers to wrap their graph
in `CopilotKitRemoteEndpoint`. That path is retired and fails two ways
against the stack the reporter used (`copilotkit==0.1.94`,
`ag-ui-langgraph==0.0.4x`, Python 3.12):

```
import LangGraphAgent -> ImportError: cannot import name 'LangGraphAgent' from 'copilotkit'
execute_agent -> AgentExecutionException: Agent 'sample_agent' failed to execute:
                 'LangGraphAGUIAgent' object has no attribute 'execute'
```

(Reproduced locally against the `langgraph-fastapi` example's venv —
output above is verbatim.)

## The fix

`showcase/shell-docs/src/content/docs/auth.mdx` (Self-hosted tab of the
`auth_pattern: langgraph` section) and
`showcase/shell-docs/src/content/docs/integrations/langgraph/auth.mdx`
now document the supported pattern: **serve the AG-UI endpoint
yourself**, validate in a FastAPI dependency (401 before the graph
runs), and bake the resolved user into a **per-request**
`LangGraphAGUIAgent(config={"configurable": {"auth_user": user}})` so
nodes read an already-verified identity off `RunnableConfig` — no raw
token in the graph, no shared agent carrying another request's identity.
The gate-only variant (`FastAPI(dependencies=[Depends(current_user)])` +
`add_langgraph_fastapi_endpoint`) is documented for readers who only
want unauthenticated traffic rejected.

Two adjacent bugs on the same pages, fixed here because they break the
same walkthrough:

- **The frontend channel was wrong.** The pages said to pass
`properties={{ authorization: userToken }}` and claimed it "is forwarded
as a Bearer token". Nothing in `packages/` converts properties into
headers — `properties` reach the agent as AG-UI `forwardedProps` (run
payload data). The v2 runtime *does* forward the inbound `authorization`
header (and custom `x-*`) onto the agent call, so `headers={{
Authorization: ... }}` is the channel that actually works, for both
Platform and self-hosted.
- **The Platform user key was wrong.**
`config["configuration"]["langgraph_auth_user"]` →
`config["configurable"]["langgraph_auth_user"]` (matches
`langgraph/pregel/main.py` and `langgraph_api/worker.py`).

## Testing

**1. Doc snippets extracted verbatim from the MDX and executed** (a
script pulls the `main.py` + node code blocks out of each page, stubs
only `validate_your_token`, and drives them with `TestClient`; run under
the `examples/integrations/langgraph-fastapi` venv — `copilotkit
0.1.94`, `ag-ui-langgraph 0.0.41`, Python 3.12):

```
# docs/auth.mdx
PASS  no header -> 401  {"detail":"Missing bearer token"}
PASS  bad token -> 401  {"detail":"Invalid token"}
PASS  valid token -> 200
PASS  no RUN_ERROR
PASS  node read user_123 off RunnableConfig
PASS  node read role 'member'
PASS  run completed
   MESSAGES_SNAPSHOT: [{"id": "None", "role": "assistant", "content": "hello user_123"}]
ALL DOC-SNIPPET CHECKS PASSED

# docs/integrations/langgraph/auth.mdx — same script, same 7 checks
ALL DOC-SNIPPET CHECKS PASSED
```

**2. Gate-only variant**
(`FastAPI(dependencies=[Depends(current_user)])` + stock
`add_langgraph_fastapi_endpoint`):

```
no token -> 401 {"detail":"Missing bearer token"}
valid token -> 200 True True
PASS gate-only pattern (401 without token, run proceeds with token; identity NOT injected)
```

The trailing `True True` is `RUN_FINISHED` present **and** the node
seeing `nobody` — i.e. the gate works but no identity lands on the
config, exactly as the docs now say.

**3. Header forwarding actually reaches a LangGraph deployment** — the
claim behind the new `headers` guidance. Pointed a real
`@ag-ui/langgraph` `LangGraphAgent` at a local stub server, set
`agent.headers` the way `configureAgentForRequest` does, and recorded
what arrived:

```
[ { "url": "/assistants/search", "auth": "Bearer end-user-token", "apiKey": "server-side-key" } ]
PASS: authorization forwarded to the deployment
```

Both the end-user token and the server-side key arrive, which is why the
"server-configured headers win on collision" note is accurate.
Runtime-side breadth is already covered by
`packages/runtime/src/v2/runtime/__tests__/agent-utils-header-forwarding.test.ts`
("authorization header IS forwarded").

**4. Docs render checks** — both pages compile as MDX (`@mdx-js/mdx`
`compile()`), and every `python` block on both pages parses
(`ast.parse`), including the ones I didn't touch.

## Follow-up

**The DIY endpoint is deliberate but temporary.**
`add_langgraph_fastapi_endpoint` exposes no per-request seam (no
`dependencies` passthrough, no config/agent factory), and `endpoint.py`
is byte-identical in 0.0.41 and 0.0.42 — so owning the route is
currently the only way to get a verified identity onto
`config["configurable"]`. Adding that seam upstream in
`ag-ui-protocol/ag-ui` is tracked as **OSS-760**; when it lands, both
pages collapse back to the helper form and the DIY route stays only as
an escape hatch.


The broader "document request-scoped auth for
`add_langgraph_fastapi_endpoint`" ask in #3177 is now substantively
answered by these pages; leaving that issue open pending a maintainer's
call on whether it wants an SDK-level hook rather than the DIY endpoint.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-07 11:34:26 -05:00
Ran Shem Tov 7e8a65a972 test(showcase): ratchet CrewAI matrix after main merge 2026-08-07 18:36:50 +03:00
Ran Shem Tov 6862508eb2 Merge remote-tracking branch 'origin/main' into codex/crewai-full-d6
# Conflicts:
#	showcase/harness/Dockerfile
#	showcase/scripts/fail-baseline.json
2026-08-07 17:53:55 +03:00
Ran Shem Tov 61eed4a4ad fix(showcase): harden CrewAI D6 parity on a3 2026-08-07 17:50:13 +03:00
Ran Shem Tov 255f791d81 test(showcase): support live D6 fixture recording 2026-08-07 17:49:22 +03:00
Alem Tuzlak 6f640f7eb1 fix(showcase/ms-agent-dotnet): surface shared-state-read-write chat replies (#6233)
## Summary

`shared-state-read-write` pills showed **no chat responses** on staging.

### Cause

#6227 wired deterministic replies for the suggestion pills, but those
updates were emitted as:

```csharp
new AgentRunResponseUpdate { Contents = [new TextContent(...)] }
```

without `Role = ChatRole.Assistant`. AG-UI's .NET adapter only turns
assistant-role text into `TEXT_MESSAGE_*` events, so the frontend
dropped every pill reply. Notes snapshots could still land; chat looked
dead.

### Fix

- Set `Role = ChatRole.Assistant` on deterministic text updates
- Prefer `message.Text` when resolving the latest user message
- Broaden pill matching for greet / weekend / remember-something copy

## Test plan

- [x] `dotnet build` ms-agent-dotnet agent
- [ ] Staging after deploy: Greet / Remember something / Plan a weekend
all show assistant text; Remember something updates the notes panel
2026-08-07 16:31:02 +02:00
Alem Tuzlak d5d2e73a53 fix(showcase/ms-agent-dotnet): ground declarative-gen-ui charts in sales data (#6232)
## Summary

`declarative-gen-ui` on staging painted surfaces but charts showed **No
data available** and tables were empty.

### Cause

With `injectA2UITool: false`, the secondary design LLM does **not**
receive frontend App Context (`useSalesAnalystContext` /
sales-context.ts). It only got a thin design prompt, so it omitted or
emptied `PieChart`/`BarChart` `data` arrays and `DataTable` rows.

### Fix

- Embed the Vantage Threads Q2 dataset + composition rules into
`DeclarativeGenUiDesignSystemPrompt`
- Add concrete non-empty PieChart / BarChart / DataTable examples
- Coerce string chart values to numbers
- Tighten outer agent: one short sentence, no prose dashboards

## Test plan

- [x] GenerateA2ui unit tests 12/12
- [ ] Staging after deploy: all four declarative-gen-ui pills show
populated charts/tables from the Q2 dataset
2026-08-07 16:29:19 +02:00
Maxim 6181fd24c5 feat(reskinnable-demo): LOCK_SKIN serves one skin at the root (#6405)
`LOCK_SKIN=<skin id>` turns the four-skin demo shell into a
**single-tenant product deploy**. Unset — the default — behaviour is
byte-identical to before.

```
LOCK_SKIN=logistics   # the skin is SERVED AT /, and the /logistics prefix
                      #   leaves the URL space: /, /lanes, /inventory
                      # /logistics itself -> 404, as do banking|airline|keel
                      # switcher -> static badge; tab reads "Meridian"
LOCK_SKIN=            # unset: all four reachable under /<id>, switcher present
LOCK_SKIN=bankng      # throws at boot, naming the typo and listing valid ids
```

The point is what the deploy *admits to being*. The selector card used
to announce "this is a reskinnable demo with four tenants" — and so did
every URL. A locked deploy says "this is Meridian": in the routing, the
chrome, the page metadata, **and the address bar**.

## Design notes for review

- **Served at `/`, not redirected to `/logistics`.** A redirect still
puts the substrate's tenant id in front of a customer, on the front door
and on every link after it. `src/proxy.ts` REWRITES the prefix-free
space onto the `/[skin]` route tree instead, so the segment never
appears.
- **`proxy.ts`, not a `next.config` rewrite.** `rewrites()` is
serialised into `routes-manifest.json` at BUILD time, which would bake
the lock into the artifact. Proxy files (Next 16's rename of
`middleware.ts`) always run on the Node.js server, so `LOCK_SKIN` stays
a per-request read and ONE BUILD SERVES BOTH HOSTS.
- **The SSE stream is safe by construction.** The matcher excludes `api`
at a segment boundary, so `/api/copilotkit` never enters the proxy.
`proxy.test.ts` asserts it directly, plus a live-server check in the
locked e2e.
- **Links are the other half of the contract.** `useSkinHref`
(`src/shell/skin-path.ts`) makes every in-skin href prefix-free under a
lock. The rewrite alone is useless: a hardcoded `` `/${skin.id}/cards`
`` still RESOLVES, it just puts the prefix back in the address bar on
the first nav click.
- **`useSkinHref` drops the prefix for the LOCKED skin, not for any
lock** (`locked === skinId`). Otherwise `useSkinHref("airline")` under
`LOCK_SKIN=banking` would silently ignore the id it was handed and
return a banking URL.
- **`params` is untouched, which is why this is a rewrite.** The rewrite
target keeps the `[skin]` segment, so keel's `useParams<{ skin, rest }>`
pages needed no change. Collapsing `[skin]/[[...rest]]` into a root
catch-all — the obvious alternative — would have broken them.
- **`useSkinSegments` replaces three copies of
`pathname.split("/").slice(2)`.** It strips a LEADING skin id rather
than slicing a fixed offset, so it is correct whether or not the
pathname carries the prefix, and does not depend on resolving whether
`usePathname()` reports the browser URL or the matched route under a
rewrite.
- **The URL contract is enforced by an ESLint AST rule**, not by
scanning source as text. See "What the review changed" below — this
replaced a regex scanner that drifted out of true three rounds running.
- **Non-`NEXT_PUBLIC_` env**, read server-side and threaded to client
chrome through a small context, so one build serves every deployment
shape. **`force-dynamic` on both env-reading entry points** — reading
`process.env` is not a dynamic API, so `/` would otherwise be
prerendered with the build-time skin baked in. **SSR metadata** via
`generateMetadata`, because a client effect cannot brand what crawlers
and unfurlers read.
- **A disabled dropdown was rejected** for the locked state — it implies
a choice that doesn't exist. The switcher's own
`router.push(\`/${skin.id}\`)` deliberately KEEPS the prefix: it renders
only when unlocked, and switching skins is the one case where the
segment is meaningful.

## What the review changed

A 5-round review loop (7+ unbiased agents per round, ~60 agent-reviews
total) found and fixed the following. Round 1 found four production
defects; rounds 2–5 found **zero** — every later finding was in the
review's own scaffolding or in docs the fix cycles themselves wrote.

**Production defects (all round 1):**

| Defect | Impact |
|---|---|
| `` `${base}/charges` `` and `` `${base}${page}` `` in
`banking/tools.tsx` | `skinHref()` returns `/` under a lock, so these
emitted `//charges` — a **protocol-relative URL that navigates
off-site** to `https://charges/`. Both were `router.push` calls,
invisible to any rendered-href check. Now routed through a pure,
unit-tested `nav-target.ts`. |
| Proxy matcher excluded `_next/static` + `_next/image`, not `_next` |
`/_next/webpack-hmr` and the error-overlay endpoint WERE rewritten under
a lock, breaking HMR and the overlay in `next dev` — which
`next.config.mjs:22` states is how this demo is presented. |
| `api`/`_next` matched by prefix, not segment | A future `/apiary` or
`/api-keys` route would silently skip the rewrite and 404 only on locked
deploys. |
| The locked e2e's headline guard passed vacuously |
`expect(hrefs).toEqual([])` succeeds when zero links render. Now has a
positive precondition plus a `//` assertion. |

**Scaffolding and docs, rounds 2–5:** the drift guard was rewritten from
a regex text-scanner to an ESLint AST rule after it produced a mandatory
finding three rounds running (it caught 1 of 5 spellings, missed the bug
that actually shipped, over-claimed its coverage, and was evadable via a
`$` in a variable name); the AST rule was then narrowed twice, first to
navigation contexts and then to navigation *objects*, after it
false-positived on dates (`` `${m}/${d}` ``), `String.replace`,
`Object.assign` and `Array.push`. Docs fixes: a false "defence in depth"
claim on `/`, the README's skin count, keel's brand name, and the reskin
skill's file list.

**Deliberately not fixed here** — 13 real findings that fail all three
subject-scope tests, routed to follow-up PRs under four subject handles:
Intelligence dev-env credential/org consistency (`.env.example` key
contradicts `docker-compose.yml`, silently emptying memory scope), HITL
replay-safety across banking and keel (including an approval card that
offers a non-approver no escape, hanging the interrupt), reskin template
correctness (a stray space in the `theme.css` selector yields invalid
CSS), and assorted pre-existing nits. Full list in the review ledger.

## Deliberately out of scope

- **Does not pin dark/light** — separate axis (theme toggle + per-skin
`--nw-dark-capable`).
- **Does not hide the inspector.** Locked-`banking`-with-inspector is
the intended FDE configuration.
- **Not a security boundary.** All four agents stay registered
server-side, so another skin's agent endpoint remains reachable under a
lock. `.env.example` says so explicitly.

## Verification

`pnpm lint` clean · `pnpm test:unit` 54 files / 335 tests · `pnpm build`
clean (the type-check gate) · zero static routes, `ƒ Proxy (Middleware)`
registered · locked e2e 12/12.

**One build artifact, served three ways, driven in a REAL BROWSER.** Raw
SSR HTML cannot substitute: the skin tree is entirely client-rendered,
so the server response contains no nav links at all. The hrefs — the
thing most likely to be wrong — only exist after hydration.

| Same build served… | `<title>` | `/` renders | nav hrefs | other
routes |
|---|---|---|---|---|
| `LOCK_SKIN=banking` | `Northwind Finance` | cards view **at `/`** |
`/`, `/dashboard`, `/charges`, `/team` | `/banking`, `/airline`, `/nope`
→ 404 page |
| `LOCK_SKIN=keel` | `Keel` | Desk **at `/`** | zero `/keel`-prefixed
hrefs in the DOM | `/knowledge/phi-access-policy` → doc reader, all 6
sections |
| unlocked | `CopilotKit Reskinnable Demo` | 307 → `/banking` |
`/banking`, `/banking/dashboard`, … | all four 200; switcher present |

Clicking a nav entry under a lock keeps the URL prefix-free with
`aria-current` on the correct entry. `GET /api/copilotkit/info` returns
200 under both locks and `public/sample-invoice-q2.pdf` still serves.
Airline and logistics were browser-verified locked as well.

**The e2e suite now has two projects**, because the lock is a boot-time
server env and the two deploy shapes are therefore two processes:
`unlocked` (port 3000) runs 17 tests, `locked` (port 3100,
`LOCK_SKIN=banking`, its own `.next-locked` dist dir) runs 12. Target
one with `--project=locked`.

## Known, pre-existing

**An unknown path under a lock renders the 404 PAGE but returns HTTP
200.** Not caused by the rewrite — on the unlocked build `/banking/nope`
is already 200, because `notFound()` raised from a client PAGE component
cannot change a status Next has already committed, whereas `notFound()`
from a layout can. The lock only changes which of those two paths an
unknown URL takes.

**The lint rule is sound, not complete** — deliberately, and documented
in the config. A URL assembled into a variable before `router.push(u)`,
or built with string concatenation, is not caught. Completeness would
require flagging shapes indistinguishable from legitimate code, and a
guard that misfires gets disabled.

**`next-env.d.ts` churns on e2e runs.** Next rewrites it to reference
whichever dist dir booted last, so a full run leaves it pointing at
`.next-locked`. Discard that hunk before committing; any build restores
it. Documented at the env block in `playwright.config.ts`.

`e2e/memory-learning.spec.ts` fails in this environment and reproduces
identically at base `77d99f6` — it exercises license-gated durable
memory and needs the Docker Intelligence stack. Not this branch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-07 13:45:14 +02:00
renovate[bot] dcddb18e78 chore(deps): update reviewdog/action-actionlint action to v1.73.1 (#6429)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[reviewdog/action-actionlint](https://redirect.github.com/reviewdog/action-actionlint)
| action | patch | `v1.73.0` → `v1.73.1` |

---

### Release Notes

<details>
<summary>reviewdog/action-actionlint
(reviewdog/action-actionlint)</summary>

###
[`v1.73.1`](https://redirect.github.com/reviewdog/action-actionlint/compare/v1.73.0...v1.73.1)

[Compare
Source](https://redirect.github.com/reviewdog/action-actionlint/compare/v1.73.0...v1.73.1)

</details>

---

### Configuration

📅 **Schedule**: (in timezone America/Los_Angeles)

- Branch creation
  - "before 9am every weekday"
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/CopilotKit/CopilotKit).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
2026-08-07 11:32:52 +00:00
Maxim e79376b11b Merge branch 'main' into feat/reskinnable-demo-lock-skin 2026-08-07 13:32:13 +02:00
renovate[bot] f4c959e3fe chore(deps): update reviewdog/action-actionlint action to v1.73.1 2026-08-07 10:11:21 +00:00
Maxim d6f285baec docs(reskinnable-demo): require a skill-staleness check on every code change
The reskin skill is the only instruction a new skin's author reads, and it goes
stale SILENTLY: nothing type-checks it, no test imports it, and a skin built from
a stale template still compiles, lints and renders. There is no mechanism that
notices — only a person who thought to look.

This adds one standing question to every change to existing code: does it make
anything in `.claude/skills/reskin/` wrong, incomplete or misleading? Answered in
the PR body or commit message; "checked, no skill impact" is a fine answer. The
unanswered question is the failure, not a considered no.

Grounded in three real misses from the LOCK_SKIN root-serving change in this same
PR, all caught late and none by tooling:

- templates.md handed every new skin the two patterns that change had just removed
  (a hardcoded `/${skin.id}/…` href, a fixed `pathname.split("/").slice(2)`). Both
  fail silently under a lock — the page renders, the URL is just wrong.
- SKILL.md's verification steps pointed at `pnpm test:unit` and a drift test the
  same PR deleted. Caught by a reviewer, not by a gate.
- The skill's authoring half was updated and its verification half was not; the gap
  survived until it was asked about directly.

Includes a trigger table (contract change, required/forbidden call, a gate a skin
must pass, registration/routing/boundary, beat mechanism, brand or id, deleted or
renamed referenced file) so it is a lookup rather than a judgement call, and a
~2-minute grep check.

Skill-staleness check for THIS change: no impact. It is a process rule for people
editing the app, not guidance for people authoring a skin; no contract, gate,
command or path the skill references is altered.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 10:48:30 +02:00
Mark 2e0627fc08 fix(shell-docs): drop the redirect-only link rewrites from this PR
Nine /integrations/<fw>/* links were rewritten to their canonical URLs.
Checking production, they were never broken — seo-redirects.ts 301s that
whole retired surface, so a reader always landed on the right page. That
made them cosmetic, and cosmetic changes do not belong in a PR whose
value is the defects around them.

Removing them takes this from 22 files to 15, all of which are things a
reader actually hits. The canonicalization is still worth doing; the
checker now reports it as its own advisory (legacy-redirect-links) so it
is tracked rather than lost.
2026-08-07 02:23:09 +00:00
Tyler Slaton 66fef88b24 chore: release monorepo v1.66.4 (#6426)
## Release monorepo v1.66.4

**Scope:** `monorepo` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.66.4`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.66.4`
   - Creates git tag `monorepo/v1.66.4`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
v1.66.4
2026-08-06 18:25:59 -07:00
tylerslaton b40602e698 chore: release monorepo v1.66.4 2026-08-07 01:25:14 +00:00
Mark 6457e87378 fix(shell-docs): repair 24 dead links, missing imports, and stale demo ids
Twenty-four defects a reader would hit, each verified against the tree
rather than pattern-matched. Found while root-causing PDX-313.

Links written as filesystem paths instead of served URLs (9). The docs
router serves integration pages at /<framework>/<slug>; the
/integrations/ prefix is the content directory, not a route. All nine
corrected URLs were confirmed to resolve.

Tutorial cross-links to directories with no index.mdx (4). loadDoc
resolves <slug>.mdx or <slug>/index.mdx, so /tutorials/ai-todo-app was a
404 — the page is at /overview.

Snippet components used with props but never imported (7). These fall
through to stubWithPartial in the global mdx-registry, which drops props
"on the floor" by design, so framework="pydantic-ai" never reached the
partial and the shared snippet rendered untailored. Importing the
partial restores prop flow. The mastra and ag2 siblings were already
correct; the seven broken ones are all in authored trees.

Dead YouTubeVideo imports (2). The component is provided globally by
mdx-registry.tsx and four other pages render it with no import at all;
these two imported a module that has never existed in the repo.

Stale byoc-* demo ids (2). Renamed to declarative-* in 70e2fb13c8
(2026-05-10, "rename byoc-* slugs to declarative-*"); the docs were
never updated. Only the three registry ID references per page change
here — snippet_cell, InlineDemo, IntegrationGrid.

Left alone deliberately: the runtimeUrl/agent code samples on the
hashbrown and json-render pages. The API routes were renamed to
copilotkit-declarative-*, but the agent ids were not renamed
consistently — declarative-hashbrown's demo uses
agent="declarative-hashbrown-demo" while declarative-json-render's still
exports AGENT_ID = "byoc_json_render". Guessing would ship a broken
copy-paste sample, so that needs an owner.
2026-08-07 01:17:53 +00:00
Tyler Slaton 5ef81c1d5b chore: release monorepo v1.66.3 (#6424)
## Release monorepo v1.66.3

**Scope:** `monorepo` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.66.3`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.66.3`
   - Creates git tag `monorepo/v1.66.3`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
v1.66.3
2026-08-06 17:34:05 -07:00
tylerslaton cfc5cfe727 chore: release monorepo v1.66.3 2026-08-07 00:31:47 +00:00
Mark 6c6ec28da6 docs(pydantic-ai): remove duplicate quickstart, fix dead links and commands (#6421)
Mechanical documentation repairs for the Pydantic AI integration, found
while auditing its docs. **No content rewrites** — every change here is
a dead link, a wrong command, or a duplicate file, and each was verified
against the tree.

## Changes

| Fix | Evidence |
|---|---|
| Delete `shell-docs/.../pydantic-ai/quickstart/` (`pydantic-ai.mdx` +
`meta.json`) | `seo-redirects.ts` rule **F6** already routes
`/pydantic-ai/quickstart/pydantic-ai` → `/pydantic-ai/quickstart`; adk
has the identical **F7** rule and no such directory. pydantic-ai was the
**only** framework of 17 still carrying a `quickstart/` subdir alongside
the canonical `quickstart.mdx`. |
| `human-in-the-loop/agent.mdx` — quickstart link | Pointed at the
redirected legacy path; now points at `/pydantic-ai/quickstart`
directly. |
| `human-in-the-loop/agent.mdx` — starter link |
`examples/coagents-starter-pydantic-ai` does not exist. Now
`examples/integrations/pydantic-ai`. |
| `docs-links.json` — `subagents.shell_docs_path` | Was
`/multi-agent/subagents`; there is no `multi-agent/` directory. Real
page is `/multi-agent-flows`, which the entry's own `og_docs_url`
already pointed at. |
| `headless-simple/chat.tsx` — console tag | Said
`[langgraph-python:headless-simple]` inside the pydantic-ai package.
This sits inside an `@region` block, so it is pulled into the docs as a
snippet. |
| `pydantic-ai-todos/README.md` — troubleshooting command | `uv run
src/main.py`; that file does not exist in this tree (entrypoint is
`agent/main.py`, which `scripts/run-agent.sh` gets right). |
| `pydantic-ai-todos/README.md` — Python floor | Said 3.12+;
`agent/pyproject.toml` declares `requires-python = ">=3.13"`. A 3.12
user hits a `uv sync` resolver error. |
| `canvas/pydantic-ai/README.md` — prerequisites | Said Python 3.8+, but
`agent/agent.py:100` uses a PEP 604 union (`str \| None`), which
requires 3.10+ at runtime. Aligned to the sibling tree pinning the same
`pydantic-ai-slim==2.22.0`. Node floor aligned to the two sibling
READMEs. |

## Deliberately not included

- **The `human-in-the-loop.mdx` / `human-in-the-loop/index.mdx` route
collision.** Both resolve to `/pydantic-ai/human-in-the-loop`, and
pydantic-ai is the only framework with both. Resolving it means choosing
which page survives — the flat file has the correct `pydantic-ai` demo
embed, the directory matches the house structure. That is a content
decision, tracked in OSS-777 along with the related `meta.json` nav
omission.
- **11 other integrations carry the same
`[langgraph-python:headless-simple]` console tag.** Left for the fleet
sweep rather than fixed piecemeal here.
- Two candidate findings were **dropped after verification**:
`/pydantic-ai/generative-ui` is not a dead link (no framework has a
`generative-ui/index.mdx` — it is the house pattern), and `uv run
main.py` in `docs/setup/channels-agent-setup.mdx` is correct (the
quickstart genuinely produces a `main.py` in a uv project).

## Related

- OSS-777 — the remaining pydantic-ai documentation drift (PARITY_NOTES
rewrite, `qa/*.md` sweep, per-demo READMEs teaching LangGraph APIs)
- #6379 — carries the v2-specific doc corrections
- #6381 — the D6 probe failures with the same root cause

## Verification

Static: `docs-links.json` re-parsed and its new target confirmed to
exist; deleted paths confirmed unreferenced except by the F6 redirect
that supersedes them; every replacement path confirmed present on disk.
No Docker in the audit environment, so the docs site was not built —
worth a preview check on the nav after the `quickstart/` deletion.
2026-08-06 16:51:36 -07:00
Mark 0c10d8c882 docs(pydantic-ai): remove duplicate quickstart, fix dead links and commands
Mechanical repairs found while auditing the pydantic-ai docs. Each was
verified against the tree; nothing here is a content rewrite.

- Delete `quickstart/pydantic-ai.mdx` + its `meta.json`. `seo-redirects.ts`
  already routes `/pydantic-ai/quickstart/pydantic-ai` ->
  `/pydantic-ai/quickstart` (rule F6), and adk got the same treatment (F7).
  pydantic-ai was the only framework still carrying a `quickstart/`
  subdirectory alongside the canonical `quickstart.mdx`.
- `human-in-the-loop/agent.mdx`: link to the canonical quickstart directly
  instead of the redirected legacy path, and point the starter link at
  `examples/integrations/pydantic-ai` — `examples/coagents-starter-pydantic-ai`
  does not exist.
- `docs-links.json`: `subagents.shell_docs_path` was `/multi-agent/subagents`,
  which has no page. The real page is `/multi-agent-flows`, which the
  entry's own `og_docs_url` already pointed at.
- `headless-simple/chat.tsx`: the console tag said `langgraph-python` inside
  the pydantic-ai package. This sits in an `@region` block, so it is pulled
  into docs as a snippet. 11 other integrations carry the same copy-paste;
  they are left for the fleet sweep.
- `examples/showcases/pydantic-ai-todos/README.md`: `uv run src/main.py` ->
  `uv run main.py` (there is no `src/main.py` in that tree), and the stated
  Python floor now matches `agent/pyproject.toml` (`>=3.13`).
- `examples/canvas/pydantic-ai/README.md`: Python 3.8+ was unrunnable —
  `agent/agent.py` uses PEP 604 unions. Aligned to the sibling tree that
  pins the same `pydantic-ai-slim==2.22.0`.
2026-08-06 21:47:23 +00:00
Mark 3cf128ec8f docs(showcase): correct pydantic-ai v2 API refs and gen-ui-agent comments
PARITY_NOTES.md and qa/beautiful-chat.md described `agent.to_ag_ui()`,
which v2 removes. Replaced with the AG-UI adapter / `mount_agent()`
wording this branch introduces.

Also flags the PARITY_NOTES "Skipped demos" section as stale rather than
silently leaving it: mcp-apps, hitl-in-chat and hitl-in-chat-booking all
ship, and the reasoning/interrupt reasons no longer match manifest.yaml
(which is the authority). Full rewrite tracked in OSS-777.

The gen-ui-agent comments asserted a `src/agents/gen_ui_agent.py` and a
`set_steps` tool that exist nowhere in this package. The cell has no route
override, so it proxies to the root sales agent and its D6 probe is red on
main (GH #6381). The comments now describe that, instead of an
intended-but-unbuilt contract.

Adds the missing `shared-state-read` entry to manifest.yaml `demos:` — it
was declared under `features:` with no route or highlight. Mirrors
langgraph-python's entry, which likewise omits an agent file because the
cell runs on the neutral default agent.
2026-08-06 21:42:05 +00:00
Maxim 43df6e5afd Merge remote-tracking branch 'origin/main' into feat/reskinnable-demo-lock-skin 2026-08-06 22:10:21 +02:00