Commit Graph

13613 Commits

Author SHA1 Message Date
Alem Tuzlak db65524aad fix(channels-slack): clear the "is thinking" status on finish for tool-only replies
The run renderer only cleared Slack's native "is thinking…" assistant
status from onFirstReply() (streamed-text paths) or the error/interrupt
paths. A turn whose reply streamed NO text — a tool-only / file-only
reply such as a posted chart — never triggered onFirstReply, so the
status indicator lingered forever.

finish() now clears the status as a backstop when statusMode is on and
no reply was posted. The postedReply guard prevents a redundant clear on
the normal streamed-text path (onFirstReply already cleared it).

Adds regression tests covering both the tool-only clear and the
postedReply guard.
2026-07-16 12:55:57 -05:00
Alem Tuzlak a06c8cf1be feat(channels): canonical cross-platform reaction normalization for Teams & WhatsApp
Normalize inbound reaction emoji to a canonical cross-platform name at the
central channels-core ingress, so onReaction handlers match one value
regardless of provider.

- channels-ui/emoji: add "teams" and "whatsapp" to EmojiPlatform and canonical
  entries for refresh/laugh/surprised/sad/angry. Teams normalizes its
  <codepoint>_<name> emoji codes (1f504_refresh -> refresh) and classic bare
  names (like -> thumbs_up); an out-of-range codepoint degrades to passthrough
  instead of throwing. WhatsApp uses the unicode path like Discord/Telegram.
- channels-core: add teams+whatsapp to EMOJI_PLATFORMS; IncomingReaction gains
  an optional source `platform`; onReaction normalizes by
  evt.platform ?? adapter.platform.
- channels-intelligence: the managed reaction dispatch passes the delivery's
  source platform (env.platform) so managed reactions normalize too.
