Make LangChain the default harness, and let a framework Bot call tools back - #33
Open
davidmckayv wants to merge 1 commit into
Open
Make LangChain the default harness, and let a framework Bot call tools back#33davidmckayv wants to merge 1 commit into
davidmckayv wants to merge 1 commit into
Conversation
`agent-bot` hand-writes the AG-UI protocol and leaves the tool loop to whatever is watching. That is a fine reference and a bad thing to build a deployment on, so the default teammate endpoint is now `agent-langgraph` on 4201: a real framework, running a real loop. The loop moves into the agent, and stays governed. A framework Bot that called an MCP server directly would be a Bot that walked around the grant, the policy and the audit row, which are the product. So it calls back to `/api/agent-tools/call`, authenticated by a shared secret because the caller is a service with no person behind it, and that route goes through the same plugin store as everything else. No secret configured means the route does not exist and the Bot is told so, rather than a deployment quietly accepting anybody who can reach the port. The runtime now sends a remote agent the tools its Bot was granted, on every run rather than configured once, so a grant added or revoked applies to the next run and not after a restart. Two defects fixed on the way. `BOT_MODEL` arrived from compose as an empty string, which is a value, so the agent asked its provider for a model named "" and every run died with "you must provide a model parameter" — read as a broken Bot rather than missing configuration. And the run emitted its answer before the tool calls that informed it, so the surface drew a Bot that spoke first and worked afterwards; tool events are now sent as they happen, with each stretch of prose owning its own message id. Driven in a browser: the LangGraph Bot answered a question about the expense policy, the transcript drew the tool line and then the answer with its source link, and the audit row names risk-analyst calling through the deployment rather than the vendor.
davidmckayv
requested review from
MikeRyanDev,
guidovizoso and
tylerslaton
as code owners
August 20, 2026 03:52
8 tasks
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.
What this changes
agent-bothand-writes the AG-UI protocol over the raw OpenAI SDK, 235 lines, with its own tool loop. It is a fine reference and a bad thing to build a deployment on, and it was the default:MANAGED_AGENT_AG_UI_URLpointed at it on 4200, so the Bot we ship as the example of "bring your own" was the hand-rolled one while the real framework sat unused on 4201.The default is now
agent-langgraph: real@langchain/langgraph, running a real loop.agent-botstays in the tree as the reference it always was.This also closes the regression #31 disclosed. A framework Bot runs its own loop in its own process, which is the honest shape, but it must not have a route to a vendor that goes around this deployment. So it calls back to
/api/agent-tools/call, which goes through the same plugin store as everything else: same grant check, same policy, same audit row. Remote Bots have MCP tools again.The runtime sends a remote Bot its granted tools on every run rather than at configuration time, so a grant added or revoked applies to the next run instead of after a restart.
Taken from
CopilotKit/openkai(bc246d4), minus its visitor demo, withOPENKAI_/x-openkai-renamed and the refusal marker from #31 applied to this path too.Two defects it also fixes
BOT_MODELarrived from compose as an empty string, which is a value, so the agent asked its provider for a model named""and every run died with "you must provide a model parameter". That reads as a broken Bot rather than as missing configuration. Compose now defaults it.Where it runs
AGENT_TOOL_TOKENis set, so a deployment that has not configured it refuses rather than accepting anybody who can reach the port.Boundary and audit
pluginStore.callTool: grant, then policy, then audit, then the vendor.Known weakness, and the next PR
The actor on this path is not trustworthy yet.
/api/agent-tools/callreadsactorIdfrom the request body and falls back to"agent". Two consequences, both visible in the audit row I captured below:agent.The trail is the product, so a forgeable trail is worse than a thin one. The next PR replaces the shared secret with a per-agent token plus a signed, expiring run assertion that names the Bot and the person, and refuses a call whose assertion does not match the token presenting it. Landing immediately after this one.
Proof
Driven in Chrome.
agent-langgraphrebuilt and started on 4201,AGENT_TOOL_TOKENset,search_notesgranted to Risk Analyst through/admin/plugins.mcp.call_succeeded,notes/search_notes, botrisk-analyst, allowedtrue. Actoragent, which is the weakness above.401with no token,400with the token and no body.format:check,lint,typecheckclean. 665 pass, 5 skip, 0 fail.