feat: remote agents - #63
Draft
maxy-shpfy wants to merge 1 commit into
Draft
Conversation
Collaborator
Author
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
This was referenced Jul 17, 2026
maxy-shpfy
force-pushed
the
07-17-feat_remote_agents
branch
from
August 20, 2026 22:51
61faaff to
7ce539e
Compare
maxy-shpfy
force-pushed
the
07-01-refactor_extract_ui-extensions-sdk
branch
from
August 20, 2026 22:51
ba826b5 to
844886d
Compare
This was referenced Aug 20, 2026
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.

TL;DR
Introduces remote and external sub-agent hosting, a generic MCP relay, and the
@tangent/remote-subagentconnector SDK so sub-agents can run outside the localpiprocess.What changed?
Remote sub-agent transport (
RemoteEnvironmentGateway)/remote-env) that a remote environment authenticates against usingREMOTE_ENV_TOKEN.RemoteEnvironmentGatewayexposes the samespawnSubagent/sendToAgent/killAgent/listSubagents/hasAgentsurface asPiAgentManager, so the internal agents API can route a sub-agent to either host transparently.PiAgentHandlersa local sub-agent uses; finalized auto-relay replies andmessage_prime-style reports are fed into Prime via adeliverToPrimecallback.host: "remote"and are skipped byreviveSubagentson restart.External sub-agent gateway (
ExternalSubagentGateway)POST /internal/external-agents/{register,event,status}.PiAgentHandlersrelay path as local and remote sub-agents.Generic MCP relay (
RelayRegistry+McpRelayServer)RelayRegistrymanages ephemeral relay channels, each bound to a session and protected by a per-channel bearer secret.McpRelayServerspeaks the MCP JSON-RPC subset an external client exercises (initialize,tools/list,tools/call) and exposes two tools —send_to_prime(fire-and-forget) andask_prime(blocking poll up to 25 s) — that forward to the channel's session Prime.POST /internal/mcp-relay/open(requiresTANGENT_PUBLIC_URL), poll/answer pending questions, and close channels. The external client dialsPOST /api/mcp/:channelIdwith its per-channel bearer.@tangent/remote-subagentpackagespawn/message/killcommands to user-supplied handlers, and exposes typed helpers (agentEvent,subagentUpdate,report,readRoom,disconnect). Ships no agent runtime.Shared contracts (
@tangent/shared)SubagentHosttype ("local" | "remote") andhostfield onSubagentInfo.remoteSubagent.tswith all wire shapes (RemoteEnvHandshake,RemoteEnvEvents,RemoteSpawnCommand,RemoteMessageCommand,RemoteKillCommand,RemoteAgentEvent, and payload/response types) shared by both sides of the transport.spawn_subagentorchestrator toolenvironmentparameter (local|remote) that flows throughPOST /internal/agents/spawnand routes the spawn to the appropriate host.Database
0005_quick_lifeguardadds ahostcolumn (default'local') tosession_agents.Sub-agent roster
handleChatJoinand the internal agentslistendpoint now merge local, remote, and external rosters before emitting to the UI.How to test?
Remote sub-agents: Set
REMOTE_ENV_TOKENto a shared secret. Connect a remote environment usingconnectRemoteEnvironmentfrom@tangent/remote-subagentwith matching credentials. Ask Prime tospawn_subagentwithenvironment: "remote"and verify the tab appears in the sidebar and streams events correctly. Disconnect the environment and confirm active remote sub-agents transition toerror.External sub-agents: From a bundle tool, call
POST /internal/external-agents/registerto create a tab, thenPOST /internal/external-agents/eventto stream events into it, andPOST /internal/external-agents/statusto mark it complete. Verify the tab renders and updates in the sidebar.MCP relay: Set
TANGENT_PUBLIC_URLto a reachable base URL. Open a channel viaPOST /internal/mcp-relay/open. Point an MCP client at the returnedurlwith the returnedsecretas a bearer token. Calltools/listandtools/callforsend_to_primeandask_prime. Verify messages arrive in Prime and thatask_primeresolves after answering viaPOST /internal/mcp-relay/:channelId/answer.Unit tests: Run the new test files
externalSubagentGateway.test.tsandrelayRegistry.test.tswithnode --test.Restart resilience: Spawn a remote sub-agent, restart the server, and confirm it is not revived (unlike local sub-agents).
Why make this change?
Local
pichild processes are the only sub-agent host today, which limits where agent work can run. This change decouples the sub-agent interface (roster, streaming events, relay to Prime) from the runtime, enabling three new hosting modes: a connected remote environment (for agent runtimes that live outside the server process), an external bridge (for bundle tools that drive a proprietary runtime and only need a sidebar tab), and a generic MCP relay (for external clients that speak standard MCP and need to communicate with Prime). All three share the same relay handlers and persistence path as local sub-agents, so the UI and storage layers require no per-host changes.