KiteBot on CopilotKit Intelligence — Phases 1 & 2 (channels + Intelligence Gateway + LangGraph deep-research agent) - #6
Merged
jerelvelarde merged 25 commits intoJul 16, 2026
Conversation
…esign Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…hannels-intelligence channels-discord/-telegram/-whatsapp are only published at 0.0.x; pinned to their latest published versions. jsxImportSource -> @copilotkit/channels-ui. Commit the pnpm lockfile now that standalone install resolves. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…dupe rxjs Global import-specifier rename across app/** (API identifiers unchanged: createBot, defineBotTool, slack, SanitizingHttpAgent, etc.). The rename made the slack agent import resolve correctly, exposing a latent duplicate-rxjs skew (channels@7.8.1 vs channels-slack->core@7.8.2) that broke the AbstractAgent structural type at app/index.ts. Fixed with a pnpm override pinning rxjs ^7.8.2 to a single copy. check-types clean; 62 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ltimeGateway)
app/managed.ts runs the same bot over the CopilotKit Intelligence Realtime
Gateway (published @copilotkit/channels-intelligence two-process pattern; the
unified CopilotRuntime({channels}) API is main-only/unpublished). Pure
createKiteBot() factory + unit test; 65 tests green, check-types clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…eBot mentions .env.example gains the INTELLIGENCE_* block for pnpm channel (full gateway scope). README + setup.md rename bot->channels, add channels-intelligence, present the managed Intelligence deployment as the recommended default with self-hosted as the alternative, drop Redis, and note packages now publish to npm (standalone install works). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…st managed service Relabel the pnpm channel mode 'Intelligence Gateway' (was 'Intelligence (managed)') and reserve 'managed service' for the coming-soon hosted waitlist, resolving the terminology collision. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…mands, render-table, components) - managed.ts: drop bot.name! (local channelName const), guard onThreadStarted, extract+test pure helpers (promptFromMessage/buildAgentHeaders/parseProjectId) - index.ts: log the swallowed error-post, harden shutdown (runShutdown wrapper, guarded closeBrowser, exit codes) mirroring managed.ts - commands: wrap /agent /triage /file-issue-fallback runAgent (runAgentSafely helper, log + apology); test /triage-with-text and /preview no-user - render-table: surface clamp truncation notes to user + agent, align 'Max 99' desc, right-align monospace fallback, log the native-post failure - components: render priority in issue-list meta, cap page-list blocks - render-chart: add JSON.parse/upload-failure/bytes tests 84 tests pass; check-types clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ntime, config) - confirm-write-tool: distinguish no-response (timeout/dismissed) from explicit decline instead of silently reporting DECLINED - confirm-write / showcase onClick handlers: guard fire-and-forget update/post - file-issue: log swallowed apology-post; document the necessary ModalView cast; test success-path prompt + sender context - read-thread: cover the handle fallback branch - runtime.ts: narrowing instead of (reason as Error); drop the as never[] cast (types align); document the AGENT_MODEL cast caveat; platform-neutral framing (log prefix [runtime], doc header, SYSTEM_PROMPT) since the backend serves all platforms - .env.example: header includes WhatsApp; setup.md: correct the table-renderer row (native Table, not Playwright); tsconfig: type-check scripts/ (+ fix childEnv) 89 tests pass; check-types clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…hygiene, coverage - runtime.ts + index.ts: validate PORT (integer, 1-65535; reject 0 / out-of-range) - index.ts: guard onThreadStarted (match managed.ts) - managed.ts: type promptFromMessage (drop cast); instanceof narrowing; +parseProjectId edge tests - scripts/start-notion-mcp.ts: drop --auth-token CLI arg (secret leaked via ps under shell:true; AUTH_TOKEN env suffices) - docs: correct OpenAI-only reality (runtime is openaiText-only; Anthropic/Google not wired), AGENT_URL is required (not a code default), document NOTION_MCP_PORT/NOTION_VERSION - tsconfig: drop stale 'agent' exclude; type-check scripts/ - tests: runAgentSafely error path, confirm-write no-response branch, render-chart DIAGRAM_PNG bytes + comment fix 94 tests pass; check-types clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…/LangGraph design Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…PENAI_API_KEY) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…on :8123) New agent/ service ported from CopilotKit examples/showcases/deep-agents: create_deep_agent planner + virtual filesystem + Tavily research() tool, served over AG-UI via LangGraphAGUIAgent + FastAPI/uvicorn. TAVILY_API_KEY is OPTIONAL — only OPENAI_API_KEY is required; the research tool is gated on TAVILY, and chat + UI-component generation work without it. Default model gpt-5.5, port 8123. uv sync resolves cleanly; build (research disabled/enabled) + /health verified. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Root .env.example gains an agent/-scoped block (OPENAI_MODEL distinct from runtime.ts's AGENT_MODEL; optional TAVILY_API_KEY; AGENT_URL->:8123). Adds the 'agent' pnpm script and a 'Deep research (LangGraph deep agent)' section to README + setup.md (uv sync + pnpm agent; OPENAI required, Tavily optional). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…_PORT apply The script previously ran uvicorn main:app directly, bypassing main() — so the documented SERVER_HOST/SERVER_PORT (and the 0.0.0.0 default) were silently ignored and it bound 127.0.0.1. Now it uses the code path, matching the docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-required test_tools: internet_search truncation, missing-key raise, error-swallow. test_health: /health ok, build_agent works WITHOUT Tavily (optional-Tavily proof), build_agent requires OPENAI_API_KEY. Adds pytest pythonpath=['.'] for flat imports. 6 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…v-gated) internal_source_tools() builds langchain-mcp-adapters clients for Linear (LINEAR_API_KEY) and Notion (NOTION_MCP_AUTH_TOKEN), mirroring runtime.ts's transports; returns [] when unconfigured and is failure-safe (a down MCP never breaks startup). Wired into main_tools in both research on/off branches so the agent can consult team docs/issues even without web research. 8 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… in main.py delenv LINEAR_API_KEY/NOTION_MCP_AUTH_TOKEN in the two build tests so they never attempt a real MCP connection regardless of the dev's env; reword main.py module docstring to reflect optional Tavily web research. 8 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ases, docs agent/main.py: remove emit_tool_calls allowlist (it filtered the bridge-forwarded generative-UI + confirm_write HITL tools — cards/write-gate would never surface); honor Railway $PORT; gate uvicorn reload (default off); CORS allow_credentials=false; version 0.1.0. agent/agent.py + tools.py: drop temperature=0.7 (gpt-5.5 rejects it); remove dead @tool internet_search. agent/.env.example: document optional Linear/Notion MCP source vars. render-chart/diagram: post caption only after upload succeeds (no orphaned caption); drop unreachable stringified-chartSpec branch. render-table: surface dropped extra cells. runtime.ts: close late-arriving MCP client (post-timeout leak). docs: correct pnpm agent command + monorepo/standalone naming. agent 8 tests + root 97 tests pass; check-types clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Regressions from round 1: neutralize render-chart/diagram captions (reorder made 'chart/diagram below' wrong); render-table extra-cell note now compares declared columns.length (not clamped) so >20-col tables aren't falsely flagged. Robustness: main.py PORT range/non-numeric validation (fail loud); runtime.ts empty-string PORT -> default 8200; managed.ts gates message-content logging behind CHANNEL_DEBUG; start-notion-mcp exits nonzero on signal death + validates NOTION_MCP_PORT; test_health drops importlib.reload (hermetic vs a present .env). Edge: drop unvalidatable scatter chart type; monospace center-align; page-list renders editedBy independently of edited. agent 8 + root 100 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- tools.py: rename inner research tool to internet_search (prompt/name match); 8s asyncio.wait_for timeout on MCP get_tools (hung server can't block startup) - render-chart/diagram: caption post moved out of the failure try (upload success no longer misreported as render failure), console.error on render failure, Message-rooted caption - render-table: guard the monospace fallback post (returns status string, no throw) - managed.ts: parseProjectId strict /^\d+$/ (reject hex/exp/binary/float typos) - start-notion-mcp: child 'error' listener (clean message on spawn failure) - tests: test_health order/.env-independent + assert research enabled/disabled; exact-count footer assertions; agent.py docstring corrected agent 9 + root 108 tests pass; check-types clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jerelvelarde
added a commit
that referenced
this pull request
Jul 27, 2026
`.migration-discovery.md` was a scratch artifact sitting at the repo root, ungitignored, and contradicted by the PR that carried it: it records the runtime floor staying at ^1.62.3 and channels-intelligence as a direct dep, while the shipped branch raises the floor to ^1.63.2 and drops that dep. Its 571 lines of verified SDK signatures are worth keeping, so move it beside the design doc and plan under docs/superpowers/specs/ (the convention PRs #6 and #7 established) and head it with a note marking it a point-in-time record plus the two places the implementation deliberately diverged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
KiteBot on CopilotKit Intelligence — Phases 1 & 2
Turns OpenTag into KiteBot on the CopilotKit Channels + Intelligence stack, with an optional LangGraph deepagents deep-research brain. Specs + plans under
docs/superpowers/.Phase 1 — Channels migration + Intelligence Gateway
@copilotkit/bot*→@copilotkit/channels*(pure rename; APIs unchanged). Packages are published, so standalonepnpm installworks.kitebot); the project stays "OpenTag".examples/slack).app/managed.ts— the Intelligence Gateway channel host (pnpm channel), using the published two-process pattern (createBot+startChannelsOverRealtimeGateway). Holds no Slack tokens; Intelligence owns the Slack edge.pnpm dev) is the alternative.Phase 2 — LangGraph deepagents deep-research agent (
agent/)agent/, Python 3.12 +uv), ported from CopilotKit'sexamples/showcases/deep-agents: acreate_deep_agentplanner + virtual filesystem, served over AG-UI viaLangGraphAGUIAgent+ FastAPI/uvicorn on:8123. KiteBot's channel host pointsAGENT_URLat it.OPENAI_API_KEYis required; chat + generative-UI rendering work without a key, and web research turns on whenTAVILY_API_KEYis set.runtime.ts.ag_ui_langgraphstate-injection +CopilotKitMiddleware, so KiteBot's rich cards render through the deep agent (confirmed by reading the installed adapter source; the emit-tool-call allowlist that would have suppressed cards + theconfirm_writewrite-gate was removed in review).Code review
Ran the canonical 7-agent
pr-review-toolkitCR over the whole PR — 3 rounds, all findings fixed:$PORT, CORSallow_credentials,temperature=0.7vs gpt-5.5 (reasoning models 400), theemit_tool_callsallowlist (would suppress cards + write-gate), aruntime.tsMCP late-success leak, secret-in-argv instart-notion-mcp, and the multi-provider docs contradiction (runtime is OpenAI-only).parseProjectId, hermetic tests).Per-round wave reviews + a final integration review all approved. Verification:
pnpm check-typesclean, 108 TS tests, 9 Python tests, agent boots +/healthok. (Review stopped at round 3 by maintainer decision — code is green with no known unfixed bug; residual whole-file-review edge findings accepted as follow-up. No CI is configured in the repo.)Still manual (needs live creds)
agent/(OPENAI_API_KEY, optionalTAVILY_API_KEY) + KiteBot with realINTELLIGENCE_*creds; confirm the dashboard flips Waiting for runtime → live and a card renders in Slack. Confirm the channel-name slug (kitebot) and the devapiUrl/wsUrl.Out of scope (Phase 3)
railway.toml+ a Dockerfile are the references.🤖 Generated with Claude Code