Commit Graph

12110 Commits

Author SHA1 Message Date
Maxim 2169cc9383 fix(sdk): widen AG-UI dispatcher args validation to match emitter contracts
The AG-UI dispatcher's ManuallyEmitToolCall handler rejected non-dict,
non-string args with CopilotKitMisuseError, but all three emitters
(JS, Python LangGraph, Python CrewAI) accept any JSON-serializable
value. This mismatch caused JS-emitted list/number args to crash the
Python dispatcher.

Replace the strict isinstance(dict, str) check with a None guard and
rely on the existing json.dumps try/except for serializability.

Call-site enumeration:
- langgraph_agui_agent.py:129 — changed from isinstance check to None guard
- test_emit_tool_call_optional_id.py — updated test_missing_args_raises match,
  test_non_serializable_args_raises match, converted test_list_args_raises and
  test_int_args_raises from negative to positive tests
- No other call sites reference the removed isinstance pattern

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:26 +02:00
Maxim 570bcf4264 fix(sdk): remove dead try/except in emit_message, drop unused imports in sdk.py
Remove no-op `try/except CancelledError: raise` around asyncio.shield
in copilotkit_emit_message (the shield handles cancellation on its own).
Remove unused CopilotKitError and CopilotKitMisuseError imports from
sdk.py (already re-exported via __init__.py).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:26 +02:00
Maxim f434418df5 fix(sdk): restore batched queue_put for atomicity, fix end_dispatched flag ordering
The split queue_put calls introduced interleaving risk (6 yield points
vs 2) and the end_attempted flag was set before the END dispatch,
causing the compensating END to be skipped when END itself failed.

- CrewAI: restore single batched queue_put(start, args, end) call;
  compensating END is now unconditional on batch failure
- AG-UI agent: rename end_attempted → end_dispatched, set after
  successful END dispatch so compensation fires for all failure modes
- Tests: rewrite CrewAI compensating tests for batch semantics,
  add test_failure_on_end_emits_compensating_end for AG-UI agent

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:25 +02:00
Maxim 90de3cef88 fix(sdk): wrap dispatch errors instead of mutating, fix duplicate-END, use UUID for tool call IDs
- Replace JS error.message mutation with wrapped Error + cause chain
  (safe for frozen errors, shared references, non-Error throwables)
- Rename dispatched_end → end_attempted, set before END dispatch to
  prevent duplicate TOOL_CALL_END when END partially flushes before throwing
- Switch JS randomId() (ck-prefixed) to randomUUID() for cross-SDK parity
  with Python's str(uuid.uuid4())

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:25 +02:00
github-actions[bot] 40a4fe6d73 style: auto-fix formatting 2026-05-20 00:18:25 +02:00
Maxim d395501de0 fix(sdk): enrich JS dispatch errors, shield emit_message, standardize validation order
- Wrap JS dispatchCustomEvent in try/catch that enriches error messages
  with tool name and ID for debuggability
- Apply asyncio.shield to copilotkit_emit_message's post-dispatch sleep
  to match copilotkit_emit_tool_call's behavior under task cancellation
- Reorder validation in LangGraph Python and JS to name → toolCallId →
  args, matching CrewAI's order (cheap checks before serialization)
- Narrow AG-UI dispatcher's except clause around json.dumps from
  Exception to (TypeError, ValueError), matching sibling SDK variants
- Add CancelledError propagation and warning-log tests for the shielded
  sleep path

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:24 +02:00
github-actions[bot] 4f81dc38e5 style: auto-fix formatting 2026-05-20 00:18:24 +02:00
Maxim e1da79a5ea fix(sdk): fix CancelledError swallow, dispatched_end ordering, add JS args validation
- Re-raise CancelledError after logging in langgraph copilotkit_emit_tool_call
  to honor asyncio cancellation contract (was silently un-cancelling tasks)
- Move dispatched_end flag to after ToolCallEndEvent dispatch in AG-UI agent
  so compensating END fires when END itself throws
- Add dispatched_end tracking to CrewAI variant to prevent double-END on
  partial failure
- Add JSON.stringify(args) validation in JS SDK matching Python parity
- Add 4 CrewAI compensating-END tests and 1 JS serializability test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:24 +02:00
Maxim 4a6d364e2c fix(sdk): harden error handling, revert args strictness, shield sleep
Address code review findings across all three SDK variants:

- Shield asyncio.sleep(0.02) with asyncio.shield() so task cancellation
  doesn't prevent returning the tool_call_id after dispatch
