@rk0429/agentic-relay 2.0.10 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +11 -318
  2. package/dist/application/spawn-agents-service.d.ts +20 -0
  3. package/dist/application/spawn-agents-service.js +222 -0
  4. package/dist/application/spawn-agents-service.js.map +1 -0
  5. package/dist/bin/relay.d.ts +2 -0
  6. package/dist/bin/relay.js +47 -0
  7. package/dist/bin/relay.js.map +1 -0
  8. package/dist/core/errors.d.ts +14 -0
  9. package/dist/core/errors.js +29 -0
  10. package/dist/core/errors.js.map +1 -0
  11. package/dist/core/types.d.ts +69 -0
  12. package/dist/core/types.js +10 -0
  13. package/dist/core/types.js.map +1 -0
  14. package/dist/domain/depth.d.ts +3 -0
  15. package/dist/domain/depth.js +31 -0
  16. package/dist/domain/depth.js.map +1 -0
  17. package/dist/domain/routing.d.ts +8 -0
  18. package/dist/domain/routing.js +58 -0
  19. package/dist/domain/routing.js.map +1 -0
  20. package/dist/index.d.ts +8 -0
  21. package/dist/index.js +9 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/infrastructure/backends/backend-registry.d.ts +20 -0
  24. package/dist/infrastructure/backends/backend-registry.js +86 -0
  25. package/dist/infrastructure/backends/backend-registry.js.map +1 -0
  26. package/dist/infrastructure/backends/cli-backend-executor.d.ts +12 -0
  27. package/dist/infrastructure/backends/cli-backend-executor.js +210 -0
  28. package/dist/infrastructure/backends/cli-backend-executor.js.map +1 -0
  29. package/dist/infrastructure/process/process-executor.d.ts +18 -0
  30. package/dist/infrastructure/process/process-executor.js +54 -0
  31. package/dist/infrastructure/process/process-executor.js.map +1 -0
  32. package/dist/infrastructure/store/relay-store.d.ts +14 -0
  33. package/dist/infrastructure/store/relay-store.js +68 -0
  34. package/dist/infrastructure/store/relay-store.js.map +1 -0
  35. package/dist/interfaces/mcp/relay-mcp-server.d.ts +7 -0
  36. package/dist/interfaces/mcp/relay-mcp-server.js +54 -0
  37. package/dist/interfaces/mcp/relay-mcp-server.js.map +1 -0
  38. package/package.json +18 -54
  39. package/LICENSE +0 -201
  40. package/dist/relay.mjs +0 -14131
package/README.md CHANGED
@@ -1,329 +1,22 @@
1
1
  # agentic-relay
2
2
 
