Repository navigation
feat(managed-agents): add @chat-adapter/managed-agents with Claude, Cursor, and OpenAI drivers - #1034
roboeve[bot] wants to merge 9 commits into
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…nal text diverges
…ation and API type tests
|
All alerts resolved. Learn more about Socket for GitHub. This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored. |
|
CI on a6cb121 failed at Fix: merged main into the branch and pushed 2d461b6. That commit bumps |
Summary
Adds
@chat-adapter/managed-agents, which runs a hosted agent session in each chat thread. It ships with drivers for Claude Managed Agents, the Cursor SDK, and the OpenAI Agents API.Connecting a hosted agent to Chat SDK takes a lot of glue code today. The Claude Managed Agents template spends about 560 lines mapping threads to sessions, adapting provider events into a
thread.post()stream, reconciling previews with final messages, skipping events from earlier turns, and serializing turns with an in-process queue. Every provider with sessions needs the same chat-side work, so this package does it once.Core
createManagedAgent({ driver })handles the chat side:{ driver, sessionId }in thread state, and starts a new session when the stored one can't be resumed.task_updatechunks.thread.signalaborts.queueconcurrency strategy for turn order, and sends queued messages (context.skipped) with the latest one.A driver implements
ManagedAgentDriver(createSession,resumeSession,runTurn, and an optionalrespondToApproval) and translates provider events intotext-delta,message,tool-call,approval-request,turn-end, andsession-ended. The core never imports a provider SDK. Each SDK is an optional peer dependency that only its subpath uses.The package isn't a platform or state adapter, so it doesn't use the
adapter-*orstate-*naming and konsistent doesn't apply to it.Drivers
/claudeANTHROPIC_API_KEY,CLAUDE_AGENT_ID,CLAUDE_ENVIRONMENT_IDuser.interruptuser.tool_confirmationevents/cursorCURSOR_API_KEY, read by the SDK. Theagentoption is required./openaiOPENAI_API_KEY,OPENAI_AGENT_ID, and optionallyOPENAI_ENVIRONMENT_IDagent.session.input.cancelagent.messageas authoritative over previews, and only reuses sessions owned by the configured agent.AgentNotFoundErroras an ended session.client.beta.agents.sessionsinopenai7.32+). Sending returns no event ID, so the driver anchors on the firstturn.createdevent and ignores events for other turns. Without an environment ID, sessions use{ type: "none" }.Slack task cards
taskDisplay: "timeline" | "plan"sets how Slack groups task cards, throughStreamingPlan(groupTasks).When the final message differs from the streamed preview, the message is edited to the final text only if no task cards were streamed, because an edit replaces the whole message and would remove them. Otherwise the preview stays and a warning is logged. The same applies when
taskDisplayis set, because aStreamingPlanpost returns noSentMessageto edit.Replies after an approval click keep native streaming and task cards. Chat SDK builds the action's thread with the clicking user and the
block_actionspayload, which supply the user and team that Slack's native streaming needs.Example app
examples/nextjs-managed-agentsis a Next.js Slack bot that uses the package.AGENT_PROVIDER=claude|cursor|openaipicks the driver (defaultclaude). The Slack manifest enablesagent_viewandassistant:writefor task cards and the stop button, plus interactivity for approval buttons. The webhook route imports the bot at request time, sonext builddoesn't need agent credentials.Test plan
pnpm --filter @chat-adapter/managed-agents testpasses. It also type-checks the test files throughtsconfig.typecheck.json, aspackages/chatdoes, becausetscskips them.accumulateManagedAgentsEvent.chat.integration.test.tsruns a realChatandThreadImplwith@chat-adapter/testsmocks, from the mention through the approval click to the continuation stream.index.test-d.tschecks the public API types against realChathandlers.typecheck,build,pnpm knip, andpnpm konsistentpass, andultracite checkpasses on the changed files.examples/nextjs-managed-agents,next buildandtsc --noEmitpass with no environment variables set.pnpm validatedoesn't fully pass locally.pnpm checkfails on an existing warning inapps/docs/lib/read-more.ts, andinstallation.test.tsandmain-readme.test.tsneed every package built, so they also fail onmain.user.tool_confirmationevents, which the driver anchors on, and that Cursorassistantevents are deltas.Checklist
git commit -s). Needs a sign-off or remediation commit from the authorpnpm validatepasses (see notes above)/docs/ai/managed-agents)