Skip to content

Commit f3ec5dd

Browse files
authored
feat(integrations): Intelligence threads — north-star foundation + batch 1 (7 examples on 1.59.1) [ENT-679] (CopilotKit#5151)
## Summary **Threads/Intelligence rollout across the integration examples ([ENT-679](https://linear.app/copilotkit/issue/ENT-679)) — the shared foundation + Batch 1.** Makes the **`langgraph-python` north-star** Intelligence-ready, ships the framework-agnostic activation overlay + parity wiring, and integrates the **six Batch-1 examples**, standardizing everything on **`@copilotkit/* 1.59.1`**. > Originally two stacked PRs; the batch-1 work was folded into this branch so it's reviewed as one unit. ## Per-example status | Example | agent | threads | demo | `next build` | verified | |---|---|---|---|---|---| | langgraph-python (north-star) | `default` | ✅ | todo (CopilotChat) | ✅ | bumped 1.56.5→1.59.1 | | langgraph-js | `default` | ✅ | todo (shared) | ✅ | build | | mastra | `weatherAgent` | ✅ | proverbs/weather/moon | ✅ | ✅ **full E2E** | | adk | `my_agent` | ✅ | proverbs (`useRenderTool` weather) | ✅ | build | | agno | `agno_agent` | ✅ | proverbs (local state) + tools | ✅ | build | | ms-agent-framework-python | `my_agent` | ✅ | proverbs/weather/moon | ✅ | build | | ms-agent-framework-dotnet | `my_agent` | ✅ | proverbs/weather/moon | ✅ | build | ## What's in it **Foundation (north-star + shared):** - **Env-gated runtime wiring** (`route.ts`): license → `CopilotKitIntelligence` + `identifyUser` + `licenseToken`; otherwise `InMemoryAgentRunner`. Marker-fenced for opt-out; multi-route endpoint. - **Threads frontend**: `threads-drawer/**` refactored into a **token-driven themeable base** + locked-state tease; `next.config` derives `NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED` from the license (SSR-safe client mount). **Without a license the panel renders locked.** - **`_intelligence/` activation overlay**: docker-compose (postgres + redis + composite `0.2.0`), init-db, `.env.intelligence`, an idempotent **`provision-user`** one-shot (`demo-user`), and **`CHECK_ORIGIN=false`** so the local realtime-gateway accepts the app's websocket origin (live thread updates). - **Parity staging**: `threads-drawer/**` tracked as `verbatimFiles` (north-star canonical); per-example threads files in `allowedDivergence`. **Batch 1 (per example):** the env-gated route branch (multi-route + **`useSingleEndpoint={false}`** REST transport, no `organizationId`); a **bespoke themed threads panel** matching each example's chat; the `next.config` gate; `demo-user` identity. **v2 demo migration** — the 1.59.1 bump broke the V1-era proverbs/weather/moon demos, so: - `useAgent({ agentId })` → `{ agent }` (read `agent.state`, write `agent.setState`); - `useFrontendTool` params as **Zod** schemas (not the V1 array); - `<CopilotSidebar>` content as a **sibling** (v2 slot model), not children — otherwise the canvas silently never mounts; - guarded card state for the async-loaded agent state. ## Verification - All seven examples **`next build` clean** (`/` prerenders; gate holds in both license states). - **Full end-to-end on mastra** against the running stack: thread create/list/auto-name, agent run, generative-UI + frontend-tool + human-in-the-loop, **live websocket updates**, demo renders, clean console. - The other five are build-clean and under **per-example visual/functional review** (fixes land on this branch). ## Known follow-ups / not in this PR - Per-example visual + functional review (in progress). - `langgraph-fastapi` / `strands-python` (parity instances, **Batch 2**) stay on `1.56.5`, so the parity-tracked `@copilotkit/*` version field diverges from the bumped north-star until Batch 2 (parity-check already red on `main`; branch protection off). - Retiring `langgraph-python-threads` (kept as reference), showcase `manifest.yaml` registration ("marketing"), inspector locked-panel (ENT-680), and the CLI `-i` allowlist flips (separate Intelligence-repo PR). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
2 parents be20a38 + 53af72b commit f3ec5dd

160 files changed

Lines changed: 163731 additions & 1244 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Appended by `copilotkit add-intelligence`
2+
COPILOTKIT_LICENSE_TOKEN=
3+
INTELLIGENCE_API_URL=http://localhost:4201
4+
INTELLIGENCE_GATEWAY_WS_URL=ws://localhost:4401
5+
INTELLIGENCE_API_KEY=cpk_sPRVSEED_seed0privat0longtoken00
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# `_intelligence/` — CopilotKit Intelligence Activation Overlay
2+
3+
This directory is the **framework-agnostic** overlay consumed by `copilotkit init -i` and
4+
`copilotkit add-intelligence`. It contains everything needed to run the CopilotKit Intelligence
5+
stack locally, independent of which framework template your project uses.
6+
7+
## Assets
8+
9+
### `docker-compose.yml`
10+
11+
Starts three services:
12+
13+
- **postgres** — relational store used by the Intelligence runtime
14+
- **redis** — cache and pub/sub broker
15+
- **`ghcr.io/copilotkit/intelligence/composite`** — the all-in-one Intelligence container (app-api
16+
on 4201, realtime-gateway on 4401, thread-culler, and a db-migrations oneshot)
17+
18+
Bring the stack up with:
19+
20+
```bash
21+
docker compose up -d --wait
22+
```
23+
24+
### `.env.intelligence`
25+
26+
A fragment of environment variables appended to your project's `.env` when you run
27+
`copilotkit add-intelligence`. It wires the scaffolded app to the local stack:
28+
29+
```
30+
COPILOTKIT_LICENSE_TOKEN=
31+
INTELLIGENCE_API_URL=http://localhost:4201
32+
INTELLIGENCE_GATEWAY_WS_URL=ws://localhost:4401
33+
INTELLIGENCE_API_KEY=cpk_sPRVSEED_seed0privat0longtoken00
34+
```
35+
36+
`INTELLIGENCE_API_KEY` is pre-seeded with the local-dev value the bundled composite
37+
container expects. To activate Intelligence, set `COPILOTKIT_LICENSE_TOKEN` (server-side
38+
secret, from your CopilotKit dashboard); each base template's runtime wires Intelligence
39+
from that token (see the per-framework dormant wiring below). The stack runs locally once
40+
the token is set.
41+
42+
## Framework independence
43+
44+
This overlay is **not tied to any specific framework template**. The per-framework dormant
45+
runtime wiring (e.g. the `CopilotRuntime` provider, route handler, and hook configuration)
46+
lives in each base template. The overlay only supplies the Docker stack and the env-key
47+
fragment that activates it.
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Framework-agnostic CopilotKit Intelligence activation overlay.
2+
#
3+
# Starts postgres, redis, and the all-in-one intelligence composite
4+
# container (runs app-api, realtime-gateway, thread-culler, and the
5+
# db-migrations oneshot internally under s6-overlay).
6+
#
7+
# Usage:
8+
# docker compose up -d --wait
9+
#
10+
# Then start the app services on the host:
11+
# npm run dev
12+
13+
name: copilotkit-intelligence
14+
15+
services:
16+
# ---------------------------------------------------------------------------
17+
# Infrastructure
18+
# ---------------------------------------------------------------------------
19+
20+
postgres:
21+
image: postgres:16-alpine
22+
ports:
23+
- "${POSTGRES_HOST_PORT:-5432}:5432"
24+
environment:
25+
POSTGRES_USER: intelligence
26+
POSTGRES_PASSWORD: intelligence
27+
POSTGRES_DB: postgres
28+
volumes:
29+
- postgres-data:/var/lib/postgresql/data
30+
- ./docker/init-db:/docker-entrypoint-initdb.d:ro
31+
healthcheck:
32+
test: ["CMD-SHELL", "pg_isready -U intelligence -d postgres"]
33+
interval: 5s
34+
timeout: 3s
35+
retries: 5
36+
restart: unless-stopped
37+
networks:
38+
- intelligence
39+
40+
redis:
41+
image: redis:7-alpine
42+
ports:
43+
- "${REDIS_HOST_PORT:-6379}:6379"
44+
volumes:
45+
- redis-data:/data
46+
healthcheck:
47+
test: ["CMD", "redis-cli", "ping"]
48+
interval: 5s
49+
timeout: 3s
50+
retries: 5
51+
restart: unless-stopped
52+
networks:
53+
- intelligence
54+
55+
# ---------------------------------------------------------------------------
56+
# Intelligence composite (app-api + realtime-gateway + thread-culler +
57+
# db-migrations, all in one container under s6-overlay)
58+
# ---------------------------------------------------------------------------
59+
60+
intelligence:
61+
image: ghcr.io/copilotkit/intelligence/composite:0.2.0
62+
ports:
63+
- "${APP_API_HOST_PORT:-4201}:4201"
64+
- "${REALTIME_GATEWAY_HOST_PORT:-4401}:4401"
65+
environment:
66+
DATABASE_URL: postgresql://intelligence:intelligence@postgres:5432/intelligence_app
67+
REDIS_URL: redis://redis:6379
68+
AUTH_SECRET: local-dev-secret-must-be-at-least-32-chars
69+
RUNNER_AUTH_SECRET: dev-runner-secret
70+
SECRET_KEY_BASE: local-realtime-gateway-secret-key-base-at-least-64-bytes-long-for-dev
71+
DEFAULT_ORGANIZATION_ID: casa-de-erlang
72+
# Local dev: the web app runs on http://localhost:<port>, not the gateway's
73+
# configured https://localhost, so disable Phoenix origin checking on the
74+
# realtime-gateway websocket (otherwise client WS connects get a 403).
75+
CHECK_ORIGIN: "false"
76+
COPILOTKIT_LICENSE_TOKEN: "${COPILOTKIT_LICENSE_TOKEN:-}"
77+
THREAD_STALE_HOURS: "${THREAD_STALE_HOURS:-3}"
78+
THREAD_CULL_BATCH_SIZE: "${THREAD_CULL_BATCH_SIZE:-1000}"
79+
depends_on:
80+
postgres:
81+
condition: service_healthy
82+
redis:
83+
condition: service_healthy
84+
restart: unless-stopped
85+
networks:
86+
- intelligence
87+
88+
# ---------------------------------------------------------------------------
89+
# Demo user provisioning (one-shot)
90+
# ---------------------------------------------------------------------------
91+
# Ensures the runtime's identifyUser id (COPILOTKIT_DEMO_USER_ID, default
92+
# "demo-user") exists in cpki.users so created threads can attach to it.
93+
# Idempotent; mirrors the two-row pattern the composite's startup seed uses:
94+
# a bare id (membership checks) plus a per-project scoped alias
95+
# "<projectId>_<userId>" (the threads_user_id_fkey target). Runs once after the
96+
# composite is healthy (schema + org/projects seeded), then exits.
97+
provision-user:
98+
image: postgres:16-alpine
99+
depends_on:
100+
intelligence:
101+
condition: service_healthy
102+
environment:
103+
PGPASSWORD: intelligence
104+
DEMO_USER_ID: "${COPILOTKIT_DEMO_USER_ID:-demo-user}"
105+
ORG_ID: "${COPILOTKIT_ORGANIZATION_ID:-casa-de-erlang}"
106+
entrypoint: ["sh", "-c"]
107+
command:
108+
- |
109+
psql -h postgres -U intelligence -d intelligence_app -v ON_ERROR_STOP=1 \
110+
-c "INSERT INTO cpki.users (id, organization_id) VALUES ('$$DEMO_USER_ID', '$$ORG_ID') ON CONFLICT (id) DO NOTHING;" \
111+
-c "INSERT INTO cpki.users (id, organization_id) SELECT p.id || '_' || '$$DEMO_USER_ID', '$$ORG_ID' FROM cpki.projects p WHERE p.organization_id = '$$ORG_ID' AND p.deleted_at IS NULL ON CONFLICT (id) DO NOTHING;"
112+
restart: "no"
113+
networks:
114+
- intelligence
115+
116+
volumes:
117+
postgres-data:
118+
redis-data:
119+
120+
networks:
121+
intelligence:
122+
driver: bridge
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CREATE DATABASE intelligence_app;
2+
CREATE DATABASE intelligence_app_shadow;

examples/integrations/_parity/manifest.json

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
"src/components/generative-ui/meeting-time-picker.tsx",
3434
"src/components/headless-chat.tsx",
3535
"src/components/tool-rendering.tsx",
36+
"src/components/threads-drawer/index.tsx",
37+
"src/components/threads-drawer/locked-state.tsx",
38+
"src/components/threads-drawer/threads-drawer.module.css",
39+
"src/components/threads-drawer/threads-drawer.tsx",
3640
"src/components/ui/badge.tsx",
3741
"src/components/ui/button.tsx",
3842
"src/components/ui/card.tsx",
@@ -126,7 +130,10 @@
126130
"docker-compose.test.yml",
127131
"entrypoint.sh",
128132
"serve.py",
129-
"scripts/**"
133+
"scripts/**",
134+
"src/components/threads-drawer/**",
135+
"src/app/page.tsx",
136+
"next.config.ts"
130137
],
131138
"packageJsonOverrides": {
132139
"scripts.dev:agent": "./scripts/run-agent.sh || scripts\\\\run-agent.bat",
@@ -144,7 +151,10 @@
144151
"src/app/api/copilotkit/**",
145152
"docker/Dockerfile.agent",
146153
"docker-compose.test.yml",
147-
"scripts/**"
154+
"scripts/**",
155+
"src/components/threads-drawer/**",
156+
"src/app/page.tsx",
157+
"next.config.ts"
148158
],
149159
"packageJsonOverrides": {
150160
"scripts.dev:agent": "cd agent && uv run main.py",
@@ -164,7 +174,10 @@
164174
"docker/Dockerfile.agent",
165175
"docker-compose.test.yml",
166176
"serve.py",
167-
"scripts/**"
177+
"scripts/**",
178+
"src/components/threads-drawer/**",
179+
"src/app/page.tsx",
180+
"next.config.ts"
168181
],
169182
"packageJsonOverrides": {
170183
"scripts.dev:agent": "./scripts/run-agent.sh || scripts\\\\run-agent.bat",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
GOOGLE_API_KEY=your-api-key-here
22
AGENT_URL=http://localhost:8000
3+
4+
# --- CopilotKit Intelligence (optional; set COPILOTKIT_LICENSE_TOKEN to enable Threads — server + UI) ---
5+
# COPILOTKIT_LICENSE_TOKEN=
6+
# INTELLIGENCE_API_URL=http://localhost:4201
7+
# INTELLIGENCE_GATEWAY_WS_URL=ws://localhost:4401
8+
# INTELLIGENCE_API_KEY= # local dev: see examples/integrations/_intelligence/.env.intelligence for the seed value

examples/integrations/adk/next.config.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@ import type { NextConfig } from "next";
22

33
const nextConfig: NextConfig = {
44
serverExternalPackages: ["@copilotkit/runtime"],
5+
env: {
6+
// The public Threads UI flag is DERIVED from the server-side license token.
7+
// Set COPILOTKIT_LICENSE_TOKEN (only) to enable Threads — do not set this flag
8+
// directly. NOTE: NEXT_PUBLIC_* resolves at BUILD time while the runtime reads
9+
// the token per-request, so the UI gate and runtime agree only when the token is
10+
// present at build time (the standard `next dev` / host-build flow). For a
11+
// standalone/Docker image built without the token and injected at runtime, set
12+
// COPILOTKIT_LICENSE_TOKEN at build time too (or gate the UI at runtime) so the
13+
// baked flag reflects it.
14+
NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED: process.env.COPILOTKIT_LICENSE_TOKEN
15+
? "true"
16+
: "false",
17+
},
518
typescript: {
619
// HttpAgent type mismatch with CopilotRuntime — pending upstream fix in @copilotkit/runtime
720
ignoreBuildErrors: true,

0 commit comments

Comments
 (0)