mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
tyler/workflow-observer-example
1065 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f2c9a2ecfe |
docs(react-core): clarify system_prompt requirements for useFrontendTool (#5469)
## What does this PR do? Adds documentation explaining that `useFrontendTool` may require explicit `system_prompt` guidance in LangGraph agents to be reliably called. Includes a working code example showing both a well-described `useFrontendTool` registration and the matching system prompt instruction. Addresses the confusion reported in #4950 where users implement tools with only a `description` and find the agent doesn't call them. Changes: - `docs/integrations/langgraph/frontend-tools.mdx` — new section "Ensuring your agent reliably calls frontend tools" with a `Callout`, Python+TypeScript code examples, and a decision table (description vs. system_prompt) - `reference/hooks/useFrontendTool.mdx` — added "LangGraph agents: description vs. system_prompt" subsection linking to the full example - `docs/troubleshooting/common-issues.mdx` — expanded the "tool listed but agent never calls it" bullet to cross-link the new guide ## Related PRs and Issues - Closes #4950 ## Checklist - [x] I have read the Contribution Guide - [x] If the PR changes or adds functionality, I have updated the relevant documentation - [x] "Allow edits by maintainers" is checked |
||
|
|
6c955686eb |
feat(react-core): expose AG-UI raw event to feedback callbacks (#6289)
## Summary React v2 feedback callbacks receive an assistant message without the trace metadata carried by the direct AG-UI event that created it. This slice exposes that metadata to thumbs callbacks without changing canonical messages or future run inputs. ## Root cause AG-UI keeps `rawEvent` on events while reducer-created assistant messages remain protocol-clean. `StateManager` sees the direct start event but previously discarded its correlation before `CopilotChatMessageView` forwarded the message to feedback callbacks. ## Changes - Store defined direct `TEXT_MESSAGE_START.rawEvent` metadata by agent, thread, and message. - Replace repeated scoped entries and prune them with message removal and lifecycle cleanup. - Return a cloned sidecar value through `CopilotKitCore.getRawEventForMessage`. - Enrich only thumbs-up and thumbs-down callback arguments at click time across flat and virtualized rendering. - Add production-path regressions and document the callback-only type. ## Out of scope Canonical messages, future `RunAgentInput.messages`, render props, message identity, stream ordering, snapshots, transformed chunks, persistence, GraphQL, legacy React, Vue, Angular, and standardized trace semantics remain outside this slice. ## Related PRs and Issues Addresses #3039. The callback-only scope follows https://github.com/CopilotKit/CopilotKit/issues/3039#issuecomment-5086936452. Related trace-correlation contract: #4634. ## Test plan - [x] StateManager sidecar tests, 10 passed. Covers direct capture, falsey values, replacement, scope isolation, cleanup, snapshots, and chunks. - [x] React v2 feedback tests, 4 passed. Covers real callback routing, canonical and outbound cleanliness, render identity, and flat/virtual paths. - [x] Full package suites, 625 core tests, 1,475 React Core tests, and 2 script tests passed. - [x] Typecheck, formatting, lint, and whitespace validation passed; lint reported five pre-existing warnings. - [ ] CI green (`static / quality`, `test / unit` on Node 20/22/24). ## Notes The clean-base behavioral half of the reproduction remains unproved because temporary worktree setup hung behind unrelated Git processes. The PR makes no base execution claim for that half. |
||
|
|
27431412e6 |
fix(react-core): stop the compat CopilotKit wrapper pinning useSingleEndpoint (#6605)
Refs [OSS-888](https://linear.app/copilotkit/issue/OSS-888). ## The failure A correctly assembled v2 integration 404s on its first browser request while every static check passes and `GET /info` returns 200. `packages/react-core/src/v2/index.ts:28` re-exports the **v1-compat** `CopilotKit` wrapper, so it is the provider most integrations reach for. That wrapper pinned: ```tsx useSingleEndpoint={props.useSingleEndpoint ?? true} ``` which overrode the core's `"auto"` negotiation and forced single-route transport. But **every** v2 handler defaults to `mode: "multi-route"` (`endpoints/hono.ts:95`; `createCopilotEndpoint` is an alias at `:90`). Nothing serves the single-route envelope the client sends, so the runtime 404s while the provider looks connected. ## What this is *not* The library defaults do not actually disagree. `CopilotKitProvider` (the real v2 provider) leaves the flag undefined → `"auto"`, which probes `GET /info` and falls back to the single-route envelope (`core/agent-registry.ts` `fetchRuntimeInfoAutoDetect`) — it works against **either** handler mode. Only the compat wrapper defeated that. So this is one line of override, not a defaults mismatch needing a direction chosen. ## Why four onboarding runs hit it, not one The library bug alone doesn't explain a 100% failure rate. The shipped `react-core` skill does: `packages/react-core/skills/react-core/references/provider-setup.md` — bundled in the npm tarball (`files: ["dist","skills"]`) — **mandated** the compat wrapper, **forbade** `CopilotKitProvider` as "a subset of the functionality", and mentioned `useSingleEndpoint` **zero times** across ~10 code samples. An agent following it wrote the 404 configuration every time. Meanwhile `skills/copilotkit-setup/SKILL.md` got it right, so the two shipped skills contradicted each other and nothing gated either against the code. ## The change **Commit 1 — the library fix.** The prop already arrives through `v2Props`, so dropping the override lets it stay `undefined` and inherit `"auto"`. An explicit `useSingleEndpoint` still wins in both directions. **Commit 2 — the docs and skills.** Correcting the default made ~15 pages' explanations false. Code samples that pass `{false}` stay valid (they pin what negotiation would find anyway), so this corrects the *explanations* rather than the samples — keeping every page true both before and after release. Includes dropping the now-false causal claim from the single-route-envelope diagnostic added in #6579. ## Compatibility Safe for existing v1 apps. A v1 app on a single-route-only handler (`copilotRuntimeNextJSAppRouterEndpoint` and friends) now does one `GET /info` that 404s, then falls back to single-route and works. Cost is one extra request on connect. One edge case worth a reviewer's eye: if a deployment's `runtimeUrl` + `/info` returns 200 from something that is *not* a multi-route CopilotKit runtime (a catch-all proxy serving HTML, say), `"auto"` would resolve to `rest`. Setting `useSingleEndpoint` explicitly remains the escape hatch. Conventional-commit note: this lands as `fix`, but it *does* change a public default. Flag if you'd rather it carried a minor bump. ## Tests - New `copilotkit-transport-default.test.tsx` — omitted → `"auto"`, `{true}` → `"single"`, `{false}` → `"rest"`. Confirmed RED first (`expected 'single' to be 'auto'`). - `CopilotChat.readinessGate.test.tsx` depended on the old default to avoid a REST probe. Single-route transport is a **precondition of that fixture**, not the behaviour under test, so it now pins the flag explicitly and its stale comments are corrected. Its coverage (readiness gate across the real SSE boundary) is unchanged. - `react-core` 1512 passed · `runtime` 2073 passed · `core` 668 passed. - `pnpm check:plugin-skills` in sync (`skills/react-core/` is the generated mirror). `showcase/shell-docs`'s own vitest suite fails to load 35 files with `Cannot find package 'react/jsx-dev-runtime'` — reproduced identically on unmodified `origin/main`, so it is environmental in this checkout and unrelated. All 183 tests that do run pass. ## Not addressed here Nothing gates a shipped skill against the code it documents, which is why `provider-setup.md` could contradict both the library and the sibling skill indefinitely. Worth its own ticket. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
0298616223 |
docs: add Claude Managed Agents cookbook (#6430)
## Summary - add an independently runnable Claude Managed Agents finance-assistant example - add a cookbook recipe that explains the CopilotKit runtime, managed-session mapping, and tool rendering flow - add the recipe to cookbook navigation, the overview grid, sidebar icon mapping, and render coverage - use the real Claude vector mark for the cookbook instead of the text-placeholder SDK asset - register the example's Vite configuration and managed-agent model with the repository CI allowlists - include a compact architecture diagram and links to the relevant rendering and CopilotKit Intelligence documentation - disable Claude's complete built-in toolset and expose only the scoped `show_growth_projection` runtime tool - make the provisioning model configurable through `ANTHROPIC_MODEL`, defaulting to `claude-fable-5` - bound CopilotKit request bodies to 256 KB and managed-agent turns to 90 seconds, while relying on the adapter's per-thread serialization - cap public run traffic at 20 provider-like attempts per client IP per minute and 2,000 successful starts per process per 24-hour window - restrict browser runtime requests with an exact Origin allowlist that supports same-origin or separately hosted frontends, and restrict iframe parents with CSP `frame-ancestors` - validate persisted managed-agent IDs at startup so malformed local configuration fails immediately - publish the interactive example on Railway and embed the live deployment in the cookbook - align the demo with the existing cookbook chat styling and show the `Project monthly investing` starter on first load ## Demo  ## Why This gives developers a focused example of connecting CopilotKit to Anthropic Claude Managed Agents without the extra surface area of a larger analyst application. The recipe follows the existing cookbook structure and keeps the live demo compact enough for the standard cookbook pane. Its managed environment has no outbound network or package-manager access, and its agent cannot use bash, filesystem, search, or fetch tools. The request, turn, per-IP, and process-wide limits bound public demo traffic without adding authentication or user friction. The traffic counters are intentionally in memory, reset on process restart, and are not shared across replicas, so the dedicated Anthropic workspace spend limit remains the durable cost backstop. The exact-Origin browser check reduces drive-by use but is explicitly documented as a control rather than authentication. The model override allows operators to select a lower-cost supported model during provisioning without editing source code. ## Validation - scoped formatting: passed - scoped lint: 0 warnings, 0 errors - shell-docs typecheck: passed - standalone example typecheck: passed - docs render tests: 26/26 passed - standalone example tests: 23/23 passed - shell-docs tests: 375/375 passed - shell-docs production build: passed (222/222 pages) - standalone example production build: passed - standalone npm lockfile validation: passed - build-config allowlist validator: passed - docs model-name validator: passed - exact-Origin regression coverage for run requests plus headerless same-origin runtime discovery: passed - malformed persisted agent-ID regression coverage: passed - live Railway root and iframe CSP: passed - live Railway runtime discovery, exact welcome copy, and first-load starter pill: passed - live three-turn AG-UI managed-agent run with `show_growth_projection`: passed - cookbook verified in the browser at desktop and narrow widths with no console errors or horizontal overflow |
||
|
|
b8b19834a2 |
fix(runtime): unify the Intelligence key name and publish the wiring (refs OSS-881) (#6595)
## What does this PR do? Closes the naming and documentation half of [OSS-881](https://linear.app/copilotkit/issue/OSS-881). Paired with CopilotKit/Intelligence#890, which adds `copilotkit verify` and tightens the evaluation rubric. ### 1. One name for the Intelligence key **Three** names for one value were live in CopilotKit's own documentation, and following the wrong one with a CLI-provisioned project yields an undefined key: | Name | Where | Code readers | | --- | --- | --- | | `INTELLIGENCE_API_KEY` | what `copilotkit project select` writes; all 34 integration examples; the docs site | 34 | | `COPILOTKIT_INTELLIGENCE_API_KEY` | 7 Channels package READMEs + packaged skills | **0** | | `COPILOTKIT_API_KEY` | `examples/slack`, `examples/teams`, and the TSDoc on `CopilotKitIntelligence` itself | 2 | `INTELLIGENCE_API_KEY` wins — it is the name the CLI provisions, and changing it would break every scaffolded project in the wild. - `COPILOTKIT_INTELLIGENCE_API_KEY` is **retired outright**. Nothing ever read it, so there is nothing to keep compatible. - `COPILOTKIT_API_KEY` stays **readable as a deprecated alias** in the two examples that consume it, so an existing `.env` keeps working, and is documented as deprecated everywhere it appears. The third name was the worst placed: it was in the TSDoc on `CopilotKitIntelligence`, which is what an IDE shows on hover. This was not only untidy. The CLI's own `channels-preflight` accepts `INTELLIGENCE_API_KEY` or `COPILOTKIT_API_KEY` — **not** `COPILOTKIT_INTELLIGENCE_API_KEY`, the name the Channels READMEs told people to set. So following a Channels README verbatim made `copilotkit channels` warn that no runtime API key was present while the key sat visibly in `.env`. After this PR the documented name is one preflight accepts. > [!NOTE] > `NEXT_PUBLIC_COPILOTKIT_API_KEY` is a **different value** — the legacy Copilot Cloud public key — and is deliberately left alone. ### 2. A real defect, not just naming skew `skills/runtime/references/intelligence-mode.md` documented `organizationId` as a `CopilotKitIntelligence` option, sourced from two further env names (`COPILOTKIT_INTELLIGENCE_ORG_ID`, `COPILOTKIT_ORG_ID`). `CopilotKitIntelligenceConfig` has no such field — the copy-pasteable sample it appeared in **would not compile**. Removed from the samples, and the prose telling readers to fetch a value for it corrected. That file is the only place those two names ever existed, which is very likely why the failing validation run reported that "the runtime reads `COPILOTKIT_INTELLIGENCE_API_KEY` and `COPILOTKIT_INTELLIGENCE_ORG_ID`". ### 3. Publish the Intelligence wiring The wiring instructions existed only inside `node_modules/@copilotkit/runtime/skills/`, and the only docs pages mentioning `CopilotKitIntelligence` at all were the two Channels frontends — so a developer on the plain web path had no page to reach it from. Adds **`/premium/connect-your-runtime`**: the wiring itself, how to confirm the credential is actually consumed, the self-hosted both-URLs-or-neither rule, and a troubleshooting table. Linked into both navs, and the skills reference now points at the published page. ### 4. A guard so it cannot drift back `scripts/validate-intelligence-env-names.ts` (`pnpm check:intelligence-env-names`), wired to lefthook and a new workflow. The workflow is **intentionally unfiltered**. The two workflows that would otherwise cover this both filter: `plugin-skills-check` by `paths:`, and `static/quality` by `paths-ignore: examples/**` — which is exactly where the deprecated alias lives. Scoping the job would re-open the hole it exists to close. Legitimate alias sites live in `ALIAS_ALLOWLIST`. ## Related PRs and Issues - [OSS-881](https://linear.app/copilotkit/issue/OSS-881) — needs **both** PRs; neither closes it alone - CopilotKit/Intelligence#890 — items 1 and 4 (`copilotkit verify` + rubric contract 1.3.0) ## Verification - Full lefthook pre-commit ran green: `check-plugin-skills`, `lint-fix`, the new `check-intelligence-env-names`, and `test`/`publint`/`attw` across **25 projects**. - `examples/slack` `managed.test.ts` extended to cover **both** the canonical name and the alias fallback, and proven non-vacuous — removing the fallback turns the new test red. - The drift guard proven non-vacuous the same way: reintroducing a retired name fails it, exit 1. - `oxfmt` and `oxlint` clean on every file touched (0 errors). ## Checklist - [x] I have read the [Contribution Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md) - [x] If the PR changes or adds functionality, I have updated the relevant documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
f30d3bfae5 |
docs: correct the useSingleEndpoint default across docs and shipped skills
The compat `<CopilotKit>` wrapper no longer pins `useSingleEndpoint` to `true`,
so every statement that it "defaults to single-route" or that a multi-route
backend "needs `{false}`" is now wrong. Code samples that pass `{false}`
explicitly stay valid — they pin what negotiation would find anyway — so this
corrects the explanations rather than the samples, keeping the pages true both
before and after the release.
The shipped `react-core` skill is the load-bearing one. `provider-setup.md`
mandated the wrapper, forbade `CopilotKitProvider` as "a subset of the
functionality", and never mentioned `useSingleEndpoint` across ~10 samples — so
an agent following it wrote the 404 configuration every time. It now documents
the transport and stops steering readers off the negotiating provider.
Also drops the false causal claim from the runtime's single-route-envelope
diagnostic (added in #6579), which named the wrapper's old default as the cause.
`skills/react-core/` is the generated mirror of `packages/react-core/skills/`,
synced with `pnpm sync:plugin-skills`.
Refs OSS-888.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
d50e8d7e7c | Merge branch 'main' into codex/claude-managed-agents-cookbook | ||
|
|
7089b3cf53 | fix(showcase): harden managed-agent deployment setup | ||
|
|
589239686e | make tool-rendering docs layout executable | ||
|
|
1698420360 | keep tool-rendering example docs-only | ||
|
|
cfde633882 | style: auto-fix formatting | ||
|
|
43fe5fde9d | make tool-rendering docs dependency complete | ||
|
|
ed031949ca | docs(shell-docs): state the Intelligence wiring steps directly | ||
|
|
cba6bad69b |
docs(shell-docs): confirm Intelligence use without an unreleased command
The page told the reader to run `npx copilotkit verify` and said it "reports whether the runtime is wired for Intelligence at all". Neither half holds yet: `verify` is not in the published CLI — `latest` is 4.8.3 and the command landed after that tag — and the Intelligence-consumption check it referred to is still in review, so even on `main` the command does not report that. Publishing it would have documented a seam that does not exist, which is the class of defect this change set exists to remove. The dashboard check works today and needs no CLI at all, so it becomes the instruction: send a message and confirm a thread appears. A runtime in SSE mode produces none, whatever the browser showed. The `verify` route can be documented once the command ships with the check in it. |
||
|
|
9df63beeef |
fix(runtime): name useSingleEndpoint when a single-route envelope hits a multi-route runtime (#6579)
Closes [OSS-882](https://linear.app/copilotkit/issue/OSS-882/add-to-existing-journeys-reach-for-the-v1-compat-copilotkit-wrapper). ## The failure The v1-compatible `<CopilotKit>` provider pins `useSingleEndpoint` to `true` ([`copilotkit.tsx:108`](https://github.com/CopilotKit/CopilotKit/blob/main/packages/react-core/src/components/copilot-provider/copilotkit.tsx#L108)), so its startup handshake POSTs `{ method: "info" }` at the base path. A multi-route runtime — the default — matches no route for that path and answered a bare `{"error":"Not found"}`, indistinguishable from a wrong `basePath` or an unmounted handler. Two independent onboarding validation runs hit this on their first browser attempt and each had to guess the cause. Both were *add-to-existing-app* journeys; the greenfield one reached for `CopilotKitProvider` and never saw it. ## What changed **The runtime says what happened.** `detectSingleRouteEnvelope` recognises a POST whose JSON body carries a `method` the single-route endpoint accepts, and the multi-route handler uses it at the one point routing gives up. The 404 now carries a `code` and a message naming the prop, plus a `logger.warn` so it lands in the dev-server terminal too. Deliberately conservative — wrong verb, non-JSON, unknown method, or a JSON POST that isn't an envelope all stay ordinary 404s, unchanged in status and shape. **The client stops discarding it.** All four `/info` callers (two in `agent-registry.ts`, two in `agent.ts`) threw away the response body and reported only the status, so a server-side diagnosis reached nobody. They now go through `runtimeInfoError`, which folds a string `message` from the body into the thrown error. Any future server-side diagnosis reaches the developer for free. **Docs.** Five pages paired a v2 multi-route handler with `<CopilotKit>` and never mentioned the prop. Rather than a warning under a snippet that is still wrong to copy, the snippets themselves now pass `useSingleEndpoint={false}`, with a short callout linking to the provider/handler mapping. Two pages were deliberately left alone: `backend/runtime-endpoints.mdx` already documents the pairing in full, and `cookbook/arcade.mdx` uses `mode: "single-route"` on purpose and already explains it. `backend/copilot-runtime.mdx` keeps its snippet as-is — it pairs with the v1 endpoint, where the default is correct — and gains the caveat only on its "switch to v2 handlers" note. Option 3 in the issue (reconsidering the compat default) is **not** in this PR. ## Testing ### Both halves connect, end to end Real `createCopilotRuntimeHandler` + real `CopilotKitCore` configured the way the v1 wrapper configures it — no mocks on either side: ``` code : runtime_info_fetch_failed message: Runtime info request failed with status 404: Received a single-route request envelope ({ method: "..." }) but this runtime is mounted in multi-route mode, so the request matched no route. If the frontend uses <CopilotKit> from @copilotkit/react-core/v2, pass useSingleEndpoint={false} — that provider defaults it to true. Otherwise mount the runtime with mode: "single-route" to serve this envelope. PASS — the diagnostic reached the client ``` The server-side `logger.warn` fired in the same run, carrying `{ url, path, method: 'info' }`. ### Unit tests `packages/runtime` — `single-route-envelope-diagnostic.test.ts` (2 positive, 5 control): ``` ✓ src/v2/runtime/__tests__/single-route-envelope-diagnostic.test.ts (7 tests) 26ms Tests 7 passed (7) ``` `packages/core` — `runtime-info-error-detail.test.ts` (2 positive, 5 control): ``` ✓ src/__tests__/runtime-info-error-detail.test.ts (7 tests) 267ms Tests 7 passed (7) ``` ### Mutation checks Every new test was verified to fail when its mechanism is broken, in both directions. Detector forced to `return null` — the two positives die, the four controls hold: ``` × names useSingleEndpoint when the envelope is an info call × diagnoses every method the single-route envelope accepts ✓ leaves an ordinary unmatched route as a plain 404 ✓ leaves a JSON POST that is not an envelope as a plain 404 ✓ leaves an unrecognized method name as a plain 404 ✓ does not diagnose a non-JSON POST ``` Detector forced to `return "info"` — the controls die instead, proving they are not vacuous: ``` ✓ names useSingleEndpoint when the envelope is an info call ✓ diagnoses every method the single-route envelope accepts × leaves an ordinary unmatched route as a plain 404 × leaves a JSON POST that is not an envelope as a plain 404 × leaves an unrecognized method name as a plain 404 × does not diagnose a non-JSON POST ``` `runtimeInfoError` with the detail dropped, then with the `typeof message === "string"` guard removed — each kills a different pair: ``` mutation: detail dropped → 2 failed | 5 passed mutation: accept any message field → 2 failed | 5 passed restored → 7 passed ``` ### Full suites, builds, docs | Check | Result | |---|---| | `packages/core` full suite | `Test Files 60 passed (60)` / `Tests 662 passed (662)` | | `packages/runtime` full suite | `Test Files 142 passed (142)` / `Tests 2067 passed (2067)` | | `packages/core` `tsc --noEmit` | clean | | `packages/runtime` `tsdown` | `416 files` — build complete | | MDX compile, 5 edited pages | all `OK` | | pre-commit `nx run-many -t test,publint,attw` | passed across affected projects | | CI on `f94d1ab0` | 72 pass, 3 skipping, 0 fail | Both suites are fully green. An earlier revision of this description reported 6 runtime failures as pre-existing on `main`; they were not. They were artifacts of a worktree whose `node_modules` had been assembled by hand, and a proper `pnpm install` cleared all of them along with the inspector-metadata failures from a stale `@copilotkit/shared` dist. `main` is clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
f36deaaa61 |
fix(docs): keep the useSingleEndpoint guidance mode-aware on multi-mode pages
Two pages document both transport modes and carry a single "point your
frontend at it" snippet serving every front door on the page. Baking
`useSingleEndpoint={false}` into those snippets traded one silent mismatch for
its mirror image: correct for the multi-route majority, wrong for anyone who
followed the `mode: "single-route"` example.
Both now state the rule conditionally next to the snippet instead of asserting
one side of it. Pages with a single handler mode (auth, custom-agent) are
unambiguous and keep the prop inline.
Also pins the one path where the diagnostic could have cost more than it gives:
`clone()` throws once a before-request middleware has drained the body, so the
detector must return null and let the plain 404 stand rather than surfacing a
500. The guard existed; nothing held it in place.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
ba41a31d7c | feat: implement interrupt handling in AgentStore and add injectInterrupt function | ||
|
|
6f58b2c6a4 |
fix(runtime): unify the Intelligence key name and publish the wiring (refs OSS-881)
Three names for one value were live in CopilotKit's own documentation, and following the wrong one with a CLI-provisioned project yields an undefined key: - `INTELLIGENCE_API_KEY` — what `copilotkit project select` writes, used by all 34 integration examples and the docs site. - `COPILOTKIT_INTELLIGENCE_API_KEY` — the seven Channels package READMEs and the packaged skills. Nothing ever read it. - `COPILOTKIT_API_KEY` — the Slack and Teams examples, and the TSDoc on `CopilotKitIntelligence` itself, which is what an IDE shows on hover. `INTELLIGENCE_API_KEY` wins, because it is the name the CLI provisions and changing it would break every scaffolded project in the wild. `COPILOTKIT_INTELLIGENCE_API_KEY` is retired outright — no code read it. `COPILOTKIT_API_KEY` stays readable as a deprecated alias in the two examples that consume it, so an existing `.env` keeps working, and is documented as deprecated everywhere it appears. The skills reference also documented `organizationId`, sourced from a fourth and fifth env name, as a `CopilotKitIntelligence` option. It is not one: `CopilotKitIntelligenceConfig` has no such field, so the copy-pasteable sample it appeared in would not compile. Removed from the samples, and the prose that told readers to fetch a value for it corrected. The Intelligence wiring itself was published only inside `node_modules/@copilotkit/runtime/skills/`, and the only docs pages showing `CopilotKitIntelligence` were the two Channels frontends — so a developer on the plain web path had no page to reach it from. Adds `/premium/connect-your-runtime`, which covers the wiring, how to confirm the credential is actually consumed, and the self-hosted two-URL rule. `scripts/validate-intelligence-env-names.ts` keeps this from drifting back. It runs unfiltered in CI on purpose: the two workflows that would otherwise cover it filter paths, and static/quality ignores `examples/**` — exactly where the deprecated alias lives. |
||
|
|
f94d1ab0fb |
fix(runtime): name useSingleEndpoint when a single-route envelope hits a multi-route runtime
The v1-compatible `<CopilotKit>` provider pins `useSingleEndpoint` to `true`,
so it POSTs `{ method: "info" }` at the base path. A multi-route runtime — the
default — matches no route for that path and answered a bare `{"error":"Not
found"}`, which is indistinguishable from a wrong `basePath` or an unmounted
handler. Two independent onboarding validation runs hit this on their first
attempt and had to guess the cause.
The runtime now recognises the envelope at the one point multi-route routing
gives up, and answers the 404 with a message naming the prop, plus a
`logger.warn` so it also lands in the dev server terminal. Status and shape are
unchanged for every other miss.
That message was reaching nobody: all four `/info` callers threw away the
response body and reported only the status. They now route through
`runtimeInfoError`, which folds a string `message` from the body into the
error — so any future server-side diagnosis reaches the developer too.
Docs: five pages paired a v2 multi-route handler with `<CopilotKit>` without
mentioning the prop. Their snippets now pass `useSingleEndpoint={false}` and
link to the provider/handler mapping. `backend/runtime-endpoints.mdx` already
documents the pairing and is untouched; `cookbook/arcade.mdx` deliberately uses
single-route mode and already explains it.
Closes OSS-882
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
1ef16b6789 |
feat(web-inspector): pop the Inspector into its own window
Keep the same live Inspector session in a named browser popup, restore it when the popup closes, and document the workflow. |
||
|
|
092058b224 |
docs(a2ui): require a literal-or-binding union for bound props (refs OSS-857) (#6573)
Four defects were reported from a LangGraph TypeScript + Next.js
onboarding run. Two
were unverified and one was unsound as stated, so each was reproduced or
traced to
source before anything was written. Two needed a fix, one needed a fix
plus a package
re-export, and one turned out to be correct as documented.
## Per-defect findings
**Defect 1 — bound props need a literal-or-binding union schema. REAL,
and the page said the opposite.**
Confirmed, with the mechanism. `scrapeSchemaBehavior` in
`@a2ui/web_core`'s
`GenericBinder` decides whether to resolve a `{ path }` binding by
inspecting the prop's
Zod type: a `ZodUnion` containing an object with a `path` key (and no
`componentId`)
becomes `DYNAMIC`; everything else falls through to `STATIC`, whose
handler is
`case 'STATIC': return value;`. So a bound prop declared as a plain
`z.string()` is never
resolved and the raw `{ path: "/origin" }` object reaches the renderer,
where the first
thing that renders it as text throws React error #31.
The page was not merely silent about this — it asserted the opposite:
> The A2UI binder resolves those paths *before* the React renderer runs,
so renderer
> props are typed as their resolved values (plain `z.string()`, not a
path-or-literal union).
The reference cell has declared the union all along and carries a
comment naming the exact
React error, but that comment sits *outside* the
`@region[definitions-types]` marker, and
`extractRegion` returns only the lines between the markers — so it never
reaches the page.
The rule is now stated where the reader declares the prop, with the
failure mode.
**Defect 2 — `DynamicStringSchema` is not re-exported. Explanation 2:
the symbol exists in a package that had not been searched.**
It is real and it is not a wished-for helper. It lives in
`@a2ui/web_core` at
`src/v0_9/schema/common-types`, reachable on the export map as
`@a2ui/web_core/v0_9`, and
it is a three-member union (`z.string()`, `DataBindingSchema`,
`FunctionCallSchema`) —
slightly wider than the two-member `DynString` the reference cells
hand-roll. The earlier
search was correct that it appears nowhere under `packages/`; it is a
dependency symbol.
It is also genuinely unreachable for users: `@a2ui/web_core` is a plain
`dependency` of
`@copilotkit/a2ui-renderer`, so application code cannot rely on
importing it. Re-exported
from `@copilotkit/a2ui-renderer` with its numeric/boolean/list siblings
and their types,
and noted in the docs as an alternative to hand-rolling the union.
**Defect 3 — the quickstart recommended the host form that fails. REAL,
verified independently for both runtimes.**
The advice was *"try using `0.0.0.0` or `127.0.0.1` instead of
`localhost`"*, in shared prose.
For the Node runtime that is exactly backwards, and it was verified from
source and by
running it, not taken on report. Rewritten and split across the page's
existing
Python/TypeScript language tabs so neither runtime sees the other's
advice. Also corrected
the `0.0.0.0` half, which is wrong for both: it is a bind-all address
for a server, not a
target for a client URL.
**Defect 4 — `useSingleEndpoint` guidance for the compat component. NOT
A DEFECT. Nothing changed.**
The docs are right. The compat wrapper resolves its default at
`packages/react-core/src/components/copilot-provider/copilotkit.tsx:108`:
```tsx
useSingleEndpoint={props.useSingleEndpoint ?? true}
```
and the v2 provider maps `true → "single"`, `false → "rest"`, `undefined
→ "auto"`
(`CopilotKitProvider.tsx:616-620`, again at `777-781`). So omitting the
prop really does
keep a single-route default, and `useSingleEndpoint={false}` really is
what a multi-route
Runtime needs. The same `CopilotKit` component is exported from both
`@copilotkit/react-core`
and `@copilotkit/react-core/v2`, so the guidance holds for either
import. Reported as one
observation from one run rather than an established finding — it did not
survive checking.
## Two things worth flagging
**The URL is served by the root page, not the LangGraph one.** Both
`generative-ui/a2ui/fixed-schema.mdx` and
`integrations/langgraph/generative-ui/a2ui/fixed-schema.mdx` exist, and
the resolution is the
opposite of what the directory layout suggests: all three langgraph
slugs are
`docs_mode: generated` in their manifests, and in that branch root MDX
wins
(`[framework]/[[...slug]]/page.tsx:836-841`). Confirmed live — the
LangGraph-scoped copy is a
thinner, older duplicate that is **not served at that URL for any
framework**. Left in place,
but it is a trap for the next person and probably wants deleting
separately.
**Overlap with #6569.** That PR is still open and edits both files this
one touches.
`git merge-tree` against its head merges clean, so no action needed, but
the two should be
read together.
## Testing
Worktree off `origin/main` (which already contains #6566 and #6568).
**Defect 1 — mechanism, against the locked `@a2ui/web_core@0.10.4`.**
Schema classification:
```
plain z.string() -> {"type":"STATIC"}
literal|binding -> {"type":"DYNAMIC"}
```
End-to-end through the real `GenericBinder`, feeding `{ path: "/origin"
}` against a data
model of `{ origin: "SFO" }`:
```
z.string() : typeof=object value={"path":"/origin"}
literal|binding : typeof=string value="SFO"
z.string() -> renderable as a React child? NO — React throws: Objects are not valid as a
React child (found: object with keys {path})
literal|binding -> renderable as a React child? yes
```
**Defect 2 — the re-export works from the built entry point**, and
behaves identically to the
hand-rolled union in the binder (it has a third union member, so this
needed checking):
```
DynamicStringSchema parses a literal: "SFO"
DynamicStringSchema parses a binding: {"path":"/origin"}
hand-rolled union -> {"type":"DYNAMIC"}
DynamicStringSchema -> {"type":"DYNAMIC"}
plain z.string() -> {"type":"STATIC"}
```
**Defect 3 — both runtimes verified from CLI source, and the Node
binding reproduced.**
`@langchain/langgraph-cli@1.4.4` `dist/cli/dev.mjs:19` defaults `--host`
to `"localhost"`
and passes it to `serve({ hostname })`; `langgraph_cli-0.4.31`
`cli.py:664-666` defaults
`--host` to `"127.0.0.1"`. Reproducing what Node does with `{ host:
"localhost" }` on this
dual-stack machine:
```
node version: v22.14.0
bound to: {"address":"::1","family":"IPv6","port":42024}
localhost -> CONNECTED
127.0.0.1 -> ECONNREFUSED
::1 -> CONNECTED
0.0.0.0 -> ECONNREFUSED
```
`127.0.0.1` is refused by the very server `localhost` reaches — so the
old advice broke a
working setup.
**Rendered checks (`next dev`, body-inspected — this site soft-404s, so
no status codes were trusted).**
`/langgraph-typescript/...` and
`/langgraph-python/generative-ui/a2ui/fixed-schema`: root-file
marker present, LangGraph-file marker absent, new prose and the
React-error callout present,
old wrong sentence gone. The `{path}` braces render literally inside
`<code>` and the
`#declare-the-component-definitions` anchor resolves to a real heading
id.
Quickstart troubleshooting tabs resolve per framework, so the gating is
right:
```
/langgraph-typescript/quickstart Python selected=false TypeScript selected=true
/langgraph-python/quickstart Python selected=true TypeScript selected=false
/langgraph-fastapi/quickstart Python selected=true TypeScript selected=false
```
The `<Tabs>` nested in a list item renders as a real `<ul><li>` with a
working tablist, not
broken MDX.
**Suites.**
| Check | Result |
| --- | --- |
| `packages/a2ui-renderer` `tsc --noEmit` | pass |
| `packages/a2ui-renderer` build (`tsdown`) | pass, 143 files |
| `packages/a2ui-renderer` `vitest run` | 4 files, 22 tests passed |
| `oxlint` on the changed source | 0 warnings, 0 errors |
| `shell-docs` `npm run typecheck` | pass (exit 0) |
| `shell-docs` `npm run lint` | pass (exit 0) |
| `shell-docs` `npm run test` | 58/59 files, 420/421 tests |
The one failing test is `channels-docs.test.ts > publishes the Channels
overview only through
provider navigation`. It is **pre-existing on `origin/main`** and
unrelated to these files —
verified by reverting all three changes to a pristine checkout and
re-running it, where it
fails identically (`1 failed | 29 passed`).
## Conventions pass
Checked the added prose against the docs tree's actual conventions
rather than by ear, which
turned up four things worth changing:
- **`Callout type="warn"`** is the house spelling (84 uses vs 11
`warning`) — already correct.
- **Code identifiers in Callout titles are backticked** (95-odd
precedents, e.g.
``title="`identifyUser` is not an authentication gate"``). Mine wasn't;
fixed. Note these
render as *literal* backticks — verified that existing titles behave
identically on `/auth`,
so this matches the site rather than diverging from it.
- **Dropped a hand-written code fence.** The first draft illustrated the
union with a synthetic
`ts` block that (a) wasn't valid TypeScript — an orphaned object
property with no enclosing
object — and (b) duplicated the `<Snippet region="definitions-types" />`
rendered immediately
below it. Hand-copied code next to the generated snippet is exactly the
drift the snippet
architecture exists to prevent, so the prose now names `DynString` and
`Airport`'s `code` and
lets the snippet carry the code. Confirmed those two names are present
in **all 21**
integration cells that feed this page, since the root page serves every
framework.
- **Matched local line-style.** The quickstart's other troubleshooting
bullets are single
unwrapped lines, so the new bullet's prose is too; the a2ui page wraps
at ~70–80 columns and
the new paragraphs match that.
Also tightened two things for accuracy over emphasis: the binder rule
now says "a union with a
`{ path }` member" rather than "a union containing an object with a
`path` key", which was
over-broad (a `{ componentId, path }` member is classified `STRUCTURAL`,
not `DYNAMIC`), and
the package comment was cut from nine lines to six to sit better among
that file's one-line
section labels.
Re-verified after the rewrite: `tsc` pass, `vitest` 22 passed, `oxlint`
clean, `oxfmt` clean,
shell-docs typecheck/lint pass, tests unchanged at 420/421 with the same
pre-existing channels
failure, and both pages re-rendered — anchor still resolves, tabs still
resolve per framework
(`langgraph-python` → Python, `langgraph-typescript` → TypeScript).
Out of scope and untouched: `snippets/shared/premium/inspector.mdx`. No
changeset added.
Does not close OSS-857.
|
||
|
|
4df1e3dccd |
docs(a2ui): require a literal-or-binding union for bound props (refs OSS-857)
Three findings from a LangGraph TypeScript onboarding run, plus the
supporting re-export.
The A2UI binder decides whether to resolve a `{ path }` binding by
inspecting the prop's Zod type: `scrapeSchemaBehavior` classifies a
`ZodUnion` containing an object with a `path` key as DYNAMIC and
everything else as STATIC, and STATIC returns the value untouched. A
bound prop declared as a plain `z.string()` therefore reaches the
renderer as the raw `{ path: "/origin" }` object, and the first thing
that renders it as text throws React error #31. The fixed-schema page
said the opposite — that renderer props are "plain z.string(), not a
path-or-literal union" — so the obvious declaration produced an opaque
crash. The reference cell already declares the union and carries a
comment explaining why, but that comment sits outside the
`definitions-types` region marker and so never reaches the page.
`DynamicStringSchema` is real; it lives in `@a2ui/web_core`, which is a
transitive dependency of `@copilotkit/a2ui-renderer` and so not
reliably importable from application code. Re-exported here with its
numeric/boolean/list siblings and their types.
The LangGraph quickstart's troubleshooting advice told everyone with a
connection problem to swap `localhost` for `0.0.0.0` or `127.0.0.1`.
That is backwards for the Node runtime: `langgraphjs dev` defaults to
`--host localhost`, which Node resolves to IPv6 and binds `::1` only,
so `127.0.0.1` is refused by the same running server. The Python CLI
defaults to `--host 127.0.0.1` and behaves the other way, so the advice
is now split across the page's existing Python/TypeScript language tabs
instead of stated once in shared prose.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
68d6c5c62d |
docs(inspector): document mounting the Inspector in Angular (refs OSS-857) (#6572)
## What this fixes
The Inspector is `cpk-web-inspector`, a framework-agnostic web component
from
`@copilotkit/web-inspector`. `@copilotkit/angular` does not reference
that package
and does not mount the element, so an Angular application has to create
it
itself. Nothing in the docs said so.
It was worse than a missing paragraph. `ANGULAR_DOC_REDIRECTS` mapped
the
`inspector` slug onto `guides/troubleshooting`, so
`/angular/*/inspector`
**redirected away from the Inspector**, and the Angular sidebar's
"Observe & Operate" section contained a single entry — the VS Code
extension:
```
== Observe & Operate
- VS Code Extension [vs-code-extension]
```
## What I documented
New Angular-owned page, `frontends/angular/inspector.mdx`, sourced from
`examples/integrations/adk-angular/src/app/web-inspector.ts`:
- the Inspector is a web component and `@copilotkit/angular` does not
mount it
- the mount component: `afterNextRender`, reuse-or-create, append to
`document.body`
- `inspector.core = copilotKit.core` plus `auto-attach-core="false"`,
and why —
given no core the element hunts for development globals such as
`window.__COPILOTKIT_CORE__`, so turning the search off is what
guarantees it
observes the app's core and never a different one
- anchoring the launcher bottom-left, clear of a chat panel's close
button
- keeping it out of production builds via `@defer (when isDev)` +
`isDevMode()`
- server rendering (`afterNextRender` + the deferred import vs.
`customElements`)
- cleanup through `DestroyRef.onDestroy`
Plus: the redirect is gone so the page is reachable, and
`frontends/angular/guides/troubleshooting.mdx` links to it.
**React's Inspector content is untouched** — not edited, not moved, not
gated.
### House style
Checked against the eleven existing Angular-owned pages rather than
written to
taste, which changed four things from my first draft:
- **`## Next steps` with a bare link list.** Every Angular guide closes
that way;
I had `## Related` with a prose gloss per link.
- **No `<video>`.** No Angular-owned page embeds media, and none uses
`<Callout>`
or `<Steps>` either — that surface is prose, tables, and fences. I had
carried
the Inspector video over from the shared snippet.
- **Imperative task headings**, matching "Send the current session" /
"Validate every runtime request" in `auth.mdx`: "Mount the element",
"Supply the application's core", "Position the launcher". I had
"Mount it yourself" and "Hand it the application's core".
- **Declarative sentences, no rhetorical fragments.** "The mount is
yours, so the
exclusion is yours as well." and a bare "`DestroyRef.onDestroy` does."
are not
this surface's register; both are now plain statements of mechanism.
Frontmatter (`title`/`description`/`icon`/`doc_type: how-to`), h2-only
structure, ~80-column wrapping, and the `{runtimeUrl}` placeholder
convention all
follow the siblings. `<AngularSnippet region=…>` does **not** apply —
that
component pulls code extracted from the Angular Showcase at build time,
and this
mount component is not in the Showcase. Nav needs no `meta.json` entry
either:
`frontends/meta.json` carries only a title, and the Angular sidebar is
derived in
`getAngularDocsNavTree`. Verified the entry renders anyway.
### Two deviations from the brief, both deliberate
**1. Structural gating instead of `<FrontendOnly frontend="angular">` in
the
shared snippet.** The brief described
`snippets/shared/premium/inspector.mdx` as
the real Inspector content with the per-framework pages as shims onto
it. On
current `main` that is only half true: `docs/inspector.mdx` is now a
131-line
standalone page that does **not** render `<Inspector />`, and it is what
the
Angular root and every `docs_mode: generated` framework resolve to. I
built the
`FrontendOnly` version first and it forced the Angular guide to be
duplicated
into two files that had already diverged. An Angular-owned page instead
matches
how all eleven existing Angular guides work, keeps one source of truth,
and
gates by resolution rather than by branch.
The repo's own test agrees on the direction —
`angular-docs-content.test.ts`
lists `<FrontendOnly` in `REACT_ONLY_CONTENT`, i.e. it treats the tag as
something that should not reach the Angular surface.
That test also gave me a real mutation check for free. My first attempt
leaked
React's `<CopilotKit … enableInspector={false}>` into 19 Angular pages,
and the
suite caught every one:
```
× keeps the complete Angular surface free of another frontend's code
+ "inspector: <CopilotKit
+ publicLicenseKey={process.env.NEXT_PUBLIC_COPILOTKIT_LICENSE_KEY}
+ enableInspector={false}
+ >",
× keeps every Angular and backend combination frontend-native
expected [ …(18) ] to deeply equal []
```
**2. I document the CSS override for positioning, not
`setAttribute("anchor", …)`.**
The scaffold sets that attribute, but `cpk-web-inspector` never reads
it. Runtime
proof against the built `dist`:
```
observedAttributes: ["auto-attach-core"]
static properties keys: ["core","autoAttachCore","_capabilitiesVersion"]
'anchor' observed? -> false
```
There is no `getAttribute("anchor")` anywhere in the package, and
`defaultAnchor`
(the prop React's `CopilotKitInspector` accepts) is not consumed either.
What
actually moves the panel is the CSS in the scaffold's own `styles.css` —
as its
comment already says: "CSS in styles.css enforces this too." So the docs
describe
the mechanism that works. **The scaffold has one dead line** its owner
may want
to drop; I did not touch it (see below).
## The adk-angular dependency is discharged
`examples/integrations/adk-angular` is planned for removal, and its
`web-inspector.ts` comment was the only written record of this pattern.
That
pattern is now documented. **Whoever removes that scaffold no longer
needs to
preserve it.** I only read the scaffold — no file under
`examples/integrations/adk-angular` is modified by this PR.
## The VS Code extension claim: both halves reproduced
The report said Angular users are pointed at a VS Code extension
instead, that
its `cpk-debug-events` endpoint is documented at the wrong path, and
that it
produced no events for a real run. I verified each independently rather
than
acting on the report.
**Pointed at the extension — confirmed.** See the one-entry sidebar
above.
**Wrong path — confirmed, and fixed.** The router suffix-matches
`cpk-debug-events`, but a runtime mounted with a `basePath` rejects
anything
outside it. Against a real runtime on `basePath: "/api/copilotkit"`:
```
runtime mounted at basePath=/api/copilotkit, NODE_ENV=development
/cpk-debug-events -> 404 application/json {"error":"Not found"}
/api/copilotkit/cpk-debug-events -> 200 text/event-stream ": connected\n\n"
/api/copilotkit/info -> 200 application/json {"version":"1.64.1",…}
```
The docs said "available at `GET /cpk-debug-events` on your CopilotKit
runtime"
and gave the panel default as the bare origin `http://localhost:4000`,
so a
reader supplying their server's origin gets a 404. Now documented as
`GET {runtimeUrl}/cpk-debug-events`, base-path-relative, with the worked
`localhost:8200` example and a `curl` check, in both
`troubleshooting/event-inspector.mdx` and `vs-code-extension.mdx`.
**No events for a real run — confirmed, cause is runtime mode.** The
debug bus is
fed from exactly one place, `handlers/shared/sse-response.ts`, reached
only by
`handlers/sse/run.ts` and `handlers/sse/connect.ts`. An
Intelligence-configured
runtime dispatches to `handlers/intelligence/run.ts` and
`handlers/intelligence/connect.ts`, which return `Response.json` and
hand the
browser a realtime connection — no AG-UI event ever passes through the
runtime's
SSE layer. Neither file mentions `debugEventBus`. So on an
Intelligence-backed
runtime the endpoint connects, emits `: connected`, and then stays
silent
forever. That is now a callout on the event-inspector page pointing
readers at
the in-app Inspector, which reads the events client-side.
I did not change runtime code for this — it is a docs-accuracy gap, and
whether
the Intelligence path *should* feed the bus is a product decision, not
mine to
make here.
## Testing
From `showcase/shell-docs`:
**`npm run test`** — 403 passed, 1 failed, and that failure is
pre-existing on
`origin/main`. Verified in a pristine `origin/main` worktree with no
changes:
```
❯ src/lib/__tests__/channels-docs.test.ts (30 tests | 1 failed)
× publishes the Channels overview only through provider navigation
```
It asserts `channels-architecture-dark.png` in the Channels overview
source and
is unrelated to anything here. The seven `angular-docs-content.test.ts`
tests —
the ones that police frontend separation — all pass.
**`npm run typecheck`** — identical output on my branch and on a
pristine
`origin/main` worktree (5 pre-existing `@testing-library/react`
resolution
errors from my symlinked `node_modules`, all in test files I did not
touch). No
new errors.
**`npm run lint`** — exit 0, no warnings in any file I changed.
**`npx oxfmt --check`** on the one `.ts` file — "All matched files use
the
correct format."
### Render check, both namespaces
`next dev`, following redirects, checking bodies rather than status
codes since
this site soft-404s:
| URL | http | Angular mount content | React `enableInspector` |
| --- | --- | --- | --- |
| `/angular/langgraph-typescript/inspector` | 200 | yes
(`afterNextRender`, `auto-attach-core`, `cpk-web-inspector`) | **no** |
| `/langgraph-python/inspector` | 200 | **no** | yes |
Each namespace shows only its own instructions. The only `tsx` string on
the
Angular page is Next.js dev chunk filenames, not content.
Before this change `/angular/langgraph-typescript/inspector` answered
`307 -> /angular/langgraph-typescript/guides/troubleshooting`.
Also confirmed 200-with-content, no redirect, and the mount instructions
present
on `/angular/inspector`, `/angular/google-adk/inspector`, and
`/angular/mastra/inspector`; the sidebar now carries
`href="/angular/langgraph-typescript/inspector"` under "Observe &
Operate"; the
Angular troubleshooting page links to it; and the new event-inspector
callouts
render in both the React and Angular namespaces with `/inspector`
correctly
rewritten to `/angular/<backend>/inspector`.
## Notes for reviewers
- **OSS-857 stays open** — other defects on it are unresolved.
- No changeset, per this repo's release process.
- Follow-up for the adk-angular owner, not done here:
`setAttribute("anchor", "bottom-left")` in `web-inspector.ts` is a no-op
and
can be deleted; the `styles.css` rule below it is what positions the
panel.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||
|
|
3801de3708 |
docs(runtime): map the provider/handler pairs and guard BuiltInAgent (refs OSS-857) (#6569)
Follow-up to #6566. Fixes **defects 5 and 9** of OSS-857, plus the half of **defect 6** that lives on the Built-in Agent quickstart. Defects **1 and 2** are deliberately left — they land with the non-interactive `project list`/`select` work, since the real fix is tooling that provisions and names the key, not prose. **Do not close OSS-857 on this PR** — 1 and 2 remain. ## The finding that reframes defect 5 The three names are **not interchangeable**. They pair up, and nobody had written the pairing down. Traced through source, not inferred: | Provider | `useSingleEndpoint` | Transport | Needs handler | | --- | --- | --- | --- | | `<CopilotKit>` (v1 wrapper) | omitted → `true` | `single` | single-route | | `<CopilotKit>` | `{false}` | `rest` | multi-route | | `<CopilotKitProvider>` (v2) | omitted | `auto`, detected from `/info` | either | | `<CopilotKitProvider>` | `{true}` | `single` | single-route | `copilotkit.tsx:108` is the whole story: `useSingleEndpoint={props.useSingleEndpoint ?? true}`. The v1 wrapper renders `<CopilotKitProvider>` internally and **pins single-route transport unless you pass the prop.** So the LangGraph quickstart is internally coherent — v1 provider asks for single, `copilotRuntimeNextJSAppRouterEndpoint` serves single — which is exactly why chat works there and Threads cannot. ### The constraint nobody had documented I swept every v1-era wrapper: - `copilotRuntimeNextJSAppRouterEndpoint` → `createCopilotEndpointSingleRoute` - `copilotRuntimeNodeHttpEndpoint` → `createCopilotEndpointSingleRoute` - `copilotRuntimeNextJSPagesRouterEndpoint`, `copilotRuntimeNodeExpressEndpoint`, `copilotRuntimeNestEndpoint` → all delegate to `copilotRuntimeNodeHttpEndpoint` **Every one builds its handler with `mode: "single-route"` and exposes no option to change it.** There is no v1-shaped multi-route handler anywhere in the package. The consequence is sharper than defect 5 as filed: **Rich Threads and the Inspector are unreachable from the wiring both quickstarts teach, at any provider setting.** Setting `useSingleEndpoint={false}` cannot fix it — it just points the browser at routes the wrapper will not serve. You need a v2 `CopilotRuntime` from `@copilotkit/runtime/v2` plus `createCopilotRuntimeHandler`. That is a server-side change, not a provider prop, and it is the structural reason defect 3's trap exists. Worth its own ticket. ## Why I did not converge the quickstarts on v2 That was the original plan for this PR and I abandoned it after checking the backend half. The split matters: - **Frontend would have been free.** Both quickstarts already import from `@copilotkit/react-core/v2`, where `CopilotKit` is labelled in source as a *"V1 backward-compat re-export"*. `CopilotKitProvider` ships from that same entry, and `CopilotSidebar` already depends on `useLicenseContext` from it. Swapping is an import change. - **Backend would not.** The multi-route handler takes a v2 `CopilotRuntimeLike`; the quickstart's v1 `CopilotRuntime` only reaches it via an internal `.instance` getter that lazily news up a `CopilotRuntimeVNext`. Converging means teaching v2 runtime construction and dropping `ExperimentalEmptyAdapter` mid-quickstart — a real v1→v2 migration for every reader of the two highest-traffic pages. v1 is supported, so the default path stays put. The mapping documents all pairs instead, and the Threads upgrade stays a labelled, complete recipe on the page the quickstarts already link to. ## What changed **`backend/runtime-endpoints.mdx`** — new "Provider and handler pairs" section: the provider table, the handlers-by-mode table, the deprecated-alias mapping (`createCopilotEndpoint`, `createCopilotEndpointSingleRoute`, and the Express pair), the wrapper constraint above, and a "read the symptom" callout (a mismatch fails at discovery — `GET {basePath}/info` 404s, or the Runtime rejects the envelope — never in your application code). **Both quickstarts** — a short callout naming the pair the page uses and linking the mapping. **Defect 9, `integrations/built-in-agent/quickstart.mdx`** — this is what `/quickstart` actually serves (verified: both URLs return the identical 8175-byte body; the root `quickstart.mdx` is a 17-line routing shim that 308-redirects to `/`). `BuiltInAgent` extends `AbstractAgent` and calls the model directly via `streamText`, so registering it as `default` replaces the developer's agent rather than connecting to it. Added a caution: readers with an existing agent take the frontend steps here and the runtime wiring from their framework's quickstart. **Defect 6, second half** — same page installed `@copilotkit/react-ui` and never used it, importing `CopilotKit`/`CopilotSidebar` from `@copilotkit/react-core/v2`. Dropped, matching #6566. ## Testing ``` $ npx vitest run Test Files 1 failed | 58 passed (59) Tests 1 failed | 417 passed (418) ``` The one failure is `channels-docs.test.ts > publishes the Channels overview only through provider navigation` — pre-existing, and proven so in #6566 by stashing on a clean tree. **I broke two tests and fixed them, which is worth recording** because it caught a real defect in my first draft. `angular-docs-content.test.ts` flagged: ``` built-in-agent/backend/runtime-endpoints: @copilotkit/react langgraph-python/backend/runtime-endpoints: @copilotkit/react ... 10 surfaces total ``` `backend/runtime-endpoints.mdx` also serves the **Angular** surface, and my provider prose named React packages there. Correct fix, not a suppression: the provider axis is React-only — Angular's `provideCopilotKit` has no `useSingleEndpoint` — so the provider table is now `<FrontendOnly frontend="react">` with an Angular branch saying only the handler half applies. Both Angular tests pass. ### Render checks Per surface, `.md` and HTML: | surface | provider table | Angular note | `@copilotkit/react` | wrapper callout | |---|---|---|---|---| | langgraph-python | ✅ | — | 3 | ✅ | | langgraph-typescript | ✅ | — | 3 | ✅ | | angular | — | ✅ | **0** | ✅ | The wrapper-constraint callout correctly stays on all three: it is a server-side fact that applies to Angular too. Defect 9 / 6b on `/quickstart` and `/built-in-agent/quickstart` — both 8175 bytes, caution present, `react-ui` gone from the install line, pair pointer present. Every link I added was **body-verified, never by status code** (this site soft-404s with HTTP 200): ``` /langgraph-python/quickstart bytes=428497 soft404=0 h1=Quickstart / bytes=248255 soft404=0 h1=CopilotKit /backend/runtime-endpoints bytes=375782 soft404=0 h1=Runtime HTTP endpoints /langgraph-python/backend/runtime-endpoints bytes=395130 soft404=0 h1=Runtime HTTP endpoints ``` New anchors confirmed present (`id="provider-and-handler-pairs"`, `id="which-handlers-serve-which-mode"`), and the pointer rewrites into the reader's namespace correctly — `/langgraph-python/backend/...` from the LangGraph page, `/backend/...` from the root surface. ## Voice pass A third commit runs a tone/voice check over everything added for OSS-857, measured against the corpus instead of guessed. It also corrects the wording that already landed in #6566, so the whole ticket reads in one voice. **Second person stays.** It is emphatically the house voice: 22 of 29 top-level and backend pages use `you`/`your`, and the three pages involved used it **17, 23 and 64 times** before any of these edits. Stripping it would make the new prose stand out, not blend in. Mid-sentence `**bold**` also stays — the corpus does that 17 times. What genuinely drifted, and is now fixed: | Issue | Was | Now | |---|---|---| | British spelling | `honours` | `serves` | | Third person on a second-person page | `A developer adding A2UI to an agent they already wrote…` | `If you added A2UI to an agent you already wrote…` | | Essay register | `That default is the one thing to remember:` | plain statement of the fact | | Meta phrasing | `so this is the mapping` | `so this table is the mapping` | | Conversational | `no provider pairing to get wrong` | `to configure` | | Conversational | `` `uvicorn` is told to listen on `8123` `` | `` `main.py` sets uvicorn's port to `8123` `` | | Literary | `you may also meet these deprecated aliases` | `Older code may use these deprecated aliases` | | Coinage | `agent construct` | `how the agent itself is built` | | Coinage | `without that steer` | `Without it, the model tends to…` | | Aphoristic Callout title | `Mismatched pair? Read the symptom, not the code` | `A mismatched pair fails at discovery` | | Epigram | `It replaces your agent; it does not connect to one.` | `It replaces your agent rather than connecting to it.` | | Redundancy | `nothing supplies persistence for you` | `nothing supplies persistence` | Two of these were objective, not stylistic: the corpus is American English (`behavior` 66:6, `customize` 77:4, `serialize` 18:1, `organize` 15:0) and its only `honour` was mine; and it contains exactly two instances of `a developer`, one of which was mine on a page that addresses the reader directly throughout. Callout titles were checked against the house set — declarative or plain question (`v1 behaves differently`, `Three routes are not user-scoped`, `Using a custom backend?`) — which is why the aphorism was the one outlier. Re-verified after the rewording: tests back to the single pre-existing failure, every reworded string renders on the right surface, Angular still shows **zero** React package mentions, and the `StateGraph` step is still gated to langgraph-python + langgraph-fastapi only. ## Coordination Draft PR #6112 (onsclom) also touches `integrations/built-in-agent/quickstart.mdx`, but only two prose lines — the signup sentence and the "Already have an app?" callout. My hunks are the install line and the runtime step, so they should merge cleanly. Flagging rather than assuming. ## Follow-ups this surfaced - **Threads needs a v2 server migration** from either quickstart's starting point. No v1-shaped multi-route handler exists. Own ticket. - **Defects 1 and 2** ride the non-interactive project-selection work. |
||
|
|
9ffe2546ce |
docs(inspector): document mounting the Inspector in Angular
The Inspector is the framework-agnostic `cpk-web-inspector` web component. `@copilotkit/angular` does not reference or mount it, so an Angular app has to create the element itself — and nothing said so. Worse, the Angular docs mapped the `inspector` slug onto `guides/troubleshooting`, so `/angular/*/inspector` redirected away from the Inspector entirely and the only thing left under "Observe & Operate" was the VS Code extension. Add an Angular-owned Inspector page covering the mount component, the `core` handoff with `auto-attach-core="false"`, positioning, production exclusion, server rendering, and cleanup on destroy. Drop the redirect so the page is reachable, and point at it from the Angular troubleshooting guide. React's Inspector content is untouched and unmoved. Also correct the `/cpk-debug-events` path: it is relative to the runtime's mounted `basePath`, not the server origin, and it only carries events for a self-hosted SSE runtime — an Intelligence-backed runtime answers runs over the platform's realtime connection, so the stream connects and stays empty. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
6c1a9eb4b4 |
docs: match the house voice in the OSS-857 prose (refs OSS-857)
A voice pass over everything added for OSS-857, measured against the
corpus rather than guessed.
Second person stays: it is emphatically the house voice — 22 of 29
top-level and backend pages use you/your, and the three pages involved
used it 17, 23 and 64 times before any of these edits. Mid-sentence
`**bold**` for emphasis also stays; the corpus does that 17 times.
What actually drifted:
- `honours` → `serves`. The corpus is American English (behavior 66:6,
customize 77:4, serialize 18:1, organize 15:0) and the single
`honour` in it was mine.
- `A developer adding A2UI to an agent they already wrote…` → second
person. The corpus contains exactly two `a developer`, and one was
mine; the page around it addresses the reader directly throughout.
- Essay register: "That default is the one thing to remember:" → a plain
statement of the fact. "so this is the mapping" → "so this table is
the mapping".
- Conversational: "no provider pairing to get wrong" → "to configure";
"`uvicorn` is told to listen on 8123" → "`main.py` sets uvicorn's port
to 8123"; "you may also meet these deprecated aliases" → "older code
may use these deprecated aliases".
- Coinages: "agent construct" → "how the agent itself is built"; "that
steer" → "Without it, the model tends to…".
- Aphoristic Callout title "Mismatched pair? Read the symptom, not the
code" → "A mismatched pair fails at discovery". House titles are
declarative or plain questions ("v1 behaves differently", "Three
routes are not user-scoped", "Using a custom backend?").
- Epigram: "It replaces your agent; it does not connect to one." → "It
replaces your agent rather than connecting to it."
- Redundancy: "nothing supplies persistence for you" → "nothing
supplies persistence".
The a2ui and LangGraph quickstart wording landed in #6566; those files
are corrected here so the whole ticket reads in one voice.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
4078a11f36 |
docs(runtime): map the provider/handler pairs and guard BuiltInAgent (refs OSS-857)
Fixes defects 5 and 9 from the OSS-856 phase 1 validation run, plus the half of defect 6 that lives on the Built-in Agent quickstart. Every claim was traced through package source. Defect 5 — three provider/handler names presented as interchangeable. They are not interchangeable; they pair up, and the pairing is what was undocumented. Added a "Provider and handler pairs" section to `backend/runtime-endpoints.mdx`: - The v1 `<CopilotKit>` wrapper renders `<CopilotKitProvider>` internally and pins `useSingleEndpoint` to `true` unless the prop is passed (`copilotkit.tsx:108`), so it asks for single-route transport even against a multi-route Runtime. `<CopilotKitProvider>` with the prop omitted resolves to `auto` and detects from `/info`. - A table of which handlers serve which mode, and the deprecated aliases (`createCopilotEndpoint`, `createCopilotEndpointSingleRoute`, and the Express pair) mapped to their replacements. - The constraint nobody had written down: every `copilotRuntime*Endpoint` wrapper builds its handler with `mode: "single-route"` and exposes no option to change it. Next.js App Router and node-http call the single-route helper directly; pages-router, node-express and nest all delegate to node-http. So Rich Threads is unreachable from the wiring the quickstarts teach at ANY provider setting — it needs a v2 `CopilotRuntime` plus a multi-route handler. That is the structural reason behind defect 3. - Provider half is scoped to `<FrontendOnly frontend="react">` with an Angular branch, because this page also serves the Angular surface and `provideCopilotKit` has no `useSingleEndpoint`. Both quickstarts gain a short callout naming the pair they use and linking the mapping. Defect 9 — the Built-in Agent quickstart (what `/quickstart` actually serves) instantiates `new BuiltInAgent(...)` as the `default` agent with nothing warning a reader who already has one. `BuiltInAgent` extends `AbstractAgent` and calls the model directly via `streamText`, so registering it replaces the developer's agent rather than connecting to it — the `user_code_preservation` violation the ticket describes. Added a caution telling readers with an existing agent to take the frontend steps here and the runtime wiring from their framework's quickstart. Defect 6, second half — the same page installed `@copilotkit/react-ui` and never used it, importing `CopilotKit` and `CopilotSidebar` from `@copilotkit/react-core/v2`. Dropped it, matching the LangGraph fix in #6566. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
573a614112 | Merge main into codex/fac-126-strands-ts-starter | ||
|
|
b9d41c0e3a | Merge main into codex/fac-126-strands-ts-starter | ||
|
|
99d3f99f4c |
docs(backend): construct the Intelligence client and name its key (refs OSS-857)
Fixes OSS-857 defects 1 and 2, which are one root cause. No page on the web
path ever constructs `CopilotKitIntelligence`, so `intelligence` reads as an
undefined identifier in the `new CopilotRuntime({ agents, intelligence,
identifyUser })` example, and `INTELLIGENCE_API_KEY` reads as a credential
with no consumer. `apiKey` IS that consumer.
The construction was already documented correctly, but only on the Channels
pages (frontends/slack.mdx, frontends/teams.mdx). This lifts the same pattern
onto the web path rather than inventing a second vocabulary for it.
Verified against packages/runtime source rather than inferred:
- `CopilotKitIntelligence` is exported publicly from `@copilotkit/runtime/v2`
via intelligence-platform -> v2/runtime/index.ts -> v2/index.ts
- `apiKey` is the only required field of `CopilotKitIntelligenceConfig`
- `apiUrl` and `wsUrl` default to the managed platform, and
`warnOnPartialHostOverride` logs a warning when one is set without the other,
which is why the docs now say to override both together
The Inspector page was NOT wrong to show `NEXT_PUBLIC_COPILOTKIT_LICENSE_KEY` --
that is the correct variable for that purpose. The defect is that a reader whose
.env holds `INTELLIGENCE_API_KEY` cannot tell whether the two are the same
credential. So that page disambiguates rather than substitutes: publishable
browser key versus server-side project key, with a pointer to what consumes the
latter.
Not verified: the site build and its vitest suite. A fresh worktree has no
installed toolchain (oxlint is absent), and oxlint covers JS/TS rather than MDX,
so it would not have exercised these edits. What was checked instead: <Step>,
<FrontendOnly> and code-fence balance in both files, and both new links against
existing usage -- `](/inspector)` appears 7 times and
`](/backend/runtime-endpoints)` 10 times elsewhere in the content tree. The site
soft-404s on unknown paths, so a link cannot be verified by status code.
Defects 5 and 9 remain open and are not addressed here.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
f24c4e2f22 |
docs(langgraph): correct the A2UI StateGraph framing after re-verification (refs OSS-857)
Three fixes found on a second pass over the docs changes: - The new StateGraph step claimed "the snippet above is the reference cell's `create_agent` form". It is not: `create_agent` appears on that page only as an *import* — both snippet regions stop inside the tool body, so the agent construction is never shown at all. Reworded to say that, which is the sharper version of defect 11: the page never shows how the tool attaches to any agent, leaving `create_agent`, `CopilotKitMiddleware` and `ChatOpenAI` as imports the reader cannot act on. - Carry over the system-prompt caveat. The reference cell steers the model to call `display_flight` once and stop because the tool result *is* the card; a StateGraph reader who drops that gets repeat tool calls. - The install note named only two of the four packages the FastAPI tab adds on top of the shared line. List all four. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
3ec309b724 |
docs(langgraph): fix 8 verified defects in the LangGraph onboarding docs (refs OSS-857)
Fixes defects 3, 4, 6, 7, 8, 10, 11 and 12 from the OSS-856 phase 1 validation run. Every claim below was re-verified against installed package source or a live run, not recalled. LangGraph quickstart (`integrations/langgraph/quickstart.mdx`): - Route shape: a caution at the route step. The POST-only route runs the runtime in single-route mode, which is all chat needs; Threads and the Inspector need the multi-route catch-all with GET/POST/PATCH/DELETE. Links to the canonical runtime-endpoints section. - Port: bare `langgraph dev` serves 2024, not 8123. Verified against both CLIs (`@langchain/langgraph-cli` help output, and `default=2024` in `langgraph_cli/cli.py`). The guide keeps `--port 8123` to stay consistent with every sibling page, and now says so. - Drop `@copilotkit/react-ui` from the install list. `CopilotSidebar` lives in `@copilotkit/react-core/v2`; react-ui exports no `./v2` JS entry point and the v2 react example does not depend on it. - Checkpointer: state the reason each tab differs. `langgraph dev` fails to load a graph compiled with a custom checkpointer (reproduced), while the FastAPI tab needs one because `ag-ui-langgraph` calls `graph.aget_state(...)`, which raises `ValueError: No checkpointer set`. - Narrow the shared `uv add` line to what both tabs import, and warn that a project with exact pins should add them by hand. A2UI fixed schema (`generative-ui/a2ui/fixed-schema.mdx`): - Add the missing install step for `@copilotkit/a2ui-renderer` + `zod`, which the catalog/definitions/renderer snippets all import. - Add a `StateGraph` + `ToolNode` form for developers who already have a hand-built graph, gated to the Python LangGraph slugs by a new `a2ui_agent_form` docs flag so the shared page does not show Python to langgraph-typescript or LangGraph code to LlamaIndex/ADK/Mastra. - Repoint the cross-tree `/integrations/langgraph/...` link, which 301'd back to this same page, at the action-handler reference it promises. Raw Markdown pipeline (`src/lib/llm-text.ts`): - `renderPageToLlmText` never applied `filterFrameworkScopedBlocks`, so `/<framework>/<page>.md` emitted every `<WhenFrameworkHas>` branch with raw JSX tags, each carrying the one selected framework's snippet. On the A2UI page that produced three mutually-exclusive "how the schema is delivered" sections whose prose contradicted the identical code under each. Gate on the same framework the snippets resolve to, with a regression test. Also corrects a factually wrong comment in the langgraph-python showcase `.env.example` that claimed 8123 was the `langgraph dev` default — the same mis-belief this ticket found in the docs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
38b013c5a0 | fix(showcase): cap public Claude demo traffic | ||
|
|
c81c6e2535 | fix: harden Strands TypeScript request boundaries | ||
|
|
1d32e8bd31 | Merge main into codex/fac-126-strands-ts-starter | ||
|
|
a1ca0150b8 | feat: configure Claude cookbook model | ||
|
|
bd91313517 | feat: add AWS Strands TypeScript starter | ||
|
|
4879b941ab | docs(deepagents): make state rendering example executable | ||
|
|
ed5d370936 | docs: initialize shared-state rendering example | ||
|
|
c45a50fa71 | docs: scope tool setup copy to Claude | ||
|
|
40608dc01d | docs: show Claude tool-rendering backend wiring | ||
|
|
35f14ff4d0 | fix(showcase): prune Claude test deps and clean snippets | ||
|
|
778dde6627 | test(showcase): cover Claude SDK MCP wiring | ||
|
|
0d528d57cc | docs(showcase): expose Claude fixed-schema backend wiring | ||
|
|
dc2aee1218 |
docs(channels): name which Microsoft bot identity Teams setup creates
The docs said only what setup does not create — no Azure subscription, no Azure Bot resource. That answers nothing for the tenant administrator who has to account for a new identity in their own directory, and the only way to learn the answer was to read our CLI source and notice `--teams-managed`. Names the kind we create and contrasts it with the two alternatives: where the credentials live, who rotates them, that it is single-tenant, and that nothing is billable. Also states that the choice is effectively permanent, since the app ID is the manifest's bot ID. Kept to one section on the tutorial page, which already carried the bot-ownership sentence, rather than a new page. It sits after the orientation links as an `h2` alongside the page's other sections; as an `h3` wedged between the intro and those links, the links read as part of it. refs OSS-833 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
1b7d56029c |
docs(channels): correct the Teams package hand-off
The rewrite claimed the command "installs it to a Team you choose" and that "there is no package to download". Neither is true. Microsoft exposes no install API, so `runAutomaticTeamsProvision` writes `<channel-name>-teams-app.zip`, prints upload steps, and blocks on Enter before verifying the installation. The old prose and the Teams tutorial's "upload the complete zip that setup produced" also contradicted each other. Documents what the command actually hands you: the package path, that the upload must come from the team's own Apps tab rather than the personal Apps section — personal scope yields a working DM that cannot be promoted — and that a tenant disallowing custom apps means Ctrl-C, get an administrator to install it, and re-run to resume rather than create a second app. Also covers `--teams-package`, which the wizard adds when the reader customizes branding: the browser builds that file, the CLI validates it, builds the app from it, and deletes the local copy. It decides how the app looks and does not replace the Team upload. Strikes "no Azure subscription and no Azure Bot resource are involved" from the Intelligence step. The Teams tutorial still says it, once, where a reader arriving with Azure expectations actually starts. The doc test pinned that struck sentence. It now pins the package hand-off instead, which is the claim that was wrong and would otherwise drift back. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
df8ae72069 |
docs(channels): document the shipped Teams setup flow
The Teams docs described a flow that no longer exists: registering an app by hand in Microsoft Entra, pointing an Azure Bot at the Intelligence messaging endpoint, pasting a client ID, tenant ID, and secret into the wizard, and downloading a package to upload. Setup is now a single CLI command that creates a Teams-managed bot in the reader's own tenant, registers the endpoint, and installs the app. Also corrects the file permission. The manifest requests the read-only `Files.Read.All`, not `Files.ReadWrite.All`, and it is optional: skipping it costs only files uploaded to a Team channel, and no longer holds the connection back from reporting ready. The doc test pinned the old prose, so it is repointed at the new contract — the command's flags, both permissions and which is optional, and that Entra and Azure Bot appear only to say they are not involved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
983c205feb |
fix: stale useCoAgent node name, silent content-part drops, and the LangGraph docs gaps (#6520)
Bundles the CopilotKit-side work from **OSS-769**, **OSS-767** (partial), and the unshipped remainder of **OSS-609**. ## OSS-769 — `useCoAgent().nodeName` never updates `useAgentNodeName` tracked the current node in a ref and returned `nodeNameRef.current`. Mutating a ref schedules no render, so a component reading `useCoAgent().nodeName` kept showing whichever node was current at its last render and never updated on its own — it only appeared to work when something unrelated happened to re-render it. Backing the value with state fixes it. Five lines, no API change. ## OSS-767 (partial) — silent content-part drops (#1748) `normalizeMessageContent` handles only `text` and `binary` parts; anything else — the `{"type": "image", ...}` case from the report — maps to `""` and is filtered out with no signal, so an agent emitting structured content sees its output vanish silently. This makes the drop visible, once per unrecognised part type so streaming doesn't flood the log. Deliberately **not** the schema change: carrying structured assistant content needs an `AssistantMessage` decision upstream in `ag-ui`, which stays open on OSS-767. ## OSS-609 — the five docs gaps that never shipped Gap #2 shipped in #6403; gaps 1, 3, 4, 5 and 6 did not. | Gap | Where | Closes | | --- | --- | --- | | AWS Lambda self-hosting | `docs/deploy/aws-lambda.mdx` | #1151 | | Per-user thread authorization | `docs/auth.mdx` (new section) | #2241 | | Thread persistence without the platform | `docs/threads-self-managed.mdx` | #6090 | | DIY guardrails / DLP | `docs/integrations/langgraph/guardrails.mdx` | #3414 | | When you need an MCP App | `docs/agentic-protocols/mcp.mdx` (new section) | #5991 | The Lambda guide leads with the constraint that actually bites — streaming is opt-in on every front door, so a chat runtime deployed with the defaults appears to hang for the whole run and then dumps the reply at once. It documents the Function URL + `RESPONSE_STREAM` path as the default, and API Gateway REST + `responseTransferMode: STREAM` for anyone who needs a REST API in front. `threads-self-managed` follows the existing shared-snippet pattern with per-framework wrappers, because two nav contracts require it: every authored framework must publish the page, and every React destination must map to an Angular one (`ANGULAR_DOC_REDIRECTS`). All nine wrappers were confirmed necessary by deleting one and watching the suite fail. ## Review corrections Two blockers from @MikeRyanDev, both verified against primary sources before changing anything. **API Gateway REST APIs can stream** ([`91b3e632d5`](https://github.com/CopilotKit/CopilotKit/commit/91b3e632d5)). The guide was built on the pre-November-2025 limitation and claimed no API Gateway type supports response streaming, steering readers to a buffered `serverless-http` setup. REST gained it via `responseTransferMode: STREAM`, which also lifts the 10 MB cap and 29-second timeout. REST and HTTP are now split; REST is documented as a streaming front door (payload-format-1.0 event adapter, `AWS_PROXY` integration on the `2021-11-15/.../response-streaming-invocations` URI, CLI/CDK/SAM config), and the buffered fallback is scoped to HTTP APIs and ALB, which still have no streaming path. Added the constraints that actually matter for chat: the 30-second idle timeout on edge-optimized endpoints (5 min Regional), and the console Test tab always buffering so a working config looks broken. **`identifyUser` is the platform's thread-scoping binding** ([`91b3e632d5`](https://github.com/CopilotKit/CopilotKit/commit/91b3e632d5)). The section told every reader to build an ownership table and enforce it in `onBeforeHandler`. On the Intelligence path the runtime already resolves `identifyUser(request)` server-side and carries that id to the platform; `listThreads` is scoped by user *and* filtered by `agentId`, so the "every user of one project sees that project's threads" claim was wrong. `identifyUser` is now documented as the binding, and the DIY pattern is scoped to SSE runtimes, custom stores, and the local in-memory runner. **Follow-up correction — two routes are genuinely unscoped** ([`240672ff56`](https://github.com/CopilotKit/CopilotKit/commit/240672ff56)). My rewrite then over-claimed. `handleGetThreadEvents` and `handleGetThreadState` resolve the caller and discard it, and the platform client takes no `userId` on either method (`client.ts:1113`/`1135`) — unlike `getThreadMessages` at `1063`. Both hit project-authenticated `_inspect` endpoints, so any caller `identifyUser` accepts can read the event log and agent state of **any thread in the project** given its id. The blanket guarantee is replaced by a per-route table marking those two explicitly unscoped, plus an `onBeforeHandler` guard narrowed to them. That is a live gap in shipped runtime code, not a docs error, and it is tracked as **OSS-851** — a platform-side `_inspect` change plus matching runtime/client work and tests, out of scope for a docs PR. The interim callout in `auth.mdx` comes out when OSS-851 lands. ## Not in this PR **OSS-772** and **OSS-773** are already merged in `oss-path-to-production` (#237, #238). Both are telemetry-sink changes with no CopilotKit-side component. OSS-773's remaining half — re-keying runtime `distinct_id` from email to the Clerk subject — is recorded on the ticket as an open decision, not a task. ## Testing **OSS-769.** New `use-agent-nodename.test.tsx`, 5 tests. Against unmodified `origin/main`, **4 of 5 fail**: ``` × re-renders consumers on every node transition × reports 'end' when a run errors × resets to 'start' when a new run begins ✓ unsubscribes on unmount × carries the agent, thread, and current node Tests 4 failed | 1 passed (5) ``` With the fix: `Tests 5 passed (5)`. These assert only re-render behaviour under normal `act()` flushing — no manufactured intra-batch window. **Full react-core suite:** `Tests 7 failed | 1496 passed (1503)`. All 7 failures are **pre-existing** `ResizeObserver is not a constructor` under jsdom, confined to `CopilotChatView.pinToSend` and `use-pin-to-send` — neither of which this PR touches. **Typecheck:** `packages/react-core` → `tsc --noEmit` exit 0, no output. **OSS-767:** 3 new tests covering the warn, warn-once-per-type, and no-warn-for-supported-types. `src/graphql/message-conversion/` → `Tests 125 passed (125)`. **Docs:** `showcase/shell-docs` → `Tests 1 failed | 373 passed (374)`. The single failure (`channels-docs > publishes the Channels overview only through provider navigation`) is **pre-existing**; baselining with all changes stashed reproduces it and nothing else. Re-run unchanged after both review-correction commits. **Review corrections.** The AWS rewrite was checked against the AWS sources rather than written from memory — the REST streaming announcement, `configuration-response-streaming`, `response-transfer-mode` (endpoint-type idle timeouts, unsupported buffered-only features), `response-streaming-lambda-configure` (CLI/OpenAPI shapes), the CFN `Integration` reference, and the CDK `ResponseTransferMode` enum. Two details corrected in passing: `InvokeWithResponseStream` authorizes against plain `lambda:InvokeFunction` (no new grant, contrary to what the streaming URI suggests), and ALB still has no Lambda streaming path. The auth corrections were verified by reading the handlers and the platform client, not the tests — `resolve-intelligence-user.ts`, `intelligence/threads.ts` (every `resolveIntelligenceUser` call site), and `intelligence-platform/client.ts`. The existing tests assert the `threadId`-only call shape, so they pass under the defect and could not have surfaced it. Also corrected: there is no `threads/delete` route — delete is `DELETE` on `threads/update` (`fetch-handler.ts:606`). Both edited pages MDX-compile clean, and all inbound `#thread-authorization` anchors still resolve after the h3→h4 demotions. Two nav tests broke during this work and are fixed rather than papered over — adding a page to the Rich Threads group violated the cross-framework ordering contract and the React→Angular parity contract: ``` src/lib/__tests__/docs-render.test.ts src/lib/__tests__/angular-docs-content.test.ts Test Files 2 passed (2) Tests 33 passed (33) ``` All 15 internal links in the new pages resolve against the content tree. Closes #1151, #2241, #3414, #5991, #6090 Refs #1748, OSS-851 |
||
|
|
eb567d44ae | fix(docs): address programmatic control review feedback | ||
|
|
1cc34c641a | fix(docs): make programmatic control example self-contained |