Copy updated tool-rendering-default-catchall.spec.ts and
frontend-tools.spec.ts from LGP. Also update page.tsx to import
useSuggestions() from ./suggestions (same fix as LGP).
tool-rendering-default-catchall: page.tsx had inline 3-pill config but
suggestions.ts exists with 4 pills (including "Chain tools"). Switched
page.tsx to import useSuggestions() from ./suggestions so all 4 pills
render, matching the test expectations.
frontend-tools: test used stale selectors ("background-container",
"var(--copilot-kit-background-color)", "Change background" pill) that
didn't match the actual demo code. Updated test to use the real
data-testid ("frontend-tools-background"), real default ("#4f46e5"),
and real pill names ("Sunset/Forest/Cosmic theme").
Rename byoc-hashbrown -> declarative-hashbrown and
byoc-json-render -> declarative-json-render across demo directories,
API route directories, manifest.yaml feature/demo IDs, runtime
endpoint paths, agent names, and page header text to match the
langgraph-python reference integration.
Internal graph IDs (byoc_hashbrown, byoc_json_render) and agent
source files (src/agent/byoc-hashbrown.ts) retain their names,
matching how LGP keeps byoc_hashbrown_agent.py internally.
The e2e tests already expected /demos/declarative-* routes, so this
resolves the 404 mismatch.
Fix heading assertions to match actual demo headings ('Sidebar demo'
and 'Popup demo' instead of the longer inline-pattern versions).
Use JS-level .click() to bypass cpk-web-inspector overlay that
intercepts Playwright pointer events on localhost (same pattern
as harness probes in _genuine-shared.ts:clickByJs).
Copy all 37 LGP test files to LGT verbatim, replacing the 10
existing LGT-specific tests and adding 27 new ones. Delete
shared-state-write.spec.ts which has no LGP counterpart. The
LGT demo pages have already been aligned to match LGP's UI,
testids, and selectors, so LGP's tests should work as-is.
@langchain/openai places tool_calls from mixed content+toolCalls responses
into additional_kwargs.tool_calls (not top-level .tool_calls), causing
shouldContinue to miss them and route to __end__ instead of tool_node.
Real OpenAI sends tool_calls with content: null — no mixing.
Note: 24 other d5-all.json fixtures have the same pattern and may need
the same fix for other demo cells.
matches SDK middleware
Replace the array-of-{value:string} extraction with the same logic used
by createAppContextBeforeAgent in CopilotKitMiddleware: treat context as
a string or JSON-serializable object, stringify it, and inject as a
separate "App Context:" system message after the main system prompt.
Fixes 2 of 9 remaining LGT cell failures (Who am I?, Suggest next
steps on the readonly-state-agent-context page).
Move "tool-rendering" from starterAgentNames (which maps to the generic
starterAgent graph) into the demoAgents section, mapping it to a new
tool_rendering graph ID that points to ./tool-rendering.ts:graph -- the
same backend as tool-rendering-default-catchall and
tool-rendering-custom-catchall.
Added tool_rendering entry to langgraph.json, server.mjs, and route.ts
so all three stay in sync.
Fixes 7 of 9 remaining LGT cell failures (Weather, Flights, Stock,
Dice, Chain suggestions on tool-rendering page; Find flights on both
default-catchall and custom-catchall).
1. Model: gpt-4o-mini -> gpt-5.4 to match LGP
2. System prompt: remove "helpful", use "Use the mock tools" to match LGP
3. get_stock_price: add optional price_usd/change_pct params for
deterministic test fixtures, matching LGP schema and return shape
4. get_weather description: remove extra "Useful on its own..." text
5. search_flights description: remove extra "Pairs naturally..." text
6. get_stock_price description: match LGP docstring explaining the
deterministic override pattern
7. CopilotKit integration: replace bare createReactAgent with full
StateGraph + CopilotKitStateAnnotation + convertActionsToDynamicStructuredTools
+ frontend action routing, matching the pattern used by all other LGT agents
Add recursionLimit: 50 to graph.compile() to match LGP's
.with_config({"recursion_limit": 50}). The prompt drives ~7 set_steps
cycles + 1 final model turn (~15 supersteps); 50 gives ~3x headroom
for LLM retries.
System prompt, tool schema (Step fields: id, title, status), and tool
description already match character-for-character.
The LGT readonly-state agent was ignoring copilotkit.context, so
useAgentContext values never reached the model. Now the chatNode
reads state.copilotkit.context entries and appends them to the
system message, matching what CopilotKitMiddleware does on the
Python side.
Also adds non-gated aimock fixtures in feature-parity.json for
both the "Who am I?" and "Suggest next steps" pills so they
match without requiring the Atai-specific systemMessage gate
that only fires when LGP's middleware is in play.
Fixes "message type returned from LangGraph is not supported" error
for search_flights. The dependency is transitive (via @copilotkit/runtime
and @copilotkit/sdk-js), so npm overrides are used to force 0.0.32.
Record-replay from LGT with real OpenAI key captures the exact request
format the LangGraph TS agent sends through the CopilotKit pipeline.
Covers Sales Dashboard (A2UI Dynamic), Calculator (Open Gen UI), and
Task Manager (Shared State) — all of which failed locally because
hand-written fixtures didn't match the LGT request format.
Also adds d5-recorded directory to docker-compose.local.yml fixture
loading so recordings replay automatically.
Sales Dashboard: add query_data turn-0 fixture and generate_a2ui
turn-1 fixture; remove hasToolResult:false from _design_a2ui_surface
and render_a2ui sub-fixtures so they match after query_data returns.
Calculator: add generateSandboxedUi fixture with metric shortcut
buttons (Revenue, Customers, Conv%, category breakdowns) plus
toolCallId response.
Search Flights: already covered by existing "flights from SFO to JFK"
fixture — no changes needed.