5522 Commits

Author SHA1 Message Date
Mike Ryan d950f00340 docs: fix MCP endpoint and native Codex setup 2026-09-08 15:24:47 -07:00
Benjamin Taylor 82cd7c01f7 fix(react-core): let a custom catch-all renderer return null
`useDefaultRenderTool`'s `render` was typed to return `React.ReactElement`,
so a caller who wanted to render only some tool calls could not return
`null` to suppress the built-in default for the rest. The value already
flowed through correctly at runtime; only the type rejected it.

Widen the public `render` return type, and the wrapper local that carries
the user's value, to `React.ReactElement | null`. The `as unknown as` cast
into `useRenderTool` stays, because `useRenderTool` still requires a
`ReactElement` return on main; PR #6533 widens that hook, after which the
cast can be tightened.

Guarded by a `.test-d.ts` assertion rather than a runtime test: types are
erased, so a null-returning render forwards identically before and after
the widening and a runtime test would assert nothing.

Extracted from #5509, which is otherwise stale.

Co-authored-by: Atai Barkai <atai.barkai@gmail.com>
2026-09-08 16:39:06 -05:00
Ben Taylor 30aba6b959 docs(showcase): state the frontend-tool requirement for the last nine frameworks (closes OSS-1036) (#6874)
## Problem

`generative-ui/tool-based` is the terminal page every onboarding run
fetches, on every framework route (OSS-1034). Its `## How it works in
code` section is one `<FrameworkSetup concept="frontend-tools-setup" />`
call that resolves a per-framework snippet. Nine frameworks shipped no
snippet, so the section rendered nothing and the `.md` output emitted
`<!-- setup skipped: ... -->`. That silence meant two different things
at once: "this framework needs no agent-side wiring" and "it needs
wiring and nobody wrote it down".

Verified on the live host before the change: all nine emitted the skip
comment, at ~2.4KB per page.

One of the nine is `built-in-agent`, which is `ROOT_FRAMEWORK`. So the
page carrying the gap included the unscoped default,
`https://docs.copilotkit.ai/generative-ui/tool-based.md`.

## Solution

A snippet for each of the nine. Each verdict was read out of the pinned
adapter rather than out of the docs, which is what the ticket asked for.

**Nothing to wire on the agent** — confirmed in the adapter:

| framework | the line that decides it |
| --- | --- |
| `ag2` | `autogen/ag_ui/adapter.py` `run_stream` builds `client_tools`
from `command.incoming.tools` |
| `mastra` | `@ag-ui/mastra@1.1.0` reduces `input.tools` into
`clientTools` for `agent.stream()` |
| `strands` | `ag_ui_strands@0.2.2` calls
`sync_proxy_tools(agent.tool_registry, input_data.tools, ...)` |
| `strands-typescript` | `@ag-ui/aws-strands@0.2.3` registers a proxy
tool per forwarded tool in `toolRegistry` |

Both Strands adapters refuse to overwrite a native tool of the same
name, so each snippet says to keep the `useComponent` name distinct.

**Real wiring:**

- `agno`. Its AG-UI interface never reads `RunAgentInput.tools`. Checked
against `agno==2.6.19`: the only tool path out of
`agno/os/interfaces/agui/` is
`RunPausedEvent.tools_awaiting_external_execution`. So a component needs
a declared `@tool(external_execution=True)` stub and the `Agent` needs a
`db` to hold the paused run.
- `deepagents`. `sdk-python/copilotkit/copilotkit_lg_middleware.py`
merges `copilotkit.actions` into `request.tools` inside
`wrap_model_call`, so `middleware=[CopilotKitMiddleware()]` is
load-bearing. Its snippet lives in the docs-only tree, because
`deepagents` has no integration package.

**Mode-dependent:**

- `built-in-agent`. Config mode merges `input.tools` for you
(`packages/runtime/src/agent/index.ts`). A factory owns the model call
and forwards nothing, so it has to pass them itself. Both halves are in
the snippet, plus the collision rule: a frontend tool whose name matches
a server tool is dropped in favor of the server executor.

**In-repo evidence only:**

- `ms-agent-dotnet`, `ms-agent-harness-dotnet`. Their own
`gen-ui-tool-based` agents render charts with an empty tool list
(`tools: []` / `Tools = []`) and their instructions name the chart
tools. No .NET SDK was available here to read
`Microsoft.Agents.AI.Hosting.AGUI.AspNetCore` directly.

Six of the nine snippets also carry the "Tell the model when to call it"
step, which is not filler. `GEN_UI_TOOL_BASED_PROMPT` in
`showcase/integrations/built-in-agent/src/lib/factory/demo-prompts.ts`
records what happens without it: the model emits `value: 0` for every
point and renders a chart with no bars.

## Tests

- `REQUIREMENT_NOT_ESTABLISHED` is now empty, and the docblock says a
new framework arriving without a snippet is fixed with a snippet, not
with a name.
- The shape test pins all six auto-forwarding frameworks, plus the three
that do not fit that shape (`agno`, `deepagents`, `built-in-agent`).
- `setup-concept.test.ts` used `ag2` as its example of an unbundled
concept, so closing the last gap would have turned it red for the right
reason. It now uses a concept name that is deliberately never bundled.

## The gate never ran in CI

Second commit. No workflow runs the shell-docs vitest suite:
`test_integration-docs.yml` runs exactly one test file,
`test_unit-showcase.yml` covers harness and shell-dashboard only, and
`showcase_build_check.yml` matches `showcase/**` but only builds images.
Neither path filter listed the snippet files either. So the ratchet
added in #6777 was local-only.

Added a scoped job and widened both filters. The job runs only the two
setup-concept files on purpose: the full shell-docs suite is not green
on `main`, and gating every snippet change on unrelated failures would
be worse than no gate.

## Verification

Ran against a local `shell-docs` dev server on this branch. Expected
`setup skipped` count is 0 everywhere:

```
ag2                        skip=0 bytes=3825
agno                       skip=0 bytes=4299
deepagents                 skip=0 bytes=3786
mastra                     skip=0 bytes=3857
ms-agent-dotnet            skip=0 bytes=3706
ms-agent-harness-dotnet    skip=0 bytes=4236
strands                    skip=0 bytes=4026
strands-typescript         skip=0 bytes=4001
built-in-agent (root path) skip=0 bytes=4723
```

`vitest run` on the two setup-concept files: 12 passed. `npm run
typecheck` and `npm run lint` both exit 0.

Four tests fail in the full shell-docs suite (`llm-text.test.ts` mastra
tool-rendering, three in `angular-docs-content.test.ts`). All four fail
identically at the pre-change baseline in the same worktree, so they are
pre-existing on `main` and untouched by this branch.

## Two findings this turned up, not fixed here

1. **The `agno` showcase demo contradicts its own snippet.** Every
`useFrontendTool` tool in agno's demos has a matching
`external_execution` stub, but the `useComponent` ones do not:
`render_bar_chart`, `render_pie_chart`, `query_notes` and
`highlight_note` have no backend declaration, and
`_run_main_agent_hitl_aware` in `src/agent_server.py` cannot forward
them. Its e2e spec cannot catch this, because it asserts only that an
`svg` is visible inside an assistant message, which any icon satisfies.
2. **Four frameworks redirect the HTML page away.** For `ag2`, `agno`,
`deepagents` and `mastra`, `/<slug>/generative-ui/tool-based` 301s to
`/<slug>/generative-ui/tool-rendering`. Confirmed on the live host as
well as locally, so it predates this branch. Their `.md` output serves
the page normally, which is the path onboarding runs fetch, but a human
browsing those four never reaches it.

Closes OSS-1036.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Documentation**
- Added frontend tool setup guides for AG2, Agno, Built-in Agent,
Mastra, Microsoft Agent integrations, Strands, and Deep Agents.
- Documented tool registration, prompting, execution behavior,
persistence, and middleware configuration.

- **Tests**
- Expanded coverage for frontend tool setup documentation across
supported integrations.
- Updated setup concept tests to use a stable, intentionally unbundled
example.

- **Chores**
- Added automated workflow coverage for setup documentation and related
tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 16:36:44 -05:00
Ben Taylor b0c0b50826 docs(microsoft-agent-framework): document backend approval interrupts (#6922)
Closes #2770.

## Problem

Our Microsoft Agent Framework human-in-the-loop page taught exactly one
pattern: register a frontend tool whose name matches a backend tool.
That is why #2770 was filed asking for a feature we already ship, and
why two more people asked for an update on it.

Backend-raised approvals have worked for months. Mark a tool with
`approval_mode="always_require"` (Python) or wrap it in
`ApprovalRequiredAIFunction` (.NET), and the agent ends the run with an
AG-UI interrupt that `useInterrupt` renders. No name matching. Nothing
on the docs site said so.

## What changed

Split the page the way Mastra's already is, and add the missing half:

- `human-in-the-loop/index.mdx` — picks between the two patterns. It
keeps `/microsoft-agent-framework/human-in-the-loop` resolving, so the
three existing pages that link there need no edit.
- `human-in-the-loop/interrupt-flow.mdx` — new; the approval path.
- `human-in-the-loop/tool-based.mdx` — the old page, retitled, content
unchanged.
- `custom-look-and-feel/headless-ui.mdx` — one sentence pointing backend
approvals at the new page.

The new page records four details that are easy to get wrong from
reading the source. I got each of them wrong myself before running it:

- `reason` is `"tool_call"`, not `"approval"`.
- The tool name and arguments live under `metadata.agent_framework`
**only on Python**. .NET sends no such field and names the tool in
`message`.
- `cancel()` and `resolve({ approved: false })` both leave the tool
unrun, but cancel ends the run while a false approval lets the agent
keep talking.
- `renderInChat` defaults to `true`, so the UI renders nothing —
silently, no warning — unless a `<CopilotChat />` is mounted.

## Testing

Every claim on the new page was executed, not inferred.

**End to end against a real agent.** Published `@copilotkit/react-core`
over real HTTP against a real Microsoft Agent Framework agent on
released `agent-framework-ag-ui` 1.2.2, with a tool marked
`approval_mode="always_require"`, served through the real AG-UI FastAPI
endpoint. A deterministic stub chat client stands in for the model, so
no API key is needed.

```
✓ CopilotKit <-> real Microsoft Agent Framework approval (2 tests)
  ✓ renders the backend approval and, on approve, the backend runs the tool
  ✓ on cancel, the backend does not run the tool
  Tests  2 passed (2)
```

Approving produced `TOOL_CALL_RESULT ... "content":"Deleted notes.txt."`
from the backend and surfaced it in the frontend. Cancelling produced no
tool result.

**Version floors are measured, not read off a changelog.** The same test
passes on `@copilotkit/react-core` 1.61.2 and fails on 1.61.1 (`Unable
to find an element by: [data-testid="reason"]`), which is where the
1.61.2 in the requirements table comes from. `agent-framework-ag-ui`
1.2.0 ships byte-identical interrupt-conversion logic to the 1.2.2 I
ran. `AGUI.Server` 0.0.6's shipped DLL contains the `tool_call` reason
and the `Approval required for tool call` message, and ag-ui's own
verified .NET baseline shows the same wire shape.

**Mutation-checked.** Changing the backend tool's return string fails
the approve test; clicking Approve in the cancel test fails it. An
earlier version of the cancel test passed under that mutation — it
settled with a bare `setTimeout` outside `act()` — so it was rewritten
to poll with `waitFor` and require a timeout.

**Docs suite.** Generators plus the node-environment tests that cover
routing and the nav tree:

```
 Test Files  4 passed (4)
      Tests  30 passed (30)
```
(`sitemap`, `page-tree-bridge`, `llms.txt`, `llms-mdx`)

All three routes appear in the generated search index, including the
preserved index URL:

```
microsoft-agent-framework/human-in-the-loop
microsoft-agent-framework/human-in-the-loop/interrupt-flow
microsoft-agent-framework/human-in-the-loop/tool-based
```

The jsdom-environment tests could not run locally — this checkout's
`showcase/shell-docs` install predates `jsdom`, and it resolves through
symlinks to the main checkout. CI covers them.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Added a Human-in-the-Loop section for Microsoft Agent Framework
integrations.
* Documented interrupt-based and tool-based workflows, including
approval, denial, cancellation, and frontend interaction guidance.
* Added details on approval-gated backend tools, interrupt payloads, and
rendering requirements.
  * Updated the tool-based guide’s title and description.
* Added the new section and page ordering to the documentation
navigation.
* Clarified how headless UI examples should render backend-tool
approvals.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 16:36:40 -05:00
Jerel John Velarde 1822de72da docs(channels): bump the tested SDK pair to channels 0.9.2 / runtime 1.70.2
The Channels pages pinned @copilotkit/channels@0.6.1 with
@copilotkit/runtime@1.65.0, four minors behind the current release.
Anyone following them installs a Channels version that predates
defineChannelComponent, which landed in 0.7.0, so agent-rendered
components cannot compile.

Update every pinned pair in the Channels docs to
@copilotkit/channels@0.9.2 + @copilotkit/runtime@1.70.2, refresh the
direct-adapters availability note that named 0.6.1, and add the
tested-pair framing to the SDK reference index, which pinned versions
without explaining that the two ship and upgrade together.

Also updates the pinned constants in the shell-docs guard test, which
asserts the quickstarts contain the exact tested install string.
2026-09-08 14:25:12 -07:00
Benjamin Taylor 0748b1a8e8 docs(showcase): explain the AgentCore 401 "Missing Authentication Token" (closes #2912)
Reporters following a framework quickstart and then pointing the runtime at a
deployed AgentCore endpoint hit `HTTP 401: Missing Authentication Token` with no
guidance anywhere in the docs. The string is AWS's own response to an unsigned
request or an unmatched route, so it reads like a CopilotKit failure when it is
not.

Add a Troubleshooting section covering the four causes: an unset
AGENTCORE_ACCESS_TOKEN interpolating to `Bearer undefined`, an expired Cognito
token, an AGENTCORE_ENDPOINT_URL that stops short of /invocations, and a browser
calling AgentCore directly instead of going through Copilot Runtime.

The AgentCore guide exists as two near-duplicate copies -- docs/deploy/agentcore.mdx
serves /deploy/agentcore, and snippets/integrations/agentcore/index.mdx is what
<Content framework="..." /> renders at /strands/deploy-agentcore and
/langgraph/deploy-agentcore. Both are live, so the section lands in both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:45 -05:00
Benjamin Taylor 5f8da811d9 docs(microsoft-agent-framework): document backend approval interrupts
Our Microsoft Agent Framework HITL page taught only the frontend-tool
approach, where the frontend registers a tool whose name matches a backend
tool. Backend-raised approvals have worked for months -- mark a tool with
approval_mode="always_require" (Python) or ApprovalRequiredAIFunction (.NET)
and the agent raises an AG-UI interrupt that useInterrupt renders -- but no
page said so, so readers kept reaching for name matching (issue #2770).

Split the page the way Mastra's is split and add the missing half:

- human-in-the-loop/index.mdx picks between the two patterns. It keeps the
  existing /microsoft-agent-framework/human-in-the-loop URL working, so the
  three pages linking there are untouched.
- human-in-the-loop/interrupt-flow.mdx documents the approval path.
- human-in-the-loop/tool-based.mdx is the old page, retitled.

The interrupt page records details that are easy to get wrong from reading
the code: reason is "tool_call" rather than "approval"; the tool name and
arguments sit under metadata.agent_framework only on Python, while .NET
names the tool in message; cancel() and resolve({approved:false}) both skip
the tool but end the turn differently; renderInChat defaults to true and
renders nothing, silently, with no chat mounted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:34 -05:00
Benjamin Taylor 2e05c9ce81 docs(showcase): put the built-in-agent name-collision rule in the right mode (refs OSS-1036)
The snippet stated the collision rule under factory mode, which implied the
runtime resolves it for you there. It does not.

Config mode is where the runtime decides: `index.ts` builds the tool set from
`convertToolsToVercelAITools(input.tools)` and then spreads the configured
tools over it, so a shared name resolves to the backend tool. The rule now
sits in that step.

In factory mode the factory owns precedence, because nothing merges the two
lists on its behalf. The showcase's own TanStack factory shows one choice,
filtering forwarded tools through `!serverToolNames.has(t.name)`, but that is
its decision rather than runtime behavior. The factory step now says so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:29 -05:00
Benjamin Taylor b3462e01fe docs(showcase): fix the using directives in the two .NET snippets (refs OSS-1036)
Both snippets named namespaces that do not resolve.

`Microsoft.Agents.AI.Harness` is the NuGet package name, not a namespace.
`AsHarnessAgent` and `HarnessAgentOptions` come from `Microsoft.Agents.AI`,
and no `.cs` file in the repo carries a `using` for the package name.

Both snippets also needed `using Microsoft.Extensions.AI`, which is where
`AsIChatClient()` and `ChatOptions` live. Every agent file in both showcase
columns uses exactly `Microsoft.Agents.AI` plus `Microsoft.Extensions.AI`.

Also define `HarnessMaxContextWindowTokens` and `HarnessMaxOutputTokens` in the
harness snippet, which referenced them without showing a value.

No .NET SDK is available here, so this was checked against the `using` blocks
of the twelve agent files that call `AsHarnessAgent`, not by compiling.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:29 -05:00
github-actions[bot] 700fb1496b style: auto-fix formatting 2026-09-08 16:22:29 -05:00
Benjamin Taylor cf060da900 docs(showcase): state the frontend-tool requirement for the last nine frameworks (closes OSS-1036)
`generative-ui/tool-based` is the terminal page every onboarding run fetches,
and its `## How it works in code` section renders a per-framework snippet.
Nine frameworks shipped no snippet, so the section rendered nothing and the
silence meant both "no agent-side wiring is needed" and "wiring is needed and
nobody wrote it down".

Each verdict was read out of the pinned adapter rather than the docs:

- ag2: `run_stream` builds `client_tools` from `incoming.tools`.
- mastra: the adapter reduces `input.tools` into `clientTools`.
- strands, strands-typescript: a proxy tool per forwarded tool is registered
  in the agent's tool registry, and a native tool of the same name wins.
- agno: its AG-UI interface never reads `RunAgentInput.tools`, so a component
  needs an `external_execution=True` stub and a `db` for the paused run.
- deepagents: `CopilotKitMiddleware` merges `copilotkit.actions` into
  `request.tools`, so the middleware is load-bearing.
- built-in-agent: config mode forwards for you, a factory does not. It is also
  the root framework, so this is the unscoped default page.

The two .NET columns rest on their own demo agents, which render charts with
an empty tool list. No .NET SDK was available to read the NuGet hosting
package.

REQUIREMENT_NOT_ESTABLISHED is now empty. The shape test pins each snippet,
and setup-concept.test.ts no longer depends on ag2 being an open gap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 16:22:29 -05:00
copilotkit-qa-bot[bot] 0f997c706e docs(strands): render subagent state in text export 2026-09-08 10:26:10 -07:00
copilotkit-qa-bot[bot] 81f43c0998 docs(strands): include subagent state helper 2026-09-08 10:00:36 -07:00
copilotkit-qa-bot[bot] 1dc49d3bfc test(strands): cover dynamic A2UI starter flow 2026-09-08 09:37:26 -07:00
copilotkit-qa-bot[bot] 4e75a0233f test(strands): keep catalog parity check outside agent image 2026-09-08 09:15:14 -07:00
Doniyor 62c895fee2 fix(react-core): default attachment uploads to one at a time
`maxConcurrentUploads` defaulted to 3, which changed when a public
`onUpload` is called with no code change on the app's side: a handler
written when uploads were serial could suddenly see the next file start
before the previous one finished. Concurrency is now something the app
asks for, and `maxConcurrentUploads: 3` restores the pool.

Queueing the whole selection up front is kept at every limit — it shows
the user what they picked rather than changing a contract.

The default test now pins one-at-a-time; a separate test pins that
`maxConcurrentUploads: 3` really runs three. Docs, the `AttachmentsConfig`
JSDoc and the react-core skill reference say `1`.
2026-09-07 15:02:30 +05:00
Doniyor c237f29dbb fix(react-core): share the upload pool across processFiles calls
The worker pool was per `processFiles` call, so a paste landing while a
dropped selection was still uploading opened its own set of workers —
two overlapping selections could run 2× the limit, and
`maxConcurrentUploads: 1` gave one upload per call rather than one at a
time.

Move the queue and the worker count onto the hook: workers are counted,
not owned by a call, and a call tops the pool up to the limit instead of
starting a fresh one. Each call still resolves when its own files have
settled.

Also pin `Infinity` as "no limit" with a test, and say in the docs that
the limit covers everything in flight rather than each batch.
2026-09-07 15:02:30 +05:00
Doniyor 62067b76d1 feat(react-core): upload attachments concurrently
`processFiles` walked the valid files in a `for` loop and awaited each
upload inside it, so `onUpload` was called for one file only after the
previous had finished — attaching 8 files to a chat cost 8 sequential
round trips to whatever storage the app uploads to.

Queue the whole selection first, then drain it with a bounded worker
pool: `maxConcurrentUploads` on `AttachmentsConfig` sets the bound and
defaults to 3, and `1` restores one-at-a-time uploads for an endpoint
that wants them. `onUpload` may now be called concurrently.

Queueing up front also means a file waiting for a free slot is already
visible as `uploading` rather than appearing once its upload starts.

The Vue and Angular bindings read the same config type and still upload
serially; they can follow separately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 15:02:30 +05:00
Rainer Hahnekamp 0d46ef5fe7 Merge branch 'main' into feat/angular-copilot-activity 2026-09-06 21:53:17 +02:00
Tyler Slaton 9173ab479c fix(docs): address search accessibility and indexing review findings
Announce recommendation selection without invalid active descendants, omit
missing controlled elements, and cover empty-result and result-slot behavior.
Report snippet expansion failures and reject partially staged content roots
before either search index is overwritten.

Validation: 829 tests pass; three Angular/Mastra content failures already
reported in PR #6887 remain. Typecheck and lint pass (existing lint warnings).
Browser-verified local search, keyboard selection, and recommendation navigation.
2026-09-05 03:05:49 +02:00
Lukas Moschitz 45ac1b482b feat(docs): improve search ranking and recommend Intelligence guides 2026-09-05 03:05:49 +02:00
Lukas Moschitz c1086fe5fa fix(docs): index reachable pages across docs build contexts 2026-09-05 03:05:49 +02:00
Martha Kelly Schumann c70502b137 feat(inspector): add Learning view and workbench 2026-09-04 17:11:59 -07:00
Tyler Slaton e9ff66ce72 docs(integrations): state the JSON-string context contract on every agent-app-context page (#6893)
Closes OSS-1134.

## Problem

`useAgentContext` calls `JSON.stringify` on any non-string `value`
before the run leaves the browser
([`use-agent-context.tsx:29-34`](https://github.com/CopilotKit/CopilotKit/blob/main/packages/react-core/src/v2/hooks/use-agent-context.tsx#L29-L34)),
because the AG-UI protocol types `Context.value` as `z.string()` on both
ends. The Python SDK only calls `model_dump()`, so the value reaches
`state["copilotkit"]["context"]` as a JSON string with no parsing
anywhere in between.

The four reference pages have said so since b18f7054af (OSS-1003). The
**integration guides** — the pages a reader actually follows — did not,
and they walked the reader straight into the trap:

- register `colleagues`, an array of objects
- read `.get("value")` and interpolate it into an f-string

An f-string hides the type completely, because a JSON string formats
without complaint. A reader who wants `colleagues[0]["name"]` gets `'['`
instead, and the failure reads as "the frontend sent nothing" —
indistinguishable from an empty context.

## What changed

Documentation only. The wire format does not change: the string is the
protocol.

**One shared callout, eight pages.** New snippet
`snippets/shared/basics/agent-context-json-string.mdx`, imported by
every `agent-app-context` variant before its first code sample, so the
wording cannot drift. Three pages (`adk`, `crewai-flows`, `pydantic-ai`)
already stated the contract, but only *after* their first code sample,
where a reader skimming to the code misses it.

**Four examples were wrong, not just undocumented:**

| Page | Defect | Fix |
|---|---|---|
| langgraph (Python) | interpolated the raw string | `json.loads`, then
reads `c["name"]` so the reason to parse is visible |
| langgraph (TypeScript) | `find` predicate was `'The current user\'s
colleagues"'` — a stray quote that could never match | predicate
corrected, then `JSON.parse` |
| mastra | `JSON.stringify(item?.value)` on an already-encoded value →
double encoding | parses instead |
| ag2 | returned the raw string at three sites, one annotated `->
list[dict]` | all three parse |

The langgraph TypeScript predicate bug meant that example could not have
worked as printed, independently of the JSON issue.

Reference pages are untouched — all four already cover this correctly.

## Testing

**Acceptance criteria, checked mechanically against the final content:**

```
=== AC1: callout precedes the first code fence, all 8 variants
  PASS adk        PASS ag2          PASS built-in-agent   PASS crewai-flows
  PASS langgraph  PASS mastra       PASS ms-agent-fwk     PASS pydantic-ai
=== AC2: no context value interpolated without a parse
  PASS (all 8; every ag2 extraction assigns to `raw`, then json.loads(raw))
=== AC3: nothing stringifies an already-string value
  PASS (swept every .mdx under docs/ and snippets/)
```

**The edited code actually runs.** Executed the Python and TypeScript
fragments as printed:

```
compiles: langgraph / ag2 get_readable / ag2 list_colleagues
round trip OK; None default still absorbed by the call site's `or []`
chat_node   -> 'John Doe (Developer), Jane Smith (Designer)'
mastra      -> 'John Doe (Developer), Jane Smith (Designer)'
pre-fix colleagues[0] was '[' (a single character)
pre-fix mastra output: "[{\"id\":1,\"name\":\"John Doe\",\"role\":\"D...   (double encoded)
pre-fix langgraph TS find predicate matched: false (was always undefined)
```

The last three lines reproduce the reported failure and both latent
bugs, then show them fixed.

**MDX renders.** All 9 files compiled through the real pipeline
(`inlineSnippets` → `convertTablesInJSX` → `@mdx-js/mdx`), with zero
snippet-resolution warnings:

```
PASS × 9   snippet warnings: (none)
```

**Test suite — failure-set diff, not a bare pass.** This environment has
a known install-staleness gap (`@clerk/nextjs`), so I compared against a
pristine-content baseline in the same worktree rather than against zero:

```
baseline (pristine main content):  Test Files  14 failed | 68 passed (82)   Tests 35 failed
with this change:                  Test Files  14 failed | 68 passed (82)   Tests 35 failed
FAILURE-SET DIFF: IDENTICAL — this change introduces no new failure
```

For reference, the same content passes cleanly where the install is
complete: 51 files / 351 tests, matching its own baseline exactly.

**Mutation-checked the probes** rather than trusting a green light:
breaking the snippet import path fails 1 page, and deleting the callout
text fails all 6 dependents — confirming the snippet is genuinely shared
and the checks can actually fail.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Added guidance across integration guides clarifying that agent context
values arrive as JSON strings.
* Added parsing examples for Python and TypeScript, including
colleague-list formatting.
* Added warnings about avoiding raw access and double-encoding context
values.
* Updated AG2, LangGraph, and Mastra examples to parse context values
before use.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-05 01:39:23 +02:00
Tyler Slaton 97d1379ae8 feat(docs): improve page prompt actions 2026-09-05 01:24:50 +02:00
Tyler Slaton 282e8f1c11 feat(docs): make quickstart and learning product first 2026-09-05 01:24:50 +02:00
Tyler Slaton 79c683bb2c feat(docs): refine navigation and Intelligence hierarchy 2026-09-05 01:24:50 +02:00
Tyler Slaton 21ac18fba6 fix(docs): center reading layout and mobile toc 2026-09-05 01:24:50 +02:00
Ben Taylor 8c629c147b docs(showcase): document frontend-driven activity cards (refs #3388) (#6904)
## What

Issue #3388 asked for a way to put a card into the chat transcript from
frontend code, without a tool call and without adding to the
conversation the model reads.

**That already ships.** A message with `role: "activity"` renders
standalone in the transcript, and `AbstractAgent.prepareRunAgentInput`
strips every activity message from the run payload:

```js
prepareRunAgentInput(e) {
  let t = structuredClone_(this.messages).filter(e => e.role !== `activity`);
  ...
}
```

The gap was documentation. `renderActivityMessages` is only documented
for **backend-emitted** activities (mastra background-tasks, a2a,
mcp-apps), so the frontend-driven path was undiscoverable.

This PR adds the missing guide page and a test that pins the behavior.

## Changes

| File | Why |
| --- | --- |
| `showcase/shell-docs/.../generative-ui/frontend-cards.mdx` | New
"Frontend-Driven Cards" guide |
| `showcase/shell-docs/.../generative-ui/meta.json` | Sidebar entry
(6-line insertion) |
| `packages/react-core/.../CopilotChatFrontendActivityCard.e2e.test.tsx`
| Pins both halves of the contract |

No source changes. Behavior is unchanged; this documents and locks what
already works.

## The non-obvious part

The card must be added via the agent returned by `useAgent()`. An agent
instance constructed and held outside React is **not** the instance the
chat renders, so messages added to it silently never appear. This cost
me a debugging round while verifying, and it is called out as a warning
callout in the docs.

## Testing

**1. New test passes against clean `origin/main`** (run in a worktree at
`96cf7aa55f`, with `@copilotkit/shared` and `@copilotkit/core` rebuilt
from the worktree so the test is not reading a stale dist):

```
✓ src/v2/components/chat/__tests__/CopilotChatFrontendActivityCard.e2e.test.tsx (2 tests) 72ms

 Test Files  1 passed (1)
      Tests  2 passed (2)
```

**2. Mutation-checked, so neither assertion is self-fulfilling.**

Drop the renderer registration → the render test fails:
```
× renders a card added from frontend code, with no tool call 1068ms
      Tests  1 failed | 1 passed (2)
```

Swap the card from `role: "activity"` to `role: "assistant"` → it
reappears in the payload, so the exclusion is real and specific to
`activity`:
```
AssertionError: expected [ 'user', 'assistant' ] to deeply equal [ 'user' ]
```

**3. Neighboring test unaffected on the same base:**

```
✓ src/v2/components/chat/__tests__/CopilotChatMessageView.test.tsx (16 tests) 53ms
      Tests  16 passed (16)
```

**4. Independent probe of the filter** against the pinned
`@ag-ui/client` 0.0.57:

```
agent.messages roles: [ 'user', 'activity' ]
run input roles     : [ 'user' ]
```

**5. `tsc --noEmit`** — zero errors in the new file. Remaining errors in
this workspace are in files this PR does not touch
(`MCPAppsActivityRenderer.tsx`, `CopilotKitInspector.tsx`) and are
artifacts of a hand-assembled local `node_modules`; CI has the real
install.

**6. `oxfmt --check`** — clean.

**7. Docs checks** — `meta.json` validated as JSON; internal link uses
the house `/generative-ui/...` form (no `/docs` prefix); `Callout
type="warn"` matches the dominant existing usage; import paths verified
against the real `@copilotkit/react-core/v2` barrel exports.

## Follow-up

Leaving #3388 open until this lands, then closing it with a pointer to
the new page.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added support for frontend-driven activity cards that render in chat
transcripts without being sent to the agent or language model.
- Added documentation covering activity card renderers, schemas,
registration, payload filtering, snapshots, and limitations.
- Added a new “Frontend-Driven” section to the Generative UI
documentation navigation.

- **Tests**
- Added end-to-end coverage for activity card rendering and payload
exclusion.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-04 17:32:15 -05:00
Ran Shem Tov 4b2222d3cc ci(showcase): install the agent's own dependencies before its unit tests
The gate added in the previous commit would have failed on a clean checkout.
The Strands TypeScript integration sits outside the pnpm workspace on purpose:
its agent process resolves openai and the Strands SDK from its own
node_modules, which the Dockerfile installs with npm ci. The workflow ran only
the repo-root pnpm install, so two of the four test files could not resolve
their imports. It passed locally only because that directory already existed on
this machine. Reproduced by moving it aside (2 files fail), then confirmed the
workflow's own steps green it again (16 tests pass).

The job now installs the agent package the same way the Dockerfile does, and
runs the vitest config that already lives beside those tests rather than a
second config layered above them, so CI runs exactly what `npm test` in that
directory runs. The path filters narrow to the sources the run actually covers,
so a PR touching an unrelated integration no longer collects a green check from
a job that exercised none of its code.
2026-09-04 23:49:13 +02:00
Ran Shem Tov 19bfa83df1 ci(showcase): gate the integration unit tests that nothing ran
The showcase integrations sit outside the pnpm workspace, so nx never
discovers them and the harness unit workflow does not cover them. Their Python
tests are already gated by showcase_validate.yml, but nothing anywhere ran
vitest under showcase/integrations: four test files in the Strands TypeScript
agent, including the one this branch adds for the resume envelope, could fail
indefinitely without CI noticing.

A small config at showcase/integrations/vitest.config.ts gives those tests one
home, driven by the monorepo's own vitest so no integration has to carry a test
dependency into its Docker image. Its include list is an allowlist rather than
a wildcard: most integrations' existing tests resolve imports through their own
Next.js path aliases and only run under their own config, so sweeping them all
in would fail on arrival. Adding an integration to the list means first making
its tests runnable from the repo root.

The workflow runs that config on pull requests touching the integration agent
sources or their tests. It does not pass --passWithNoTests, so an include list
that stops matching fails the job rather than reporting an empty success, and
it interpolates no discovered filenames into a shell command, since a fork
controls the file names in this tree.
2026-09-04 23:42:10 +02:00
Ran Shem Tov 927ceb7817 fix(showcase): make the Strands stub modules importable as packages
The instrumentor test serves `strands.*` stubs through a meta-path finder,
but the import machinery reads the parent module's `__path__` BEFORE it
consults any finder, so every submodule import died with "'strands' is not
a package" and the finder never ran. It only ever passed because earlier
test modules left `agents.*` cached in `sys.modules`, which skipped the
`from strands... import` lines entirely.

Adding `build_reasoning_agent()` at agent_server import time broke that
accident: its `from strands.models.openai_responses import ...` sits inside
the function body, so module caching cannot hide it and the whole suite
went red.

Give the three package-like stubs (`strands`, `strands.models`,
`strands.types`) an empty `__path__` so the finder is reached, and drop the
stub entries from `sys.modules` afterwards so the real-package probe later
in the file does not inherit a `strands` whose empty `__path__` hides the
installed submodules.

Suite is now green both as a whole and file by file, which it was not
before on either this branch or main.
2026-09-04 23:37:03 +02:00
Manfred Steyer 603bdb4e12 Update showcase/shell-docs/src/content/reference/angular/components/CopilotActivity.mdx
Co-authored-by: Rainer Hahnekamp <rainer.hahnekamp@gmail.com>
2026-09-05 00:02:56 +03:00
Ran Shem Tov 9a12dcc345 fix(showcase): close the second review round on the Strands interrupt demos
Cancel handling was asymmetric in both languages: the TypeScript-shaped
sentinel was only recognised on the outer envelope, so a cancel that arrived
wrapped as {"response": {"status": "cancelled"}} was reported to the model as
"did not pick a time". Both tools now check the sentinel at both levels, and
the test matrix covers the shape it missed (three cases fail without the fix).
The TypeScript tool also coalesced the label with ?? where Python uses or, so
an empty label swallowed a valid time; both now fall back the same way.

Frontend and probes:

- The headless resume waited on a single animation frame, which never fires in
  a background tab, stranding the run. A timer races it and the resume fires
  once, whichever lands first.
- The picker latches after the first answer, so a second click cannot race the
  resume already in flight.
- A rejected resume now replaces the green "Booked" badge with a failure state
  instead of leaving a success the user never got.
- The headless probe searched the whole page for booking words, which the
  demo's own static copy already satisfies; it now reads assistant bubbles only
  and matches phrases the page does not contain.
- The pick-path spec asserted a bubble was visible, which the pre-pause bubble
  already satisfies; it now asserts the post-resume narration. The headless
  spec scopes the picker to the app-surface pane, which is the contract it
  claims to hold.

Prose and fixtures:

- The dedicated-mount rationale named the wrong tool: the in-chat demo
  registers book_call, and the real collision is the shared agent's own
  immediate schedule_meeting. Corrected in the parity notes and both tools.
- The TypeScript integration no longer cites Python API names, and the picker
  no longer cites a slot generator that does not exist.
- The shared docs no longer describe a hook the embedded snippet does not
  show, no longer place a standard interrupt's payload on event.value, and
  carry the correct RUN_FINISHED outcome shape.
- The d4 fixture edits are back to UTF-8 literals, dropping 86 lines of
  re-encoding noise so only the six intended key changes remain.
- The agent package exposes a test script, so the new unit test is runnable.
2026-09-04 23:00:27 +02:00
Ran Shem Tov 922ce030dd fix(showcase): correct the Strands interrupt resume path and its coverage
Review pass over the native-interrupt work. The load-bearing fix is the
resume envelope: the TypeScript tool read only the shape the Python bridge
produces, so a valid time pick came back to the model as "user did not pick
a time" and the meeting was never scheduled. Reproduced at the wire on a
real model, fixed with a normaliser that accepts both the wrapped and the
raw payload, and covered by a unit test that fails when the read is reverted.
The Python tool had the mirror-image gap and is fixed and tested the same way.

Also in this pass:

- Both demo pages read the interrupt payload without throwing during render,
  and a rejected resume is surfaced instead of leaving a green "Booked" badge.
- The e2e specs asserted the pre-pause assistant bubble, so a broken resume
  passed; they now assert the last bubble, plus a cancel-path narration guard.
- Fixture legs that gated on turn number now gate on whether the tool has
  already answered, matching the reference integration, and two bare D4 keys
  that shadowed D6 prompts are narrowed.
- The reasoning parameter is Responses-API only and the reasoning model id no
  longer reaches the Anthropic or Bedrock branches.
- Stale prose corrected in the parity notes, the setup docs, the shared
  human-in-the-loop pages, both probe docblocks and the agent server docstring.
2026-09-04 22:22:09 +02:00
Benjamin Taylor 28a19ddfa2 docs: document controlling the chat open state from your own UI
Leads the "Open, close, and feedback" page with the `open` /
`onOpenChange` pair and an example driving the sidebar from a nav button
outside it, which is the case #3334 asked about. The existing
`useCopilotChatConfiguration` route stays, now framed as the option for
callers who would rather not lift the state.

Also corrects `defaultOpen` on the CopilotSidebar and CopilotPopup
reference pages: both documented `false`, but both surfaces mount open.
2026-09-04 15:12:11 -05:00
Benjamin Taylor 3672d007ae docs(showcase): document frontend-driven activity cards, lock the behavior with a test
Activity messages (role: "activity") already render standalone in the
transcript and are stripped from the run payload by
AbstractAgent.prepareRunAgentInput, so frontend code can put a card in the
chat without a tool call and without polluting the conversation. That was
only ever documented for backend-emitted activities, so the frontend-driven
path was undiscoverable — issue #3388 asked for a feature that already ships.

Adds a Generative UI guide page for the pattern and a react-core test that
pins both halves of the contract: the card renders, and it never reaches the
agent.

The non-obvious part, and the reason this needs documenting rather than a
one-line answer: the card must be added via the agent from useAgent(). An
agent instance constructed and held outside React is not the instance the
chat renders, so messages added to it silently never appear.

Refs #3388

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 15:05:30 -05:00
Mike Ryan 37703eb083 Support Intelligence over the single Runtime route (#6896)
## Summary

- carry Intelligence thread, memory, and annotation requests through the
single Runtime endpoint
- advertise the bridge through an optional Runtime info capability
- reuse the existing REST route matcher, handlers, method checks, hooks,
and memory gate
- route Core memory and React annotation calls through the negotiated
Runtime fetch
- make single-route the documented Intelligence quickstart while keeping
multi-route supported

## Compatibility

- Multi-route behavior does not change.
- A new client uses the bridge only when a single-route Runtime
advertises it.
- An old client ignores the new optional capability.
- A new client keeps the old behavior with a Runtime that does not
advertise the capability.

## Validation

- `pnpm nx run-many -t check-types,build
--projects=@copilotkit/shared,@copilotkit/core,@copilotkit/runtime,@copilotkit/react-core`
- package pre-commit gate: tests, `publint`, and `attw` passed for all
affected packages
- Runtime focused suite: 102 tests passed
- Core focused suite: 108 tests passed
- React focused suite: 53 tests passed
- React full suite: 1,591 Vitest tests and 47 script tests passed
- Angular and React memory tests: 18 tests passed
- docs type-check and production build passed
- changed docs contract tests: 33 tests passed

## Local baseline notes

The full docs test command also reads Git LFS images and generated
cross-framework fixtures. It has six unrelated failures in this
checkout: three image-pointer checks, two Angular content checks, and
one Mastra content check. The changed docs tests pass, and the docs
production build passes.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added single-route support for thread, memory, and annotation
operations.
- Runtime capability discovery now advertises single-route resource
support.
- Resource requests preserve paths, query parameters, headers, methods,
and request bodies.
- Memory and annotation operations consistently use the configured
runtime transport.

- **Documentation**
- Updated setup guides for single-route configuration, capability
negotiation, and compatibility.
  - Added guidance for single-route LangGraph deployments.

- **Tests**
- Added coverage for transport behavior, validation, resource
operations, and error handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-04 11:33:44 -07:00
Tyler Slaton e1a6225afc docs: streamline Learning workflow explanation 2026-09-04 20:09:01 +02:00
Tyler Slaton b0035f2b78 docs: simplify Intelligence Learning guide 2026-09-04 20:09:01 +02:00
Tyler Slaton ff3dbd2922 docs: clarify Intelligence Learning guide 2026-09-04 20:09:01 +02:00
Tyler Slaton f08ff8e926 docs: document Intelligence Learning 2026-09-04 20:09:01 +02:00
Tyler Slaton df104edff4 docs(intelligence): document Memories and recall (#6854)
## Why

Memories ships and is entitlement-gated, but has no conceptual or
activation
documentation on the public site.

The only existing coverage is the Angular headless guide, which shows
`injectMemories` without explaining what a memory is, and the Angular
public API
reference. There is nothing for React, nothing on the three kinds or the
scope
model, and nothing on what a deployment needs before the memory surfaces
exist
at all.

That last gap is the expensive one. A self-hosted operator reasonably
looks for
a `memory.enabled` value or a `MEMORY_ENABLED` variable, finds neither,
and has
no way to discover that access is granted by entitlement and that the
embedder
must be configured separately at startup. This is an initial pass at
closing
that, offered ahead of the planned docs work rather than instead of it.

## What the page covers

An explanation page at `/intelligence/memories`, following the structure
and
voice of `threads-explained.mdx`:

- What a memory is, and how it differs from a thread in lifetime and
purpose
- The three kinds (`topical`, `episodic`, `operational`), and that dedup
and
  supersession are same-kind operations, so the kind is not cosmetic
- `user` and `project` scope, with `user` as the platform default
- That saving a near-duplicate absorbs it into the existing memory
rather than
  creating a second one
- That update is a supersede and a **full replacement**, including that
omitting
  `sourceThreadIds` resets rather than preserves them
- That removal retires rather than erases
- Activation: entitlement for self-hosted and managed, the four embedder
variables, the fail-loud startup behaviour, the pgvector requirement,
the
  bundled in-cluster embedder and the external-provider switch
- That changing the embedding model changes the vector space, so it is a
  migration rather than a config change
- The React (`useMemories`), REST, and MCP surfaces

## Validation

Every claim is taken from the implementation, not from intent. Notably:

- Activation is resolved through the license/entitlement checker,
fail-closed,
  and `memory` ships in the enterprise plan
- The embedder variables, the mandatory 1024 dimensions, and app-api's
refusal
  to start without valid configuration
- Route list, request limits (`content` 8192 chars, `sourceThreadIds`
100
entries, recall `limit` default 5 capped at 20), strict rejection of
unknown
fields, and the exact response shape (`id`, `kind`, `scope`, `content`,
`sourceThreadIds`, plus `score` on recall and `invalidatedAt` on the
list)
- `useMemories` semantics for `isAvailable` and `realtimeStatus`, and
the
supersede and retire behaviour, which match what the Angular guide
already
  documents

Checks run:

- `npm run pretypecheck` in `showcase/shell-docs`; the page indexes as
  "Memories & Recall" under the Intelligence section at
  `/docs/intelligence/memories`
- Pre-commit `check-intelligence-env-names` passes, which independently
confirms
  the documented environment variable names are canonical
- All in-page links point at paths already used elsewhere in the docs. I
deliberately did not link a generated `injectMemories` reference URL,
since no
such page exists in content; the Angular guide and public API reference
are
  linked instead

## Notes for review

- I used `feature="learning"` on `IntelligenceOnboardingPrompt`, because
the
component's feature union is `"learning" | "threads"` and adding a third
value
felt out of scope for a docs change. Happy to add `"memories"` if you
would
  rather it read that way.
- The Inspector memory surface is deliberately not described, only
referenced,
  since that UX is changing.
- Nothing in the existing Angular guide is contradicted; where we
overlap, the
  wording agrees.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Added documentation for the Memories & Recall feature, including
memory types, scopes, recall behavior, updates, and removal.
* Documented activation requirements and configuration for managed and
self-hosted deployments.
* Added guidance for using memories with React, Angular, REST, and MCP
integrations.
* Added the Memories page to the Intelligence documentation navigation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-04 20:08:38 +02:00
Mike Ryan 840bfa8c8b docs(runtime): document Intelligence single-route support 2026-09-04 10:36:27 -07:00
Ran Shem Tov 85ceb8721e feat(showcase): run the AWS Strands interrupt demos on the native interrupt
Both Strands showcase columns claimed no interrupt support and drove their two
interrupt demos through a frontend tool with an async handler. Both AG-UI Strands
bridges implement the AG-UI interrupt protocol on top of Strands' own interrupt
primitive, so the demos now use it.

- Dedicated interrupt agents whose schedule_meeting tool pauses itself with
  tool_context.interrupt(...) / context.interrupt(...), mounted on their own
  sub-path because hitl-in-chat registers a FRONTEND tool of the same name.
- interrupt-headless rebuilt on useInterrupt({ renderInChat: false }), replacing
  a hand-rolled subscriber that only matched LangGraph's legacy interrupt shape.
- Quarantine lifted, interrupt_pattern is native, and the prose claiming Strands
  has no interrupt primitive is corrected.
- reasoning-default, reasoning-custom and tool-rendering-reasoning-chain were
  registered under deprecated ids and pointed at agent names the runtime never
  registered; they now run against dedicated Responses-API agents with reasoning
  summaries enabled.
- Fixture repairs: interrupt keys that matched neither pill prompt, generic legs
  gated on turn position rather than on whether the tool had answered, and two
  short D4 keys that shadowed D6 prompts.
- Shared probes: the interrupt turns settle on the picker mounting instead of
  assistant-text stability, which an interrupt turn never produces.
- Pins raised to ag_ui_strands 0.3.0, strands-agents 1.54.0, openai 2.54.0 and
  @strands-agents/sdk 1.16.0.
2026-09-04 19:28:03 +02:00
Benjamin Taylor c99db2d80d docs(integrations): state the JSON-string context contract on every agent-app-context page (OSS-1134)
`useAgentContext` calls `JSON.stringify` on any non-string `value` before the
run leaves the browser, because the AG-UI protocol types `Context.value` as
`z.string()` on both ends. The reference pages say so since b18f7054af, but the
integration guides -- the pages a reader actually follows -- did not, and they
walked the reader straight into the trap: register `colleagues`, an array of
objects, then read `.get("value")` and interpolate it into an f-string, which
hides the type completely because a JSON string formats without complaint.

A reader who wants `colleagues[0]["name"]` gets a single character instead, and
the failure reads as "the frontend sent nothing" -- indistinguishable from an
empty context.

Every one of the eight variants now carries the same callout before its first
code sample, from one shared snippet so the wording cannot drift. Three pages
(adk, crewai-flows, pydantic-ai) already stated the contract, but only after
their first code sample, where a reader skimming to the code misses it.

The examples now show the round trip honestly rather than hiding it:

- langgraph Python parses with `json.loads` and then reads `c["name"]`, so the
  reason to parse is visible.
- langgraph TypeScript parses with `JSON.parse`. Its `find` predicate was also
  `'The current user\'s colleagues"'` -- a stray quote that could never match
  any description -- so the example could not have worked as printed.
- mastra passed the already-encoded value back through `JSON.stringify`,
  producing double encoding. It now parses instead.
- ag2 returned the raw string from `get_readable` at three sites, one of them
  annotated `-> list[dict]`, which the function never returned.

Documentation only. The wire format does not change: the string is the protocol.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:02:26 -05:00
deepshekhardas 4c08471c56 fix(showcase): port sales-analyst pills to 8 declarative-gen-ui demos
The OSS-136 sales-analyst rework migrated the D6 fixtures but left the
demo page pills on the pre-OSS-136 KPI set in 8 integrations. Port the
4 canonical sales-analyst pills from the langgraph-python reference so
the pills match what the fixtures answer.

Fixes #6791.
2026-09-04 14:07:30 +05:30
Tyler Slaton 03b436ed31 fix(ci): resolve local tsx for promote import test 2026-09-03 16:11:24 -07:00
Tyler Slaton 2623fdd361 fix(docs): improve dark accent contrast 2026-09-03 15:10:30 -07:00
Tyler Slaton b7be798709 fix(docs): restore quickstart table of contents 2026-09-03 15:04:59 -07:00