- Revert args validation to original permissiveness (JS: undefined-only
  check, Python: no isinstance check) to avoid breaking existing callers
- Add upfront json.dumps() serializability check in Python variants
- Fix compensating TOOL_CALL_END double-emit by tracking dispatched_end
- Add compensating action_execution_end to CrewAI variant (queue_put is
  non-atomic)
- Use exc_info=True in compensating-END error logging
- Export all exception types from copilotkit package root (__init__.py)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:23 +02:00
Maxim 62a3164aab fix(sdk): add @returns JSDoc and compensating-END test coverage
Add missing @returns tag to JS copilotkitEmitToolCall JSDoc, and add
4 tests for the AG-UI compensating TOOL_CALL_END error-recovery path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:23 +02:00
github-actions[bot] 1df8a80e58 style: auto-fix formatting 2026-05-20 00:18:23 +02:00
Maxim be9b60c8a9 fix(sdk): harden AG-UI dispatch, add exception hierarchy, fix docstrings
Address code review findings:
- Wrap AG-UI tool call dispatch in try/except with compensating
  TOOL_CALL_END to prevent clients hanging on partial emission
- Reject non-dict/non-str args at the dispatch layer (lists, ints, None)
- Guard against None event value before calling .get()
- Fix docstring examples that reuse variable names (won't compile)
- Introduce CopilotKitError base class; all exceptions now inherit from
  it; CopilotKitMisuseError inherits from both CopilotKitError and
  ValueError
- Add missing validation tests for name and args across LangGraph and
  CrewAI Python variants, plus AG-UI dispatch edge cases

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:22 +02:00
github-actions[bot] d5cc135c5c style: auto-fix formatting 2026-05-20 00:18:22 +02:00
Maxim 9cb8996056 fix(sdk): harden validation, error types, and dispatch safety across SDKs
Address code review findings: stop mislabeling dispatch errors as
CopilotKitMisuseError in JS (let them propagate naturally), add
CopilotKitMisuseError(ValueError) to Python SDK, pre-serialize args
in AG-UI handler to prevent partial event emission, align whitespace
validation across all SDKs and the dispatch layer, tighten JS args
type to Record<string, unknown>, and add comprehensive negative tests
for AG-UI dispatch validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:21 +02:00
github-actions[bot] 6fb417a90a style: auto-fix formatting 2026-05-20 00:18:21 +02:00
Maxim 50301b7bf0 fix(sdk): restore error type, rename options.id, add validation parity
- Restore CopilotKitMisuseError for dispatch failures in JS (was bare Error)
- Rename JS options.id to options.toolCallId for cross-SDK naming parity
- Add name/args validation to Python LangGraph and CrewAI variants
- Add defensive field validation in AG-UI dispatch handler
- Add missing CrewAI whitespace-only ID test
- Add JS dispatch failure test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:21 +02:00
Maxim 09ede29d58 fix(sdk): align whitespace validation, improve error handling and docs
Align JS whitespace-only ID rejection with Python (.trim()), show
returned ID in docstring examples, strengthen CrewAI test assertions
to verify event payloads structurally, and stop miscategorizing
dispatch errors as CopilotKitMisuseError (preserve original stack).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:20 +02:00
github-actions[bot] d2070b7b5f style: auto-fix formatting 2026-05-20 00:18:20 +02:00
Maxim c7693e938e fix(sdk): validate id param, rename to tool_call_id, use options bag in JS
Address review feedback on copilotkit_emit_tool_call:
- Add non-empty string validation for the tool call ID in all 3 SDKs
- Rename Python `id` param to `tool_call_id` to avoid shadowing the builtin
- Refactor JS 4th positional arg to options bag `{ id?: string }` for extensibility
- Document that the ID is also used as parentMessageId in AG-UI events
- Add JS tests for the new parameter (generated ID, custom ID, validation)
- Add Python validation tests (empty string, whitespace rejection)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:20 +02:00
github-actions[bot] 174be4f355 style: auto-fix formatting 2026-05-20 00:18:19 +02:00
Maxim 865991b463 feat(sdk): add optional id parameter to copilotkit_emit_tool_call
Allow callers to supply a custom tool call ID for correlation,
idempotency, and observability. Falls back to uuid4 when omitted.
Applied consistently across Python LangGraph, Python CrewAI, and JS SDK.
Also returns the tool call ID from all variants for downstream reference.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 00:18:19 +02:00
Tyler Slaton 00af36c472 docs(showcase): worker prompt and baseline-split helper for Phase 1 blitz
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 14:08:09 -07:00
Tyler Slaton 504e025b6d feat(showcase): register A2UI, MigrateTo{1100,182,V2}, SelfHosting stubs in mdx-registry
All 5 missing stubs now map to their existing shell-docs partials in
STUB_PARTIAL_MAP and are exported from docsComponents via stubWithPartial.
No new partial files needed — all backing .mdx files already exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 14:05:10 -07:00
Tyler Slaton fc364337c9 feat(showcase): add v1 component mapping table + legacy shim barrel
Maps all 77 JSX components from the Phase 0 audit to either
use-existing (74 entries) or shim (5 entries: A2UI, MigrateTo1100,
MigrateTo182, MigrateToV2, SelfHosting). Creates the legacy/index.ts
barrel scaffold that Task 13 will populate with shim implementations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 13:59:31 -07:00
Ran Shemtov c2d2046d73 chore: renovate aws strands canonical demo (#4730) 2026-05-19 22:57:35 +02:00
Tyler Slaton 8508073bd3 feat(showcase): add essential-content checklist and wire into verifier
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:47:10 -07:00
Tyler Slaton c63161018a fix(showcase): strip route-group segments in shell-docs verifier known-routes
Fumadocs/Next.js route groups like (other) are stripped from URL paths, so
a file at (other)/telemetry.mdx is served at /telemetry. loadKnownRoutes()
now filters those segments before registering routes, eliminating false-positive
dead-link failures for pages inside route-group directories.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 13:44:28 -07:00
Tyler Slaton a251e21126 feat(showcase): shell-docs verifier CLI runs all checks against real repo state
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 13:41:49 -07:00
Tyler Slaton c573fd0622 feat(showcase): verifier checks @/snippets and @/components import paths 2026-05-19 13:36:34 -07:00
Tyler Slaton c485ec8981 feat(showcase): verifier checks internal markdown links against known routes 2026-05-19 13:36:04 -07:00
Tyler Slaton 4a56b958dc feat(showcase): verifier checks <Snippet> regions against demo-content 2026-05-19 13:35:32 -07:00
Tyler Slaton 11a351d4b9 feat(showcase): verifier checks <InlineDemo> ids against registry 2026-05-19 13:34:56 -07:00
Tyler Slaton b0a370b41b docs(showcase): clarify REPO_ROOT derivation in shell-docs verifier 2026-05-19 13:32:58 -07:00
Tyler Slaton 52ffd2ee8a feat(showcase): scaffold shell-docs verifier with nx build check
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:31:07 -07:00
Tyler Slaton de9ecd32cc fix(showcase): make docs-porting audit resilient to unreadable MDX files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:29:18 -07:00
Sam Julien d38cfecb5c docs(shell-docs): tighten telemetry opt-out copy + useAgent API rename (#4905)
## Summary

Two surgical pickups from a closed auto-sync PR, applied directly to
shell-docs (the post-cutover canonical authoring location).

**1. `telemetry/index.mdx`** — collapse three opt-out paragraphs into a
single tighter sentence, and add the Inspector dev-console to the scope
of what `COPILOTKIT_TELEMETRY_DISABLED` covers.

**2. `snippets/use-agent.mdx`** — three independent improvements:
- `agent.id` → `agent.agentId` (current v2 API field name).
- New `<Callout>` pointing out that `useAgent({ agentId })` is required
when not using CopilotKit Cloud's public access/license key.
- `subscribe()` `useEffect` cleanup gets `[agent]` in the deps array
(exhaustive-deps; prevents stale subscriber after the agent reference
changes).

## What was deliberately skipped

The auto-sync also wanted to rewrite `@copilotkit/shared/v2` →
`@copilotkit/shared` in `use-agent.mdx`. The `/v2` subpath was
deliberately restored as the V2 canonical-form import — left alone here.

## Test plan

- [ ] CI green
- [ ] Spot-check rendered `/telemetry` page locally / on Railway preview
— opt-out paragraph reads cleaner
- [ ] Spot-check rendered `/{any-framework}/use-agent` — Callout renders
inside the `<Steps>` flow, `agent.agentId` displays where the Agent ID
line was, dependency array shows `[agent]`
2026-05-19 13:27:54 -07:00
Sam Julien fd21473fbd fix(shell-docs): backport Deep Agents + Agent Spec as hidden placeholders, repoint CTA, add redirects (#4833)
## Summary

External QA flagged that Deep Agents and Agent Spec are documented in
shell-docs but neither has shipped as a showcase integration. Both have
orphaned MDX in the dead `src/content/docs/integrations/*/` tree (which
the framework router doesn't serve), and the live
`/whats-new/langgraph-deep-agents` page had a CTA pointing at
`/langgraph/deep-agents` which 404s.

This PR backports both as **live placeholder pages, hidden from sidebar
navigation and framework pickers**, ready to be revealed in nav when the
showcase integrations are built. It also re-points the broken CTA at the
new canonical URL and adds legacy URL redirects.

Supersedes PR #4832 (which only removed the CTA).

## What changed

### New live placeholder pages

- `/deepagents` — full Deep Agents documentation, content adapted from
the upstream `integrations/langgraph/deep-agents.mdx` (the
self-referential "promoted to top-level integration" Callout removed
since this *is* the destination now)
- `/agent-spec` — Agent Spec landing
- `/agent-spec/quickstart`
- `/agent-spec/langgraph`
- `/agent-spec/wayflow`
- `/agent-spec/human-in-the-loop`

All six new MDX files are at
`showcase/shell-docs/src/content/docs/{deepagents,agent-spec}/`.

### Hiding mechanism

The framework router (`[framework]/[[...slug]]/page.tsx`) falls through
to `UnscopedDocsPage` when `getIntegration(slug)` returns `undefined`.
Neither `deepagents` nor `agent-spec` is in `registry.json` (since
neither has showcase integration code), so they automatically take this
fall-through path and `loadDoc()` resolves the MDX. No registry entries
needed.

- Sidebar nav: pages are not listed in any `meta.json`, so
`buildNavTree()` (which iterates `meta.json` `pages` arrays) silently
omits them
- Framework picker / `<IntegrationGrid>`: pulls from `registry.json`,
which only contains integrations with manifests under
`showcase/integrations/`. Neither placeholder is in the registry —
neither surfaces in pickers
- Existing `<IntegrationGrid exclude={["agent-spec", ...]}>` calls
remain no-ops (the grid renders a static link, not a registry-driven
list) — no behavior change

### CTA fix

`whats-new/langgraph-deep-agents.mdx` CTA now points at `/deepagents`
(was: `/langgraph/deep-agents`, 404).

### Redirect entries

Two new `LEGACY_CHAINS_EXACT` rules in `src/lib/seo-redirects.ts`:

- `L12`: `/langgraph/deep-agents → /deepagents`
- `L13`: `/langgraph-python/deep-agents → /deepagents`

Together these catch the legacy-slug upstream URL (`/langgraph/...`) and
the post-slug-rename path that the existing rename system would
otherwise produce (`/langgraph-python/...`). Both land on the canonical
placeholder.

No new redirects are needed for Agent Spec — `agent-spec` is already in
the `FRAMEWORKS` array, and the subpath-rename redirects it generates
now resolve to live placeholder pages rather than 404s.

## Future evolution

When the Deep Agents or Agent Spec showcase integration ships:

1. Add a manifest at `showcase/integrations/{integration}/manifest.yaml`
(or wherever new integrations register)
2. The registry regenerates, the framework picker surfaces the
integration, sidebar nav surfaces its pages
3. The placeholder content can be replaced with real demo-linked content
and the redirects remain valid

## Files changed

- `showcase/shell-docs/src/content/docs/deepagents/index.mdx` (new, 370
lines)
- `showcase/shell-docs/src/content/docs/agent-spec/index.mdx` (new, 54
lines)
- `showcase/shell-docs/src/content/docs/agent-spec/quickstart.mdx` (new,
509 lines)
- `showcase/shell-docs/src/content/docs/agent-spec/langgraph.mdx` (new,
114 lines)
- `showcase/shell-docs/src/content/docs/agent-spec/wayflow.mdx` (new,
114 lines)
-
`showcase/shell-docs/src/content/docs/agent-spec/human-in-the-loop.mdx`
(new, 119 lines)
-
`showcase/shell-docs/src/content/docs/whats-new/langgraph-deep-agents.mdx`
(1 line — CTA repoint)
- `showcase/shell-docs/src/lib/seo-redirects.ts` (15 lines — two new
redirect entries)

## Test plan

- [ ] `/deepagents` renders the Deep Agents documentation
- [ ] `/agent-spec`, `/agent-spec/quickstart`, `/agent-spec/langgraph`,
`/agent-spec/wayflow`, `/agent-spec/human-in-the-loop` all render
- [ ] Neither page appears in the sidebar nav on any framework
- [ ] Neither integration appears in the framework picker or in
`<IntegrationGrid>` listings
- [ ] `/whats-new/langgraph-deep-agents` CTA points at `/deepagents` and
lands on the placeholder
- [ ] `/langgraph/deep-agents` 301s to `/deepagents`
- [ ] `/langgraph-python/deep-agents` 301s to `/deepagents`

## Hook bypass

Pre-commit `test-and-check-packages` fails on a pre-existing
`@copilotkit/web-inspector` telemetry test on main (jsdom not installed
in fresh worktrees). Commits used
`LEFTHOOK_EXCLUDE=test-and-check-packages` to bypass only that one hook;
lint-fix, commitlint, sync-lockfile, and check-binaries all ran and
passed.
2026-05-19 13:27:28 -07:00
Tyler Slaton 245a77e768 feat(showcase): add CLI entry for docs-porting audit and run end-to-end
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:26:25 -07:00
github-actions[bot] 2843f61581 style: auto-fix formatting 2026-05-19 20:25:47 +00:00
Tyler Slaton e4b52861a5 fix(showcase): strip code blocks and dedup snippet imports in MDX reference extraction
Fenced code blocks are now stripped before extracting JSX component
references so samples inside ``` blocks don't get counted as real
component refs. snippetImports is deduplicated via a Set consistent
with how components are handled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 13:24:15 -07:00
Ran Shem Tov 6389d5111b chore: refresh showcase validate-pins hash after main merge 2026-05-19 15:23:01 -05:00
Tyler Slaton 23f562afb5 feat(showcase): extract MDX component refs and snippet imports in porting audit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:21:42 -07:00
Tyler Slaton 9a74927635 fix(showcase): normalize line endings and clean up tempdirs in docs-porting audit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:19:51 -07:00
Tyler Slaton 3e4eac44d9 feat(showcase): add per-framework page diff to docs-porting audit 2026-05-19 13:16:04 -07:00
Tyler Slaton ef991db232 fix(showcase): export READY_SLUGS and drop brittle length assertion in docs-porting audit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:13:51 -07:00
Tyler Slaton aef5637aa6 feat(showcase): scaffold docs-porting audit script with unready-framework enumeration 2026-05-19 13:10:42 -07:00
Ran Shemtov bf7898c446 Merge branch 'main' into chore/upgrade-strands-integration-demo 2026-05-19 19:27:50 +02:00
github-actions[bot] a3654c3f08 style: auto-fix formatting 2026-05-19 17:04:12 +00:00
Alem Tuzlak 393b75facb feat(showcase/ms-agent-python): LGP parity sweep — 33/37 cells green (#4924)
## Summary

Brings `ms-agent-python` to one-to-one parity with `langgraph-python`
(the D5 north star). Playwright e2e suite goes **from 49/108 (~26%) →
164/178 (~92%)**, **33 of 37 cells fully green**.

| | Before | After |
| --- | --- | --- |
| ✅ Green cells | ~5 | 33 |
| Tests passing | 49 / 108 | 164 / 178 |
| Pass rate | ~26% | ~92% |

## Highlights

**Manifest parity:** dropped 4 MAF-only cells with no LGP analog
(`agentic-chat-reasoning`, `hitl-in-chat-booking`, `shared-state-write`,
`reasoning-default-render`), renamed `byoc-hashbrown` →
`declarative-hashbrown` and `byoc-json-render` →
`declarative-json-render` to match LGP. Ported LGP `_shared/`,
`_shared/interrupt-fallback-slots.ts`, and `demos/layout.tsx`.

**Cells ported verbatim from LGP** (page + e2e spec): every shared cell
— agentic-chat, auth, beautiful-chat, chat-customization-css,
chat-slots, declarative-*, frontend-tools*, gen-ui-*, headless-*,
hitl-in-*, shared-state-*, subagents, tool-rendering* (4 variants),
a2ui-fixed-schema, agent-config, mcp-apps, multimodal, open-gen-ui*,
prebuilt-*, readonly-state-agent-context, reasoning-*, voice.

**Chat client swap.** `OpenAIChatClient` (Responses API) →
`OpenAIChatCompletionClient`. Root cause of the cross-cell post-tool
ChatClientException family: Responses is stateful, sends only NEW items
per leg, relies on `previous_response_id`. aimock has no view of
server-side state, so second-leg requests arrived without the user
message — fixture matchers keyed on `userMessage` couldn't fire and runs
fell through to real OpenAI. ChatCompletions sends full history every
leg, matching LGP's wire shape. The reasoning agent is the one exception
(kept on Responses since it needs the `reasoning_summary_text.delta`
event path).

**`@ag-ui/client` `^0.0.43` → `^0.0.53`** (matches google-adk/LGP).
Fixes the REASONING_* Zod discriminator trap. Lockfile regenerated in
isolation.

**Six new / re-added MAF agent backends mirroring LGP behavior:**

| File | LGP reference | FastAPI path |
| --- | --- | --- |
| `reasoning_agent.py` | `reasoning_agent.py` | `/reasoning` |
| `tool_rendering_agent.py` | `tool_rendering_agent.py` |
`/tool-rendering` |
| `gen_ui_agent.py` | `gen_ui_agent.py` | `/gen-ui-agent` |
| `shared_state_streaming.py` | `shared_state_streaming.py` |
`/shared-state-streaming` |
| `readonly_state_agent_context.py` | same |
`/readonly-state-agent-context` |
| `headless_complete_agent.py` | `headless_complete.py` |
`/headless-complete` |

State-bearing agents (`gen_ui_agent`, `shared_state_streaming`) use
MAF's `state_update(text=..., state={...})` (equivalent of LGP's
`Command(update={...})`) plus `predict_state_config` for per-token
tool-arg streaming.

**A2UI tool rename** `render_a2ui` → `_design_a2ui_surface` across
`tools/generate_a2ui.py`, `tools/__init__.py`, and
`src/agents/{a2ui_dynamic,agent,beautiful_chat}.py`. LGP renamed to
avoid the A2UI middleware's auto-bypass; shared d5-all.json fixtures key
responses on the new name. Also patched 4 declarative-gen-ui aimock
fixtures to pass `context` arg in the first-leg `generate_a2ui` call
(`agent_framework` doesn't auto-inject `AgentSession` into our `@tool`
function so `session=None`, and the secondary-LLM `user_content` was
defaulting to a catch-all string that matched the KPI fixture for every
pill).

**Test infrastructure:** capped local `workers: 4` + `retries: 1`. CI
keeps `workers: 1, retries: 2`. `agent_framework.Agent` instance is
reused across requests and the shared OpenAI HTTP client serialises
concurrent SSE streams; >4 workers makes 30s timeouts inevitable for a
handful of cells. Hard-data: workers=1 serial = 164 passed (16.8 min);
workers=4+retries=1 = 164 passed (7.2 min); workers=undefined parallel =
159 passed. Same green set, ~2x faster. Long-term upstream fix is
per-request `Agent(...)` instantiation in `agent_framework_ag_ui`.

## Remaining 14 failures (4 cells)

Documented per-cell in [the Notion D5 sweep
doc](https://www.notion.so/3653aa38185281479e37dbf3569ababa) with
specific next-pass actions:

- `declarative-gen-ui` (2) — A2UI surface activity not mounting in DOM
despite correct payload arriving. Suspected `@copilotkit/*@next`
(1.55.2-next.1) vs LGP's 1.57.1 version mismatch in the A2UI renderer.
- `multimodal` (4) — image/PDF attachment forwarding not wired in
`multimodal_agent.py`.
- `tool-rendering-default-catchall` (6) +
`tool-rendering-reasoning-chain` (4) — multi-leg chain fixture chaining;
needs aimock-log traces per chain.

## Test plan

- [x] Run `BASE_URL=http://localhost:3114
../../harness/node_modules/.bin/playwright test --reporter=line` from
`showcase/integrations/ms-agent-python` — 164 passing, 14 failing, 7
skipped.
- [x] Verified each of the 5 "flaky-under-parallel-load" cells
(`agent-config`, `agentic-chat`, `gen-ui-tool-based`, `auth`,
`beautiful-chat`) passes 100% in isolation.
- [x] Confirmed `workers: 1` serial vs `workers: 4` + `retries: 1`
produce the same pass set (164).
- [x] Manual headed Playwright walkthrough of every newly-green cell.
- [ ] CI green (depends on the test-infra changes landing cleanly in the
CI env).

Migration tracking: [MAF migration
doc](https://www.notion.so/3643aa38185281e4bdc8fd8972e56b5f) · [D5 sweep
+ next-pass
plan](https://www.notion.so/3653aa38185281479e37dbf3569ababa)
2026-05-19 18:53:41 +02:00
Ran Shem Tov 00ce3a9332 chore: ratchet showcase baseline to 95 + sync strands lockfile 2026-05-19 11:45:34 -05:00