## What does this PR do?
This PR fixes build failures on Windows by replacing Unix-only shell
commands (`rm -rf`, `cp`, `mkdir -p`) in `package.json` scripts with
cross-platform Node.js `fs` built-in commands.
This follows the project's existing codebase pattern for cross-platform
operations, as seen in `packages/react-ui/package.json` (line 45).
### 🛠️ Changes:
- **`packages/runtime`**: Replaced `rm -rf` in `generate-graphql-schema`
with `fs.rmSync`.
- **`packages/vue`**: Replaced `cp` in `build:types` and `rm -rf` in
`clean` with `fs.cpSync` and `fs.rmSync`.
- **`packages/angular`**: Replaced `mkdir -p` and `cp` in `build:css`
with `fs.mkdirSync` and `fs.cpSync`.
- **`examples/v1/next-openai`, `next-pages-router`, `state-machine`**:
Replaced `rm -rf` clean commands with a single Node.js loop that deletes
`.turbo`, `node_modules`, `dist`, and `.next`.
All modified packages now build successfully on Windows.
## Related PRs and Issues
- Closes#5601
## Checklist
- [x] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [ ] If the PR changes or adds functionality, I have updated the
relevant documentation
- [x] "Allow edits by maintainers" is checked (lets us help iterate on
your PR directly — faster turnaround for everyone)
Adds /a2ui-catalog page and a runtime endpoint with NO a2ui config, so
A2UI switches on purely from the provider's a2ui.catalog (the #5774
path). Also fixes DemoButtonAgent, which never actually rendered: it
emitted the wrong activity content key (operations -> a2ui_operations)
and a non-canonical operation/component format. Rewritten to the A2UI
v0.9 wire format (createSurface/updateComponents, flat components, root
id "root") so the surface paints and the Confirm round-trip works.
Same class as the toggle-theme fix: langgraph-js's 'schedule a meeting' chip
returned text, so the meeting picker never rendered, while langgraph-python emits
the scheduleTime tool call. scheduleTime is a registered langgraph-js frontend
tool (reasonForScheduling/meetingDuration) — swap text -> tool call, mirroring
langgraph-python. Because scheduleTime is Human-in-the-Loop (the user's pick
returns as a tool result and re-invokes the LLM), add a terminating
call_schedule_time_001 result fixture in BOTH templates so the turn doesn't
re-match the user message and loop (langgraph-python lacked it too — latent).
Verified both terminate at 2 steps (tool call -> terminating text).
The langgraph-js Toggle Theme chip returned a text response claiming it toggled
the theme, but emitted no tool call -- so the theme never changed, while the same
chip in langgraph-python emits the toggleTheme frontend tool call and works.
Identical chip, different outcome by template. Swap the text response for the
toggleTheme tool call, mirroring langgraph-python (frontend tool, no terminating
result fixture needed -> no loop). Verified aimock now returns the toggleTheme
tool call for the chip.
The chart-chain fixtures looped under multi-step tool execution: langgraph-python
emitted a 2nd tool call (pieChart/barChart/dashboard) with no terminating
toolCallId result fixture, so it fell through to the still-matching userMessage
fixture and re-called query_data. langgraph-js had its toolCallId result fixtures
ordered after the userMessage fixtures (first array match wins -> re-call).
Add the missing terminating result fixtures (langgraph-python) and reorder so all
toolCallId fixtures precede userMessage fixtures (langgraph-js). Verified termination
via the 2-3 step multi-turn repro; mastra fixtures already terminated.
The 6 OpenAI drop-in integration examples enabled for the CLI's keyless
AIMock mock mode shipped fixtures that did not cover the prompts each
starter's own UI suggests, so a keyless first-run user clicking the demo
suggestions mostly hit the generic catch-all. Re-key/extend each
example's fixtures/default.json (substring, most-specific-first,
catch-all last) so the surfaced suggestions return scripted replies.
ENT-1003.
Ports two fixes from the canonical oracle-cookbook demo into the oracle-agent-memory
showcase agent (server.py was byte-identical to the demo's pre-fix version):
1. Dangling tool-calls: booking conversationally calls the book_flight HITL tool,
which interrupts and emits an assistant tool_call awaiting the UI's Confirm/Cancel.
If the traveler sends another chat message instead, the unanswered tool_call made
the next turn 400 ("tool_call_ids did not have response messages"). _repair_dangling_tool_calls
synthesizes a "not completed" tool result for any dangling call before the history
reaches the graph. (Inverse of the duplicate-tool-block issue the history-replace
already handled — documented in docs/known-issues/agentspec-multiturn-toolcall-correlation.md.)
2. HTML-escaped persistence: the agentspec exporter HTML-escapes streamed deltas
(& < > -> & < >); the SSE generator persisted them raw, so assistant
replies were stored in Oracle Agent Memory as e.g. "fares < $700".
_clean_assistant_text html.unescapes the assembled text before persisting.
Both are reproduced + verified in oracle-cookbook (unit tests + in-browser); the ported
functions are byte-identical to the verified demo code.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Flag-gated (LANGGRAPH_CHECKPOINTER=oracle, default memory) AsyncOracleSaver from
langgraph-oracledb for durable per-thread LangGraph graph state in Oracle,
complementing oracleagentmemory. Default-safe (in-memory fallback). Mirrors
jerelvelarde/oracle-cookbook#4. Draft, stacked on #5563.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The StateStore interface and the in-memory MemoryStore default remain;
durable backends can be reintroduced as a follow-up. Both adapter packages
were merged in #5613 but never published to npm, so removal is a clean
delete with no consumer impact.
- Delete packages/bot-store-redis and packages/bot-store-postgres.
- Revert the bot release scope and drift guard to bot + bot-ui.
- Strip the Redis dep, demo:restart script, restart demo, docker-compose,
and REDIS_URL env from examples/slack.
- Rewrite the bot persistence/transcripts docs around "MemoryStore default
+ implement the StateStore interface yourself for durability".
Sync the three travel-concierge UX fixes from the source repo
(jerelvelarde/oracle-cookbook#3) into the showcase:
- agent/concierge/server.py: persist memory in a serialized background task so
the SSE stream closes at RUN_FINISHED instead of blocking ~2-13s on memory
extraction + reconciliation (the post-generation loading lag). Adds a FastAPI
lifespan drain + background-task failure surfacing.
- frontend/.../FlightOptions.tsx: "Select this flight" now drives confirm -> book
entirely client-side, so the booking confirm card renders inline in view
instead of off-screen via a fresh agent turn. The conversational book_flight
HITL path is unchanged.
- frontend/e2e: add a covering test for the inline booking flow; rename
sendAndPersist -> sendAndAwaitRun (stream-close is no longer a "memory written"
signal now that persistence is backgrounded).
oxfmt --check + tsc --noEmit clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds examples/teams: a runnable Teams bot built on @copilotkit/bot-teams.
Demonstrates rendering charts from uploaded CSV files, inbound file
handling over the Graph API, and human-in-the-loop confirmation flows,
plus the Teams app manifest and packaging scripts.
The triage runtime connected its MCP clients with Promise.all, so a single
unreachable/misconfigured server (bad key, sidecar down, hang) rejected the
whole run and surfaced as a fatal "⚠️ Agent error: Failed to connect to
MCP server" — the bot was dead for every request, even ones needing no MCP.
Connect each server independently (Promise.allSettled) with an 8s timeout,
drop the ones that fail, and let the agent run with whatever's left (web search,
rendering, thread reading, and any MCP that did connect). A per-turn system note
lists any down sources so the model only tells the user a source is unreachable
if they actually ask for it, and never invents data. Connections are retried
each turn, so a transient outage self-heals.
Repairs TypeScript check-types across the monorepo and adds a CI gate so
regressions are caught going forward:
- core: bundler module resolution and strict-mode fixes
- sdk-js: bundler module resolution; keep codegen, formatter, packaging working
- react-core: fixes across components, hooks, and tests
- react-native: restore catch binding referenced by TypeError cause
- runtime: repair check-types and bound AI SDK schema inference
- web-inspector: nodenext import extensions, export Anchor
- remaining packages and node example: assorted check-types repairs
- deps: add missing type-only devDependencies
- license context driven from /info licenseStatus
- ci: run check-types in the static quality workflow
Squashed from 12 commits for a single, easily-revertable change.
## What does this PR do?
Routes the Gemini canvas stack analyzer through its registered `end`
node instead of directly to LangGraph's `END` sentinel.
This keeps the workflow wiring consistent with
`workflow.set_finish_point("end")` and ensures the cleanup/final state
emission in `end_node` is reachable.
## Related PRs and Issues
- Fixes#5605
## Tests
- `python3.12 -m py_compile examples/canvas/gemini/agent/stack_agent.py`
- `python3.12 - <<'PY' ... PY` (AST check that
`workflow.add_edge("analyze", "end")` exists and
`workflow.add_edge("analyze", END)` does not)
- `. /tmp/oss-pr-pipeline/langgraph-venv/bin/activate && python - <<'PY'
... PY` (LangGraph topology reproduction asserts `analyze -> end ->
__end__` and that `end_node` runs)
- `. /tmp/oss-pr-pipeline/langgraph-venv/bin/activate && python - <<'PY'
... PY` (imports `stack_agent.py` with CopilotKit/Gemini stubs and
asserts compiled `stack_analysis_graph` edges include `analyze -> end`
and not `analyze -> __end__`)
- `git diff --check`
## Checklist
- [x] I have read the [Contribution
Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md)
- [x] If the PR changes or adds functionality, I have updated the
relevant documentation (not applicable: example graph wiring bug fix)
- [x] "Allow edits by maintainers" is checked (lets us help iterate on
your PR directly — faster turnaround for everyone)
Add per-feature demos to examples/slack that narrate per-platform degradation
explicitly rather than failing silently:
- emoji triage — 🐛/🔥/✅ reactions file/escalate/ack via the agent
- /preview — ephemeral draft issue (native only-you on Slack, DM fallback on
Discord/Telegram)
- /file-issue — modal form (Slack rich, Discord text-only, Telegram
conversational fallback)
Also updates the Slack frontend guide (slack.mdx) with the capability matrix.
The aisdk + tanstack agents expose a needsApproval bookFlight tool; /interrupts renders interrupts in-chat via useInterrupt(renderInChat) with a reusable InterruptCard and single/multiple suggestion pills. Requires OPENAI_API_KEY.
Adds a durable persistence layer for @copilotkit/bot, replacing the
in-memory-only ActionStore with a pluggable StateStore.
- StateStore interface (kv/list/lock/dedup/queue) with a shared
conformance suite; MemoryStore default plus @copilotkit/bot-store-redis
and @copilotkit/bot-store-postgres backends.
- createBot({ store }): typed per-thread state via Standard Schema,
action snapshots persisted through the store, per-conversation turn
lock (onLockConflict drop|force), and inbound-event dedup keyed on a
stable eventId. ActionStore is kept as a deprecated alias.
- Cross-platform transcripts (bot.transcripts + identity resolver) with
age-bounded retention (prune on append + filter on read), and
runAgent({ transcript: true }) to auto-inject history and capture the
reply.
- createBot({ components }) re-registers components so durable actions
re-fire after a restart; restart-durability demo in examples/slack.
- Dedup is marked seen only after the turn lock is acquired, so a turn
dropped on lock-conflict does not burn its eventId (no lost retries).
- Release lockstep: bot-store-redis/postgres version with bot + bot-ui.
The standalone showcase installs with `npm install` (Nixpacks does this
automatically when there's no lockfile; the README already uses npm install).
Removing the 16.6k-line lockfile also clears the fork-pr-monitor security
alert, which flagged it as a "large added file." Verified: a fresh
`npm install` + `next build` succeeds with no committed lockfile.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The build script enumerated bot-slack/bot-discord/runtime, so it silently
omitted bot-telegram and bot-whatsapp — deploying with TELEGRAM_*/WHATSAPP_*
secrets would fail at runtime because those adapters' dist/ was never built
(start runs via tsx against the workspace packages' compiled output).
Use the nx project glob '@copilotkit/bot*' (+ runtime) so every bot adapter,
including any added later, is built without editing this script.
## What
Brings `@copilotkit/bot-slack` up to the **current** Slack native
streaming API surface (`chat.startStream` / `appendStream` /
`stopStream`, GA Oct 2025; structured chunks + AI feedback elements) and
removes the type-erasure workarounds. Result of an audit
cross-referencing the live `@slack/web-api@7.16.0` /
`@slack/types@2.21.1` types and Vercel's `vercel/chat` Slack adapter.
## Changes
- **No more `as unknown as Parameters<…>` casts** — every
streaming/post/update call uses the SDK's typed args.
- **One streamed message per turn** — dropped the per-message
continuation splitting (Slack documents only a 12k-per-append limit, no
cumulative cap; matches `vercel/chat`), keeping ≤12k per-append
chunking.
- **Native `task_update` tool-progress chunks** (`task_display_mode:
"timeline"`) interleaved into the streamed reply, replacing the separate
`🔧` status messages — with automatic degradation back to
`🔧` rows where structured chunks aren't supported.
- **Opt-in AI feedback buttons** via `slack({ feedback })` — a typed
`context_actions` + `feedback_buttons` row attached at `stopStream`;
clicks are routed adapter-locally (bypassing the engine's interaction
dispatch). No handler ⇒ no buttons.
- **Recipient scoping** — `recipient_user_id` / `recipient_team_id` only
for channel targets.
- **Cadence** — native flush floor lowered to ~600ms (appendStream
Tier-4); legacy `chat.update` stays 800ms.
### Engine (`@copilotkit/bot`)
One small, backward-compatible addition: optional
`RunRenderer.finish?()`, called after `runAgentLoop` resolves, so a
turn-scoped renderer can finalize its single stream. No-op for existing
adapters.
## Verification
- `bot-slack`: type-check (both tsconfigs) clean, **208 tests pass**,
oxfmt + oxlint clean.
- `bot`: type-check clean, **33 tests pass** (incl. a new `finish()`
test).
- Reviewed for correctness (stream lifecycle, finish/interrupt
interaction, delta tracking, degradation) — no high-confidence bugs;
feedback-on-interrupt and missing-ref-logging were tightened.
### Not verifiable without a live workspace (flagged in-code)
- That a >12k reply truly streams into one message (the
no-cumulative-cap assumption).
- `startStream` with no initial content.
## What
Removes the live-consumed local Intelligence overlay and the dead
references the deletion would leave behind.
- Deletes `examples/integrations/_intelligence/` (`docker-compose.yml`,
`.env.intelligence`, `README.md`) — the overlay the currently-shipped
CLI clones at runtime.
- Strips the now-dangling `# see
examples/integrations/_intelligence/.env.intelligence for the seed
value` pointer from 8 integration `.env.example` files (adk, agno,
langgraph-fastapi, langgraph-js, langgraph-python,
ms-agent-framework-{dotnet,python}, strands-python).
Closes ENT-834.
## ⚠️ DO NOT MERGE until launch
The **currently-shipped** CLI clones
`CopilotKit/CopilotKit@main:examples/integrations/_intelligence` at
runtime via `fetchIntelligenceOverlay` (hardcoded to `main`). Deleting
this dir from `main` **immediately breaks** the shipped CLI's
threads-framework `init` — the overlay fetch 404s.
**Merge gate (verify at merge time):**
- [ ] The managed-only CLI build has **dropped
`fetchIntelligenceOverlay`** (Intelligence-repo removal ticket)
- [ ] That managed-only CLI has been **released**
- [ ] Merge in lockstep with launch
## Scope
- ✅ **Included:** the `_intelligence/` overlay dir + the 8 dead
`.env.example` pointers it leaves behind.
- ✅ **Already done elsewhere:**
`examples/integrations/langgraph-python-threads/` (the ticket's "maybe"
scope) was already removed via ENT-800 — it is no longer on
`origin/main`.
- ⏭️ **Deferred to a launch-coordinated follow-up:** the local-stack
`INTELLIGENCE_API_URL`/`GATEWAY_WS_URL` defaults (`localhost:4201` /
`ws://localhost:4401`) baked into ~18 `copilotkit:intelligence` route
blocks + `agentcore/docker/docker-compose.yml`, and the matching
local-dev block in each `.env.example`. These depend on the managed
CLI's hosted env contract (Intelligence repo) and shouldn't be guessed
at now. The `copilotkit license` locked-state copy is owned by ENT-804.
## Not affected
The `docker-compose.test.yml` + `docker/Dockerfile.{agent,app}` files
across the integrations are the **e2e/CI test harness** for the example
apps, unrelated to the Intelligence pivot. The Threads feature, the
activation-gated `copilotkit:intelligence` block, and the themed
threads-drawer UI are the product and work against hosted Intelligence —
only the local-stack scaffolding is being removed.
## Notes
Branched off fresh `origin/main` (`c540734143`). No in-repo code
references the overlay dir (the `_intelligence` matches under
`packages/` are an unrelated private field on the agent registry).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The build script only built bot-slack, bot-discord, and runtime, so
@copilotkit/bot-telegram (plus bot and bot-ui) were never compiled — the
Railway deploy then crashed on `import { telegram } from @copilotkit/bot-telegram`.
Build every workspace package the app imports.
Resolve event-renderer.ts onRunFinishedEvent: keep the native turn stream open
(finalized in finish()) AND retain the legacy per-message stream drain from main
(#5573) as a no-op-in-native safety net. app/index.ts (telegram adapter from
#5520 + showToolStatus:false) and create-bot.test.ts auto-merged.
Bump @tanstack/ai-openai 0.14.4 → 0.15.2 (pins @tanstack/openai-base 0.8.7,
TanStack/ai#790) and @tanstack/ai → 0.32.0. 0.8.7 emits strict:false for tool
schemas outside OpenAI's strict subset in the provider-path function-tool
converter, so MCP tools (e.g. Notion's API-post-search) no longer 400 — no
local patch needed. Verified end-to-end against the live Slack bot.
- runtime.ts: pass the bridge's forwarded client tools (convertInputToTanStackAI's
tools) into chat() alongside web_search + MCP, so generative-UI cards and the
confirm_write HITL gate work; drop the prompt line that made the model narrate
charts with a trailing "Charting …" sentence (it landed after the image).
- render-chart / render-diagram: post the caption as a header BEFORE the image
(a file upload's message lands a beat after postFile resolves, so caption-first
keeps a stable caption → image order) and drop the false "rendered above" wording.
Depends on the @copilotkit/runtime factory tool-lifecycle fix (#5572) and the
bot-slack HITL/render-order fix (#5573).
The example's runtime agent needed OpenAI's hosted `web_search` tool, but
BuiltInAgent's classic `tools` only accepts handler-based `ToolDefinition[]`
(needs `execute`) — it can't carry a provider/hosted tool. So switch the
agent to BuiltInAgent **factory mode** (`type: "tanstack"`) and drive it with
TanStack AI's `chat()`:
- `openaiText(model)` adapter (OpenAI Responses API; gpt-5.5 default)
- `webSearchTool({ type: "web_search" })` provider tool (`@tanstack/ai-openai/tools`)
- Linear/Notion MCP via `@tanstack/ai-mcp` `createMCPClient` (HTTP + bearer),
created per-run; `chat()` discovers their tools and closes the connections
- `convertInputToTanStackAI(ctx.input)` bridges AG-UI input → `chat()`;
BuiltInAgent converts `chat()`'s stream back to AG-UI events
OpenAI-only now (web search is OpenAI-specific); AGENT_MODEL accepts a bare
OpenAI id or an "openai/<id>" form. Adds @tanstack/ai, @tanstack/ai-openai,
@tanstack/ai-mcp to the example.