openfox 1.6.74 → 1.6.76
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/{ask-3RK5YJZE.js → ask-5SSOA6SZ.js} +2 -2
- package/dist/{auth-LZZX63KI.js → auth-56SIRACI.js} +3 -6
- package/dist/auto-compaction-V3PA77WG.js +27 -0
- package/dist/{branch.api-XADFZZAA.js → branch.api-PWFW26KC.js} +2 -2
- package/dist/{chat-handler-KYMMXPP6.js → chat-handler-7DKHGTVO.js} +31 -29
- package/dist/{chunk-5UTTLO4D.js → chunk-5ZD3GZTK.js} +89 -49
- package/dist/{chunk-AFATQ5LJ.js → chunk-B5AP3RSV.js} +1 -1
- package/dist/{chunk-22CTURMH.js → chunk-BJYPTN5S.js} +1 -1
- package/dist/{chunk-DLINTLB7.js → chunk-BSTVRSV6.js} +7 -5
- package/dist/{chunk-7JPKRM6M.js → chunk-CMQCO27Y.js} +22 -12
- package/dist/{chunk-R4HADRYO.js → chunk-CQGTEGKL.js} +1 -1
- package/dist/{chunk-J5DV33SS.js → chunk-CUDAT6SS.js} +46 -18
- package/dist/{chunk-ETIXH35K.js → chunk-H5EICXF3.js} +499 -277
- package/dist/{chunk-ODOA4RNN.js → chunk-K2V7EW5F.js} +541 -299
- package/dist/{chunk-PNBH3RAX.js → chunk-K44MW7JJ.js} +1 -1
- package/dist/{chunk-BLNFJ22S.js → chunk-KIOUKC3Z.js} +6 -4
- package/dist/{chunk-4CQ7CUQ6.js → chunk-LCQ3MPXD.js} +5 -5
- package/dist/{chunk-CTAIXOZJ.js → chunk-NDJ6FKSP.js} +1 -1
- package/dist/{chunk-IA4O65CR.js → chunk-NHJ2GVCF.js} +100 -68
- package/dist/{chunk-GQZGIMJO.js → chunk-OXI26S7U.js} +12 -7
- package/dist/{chunk-NBU6KIOD.js → chunk-PBGOZMVY.js} +4 -4
- package/dist/{chunk-B7E3BICY.js → chunk-RGRBWDZP.js} +2 -4
- package/dist/{chunk-CLBUWGUB.js → chunk-RQ4XSKUR.js} +15 -16
- package/dist/{chunk-KFBIHS3S.js → chunk-STYHKCG7.js} +20 -14
- package/dist/{chunk-55Z3DJ7G.js → chunk-TGWEH2BC.js} +10 -11
- package/dist/{chunk-TYUNDOX2.js → chunk-UKMRZDWM.js} +90 -41
- package/dist/{chunk-PFRQO5Z3.js → chunk-VAMTEAYI.js} +49 -27
- package/dist/{chunk-574HZVLE.js → chunk-VRGRAQDG.js} +2 -2
- package/dist/{chunk-JQBTYHUR.js → chunk-WR6QCJJO.js} +53 -15
- package/dist/{chunk-RBPOAAIZ.js → chunk-XKIEDGQF.js} +22 -18
- package/dist/cli/dev.js +2 -2
- package/dist/cli/index.js +2 -2
- package/dist/{config-6T4EHAP2.js → config-5CONAOL7.js} +7 -7
- package/dist/{events-LKEZ3YCW.js → events-BDXQOC7F.js} +6 -6
- package/dist/{folding-JN2WT44N.js → folding-2HW7FIKL.js} +2 -2
- package/dist/{inspect-proxy-Y4MRAVB7.js → inspect-proxy-Y75AXMRX.js} +3 -3
- package/dist/{manager-HM2J5VMW.js → manager-W7N3XQ4Q.js} +3 -3
- package/dist/orchestrator-KCHEENHK.js +43 -0
- package/dist/package.json +19 -3
- package/dist/{paths-ZRI56O63.js → paths-X46PPOI2.js} +2 -2
- package/dist/{processor-23O4HPSS.js → processor-6TS37IYH.js} +15 -11
- package/dist/{project-creator-LASKNQPA.js → project-creator-VD7MLOWE.js} +8 -5
- package/dist/{projects-HEUOWNSR.js → projects-XLMSDFTQ.js} +4 -4
- package/dist/{protocol-5AWNGFLH.js → protocol-4CTV7OZC.js} +3 -3
- package/dist/{protocol-DRBnujwe.d.ts → protocol-4xbfAlGO.d.ts} +3 -0
- package/dist/{provider-AKN355YH.js → provider-ESEBV3LL.js} +15 -11
- package/dist/{pwa-GHQCMCIU.js → pwa-76XP2DY2.js} +2 -2
- package/dist/{runtime-config-ZCK74XKM.js → runtime-config-CBJJJGBD.js} +2 -2
- package/dist/{serve-W6CHNSRO.js → serve-OLDABBV3.js} +29 -27
- package/dist/server/index.d.ts +6 -1
- package/dist/server/index.js +22 -22
- package/dist/server/public/__inspect__.js +2 -1
- package/dist/{service-74Z7JK2J.js → service-D6LC3CAM.js} +3 -2
- package/dist/{settings-NI4ITGV6.js → settings-TQNQB56H.js} +4 -4
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +2 -2
- package/dist/{store-2IF3ZSLD.js → store-OQ45KONN.js} +2 -2
- package/dist/{tools-RUAY6EVI.js → tools-BHYHS3RY.js} +18 -18
- package/dist/{vision-fallback-AXH3BGJC.js → vision-fallback-ED27LH6C.js} +3 -3
- package/dist/web/assets/{index-9GgVgB7B.js → index-DAuZ02-Q.js} +57 -57
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +19 -3
- package/dist/auto-compaction-OW4P2QWQ.js +0 -27
- package/dist/orchestrator-QP4O7MUM.js +0 -43
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
deleteSetting,
|
|
4
4
|
getSetting,
|
|
5
5
|
setSetting
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OXI26S7U.js";
|
|
7
7
|
import {
|
|
8
8
|
getProject
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-CMQCO27Y.js";
|
|
10
10
|
import {
|
|
11
11
|
startInspectProxy
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-XKIEDGQF.js";
|
|
13
13
|
import {
|
|
14
14
|
createProcess,
|
|
15
15
|
getPlatformShell,
|
|
@@ -18,22 +18,22 @@ import {
|
|
|
18
18
|
getSessionProcesses,
|
|
19
19
|
startProcessCommand,
|
|
20
20
|
stopProcess
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-PBGOZMVY.js";
|
|
22
22
|
import {
|
|
23
23
|
getMaxPerSession,
|
|
24
24
|
getSessionProcessCount
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-VRGRAQDG.js";
|
|
26
26
|
import {
|
|
27
27
|
buildModelParams,
|
|
28
28
|
getBackendCapabilities,
|
|
29
29
|
getModelProfile,
|
|
30
30
|
streamWithSegments
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-CUDAT6SS.js";
|
|
32
32
|
import {
|
|
33
33
|
getContextMessages,
|
|
34
34
|
getCurrentContextWindowId,
|
|
35
35
|
getEventStore
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-5ZD3GZTK.js";
|
|
37
37
|
import {
|
|
38
38
|
createChatDoneMessage,
|
|
39
39
|
createChatMessageMessage,
|
|
@@ -42,20 +42,20 @@ import {
|
|
|
42
42
|
createChatToolOutputMessage,
|
|
43
43
|
createChatVisionFallbackMessage,
|
|
44
44
|
createQueueStateMessage
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-STYHKCG7.js";
|
|
46
46
|
import {
|
|
47
47
|
AskUserInterrupt,
|
|
48
48
|
askUserTool
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-BJYPTN5S.js";
|
|
50
50
|
import {
|
|
51
51
|
getGlobalConfigDir
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-CQGTEGKL.js";
|
|
53
53
|
import {
|
|
54
54
|
getRuntimeConfig
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-B5AP3RSV.js";
|
|
56
56
|
import {
|
|
57
57
|
logger
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-K44MW7JJ.js";
|
|
59
59
|
|
|
60
60
|
// src/server/context/instructions.ts
|
|
61
61
|
import { readFile, access } from "fs/promises";
|
|
@@ -147,6 +147,13 @@ async function fileExists(path) {
|
|
|
147
147
|
return false;
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
|
+
function toInjectedFiles(files) {
|
|
151
|
+
return files.map((file) => ({
|
|
152
|
+
path: file.path,
|
|
153
|
+
content: file.content ?? "",
|
|
154
|
+
source: file.source
|
|
155
|
+
}));
|
|
156
|
+
}
|
|
150
157
|
|
|
151
158
|
// src/server/context/compactor.ts
|
|
152
159
|
function shouldCompact(currentTokens, maxTokens, threshold) {
|
|
@@ -403,6 +410,7 @@ function minimalMessageToRequestContextMessage(message, source = "history") {
|
|
|
403
410
|
role: message.role,
|
|
404
411
|
content: message.content,
|
|
405
412
|
source,
|
|
413
|
+
...message.thinkingContent ? { thinkingContent: message.thinkingContent } : {},
|
|
406
414
|
...spreadMessageProps(message)
|
|
407
415
|
};
|
|
408
416
|
}
|
|
@@ -410,6 +418,7 @@ function messageToMinimal(message) {
|
|
|
410
418
|
return {
|
|
411
419
|
role: message.role,
|
|
412
420
|
content: message.content,
|
|
421
|
+
...message.thinkingContent ? { thinkingContent: message.thinkingContent } : {},
|
|
413
422
|
...spreadMessageProps(message)
|
|
414
423
|
};
|
|
415
424
|
}
|
|
@@ -475,12 +484,7 @@ function buildAssemblyInput(systemPrompt, baseInput) {
|
|
|
475
484
|
function assembleAgentRequest(input) {
|
|
476
485
|
const { agentDef, subAgentDefs, ...baseInput } = input;
|
|
477
486
|
if (agentDef.metadata.subagent) {
|
|
478
|
-
const systemPrompt2 = buildSubAgentSystemPrompt(
|
|
479
|
-
baseInput.workdir,
|
|
480
|
-
agentDef,
|
|
481
|
-
baseInput.skills,
|
|
482
|
-
baseInput.modelName
|
|
483
|
-
);
|
|
487
|
+
const systemPrompt2 = buildSubAgentSystemPrompt(baseInput.workdir, agentDef, baseInput.skills, baseInput.modelName);
|
|
484
488
|
return buildAssemblyInput(systemPrompt2, baseInput);
|
|
485
489
|
}
|
|
486
490
|
const systemPrompt = buildTopLevelSystemPrompt(
|
|
@@ -495,7 +499,16 @@ function assembleAgentRequest(input) {
|
|
|
495
499
|
|
|
496
500
|
// src/server/chat/stream-utils.ts
|
|
497
501
|
function buildStreamRequestObject(params) {
|
|
498
|
-
const {
|
|
502
|
+
const {
|
|
503
|
+
messages,
|
|
504
|
+
tools,
|
|
505
|
+
toolChoice,
|
|
506
|
+
disableThinking,
|
|
507
|
+
signal,
|
|
508
|
+
modelSettings,
|
|
509
|
+
onVisionFallbackStart,
|
|
510
|
+
onVisionFallbackDone
|
|
511
|
+
} = params;
|
|
499
512
|
const streamRequest = {
|
|
500
513
|
messages,
|
|
501
514
|
...tools && { tools },
|
|
@@ -515,7 +528,17 @@ function buildStreamRequest(client, options) {
|
|
|
515
528
|
// src/server/chat/stats.ts
|
|
516
529
|
var roundTo1 = (n) => Math.round(n * 10) / 10;
|
|
517
530
|
function computeAggregatedStats(input) {
|
|
518
|
-
const {
|
|
531
|
+
const {
|
|
532
|
+
identity,
|
|
533
|
+
mode,
|
|
534
|
+
totalPrefillTokens,
|
|
535
|
+
totalGenTokens,
|
|
536
|
+
totalPrefillTime,
|
|
537
|
+
totalGenTime,
|
|
538
|
+
totalToolTime,
|
|
539
|
+
totalTime,
|
|
540
|
+
llmCalls
|
|
541
|
+
} = input;
|
|
519
542
|
return {
|
|
520
543
|
...identity,
|
|
521
544
|
mode,
|
|
@@ -543,7 +566,18 @@ function createEmptyStreamResult(aborted, xmlFormatError, modelParams) {
|
|
|
543
566
|
};
|
|
544
567
|
}
|
|
545
568
|
async function* streamLLMPure(options) {
|
|
546
|
-
const {
|
|
569
|
+
const {
|
|
570
|
+
messageId,
|
|
571
|
+
systemPrompt,
|
|
572
|
+
llmClient,
|
|
573
|
+
messages,
|
|
574
|
+
tools,
|
|
575
|
+
toolChoice,
|
|
576
|
+
signal,
|
|
577
|
+
disableThinking,
|
|
578
|
+
onVisionFallbackStart,
|
|
579
|
+
onVisionFallbackDone
|
|
580
|
+
} = options;
|
|
547
581
|
const llmMessages = [{ role: "system", content: systemPrompt }, ...messages];
|
|
548
582
|
const profile = getModelProfile(llmClient.getModel());
|
|
549
583
|
const backend = getBackendCapabilities(llmClient.getBackend());
|
|
@@ -584,6 +618,7 @@ async function* streamLLMPure(options) {
|
|
|
584
618
|
const toolNames = /* @__PURE__ */ new Map();
|
|
585
619
|
const toolIds = /* @__PURE__ */ new Map();
|
|
586
620
|
const returnValueArgs = /* @__PURE__ */ new Map();
|
|
621
|
+
const toolArgs = /* @__PURE__ */ new Map();
|
|
587
622
|
let result = null;
|
|
588
623
|
let aborted = false;
|
|
589
624
|
let xmlFormatError = false;
|
|
@@ -619,13 +654,32 @@ async function* streamLLMPure(options) {
|
|
|
619
654
|
if (value.id) {
|
|
620
655
|
toolIds.set(value.index, value.id);
|
|
621
656
|
}
|
|
657
|
+
if (value.arguments) {
|
|
658
|
+
const existingArgs = toolArgs.get(value.index) ?? "";
|
|
659
|
+
toolArgs.set(value.index, existingArgs + value.arguments);
|
|
660
|
+
}
|
|
622
661
|
const fullName = toolNames.get(value.index);
|
|
623
662
|
if (!seenToolIndices.has(value.index) && fullName) {
|
|
624
663
|
seenToolIndices.add(value.index);
|
|
664
|
+
const accumulatedArgs = toolArgs.get(value.index);
|
|
625
665
|
yield {
|
|
626
666
|
type: "tool.preparing",
|
|
627
|
-
data: {
|
|
667
|
+
data: {
|
|
668
|
+
messageId,
|
|
669
|
+
index: value.index,
|
|
670
|
+
name: fullName,
|
|
671
|
+
...accumulatedArgs ? { arguments: accumulatedArgs } : {}
|
|
672
|
+
}
|
|
628
673
|
};
|
|
674
|
+
} else if (seenToolIndices.has(value.index) && value.arguments) {
|
|
675
|
+
const accumulatedArgs = toolArgs.get(value.index);
|
|
676
|
+
const name = toolNames.get(value.index);
|
|
677
|
+
if (accumulatedArgs && name) {
|
|
678
|
+
yield {
|
|
679
|
+
type: "tool.preparing",
|
|
680
|
+
data: { messageId, index: value.index, name, arguments: accumulatedArgs }
|
|
681
|
+
};
|
|
682
|
+
}
|
|
629
683
|
}
|
|
630
684
|
if (fullName === "return_value" && value.arguments) {
|
|
631
685
|
const toolCallId = toolIds.get(value.index);
|
|
@@ -884,10 +938,12 @@ async function consumeStreamWithToolLoop(options) {
|
|
|
884
938
|
turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens, result.modelParams);
|
|
885
939
|
if (result.toolCalls.length > 0) {
|
|
886
940
|
const stats = turnMetrics.buildStats(statsIdentity, "compaction");
|
|
887
|
-
onEvent(
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
941
|
+
onEvent(
|
|
942
|
+
createMessageDoneEvent(messageId, {
|
|
943
|
+
segments: result.segments,
|
|
944
|
+
stats
|
|
945
|
+
})
|
|
946
|
+
);
|
|
891
947
|
const toolContext = {
|
|
892
948
|
sessionId,
|
|
893
949
|
workdir,
|
|
@@ -910,6 +966,7 @@ async function consumeStreamWithToolLoop(options) {
|
|
|
910
966
|
currentMessages.push({
|
|
911
967
|
role: "assistant",
|
|
912
968
|
content: result.content,
|
|
969
|
+
...result.thinkingContent ? { thinkingContent: result.thinkingContent } : {},
|
|
913
970
|
toolCalls: result.toolCalls
|
|
914
971
|
});
|
|
915
972
|
continue;
|
|
@@ -1036,10 +1093,7 @@ async function loadUserAgents(configDir) {
|
|
|
1036
1093
|
return loadAgentsFromDir(getAgentsDir(configDir));
|
|
1037
1094
|
}
|
|
1038
1095
|
async function loadAllAgents(configDir) {
|
|
1039
|
-
const [defaultAgents, userAgents] = await Promise.all([
|
|
1040
|
-
loadDefaultAgents(),
|
|
1041
|
-
loadUserAgents(configDir)
|
|
1042
|
-
]);
|
|
1096
|
+
const [defaultAgents, userAgents] = await Promise.all([loadDefaultAgents(), loadUserAgents(configDir)]);
|
|
1043
1097
|
const agentMap = /* @__PURE__ */ new Map();
|
|
1044
1098
|
for (const agent of defaultAgents) {
|
|
1045
1099
|
agentMap.set(agent.metadata.id, agent);
|
|
@@ -1077,10 +1131,7 @@ async function isDefaultAgent(agentId) {
|
|
|
1077
1131
|
}
|
|
1078
1132
|
function getAgentFilePaths(agentsDir, agentId) {
|
|
1079
1133
|
const hyphenated = agentId.replace(/_/g, "-");
|
|
1080
|
-
return [
|
|
1081
|
-
join2(agentsDir, `${agentId}${AGENT_EXTENSION}`),
|
|
1082
|
-
join2(agentsDir, `${hyphenated}${AGENT_EXTENSION}`)
|
|
1083
|
-
];
|
|
1134
|
+
return [join2(agentsDir, `${agentId}${AGENT_EXTENSION}`), join2(agentsDir, `${hyphenated}${AGENT_EXTENSION}`)];
|
|
1084
1135
|
}
|
|
1085
1136
|
function findAgentById(agentId, agents) {
|
|
1086
1137
|
return agents.find((a) => a.metadata.id === agentId);
|
|
@@ -1171,11 +1222,7 @@ var SAFE_PATHS = /* @__PURE__ */ new Set([
|
|
|
1171
1222
|
"/dev/fd/1",
|
|
1172
1223
|
"/dev/fd/2"
|
|
1173
1224
|
]);
|
|
1174
|
-
var ALLOWED_ROOTS = [
|
|
1175
|
-
"/tmp",
|
|
1176
|
-
"/var/tmp",
|
|
1177
|
-
tmpdir()
|
|
1178
|
-
];
|
|
1225
|
+
var ALLOWED_ROOTS = ["/tmp", "/var/tmp", tmpdir()];
|
|
1179
1226
|
var SENSITIVE_FILE_PATTERNS = [
|
|
1180
1227
|
// Dotenv files (but not .envrc, .env-example, .env.example)
|
|
1181
1228
|
/^\.env$/,
|
|
@@ -1261,7 +1308,7 @@ function extractAbsolutePathsFromCommand(command) {
|
|
|
1261
1308
|
const paths = [];
|
|
1262
1309
|
const home = homedir();
|
|
1263
1310
|
let sanitized = command.replace(/https?:\/\/[^\s'"]+/g, " __URL__ ").replace(/ftp:\/\/[^\s'"]+/g, " __URL__ ");
|
|
1264
|
-
sanitized = sanitized.replace(/s\/[
|
|
1311
|
+
sanitized = sanitized.replace(/s\/[^/]*\/[^/]*\/[gip]*/g, " __SED__ ");
|
|
1265
1312
|
sanitized = sanitized.replace(/s\|[^|]*\|[^|]*\|[gip]*/g, " __SED__ ");
|
|
1266
1313
|
sanitized = sanitized.replace(/s:[^:]*:[^:]*:[gip]*/g, " __SED__ ");
|
|
1267
1314
|
const fileUrlMatches = command.matchAll(/file:\/\/([^\s'"]+)/g);
|
|
@@ -1371,7 +1418,7 @@ async function checkPathsAccess(paths, workdir, sessionId) {
|
|
|
1371
1418
|
}
|
|
1372
1419
|
var DANGEROUS_PATTERNS = [
|
|
1373
1420
|
/sudo\s/,
|
|
1374
|
-
/rm\s+(-rf?|--recursive)\s+[
|
|
1421
|
+
/rm\s+(-rf?|--recursive)\s+[~]/,
|
|
1375
1422
|
/chmod\s+777/,
|
|
1376
1423
|
/>\s*\/dev\/sd/,
|
|
1377
1424
|
/mkfs\s/,
|
|
@@ -1421,7 +1468,9 @@ async function requestPathAccess(paths, workdir, sessionId, callId, tool, onEven
|
|
|
1421
1468
|
if (dangerousPatterns.length > 0) {
|
|
1422
1469
|
emitPendingEvent([workdir], "dangerous_command");
|
|
1423
1470
|
const confirmationPromise2 = registerPathConfirmation(callId, [workdir], sessionId);
|
|
1424
|
-
onEvent(
|
|
1471
|
+
onEvent(
|
|
1472
|
+
createChatPathConfirmationMessage(callId, tool, [dangerousPatterns.join(", ")], workdir, "dangerous_command")
|
|
1473
|
+
);
|
|
1425
1474
|
const approved2 = await confirmationPromise2;
|
|
1426
1475
|
if (!approved2) {
|
|
1427
1476
|
throw new PathAccessDeniedError(dangerousPatterns, tool, "dangerous_command");
|
|
@@ -1477,7 +1526,7 @@ function providePathConfirmation(callId, approved, alwaysAllow) {
|
|
|
1477
1526
|
type: "path.confirmation_responded",
|
|
1478
1527
|
data: { callId, approved, alwaysAllow: alwaysAllow ?? false }
|
|
1479
1528
|
});
|
|
1480
|
-
} catch
|
|
1529
|
+
} catch {
|
|
1481
1530
|
}
|
|
1482
1531
|
if (approved) {
|
|
1483
1532
|
if (alwaysAllow) {
|
|
@@ -1602,7 +1651,9 @@ var FileNotReadError = class extends Error {
|
|
|
1602
1651
|
};
|
|
1603
1652
|
var FileChangedExternallyError = class extends Error {
|
|
1604
1653
|
constructor(path) {
|
|
1605
|
-
super(
|
|
1654
|
+
super(
|
|
1655
|
+
`File "${path}" was modified externally and must be read before writing. Use read_file to see current contents.`
|
|
1656
|
+
);
|
|
1606
1657
|
this.name = "FileChangedExternallyError";
|
|
1607
1658
|
}
|
|
1608
1659
|
};
|
|
@@ -1655,7 +1706,11 @@ var IMAGE_MIME_TYPES = {
|
|
|
1655
1706
|
".svg": "image/svg+xml"
|
|
1656
1707
|
};
|
|
1657
1708
|
var IMAGE_SIGNATURES = [
|
|
1658
|
-
{
|
|
1709
|
+
{
|
|
1710
|
+
mimeType: "image/png",
|
|
1711
|
+
signature: Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
|
|
1712
|
+
extension: ".png"
|
|
1713
|
+
},
|
|
1659
1714
|
{ mimeType: "image/jpeg", signature: Buffer.from([255, 216, 255]), extension: ".jpg" },
|
|
1660
1715
|
{ mimeType: "image/gif", signature: Buffer.from([71, 73, 70, 56]), extension: ".gif" },
|
|
1661
1716
|
{ mimeType: "image/webp", signature: Buffer.from([]), extension: ".webp" },
|
|
@@ -1723,10 +1778,7 @@ var readFileTool = createTool(
|
|
|
1723
1778
|
},
|
|
1724
1779
|
async (args, context, helpers) => {
|
|
1725
1780
|
const offset = args.offset ?? 1;
|
|
1726
|
-
const limit = Math.min(
|
|
1727
|
-
args.limit ?? OUTPUT_LIMITS.read_file.maxLines,
|
|
1728
|
-
OUTPUT_LIMITS.read_file.maxLines
|
|
1729
|
-
);
|
|
1781
|
+
const limit = Math.min(args.limit ?? OUTPUT_LIMITS.read_file.maxLines, OUTPUT_LIMITS.read_file.maxLines);
|
|
1730
1782
|
const fullPath = helpers.resolvePath(args.path);
|
|
1731
1783
|
await helpers.checkPathAccess([fullPath]);
|
|
1732
1784
|
try {
|
|
@@ -1735,7 +1787,9 @@ var readFileTool = createTool(
|
|
|
1735
1787
|
return helpers.error(`Path is a directory, not a file: ${args.path}`);
|
|
1736
1788
|
}
|
|
1737
1789
|
if (stats.size > OUTPUT_LIMITS.read_file.maxImageBytes) {
|
|
1738
|
-
return helpers.error(
|
|
1790
|
+
return helpers.error(
|
|
1791
|
+
`File size (${stats.size} bytes) exceeds image size limit (2MB). Use shell command to process large files.`
|
|
1792
|
+
);
|
|
1739
1793
|
}
|
|
1740
1794
|
} catch {
|
|
1741
1795
|
return helpers.error(`File not found: ${args.path}`);
|
|
@@ -1749,19 +1803,15 @@ var readFileTool = createTool(
|
|
|
1749
1803
|
if (contentHash2) {
|
|
1750
1804
|
context.sessionManager.recordFileRead(context.sessionId, fullPath, contentHash2);
|
|
1751
1805
|
}
|
|
1752
|
-
return helpers.success(
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
base64Data,
|
|
1760
|
-
dataUrl,
|
|
1761
|
-
path: fullPath
|
|
1762
|
-
}
|
|
1806
|
+
return helpers.success(`[Image: ${args.path} (${mimeType}, ${rawBuffer.length} bytes)]`, false, {
|
|
1807
|
+
metadata: {
|
|
1808
|
+
mimeType,
|
|
1809
|
+
size: rawBuffer.length,
|
|
1810
|
+
base64Data,
|
|
1811
|
+
dataUrl,
|
|
1812
|
+
path: fullPath
|
|
1763
1813
|
}
|
|
1764
|
-
);
|
|
1814
|
+
});
|
|
1765
1815
|
}
|
|
1766
1816
|
const content = rawBuffer.toString("utf-8");
|
|
1767
1817
|
const lines = content.split("\n");
|
|
@@ -1865,11 +1915,7 @@ var writeFileTool = createTool(
|
|
|
1865
1915
|
if (newHash) {
|
|
1866
1916
|
context.sessionManager.updateFileHash(context.sessionId, fullPath, newHash);
|
|
1867
1917
|
}
|
|
1868
|
-
return helpers.success(
|
|
1869
|
-
output,
|
|
1870
|
-
false,
|
|
1871
|
-
diagnostics.length > 0 ? { diagnostics } : void 0
|
|
1872
|
-
);
|
|
1918
|
+
return helpers.success(output, false, diagnostics.length > 0 ? { diagnostics } : void 0);
|
|
1873
1919
|
}
|
|
1874
1920
|
);
|
|
1875
1921
|
|
|
@@ -2054,7 +2100,12 @@ Make sure whitespace and indentation match exactly.`
|
|
|
2054
2100
|
`Found ${occurrences} matches for old_string. Use replace_all: true to replace all, or provide more context to make the match unique.`
|
|
2055
2101
|
);
|
|
2056
2102
|
}
|
|
2057
|
-
const contextResult = extractEditContext(
|
|
2103
|
+
const contextResult = extractEditContext(
|
|
2104
|
+
normalizedContent,
|
|
2105
|
+
normalizedOldString,
|
|
2106
|
+
normalizeToLF(args.new_string),
|
|
2107
|
+
replaceAll
|
|
2108
|
+
);
|
|
2058
2109
|
const editContextRegions = contextResult.regions.map((region) => ({
|
|
2059
2110
|
beforeContext: region.beforeContext.map((line) => ({
|
|
2060
2111
|
lineNumber: line.lineNumber,
|
|
@@ -2086,7 +2137,10 @@ Make sure whitespace and indentation match exactly.`
|
|
|
2086
2137
|
}
|
|
2087
2138
|
replacedContent = normalizedContent.slice(0, index) + normalizedNewString + normalizedContent.slice(index + normalizedOldString.length);
|
|
2088
2139
|
}
|
|
2089
|
-
const newContent = replacedContent.replace(
|
|
2140
|
+
const newContent = replacedContent.replace(
|
|
2141
|
+
/\n/g,
|
|
2142
|
+
fileLineEnding === "crlf" ? "\r\n" : fileLineEnding === "cr" ? "\r" : "\n"
|
|
2143
|
+
);
|
|
2090
2144
|
await writeFile3(fullPath, newContent, "utf-8");
|
|
2091
2145
|
let output = `Successfully replaced ${replaceAll ? occurrences : 1} occurrence(s) in ${args.path}`;
|
|
2092
2146
|
let diagnostics = [];
|
|
@@ -2359,12 +2413,21 @@ var criterionTool = createTool(
|
|
|
2359
2413
|
}
|
|
2360
2414
|
},
|
|
2361
2415
|
async (args, context, helpers) => {
|
|
2362
|
-
const actionError = validateActionWithPermission(
|
|
2416
|
+
const actionError = validateActionWithPermission(
|
|
2417
|
+
args.action,
|
|
2418
|
+
["get", "add", "update", "remove", "complete", "pass", "fail"],
|
|
2419
|
+
"criterion",
|
|
2420
|
+
context.permittedActions
|
|
2421
|
+
);
|
|
2363
2422
|
if (actionError) return actionError;
|
|
2364
2423
|
const session = requireSession(context.sessionManager, context.sessionId);
|
|
2365
2424
|
if (args.action === "get") {
|
|
2366
2425
|
return helpers.success(
|
|
2367
|
-
session.criteria.length === 0 ? "No criteria defined yet." : JSON.stringify(
|
|
2426
|
+
session.criteria.length === 0 ? "No criteria defined yet." : JSON.stringify(
|
|
2427
|
+
session.criteria.map((c) => ({ id: c.id, description: c.description })),
|
|
2428
|
+
null,
|
|
2429
|
+
2
|
|
2430
|
+
)
|
|
2368
2431
|
);
|
|
2369
2432
|
}
|
|
2370
2433
|
if (args.action === "add") {
|
|
@@ -2377,14 +2440,18 @@ var criterionTool = createTool(
|
|
|
2377
2440
|
};
|
|
2378
2441
|
const result = context.sessionManager.addCriterion(context.sessionId, criterion);
|
|
2379
2442
|
if ("error" in result) return helpers.error(result.error);
|
|
2380
|
-
return helpers.success(
|
|
2381
|
-
${
|
|
2443
|
+
return helpers.success(
|
|
2444
|
+
`Added criterion "${result.actualId}". Current criteria:
|
|
2445
|
+
${formatCriteriaList(result.criteria)}`
|
|
2446
|
+
);
|
|
2382
2447
|
}
|
|
2383
2448
|
if (args.action === "update") {
|
|
2384
2449
|
if (!args.id) return helpers.error("Missing required field: id");
|
|
2385
2450
|
if (!args.description) return helpers.error("Missing required field: description");
|
|
2386
2451
|
if (!session.criteria.find((c) => c.id === args.id)) return helpers.error(`Criterion "${args.id}" not found`);
|
|
2387
|
-
const criteria = context.sessionManager.updateCriterionFull(context.sessionId, args.id, {
|
|
2452
|
+
const criteria = context.sessionManager.updateCriterionFull(context.sessionId, args.id, {
|
|
2453
|
+
description: args.description
|
|
2454
|
+
});
|
|
2388
2455
|
return helpers.success(`Updated criterion "${args.id}". Current criteria:
|
|
2389
2456
|
${formatCriteriaList(criteria)}`);
|
|
2390
2457
|
}
|
|
@@ -2400,13 +2467,18 @@ ${formatCriteriaList(criteria)}`
|
|
|
2400
2467
|
if (args.action === "complete") {
|
|
2401
2468
|
if (!args.id) return helpers.error("Missing required field: id");
|
|
2402
2469
|
const criterion = session.criteria.find((c) => c.id === args.id);
|
|
2403
|
-
if (!criterion)
|
|
2470
|
+
if (!criterion)
|
|
2471
|
+
return helpers.error(
|
|
2472
|
+
`Criterion "${args.id}" not found. Available: ${session.criteria.map((c) => c.id).join(", ")}`
|
|
2473
|
+
);
|
|
2404
2474
|
context.sessionManager.updateCriterionStatus(context.sessionId, args.id, {
|
|
2405
2475
|
type: "completed",
|
|
2406
2476
|
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2407
2477
|
...args.reason ? { reason: args.reason } : {}
|
|
2408
2478
|
});
|
|
2409
|
-
return helpers.success(
|
|
2479
|
+
return helpers.success(
|
|
2480
|
+
`Criterion "${args.id}" marked as completed.${args.reason ? ` Reason: ${args.reason}` : ""}`
|
|
2481
|
+
);
|
|
2410
2482
|
}
|
|
2411
2483
|
if (args.action === "pass") {
|
|
2412
2484
|
if (!args.id) return helpers.error("Missing required field: id");
|
|
@@ -2485,13 +2557,16 @@ var todoTool = createTool(
|
|
|
2485
2557
|
}
|
|
2486
2558
|
},
|
|
2487
2559
|
async (args, context, helpers) => {
|
|
2488
|
-
const actionError = validateActionWithPermission(
|
|
2560
|
+
const actionError = validateActionWithPermission(
|
|
2561
|
+
args.action,
|
|
2562
|
+
["list", "write", "add", "update", "remove"],
|
|
2563
|
+
"todo",
|
|
2564
|
+
context.permittedActions
|
|
2565
|
+
);
|
|
2489
2566
|
if (actionError) return actionError;
|
|
2490
2567
|
if (args.action === "list") {
|
|
2491
2568
|
const todosList = sessionTodos.get(context.sessionId) ?? [];
|
|
2492
|
-
return helpers.success(
|
|
2493
|
-
todosList.length === 0 ? "No tasks defined yet." : JSON.stringify(todosList, null, 2)
|
|
2494
|
-
);
|
|
2569
|
+
return helpers.success(todosList.length === 0 ? "No tasks defined yet." : JSON.stringify(todosList, null, 2));
|
|
2495
2570
|
}
|
|
2496
2571
|
if (args.action === "write") {
|
|
2497
2572
|
if (!args.todos) return helpers.error("Missing required field: todos");
|
|
@@ -2504,7 +2579,9 @@ var todoTool = createTool(
|
|
|
2504
2579
|
}
|
|
2505
2580
|
sessionTodos.set(context.sessionId, args.todos);
|
|
2506
2581
|
if (onTodoUpdate) onTodoUpdate(context.sessionId, args.todos);
|
|
2507
|
-
return helpers.success(
|
|
2582
|
+
return helpers.success(
|
|
2583
|
+
`${args.todos.filter((t) => t.status === "completed").length} completed, ${args.todos.filter((t) => t.status === "in_progress").length} in progress, ${args.todos.filter((t) => t.status === "pending").length} pending`
|
|
2584
|
+
);
|
|
2508
2585
|
}
|
|
2509
2586
|
if (args.action === "add") {
|
|
2510
2587
|
if (!args.content) return helpers.error("Missing required field: content");
|
|
@@ -2650,10 +2727,7 @@ async function loadUserSkills(configDir) {
|
|
|
2650
2727
|
});
|
|
2651
2728
|
}
|
|
2652
2729
|
async function loadAllSkills(configDir) {
|
|
2653
|
-
const [defaultSkills, userSkills] = await Promise.all([
|
|
2654
|
-
loadDefaultSkills(),
|
|
2655
|
-
loadUserSkills(configDir)
|
|
2656
|
-
]);
|
|
2730
|
+
const [defaultSkills, userSkills] = await Promise.all([loadDefaultSkills(), loadUserSkills(configDir)]);
|
|
2657
2731
|
const skillMap = /* @__PURE__ */ new Map();
|
|
2658
2732
|
for (const skill of defaultSkills) {
|
|
2659
2733
|
skillMap.set(skill.metadata.id, skill);
|
|
@@ -2726,11 +2800,14 @@ async function deleteSkill(configDir, skillId) {
|
|
|
2726
2800
|
import stripAnsi from "strip-ansi";
|
|
2727
2801
|
function emitPartialDoneEvents(sessionId, assistantMsgId, statsIdentity, mode, turnMetrics, promptContext, eventStore) {
|
|
2728
2802
|
const stats = turnMetrics.buildStats(statsIdentity, mode);
|
|
2729
|
-
eventStore.append(
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2803
|
+
eventStore.append(
|
|
2804
|
+
sessionId,
|
|
2805
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
2806
|
+
stats,
|
|
2807
|
+
partial: true,
|
|
2808
|
+
promptContext
|
|
2809
|
+
})
|
|
2810
|
+
);
|
|
2734
2811
|
eventStore.append(sessionId, createChatDoneEvent(assistantMsgId, "stopped", stats));
|
|
2735
2812
|
}
|
|
2736
2813
|
function getCurrentWindowMessageOptions(sessionId) {
|
|
@@ -2798,7 +2875,7 @@ async function executeToolBatch(assistantMsgId, toolCalls, ctx) {
|
|
|
2798
2875
|
type: "chat.ask_user",
|
|
2799
2876
|
data: { callId: error.callId, question: error.question }
|
|
2800
2877
|
});
|
|
2801
|
-
const { awaitAnswer } = await import("./ask-
|
|
2878
|
+
const { awaitAnswer } = await import("./ask-5SSOA6SZ.js");
|
|
2802
2879
|
const answerPromise = awaitAnswer(error.callId);
|
|
2803
2880
|
if (!answerPromise) {
|
|
2804
2881
|
throw new Error(`No pending question found for callId: ${error.callId}`);
|
|
@@ -2823,9 +2900,11 @@ async function executeToolBatch(assistantMsgId, toolCalls, ctx) {
|
|
|
2823
2900
|
}
|
|
2824
2901
|
toolMessages.push({
|
|
2825
2902
|
role: "tool",
|
|
2826
|
-
content: stripAnsi(
|
|
2903
|
+
content: stripAnsi(
|
|
2904
|
+
toolResult.success ? toolResult.output ?? "Success" : toolResult.output ? `${toolResult.output}
|
|
2827
2905
|
|
|
2828
|
-
Error: ${toolResult.error}` : `Error: ${toolResult.error}`
|
|
2906
|
+
Error: ${toolResult.error}` : `Error: ${toolResult.error}`
|
|
2907
|
+
),
|
|
2829
2908
|
source: "history",
|
|
2830
2909
|
toolCallId: toolCall.id
|
|
2831
2910
|
});
|
|
@@ -2845,7 +2924,14 @@ function toRequestContextMessages(messages) {
|
|
|
2845
2924
|
role: message.role,
|
|
2846
2925
|
content: message.content,
|
|
2847
2926
|
source: "history",
|
|
2848
|
-
...message.
|
|
2927
|
+
...message.thinkingContent ? { thinkingContent: message.thinkingContent } : {},
|
|
2928
|
+
...message.toolCalls ? {
|
|
2929
|
+
toolCalls: message.toolCalls.map((toolCall) => ({
|
|
2930
|
+
id: toolCall.id,
|
|
2931
|
+
name: toolCall.name,
|
|
2932
|
+
arguments: toolCall.arguments
|
|
2933
|
+
}))
|
|
2934
|
+
} : {},
|
|
2849
2935
|
...message.toolCallId ? { toolCallId: message.toolCallId } : {},
|
|
2850
2936
|
...message.attachments ? { attachments: message.attachments } : {}
|
|
2851
2937
|
}));
|
|
@@ -2881,11 +2967,14 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
2881
2967
|
const requestMessages = toRequestContextMessages(getContextMessages(sessionId));
|
|
2882
2968
|
if (formatRetryCount > 0) {
|
|
2883
2969
|
const correctionMsgId = crypto.randomUUID();
|
|
2884
|
-
eventStore.append(
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2970
|
+
eventStore.append(
|
|
2971
|
+
sessionId,
|
|
2972
|
+
createMessageStartEvent(correctionMsgId, "user", FORMAT_CORRECTION_PROMPT2, {
|
|
2973
|
+
...currentWindowMessageOptions ?? {},
|
|
2974
|
+
isSystemGenerated: true,
|
|
2975
|
+
messageKind: "correction"
|
|
2976
|
+
})
|
|
2977
|
+
);
|
|
2889
2978
|
eventStore.append(sessionId, createFormatRetryEvent(formatRetryCount, MAX_FORMAT_RETRIES));
|
|
2890
2979
|
requestMessages.push({ role: "user", content: FORMAT_CORRECTION_PROMPT2, source: "runtime" });
|
|
2891
2980
|
}
|
|
@@ -2902,7 +2991,10 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
2902
2991
|
...skills.length > 0 ? { skills } : {}
|
|
2903
2992
|
});
|
|
2904
2993
|
const assistantMsgId = crypto.randomUUID();
|
|
2905
|
-
eventStore.append(
|
|
2994
|
+
eventStore.append(
|
|
2995
|
+
sessionId,
|
|
2996
|
+
createMessageStartEvent(assistantMsgId, "assistant", void 0, currentWindowMessageOptions)
|
|
2997
|
+
);
|
|
2906
2998
|
const doOnMessage = (msg) => {
|
|
2907
2999
|
onMessage?.(msg);
|
|
2908
3000
|
};
|
|
@@ -2933,7 +3025,9 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
2933
3025
|
type: "vision_fallback.done",
|
|
2934
3026
|
data: { messageId: assistantMsgId, attachmentId, description }
|
|
2935
3027
|
});
|
|
2936
|
-
doOnMessage(
|
|
3028
|
+
doOnMessage(
|
|
3029
|
+
createChatVisionFallbackMessage({ type: "done", messageId: assistantMsgId, attachmentId, description })
|
|
3030
|
+
);
|
|
2937
3031
|
};
|
|
2938
3032
|
const modelSettings = sessionManager.getCurrentModelSettings();
|
|
2939
3033
|
const streamGen = streamLLMPure({
|
|
@@ -2965,16 +3059,27 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
2965
3059
|
}
|
|
2966
3060
|
}
|
|
2967
3061
|
if (result.aborted) {
|
|
2968
|
-
emitPartialDoneEvents(
|
|
3062
|
+
emitPartialDoneEvents(
|
|
3063
|
+
sessionId,
|
|
3064
|
+
assistantMsgId,
|
|
3065
|
+
statsIdentity,
|
|
3066
|
+
mode,
|
|
3067
|
+
turnMetrics,
|
|
3068
|
+
assembledRequest.promptContext,
|
|
3069
|
+
eventStore
|
|
3070
|
+
);
|
|
2969
3071
|
throw new Error("Aborted");
|
|
2970
3072
|
}
|
|
2971
3073
|
turnMetrics.addLLMCall(result.timing, result.usage.promptTokens, result.usage.completionTokens, result.modelParams);
|
|
2972
3074
|
sessionManager.setCurrentContextSize(sessionId, result.usage.promptTokens);
|
|
2973
3075
|
if (result.toolCalls.length > 0) {
|
|
2974
|
-
eventStore.append(
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
3076
|
+
eventStore.append(
|
|
3077
|
+
sessionId,
|
|
3078
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
3079
|
+
segments: result.segments,
|
|
3080
|
+
promptContext: assembledRequest.promptContext
|
|
3081
|
+
})
|
|
3082
|
+
);
|
|
2978
3083
|
try {
|
|
2979
3084
|
const batchContext = {
|
|
2980
3085
|
toolRegistry,
|
|
@@ -3000,22 +3105,41 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
3000
3105
|
}
|
|
3001
3106
|
} catch (error) {
|
|
3002
3107
|
if (error instanceof Error && error.message === "Aborted") {
|
|
3003
|
-
emitPartialDoneEvents(
|
|
3108
|
+
emitPartialDoneEvents(
|
|
3109
|
+
sessionId,
|
|
3110
|
+
assistantMsgId,
|
|
3111
|
+
statsIdentity,
|
|
3112
|
+
mode,
|
|
3113
|
+
turnMetrics,
|
|
3114
|
+
assembledRequest.promptContext,
|
|
3115
|
+
eventStore
|
|
3116
|
+
);
|
|
3004
3117
|
throw error;
|
|
3005
3118
|
}
|
|
3006
3119
|
throw error;
|
|
3007
3120
|
}
|
|
3008
3121
|
if (signal?.aborted) {
|
|
3009
|
-
emitPartialDoneEvents(
|
|
3122
|
+
emitPartialDoneEvents(
|
|
3123
|
+
sessionId,
|
|
3124
|
+
assistantMsgId,
|
|
3125
|
+
statsIdentity,
|
|
3126
|
+
mode,
|
|
3127
|
+
turnMetrics,
|
|
3128
|
+
assembledRequest.promptContext,
|
|
3129
|
+
eventStore
|
|
3130
|
+
);
|
|
3010
3131
|
throw new Error("Aborted");
|
|
3011
3132
|
}
|
|
3012
3133
|
const asapMessages = sessionManager.drainAsapMessages(sessionId);
|
|
3013
3134
|
for (const asap of asapMessages) {
|
|
3014
3135
|
const asapMsgId = crypto.randomUUID();
|
|
3015
|
-
eventStore.append(
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3136
|
+
eventStore.append(
|
|
3137
|
+
sessionId,
|
|
3138
|
+
createMessageStartEvent(asapMsgId, "user", asap.content, {
|
|
3139
|
+
...getCurrentWindowMessageOptions(sessionId),
|
|
3140
|
+
...asap.attachments ? { attachments: asap.attachments } : {}
|
|
3141
|
+
})
|
|
3142
|
+
);
|
|
3019
3143
|
eventStore.append(sessionId, { type: "message.done", data: { messageId: asapMsgId } });
|
|
3020
3144
|
}
|
|
3021
3145
|
if (asapMessages.length > 0) {
|
|
@@ -3025,11 +3149,14 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
3025
3149
|
continue;
|
|
3026
3150
|
}
|
|
3027
3151
|
const stats = turnMetrics.buildStats(statsIdentity, mode);
|
|
3028
|
-
eventStore.append(
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3152
|
+
eventStore.append(
|
|
3153
|
+
sessionId,
|
|
3154
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
3155
|
+
segments: result.segments,
|
|
3156
|
+
stats,
|
|
3157
|
+
promptContext: assembledRequest.promptContext
|
|
3158
|
+
})
|
|
3159
|
+
);
|
|
3033
3160
|
eventStore.append(sessionId, createChatDoneEvent(assistantMsgId, "complete", stats));
|
|
3034
3161
|
const currentWindowMessages = sessionManager.getCurrentWindowMessages(sessionId);
|
|
3035
3162
|
const lastUserMessage = [...currentWindowMessages].reverse().find((m) => m.role === "user");
|
|
@@ -3045,15 +3172,36 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
3045
3172
|
}
|
|
3046
3173
|
|
|
3047
3174
|
// src/server/context/nudge-helpers.ts
|
|
3175
|
+
function buildPromptContextForNudge(systemPrompt, injectedFiles, userMessage, messages, tools) {
|
|
3176
|
+
return {
|
|
3177
|
+
systemPrompt,
|
|
3178
|
+
injectedFiles,
|
|
3179
|
+
userMessage,
|
|
3180
|
+
messages: messages.map((m) => ({
|
|
3181
|
+
role: m.role,
|
|
3182
|
+
content: m.content,
|
|
3183
|
+
source: m.source
|
|
3184
|
+
})),
|
|
3185
|
+
tools: tools.map((t) => ({
|
|
3186
|
+
name: t.function.name,
|
|
3187
|
+
description: t.function.description,
|
|
3188
|
+
parameters: t.function.parameters
|
|
3189
|
+
})),
|
|
3190
|
+
requestOptions: { toolChoice: "auto", disableThinking: true }
|
|
3191
|
+
};
|
|
3192
|
+
}
|
|
3048
3193
|
function appendNudgeMessage(eventStore, sessionId, content, currentWindowMessageOptions, options) {
|
|
3049
3194
|
const msgId = crypto.randomUUID();
|
|
3050
|
-
eventStore.append(
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3195
|
+
eventStore.append(
|
|
3196
|
+
sessionId,
|
|
3197
|
+
createMessageStartEvent(msgId, "user", content, {
|
|
3198
|
+
...currentWindowMessageOptions ?? {},
|
|
3199
|
+
isSystemGenerated: true,
|
|
3200
|
+
messageKind: "correction",
|
|
3201
|
+
subAgentId: options.subAgentId,
|
|
3202
|
+
subAgentType: options.subAgentType
|
|
3203
|
+
})
|
|
3204
|
+
);
|
|
3057
3205
|
eventStore.append(sessionId, { type: "message.done", data: { messageId: msgId } });
|
|
3058
3206
|
}
|
|
3059
3207
|
|
|
@@ -3104,40 +3252,26 @@ async function executeSubAgent(options) {
|
|
|
3104
3252
|
const subAgentId = crypto.randomUUID();
|
|
3105
3253
|
let session = sessionManager.requireSession(sessionId);
|
|
3106
3254
|
const currentWindowMessageOptions = getCurrentWindowMessageOptions2(sessionId);
|
|
3107
|
-
const contextMessages = [
|
|
3108
|
-
{ role: "user", content: prompt, source: "runtime" }
|
|
3109
|
-
];
|
|
3255
|
+
const contextMessages = [{ role: "user", content: prompt, source: "runtime" }];
|
|
3110
3256
|
logger.debug("Sub-agent starting", { subAgentType, subAgentId, sessionId });
|
|
3111
3257
|
const resetMsgId = crypto.randomUUID();
|
|
3112
|
-
eventStore.append(
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
messageKind: "context-reset",
|
|
3116
|
-
subAgentId,
|
|
3117
|
-
subAgentType
|
|
3118
|
-
}));
|
|
3119
|
-
eventStore.append(sessionId, { type: "message.done", data: { messageId: resetMsgId } });
|
|
3120
|
-
for (const msg of contextMessages) {
|
|
3121
|
-
const msgId = crypto.randomUUID();
|
|
3122
|
-
eventStore.append(sessionId, createMessageStartEvent(msgId, "user", msg.content, {
|
|
3258
|
+
eventStore.append(
|
|
3259
|
+
sessionId,
|
|
3260
|
+
createMessageStartEvent(resetMsgId, "user", `Fresh Context - ${agentDef.metadata.name} Sub-Agent`, {
|
|
3123
3261
|
...currentWindowMessageOptions ?? {},
|
|
3124
3262
|
isSystemGenerated: true,
|
|
3125
|
-
messageKind: "
|
|
3263
|
+
messageKind: "context-reset",
|
|
3126
3264
|
subAgentId,
|
|
3127
|
-
subAgentType
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
id: msgId,
|
|
3138
|
-
role: "user",
|
|
3139
|
-
content: msg.content,
|
|
3140
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3265
|
+
subAgentType
|
|
3266
|
+
})
|
|
3267
|
+
);
|
|
3268
|
+
eventStore.append(sessionId, { type: "message.done", data: { messageId: resetMsgId } });
|
|
3269
|
+
for (const msg of contextMessages) {
|
|
3270
|
+
const msgId = crypto.randomUUID();
|
|
3271
|
+
eventStore.append(
|
|
3272
|
+
sessionId,
|
|
3273
|
+
createMessageStartEvent(msgId, "user", msg.content, {
|
|
3274
|
+
...currentWindowMessageOptions ?? {},
|
|
3141
3275
|
isSystemGenerated: true,
|
|
3142
3276
|
messageKind: "auto-prompt",
|
|
3143
3277
|
subAgentId,
|
|
@@ -3147,15 +3281,31 @@ async function executeSubAgent(options) {
|
|
|
3147
3281
|
name: agentDef.metadata.name,
|
|
3148
3282
|
color: agentDef.metadata.color ?? "#6b7280"
|
|
3149
3283
|
}
|
|
3150
|
-
})
|
|
3284
|
+
})
|
|
3285
|
+
);
|
|
3286
|
+
eventStore.append(sessionId, { type: "message.done", data: { messageId: msgId } });
|
|
3287
|
+
if (onMessage) {
|
|
3288
|
+
onMessage(
|
|
3289
|
+
createChatMessageMessage({
|
|
3290
|
+
id: msgId,
|
|
3291
|
+
role: "user",
|
|
3292
|
+
content: msg.content,
|
|
3293
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3294
|
+
isSystemGenerated: true,
|
|
3295
|
+
messageKind: "auto-prompt",
|
|
3296
|
+
subAgentId,
|
|
3297
|
+
subAgentType,
|
|
3298
|
+
metadata: {
|
|
3299
|
+
type: "subagent",
|
|
3300
|
+
name: agentDef.metadata.name,
|
|
3301
|
+
color: agentDef.metadata.color ?? "#6b7280"
|
|
3302
|
+
}
|
|
3303
|
+
})
|
|
3304
|
+
);
|
|
3151
3305
|
}
|
|
3152
3306
|
}
|
|
3153
3307
|
const { files } = await getAllInstructions(session.workdir, session.projectId);
|
|
3154
|
-
const injectedFiles = files
|
|
3155
|
-
path: file.path,
|
|
3156
|
-
content: file.content ?? "",
|
|
3157
|
-
source: file.source
|
|
3158
|
-
}));
|
|
3308
|
+
const injectedFiles = toInjectedFiles(files);
|
|
3159
3309
|
const configDir = getGlobalConfigDir(getRuntimeConfig().mode ?? "production");
|
|
3160
3310
|
const skills = await getEnabledSkillMetadata(configDir);
|
|
3161
3311
|
const systemPrompt = buildSubAgentSystemPrompt(
|
|
@@ -3166,7 +3316,7 @@ async function executeSubAgent(options) {
|
|
|
3166
3316
|
);
|
|
3167
3317
|
let customMessages = [...contextMessages];
|
|
3168
3318
|
let consecutiveEmptyStops = 0;
|
|
3169
|
-
let finalContent
|
|
3319
|
+
let finalContent;
|
|
3170
3320
|
let returnValueContent = null;
|
|
3171
3321
|
let returnValueResult = void 0;
|
|
3172
3322
|
let returnValueNudged = false;
|
|
@@ -3182,19 +3332,21 @@ async function executeSubAgent(options) {
|
|
|
3182
3332
|
...signal ? { signal } : {}
|
|
3183
3333
|
});
|
|
3184
3334
|
const assistantMsgId = crypto.randomUUID();
|
|
3185
|
-
eventStore.append(
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3335
|
+
eventStore.append(
|
|
3336
|
+
sessionId,
|
|
3337
|
+
createMessageStartEvent(assistantMsgId, "assistant", void 0, {
|
|
3338
|
+
...currentWindowMessageOptions ?? {},
|
|
3339
|
+
subAgentId,
|
|
3340
|
+
subAgentType
|
|
3341
|
+
})
|
|
3342
|
+
);
|
|
3343
|
+
const promptContext = buildPromptContextForNudge(
|
|
3191
3344
|
systemPrompt,
|
|
3192
3345
|
injectedFiles,
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
};
|
|
3346
|
+
prompt,
|
|
3347
|
+
customMessages,
|
|
3348
|
+
toolRegistry.definitions
|
|
3349
|
+
);
|
|
3198
3350
|
const streamGen = streamLLMPure({
|
|
3199
3351
|
messageId: assistantMsgId,
|
|
3200
3352
|
systemPrompt: systemPrompt + RETURN_VALUE_INSTRUCTION,
|
|
@@ -3215,11 +3367,14 @@ async function executeSubAgent(options) {
|
|
|
3215
3367
|
});
|
|
3216
3368
|
if (result.aborted) {
|
|
3217
3369
|
const stats = turnMetrics.buildStats(statsIdentity, "verifier");
|
|
3218
|
-
eventStore.append(
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3370
|
+
eventStore.append(
|
|
3371
|
+
sessionId,
|
|
3372
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
3373
|
+
stats,
|
|
3374
|
+
partial: true,
|
|
3375
|
+
promptContext
|
|
3376
|
+
})
|
|
3377
|
+
);
|
|
3223
3378
|
eventStore.append(sessionId, createChatDoneEvent(assistantMsgId, "stopped", stats));
|
|
3224
3379
|
throw new Error("Aborted");
|
|
3225
3380
|
}
|
|
@@ -3240,48 +3395,69 @@ async function executeSubAgent(options) {
|
|
|
3240
3395
|
if (consecutiveEmptyStops < nudgeConfig.maxConsecutiveNudges) {
|
|
3241
3396
|
consecutiveEmptyStops += 1;
|
|
3242
3397
|
const nudgeContent = nudgeConfig.buildNudgeContent(criteriaAwaiting);
|
|
3243
|
-
eventStore.append(
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3398
|
+
eventStore.append(
|
|
3399
|
+
sessionId,
|
|
3400
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
3401
|
+
segments: result.segments,
|
|
3402
|
+
promptContext
|
|
3403
|
+
})
|
|
3404
|
+
);
|
|
3405
|
+
appendNudgeMessage(eventStore, sessionId, nudgeContent, currentWindowMessageOptions, {
|
|
3406
|
+
subAgentId,
|
|
3407
|
+
subAgentType
|
|
3408
|
+
});
|
|
3248
3409
|
customMessages = [...customMessages, { role: "user", content: nudgeContent, source: "runtime" }];
|
|
3249
3410
|
continue;
|
|
3250
3411
|
}
|
|
3251
3412
|
const stalledMsgId = crypto.randomUUID();
|
|
3252
|
-
eventStore.append(
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3413
|
+
eventStore.append(
|
|
3414
|
+
sessionId,
|
|
3415
|
+
createMessageStartEvent(stalledMsgId, "user", nudgeConfig.buildRestartContent(criteriaAwaiting), {
|
|
3416
|
+
...currentWindowMessageOptions ?? {},
|
|
3417
|
+
isSystemGenerated: true,
|
|
3418
|
+
messageKind: "correction",
|
|
3419
|
+
subAgentId,
|
|
3420
|
+
subAgentType
|
|
3421
|
+
})
|
|
3422
|
+
);
|
|
3259
3423
|
eventStore.append(sessionId, { type: "message.done", data: { messageId: stalledMsgId } });
|
|
3260
3424
|
}
|
|
3261
3425
|
}
|
|
3262
3426
|
if (!returnValueContent && !returnValueNudged) {
|
|
3263
3427
|
returnValueNudged = true;
|
|
3264
|
-
eventStore.append(
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3428
|
+
eventStore.append(
|
|
3429
|
+
sessionId,
|
|
3430
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
3431
|
+
segments: result.segments,
|
|
3432
|
+
promptContext
|
|
3433
|
+
})
|
|
3434
|
+
);
|
|
3435
|
+
appendNudgeMessage(eventStore, sessionId, RETURN_VALUE_NUDGE, currentWindowMessageOptions, {
|
|
3436
|
+
subAgentId,
|
|
3437
|
+
subAgentType
|
|
3438
|
+
});
|
|
3269
3439
|
customMessages = [...customMessages, { role: "user", content: RETURN_VALUE_NUDGE, source: "runtime" }];
|
|
3270
3440
|
continue;
|
|
3271
3441
|
}
|
|
3272
3442
|
const stats = turnMetrics.buildStats(statsIdentity, "verifier");
|
|
3273
|
-
eventStore.append(
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3443
|
+
eventStore.append(
|
|
3444
|
+
sessionId,
|
|
3445
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
3446
|
+
segments: result.segments,
|
|
3447
|
+
stats,
|
|
3448
|
+
promptContext
|
|
3449
|
+
})
|
|
3450
|
+
);
|
|
3278
3451
|
eventStore.append(sessionId, createChatDoneEvent(assistantMsgId, "complete", stats));
|
|
3279
3452
|
break;
|
|
3280
3453
|
}
|
|
3281
|
-
eventStore.append(
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3454
|
+
eventStore.append(
|
|
3455
|
+
sessionId,
|
|
3456
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
3457
|
+
segments: result.segments,
|
|
3458
|
+
promptContext
|
|
3459
|
+
})
|
|
3460
|
+
);
|
|
3285
3461
|
const batchResult = await executeToolBatch(assistantMsgId, result.toolCalls, {
|
|
3286
3462
|
toolRegistry,
|
|
3287
3463
|
sessionManager,
|
|
@@ -3294,13 +3470,15 @@ async function executeSubAgent(options) {
|
|
|
3294
3470
|
if (batchResult.returnValueContent) {
|
|
3295
3471
|
returnValueContent = batchResult.returnValueContent;
|
|
3296
3472
|
returnValueResult = batchResult.returnValueResult;
|
|
3297
|
-
customMessages = [...customMessages, ...batchResult.toolMessages];
|
|
3298
3473
|
const stats = turnMetrics.buildStats(statsIdentity, subAgentType);
|
|
3299
|
-
eventStore.append(
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3474
|
+
eventStore.append(
|
|
3475
|
+
sessionId,
|
|
3476
|
+
createMessageDoneEvent(assistantMsgId, {
|
|
3477
|
+
segments: result.segments,
|
|
3478
|
+
stats,
|
|
3479
|
+
promptContext
|
|
3480
|
+
})
|
|
3481
|
+
);
|
|
3304
3482
|
if (onMessage) {
|
|
3305
3483
|
onMessage(createChatMessageUpdatedMessage(assistantMsgId, { isStreaming: false, stats, promptContext }));
|
|
3306
3484
|
}
|
|
@@ -3323,7 +3501,13 @@ async function executeSubAgent(options) {
|
|
|
3323
3501
|
});
|
|
3324
3502
|
const failed = session.criteria.filter((c) => c.status.type === "failed").map((c) => ({ id: c.id, reason: c.status.reason ?? "unknown" }));
|
|
3325
3503
|
const remaining = nudgeConfig?.getCriteriaAwaiting(session.criteria) ?? [];
|
|
3326
|
-
return buildSubAgentResult(
|
|
3504
|
+
return buildSubAgentResult(
|
|
3505
|
+
returnValueContent ?? void 0,
|
|
3506
|
+
returnValueResult ?? (subAgentType !== "verifier" ? "success" : void 0),
|
|
3507
|
+
subAgentType,
|
|
3508
|
+
failed,
|
|
3509
|
+
remaining
|
|
3510
|
+
);
|
|
3327
3511
|
}
|
|
3328
3512
|
|
|
3329
3513
|
// src/server/tools/sub-agent.ts
|
|
@@ -3391,7 +3575,7 @@ var callSubAgentTool = {
|
|
|
3391
3575
|
};
|
|
3392
3576
|
}
|
|
3393
3577
|
try {
|
|
3394
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
3578
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-BHYHS3RY.js");
|
|
3395
3579
|
const toolRegistry = getToolRegistryForAgent2(agentDef);
|
|
3396
3580
|
const turnMetrics = new TurnMetrics();
|
|
3397
3581
|
const result = await executeSubAgent({
|
|
@@ -3580,14 +3764,11 @@ var webFetchTool = createTool(
|
|
|
3580
3764
|
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
3581
3765
|
return helpers.error("URL must start with http:// or https://");
|
|
3582
3766
|
}
|
|
3583
|
-
const timeoutMs = Math.min(
|
|
3584
|
-
(args.timeout ?? DEFAULT_TIMEOUT_MS / 1e3) * 1e3,
|
|
3585
|
-
MAX_TIMEOUT_MS
|
|
3586
|
-
);
|
|
3767
|
+
const timeoutMs = Math.min((args.timeout ?? DEFAULT_TIMEOUT_MS / 1e3) * 1e3, MAX_TIMEOUT_MS);
|
|
3587
3768
|
const signal = buildSignal(timeoutMs, context.signal);
|
|
3588
3769
|
const headers = {
|
|
3589
3770
|
"User-Agent": USER_AGENT,
|
|
3590
|
-
|
|
3771
|
+
Accept: buildAcceptHeader(format),
|
|
3591
3772
|
"Accept-Language": "en-US,en;q=0.9"
|
|
3592
3773
|
};
|
|
3593
3774
|
const initial = await fetch(url, { signal, headers });
|
|
@@ -3919,16 +4100,20 @@ var devServerTool = createTool(
|
|
|
3919
4100
|
const offset = args.offset ?? 0;
|
|
3920
4101
|
const limit = args.limit ?? 100;
|
|
3921
4102
|
const result = devServerManager.getLogsSlice(workdir, offset, limit);
|
|
3922
|
-
const formattedLogs = result.logs.map(
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
4103
|
+
const formattedLogs = result.logs.map((entry) => `${entry.stream === "stderr" ? "[stderr] " : ""}${entry.content}`).join("");
|
|
4104
|
+
return helpers.success(
|
|
4105
|
+
JSON.stringify(
|
|
4106
|
+
{
|
|
4107
|
+
logs: formattedLogs,
|
|
4108
|
+
total: result.total,
|
|
4109
|
+
offset,
|
|
4110
|
+
limit,
|
|
4111
|
+
hasMore: offset + limit < result.total
|
|
4112
|
+
},
|
|
4113
|
+
null,
|
|
4114
|
+
2
|
|
4115
|
+
)
|
|
4116
|
+
);
|
|
3932
4117
|
}
|
|
3933
4118
|
let status;
|
|
3934
4119
|
switch (args.action) {
|
|
@@ -3958,12 +4143,18 @@ var devServerTool = createTool(
|
|
|
3958
4143
|
'No .openfox/dev-dev.json (dev mode) or .openfox/dev.json (prod) config found. Create one with:\n\n{\n "command": "npm run dev",\n "url": "http://localhost:3000",\n "hotReload": true\n}'
|
|
3959
4144
|
);
|
|
3960
4145
|
}
|
|
3961
|
-
return helpers.success(
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
4146
|
+
return helpers.success(
|
|
4147
|
+
JSON.stringify(
|
|
4148
|
+
{
|
|
4149
|
+
state: status.state,
|
|
4150
|
+
url: status.url,
|
|
4151
|
+
hotReload: status.hotReload,
|
|
4152
|
+
...status.errorMessage ? { error: status.errorMessage } : {}
|
|
4153
|
+
},
|
|
4154
|
+
null,
|
|
4155
|
+
2
|
|
4156
|
+
)
|
|
4157
|
+
);
|
|
3967
4158
|
}
|
|
3968
4159
|
);
|
|
3969
4160
|
|
|
@@ -4064,7 +4255,9 @@ These processes run independently of agent turns and persist across session comp
|
|
|
4064
4255
|
const count = getSessionProcessCount(sessionId);
|
|
4065
4256
|
const maxPerSession = getMaxPerSession();
|
|
4066
4257
|
if (count >= maxPerSession) {
|
|
4067
|
-
return helpers.error(
|
|
4258
|
+
return helpers.error(
|
|
4259
|
+
`Maximum number of background processes (${maxPerSession}) reached. Stop existing processes before starting new ones.`
|
|
4260
|
+
);
|
|
4068
4261
|
}
|
|
4069
4262
|
const name = args.name ?? args.command?.split(" ")[0] ?? "process";
|
|
4070
4263
|
const process2 = createProcess(sessionId, name, args.command, cwd, args.timeout);
|
|
@@ -4075,13 +4268,19 @@ These processes run independently of agent turns and persist across session comp
|
|
|
4075
4268
|
if (!pid) {
|
|
4076
4269
|
return helpers.error(`Failed to start process.`);
|
|
4077
4270
|
}
|
|
4078
|
-
return helpers.success(
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4271
|
+
return helpers.success(
|
|
4272
|
+
JSON.stringify(
|
|
4273
|
+
{
|
|
4274
|
+
processId: process2.id,
|
|
4275
|
+
name: process2.name,
|
|
4276
|
+
pid,
|
|
4277
|
+
status: "running",
|
|
4278
|
+
maxReached: count + 1 >= maxPerSession
|
|
4279
|
+
},
|
|
4280
|
+
null,
|
|
4281
|
+
2
|
|
4282
|
+
)
|
|
4283
|
+
);
|
|
4085
4284
|
}
|
|
4086
4285
|
case "stop": {
|
|
4087
4286
|
const proc = getProcessStatus(args.processId, sessionId);
|
|
@@ -4092,19 +4291,31 @@ These processes run independently of agent turns and persist across session comp
|
|
|
4092
4291
|
return helpers.error(`Process is not running (status: ${proc.status}). Cannot stop.`);
|
|
4093
4292
|
}
|
|
4094
4293
|
await stopProcess(args.processId, sessionId);
|
|
4095
|
-
return helpers.success(
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4294
|
+
return helpers.success(
|
|
4295
|
+
JSON.stringify(
|
|
4296
|
+
{
|
|
4297
|
+
processId: args.processId,
|
|
4298
|
+
status: "removed"
|
|
4299
|
+
},
|
|
4300
|
+
null,
|
|
4301
|
+
2
|
|
4302
|
+
)
|
|
4303
|
+
);
|
|
4099
4304
|
}
|
|
4100
4305
|
case "list": {
|
|
4101
4306
|
const processes = getSessionProcesses(sessionId);
|
|
4102
4307
|
const maxPerSession = getMaxPerSession();
|
|
4103
|
-
return helpers.success(
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4308
|
+
return helpers.success(
|
|
4309
|
+
JSON.stringify(
|
|
4310
|
+
{
|
|
4311
|
+
processes,
|
|
4312
|
+
maxPerSession,
|
|
4313
|
+
currentCount: processes.filter((p) => p.status !== "exited").length
|
|
4314
|
+
},
|
|
4315
|
+
null,
|
|
4316
|
+
2
|
|
4317
|
+
)
|
|
4318
|
+
);
|
|
4108
4319
|
}
|
|
4109
4320
|
case "status": {
|
|
4110
4321
|
const proc = getProcessStatus(args.processId, sessionId);
|
|
@@ -4112,10 +4323,16 @@ These processes run independently of agent turns and persist across session comp
|
|
|
4112
4323
|
return helpers.error(`Process not found: ${args.processId}`);
|
|
4113
4324
|
}
|
|
4114
4325
|
const uptime = proc.startedAt ? Date.now() - proc.startedAt : null;
|
|
4115
|
-
return helpers.success(
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4326
|
+
return helpers.success(
|
|
4327
|
+
JSON.stringify(
|
|
4328
|
+
{
|
|
4329
|
+
process: proc,
|
|
4330
|
+
uptime
|
|
4331
|
+
},
|
|
4332
|
+
null,
|
|
4333
|
+
2
|
|
4334
|
+
)
|
|
4335
|
+
);
|
|
4119
4336
|
}
|
|
4120
4337
|
case "logs": {
|
|
4121
4338
|
const proc = getProcessStatus(args.processId, sessionId);
|
|
@@ -4125,14 +4342,20 @@ These processes run independently of agent turns and persist across session comp
|
|
|
4125
4342
|
const since = args.since ?? 0;
|
|
4126
4343
|
const maxLines = Math.min(args.maxLines ?? 500, 2e3);
|
|
4127
4344
|
const { lines, totalLines, nextOffset, hasMore } = getProcessLogs(args.processId, since, maxLines);
|
|
4128
|
-
return helpers.success(
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4345
|
+
return helpers.success(
|
|
4346
|
+
JSON.stringify(
|
|
4347
|
+
{
|
|
4348
|
+
processId: args.processId,
|
|
4349
|
+
lines,
|
|
4350
|
+
totalLines,
|
|
4351
|
+
nextOffset,
|
|
4352
|
+
hasMore,
|
|
4353
|
+
truncated: hasMore
|
|
4354
|
+
},
|
|
4355
|
+
null,
|
|
4356
|
+
2
|
|
4357
|
+
)
|
|
4358
|
+
);
|
|
4136
4359
|
}
|
|
4137
4360
|
default:
|
|
4138
4361
|
return helpers.error(`Unknown action: ${args.action}`);
|
|
@@ -4384,11 +4607,7 @@ async function performContextCompaction(options) {
|
|
|
4384
4607
|
const eventStore = getEventStore();
|
|
4385
4608
|
const session = sessionManager.requireSession(sessionId);
|
|
4386
4609
|
const { content: instructions, files } = await getAllInstructions(session.workdir, session.projectId);
|
|
4387
|
-
const injectedFiles = files
|
|
4388
|
-
path: file.path,
|
|
4389
|
-
content: file.content ?? "",
|
|
4390
|
-
source: file.source
|
|
4391
|
-
}));
|
|
4610
|
+
const injectedFiles = toInjectedFiles(files);
|
|
4392
4611
|
const requestMessages = toRequestContextMessages2(getContextMessages(sessionId));
|
|
4393
4612
|
const config = getRuntimeConfig();
|
|
4394
4613
|
const allAgents = await loadAllAgentsDefault();
|
|
@@ -4414,20 +4633,23 @@ async function performContextCompaction(options) {
|
|
|
4414
4633
|
const compactionReminder = `<system-reminder>
|
|
4415
4634
|
${COMPACTION_PROMPT}
|
|
4416
4635
|
</system-reminder>`;
|
|
4417
|
-
const llmMessages = [
|
|
4418
|
-
...assembledRequest.messages,
|
|
4419
|
-
{ role: "user", content: compactionReminder }
|
|
4420
|
-
];
|
|
4636
|
+
const llmMessages = [...assembledRequest.messages, { role: "user", content: compactionReminder }];
|
|
4421
4637
|
const compactPromptMsgId = crypto.randomUUID();
|
|
4422
|
-
eventStore.append(
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4638
|
+
eventStore.append(
|
|
4639
|
+
sessionId,
|
|
4640
|
+
createMessageStartEvent(compactPromptMsgId, "user", COMPACTION_PROMPT, {
|
|
4641
|
+
...getCurrentWindowMessageOptions3(sessionId) ?? {},
|
|
4642
|
+
isSystemGenerated: true,
|
|
4643
|
+
messageKind: "auto-prompt",
|
|
4644
|
+
metadata: { type: "compaction", name: "Compaction", color: "#64748b" }
|
|
4645
|
+
})
|
|
4646
|
+
);
|
|
4428
4647
|
eventStore.append(sessionId, { type: "message.done", data: { messageId: compactPromptMsgId } });
|
|
4429
4648
|
const assistantMsgId = crypto.randomUUID();
|
|
4430
|
-
eventStore.append(
|
|
4649
|
+
eventStore.append(
|
|
4650
|
+
sessionId,
|
|
4651
|
+
createMessageStartEvent(assistantMsgId, "assistant", void 0, getCurrentWindowMessageOptions3(sessionId))
|
|
4652
|
+
);
|
|
4431
4653
|
const turnMetrics = new TurnMetrics();
|
|
4432
4654
|
const compactionToolRegistry = {
|
|
4433
4655
|
execute: async (name, args, ctx) => {
|
|
@@ -4545,4 +4767,4 @@ export {
|
|
|
4545
4767
|
getToolRegistryForAgent,
|
|
4546
4768
|
createToolRegistry
|
|
4547
4769
|
};
|
|
4548
|
-
//# sourceMappingURL=chunk-
|
|
4770
|
+
//# sourceMappingURL=chunk-H5EICXF3.js.map
|