2026-07-16 12:55:57 -05:00
renovate[bot] e4feb44c7a chore(deps): update github actions 2026-07-16 17:55:19 +00:00
Tyler Slaton 3c1b991f7c fix(runtime): install managed Channels activation dependency (#6012)
## Summary

- make @copilotkit/channels-intelligence a direct runtime dependency
- remove the optional peer declaration that left managed Channels
consumers without the activation module
- add a package-metadata regression test

## Root cause

#5963 introduced managed Channels activation through a dynamic import,
then moved @copilotkit/channels-intelligence from an auto-installed
dependency to an optional peer. Package managers therefore omitted the
module while runtime activation still required it, causing Module not
found for consumers on runtime 1.63.0.

## Verification

- regression test fails on main and passes with this change
- packed runtime manifest resolves @copilotkit/channels-intelligence to
0.2.0 as a direct dependency
- affected package tests, publint, and attw passed; Nx marked one
initial Vue failure flaky and its unchanged rerun passed 1,071 tests
2026-07-16 10:54:37 -07:00
Sam Julien a010f33994 docs(shell-docs): add Threads overview (#5947)
## Summary

- turn `/threads` into a product-oriented overview that explains why
developers use CopilotKit Threads and routes them by job to Drawer,
Headless, import, architecture, and deployment docs
- label the overview as `Overview` in the Threads navigation while
retaining `Threads` as the page title
- move the existing custom UI implementation guide to
`/headless-threads` across root, generated, authored, and Built-in
framework surfaces
- present the architecture as a product-to-system story: what users
experience, the UI/runtime/agent pieces in the app, and Enterprise
Intelligence as the cloud-hosted or self-hosted Threads platform
- provide responsive desktop and mobile diagram assets in light and dark
modes, showing durable history, replay to live, realtime sync,
lifecycle, and locking
- move `Threads & Persistence Architecture` into the Threads navigation
group across all framework modes
- replace the standalone migration CTA with contextual prose that leads
naturally to `Import Thread History`
- replace ambiguous linked-card layouts with a comparison table,
explicit action links, and a conventional next-steps list
- migrate implementation-intent links to `/headless-threads` while
keeping product-level links on `/threads`
- correct the ADK Vertex importer project-variable reference
- add regression coverage for route availability, nav labels/order,
page-title separation, shared architecture placement, and
framework-aware link rewriting

## Authoring surfaces

- **Shared/root:** `src/content/docs/{threads,headless-threads}.mdx`,
shared overview and headless snippets, root `meta.json`, and responsive
light/dark diagram assets
- **Authored frameworks:** integration wrappers and navigation metadata;
shared navigation logic inserts the architecture page into each Threads
group
- **Generated frameworks:** shared root routes, snippets, and root
navigation; generated data files are not hand-edited
- **Built-in Agent:** authored wrapper plus the same shared navigation
injection
- **Cross-links/reference:** Drawer, import, CLI, architecture,
tutorials, and `useThreads` reference pages

## Routing and redirects

No redirect is added for the old `/threads` implementation URL because
`/threads` is intentionally reused by the new overview. Existing
external links to `/threads` now land on the product overview, and
internal links that specifically mean the custom `useThreads`
implementation guide have moved to `/headless-threads`. Framework-aware
link rewriting scopes both routes normally.

## Base

This PR targets `main` after #5915 merged. Its diff contains only the
Threads overview follow-up commits.

## Validation

- `npm run lint` (passes with existing repository warnings only)
- `npm run test` (32 files, 170 tests)
- `npm run typecheck`
- `npm run build` (214 static pages generated; existing Turbopack
tracing warning only)
- `git diff --check`
- SVG XML validation for both architecture assets
- live browser checks on root, Mastra, LangGraph Python, and Built-in
Agent routes
- light/dark diagram rendering and narrow/desktop layout passes
2026-07-16 10:52:17 -07:00
Martha Schumann 9e9ce128dd test(runtime): verify packed managed channels dependency 2026-07-16 10:44:10 -07:00
Martha Schumann e84eceffbf fix(release): exempt Channels transitive packages from age gate 2026-07-16 10:35:14 -07:00
Martha Schumann fea464de52 fix(runtime): install managed channels activation dependency 2026-07-16 10:27:31 -07:00
Jordan Ritter 8a0b829732 fix(showcase): harden async-wedge repro generator lane against false-green 2026-07-16 00:06:41 -07:00
github-actions[bot] 518cb42ef3 style: auto-fix formatting 2026-07-16 06:43:01 +00:00
Jordan Ritter c5695baf2d fix(showcase): offload sync anthropic LLM calls off the claude-sdk-python event loop
The claude-sdk-python agent :8000 wedges under D6/LLM load: two synchronous
anthropic.Anthropic().messages.create() calls run directly on the uvicorn
asyncio event loop, freezing it for the full LLM round-trip so /health stops
responding. The watchdog counts 3 consecutive failures (~90s) and kill-restarts
the container, dropping active sessions.

Root cause (sync-in-async), all in integrations/claude-sdk-python/:
- src/agents/agent.py: _execute_tool's generate_a2ui branch builds a sync
  anthropic.Anthropic() and calls messages.create() synchronously; invoked on
  the loop from run_agent's agentic loop AND from the Claude-Agent-SDK MCP tool
  handler in claude_agent_sdk_adapter.py.
- src/agents/a2ui_dynamic.py: _generate_a2ui, same sync pattern, invoked on the
  loop from the run_a2ui_dynamic_agent generator.

Fix: wrap every async call site in `await asyncio.to_thread(...)` (lowest blast
radius — the sync functions and the shared ExecuteTool callback type are
unchanged, and the whole tool-dispatch path is fixed uniformly, not just
generate_a2ui):
- agent.py run_agent call site
- claude_agent_sdk_adapter.py MCP tool handler
- a2ui_dynamic.py secondary call site

Blast radius: claude-sdk-python only. a2ui_dynamic.py is per-integration (each
framework has its own copy); every other claude-sdk-python agent already uses
AsyncAnthropic. The `tools` symlink to shared/python was not touched.

entrypoint.sh: drop the Slack alert from the :8000 agent watchdog branch (keep
the kill-restart — it self-heals silently now that the root cause is fixed);
keep the LOUD #oss-alerts page on the public $PORT /api/health branch.

Adds showcase/tests/repro/async-wedge/ — a faithful RED/GREEN harness driving
the real anthropic sync client against a controllable slow endpoint, plus a
mutation guard on the real _generate_a2ui.
2026-07-15 23:40:48 -07:00
Sam Julien e4db18b718 docs(shell-docs): refine Threads overview screenshot 2026-07-15 17:40:18 -07:00
Jordan Ritter 7abcd216dc fix(showcase): stop the claude-sdk-python stdout-backpressure event-loop wedge (#5987)
## What happened

The `claude-sdk-python` showcase column went fully red on **staging**
(37 cells, `BE ✗` cascading) while prod and the TypeScript sibling
stayed green on the same image. It wasn't 37 bugs — it was one wedged
replica.

**Root cause:** a D6 fan-out pushed the container's combined log volume
past Railway's ~500 logs/sec drain cap. `entrypoint.sh` pipes both
processes' stdout through an `awk` process-substitution, so Next.js's
`fd1` is a **synchronous pipe**; when Railway stopped draining, the pipe
filled and Next.js's next `console.log` blocked in `write(2)`,
**freezing the event loop**. Even the static `/api/health` went 502,
CPU→0, memory flat, process alive — so `restartPolicyType: ON_FAILURE`
never fired and `numReplicas: 1` meant one wedge reds the whole column.
Load-triggered, not a code/env diff.

Full analysis (root cause + mitigation trade-offs): Notion → *Showcase
stdout-backpressure wedge* under Plans / Proposals.

## The fix (two coordinated MUSTs)

Showcase's promise is preserved throughout — real D6 traffic, live page,
and full CVDIAG diagnostics all intact. Nothing is sampled or dropped.

- **MUST-1 — take the flood off stdout, losslessly.** Route CVDIAG's
per-LLM-call breadcrumb off stdout behind a new `CVDIAG_LOG_STDOUT` gate
(**default ON**, so every other integration is byte-for-byte unchanged);
the non-blocking PocketBase sink still receives every envelope at full
fidelity — which is the path `cvdiag classify` and the dashboard already
read from. `emit_cvdiag` now enqueues to PB **before** the stdout write
so a wedged fd1 can't cost the durable breadcrumb. `entrypoint.sh`
self-activates `CVDIAG_LOG_STDOUT=0` only when `CVDIAG_PB_URL` is wired
(safe: never silences stdout when PB isn't receiving). Plus uvicorn
`--no-access-log` to drop the access-log noise.
- **MUST-2 — detect and recover the hang, loudly.** Extend the watchdog
to poll the public `$PORT /api/health` and, on sustained failure, POST a
`#oss-alerts` Slack alert **before** kill-restarting — and add the same
alert to the agent-`:8000` branch. No silent recovery: every wedge
pages.

## Red → green proof

A docker `node:22-slim` repro (`showcase/tests/repro/stdout-wedge/`)
reproduces the real topology (same `awk` pipe, Railway-capped drain
reader, uvicorn+CVDIAG-shaped flood, static no-log `/api/health`
victim):

- **RED** (unmitigated): `/api/health` 200 → 502/timeout the instant the
flood crosses the cap; heartbeat frozen; CPU parked at 0. `200=6 /
WEDGE=11`.
- **GREEN** (flood cut below cap): health stays fast-200 across the
whole window; heartbeat advances. `200=16 / WEDGE=0`.
- `run.sh` asserts the outcome and **exits non-zero on a false result**
(a deliberately-forced false-GREEN exits 5, was exit 0 pre-fix).
- MUST-2: the actual `entrypoint.sh` watchdog loop, run verbatim against
a genuinely wedged port, detects → POSTs the captured alert → `kill -9`s
the real Next.js PID. `watchdog.sh` needle-anchors the public
probe/kill/alert against `entrypoint.sh` (mutating the probe fails the
test).
- Unit: `test_cvdiag_log_stdout_gate.py` — 5/5 incl. a hostile-stdout
durability test (RED: enqueue starved; GREEN: enqueue preserved). Full
`_shared` suite 19 passed / 2 skipped.

## Review

Tier-3 cr-loop (shared source + deploy config + kill path): 7-agent
review → adversarial per-finding verification → 5 mandatory fixes (all
red-green'd, isolated worktrees) → 7-agent confirmation round converged
to **zero mandatory findings** → bucket-(c) promotion audit
`PROMOTE_TO_A: 0`.

## ⚠️ Not merge-ready yet — draft on purpose

- [ ] **Staging branch-deploy validation** — local can't exercise the
one runtime unknown: that the container actually reaches
`showcase-pocketbase.railway.internal:8090` and lands a `cvdiag_events`
row. Must confirm on a staging deploy of this branch before merge.
- [ ] **Railway env wiring (out-of-band, human-gated):** set on
`showcase-claude-sdk-python` (staging + prod) —
`CVDIAG_BACKEND_EMITTER=1`,
`CVDIAG_PB_URL=http://showcase-pocketbase.railway.internal:8090`,
`CVDIAG_WRITER_KEY` (op:// in DevOps `showcase`),
`SLACK_WEBHOOK_OSS_ALERTS`. Without these MUST-1/MUST-2 stay inert
(safe: default is current behavior).
- [ ] Green CI.

## Follow-up (non-blocking, fail-safe)

Repro-harness polish (none false-GREEN-capable): GREEN heartbeat
assertion is timing-fragile under a raised start-delay (false-RED only);
`run.sh` local lane doesn't forward all tunables; `watchdog.sh`
webhook-assert race + helper-death flake; reader has no close handler on
the local lane. Pre-existing (bucket c): `OPENAI_API_KEY` warning is
mislabeled; Next.js has no readiness gate; `_SETUP_DONE` degrade-latch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-15 16:05:21 -07:00
Tyler Slaton 5c36df2099 chore: release monorepo v1.63.0 (#5992)
## Release monorepo v1.63.0

**Scope:** `monorepo` | **Bump:** `minor`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `monorepo` packages to `1.63.0`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `monorepo` packages to npm at version `1.63.0`
   - Creates git tag `monorepo/v1.63.0`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
v1.63.0
2026-07-15 15:27:42 -07:00
tylerslaton 6c354037fc chore: release monorepo v1.63.0 2026-07-15 22:18:07 +00:00
Tyler Slaton 5fa4f2813d fix(release): unblock Channels umbrella publish (#5990)
## Problem

The Channels v0.2.0 release publishes its dependency packages, then
fails before publishing the umbrella package because pnpm rejects the
freshly published dependencies under the 24-hour minimum release age
policy.

## Why

The registry-backed verifier installs the packed umbrella in an isolated
temporary consumer without carrying a Channels-family release-age
exemption into that consumer.

## Fix

Generate a pnpm workspace config for the isolated consumer that exempts
every Channels package while retaining the maturity gate for unrelated
dependencies. Add regression coverage for the complete family. Verified
with all 109 release-script tests, the registry-backed Channels
verifier, explicit lint/typecheck/format checks, and the full Nx package
build.
channels/v0.2.0
2026-07-15 14:26:45 -07:00
Tyler Slaton a5387831c0 fix(release): exempt Channels verifier from maturity gate 2026-07-15 14:11:44 -07:00
Ran Shemtov a233fff69f Merge branch 'main' into claude/brave-kirch-8dbf00 2026-07-15 23:06:05 +02:00
Benjamin Taylor 7edb6dbf19 docs: address adversarial review of threads-lifecycle guide
- History section: "Platform replay (the default)" → "Server-side replay",
  state the precondition (needs a server-side store — platform or a
  persisting AgentRunner; a bare runtime replays nothing), and use the
  correct method name connectAgent() (there is no agent.connect()).
- First-message thread creation (headless): fix a race — the example set
  the thread via setActiveThreadId() (a deferred React state update) then
  sent immediately, which lands on the previous thread; and truly-headless
  has nothing syncing agent.threadId. Now set agent.threadId directly and
  add a caveat explaining the state-setter timing.
- v1 notes: correct the setThreadId throw attribution — the useThreads
  setter silently shadows under a prop; the throwing setThreadId is the
  one on the main <CopilotKit> hooks.
- MCP Apps: drop the unverified "not persisted server-side" assertion;
  reframe as client-side re-derivation that restores via normal history
  replay.
- LangGraph: don't imply the linked persistence page proves the Platform
  UUID rule; loosen the checkpointer shorthand.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 15:55:57 -05:00
Tyler Slaton 45fa204843 chore: release channels v0.2.0 (#5989)
## Release channels v0.2.0

**Scope:** `channels` | **Bump:** `minor`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `channels` packages to `0.2.0`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `channels` packages to npm at version `0.2.0`
   - Creates git tag `channels/v0.2.0`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
2026-07-15 13:38:33 -07:00
Ran Shem Tov 0440c58106 docs(showcase/mastra): document OM-as-background-activity (OSS-391)
Short how-to section in background-tasks.mdx: enable Observational Memory on
the agent's Memory + opt in on the adapter (observationalMemory: true on
getLocalAgents), render via renderActivityMessages with activityType
mastra-observational-memory. Mirrors the working /demos/observational-memory
wiring. (--no-verify: worktree commitlint binary still broken post-crash.)
2026-07-15 13:36:41 -07:00
tylerslaton add6539dcd chore: release channels v0.2.0 2026-07-15 20:29:29 +00:00
Sam Julien c72b94db4b docs(shell-docs): cover rich Threads history 2026-07-15 13:19:51 -07:00
Sam Julien f6e4c9f8ad docs(shell-docs): elevate Threads screenshot frame 2026-07-15 13:16:31 -07:00
Benjamin Taylor 47aa0b1725 docs: add Thread & History Lifecycle guide
Adds a framework-agnostic guide covering the full client-side thread
lifecycle, filling a gap between the Headless Threads how-to and the
Threads & Persistence Architecture explanation:

- how a threadId is minted (UUID v4, client-side at mount) + the
  resolution precedence and the remount-stability caveat
- how history is restored (explicit-threadId connect() replay vs.
  manual agent.setMessages); notes v2 has no initialMessages
- switching/starting threads (setActiveThreadId / startNewThread) and
  the prop-controlled no-op guard
- intercepting thread creation on first message (mint-up-front vs. the
  headless onSubmitMessage seam; built-in <CopilotChat> overrides it)
- CopilotKit threads vs. framework checkpointers (two layers correlated
  only by threadId; a checkpointer creates checkpoint tables, not a
  threads table)
- MCP Apps activity/history (frontend constructs; re-synthesize on hydration)
- v1 vs v2 disambiguation

Addresses the recurring thread-lifecycle support questions (#4790, #4778,
#5434, #2242, #5931). Added to the Threads nav group.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 15:13:25 -05:00
Tyler Slaton 9504e0666c refactor(channels): add batteries-included package architecture (#5948)
## Summary

- Extract the platform-neutral Channels foundation into
`@copilotkit/channels-core`.
- Make `@copilotkit/channels` the batteries-included consumer entry
point, with adapter and UI subpaths.
- Release the umbrella, core, UI, and all six adapters as one shared
`channels` version scope.
- Verify the packed consumer contract and migrate the Slack and Teams
examples to the umbrella.

## Why

Consumers should be able to install one Channels package without making
the runtime or selective integrations depend on every platform SDK.
Shipping the complete Channels family together prevents adapter/core
version drift and makes the umbrella's exact dependency set release as a
compatible unit.

## How

- Move shared bot/runtime primitives into `channels-core` and invert
adapter/runtime dependencies.
- Add exact workspace dependencies and export subpaths from the umbrella
package.
- Consolidate the existing release configuration and all three release
workflow selectors into one shared `channels` scope containing all nine
packages.
- Use `@copilotkit/channels` as the version source: the next minor
release resolves to `0.2.0` and bumps every Channels package together.
- Publish scoped packages in dependency order for both stable and canary
releases: UI, core, adapters, then the umbrella.
- For a stable Channels release, publish the UI/core/adapters first, run
the registry-backed packed-consumer verifier against those newly
published exact versions, then publish the umbrella.
- Generate Channels release notes from `channels/v*` tags rather than
the monorepo `v*` tags.
- Verify builds, type checks, tests, package artifacts, examples, and
release workflow scope synchronization locally.

### First stable release sequence

1. Bootstrap the currently unpublished `@copilotkit/channels-core`
package on npm and configure npm trusted publishing for every Channels
package against this repository's `release / publish` workflow and `npm`
environment.
2. Create and merge the `channels` minor release PR. The stable workflow
publishes the Channels family in the staged order above and validates
the packed umbrella from the registry before the umbrella is released.
3. Create and merge a subsequent `monorepo` release PR so the published
`@copilotkit/runtime` switches from the historical umbrella dependency
to `@copilotkit/channels-core`.
2026-07-15 13:12:16 -07:00
Sam Julien 59f15608ba docs(shell-docs): reduce Threads screenshot padding 2026-07-15 13:09:57 -07:00
Ran Shem Tov 4eed87c75b fix(showcase/mastra): correct cancel-path narration via aimock toolResultContains gate
Pick and cancel resume the native schedule_meeting suspend tool with the
SAME toolCallId; the requests differ only inside the tool-result payload,
so the cancel resume previously hit the pick-confirmation fixture and the
assistant replayed "Booked: ... confirmed" after the user cancelled. The
"__cancelled" toolCallId gates on the Denied fixtures were fictional and
never matched.

aimock 1.37.0 (CopilotKit/aimock#299) adds a JSON-expressible
match.toolResultContains substring gate on the last tool-result message.

- gen-ui-interrupt.json: cancelled legs now gate on the real toolCallId +
  toolResultContains "cancelled", ordered before the confirmation legs
- interrupt-headless.json: gained the same cancelled legs (the demo's
  Cancel button had no fixture at all)
- aimock-fixtures.test.ts: matchKey learns toolResultContains; duplicate
  ceiling 303 -> 305 (headless cancelled legs share exact keys AND
  response text with the gen-ui-interrupt ones, one pair per pill)
- e2e specs: cancel tests now assert the Denied narration and reject
  Booked/Scheduled, so the regression cannot silently return

Verified live against aimock built from source (fixture replay):
8/8 Playwright e2e across both demos, plus manual pick + cancel runs on
/demos/gen-ui-interrupt and /demos/interrupt-headless.

Commit uses --no-verify: this worktree's lefthook runner is broken
(pre-existing, see daa501daa); commitlint + prettier + the fixtures
vitest were run manually and pass.

Follow-up (blocked on aimock#299 npm publish): bump the vendored
@copilotkit/aimock pin in showcase/scripts/package.json and pull the
refreshed ghcr.io/copilotkit/aimock:latest.
2026-07-15 13:09:41 -07:00
Sam Julien 40c0401871 docs(shell-docs): tighten Threads screenshot frame 2026-07-15 13:04:21 -07:00
Ben Taylor 0777a26833 feat(channels-intelligence): realtime transport parity — kinds, identity, history/files, delete (#5983)
## What & why

The Realtime Gateway transport had drifted from the HTTP polling
transport, so managed channels running over the gateway behaved
differently from direct. This brings the realtime path to full parity.

Before, the realtime transport:
- built a **text-only** ingress envelope —
commands/reactions/interactions were coerced into empty turns;
- keyed conversations **per-turn** (`conversationKey = turn.id`), so
threaded follow-ups didn't share agent/session state;
- **dropped the provider actor** — `env.user` was never populated (on
*both* transports, in fact);
- implemented **none** of `fetchFile`/`getHistory`/`uploadFile`, so the
realtime path silently ran with no history and no file support;
- had **no `delete` render kind**, so `thread.delete` couldn't render
over the gateway.

## Changes

- **`claim-mapping.ts` (new, shared):** extract the claim→ingress
mapping — `ClaimedDelivery`, `conversationKeyFromReplyTarget`,
`mapDeliveryToEnvelope` — into one module both transports import, so
they can't drift again (drift *was* the bug). Adds the provider `actor`
to the claim turn and maps it to `env.user` — fixing identity on
**both** paths.
- **realtime transport:** builds the envelope via the shared mapper
(real kind discrimination, thread-stable `conversationKey`, actor→user)
instead of the inline text-only build. Fail-closed: an unmodeled
reply-target/kind is dropped+logged, not crashed.
- **`intelligence-file-history.ts` (new, shared):** extract
`fetchFile`/`getHistory`/`uploadFile` into
`IntelligenceFileHistoryClient`. These are **HTTP-only** — the gateway
relays the render-event stream but never file bytes or history. The
realtime transport gains them when configured with `appApiBaseUrl` +
`apiKey` (threaded through the launcher); without those, the methods
stay `undefined` and the adapter degrades exactly as before.
- **`delete` render kind:** add `{ kind: "delete"; ref }` to
`ChannelRenderEvent` (mirrors the frozen Intelligence contract) and
route `thread.delete` through a render frame when a render sink is
wired, like post/update/file.

## Tests

- `claim-mapping.test.ts`: actor→user, kind discrimination
(command/reaction/interaction/text), thread-stable conversationKey
(slack/teams), unmodeled-adapter throw.
- `render-events.test.ts`: realtime non-text kind + identity +
thread-stable key; file/history capability toggling on config; a
delete-render-frame test.
- Full suite (160) + `check-types` + `build` green.

## Companion

This is the CopilotKit SDK half of the managed-transport parity work;
the Intelligence-side half (gateway `render_event/1` validator for
file/delete, DB CHECK, Connector Outbox `chat.delete`, actor on the
claim) landed separately. Together they close the direct-vs-managed
parity matrix.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-15 14:41:41 -05:00
github-actions[bot] 36cad9530e style: auto-fix formatting 2026-07-15 19:18:05 +00:00
Jordan Ritter 9299533bfd fix(showcase): self-activate CVDIAG routing + guard public $PORT with alerting watchdog (claude-sdk-python)
Self-activate CVDIAG_LOG_STDOUT=0 when CVDIAG_PB_URL is wired (safe: only silences stdout when PB is receiving; explicit override preserved). Extend the watchdog to poll the public $PORT /api/health and, on sustained failure, POST a loud #oss-alerts Slack alert BEFORE kill-restart; add the same alert to the agent-\:8000 branch (no silent recovery). Add uvicorn --no-access-log to cut the access-log flood. Together these keep the shared log stream under the 500/sec cap so the pipe never backs up.
2026-07-15 12:15:10 -07:00
Jordan Ritter 50f119b459 fix(showcase): route CVDIAG stdout emission behind CVDIAG_LOG_STDOUT gate (default ON)
Shared cvdiag_bootstrap: gate the per-LLM-call breadcrumb capture handler and the emit_cvdiag stdout write behind CVDIAG_LOG_STDOUT (default ON so every other integration is byte-for-byte unchanged; opt-out per service). Enqueue to the non-blocking PocketBase sink BEFORE the stdout write so a wedged fd1 cannot cost the durable breadcrumb. No sampling; full fidelity to PB. Red-green unit tests incl. a hostile-stdout durability test.
2026-07-15 12:15:09 -07:00
Jordan Ritter 50245bb4dd test(showcase): reproduce stdout-backpressure event-loop wedge (docker RED+GREEN harness)
Faithful node:22-slim repro: fd1 through the same awk process-substitution as entrypoint.sh, a Railway-capped drain reader, a uvicorn+CVDIAG-shaped flood, and the static no-log /api/health as victim. RED wedges (200->502, CPU->0, heartbeat frozen); the FIXED lane stays 200 throughout. run.sh asserts the outcome (exit 3/4/5 on a false result, proven). watchdog.sh runs the entrypoint public-guard loop verbatim and needle-anchors it against entrypoint.sh.
2026-07-15 12:15:07 -07:00
Sam Julien 402646ff32 docs(shell-docs): update Threads overview screenshot 2026-07-15 12:14:44 -07:00
Ran Shem Tov cb9696fc57 Merge remote-tracking branch 'origin/main' into claude/brave-kirch-8dbf00 2026-07-15 11:45:56 -07:00
Ran Shem Tov daa501daa2 fix(showcase/mastra): interrupt resume-loop, browse_web card, reasoning replay order
Playwright-verified fixes for the Mastra demo validation round:

- aimock interrupt fixtures (gen-ui-interrupt, interrupt-headless): add
  hasToolResult:false to the schedule_meeting suspend legs so the resume
  request falls through to the toolCallId confirmation fixture instead of
  re-matching the suspend leg (picker loop, duplicated intro). Mirrors
  hitl-in-chat.json.
- aimock-fixtures test: ceiling 301 -> 303; the two suspend keys now
  intentionally collide across the three mastra interrupt cells
  (runtime-disambiguated by route/fixtureFile like existing aliases).
- browse-web tool: return the result OBJECT instead of JSON.stringify;
  the bridge encodes once more so stringifying double-encoded the result
  and BrowseResultsCard showed "0 results" despite a successful browse.
- reasoning-chain pill: "Roll a d20 ..." instead of "Roll a 20-sided die
  ..." — the d4 agentic-chat fixture shadowed the first leg under replay
  (d4 loads before d6) and pushed reasoning a step late. Real-LLM order
  verified correct.
- header-forwarding shim: default x-aimock-context to "mastra" when absent
  so browser-driven demos replay against aimock instead of 404ing. Harness
  header wins when present; real providers ignore it.
- docker-compose.local: make OPENAI_BASE_URL overridable via .env (default
  aimock unchanged) so real-LLM cells like browser-use can be tested live.

(--no-verify: commitlint binary missing in this worktree after the session
crash — ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL, infra not message)
2026-07-15 11:45:36 -07:00
Sam Julien dfe5532280 docs(shell-docs): add themed Threads diagrams 2026-07-15 11:37:11 -07:00
Benjamin Taylor a8407f84fd fix(channels): address Tyler CR — wire app-api URL through runtime activation + map user name (OSS-476)
- [P1] History/files were absent on the NORMAL managed path: defaultActivateChannel
  never forwarded the app-api HTTP URL, so the transport (which installs
  fetchFile/getHistory/uploadFile only when appApiBaseUrl is set) ran without
  them for Channels started by the CopilotRuntime handler — only manual
  low-level launcher callers got file/history. Thread intelligence.ɵgetApiUrl()
  through ChannelActivationConfig.apiUrl → defaultActivateChannel →
  startChannelsOverRealtimeGateway({ appApiBaseUrl }). The launcher + transport
  already accepted it.
- [P2] Managed turns exposed the provider profile under a non-public `displayName`
  field, leaving PlatformUser.name undefined. Map env.user.displayName -> name
  (parity with the direct Slack adapter, which populates `name`).

Tests: deriver returns apiUrl; defaultActivateChannel forwards appApiBaseUrl to
the launcher opts; onMessage sees message.user.name. channel-activation-config +
channels-intelligence (170) green; runtime build type-checks. (channel-manager.test
executes in CI — local vitest hits the known optional-peer-dep resolution flake.)
2026-07-15 13:36:36 -05:00
Sam Julien cc107b776a docs: refresh stale contributing commands, langgraph RunnableConfig imports, and Anthropic model IDs (#5982)
## What & why

Consolidates three community docs fixes that were each opened against
the retired `docs/content/docs/` tree (now just a symlink to
`showcase/shell-docs/`), so none of them could merge as-is even though
the underlying doc bugs are still live. This re-applies them against the
current shell-docs source and, where the original proposals had drifted,
uses commands verified against the current repo.

### 1. Contributing / package-linking guides — supersedes #3509
Turborepo has been **fully removed** from the repo (no `turbo`
dependency, no `turbo.json`), but every contributing guide still
instructs `turbo run …`. Across the root guide, all per-integration
copies, and the shared snippets:
- Drop the "Turborepo v2.x installed globally" prerequisite; bump pnpm
to **v10.x** to match the root `packageManager` (`pnpm@10.33.4`).
- Reframe the monorepo as a pnpm workspace orchestrated by **Nx**.
- Replace commands with equivalents verified against the current root
`package.json` / Nx targets:
  - `turbo run build|dev|format|lint` → `pnpm run build|dev|format|lint`
- `turbo run link:global` / `unlink:global` → `pnpm exec nx run-many -t
link:global` / `unlink:global`
- per-package dev (`turbo run dev --filter=…`) → `pnpm exec nx watch
--projects=packages/<name> -- pnpm run build`
- also fixed a pre-existing stale reference: `pnpm run example-dev` →
`pnpm run dev:examples` (the real script)

### 2. Anthropic model IDs — supersedes #3656
`built-in-agent/model-selection` listed dotted IDs that aren't valid;
hyphenate `claude-3-7-sonnet`, `claude-opus-4-1`, `claude-3-5-haiku`.

### 3. LangGraph `RunnableConfig` imports — supersedes #4069
Twelve langgraph reference pages annotate `config: RunnableConfig` in
Python snippets without importing it. Add `from langchain_core.runnables
import RunnableConfig` to each such block. (Tutorial pages were
intentionally left out to avoid disrupting their step-by-step
narrative.)

## Credit
Thanks to the original authors whose fixes this incorporates:
@electricalen (#3509), @Abubakar-01 (#3656), and @Koushik-Salammagari
(#4069). Those PRs can be closed in favor of this one once merged.

## Testing
- `grep` confirms **0** remaining `turbo run` / `Turborepo` / `turbo@2`
references and **0** remaining `example-dev` references across the docs
content.
- All replacement scripts/targets verified present in the root
`package.json` (`build`, `dev`, `format`, `lint`, `dev:examples`) and as
per-package Nx targets (`link:global`, `unlink:global`).
- Confirmed **0** langgraph Python blocks remain that use
`RunnableConfig` without importing it (excluding the
intentionally-skipped tutorial pages).
- Spot-checked insertion placement/indentation in both deeply-nested
(`interrupt-flow.mdx`) and flat (`auth.mdx`) code blocks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-15 11:11:54 -07:00
Benjamin Taylor 237cbf4cf9 chore(channels): CR hygiene — real test coverage + doc/log cleanups (OSS-476)
Trivial items from the CR confirmation rounds (no behavior change to production
paths):

- intelligence-adapter.test.ts: `delete source.getHistory` was inert (getHistory
  is a prototype method; delete only removes own props), so the "no getHistory"
  branch was never actually exercised. Shadow with an own `undefined` instead so
  the `source?.getHistory?.()` short-circuit is genuinely tested.
- in-memory-transports.ts: mirror the production `limit <= 0 -> []` guard in
  InMemoryDeliverySource.getHistory (was `slice(-limit)` → returns ALL for 0).
- realtime ack(): log the empty-turn (no accepted frames) drop so the OSS-491
  redelivery pile-up is diagnosable (every other drop path here logs).
- http-transports.ts: remove two orphaned JSDoc comments dangling over
  ClaimResponse (leftovers from the file/history extraction).
- intelligence-adapter.ts: correct an inaccurate op-id comment (mintOp is the
  ${turnId}:${seq} source; the render path keys on ${turnId}:${slot}:${seq}).

channels-intelligence 170 tests + check-types green.
2026-07-15 12:58:53 -05:00
Tyler Slaton 5811cab177 fix(channels): align rebase with channel API 2026-07-15 10:29:21 -07:00
Benjamin Taylor 2718474229 fix(channels): second CR round — graceful realtime stop() + parity/hygiene (OSS-476)
From the 7-agent CR confirmation round:

- RealtimeGatewayTransport.stop() now halts intake (a `stopped` guard in
  handleDeliveryAvailable — the session exposes no `off` to detach the
  DELIVERY_AVAILABLE listener) and DRAINS the in-flight delivery (awaits the
  serial `processing` chain) before clearing state, so a turn settling at stop
  time still sends its terminal signal instead of silently no-oping and
  redelivering. Mirrors HttpDeliverySource.stop().
- Realtime nack() truncates the reason to 500 chars (parity with HTTP).
- getMessages drops empty content parts before join(" ") so a read_thread
  transcript isn't corrupted with doubled/leading/trailing spaces (a test had
  enshrined "part one  part two").
- Removed dead imports (buildContentParts, AgentContentPart, ChannelFileRef)
  left in http-transports.ts after the file/history extraction.

Deferred (delivery-contract / design; need coordination — folded into OSS-491):
timeout-nack can redeliver a still-running turnId (overlap); realtime push()
no-state fallback vs HTTP fail-loud (documented intentional — parity Q); the
empty-turn completion signal.

Tests: stop() drains in-flight + ignores post-stop deliveries; getMessages
assertion corrected. channels-intelligence 170 tests + check-types green.
2026-07-15 12:21:53 -05:00
Tyler Slaton eed52e13c7 refactor(release): preserve configured publish order 2026-07-15 10:13:19 -07:00
Tyler Slaton 3b22abbbd1 fix(release): stage channels publishing 2026-07-15 10:13:18 -07:00
Tyler Slaton 17213998a1 chore(release): unify channels version scope 2026-07-15 10:13:18 -07:00
Tyler Slaton 02a93c3b8a docs(channels): clarify umbrella release availability 2026-07-15 10:13:18 -07:00
Tyler Slaton fad2aed6c2 test(channels): verify packed umbrella consumers 2026-07-15 10:13:17 -07:00
Tyler Slaton 8f6f97f231 docs(channels): dogfood the umbrella in channel examples 2026-07-15 10:13:17 -07:00
Tyler Slaton 163d0e99b8 chore(release): add channels core and umbrella scopes 2026-07-15 10:12:23 -07:00