replicas-engine 0.1.986 → 0.1.987
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-Q474L67V.js → asp-host-LOTCGOVD.js} +5 -5
- package/dist/src/{chunk-4WBOMDAN.js → chunk-2PMHC6IL.js} +1 -1
- package/dist/src/{chunk-YQE57AE6.js → chunk-5EHMJ4OT.js} +1 -1
- package/dist/src/{chunk-O2ZKAC2G.js → chunk-D5B72SUV.js} +6 -6
- package/dist/src/{chunk-B2JQRHF4.js → chunk-G6QBYUZR.js} +3 -3
- package/dist/src/{chunk-SAJ6ERGR.js → chunk-KAJYMTYA.js} +3 -3
- package/dist/src/{chunk-IIANP4GI.js → chunk-QU4FXL4X.js} +2 -1
- package/dist/src/{chunk-Z3D5SVUI.js → chunk-TYH3IEXZ.js} +1 -1
- package/dist/src/command-protection-hook.js +4 -4
- package/dist/src/headless-agent.js +3 -3
- package/dist/src/index.js +216 -135
- package/dist/src/post-tool-pr-hook.js +2 -2
- package/dist/src/subagent-mcp.js +2 -2
- package/package.json +1 -1
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
getCodexAspHost,
|
|
6
6
|
restartCodexAspHost,
|
|
7
7
|
restartCodexAspHostIfRunning
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-D5B72SUV.js";
|
|
9
|
+
import "./chunk-TYH3IEXZ.js";
|
|
10
|
+
import "./chunk-KAJYMTYA.js";
|
|
11
|
+
import "./chunk-2PMHC6IL.js";
|
|
12
12
|
import "./chunk-UZSNFLDQ.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-QU4FXL4X.js";
|
|
14
14
|
import "./chunk-VEQXQN22.js";
|
|
15
15
|
export {
|
|
16
16
|
getCodexAspHost,
|
|
@@ -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-QU4FXL4X.js";
|
|
7
7
|
|
|
8
8
|
// src/utils/exec.ts
|
|
9
9
|
import { exec, execFile } from "child_process";
|
|
@@ -5,15 +5,15 @@ import {
|
|
|
5
5
|
ENGINE_ENV,
|
|
6
6
|
monolithRequest,
|
|
7
7
|
setAgentCredentialSnapshot
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TYH3IEXZ.js";
|
|
9
9
|
import {
|
|
10
10
|
AppServerProcess,
|
|
11
11
|
buildCodexAgentEnv
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KAJYMTYA.js";
|
|
13
13
|
import {
|
|
14
14
|
SUBPROCESS_MAX_BUFFER,
|
|
15
15
|
execFileAsync
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-2PMHC6IL.js";
|
|
17
17
|
import {
|
|
18
18
|
isRecord
|
|
19
19
|
} from "./chunk-UZSNFLDQ.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
listOpenAICompatibleModels,
|
|
28
28
|
readOllamaAuthEnv,
|
|
29
29
|
resolveOpenAICompatibleModelsUrl
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-QU4FXL4X.js";
|
|
31
31
|
|
|
32
32
|
// src/managers/codex-token-manager.ts
|
|
33
33
|
import { promises as fs } from "fs";
|
|
@@ -260,7 +260,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
260
260
|
await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
|
|
261
261
|
await this.applyCredentialsResponse(data);
|
|
262
262
|
setAgentCredentialSnapshot("codex", data);
|
|
263
|
-
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-
|
|
263
|
+
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-LOTCGOVD.js");
|
|
264
264
|
await restartCodexAspHostIfRunning2();
|
|
265
265
|
});
|
|
266
266
|
await this.start(true);
|
|
@@ -280,7 +280,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
|
|
|
280
280
|
await this.applyCredentialUpdate(generation, async () => {
|
|
281
281
|
await this.applyCredentialsResponse(data);
|
|
282
282
|
if (restartOnChange && CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index])) {
|
|
283
|
-
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-
|
|
283
|
+
const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-LOTCGOVD.js");
|
|
284
284
|
await restartCodexAspHostIfRunning2();
|
|
285
285
|
}
|
|
286
286
|
setAgentCredentialSnapshot("codex", data);
|
|
@@ -3,18 +3,18 @@ import { createRequire as __createRequire } from 'node:module';
|
|
|
3
3
|
const require = __createRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
monolithRequest
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TYH3IEXZ.js";
|
|
7
7
|
import {
|
|
8
8
|
SUBPROCESS_MAX_BUFFER,
|
|
9
9
|
execFileAsync
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2PMHC6IL.js";
|
|
11
11
|
import {
|
|
12
12
|
extractCommandProtectionCommandText,
|
|
13
13
|
findCommandProtectionGitLookups,
|
|
14
14
|
findGitCommitSignals,
|
|
15
15
|
findPrMergeSignals,
|
|
16
16
|
parseCommandProtectionRequest
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-QU4FXL4X.js";
|
|
18
18
|
|
|
19
19
|
// src/services/command-protection-service.ts
|
|
20
20
|
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-2PMHC6IL.js";
|
|
7
7
|
import {
|
|
8
8
|
isVersionBelow
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QU4FXL4X.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.987";
|
|
244
244
|
var INITIALIZE_METHOD = "initialize";
|
|
245
245
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
246
246
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -1194,7 +1194,8 @@ var subagentResponseSchema = z3.object({
|
|
|
1194
1194
|
chatId: z3.string().uuid(),
|
|
1195
1195
|
status: z3.enum(["working", "completed"]),
|
|
1196
1196
|
response: z3.string().optional(),
|
|
1197
|
-
timedOut: z3.literal(true).optional()
|
|
1197
|
+
timedOut: z3.literal(true).optional(),
|
|
1198
|
+
interruptedByUserMessage: z3.literal(true).optional()
|
|
1198
1199
|
});
|
|
1199
1200
|
var integrationErrorNotificationTargetSchema = z3.discriminatedUnion("type", [
|
|
1200
1201
|
z3.object({
|
|
@@ -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-G6QBYUZR.js";
|
|
7
|
+
import "./chunk-TYH3IEXZ.js";
|
|
8
|
+
import "./chunk-2PMHC6IL.js";
|
|
9
9
|
import {
|
|
10
10
|
isRecord
|
|
11
11
|
} from "./chunk-UZSNFLDQ.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-QU4FXL4X.js";
|
|
13
13
|
import "./chunk-VEQXQN22.js";
|
|
14
14
|
|
|
15
15
|
// src/command-protection-hook.ts
|
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
AppServerProcess,
|
|
9
9
|
buildCodexAgentEnv
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-KAJYMTYA.js";
|
|
11
|
+
import "./chunk-2PMHC6IL.js";
|
|
12
12
|
import {
|
|
13
13
|
AGENT,
|
|
14
14
|
headlessAgentRequestSchema
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-QU4FXL4X.js";
|
|
16
16
|
import "./chunk-VEQXQN22.js";
|
|
17
17
|
|
|
18
18
|
// src/headless-agent.ts
|
package/dist/src/index.js
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
reportCommandProtectionBlock,
|
|
33
33
|
resolveDiffBase,
|
|
34
34
|
runGitCommand
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-G6QBYUZR.js";
|
|
36
36
|
import {
|
|
37
37
|
ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
|
|
38
38
|
AGENT_MESSAGE_DELTA_METHOD,
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
} from "./chunk-P73LGPQO.js";
|
|
58
58
|
import {
|
|
59
59
|
publishedPullRequestUrls
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-5EHMJ4OT.js";
|
|
61
61
|
import {
|
|
62
62
|
BaseRefreshManager,
|
|
63
63
|
CodexAspAuthMethodChangedError,
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
refreshDelayMs,
|
|
73
73
|
restartCodexAspHost,
|
|
74
74
|
routineRefreshExclusions
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-D5B72SUV.js";
|
|
76
76
|
import {
|
|
77
77
|
ENGINE_ENV,
|
|
78
78
|
monolithRequest,
|
|
@@ -80,16 +80,16 @@ import {
|
|
|
80
80
|
readRuntimeEnvFile,
|
|
81
81
|
reloadEngineEnv,
|
|
82
82
|
setAgentCredentialSnapshot
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-TYH3IEXZ.js";
|
|
84
84
|
import {
|
|
85
85
|
AspClient,
|
|
86
86
|
getCodexModelProvider
|
|
87
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-KAJYMTYA.js";
|
|
88
88
|
import {
|
|
89
89
|
SUBPROCESS_MAX_BUFFER,
|
|
90
90
|
execAsync,
|
|
91
91
|
execFileAsync
|
|
92
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-2PMHC6IL.js";
|
|
93
93
|
import {
|
|
94
94
|
isRecord as isRecord2
|
|
95
95
|
} from "./chunk-UZSNFLDQ.js";
|
|
@@ -315,7 +315,7 @@ import {
|
|
|
315
315
|
workspaceCredentialProviderSchema,
|
|
316
316
|
workspaceTokenRequestSchema,
|
|
317
317
|
workspaceTokenResponseSchema
|
|
318
|
-
} from "./chunk-
|
|
318
|
+
} from "./chunk-QU4FXL4X.js";
|
|
319
319
|
import {
|
|
320
320
|
cloneMcpConfig,
|
|
321
321
|
ensureCompatibilityImports,
|
|
@@ -10166,6 +10166,7 @@ var EnvironmentDetailsService = class {
|
|
|
10166
10166
|
details.engineVersion = ENGINE_ENV.REPLICAS_SANDBOX_IMAGE_VERSION;
|
|
10167
10167
|
details.supportsMidTurnSteering = true;
|
|
10168
10168
|
details.supportsClaudeMidTurnSteering = true;
|
|
10169
|
+
details.supportsSendNow = true;
|
|
10169
10170
|
details.supportsClaudeGoals = true;
|
|
10170
10171
|
details.supportsGoalUpdates = true;
|
|
10171
10172
|
details.supportsQueuedMessageEditing = true;
|
|
@@ -11769,6 +11770,7 @@ var MessageQueueService = class {
|
|
|
11769
11770
|
// version below.
|
|
11770
11771
|
acceptanceWithdrawals = /* @__PURE__ */ new WeakSet();
|
|
11771
11772
|
queueCancellationVersion = 0;
|
|
11773
|
+
activeTurn = null;
|
|
11772
11774
|
constructor(processMessage, onProcessingChanged = () => {
|
|
11773
11775
|
}, onMessageStarted = async () => {
|
|
11774
11776
|
}) {
|
|
@@ -11863,6 +11865,8 @@ var MessageQueueService = class {
|
|
|
11863
11865
|
return tail.merge === true && tail.type === request.type;
|
|
11864
11866
|
}
|
|
11865
11867
|
async startProcessing(queuedMessage) {
|
|
11868
|
+
const turn = new AbortController();
|
|
11869
|
+
this.activeTurn = turn;
|
|
11866
11870
|
this.processing = true;
|
|
11867
11871
|
this.onProcessingChanged(true);
|
|
11868
11872
|
try {
|
|
@@ -11874,11 +11878,14 @@ var MessageQueueService = class {
|
|
|
11874
11878
|
this.acceptanceByMessage.delete(queuedMessage);
|
|
11875
11879
|
break;
|
|
11876
11880
|
}
|
|
11877
|
-
|
|
11878
|
-
|
|
11881
|
+
if (!turn.signal.aborted) {
|
|
11882
|
+
await this.onMessageStarted(queuedMessage);
|
|
11883
|
+
await this.processMessage(queuedMessage, turn.signal);
|
|
11884
|
+
}
|
|
11879
11885
|
} catch (error) {
|
|
11880
11886
|
console.error("[MessageQueue] Error processing message:", error);
|
|
11881
11887
|
} finally {
|
|
11888
|
+
this.activeTurn = null;
|
|
11882
11889
|
this.processing = false;
|
|
11883
11890
|
if (this.queue.length === 0) {
|
|
11884
11891
|
this.onProcessingChanged(false);
|
|
@@ -11898,22 +11905,15 @@ var MessageQueueService = class {
|
|
|
11898
11905
|
isProcessing() {
|
|
11899
11906
|
return this.processing;
|
|
11900
11907
|
}
|
|
11901
|
-
drainQueue(
|
|
11902
|
-
const
|
|
11903
|
-
const maxChars = options?.maxChars ?? Number.POSITIVE_INFINITY;
|
|
11904
|
-
const drained = [];
|
|
11905
|
-
let totalChars = 0;
|
|
11906
|
-
for (const message of this.queue) {
|
|
11907
|
-
if (drained.length >= maxItems) break;
|
|
11908
|
-
const text = message.message;
|
|
11909
|
-
if (totalChars + text.length > maxChars) break;
|
|
11910
|
-
drained.push(text);
|
|
11911
|
-
totalChars += text.length;
|
|
11912
|
-
}
|
|
11908
|
+
drainQueue() {
|
|
11909
|
+
const drained = this.queue;
|
|
11913
11910
|
this.queueCancellationVersion++;
|
|
11914
11911
|
this.queue = [];
|
|
11915
11912
|
return drained;
|
|
11916
11913
|
}
|
|
11914
|
+
cancelActiveTurn() {
|
|
11915
|
+
this.activeTurn?.abort();
|
|
11916
|
+
}
|
|
11917
11917
|
/**
|
|
11918
11918
|
* Get all queued messages (does not include the currently processing message)
|
|
11919
11919
|
*/
|
|
@@ -11973,6 +11973,16 @@ Native subagent tools are disabled in this workspace. To delegate work to a suba
|
|
|
11973
11973
|
// src/managers/coding-agent-manager.ts
|
|
11974
11974
|
var MAX_INTERRUPT_QUEUE_ITEMS = 1e3;
|
|
11975
11975
|
var MAX_INTERRUPT_QUEUE_CHARS = 2e5;
|
|
11976
|
+
function toQueuedMessageInfo(message) {
|
|
11977
|
+
return {
|
|
11978
|
+
id: message.id,
|
|
11979
|
+
message: message.message,
|
|
11980
|
+
queuedAt: message.queuedAt,
|
|
11981
|
+
...message.senderUserId ? { senderUserId: message.senderUserId } : {},
|
|
11982
|
+
...message.senderEmail ? { senderEmail: message.senderEmail } : {},
|
|
11983
|
+
...message.senderDisplayName ? { senderDisplayName: message.senderDisplayName } : {}
|
|
11984
|
+
};
|
|
11985
|
+
}
|
|
11976
11986
|
var subagentMcpConfigRequest = null;
|
|
11977
11987
|
var CodingAgentManager = class {
|
|
11978
11988
|
workingDirectory;
|
|
@@ -11984,13 +11994,14 @@ var CodingAgentManager = class {
|
|
|
11984
11994
|
onUsageUpdate;
|
|
11985
11995
|
linearSessionId;
|
|
11986
11996
|
chatId;
|
|
11987
|
-
|
|
11997
|
+
hostOnTurnComplete;
|
|
11988
11998
|
onProcessingChanged;
|
|
11989
11999
|
onMessageStarted;
|
|
11990
12000
|
onModelSwitched;
|
|
11991
12001
|
authFallback;
|
|
11992
12002
|
subagentMcpChatId;
|
|
11993
12003
|
subagentMcpEnabledForTurn = false;
|
|
12004
|
+
unreadSteers = /* @__PURE__ */ new Map();
|
|
11994
12005
|
constructor(options) {
|
|
11995
12006
|
this.workingDirectory = options.workingDirectory ?? ENGINE_ENV.WORKSPACE_ROOT;
|
|
11996
12007
|
this.initialSessionId = options.initialSessionId;
|
|
@@ -12001,7 +12012,7 @@ var CodingAgentManager = class {
|
|
|
12001
12012
|
this.subagentMcpChatId = options.parentChatId === null && options.provider && SUBAGENT_MCP_HARNESSES.includes(options.provider) ? options.chatId : void 0;
|
|
12002
12013
|
this.linearSessionId = options.linearSessionId;
|
|
12003
12014
|
this.chatId = options.chatId;
|
|
12004
|
-
this.
|
|
12015
|
+
this.hostOnTurnComplete = options.onTurnComplete;
|
|
12005
12016
|
this.onProcessingChanged = options.onProcessingChanged ?? (() => {
|
|
12006
12017
|
});
|
|
12007
12018
|
this.onMessageStarted = options.onMessageStarted ?? (async () => {
|
|
@@ -12019,6 +12030,10 @@ var CodingAgentManager = class {
|
|
|
12019
12030
|
if (result.outcome === "switched" && result.model) await this.onModelSwitched(result.model);
|
|
12020
12031
|
return result;
|
|
12021
12032
|
}
|
|
12033
|
+
onTurnComplete = async () => {
|
|
12034
|
+
this.requeueUnreadSteers();
|
|
12035
|
+
await this.hostOnTurnComplete();
|
|
12036
|
+
};
|
|
12022
12037
|
emitSyntheticEvent(type, payload) {
|
|
12023
12038
|
this.onEvent({
|
|
12024
12039
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -12061,9 +12076,10 @@ var CodingAgentManager = class {
|
|
|
12061
12076
|
}
|
|
12062
12077
|
initializeManager(processMessage) {
|
|
12063
12078
|
this.messageQueue = new MessageQueueService(
|
|
12064
|
-
async (request) => {
|
|
12079
|
+
async (request, signal) => {
|
|
12065
12080
|
await this.refreshSubagentMcp();
|
|
12066
|
-
|
|
12081
|
+
if (signal.aborted) return;
|
|
12082
|
+
await processMessage(request, signal);
|
|
12067
12083
|
},
|
|
12068
12084
|
this.onProcessingChanged,
|
|
12069
12085
|
this.onMessageStarted
|
|
@@ -12091,46 +12107,55 @@ var CodingAgentManager = class {
|
|
|
12091
12107
|
if (!history?.appendDurably) throw new Error("Chat history is unavailable");
|
|
12092
12108
|
await history.appendDurably(event);
|
|
12093
12109
|
}
|
|
12094
|
-
async interrupt() {
|
|
12095
|
-
const queuedMessages = this.messageQueue.
|
|
12096
|
-
const
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
});
|
|
12110
|
+
async interrupt(persistRemoval) {
|
|
12111
|
+
const queuedMessages = this.messageQueue.drainQueue();
|
|
12112
|
+
const unreadSteers = [...this.unreadSteers.values()];
|
|
12113
|
+
this.unreadSteers.clear();
|
|
12114
|
+
this.messageQueue.cancelActiveTurn();
|
|
12100
12115
|
const isProcessing = this.isProcessing();
|
|
12101
12116
|
if (isProcessing) {
|
|
12102
12117
|
try {
|
|
12103
12118
|
await this.interruptActiveTurn();
|
|
12104
12119
|
} catch (error) {
|
|
12105
|
-
this.
|
|
12120
|
+
for (const steer of unreadSteers) this.unreadSteers.set(steer.message.id, steer);
|
|
12121
|
+
this.restoreQueuedMessages(queuedMessages.map((message, index) => ({ message, index })));
|
|
12106
12122
|
throw error;
|
|
12107
12123
|
}
|
|
12108
|
-
|
|
12109
|
-
|
|
12110
|
-
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
|
|
12114
|
-
|
|
12124
|
+
}
|
|
12125
|
+
const removed = [...unreadSteers.map(({ message }) => message), ...queuedMessages];
|
|
12126
|
+
if (removed.length > 0) await persistRemoval(removed.map(({ id }) => id));
|
|
12127
|
+
if (isProcessing) this.recordInterrupted();
|
|
12128
|
+
const queue = [];
|
|
12129
|
+
let queueChars = 0;
|
|
12130
|
+
for (const { message } of removed) {
|
|
12131
|
+
if (queue.length >= MAX_INTERRUPT_QUEUE_ITEMS || queueChars + message.length > MAX_INTERRUPT_QUEUE_CHARS) break;
|
|
12132
|
+
queue.push(message);
|
|
12133
|
+
queueChars += message.length;
|
|
12115
12134
|
}
|
|
12116
12135
|
this.emitInterruptedQueueEvent(queue);
|
|
12117
12136
|
return {
|
|
12118
|
-
interrupted: isProcessing ||
|
|
12119
|
-
queue
|
|
12137
|
+
interrupted: isProcessing || removed.length > 0,
|
|
12138
|
+
queue,
|
|
12139
|
+
removedMessageIds: removed.map(({ id }) => id)
|
|
12140
|
+
};
|
|
12141
|
+
}
|
|
12142
|
+
recordInterrupted() {
|
|
12143
|
+
const event = {
|
|
12144
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12145
|
+
type: CHAT_INTERRUPTED_EVENT_TYPE,
|
|
12146
|
+
payload: {}
|
|
12120
12147
|
};
|
|
12148
|
+
this.onEvent(event);
|
|
12149
|
+
this.getHistorySink()?.append(event);
|
|
12121
12150
|
}
|
|
12122
12151
|
isProcessing() {
|
|
12123
12152
|
return this.messageQueue.isProcessing();
|
|
12124
12153
|
}
|
|
12125
12154
|
getQueue() {
|
|
12126
|
-
return
|
|
12127
|
-
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
...m.senderUserId ? { senderUserId: m.senderUserId } : {},
|
|
12131
|
-
...m.senderEmail ? { senderEmail: m.senderEmail } : {},
|
|
12132
|
-
...m.senderDisplayName ? { senderDisplayName: m.senderDisplayName } : {}
|
|
12133
|
-
}));
|
|
12155
|
+
return [
|
|
12156
|
+
...[...this.unreadSteers.values()].map(({ message, steeredAt }) => ({ ...toQueuedMessageInfo(message), steeredAt })),
|
|
12157
|
+
...this.messageQueue.getQueue().map(toQueuedMessageInfo)
|
|
12158
|
+
];
|
|
12134
12159
|
}
|
|
12135
12160
|
async removeFromQueue(messageId, persistRemoval) {
|
|
12136
12161
|
return this.removeQueuedMessages([messageId], persistRemoval);
|
|
@@ -12176,33 +12201,54 @@ var CodingAgentManager = class {
|
|
|
12176
12201
|
if (!taken) {
|
|
12177
12202
|
return { success: false, queue: this.getQueue() };
|
|
12178
12203
|
}
|
|
12179
|
-
const keepQueued = this.keepSteeredMessageQueued();
|
|
12180
|
-
if (keepQueued) {
|
|
12181
|
-
this.messageQueue.restoreToQueue(taken.message, 0);
|
|
12182
|
-
}
|
|
12183
12204
|
let steered = false;
|
|
12184
12205
|
try {
|
|
12185
12206
|
steered = await this.steerRequest(taken.message);
|
|
12186
12207
|
} catch (error) {
|
|
12187
12208
|
console.error("[CodingAgentManager] steerRequest threw, keeping message queued:", error);
|
|
12188
12209
|
}
|
|
12189
|
-
if (
|
|
12190
|
-
|
|
12191
|
-
|
|
12192
|
-
|
|
12193
|
-
|
|
12194
|
-
|
|
12210
|
+
if (steered) this.unreadSteers.set(messageId, { message: taken.message, steeredAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
12211
|
+
else this.restoreQueuedMessages([{ message: taken.message, index: 0 }]);
|
|
12212
|
+
return { success: steered, queue: this.getQueue() };
|
|
12213
|
+
}
|
|
12214
|
+
async sendNow(messageId) {
|
|
12215
|
+
await this.initialized;
|
|
12216
|
+
const queued = this.messageQueue.getQueue().some(({ id }) => id === messageId);
|
|
12217
|
+
if (!queued && !this.unreadSteers.has(messageId)) return { success: false, queue: this.getQueue() };
|
|
12218
|
+
const turnRunning = this.messageQueue.isProcessing();
|
|
12219
|
+
if (turnRunning && this.canDeliverSteersNow()) {
|
|
12220
|
+
if (queued) await this.steerFromQueue(messageId);
|
|
12221
|
+
if (this.unreadSteers.has(messageId)) {
|
|
12222
|
+
await this.deliverSteersNow();
|
|
12223
|
+
return { success: true, queue: this.getQueue() };
|
|
12195
12224
|
}
|
|
12196
12225
|
}
|
|
12197
|
-
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12226
|
+
this.requeueUnreadSteers();
|
|
12227
|
+
const taken = this.messageQueue.takeFromQueue(messageId);
|
|
12228
|
+
if (taken) this.messageQueue.restoreToQueue(taken.message, 0);
|
|
12229
|
+
if (turnRunning) {
|
|
12230
|
+
this.recordInterrupted();
|
|
12231
|
+
this.messageQueue.cancelActiveTurn();
|
|
12232
|
+
await this.interruptActiveTurn();
|
|
12233
|
+
}
|
|
12234
|
+
return { success: true, queue: this.getQueue() };
|
|
12235
|
+
}
|
|
12236
|
+
requeueUnreadSteers() {
|
|
12237
|
+
const steers = [...this.unreadSteers.values()].map(({ message }) => message);
|
|
12238
|
+
this.unreadSteers.clear();
|
|
12239
|
+
this.restoreQueuedMessages(steers.map((message) => ({ message, index: 0 })));
|
|
12240
|
+
}
|
|
12241
|
+
markSteerRead(messageId) {
|
|
12242
|
+
const steer = this.unreadSteers.get(messageId);
|
|
12243
|
+
this.unreadSteers.delete(messageId);
|
|
12244
|
+
return steer?.message ?? this.messageQueue.takeFromQueue(messageId)?.message;
|
|
12202
12245
|
}
|
|
12203
|
-
|
|
12246
|
+
canDeliverSteersNow() {
|
|
12204
12247
|
return false;
|
|
12205
12248
|
}
|
|
12249
|
+
deliverSteersNow() {
|
|
12250
|
+
return Promise.resolve();
|
|
12251
|
+
}
|
|
12206
12252
|
steerRequest(_request) {
|
|
12207
12253
|
return Promise.resolve(false);
|
|
12208
12254
|
}
|
|
@@ -13035,11 +13081,19 @@ function isClaudeSessionActive(activity) {
|
|
|
13035
13081
|
// src/managers/claude-background-tasks.ts
|
|
13036
13082
|
var ClaudeBackgroundTasks = class {
|
|
13037
13083
|
active = /* @__PURE__ */ new Set();
|
|
13084
|
+
foreground = /* @__PURE__ */ new Set();
|
|
13038
13085
|
reset() {
|
|
13039
13086
|
this.active.clear();
|
|
13087
|
+
this.foreground.clear();
|
|
13040
13088
|
}
|
|
13041
13089
|
update(message) {
|
|
13042
|
-
if (message.type !== "system"
|
|
13090
|
+
if (message.type !== "system") return;
|
|
13091
|
+
if (message.subtype === "task_started" && message.is_backgrounded === false) this.foreground.add(message.task_id);
|
|
13092
|
+
if (message.subtype === "task_notification") this.foreground.delete(message.task_id);
|
|
13093
|
+
if (message.subtype === "task_updated" && (message.patch.is_backgrounded || message.patch.status && message.patch.status !== "running")) {
|
|
13094
|
+
this.foreground.delete(message.task_id);
|
|
13095
|
+
}
|
|
13096
|
+
if (message.subtype !== "background_tasks_changed") return;
|
|
13043
13097
|
this.active.clear();
|
|
13044
13098
|
for (const task of message.tasks) {
|
|
13045
13099
|
if (!task.ambient) this.active.add(task.task_id);
|
|
@@ -13359,25 +13413,31 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
13359
13413
|
await this.abortAllPendingToolInputs();
|
|
13360
13414
|
await this.tearDownSession(true);
|
|
13361
13415
|
}
|
|
13416
|
+
canDeliverSteersNow() {
|
|
13417
|
+
return this.activeQuery !== null && this.backgroundTasks.foreground.size > 0;
|
|
13418
|
+
}
|
|
13419
|
+
async deliverSteersNow() {
|
|
13420
|
+
await this.activeQuery?.backgroundTasks();
|
|
13421
|
+
}
|
|
13362
13422
|
// Claude Code folds a `next`-priority prompt into the running turn at its next tool boundary.
|
|
13363
13423
|
async steerRequest(request) {
|
|
13364
13424
|
const pendingTurn = this.pendingTurn;
|
|
13365
13425
|
const promptStream = this.activePromptStream;
|
|
13366
13426
|
if (!pendingTurn || !promptStream) return false;
|
|
13367
|
-
if (getGoalCommand(request.message, request.goalMode))
|
|
13368
|
-
this.messageQueue.restoreToQueue(request, 0);
|
|
13369
|
-
await this.interruptActiveTurn();
|
|
13370
|
-
return true;
|
|
13371
|
-
}
|
|
13427
|
+
if (getGoalCommand(request.message, request.goalMode)) return false;
|
|
13372
13428
|
const userMessage = await this.buildUserMessage(request);
|
|
13373
13429
|
if (this.pendingTurn !== pendingTurn || this.activePromptStream !== promptStream) return false;
|
|
13374
13430
|
pendingTurn.userMessageUuids.add(userMessage.uuid);
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
await this.recordEvent(userMessage, request.messageId);
|
|
13378
|
-
promptStream.push(steer);
|
|
13431
|
+
pendingTurn.steers.set(userMessage.uuid, { messageId: request.id, userMessage });
|
|
13432
|
+
promptStream.push({ ...userMessage, priority: "next" });
|
|
13379
13433
|
return true;
|
|
13380
13434
|
}
|
|
13435
|
+
async recordSteerRead(uuid) {
|
|
13436
|
+
const steer = this.pendingTurn?.steers.get(uuid);
|
|
13437
|
+
if (!steer) return;
|
|
13438
|
+
this.pendingTurn?.steers.delete(uuid);
|
|
13439
|
+
if (this.markSteerRead(steer.messageId)) await this.recordEvent(steer.userMessage, steer.messageId);
|
|
13440
|
+
}
|
|
13381
13441
|
async abortAllPendingToolInputs() {
|
|
13382
13442
|
const pending = Array.from(this.pendingToolInputs.values());
|
|
13383
13443
|
this.pendingToolInputs.clear();
|
|
@@ -13633,7 +13693,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
13633
13693
|
}
|
|
13634
13694
|
}
|
|
13635
13695
|
}
|
|
13636
|
-
async processMessageInternal(request) {
|
|
13696
|
+
async processMessageInternal(request, signal) {
|
|
13637
13697
|
let lastError;
|
|
13638
13698
|
let authRetryExhausted = false;
|
|
13639
13699
|
let quotaFallbacks = 0;
|
|
@@ -13643,7 +13703,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
13643
13703
|
let midTurnContinues = 0;
|
|
13644
13704
|
let missingSessionReset = false;
|
|
13645
13705
|
let currentRequest = request;
|
|
13646
|
-
let carriedSteers =
|
|
13706
|
+
let carriedSteers = /* @__PURE__ */ new Map();
|
|
13647
13707
|
await this.goalClear?.catch(() => {
|
|
13648
13708
|
});
|
|
13649
13709
|
try {
|
|
@@ -13651,10 +13711,10 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
13651
13711
|
await this.turnCredentials?.refresh();
|
|
13652
13712
|
while (true) {
|
|
13653
13713
|
const attemptedCredential = this.turnCredentials ? this.turnCredentials.snapshot() : ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.claude;
|
|
13654
|
-
const
|
|
13655
|
-
carriedSteers =
|
|
13714
|
+
const steers = carriedSteers;
|
|
13715
|
+
carriedSteers = /* @__PURE__ */ new Map();
|
|
13656
13716
|
try {
|
|
13657
|
-
await this.executeQuery(currentRequest, { skipUserMessageRecord: attempt > 0,
|
|
13717
|
+
await this.executeQuery(currentRequest, { skipUserMessageRecord: attempt > 0, signal, steers });
|
|
13658
13718
|
return;
|
|
13659
13719
|
} catch (error) {
|
|
13660
13720
|
lastError = error;
|
|
@@ -13699,7 +13759,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
13699
13759
|
missingSessionReset = true;
|
|
13700
13760
|
console.warn(`[ClaudeManager] Session ${this.sessionId} has no transcript; starting a fresh session:`, error.message);
|
|
13701
13761
|
this.sessionId = null;
|
|
13702
|
-
carriedSteers =
|
|
13762
|
+
carriedSteers = steers;
|
|
13703
13763
|
await this.onSaveSessionId(null);
|
|
13704
13764
|
await this.tearDownSession();
|
|
13705
13765
|
attempt++;
|
|
@@ -13882,21 +13942,21 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
13882
13942
|
if (!promptStream || !activeQuery) {
|
|
13883
13943
|
throw new Error("Claude session unavailable after ensureSession");
|
|
13884
13944
|
}
|
|
13885
|
-
if (this.pendingInterrupt) {
|
|
13945
|
+
if (this.pendingInterrupt || options.signal?.aborted) {
|
|
13886
13946
|
this.pendingInterrupt = false;
|
|
13887
13947
|
return;
|
|
13888
13948
|
}
|
|
13889
13949
|
await new Promise((resolve7, reject) => {
|
|
13890
|
-
const
|
|
13950
|
+
const steers = options.steers ?? /* @__PURE__ */ new Map();
|
|
13891
13951
|
this.pendingTurn = {
|
|
13892
13952
|
resolve: resolve7,
|
|
13893
13953
|
reject,
|
|
13894
13954
|
sawActivity: false,
|
|
13895
|
-
|
|
13896
|
-
userMessageUuids: /* @__PURE__ */ new Set([userMessage.uuid, ...
|
|
13955
|
+
steers,
|
|
13956
|
+
userMessageUuids: /* @__PURE__ */ new Set([userMessage.uuid, ...steers.keys()])
|
|
13897
13957
|
};
|
|
13898
13958
|
promptStream.push(goalCommand ? { ...userMessage, message: { role: "user", content: `/goal ${goalObjective ?? "clear"}` } } : userMessage);
|
|
13899
|
-
for (const steer of
|
|
13959
|
+
for (const { userMessage: steer } of steers.values()) promptStream.push({ ...steer, priority: "next" });
|
|
13900
13960
|
});
|
|
13901
13961
|
}
|
|
13902
13962
|
async buildUserMessage({ message, images }) {
|
|
@@ -14119,6 +14179,10 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
14119
14179
|
}
|
|
14120
14180
|
const wasProcessing = this.isProcessing();
|
|
14121
14181
|
this.setAuthRetrying(false);
|
|
14182
|
+
const lifecycle2 = msg;
|
|
14183
|
+
if (isRecord(lifecycle2) && lifecycle2.type === "command_lifecycle" && lifecycle2.state === "started" && typeof lifecycle2.command_uuid === "string") {
|
|
14184
|
+
await this.recordSteerRead(lifecycle2.command_uuid);
|
|
14185
|
+
}
|
|
14122
14186
|
if (this.pendingTurn && _ClaudeManager.isTurnActivity(msg)) {
|
|
14123
14187
|
this.pendingTurn.sawActivity = true;
|
|
14124
14188
|
}
|
|
@@ -14145,6 +14209,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
14145
14209
|
if (this.activeQuery !== response) break;
|
|
14146
14210
|
this.sessionLinearForwarder?.flushThoughtAsResponse();
|
|
14147
14211
|
const pendingUuids = this.pendingTurn?.userMessageUuids;
|
|
14212
|
+
for (const uuid of msg.user_message_uuids ?? []) await this.recordSteerRead(uuid);
|
|
14148
14213
|
if (msg.user_message_uuid) {
|
|
14149
14214
|
for (const uuid of msg.user_message_uuids ?? [msg.user_message_uuid]) pendingUuids?.delete(uuid);
|
|
14150
14215
|
if (pendingUuids?.size === 0) this.resolvePendingTurn();
|
|
@@ -15308,10 +15373,13 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15308
15373
|
async subagentMcpForTurn(enabled) {
|
|
15309
15374
|
return this.currentThreadId ? existsSync9(join17(SUBAGENT_MCP_THREADS_DIR, this.currentThreadId)) : enabled;
|
|
15310
15375
|
}
|
|
15311
|
-
async
|
|
15376
|
+
async interrupt(persistRemoval) {
|
|
15312
15377
|
if (this.currentGoal?.status === "active") {
|
|
15313
15378
|
await this.updateGoal({ status: "paused" });
|
|
15314
15379
|
}
|
|
15380
|
+
return super.interrupt(persistRemoval);
|
|
15381
|
+
}
|
|
15382
|
+
async interruptActiveTurn() {
|
|
15315
15383
|
if (!this.currentThreadId || !this.activeTurnId) {
|
|
15316
15384
|
return;
|
|
15317
15385
|
}
|
|
@@ -15370,7 +15438,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15370
15438
|
expectedTurnId,
|
|
15371
15439
|
(host, turnId) => host.client.request(
|
|
15372
15440
|
TURN_STEER_METHOD,
|
|
15373
|
-
{ threadId, expectedTurnId: turnId, input }
|
|
15441
|
+
{ threadId, expectedTurnId: turnId, input, clientUserMessageId: request.id }
|
|
15374
15442
|
)
|
|
15375
15443
|
);
|
|
15376
15444
|
if (!result.ok) {
|
|
@@ -15386,7 +15454,6 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15386
15454
|
} else {
|
|
15387
15455
|
await removeTempImageFiles(tempImagePaths);
|
|
15388
15456
|
}
|
|
15389
|
-
this.recordUserMessageEvent(request);
|
|
15390
15457
|
return true;
|
|
15391
15458
|
}
|
|
15392
15459
|
async getHistory(page2 = {}) {
|
|
@@ -15477,7 +15544,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15477
15544
|
...extraPayload
|
|
15478
15545
|
}));
|
|
15479
15546
|
}
|
|
15480
|
-
async processMessageInternal(request) {
|
|
15547
|
+
async processMessageInternal(request, signal) {
|
|
15481
15548
|
let userMessageRecorded = false;
|
|
15482
15549
|
let quotaFallbackAttempted = false;
|
|
15483
15550
|
const recordUserMessage = (extraPayload = {}) => {
|
|
@@ -15488,8 +15555,8 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15488
15555
|
const goalCommand = getGoalCommand(request.message, request.goalMode);
|
|
15489
15556
|
const dispatch = async () => {
|
|
15490
15557
|
if (isCompactCommand(request.message)) {
|
|
15491
|
-
await this.executeAspTurn(request, recordUserMessage, {
|
|
15492
|
-
runTurn: (host, threadId) => this.observeTurn(host, threadId, request, async () => {
|
|
15558
|
+
await this.executeAspTurn(request, recordUserMessage, signal, {
|
|
15559
|
+
runTurn: (host, threadId) => this.observeTurn(host, threadId, request, signal, async () => {
|
|
15493
15560
|
await host.client.request(
|
|
15494
15561
|
THREAD_COMPACT_START_METHOD,
|
|
15495
15562
|
{ threadId }
|
|
@@ -15513,13 +15580,13 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15513
15580
|
return;
|
|
15514
15581
|
}
|
|
15515
15582
|
if (goalCommand?.type === "set") {
|
|
15516
|
-
await this.executeAspTurn(request, recordUserMessage, {
|
|
15517
|
-
runTurn: (host, threadId) => this.runGoalTurn(host, threadId, request, goalCommand.objective),
|
|
15583
|
+
await this.executeAspTurn(request, recordUserMessage, signal, {
|
|
15584
|
+
runTurn: (host, threadId) => this.runGoalTurn(host, threadId, request, goalCommand.objective, signal),
|
|
15518
15585
|
userMessagePayload: { command: "goal" }
|
|
15519
15586
|
});
|
|
15520
15587
|
return;
|
|
15521
15588
|
}
|
|
15522
|
-
await this.executeAspTurn(request, recordUserMessage);
|
|
15589
|
+
await this.executeAspTurn(request, recordUserMessage, signal);
|
|
15523
15590
|
};
|
|
15524
15591
|
let attemptedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex;
|
|
15525
15592
|
try {
|
|
@@ -15611,14 +15678,15 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15611
15678
|
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
15612
15679
|
return { host, threadId };
|
|
15613
15680
|
}
|
|
15614
|
-
async executeAspTurn(request, recordUserMessage, options = {}) {
|
|
15681
|
+
async executeAspTurn(request, recordUserMessage, signal, options = {}) {
|
|
15615
15682
|
const host = await getCodexAspHost();
|
|
15616
15683
|
const developerInstructions = this.buildCombinedInstructions(request.customInstructions, true);
|
|
15617
15684
|
recordUserMessage(options.userMessagePayload);
|
|
15618
15685
|
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
15619
15686
|
const serviceTier = await this.resolveRequestedServiceTier(host, request);
|
|
15620
15687
|
await this.applyThreadServiceTier(host, threadId, serviceTier);
|
|
15621
|
-
|
|
15688
|
+
if (signal.aborted) return;
|
|
15689
|
+
const runTurn = options.runTurn ?? ((aspHost, aspThreadId) => this.runTurn(aspHost, aspThreadId, request, serviceTier, signal));
|
|
15622
15690
|
let completedTurn;
|
|
15623
15691
|
try {
|
|
15624
15692
|
completedTurn = await runTurn(host, threadId);
|
|
@@ -15758,9 +15826,9 @@ ${text.slice(-24e3)}`
|
|
|
15758
15826
|
console.warn("[CodexAspManager] Failed to apply skill registries:", error);
|
|
15759
15827
|
}
|
|
15760
15828
|
}
|
|
15761
|
-
async runTurn(host, threadId, request, serviceTier) {
|
|
15829
|
+
async runTurn(host, threadId, request, serviceTier, signal) {
|
|
15762
15830
|
const { params, tempImagePaths } = await buildTurnStartParams(threadId, request, serviceTier);
|
|
15763
|
-
return this.observeTurn(host, threadId, request, async () => {
|
|
15831
|
+
return this.observeTurn(host, threadId, request, signal, async () => {
|
|
15764
15832
|
const turnStartResponse = await host.client.request(
|
|
15765
15833
|
TURN_START_METHOD,
|
|
15766
15834
|
params
|
|
@@ -15768,8 +15836,8 @@ ${text.slice(-24e3)}`
|
|
|
15768
15836
|
return { turn: turnStartResponse.turn, tempImagePaths };
|
|
15769
15837
|
});
|
|
15770
15838
|
}
|
|
15771
|
-
async runGoalTurn(host, threadId, request, objective) {
|
|
15772
|
-
return this.observeTurn(host, threadId, request, async () => {
|
|
15839
|
+
async runGoalTurn(host, threadId, request, objective, signal) {
|
|
15840
|
+
return this.observeTurn(host, threadId, request, signal, async () => {
|
|
15773
15841
|
const response = await host.client.request(
|
|
15774
15842
|
THREAD_GOAL_SET_METHOD,
|
|
15775
15843
|
{ threadId, objective, status: "active" }
|
|
@@ -15778,7 +15846,15 @@ ${text.slice(-24e3)}`
|
|
|
15778
15846
|
return { turn: null, tempImagePaths: [] };
|
|
15779
15847
|
});
|
|
15780
15848
|
}
|
|
15781
|
-
async observeTurn(host, threadId, request, startTurn) {
|
|
15849
|
+
async observeTurn(host, threadId, request, signal, startTurn) {
|
|
15850
|
+
let stopSent = false;
|
|
15851
|
+
const interruptIfStopped = () => {
|
|
15852
|
+
if (!signal.aborted || stopSent) return;
|
|
15853
|
+
stopSent = true;
|
|
15854
|
+
void this.interruptActiveTurn().catch((error) => {
|
|
15855
|
+
console.error("[CodexAspManager] Failed to interrupt a turn stopped before it started:", error);
|
|
15856
|
+
});
|
|
15857
|
+
};
|
|
15782
15858
|
let resolveCompleted;
|
|
15783
15859
|
const completed = new Promise((resolve7) => {
|
|
15784
15860
|
resolveCompleted = resolve7;
|
|
@@ -15844,6 +15920,7 @@ ${text.slice(-24e3)}`
|
|
|
15844
15920
|
completedItems.length = 0;
|
|
15845
15921
|
agentMessageDeltas.clear();
|
|
15846
15922
|
this.startTurn(notification.params.turn);
|
|
15923
|
+
interruptIfStopped();
|
|
15847
15924
|
linearForwarder.sendEvent(convertCodexAspNotification(notification, linearSessionId ?? ""));
|
|
15848
15925
|
},
|
|
15849
15926
|
[TURN_PLAN_UPDATED_METHOD]: (notification) => {
|
|
@@ -15853,6 +15930,10 @@ ${text.slice(-24e3)}`
|
|
|
15853
15930
|
[ITEM_STARTED_METHOD]: (notification) => {
|
|
15854
15931
|
if (!matchesTurn(notification.params.threadId, notification.params.turnId)) return;
|
|
15855
15932
|
if (notification.params.item.type === "contextCompaction") this.compacting = true;
|
|
15933
|
+
if (notification.params.item.type === "userMessage" && notification.params.item.clientId) {
|
|
15934
|
+
const steer = this.markSteerRead(notification.params.item.clientId);
|
|
15935
|
+
if (steer) this.recordUserMessageEvent(steer);
|
|
15936
|
+
}
|
|
15856
15937
|
this.startItem(
|
|
15857
15938
|
notification.params.turnId,
|
|
15858
15939
|
itemToTranscriptItem(notification.params.item, timestampFromMilliseconds(notification.params.startedAtMs), "in_progress")
|
|
@@ -15956,6 +16037,7 @@ ${text.slice(-24e3)}`
|
|
|
15956
16037
|
this.activeTurnId = started.turn.id;
|
|
15957
16038
|
this.onCodexTurnStarted?.(threadId, started.turn.id);
|
|
15958
16039
|
this.startTurn(started.turn);
|
|
16040
|
+
interruptIfStopped();
|
|
15959
16041
|
}
|
|
15960
16042
|
const turn = await Promise.race([completed, disposed]);
|
|
15961
16043
|
linearForwarder.flushThoughtAsResponse();
|
|
@@ -17130,7 +17212,7 @@ ${typeof pending.subject.command === "string" ? pending.subject.command : JSON.s
|
|
|
17130
17212
|
}, this.historyFile);
|
|
17131
17213
|
}
|
|
17132
17214
|
}
|
|
17133
|
-
async processMessageInternal(request) {
|
|
17215
|
+
async processMessageInternal(request, signal) {
|
|
17134
17216
|
let userMessageRecorded = false;
|
|
17135
17217
|
const dispatch = async () => {
|
|
17136
17218
|
const model = request.model ?? DEFAULT_MUSE_MODEL;
|
|
@@ -17176,6 +17258,7 @@ ${pending}
|
|
|
17176
17258
|
</workspace-instructions>
|
|
17177
17259
|
|
|
17178
17260
|
` : ""}${request.planMode ? "Plan the requested work without modifying files or running mutating commands.\n\n" : ""}${request.message}`;
|
|
17261
|
+
if (signal.aborted) return;
|
|
17179
17262
|
this.turnError = null;
|
|
17180
17263
|
const completed = new Promise((resolve7) => {
|
|
17181
17264
|
this.turnComplete = { resolve: resolve7 };
|
|
@@ -17241,17 +17324,6 @@ ${pending}
|
|
|
17241
17324
|
turnId: this.activeTurnId
|
|
17242
17325
|
});
|
|
17243
17326
|
}
|
|
17244
|
-
async steerRequest(request) {
|
|
17245
|
-
if (!this.sessionId || !this.activeTurnId) return false;
|
|
17246
|
-
await this.request("turn/steer", {
|
|
17247
|
-
commandId: uuidV7(),
|
|
17248
|
-
sessionId: this.sessionId,
|
|
17249
|
-
expectedTurnId: this.activeTurnId,
|
|
17250
|
-
input: this.createTurnInput(request.message, request.images),
|
|
17251
|
-
reasoningEffort: codexReasoningEffortForThinkingLevel(request.thinkingLevel)
|
|
17252
|
-
});
|
|
17253
|
-
return true;
|
|
17254
|
-
}
|
|
17255
17327
|
async respondToToolInput(requestId, selectionId) {
|
|
17256
17328
|
const approval = [...this.pendingApprovals.values()].find((pending2) => pending2.requestId === requestId);
|
|
17257
17329
|
if (approval) {
|
|
@@ -58678,13 +58750,6 @@ var PiManager = class extends CodingAgentManager {
|
|
|
58678
58750
|
async interruptActiveTurn() {
|
|
58679
58751
|
await this.session?.abort();
|
|
58680
58752
|
}
|
|
58681
|
-
async steerRequest(request) {
|
|
58682
|
-
const session = this.session;
|
|
58683
|
-
if (!session?.isStreaming) return false;
|
|
58684
|
-
await session.steer(request.message);
|
|
58685
|
-
this.recordUserMessage(session, request);
|
|
58686
|
-
return true;
|
|
58687
|
-
}
|
|
58688
58753
|
async getHistory(page2 = {}) {
|
|
58689
58754
|
await this.historyFile.flush();
|
|
58690
58755
|
const history = await this.historyFile.loadEventsPage(page2);
|
|
@@ -58869,7 +58934,7 @@ var PiManager = class extends CodingAgentManager {
|
|
|
58869
58934
|
skillName ? { skillName } : {}
|
|
58870
58935
|
);
|
|
58871
58936
|
}
|
|
58872
|
-
async processMessageInternal(request) {
|
|
58937
|
+
async processMessageInternal(request, signal) {
|
|
58873
58938
|
try {
|
|
58874
58939
|
const session = await this.ensureSession(request);
|
|
58875
58940
|
this.recordUserMessage(session, request);
|
|
@@ -58878,6 +58943,7 @@ var PiManager = class extends CodingAgentManager {
|
|
|
58878
58943
|
data: image.source.data,
|
|
58879
58944
|
mimeType: image.source.media_type
|
|
58880
58945
|
})) : void 0;
|
|
58946
|
+
if (signal.aborted) return;
|
|
58881
58947
|
await session.prompt(request.message, images ? { images } : void 0);
|
|
58882
58948
|
} catch (error) {
|
|
58883
58949
|
this.recordHistoryEvent("pi-error", { message: error instanceof Error ? error.message : String(error) }, this.historyFile);
|
|
@@ -60838,6 +60904,9 @@ var ChatService = class {
|
|
|
60838
60904
|
if (signal?.aborted) throw new Error("Subagent wait was cancelled");
|
|
60839
60905
|
const result = await this.getSubagent(parentChatId, chatId);
|
|
60840
60906
|
if (result.status === "completed") return result;
|
|
60907
|
+
if (this.requireChat(parentChatId).provider.getQueue().some(({ steeredAt }) => steeredAt && Date.parse(steeredAt) >= startedAt)) {
|
|
60908
|
+
return { ...result, interruptedByUserMessage: true };
|
|
60909
|
+
}
|
|
60841
60910
|
const remainingMs = timeoutMs === null ? null : timeoutMs - (Date.now() - startedAt);
|
|
60842
60911
|
if (remainingMs !== null && remainingMs <= 0) return { ...result, timedOut: true };
|
|
60843
60912
|
await new Promise((resolve7) => setTimeout(
|
|
@@ -61020,7 +61089,7 @@ var ChatService = class {
|
|
|
61020
61089
|
}
|
|
61021
61090
|
async interrupt(chatId) {
|
|
61022
61091
|
const chat = this.requireChat(chatId);
|
|
61023
|
-
const result = await chat.provider.interrupt();
|
|
61092
|
+
const result = await chat.provider.interrupt((messageIds) => this.forgetPendingMessages(chat, messageIds));
|
|
61024
61093
|
this.endTrackedTurn(chatId);
|
|
61025
61094
|
chat.hasActiveTurn = false;
|
|
61026
61095
|
chat.activeMessageId = null;
|
|
@@ -61042,7 +61111,7 @@ var ChatService = class {
|
|
|
61042
61111
|
if (!chat.provider.clearGoal) {
|
|
61043
61112
|
return { interrupted: false, queue: [], goal: null };
|
|
61044
61113
|
}
|
|
61045
|
-
const interruptResult = await chat.provider.interrupt();
|
|
61114
|
+
const interruptResult = await chat.provider.interrupt((messageIds) => this.forgetPendingMessages(chat, messageIds));
|
|
61046
61115
|
this.endTrackedTurn(chatId);
|
|
61047
61116
|
chat.hasActiveTurn = false;
|
|
61048
61117
|
chat.activeMessageId = null;
|
|
@@ -61190,6 +61259,14 @@ var ChatService = class {
|
|
|
61190
61259
|
}
|
|
61191
61260
|
return result;
|
|
61192
61261
|
}
|
|
61262
|
+
async sendNow(chatId, messageId) {
|
|
61263
|
+
const chat = this.requireChat(chatId);
|
|
61264
|
+
const result = await chat.provider.sendNow(messageId);
|
|
61265
|
+
if (result.success && !result.queue.some(({ id, steeredAt }) => id === messageId && !steeredAt)) {
|
|
61266
|
+
chat.pendingMessageIds = chat.pendingMessageIds.filter((pendingMessageId) => pendingMessageId !== messageId);
|
|
61267
|
+
}
|
|
61268
|
+
return result;
|
|
61269
|
+
}
|
|
61193
61270
|
async respondToToolInput(chatId, requestId, selectionId) {
|
|
61194
61271
|
const chat = this.requireChat(chatId);
|
|
61195
61272
|
if (!chat.provider.respondToToolInput) {
|
|
@@ -61205,7 +61282,7 @@ var ChatService = class {
|
|
|
61205
61282
|
const target = this.chats.get(id);
|
|
61206
61283
|
if (!target || target.persisted.deletedAt) continue;
|
|
61207
61284
|
if (target.provider.isProcessing()) {
|
|
61208
|
-
await target.provider.interrupt().catch(() => {
|
|
61285
|
+
await target.provider.interrupt((messageIds) => this.forgetPendingMessages(target, messageIds)).catch(() => {
|
|
61209
61286
|
});
|
|
61210
61287
|
target.hasActiveTurn = false;
|
|
61211
61288
|
target.activeMessageId = null;
|
|
@@ -63490,17 +63567,21 @@ function createV1Routes(deps) {
|
|
|
63490
63567
|
return c.json(jsonError("Failed to update queued message", error instanceof Error ? error.message : "Unknown error"), 500);
|
|
63491
63568
|
}
|
|
63492
63569
|
});
|
|
63493
|
-
|
|
63494
|
-
|
|
63495
|
-
|
|
63496
|
-
|
|
63497
|
-
}
|
|
63498
|
-
|
|
63499
|
-
return c.json(
|
|
63570
|
+
for (const { action, failure, run } of [
|
|
63571
|
+
{ action: "steer", failure: "Failed to steer queued message", run: (chatId, messageId) => deps.chatService.steerFromQueue(chatId, messageId) },
|
|
63572
|
+
{ action: "send-now", failure: "Failed to send queued message now", run: (chatId, messageId) => deps.chatService.sendNow(chatId, messageId) }
|
|
63573
|
+
]) {
|
|
63574
|
+
app2.post(`/chats/:chatId/queue/:messageId/${action}`, async (c) => {
|
|
63575
|
+
try {
|
|
63576
|
+
return c.json(await run(c.req.param("chatId"), c.req.param("messageId")));
|
|
63577
|
+
} catch (error) {
|
|
63578
|
+
if (error instanceof ChatNotFoundError) {
|
|
63579
|
+
return c.json(jsonError("Chat not found", error.message), 404);
|
|
63580
|
+
}
|
|
63581
|
+
return c.json(jsonError(failure, error instanceof Error ? error.message : "Unknown error"), 500);
|
|
63500
63582
|
}
|
|
63501
|
-
|
|
63502
|
-
|
|
63503
|
-
});
|
|
63583
|
+
});
|
|
63584
|
+
}
|
|
63504
63585
|
app2.post("/chats/:chatId/tool-input", async (c) => {
|
|
63505
63586
|
try {
|
|
63506
63587
|
const body = respondToolInputSchema.parse(await c.req.json());
|
|
@@ -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-5EHMJ4OT.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-QU4FXL4X.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
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
spawnSubagentRequestSchema,
|
|
10
10
|
subagentResponseSchema,
|
|
11
11
|
waitSubagentRequestSchema
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-QU4FXL4X.js";
|
|
13
13
|
import "./chunk-VEQXQN22.js";
|
|
14
14
|
|
|
15
15
|
// src/subagent-mcp.ts
|
|
@@ -101,7 +101,7 @@ server.registerTool(SUBAGENT_MCP_TOOLS.getAgent, {
|
|
|
101
101
|
content: [{ type: "text", text: await request(`/chats/${parentChatId}/subagents/${chat_id}`, "GET") }]
|
|
102
102
|
}));
|
|
103
103
|
server.registerTool(SUBAGENT_MCP_TOOLS.waitAgent, {
|
|
104
|
-
description: "Wait for one of this chat\u2019s subagents to finish over a heartbeat stream. A timeout stops waiting without interrupting the child.",
|
|
104
|
+
description: "Wait for one of this chat\u2019s subagents to finish over a heartbeat stream. A timeout, or a new message from the user, stops waiting without interrupting the child.",
|
|
105
105
|
inputSchema: {
|
|
106
106
|
chat_id: z.string().uuid(),
|
|
107
107
|
timeout_minutes: waitSubagentRequestSchema.shape.timeoutMinutes
|