Removes obsolete workarounds and uses MAF's native primitives where the
framework supports them. Surfaces the genuine gaps as targeted shims.
Reasoning
- delete the no-op `think` tool; configure `reasoning={effort,summary}`
on the Agent default_options. AG-UI bridge already emits real
REASONING_MESSAGE_* events from the Responses API.
- bump `@ag-ui/client` 0.0.43 -> 0.0.52 so the frontend event schema
includes REASONING_MESSAGE_* (0.0.43 was still on the deprecated
THINKING_TEXT_MESSAGE_* union).
- reasoning-block.tsx -> consume ReasoningMessage via the
`messageView.reasoningMessage` slot; default-render demo strips
its `useRenderTool(think)` and uses zero-config CopilotChat.
Multimodal
- delete the frontend LegacyConverterShim that rewrote modern
`{type:"image"|"document", source:...}` parts to legacy `binary`.
MAF's AG-UI adapter handles the modern shape natively.
- delete the pypdf extraction subclass; gpt-5.2 reads PDFs natively
via OpenAI's `input_file`. Drop `pypdf` from requirements.
- retain a tiny 30-line `_MultimodalAgent` + adapter monkey-patch
that copies `metadata.filename` into Content.additional_properties
so OpenAI's `input_file` requirement is satisfied (upstream gap
in agent_framework_ag_ui._message_adapters._parse_multimodal_media_part).
A2UI dynamic
- fix the flat ops shape bug in `build_a2ui_operations_from_tool_call`:
middleware expects v0.9 nested `{createSurface:{surfaceId,catalogId}}`,
not flat `{type:"create_surface",surfaceId,...}`. Flat shape silently
fell back to surface group "default" and never rendered.
- secondary structured-output call: use chat_client.client (underlying
AsyncOpenAI) directly to bypass MAF's function-invocation auto-loop;
inherits api_key + model from the parent. response_format=PydanticModel
is unsuitable (strict-mode rejects open dicts); a one-shot raw-args
primitive doesn't exist in agent_framework today.
- inject the registered A2UI catalog schema (49KB of Zod types) from
`input_data.context[]` into the secondary call's system prompt so the
LLM emits correct prop names. _A2UIDynamicAgent captures the schema
on each run().
- switch the OUTER agent to OpenAIChatCompletionClient. Responses API
+ tool calls + multi-turn fails ("No tool output found for function
call ...") because reasoning items can't be replayed; chat.completions
replays tool history cleanly.
- defensive _reorder_tool_messages shim: the CopilotKit frontend message
store ships [user, tool, assistant(toolCalls), assistant, user] on
turn 2 (tool BEFORE its parent assistant), which OpenAI rejects.
Walk inbound messages and re-attach tool messages immediately after
their matching assistant.toolCalls[].id. (Should be fixed upstream
in @copilotkit/react-core/v2.)
- tighten the render_a2ui JSON schema (minItems:1, explicit
items.properties, strict:false) and the prompt header so gpt-5.x
actually emits non-empty components with entry-level props.
- same A2UI bypass replacement in agent.py + beautiful_chat.py (shared
pattern, three call sites of the original `from openai import OpenAI`).
Model bump
- default OPENAI_CHAT_MODEL_ID -> gpt-5.2 (Responses-capable reasoning
model). Scoped clients: reasoning agent on gpt-5.2 + Responses;
a2ui_dynamic on gpt-5.2 + chat.completions (avoids reasoning replay).
Upstream gaps surfaced (recommend follow-up PRs)
- agent_framework_ag_ui: propagate part.metadata.filename to
Content.additional_properties["filename"] in
_parse_multimodal_media_part. (Removes the PDF subclass.)
- agent_framework: a one-shot tool-args API
(e.g. get_response(..., auto_invoke=False)) or a cleanly exported
RawOpenAIChatClient. (Removes the A2UI raw-SDK bypass.)
- @copilotkit/react-core/v2: stop reordering role=tool messages
before their assistant parent in the frontend message store.
(Removes the A2UI message-reorder shim.)
Recent feature commits added new dependencies to integration package.json
files (@copilotkit/voice, @hashbrownai/{core,react}, @json-render/{core,react})
and bumped Next.js from 15.4.10 to 15.5.15, but never regenerated the
corresponding package-lock.json. The Showcase Build & Deploy workflow runs
`npm ci --legacy-peer-deps` which strictly enforces lock sync, so every
deploy attempt has been failing at the install step. No new images have been
pushed to GHCR, so Railway services have stayed on stale code and any cell
added since each fw's last successful deploy iframes 404.
Regenerated all 18 lockfiles via `npm install --legacy-peer-deps
--package-lock-only --ignore-scripts` per integration. Verified each with
`npm ci --dry-run --legacy-peer-deps` — all clean.
Refs PDX-90.
The showcase framework directories better reflect their role as
integration examples rather than distributable packages.
Renames showcase/packages/ -> showcase/integrations/ and updates
the test docker-compose file reference accordingly.