3
- [![CI](https://github.com/RK0429/agentic-relay/actions/workflows/ci.yml/badge.svg)](https://github.com/RK0429/agentic-relay/actions/workflows/ci.yml)
4
- [![npm version](https://img.shields.io/npm/v/@rk0429/agentic-relay)](https://www.npmjs.com/package/@rk0429/agentic-relay)
5
- [![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
6
- [![Node.js](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](https://nodejs.org/)
3
+ `agentic-relay` is a TypeScript MCP server that launches Claude Code, Codex CLI,
4
+ and Gemini CLI through a single `spawn_agents` tool.
7
5
 
8
- A unified CLI that brings Claude Code, Codex CLI, and Gemini CLI under a single interface -- solving tool fragmentation, enabling multi-layer sub-agent orchestration via MCP, and providing proactive context window monitoring.
6
+ ## Current scope
9
7
 
10
- ## Why agentic-relay?
8
+ - Phase 1 foundation from `docs/requirements.md`
9
+ - `relay mcp serve` over stdio
10
+ - Parallel `spawn_agents`
11
+ - Backend routing, depth guard, response persistence, and session metadata
12
+ - Automatic cross-backend handoff when `session_id` is resumed with a different backend
11
13
 
12
- Working with multiple AI coding CLIs means juggling different command syntaxes, configurations, and authentication flows. Nesting sub-agents across tools is not supported natively. And context window exhaustion catches you off guard.
13
-
14
- agentic-relay addresses three problems:
15
-
16
- | Problem | Solution |
17
- |---|---|
18
- | **Tool fragmentation** -- three CLIs with different flags, config formats, and auth mechanisms | Unified interface with backend adapters that normalize the differences |
19
- | **No nested sub-agents** -- parent agents cannot spawn grandchild agents through different backends | MCP server mode lets any MCP-capable client spawn agents across all three backends, with recursion guards |
20
- | **Context window surprise** -- sessions silently hit token limits | Hooks + ContextMonitor track usage and notify before the limit is reached |
21
-
22
- ## Prerequisites
23
-
24
- - Node.js 22+
25
- - One or more backend tools installed: [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Codex CLI](https://github.com/openai/codex), or [Gemini CLI](https://github.com/google-gemini/gemini-cli)
26
- - macOS 13+ / Ubuntu 22.04+ / Debian 12+
27
-
28
- ## Installation
29
-
30
- ```bash
31
- # Install globally
32
- npm install -g @rk0429/agentic-relay
33
-
34
- # Initialize project-level config (optional)
35
- relay init
36
-
37
- # Verify installation
38
- relay doctor
39
- ```
40
-
41
- ### From Source
14
+ ## Usage
42
15
 
43
16
  ```bash
44
- git clone https://github.com/RK0429/agentic-relay.git
45
- cd agentic-relay
46
17
  pnpm install
47
18
  pnpm build
48
- pnpm link --global
49
- ```
50
-
51
- ## Quick Start
52
-
53
- ```bash
54
- # Start an interactive session with Claude Code
55
- relay claude
56
-
57
- # One-shot prompt with Codex CLI
58
- relay codex -p "Refactor this function to use async/await"
59
-
60
- # Continue the latest Gemini session
61
- relay gemini -c
62
-
63
- # Check which backends are available
64
- relay doctor
65
- ```
66
-
67
- ## Usage
68
-
69
- ### Backend Commands
70
-
71
- ```bash
72
- relay claude|codex|gemini # Interactive mode
73
- relay claude|codex|gemini -p "query" # Non-interactive (one-shot)
74
- relay claude|codex|gemini -c # Continue latest session
75
- relay claude|codex|gemini -r ID # Resume session by ID
76
- relay claude|codex|gemini --agent NAME # Specify agent
77
- relay claude|codex|gemini --model NAME # Specify model
78
- ```
79
-
80
- ### Management Commands
81
-
82
- ```bash
83
- relay config show # Show merged config
84
- relay config get <key> # Get config value
85
- relay config set <key> <value> # Set config value
86
- relay auth <backend> login # Authenticate a backend
87
- relay auth <backend> status # Check auth status
88
- relay sessions # List/search sessions
89
- relay update # Update backend tools
90
- relay version # Show versions
91
- relay doctor # Run diagnostics
92
- relay init # Initialize .relay/ config
93
- ```
94
-
95
- ### MCP Commands
96
-
97
- ```bash
98
- relay mcp list # List MCP servers
99
- relay mcp add <name> -- CMD # Add MCP server
100
- relay mcp remove <name> # Remove MCP server
101
- relay mcp sync # Sync MCP config to backends
102
- relay mcp serve # Start as MCP server (stdio, default)
103
- relay mcp serve --transport http # Start as MCP server (HTTP)
104
- relay mcp serve --transport http --port 8080 # Custom port
105
- ```
106
-
107
- ## Configuration
108
-
109
- agentic-relay uses a three-tier configuration system. Each tier overrides the one above it.
110
-
111
- | Tier | Path | Scope |
112
- |---|---|---|
113
- | Global | `~/.relay/config.json` | User-wide defaults |
114
- | Project | `.relay/config.json` | Shared across team (commit to VCS) |
115
- | Local | `.relay/config.local.json` | Personal overrides (gitignored) |
116
-
117
- Example configuration:
118
-
119
- ```json
120
- {
121
- "defaultBackend": "claude",
122
- "mcpServers": {
123
- "filesystem": {
124
- "command": "npx",
125
- "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"]
126
- }
127
- },
128
- "hooks": {
129
- "hooks": [
130
- {
131
- "event": "ContextThreshold",
132
- "command": ["node", "scripts/save-state.js"],
133
- "timeoutMs": 5000,
134
- "onError": "warn"
135
- }
136
- ]
137
- },
138
- "contextMonitor": {
139
- "enabled": true,
140
- "thresholdPercent": 75,
141
- "notifyMethod": "hook"
142
- }
143
- }
19
+ pnpm relay mcp serve
144
20
  ```
145
21
 
146
- ### Environment Variables
147
-
148
- | Variable | Description | Default |
149
- |---|---|---|
150
- | `RELAY_HOME` | Home directory for relay | `~/.relay` |
151
- | `RELAY_LOG_LEVEL` | Log level (debug/info/warn/error) | `info` |
152
- | `RELAY_MAX_DEPTH` | Max recursion depth in MCP server mode | `5` |
153
- | `RELAY_CONTEXT_THRESHOLD` | Context warning threshold (%) | `75` |
154
- | `RELAY_CLAUDE_PERMISSION_MODE` | Claude permission mode (`bypassPermissions` or `default`) | `bypassPermissions` |
155
- | `ANTHROPIC_API_KEY` | Passed through to Claude Code (optional with subscription) | -- |
156
- | `OPENAI_API_KEY` | Passed through to Codex CLI (optional with subscription) | -- |
157
- | `GEMINI_API_KEY` | Passed through to Gemini CLI (optional with subscription) | -- |
158
-
159
- ### Security Considerations
160
-
161
- - **Claude adapter permission bypass**: By default, the Claude adapter runs with `bypassPermissions` mode to enable non-interactive sub-agent execution. This means spawned Claude Code agents can execute tools without user confirmation. To change this behavior, set the `RELAY_CLAUDE_PERMISSION_MODE` environment variable to `default`.
162
-
163
- ## MCP Server Mode
164
-
165
- agentic-relay can act as an MCP (Model Context Protocol) server, allowing any MCP-capable client to spawn sub-agents across all three backends. This is how nested sub-agent orchestration works -- a parent agent calls relay via MCP, which spawns a child agent on any backend, and that child can call relay again to spawn a grandchild.
166
-
167
- ### Setup
168
-
169
- Add relay as an MCP server in your client's configuration. For Claude Code:
170
-
171
- ```json
172
- {
173
- "mcpServers": {
174
- "relay": {
175
- "command": "relay",
176
- "args": ["mcp", "serve"]
177
- }
178
- }
179
- }
180
- ```
181
-
182
- ### Exposed Tools
183
-
184
- | Tool | Description |
185
- |---|---|
186
- | `spawn_agent` | Spawn a sub-agent on a specified backend |
187
- | `list_sessions` | Retrieve session history |
188
- | `get_context_status` | Query context window usage |
189
-
190
- ### Recursion Guard
191
-
192
- The MCP server includes a three-layer recursion guard to prevent runaway agent chains:
193
-
194
- 1. **Depth limit** -- rejects calls that exceed the maximum nesting depth (default: 5)
195
- 2. **Per-session call limit** -- caps the total number of spawns within a single session (default: 20)
196
- 3. **Loop detection** -- identifies repeated calls with the same backend + prompt hash
197
-
198
- Context propagation between parent and child agents uses environment variables: `RELAY_TRACE_ID`, `RELAY_PARENT_SESSION_ID`, and `RELAY_DEPTH`.
199
-
200
- ### Multi-layer Agent Call Flow
201
-
202
- ```mermaid
203
- sequenceDiagram
204
- participant User
205
- participant Parent as Parent Agent<br>(Claude Code)
206
- participant Relay as agentic-relay<br>(MCP Server)
207
- participant Child as Child Agent<br>(Codex CLI)
208
- participant Relay2 as agentic-relay<br>(MCP Server)
209
- participant Grandchild as Grandchild Agent<br>(Gemini CLI)
210
-
211
- User->>Parent: Task request
212
- Parent->>Relay: spawn_agent(codex, prompt)
213
- Note over Relay: RecursionGuard check<br>depth=1, calls=1
214
- Relay->>Child: Codex SDK thread.run("prompt")<br>RELAY_DEPTH=1
215
- Child->>Relay2: spawn_agent(gemini, sub-prompt)
216
- Note over Relay2: RecursionGuard check<br>depth=2, calls=1
217
- Relay2->>Grandchild: gemini -p "sub-prompt"<br>RELAY_DEPTH=2
218
- Grandchild-->>Relay2: Result
219
- Relay2-->>Child: Result
220
- Child-->>Relay: Result
221
- Relay-->>Parent: Result
222
- Parent-->>User: Final answer
223
- ```
224
-
225
- ## Architecture
226
-
227
- agentic-relay is organized into six layers.
228
-
229
- ```mermaid
230
- graph TD
231
- A["CLI Layer<br><i>citty entry point</i>"] --> B["Command Handlers<br><i>backend, mcp, config, auth,<br>update, sessions, version, doctor, init</i>"]
232
- B --> C["Core Layer<br><i>SessionManager, ConfigManager,<br>AuthManager, HooksEngine,<br>ContextMonitor, EventBus</i>"]
233
- B --> D["MCP Server<br><i>RelayMCPServer,<br>spawn_agent, list_sessions,<br>get_context_status, RecursionGuard</i>"]
234
- C --> E["Backend Adapters<br><i>BaseAdapter, ClaudeAdapter,<br>CodexAdapter, GeminiAdapter,<br>FlagMapper</i>"]
235
- C --> F["Infrastructure<br><i>ProcessManager, Logger</i>"]
236
- D --> E
237
- D --> F
238
- ```
239
-
240
- ### Backend Adapters
241
-
242
- Each backend CLI has different flags, output formats, and session handling. The adapter layer normalizes these differences behind a common `BackendAdapter` interface. Adding a new backend means implementing this interface and registering it with the `AdapterRegistry`.
243
-
244
- Non-interactive execution uses official SDKs where available:
245
-
246
- | Backend | Non-interactive (`-p`) | Interactive | Session listing |
247
- |---|---|---|---|
248
- | Claude Code | Agent SDK `query()` | CLI spawn | Agent SDK `listSessions()` |
249
- | Codex CLI | Codex SDK `thread.run()` | CLI spawn | -- |
250
- | Gemini CLI | CLI spawn | CLI spawn | CLI `--list-sessions` |
251
-
252
- ### Hooks Engine
253
-
254
- An event-driven hook system that executes external commands via stdin/stdout JSON pipes.
255
-
256
- | Event | Trigger |
257
- |---|---|
258
- | `SessionStart` / `SessionEnd` | Session lifecycle |
259
- | `PreToolUse` / `PostToolUse` | Tool invocation |
260
- | `PreCompact` | Before context compaction |
261
- | `ContextThreshold` | Context usage exceeds threshold (relay-specific) |
262
- | `SubagentSpawn` / `SubagentComplete` | Sub-agent lifecycle (relay-specific) |
263
-
264
- ### Context Monitor
265
-
266
- Monitors context window usage and fires `ContextThreshold` events when usage exceeds the configured threshold. Notification methods: `stderr` (direct output) or `hook` (triggers the Hooks Engine).
267
-
268
- ## Project Structure
269
-
270
- ```
271
- src/
272
- bin/relay.ts # Entry point
273
- commands/ # Command handlers
274
- backend.ts # relay claude/codex/gemini
275
- mcp.ts # relay mcp (list/add/remove/sync/serve)
276
- config.ts # relay config
277
- auth.ts # relay auth
278
- update.ts # relay update
279
- sessions.ts # relay sessions
280
- version.ts # relay version
281
- doctor.ts # relay doctor
282
- init.ts # relay init
283
- core/ # Core modules
284
- session-manager.ts
285
- config-manager.ts
286
- auth-manager.ts
287
- hooks-engine.ts
288
- context-monitor.ts
289
- event-bus.ts
290
- adapters/ # Backend adapters
291
- base-adapter.ts
292
- claude-adapter.ts
293
- codex-adapter.ts
294
- gemini-adapter.ts
295
- adapter-registry.ts
296
- flag-mapper.ts
297
- install-guides.ts
298
- mcp-server/ # MCP server mode
299
- server.ts
300
- recursion-guard.ts
301
- tools/
302
- spawn-agent.ts
303
- list-sessions.ts
304
- get-context-status.ts
305
- infrastructure/ # Infrastructure
306
- process-manager.ts
307
- logger.ts
308
- types/ # Type definitions
309
- schemas/ # Zod validation schemas
310
- ```
311
-
312
- ## Tech Stack
313
-
314
- - **Runtime**: Node.js 22+
315
- - **Language**: TypeScript
316
- - **Package manager**: pnpm
317
- - **CLI framework**: citty
318
- - **Bundler**: tsup (esbuild-based)
319
- - **Backend SDKs**: @anthropic-ai/claude-agent-sdk, @openai/codex-sdk
320
- - **MCP**: @modelcontextprotocol/sdk
321
- - **Process management**: execa (interactive modes, Gemini CLI)
322
- - **Validation**: zod
323
- - **Logging**: consola
324
- - **Testing**: vitest (771 tests across 35 files)
325
- - **Coverage**: @vitest/coverage-v8
326
-
327
- ## License
328
-
329
- Apache-2.0
22
+ Responses are stored under `.relay/` in the current working directory.
@@ -0,0 +1,20 @@
1
+ import type { SpawnAgentResult, SpawnAgentsInput } from "../core/types.js";
2
+ import { BackendRegistry } from "../infrastructure/backends/backend-registry.js";
3
+ import { CliBackendExecutor } from "../infrastructure/backends/cli-backend-executor.js";
4
+ import { RelayStore } from "../infrastructure/store/relay-store.js";
5
+ export declare class SpawnAgentsService {
6
+ private readonly dependencies;
7
+ constructor(dependencies: {
8
+ backendRegistry: BackendRegistry;
9
+ backendExecutor: Pick<CliBackendExecutor, "execute">;
10
+ store: RelayStore;
11
+ cwd: string;
12
+ env?: NodeJS.ProcessEnv;
13
+ });
14
+ spawnAgents(input: SpawnAgentsInput, options?: {
15
+ signal?: AbortSignal;
16
+ }): Promise<SpawnAgentResult[]>;
17
+ private spawnSingleAgent;
18
+ private persistSuccess;
19
+ private persistFailure;
20
+ }
@@ -0,0 +1,222 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { DepthLimitError } from "../core/errors.js";
3
+ import { getCurrentDepth, resolveMaxDepth, validateDepth } from "../domain/depth.js";
4
+ import { resolveBackend } from "../domain/routing.js";
5
+ export class SpawnAgentsService {
6
+ dependencies;
7
+ constructor(dependencies) {
8
+ this.dependencies = dependencies;
9
+ }
10
+ async spawnAgents(input, options = {}) {
11
+ const env = this.dependencies.env ?? process.env;
12
+ const currentDepth = getCurrentDepth(env);
13
+ const maxDepth = resolveMaxDepth(input.max_depth, env);
14
+ validateDepth(currentDepth, maxDepth);
15
+ const installedBackends = await this.dependencies.backendRegistry.detectInstalled();
16
+ return Promise.all(input.agents.map((agent) => this.spawnSingleAgent({
17
+ agent,
18
+ currentDepth,
19
+ maxDepth,
20
+ installedBackends,
21
+ signal: options.signal,
22
+ })));
23
+ }
24
+ async spawnSingleAgent(options) {
25
+ const { agent, currentDepth, maxDepth, installedBackends, signal } = options;
26
+ const relaySessionId = randomUUID();
27
+ try {
28
+ const resumeMetadata = agent.session_id
29
+ ? await this.dependencies.store.readSessionMetadata(agent.session_id)
30
+ : null;
31
+ const resumeResponse = agent.session_id && resumeMetadata
32
+ ? await this.dependencies.store.readResponse(agent.session_id)
33
+ : null;
34
+ const routing = resolveBackend({
35
+ explicitBackend: agent.backend ?? resumeMetadata?.backend,
36
+ taskType: agent.task_type,
37
+ installedBackends,
38
+ });
39
+ const handoff = createHandoffInfo({
40
+ requestedSessionId: agent.session_id,
41
+ resumeMetadata,
42
+ resolvedBackend: routing.resolved,
43
+ });
44
+ const prompt = handoff
45
+ ? buildCrossBackendHandoffPrompt({
46
+ sourceBackend: handoff.source_backend,
47
+ sourceSessionId: handoff.source_session_id,
48
+ responsePath: handoff.response_path,
49
+ responseContent: resumeResponse,
50
+ userPrompt: agent.prompt,
51
+ })
52
+ : agent.prompt;
53
+ await this.dependencies.store.appendLog(createLogEntry({
54
+ sessionId: relaySessionId,
55
+ taskId: agent.task_id,
56
+ backend: routing.resolved,
57
+ eventType: "agent_spawned",
58
+ status: "running",
59
+ details: {
60
+ requested_backend: agent.backend,
61
+ task_type: agent.task_type,
62
+ handoff_mode: handoff?.mode,
63
+ handoff_source_session_id: handoff?.source_session_id,
64
+ },
65
+ }));
66
+ if (routing.fellBack) {
67
+ await this.dependencies.store.appendLog(createLogEntry({
68
+ sessionId: relaySessionId,
69
+ taskId: agent.task_id,
70
+ backend: routing.resolved,
71
+ eventType: "routing_fallback",
72
+ status: "success",
73
+ details: {
74
+ fallback_reason: routing.fallbackReason,
75
+ },
76
+ }));
77
+ }
78
+ const executionResult = await this.dependencies.backendExecutor.execute({
79
+ relaySessionId,
80
+ backend: routing.resolved,
81
+ prompt,
82
+ systemPrompt: agent.system_prompt,
83
+ backendSessionId: handoff
84
+ ? undefined
85
+ : resumeMetadata?.backendSessionId ?? agent.session_id,
86
+ cwd: this.dependencies.cwd,
87
+ env: {
88
+ ...process.env,
89
+ ...(this.dependencies.env ?? {}),
90
+ RELAY_CALL_DEPTH: String(currentDepth + 1),
91
+ RELAY_MAX_DEPTH: String(maxDepth),
92
+ RELAY_ALLOW_SPAWN_AGENTS: agent.task_type === "orchestration" ? "1" : "0",
93
+ },
94
+ signal,
95
+ });
96
+ return await this.persistSuccess({
97
+ relaySessionId,
98
+ agent,
99
+ backend: routing.resolved,
100
+ routing,
101
+ executionResult,
102
+ handoff,
103
+ });
104
+ }
105
+ catch (error) {
106
+ if (error instanceof DepthLimitError) {
107
+ throw error;
108
+ }
109
+ return await this.persistFailure({
110
+ relaySessionId,
111
+ agent,
112
+ error,
113
+ });
114
+ }
115
+ }
116
+ async persistSuccess(options) {
117
+ const summary = summarize(options.executionResult.output);
118
+ const responsePath = await this.dependencies.store.writeResponse(options.relaySessionId, options.executionResult.output);
119
+ const now = new Date().toISOString();
120
+ const metadata = {
121
+ relaySessionId: options.relaySessionId,
122
+ backend: options.backend,
123
+ backendSessionId: options.executionResult.backendSessionId,
124
+ cwd: this.dependencies.cwd,
125
+ createdAt: now,
126
+ updatedAt: now,
127
+ handoffFrom: options.handoff,
128
+ };
129
+ await this.dependencies.store.writeSessionMetadata(metadata);
130
+ await this.dependencies.store.appendLog(createLogEntry({
131
+ sessionId: options.relaySessionId,
132
+ taskId: options.agent.task_id,
133
+ backend: options.backend,
134
+ eventType: "agent_completed",
135
+ status: "success",
136
+ }));
137
+ return {
138
+ session_id: options.relaySessionId,
139
+ backend: options.backend,
140
+ summary,
141
+ full_response_path: responsePath,
142
+ status: "success",
143
+ routing: options.routing,
144
+ handoff: options.handoff,
145
+ };
146
+ }
147
+ async persistFailure(options) {
148
+ const message = options.error instanceof Error ? options.error.message : String(options.error);
149
+ const responsePath = await this.dependencies.store.writeResponse(options.relaySessionId, message);
150
+ const backend = options.agent.backend ?? "claude";
151
+ await this.dependencies.store.appendLog(createLogEntry({
152
+ sessionId: options.relaySessionId,
153
+ taskId: options.agent.task_id,
154
+ backend,
155
+ eventType: "agent_failed",
156
+ status: "error",
157
+ details: {
158
+ error: message,
159
+ },
160
+ }));
161
+ return {
162
+ session_id: options.relaySessionId,
163
+ backend,
164
+ summary: summarize(message),
165
+ full_response_path: responsePath,
166
+ status: "error",
167
+ routing: {
168
+ resolved: backend,
169
+ fellBack: false,
170
+ },
171
+ };
172
+ }
173
+ }
174
+ function summarize(content) {
175
+ return content.slice(0, 500);
176
+ }
177
+ function createLogEntry(options) {
178
+ return {
179
+ timestamp: new Date().toISOString(),
180
+ session_id: options.sessionId,
181
+ task_id: options.taskId,
182
+ backend: options.backend,
183
+ event_type: options.eventType,
184
+ status: options.status,
185
+ details: options.details,
186
+ };
187
+ }
188
+ function createHandoffInfo(options) {
189
+ const { requestedSessionId, resumeMetadata, resolvedBackend } = options;
190
+ if (!requestedSessionId || !resumeMetadata) {
191
+ return undefined;
192
+ }
193
+ if (resumeMetadata.backend === resolvedBackend) {
194
+ return undefined;
195
+ }
196
+ return {
197
+ mode: "cross_backend_handoff",
198
+ source_session_id: requestedSessionId,
199
+ source_backend: resumeMetadata.backend,
200
+ response_path: `${resumeMetadata.cwd}/.relay/responses/${requestedSessionId}.md`,
201
+ };
202
+ }
203
+ function buildCrossBackendHandoffPrompt(options) {
204
+ const excerpt = (options.responseContent ?? "").slice(0, 4000);
205
+ const excerptNote = options.responseContent && options.responseContent.length > 4000
206
+ ? "\nNote: the excerpt below is truncated. Read the full file if more context is needed."
207
+ : "";
208
+ return [
209
+ "Cross-backend handoff context:",
210
+ `- Source backend: ${options.sourceBackend}`,
211
+ `- Source relay session: ${options.sourceSessionId}`,
212
+ `- Full response path: ${options.responsePath}`,
213
+ excerptNote,
214
+ "",
215
+ "Previous backend final response excerpt:",
216
+ excerpt || "(response file could not be loaded)",
217
+ "",
218
+ "Continue the work using the following user prompt:",
219
+ options.userPrompt,
220
+ ].join("\n");
221
+ }
222
+ //# sourceMappingURL=spawn-agents-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-agents-service.js","sourceRoot":"","sources":["../../src/application/spawn-agents-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { SpawnAgentsService } from "../application/spawn-agents-service.js";
5
+ import { BackendRegistry } from "../infrastructure/backends/backend-registry.js";
6
+ import { CliBackendExecutor } from "../infrastructure/backends/cli-backend-executor.js";
7
+ import { ChildProcessExecutor } from "../infrastructure/process/process-executor.js";
8
+ import { RelayStore } from "../infrastructure/store/relay-store.js";
9
+ import { createRelayMcpServer, serveRelayMcpServer, } from "../interfaces/mcp/relay-mcp-server.js";
10
+ async function main() {
11
+ const args = process.argv.slice(2);
12
+ const cwd = process.cwd();
13
+ if (args[0] !== "mcp" || args[1] !== "serve") {
14
+ printHelp();
15
+ process.exitCode = 1;
16
+ return;
17
+ }
18
+ const backendRegistry = new BackendRegistry();
19
+ const installed = await backendRegistry.detectInstalled();
20
+ if (installed.length === 0) {
21
+ console.error("agentic-relay: no supported backend CLI is installed.");
22
+ process.exitCode = 1;
23
+ return;
24
+ }
25
+ const store = new RelayStore(path.join(cwd, ".relay"));
26
+ const service = new SpawnAgentsService({
27
+ backendRegistry,
28
+ backendExecutor: new CliBackendExecutor(backendRegistry, new ChildProcessExecutor()),
29
+ store,
30
+ cwd,
31
+ env: process.env,
32
+ });
33
+ const server = createRelayMcpServer({
34
+ service,
35
+ allowSpawnAgents: process.env.RELAY_ALLOW_SPAWN_AGENTS !== "0",
36
+ });
37
+ await serveRelayMcpServer(server);
38
+ }
39
+ function printHelp() {
40
+ const scriptName = path.basename(fileURLToPath(import.meta.url));
41
+ console.error(`Usage: ${scriptName} mcp serve`);
42
+ }
43
+ main().catch((error) => {
44
+ console.error(error instanceof Error ? error.message : "agentic-relay failed unexpectedly.");
45
+ process.exitCode = 1;
46
+ });
47
+ //# sourceMappingURL=relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/bin/relay.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oDAAoD,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,uCAAuC,CAAC;AAE/C,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAC7C,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9C,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,eAAe,EAAE,CAAC;IAC1D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC;QACrC,eAAe;QACf,eAAe,EAAE,IAAI,kBAAkB,CACrC,eAAe,EACf,IAAI,oBAAoB,EAAE,CAC3B;QACD,KAAK;QACL,GAAG;QACH,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,oBAAoB,CAAC;QAClC,OAAO;QACP,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG;KAC/D,CAAC,CAAC;IAEH,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,UAAU,UAAU,YAAY,CAAC,CAAC;AAClD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oCAAoC,CAC9E,CAAC;IACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ export declare class RelayError extends Error {
2
+ readonly code: string;
3
+ readonly causeData?: unknown;
4
+ constructor(code: string, message: string, causeData?: unknown);
5
+ }
6
+ export declare class ValidationError extends RelayError {
7
+ constructor(message: string, causeData?: unknown);
8
+ }
9
+ export declare class DepthLimitError extends RelayError {
10
+ constructor(message: string);
11
+ }
12
+ export declare class BackendUnavailableError extends RelayError {
13
+ constructor(message: string, causeData?: unknown);
14
+ }