replicas-engine 0.1.1302 → 0.1.1303
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.
- package/dist/src/{asp-host-CKIKB33N.js → asp-host-SNQAHZ4O.js} +5 -5
- package/dist/src/{chunk-WJNNX4X7.js → chunk-5ERKSVWK.js} +2 -2
- package/dist/src/{chunk-II7A63N3.js → chunk-5MKQOOKZ.js} +1 -1
- package/dist/src/{chunk-EVZUJPQY.js → chunk-5OA7WBDC.js} +6 -6
- package/dist/src/{chunk-GOOVARRF.js → chunk-HWYNJQUU.js} +2 -2
- package/dist/src/{chunk-UAMATZ5S.js → chunk-MXHSZLHO.js} +25 -0
- package/dist/src/{chunk-QWDNTCIK.js → chunk-RCJP3KY5.js} +2 -2
- package/dist/src/{chunk-4GOMPL6V.js → chunk-VQQPKWKF.js} +3 -3
- package/dist/src/{chunk-BHIBP2BR.js → chunk-XHKAQ3OC.js} +1 -1
- package/dist/src/command-protection-hook.js +4 -4
- package/dist/src/headless-agent.js +4 -4
- package/dist/src/index.js +78 -22
- package/dist/src/post-tool-pr-hook.js +2 -2
- package/dist/src/subagent-mcp.js +12 -11
- package/package.json +1 -1
|
@@ -8,12 +8,12 @@ import {
|
|
|
8
8
|
listRunningCodexModels,
|
|
9
9
|
restartCodexAspHost,
|
|
10
10
|
restartCodexAspHostIfRunning
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-5OA7WBDC.js";
|
|
12
|
+
import "./chunk-5ERKSVWK.js";
|
|
13
|
+
import "./chunk-VQQPKWKF.js";
|
|
14
|
+
import "./chunk-5MKQOOKZ.js";
|
|
15
15
|
import "./chunk-UZSNFLDQ.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-MXHSZLHO.js";
|
|
17
17
|
import "./chunk-VEQXQN22.js";
|
|
18
18
|
export {
|
|
19
19
|
CODEX_ULTRAFAST_SERVICE_TIER,
|
|
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
|
|
|
4
4
|
import {
|
|
5
5
|
SUBPROCESS_MAX_BUFFER,
|
|
6
6
|
execFileAsync
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5MKQOOKZ.js";
|
|
8
8
|
import {
|
|
9
9
|
isRecord as isRecord2
|
|
10
10
|
} from "./chunk-UZSNFLDQ.js";
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
provisionedDeviceSchema,
|
|
23
23
|
readReplicasRuntimeEnv,
|
|
24
24
|
serializePosixEnvFile
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-MXHSZLHO.js";
|
|
26
26
|
|
|
27
27
|
// src/runtime-env-loader.ts
|
|
28
28
|
import { readFileSync } from "fs";
|
|
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
HOOK_EXEC_MAX_BUFFER_BYTES
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-MXHSZLHO.js";
|
|
7
7
|
|
|
8
8
|
// src/utils/exec.ts
|
|
9
9
|
import { exec, execFile } from "child_process";
|
|
@@ -10,15 +10,15 @@ import {
|
|
|
10
10
|
resolveDiffBase,
|
|
11
11
|
runGitCommand,
|
|
12
12
|
setAgentCredentialSnapshot
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-5ERKSVWK.js";
|
|
14
14
|
import {
|
|
15
15
|
AppServerProcess,
|
|
16
16
|
buildCodexAgentEnv
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-VQQPKWKF.js";
|
|
18
18
|
import {
|
|
19
19
|
SUBPROCESS_MAX_BUFFER,
|
|
20
20
|
execFileAsync
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-5MKQOOKZ.js";
|
|
22
22
|
import {
|
|
23
23
|
isRecord
|
|
24
24
|
} from "./chunk-UZSNFLDQ.js";
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
resolveOpenAICompatibleModelsUrl,
|
|
57
57
|
splitMothershipInstructions,
|
|
58
58
|
withTimeout
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-MXHSZLHO.js";
|
|
60
60
|
|
|
61
61
|
// src/managers/codex-token-manager.ts
|
|
62
62
|
import { promises as fs } from "fs";
|
|
@@ -306,7 +306,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
306
306
|
await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
|
|
307
307
|
await this.applyCredentialsResponse(data);
|
|
308
308
|
setAgentCredentialSnapshot("codex", data);
|
|
309
|
-
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-
|
|
309
|
+
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-SNQAHZ4O.js");
|
|
310
310
|
await restartCodexAspHostIfRunning2();
|
|
311
311
|
});
|
|
312
312
|
await this.start(true);
|
|
@@ -328,7 +328,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
328
328
|
const accountChanged = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex?.credentialId !== data.credentialId;
|
|
329
329
|
await this.applyCredentialsResponse(data);
|
|
330
330
|
if (restartOnChange && (accountChanged || CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index]))) {
|
|
331
|
-
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-
|
|
331
|
+
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-SNQAHZ4O.js");
|
|
332
332
|
await restartCodexAspHostIfRunning2();
|
|
333
333
|
}
|
|
334
334
|
setAgentCredentialSnapshot("codex", data);
|
|
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
AspClient
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VQQPKWKF.js";
|
|
7
7
|
import {
|
|
8
8
|
ASTER_BASE_URL,
|
|
9
9
|
ASTER_PROVIDER,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
isRecord,
|
|
16
16
|
readOllamaAuthEnv,
|
|
17
17
|
readOpenAICompatibleAuthEnv
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-MXHSZLHO.js";
|
|
19
19
|
|
|
20
20
|
// src/managers/codex-asp/notification-dispatch.ts
|
|
21
21
|
var TURN_STARTED_METHOD = "turn/started";
|
|
@@ -5185,7 +5185,9 @@ function splitMothershipInstructions(customInstructions) {
|
|
|
5185
5185
|
|
|
5186
5186
|
// ../shared/src/mothership-events.ts
|
|
5187
5187
|
var MOTHERSHIP_EVENT_KINDS = ["finished", "ready", "needs_attention", "merged", "closed", "archived"];
|
|
5188
|
+
var MOTHERSHIP_TURN_ERROR_SUMMARY = "Turn ended with an error.";
|
|
5188
5189
|
var MOTHERSHIP_EVENT_TYPE = "multitask-event";
|
|
5190
|
+
var MOTHERSHIP_EVENT_MESSAGE_TYPE = "multitask_event";
|
|
5189
5191
|
var mothershipEventSchema = z20.object({
|
|
5190
5192
|
id: z20.string(),
|
|
5191
5193
|
at: z20.string(),
|
|
@@ -5194,13 +5196,31 @@ var mothershipEventSchema = z20.object({
|
|
|
5194
5196
|
agentName: z20.string(),
|
|
5195
5197
|
summary: z20.string(),
|
|
5196
5198
|
detail: z20.string().optional(),
|
|
5199
|
+
// Set when the subagent is a chat in this workspace rather than a ship; agentId is then that chat's id.
|
|
5200
|
+
chatId: z20.string().optional(),
|
|
5197
5201
|
// Set on events recorded before every kind woke the orchestrator, which were shown as a row when they happened.
|
|
5198
5202
|
noticed: z20.boolean().optional()
|
|
5199
5203
|
});
|
|
5200
5204
|
var TAG = "multitask_event";
|
|
5201
5205
|
var BLOCK = new RegExp(`<${TAG}((?:\\s+\\w+="[^"]*")*)>\\n?([\\s\\S]*?)\\n?</${TAG}>`, "g");
|
|
5202
5206
|
var ATTRIBUTE = /(\w+)="([^"]*)"/g;
|
|
5207
|
+
var escapeAttribute = (value) => value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
5203
5208
|
var unescapeAttribute = (value) => value.replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&");
|
|
5209
|
+
var EVENT_RESPONSE_MAX_CHARS = 8e3;
|
|
5210
|
+
function truncateMothershipEventResponse(response, readTool) {
|
|
5211
|
+
return response.length > EVENT_RESPONSE_MAX_CHARS ? `${response.slice(0, EVENT_RESPONSE_MAX_CHARS)}\u2026
|
|
5212
|
+
|
|
5213
|
+
(Truncated; ${readTool} returns the full response.)` : response;
|
|
5214
|
+
}
|
|
5215
|
+
function formatMothershipEvents(events) {
|
|
5216
|
+
return events.map((event) => {
|
|
5217
|
+
const attributes = { id: event.id, at: event.at, kind: event.kind, agent: event.agentName, agent_id: event.agentId, ...event.chatId ? { chat_id: event.chatId } : {}, ...event.noticed ? { noticed: "true" } : {} };
|
|
5218
|
+
const body = [event.summary, event.detail].filter(Boolean).join("\n\n").replaceAll(`</${TAG}`, `<\\/${TAG}`);
|
|
5219
|
+
return `<${TAG}${Object.entries(attributes).map(([key, value]) => ` ${key}="${escapeAttribute(value)}"`).join("")}>
|
|
5220
|
+
${body}
|
|
5221
|
+
</${TAG}>`;
|
|
5222
|
+
}).join("\n\n");
|
|
5223
|
+
}
|
|
5204
5224
|
function extractMothershipEvents(text3) {
|
|
5205
5225
|
return [...text3.matchAll(BLOCK)].flatMap((match) => {
|
|
5206
5226
|
const attributes = Object.fromEntries([...match[1].matchAll(ATTRIBUTE)].map(([, key, value]) => [key, unescapeAttribute(value)]));
|
|
@@ -5216,6 +5236,7 @@ function extractMothershipEvents(text3) {
|
|
|
5216
5236
|
agentName: attributes.agent ?? "ship",
|
|
5217
5237
|
summary: summary.trim(),
|
|
5218
5238
|
...detail ? { detail } : {},
|
|
5239
|
+
...attributes.chat_id ? { chatId: attributes.chat_id } : {},
|
|
5219
5240
|
...attributes.noticed === "true" ? { noticed: true } : {}
|
|
5220
5241
|
}];
|
|
5221
5242
|
});
|
|
@@ -10770,6 +10791,10 @@ export {
|
|
|
10770
10791
|
MOTHERSHIP_INSTRUCTIONS_TAG,
|
|
10771
10792
|
wrapInTag,
|
|
10772
10793
|
splitMothershipInstructions,
|
|
10794
|
+
MOTHERSHIP_TURN_ERROR_SUMMARY,
|
|
10795
|
+
MOTHERSHIP_EVENT_MESSAGE_TYPE,
|
|
10796
|
+
truncateMothershipEventResponse,
|
|
10797
|
+
formatMothershipEvents,
|
|
10773
10798
|
coerceBackgroundTaskPayload,
|
|
10774
10799
|
CHAT_FORK_EXCERPT_OMITTED_NOTICE,
|
|
10775
10800
|
formatChatForkHandoffMessage,
|
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
getOriginDefaultBranch,
|
|
6
6
|
monolithRequest,
|
|
7
7
|
runGitCommand
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5ERKSVWK.js";
|
|
9
9
|
import {
|
|
10
10
|
extractCommandProtectionCommandText,
|
|
11
11
|
findCommandProtectionGitLookups,
|
|
12
12
|
findGitCommitSignals,
|
|
13
13
|
findPrMergeSignals,
|
|
14
14
|
parseCommandProtectionRequest
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-MXHSZLHO.js";
|
|
16
16
|
|
|
17
17
|
// src/services/command-protection-service.ts
|
|
18
18
|
import { readFile, stat } from "fs/promises";
|
|
@@ -3,10 +3,10 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
execFileAsync
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5MKQOOKZ.js";
|
|
7
7
|
import {
|
|
8
8
|
isVersionBelow
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MXHSZLHO.js";
|
|
10
10
|
|
|
11
11
|
// src/utils/codex-agent-env.ts
|
|
12
12
|
function buildCodexAgentEnv(source = process.env) {
|
|
@@ -240,7 +240,7 @@ function getCodexModelProvider(method) {
|
|
|
240
240
|
if (method === "foundry") return "azure";
|
|
241
241
|
return method === "ollama" || method === "openai-compatible" ? "replicas_openai_compatible" : "openai";
|
|
242
242
|
}
|
|
243
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
243
|
+
var ENGINE_PACKAGE_VERSION = "0.1.1303";
|
|
244
244
|
var INITIALIZE_METHOD = "initialize";
|
|
245
245
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
246
246
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
evaluateCommandProtection
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-RCJP3KY5.js";
|
|
7
|
+
import "./chunk-5ERKSVWK.js";
|
|
8
|
+
import "./chunk-5MKQOOKZ.js";
|
|
9
9
|
import {
|
|
10
10
|
isRecord
|
|
11
11
|
} from "./chunk-UZSNFLDQ.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-MXHSZLHO.js";
|
|
13
13
|
import "./chunk-VEQXQN22.js";
|
|
14
14
|
|
|
15
15
|
// src/command-protection-hook.ts
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
recoverCompletedTurn,
|
|
15
15
|
spawnMuseMsp,
|
|
16
16
|
startMuseSession
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-HWYNJQUU.js";
|
|
18
18
|
import {
|
|
19
19
|
AppServerProcess,
|
|
20
20
|
buildCodexAgentEnv
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
import "./chunk-
|
|
21
|
+
} from "./chunk-VQQPKWKF.js";
|
|
22
|
+
import "./chunk-5MKQOOKZ.js";
|
|
23
23
|
import {
|
|
24
24
|
AGENT,
|
|
25
25
|
OPENCODE_GO_PROVIDER,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
headlessAgentUsagePath,
|
|
30
30
|
isRecord,
|
|
31
31
|
withTimeout
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-MXHSZLHO.js";
|
|
33
33
|
import "./chunk-VEQXQN22.js";
|
|
34
34
|
|
|
35
35
|
// src/headless-agent.ts
|
package/dist/src/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
evaluateCommandProtection,
|
|
28
28
|
extractToolCommand,
|
|
29
29
|
reportCommandProtectionBlock
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-RCJP3KY5.js";
|
|
31
31
|
import {
|
|
32
32
|
ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
|
|
33
33
|
AGENT_MESSAGE_DELTA_METHOD,
|
|
@@ -65,10 +65,10 @@ import {
|
|
|
65
65
|
spawnMuseMsp,
|
|
66
66
|
startMuseSession,
|
|
67
67
|
uuidV7
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-HWYNJQUU.js";
|
|
69
69
|
import {
|
|
70
70
|
publishedPullRequestUrls
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-XHKAQ3OC.js";
|
|
72
72
|
import {
|
|
73
73
|
ACCOUNT_RATE_LIMITS_READ_METHOD,
|
|
74
74
|
AsyncLock,
|
|
@@ -143,7 +143,7 @@ import {
|
|
|
143
143
|
timestampFromSeconds,
|
|
144
144
|
upsertCredentialFileLines,
|
|
145
145
|
writeSecureCredentialFile
|
|
146
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-5OA7WBDC.js";
|
|
147
147
|
import {
|
|
148
148
|
ENGINE_ENV,
|
|
149
149
|
monolithRequest,
|
|
@@ -153,15 +153,15 @@ import {
|
|
|
153
153
|
resolveDiffBase,
|
|
154
154
|
setAgentCredentialSnapshot,
|
|
155
155
|
setLinearSessionId
|
|
156
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-5ERKSVWK.js";
|
|
157
157
|
import {
|
|
158
158
|
getCodexModelProvider
|
|
159
|
-
} from "./chunk-
|
|
159
|
+
} from "./chunk-VQQPKWKF.js";
|
|
160
160
|
import {
|
|
161
161
|
SUBPROCESS_MAX_BUFFER,
|
|
162
162
|
execAsync,
|
|
163
163
|
execFileAsync
|
|
164
|
-
} from "./chunk-
|
|
164
|
+
} from "./chunk-5MKQOOKZ.js";
|
|
165
165
|
import {
|
|
166
166
|
isRecord as isRecord2
|
|
167
167
|
} from "./chunk-UZSNFLDQ.js";
|
|
@@ -236,7 +236,9 @@ import {
|
|
|
236
236
|
MAX_CODEX_GOAL_OBJECTIVE_CHARS,
|
|
237
237
|
MAX_REPO_FILE_CONTENT_BYTES,
|
|
238
238
|
MERGED_MESSAGE_SEPARATOR,
|
|
239
|
+
MOTHERSHIP_EVENT_MESSAGE_TYPE,
|
|
239
240
|
MOTHERSHIP_INSTRUCTIONS_TAG,
|
|
241
|
+
MOTHERSHIP_TURN_ERROR_SUMMARY,
|
|
240
242
|
OLLAMA_AGENTS,
|
|
241
243
|
OPENCODE_GO_BASE_URL,
|
|
242
244
|
OPENCODE_GO_PROVIDER,
|
|
@@ -309,6 +311,7 @@ import {
|
|
|
309
311
|
forkChatRequestSchema,
|
|
310
312
|
formatChatForkHandoffMessage,
|
|
311
313
|
formatChatForkUpdateMessage,
|
|
314
|
+
formatMothershipEvents,
|
|
312
315
|
getChatContinuation,
|
|
313
316
|
getChatHistoryPageSenders,
|
|
314
317
|
getChatKind,
|
|
@@ -403,6 +406,7 @@ import {
|
|
|
403
406
|
stripAgentDiagnosticErrors,
|
|
404
407
|
threadHandoffText,
|
|
405
408
|
toClaudeCodeModel,
|
|
409
|
+
truncateMothershipEventResponse,
|
|
406
410
|
updateChatDisplayNameRequestSchema,
|
|
407
411
|
waitSubagentRequestSchema,
|
|
408
412
|
withTimeout,
|
|
@@ -411,7 +415,7 @@ import {
|
|
|
411
415
|
workspaceTokenRequestSchema,
|
|
412
416
|
workspaceTokenResponseSchema,
|
|
413
417
|
wrapInTag
|
|
414
|
-
} from "./chunk-
|
|
418
|
+
} from "./chunk-MXHSZLHO.js";
|
|
415
419
|
import {
|
|
416
420
|
cloneMcpConfig,
|
|
417
421
|
ensureCompatibilityImports,
|
|
@@ -11650,7 +11654,7 @@ var MessageQueueService = class {
|
|
|
11650
11654
|
// src/managers/subagent-mcp-prompt.ts
|
|
11651
11655
|
var SUBAGENT_MCP_INSTRUCTIONS = `# Subagents
|
|
11652
11656
|
|
|
11653
|
-
Native subagent tools are disabled in this workspace. To delegate work to a subagent, use the \`${SUBAGENT_MCP_SERVER_NAME}\` MCP server (\`${SUBAGENT_MCP_TOOLS.getProviders}\`, \`${SUBAGENT_MCP_TOOLS.spawnAgent}\`, \`${SUBAGENT_MCP_TOOLS.getAgent}\`, \`${SUBAGENT_MCP_TOOLS.waitAgent}\`, \`${SUBAGENT_MCP_TOOLS.messageAgent}\`, \`${SUBAGENT_MCP_TOOLS.deleteAgent}\`); your harness may prefix them, and Pi exposes them through its \`mcp\` gateway. Call \`${SUBAGENT_MCP_TOOLS.getProviders}\` before the first spawn. \`fork_turns\` sets inherited context: "all" (default), "none" (include every needed detail in the prompt), or "N" for the latest N user turns. \`${SUBAGENT_MCP_TOOLS.spawnAgent}\` and \`${SUBAGENT_MCP_TOOLS.messageAgent}\` block by default; pass \`blocking: false\` to keep working,
|
|
11657
|
+
Native subagent tools are disabled in this workspace. To delegate work to a subagent, use the \`${SUBAGENT_MCP_SERVER_NAME}\` MCP server (\`${SUBAGENT_MCP_TOOLS.getProviders}\`, \`${SUBAGENT_MCP_TOOLS.spawnAgent}\`, \`${SUBAGENT_MCP_TOOLS.getAgent}\`, \`${SUBAGENT_MCP_TOOLS.waitAgent}\`, \`${SUBAGENT_MCP_TOOLS.messageAgent}\`, \`${SUBAGENT_MCP_TOOLS.deleteAgent}\`); your harness may prefix them, and Pi exposes them through its \`mcp\` gateway. Call \`${SUBAGENT_MCP_TOOLS.getProviders}\` before the first spawn. \`fork_turns\` sets inherited context: "all" (default), "none" (include every needed detail in the prompt), or "N" for the latest N user turns. \`${SUBAGENT_MCP_TOOLS.spawnAgent}\` and \`${SUBAGENT_MCP_TOOLS.messageAgent}\` block by default; pass \`blocking: false\` to keep working. A subagent you are not waiting on reports back when it finishes: its final response arrives as a \`<multitask_event>\` message once your turn ends, so end your turn instead of polling. Subagents share this workspace.`;
|
|
11654
11658
|
|
|
11655
11659
|
// src/managers/coding-agent-manager.ts
|
|
11656
11660
|
var MAX_INTERRUPT_QUEUE_ITEMS = 1e3;
|
|
@@ -60262,6 +60266,8 @@ var ChatService = class {
|
|
|
60262
60266
|
agentChatActivityTrackerService;
|
|
60263
60267
|
agentTokenUsageTracker;
|
|
60264
60268
|
chats = /* @__PURE__ */ new Map();
|
|
60269
|
+
awaitedSubagents = /* @__PURE__ */ new Map();
|
|
60270
|
+
heldSubagentReports = /* @__PURE__ */ new Map();
|
|
60265
60271
|
forkSourceSeenBlocks = /* @__PURE__ */ new Map();
|
|
60266
60272
|
persistPromise = null;
|
|
60267
60273
|
persistQueued = false;
|
|
@@ -60468,19 +60474,68 @@ var ChatService = class {
|
|
|
60468
60474
|
async waitForSubagent(parentChatId, chatId, timeoutMinutes, signal) {
|
|
60469
60475
|
const timeoutMs = timeoutMinutes ? timeoutMinutes * 6e4 : null;
|
|
60470
60476
|
const startedAt = Date.now();
|
|
60471
|
-
|
|
60472
|
-
|
|
60473
|
-
|
|
60474
|
-
|
|
60475
|
-
|
|
60476
|
-
|
|
60477
|
-
|
|
60478
|
-
|
|
60479
|
-
|
|
60480
|
-
|
|
60481
|
-
|
|
60482
|
-
|
|
60483
|
-
|
|
60477
|
+
this.awaitedSubagents.set(chatId, (this.awaitedSubagents.get(chatId) ?? 0) + 1);
|
|
60478
|
+
try {
|
|
60479
|
+
while (true) {
|
|
60480
|
+
if (signal?.aborted) throw new Error("Subagent wait was cancelled");
|
|
60481
|
+
const result = await this.getSubagent(parentChatId, chatId);
|
|
60482
|
+
if (result.status === "completed" && !signal?.aborted) {
|
|
60483
|
+
this.heldSubagentReports.delete(chatId);
|
|
60484
|
+
return result;
|
|
60485
|
+
}
|
|
60486
|
+
if (this.requireChat(parentChatId).provider.getQueue().some(({ steeredAt }) => steeredAt && Date.parse(steeredAt) >= startedAt)) {
|
|
60487
|
+
return { ...result, interruptedByUserMessage: true };
|
|
60488
|
+
}
|
|
60489
|
+
const remainingMs = timeoutMs === null ? null : timeoutMs - (Date.now() - startedAt);
|
|
60490
|
+
if (remainingMs !== null && remainingMs <= 0) return { ...result, timedOut: true };
|
|
60491
|
+
await new Promise((resolve7) => setTimeout(
|
|
60492
|
+
resolve7,
|
|
60493
|
+
remainingMs === null ? SUBAGENT_POLL_INTERVAL_MS : Math.min(SUBAGENT_POLL_INTERVAL_MS, remainingMs)
|
|
60494
|
+
));
|
|
60495
|
+
}
|
|
60496
|
+
} finally {
|
|
60497
|
+
const waits = (this.awaitedSubagents.get(chatId) ?? 1) - 1;
|
|
60498
|
+
if (waits > 0) this.awaitedSubagents.set(chatId, waits);
|
|
60499
|
+
else {
|
|
60500
|
+
this.awaitedSubagents.delete(chatId);
|
|
60501
|
+
const held = this.heldSubagentReports.get(chatId);
|
|
60502
|
+
const child = this.getRuntimeChat(chatId);
|
|
60503
|
+
this.heldSubagentReports.delete(chatId);
|
|
60504
|
+
if (held && child) void this.reportSubagentToParent(child, held.completedAt, held.errors);
|
|
60505
|
+
}
|
|
60506
|
+
}
|
|
60507
|
+
}
|
|
60508
|
+
async reportSubagentToParent(chat, completedAt, errors) {
|
|
60509
|
+
const parentChatId = chat.persisted.parentChatId;
|
|
60510
|
+
if (!parentChatId) return;
|
|
60511
|
+
if (this.awaitedSubagents.has(chat.persisted.id)) {
|
|
60512
|
+
this.heldSubagentReports.set(chat.persisted.id, { completedAt, errors });
|
|
60513
|
+
return;
|
|
60514
|
+
}
|
|
60515
|
+
const last = this.getRuntimeChat(parentChatId)?.lastSendRequest;
|
|
60516
|
+
if (!last) return;
|
|
60517
|
+
try {
|
|
60518
|
+
const detail = errors?.length ? errors.join("\n") : extractFinalResponse(await chat.provider.getHistory(), chat.persisted.provider) ?? "[No response from subagent]";
|
|
60519
|
+
await this.sendMessage(parentChatId, {
|
|
60520
|
+
message: formatMothershipEvents([{
|
|
60521
|
+
id: randomUUID10(),
|
|
60522
|
+
at: completedAt,
|
|
60523
|
+
kind: "finished",
|
|
60524
|
+
agentId: chat.persisted.id,
|
|
60525
|
+
agentName: chat.persisted.title,
|
|
60526
|
+
chatId: chat.persisted.id,
|
|
60527
|
+
summary: `${errors?.length ? MOTHERSHIP_TURN_ERROR_SUMMARY : "Finished its turn."} It is a subagent in this workspace: reach it with the ${SUBAGENT_MCP_TOOLS.messageAgent} and ${SUBAGENT_MCP_TOOLS.getAgent} tools and this chat_id.`,
|
|
60528
|
+
detail: truncateMothershipEventResponse(detail, SUBAGENT_MCP_TOOLS.getAgent)
|
|
60529
|
+
}]),
|
|
60530
|
+
...last.customInstructions ? { customInstructions: last.customInstructions } : {},
|
|
60531
|
+
...last.enableInteractiveTools !== void 0 ? { enableInteractiveTools: last.enableInteractiveTools } : {},
|
|
60532
|
+
type: MOTHERSHIP_EVENT_MESSAGE_TYPE,
|
|
60533
|
+
merge: true,
|
|
60534
|
+
inheritThinkingLevel: true,
|
|
60535
|
+
idempotencyKey: `subagent-finished:${chat.persisted.id}:${completedAt}`
|
|
60536
|
+
});
|
|
60537
|
+
} catch (error) {
|
|
60538
|
+
console.error("[ChatService] Failed to report subagent to its parent:", { chatId: chat.persisted.id, error });
|
|
60484
60539
|
}
|
|
60485
60540
|
}
|
|
60486
60541
|
async sendMessage(chatId, request) {
|
|
@@ -61779,6 +61834,7 @@ ${note}`;
|
|
|
61779
61834
|
if (chat.persisted.parentChatId) {
|
|
61780
61835
|
this.publish({ type: "chat.updated", payload: { chat: this.toSummary(chat) } }).catch(() => {
|
|
61781
61836
|
});
|
|
61837
|
+
if (!processing) void this.reportSubagentToParent(chat, completedAt, chat.lastTurnErrors);
|
|
61782
61838
|
return;
|
|
61783
61839
|
}
|
|
61784
61840
|
this.publish({
|
|
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
publishedPullRequestUrls
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XHKAQ3OC.js";
|
|
7
7
|
import {
|
|
8
8
|
isRecord
|
|
9
9
|
} from "./chunk-UZSNFLDQ.js";
|
|
10
10
|
import {
|
|
11
11
|
shouldRefreshPullRequests
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MXHSZLHO.js";
|
|
13
13
|
import "./chunk-VEQXQN22.js";
|
|
14
14
|
|
|
15
15
|
// src/services/post-tool-pr-notifier.ts
|
package/dist/src/subagent-mcp.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
spawnSubagentRequestSchema,
|
|
12
12
|
subagentResponseSchema,
|
|
13
13
|
waitSubagentRequestSchema
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-MXHSZLHO.js";
|
|
15
15
|
import "./chunk-VEQXQN22.js";
|
|
16
16
|
|
|
17
17
|
// src/subagent-mcp.ts
|
|
@@ -43,13 +43,14 @@ async function request(path, method, body) {
|
|
|
43
43
|
if (!response.ok) throw new Error(text || `Subagent request failed (${response.status})`);
|
|
44
44
|
return text || JSON.stringify({ success: true });
|
|
45
45
|
}
|
|
46
|
-
async function waitForAgent(chatId, timeoutMinutes) {
|
|
46
|
+
async function waitForAgent(chatId, timeoutMinutes, signal) {
|
|
47
47
|
const query = timeoutMinutes ? `?timeoutMinutes=${timeoutMinutes}` : "";
|
|
48
48
|
const response = await fetch(`http://localhost:${enginePort}/chats/${parentChatId}/subagents/${chatId}/wait${query}`, {
|
|
49
49
|
headers: {
|
|
50
50
|
Accept: "text/event-stream",
|
|
51
51
|
"X-Replicas-Engine-Secret": engineSecret
|
|
52
|
-
}
|
|
52
|
+
},
|
|
53
|
+
signal
|
|
53
54
|
});
|
|
54
55
|
if (!response.ok || !response.body) throw new Error(await response.text() || `Subagent wait failed (${response.status})`);
|
|
55
56
|
let result;
|
|
@@ -79,7 +80,7 @@ server.registerTool(SUBAGENT_MCP_TOOLS.getProviders, {
|
|
|
79
80
|
content: [{ type: "text", text: await request(`/chats/${parentChatId}/subagents`, "GET") }]
|
|
80
81
|
}));
|
|
81
82
|
server.registerTool(SUBAGENT_MCP_TOOLS.spawnAgent, {
|
|
82
|
-
description: "Spawn a child agent with all, none, or the latest N turns of parent context. Blocks by default; set blocking to false to return its chat ID immediately.",
|
|
83
|
+
description: "Spawn a child agent with all, none, or the latest N turns of parent context. Blocks by default; set blocking to false to return its chat ID immediately, and its final response reaches you as a message once your turn ends.",
|
|
83
84
|
inputSchema: {
|
|
84
85
|
provider: spawnSubagentRequestSchema.shape.provider.describe("Provider returned by get_providers."),
|
|
85
86
|
prompt: spawnSubagentRequestSchema.shape.prompt.describe("The child\u2019s assigned task, scope, and expected result. Include all necessary context when fork_turns is none."),
|
|
@@ -91,7 +92,7 @@ server.registerTool(SUBAGENT_MCP_TOOLS.spawnAgent, {
|
|
|
91
92
|
blocking: z.boolean().optional().describe("Wait for the child to finish. Defaults to true."),
|
|
92
93
|
timeout_minutes: waitSubagentRequestSchema.shape.timeoutMinutes.describe("Maximum time to wait without interrupting the child.")
|
|
93
94
|
}
|
|
94
|
-
}, async ({ provider, prompt, fork_turns, model, thinking_level, service_tier, title, blocking, timeout_minutes }) => {
|
|
95
|
+
}, async ({ provider, prompt, fork_turns, model, thinking_level, service_tier, title, blocking, timeout_minutes }, { signal }) => {
|
|
95
96
|
const created = await request(`/chats/${parentChatId}/subagents`, "POST", {
|
|
96
97
|
provider,
|
|
97
98
|
prompt,
|
|
@@ -102,7 +103,7 @@ server.registerTool(SUBAGENT_MCP_TOOLS.spawnAgent, {
|
|
|
102
103
|
...title ? { title } : {}
|
|
103
104
|
});
|
|
104
105
|
const createdAgent = subagentResponseSchema.parse(JSON.parse(created));
|
|
105
|
-
return { content: [{ type: "text", text: blocking === false ? created : await waitForAgent(createdAgent.chatId, timeout_minutes) }] };
|
|
106
|
+
return { content: [{ type: "text", text: blocking === false ? created : await waitForAgent(createdAgent.chatId, timeout_minutes, signal) }] };
|
|
106
107
|
});
|
|
107
108
|
server.registerTool(SUBAGENT_MCP_TOOLS.getAgent, {
|
|
108
109
|
description: "Get the current status and final response, if available, for one of this chat\u2019s subagents.",
|
|
@@ -116,11 +117,11 @@ server.registerTool(SUBAGENT_MCP_TOOLS.waitAgent, {
|
|
|
116
117
|
chat_id: z.string().uuid(),
|
|
117
118
|
timeout_minutes: waitSubagentRequestSchema.shape.timeoutMinutes
|
|
118
119
|
}
|
|
119
|
-
}, async ({ chat_id, timeout_minutes }) => ({
|
|
120
|
-
content: [{ type: "text", text: await waitForAgent(chat_id, timeout_minutes) }]
|
|
120
|
+
}, async ({ chat_id, timeout_minutes }, { signal }) => ({
|
|
121
|
+
content: [{ type: "text", text: await waitForAgent(chat_id, timeout_minutes, signal) }]
|
|
121
122
|
}));
|
|
122
123
|
server.registerTool(SUBAGENT_MCP_TOOLS.messageAgent, {
|
|
123
|
-
description: "Send a follow-up to one of this chat\u2019s subagents. Blocks by default; set blocking to false to return immediately.",
|
|
124
|
+
description: "Send a follow-up to one of this chat\u2019s subagents. Blocks by default; set blocking to false to return immediately, and its reply reaches you as a message once your turn ends.",
|
|
124
125
|
inputSchema: {
|
|
125
126
|
chat_id: z.string().uuid(),
|
|
126
127
|
message: messageSubagentRequestSchema.shape.message,
|
|
@@ -130,14 +131,14 @@ server.registerTool(SUBAGENT_MCP_TOOLS.messageAgent, {
|
|
|
130
131
|
blocking: z.boolean().optional().describe("Wait for the child to finish. Defaults to true."),
|
|
131
132
|
timeout_minutes: waitSubagentRequestSchema.shape.timeoutMinutes.describe("Maximum time to wait without interrupting the child.")
|
|
132
133
|
}
|
|
133
|
-
}, async ({ chat_id, message, model, thinking_level, service_tier, blocking, timeout_minutes }) => {
|
|
134
|
+
}, async ({ chat_id, message, model, thinking_level, service_tier, blocking, timeout_minutes }, { signal }) => {
|
|
134
135
|
const accepted = await request(`/chats/${parentChatId}/subagents/${chat_id}/messages`, "POST", {
|
|
135
136
|
message,
|
|
136
137
|
...model ? { model } : {},
|
|
137
138
|
...thinking_level ? { thinkingLevel: thinking_level } : {},
|
|
138
139
|
...serviceTierFields(service_tier)
|
|
139
140
|
});
|
|
140
|
-
return { content: [{ type: "text", text: blocking === false ? accepted : await waitForAgent(chat_id, timeout_minutes) }] };
|
|
141
|
+
return { content: [{ type: "text", text: blocking === false ? accepted : await waitForAgent(chat_id, timeout_minutes, signal) }] };
|
|
141
142
|
});
|
|
142
143
|
server.registerTool(SUBAGENT_MCP_TOOLS.deleteAgent, {
|
|
143
144
|
description: "Delete one of this chat\u2019s subagents.",
|