openfox 0.1.0 → 0.2.1
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/agent-defaults/builder.agent.md +38 -0
- package/dist/agent-defaults/code-reviewer.agent.md +21 -0
- package/dist/agent-defaults/debugger.agent.md +21 -0
- package/dist/agent-defaults/planner.agent.md +35 -0
- package/dist/agent-defaults/test-generator.agent.md +22 -0
- package/dist/agent-defaults/verifier.agent.md +41 -0
- package/dist/{chunk-FF6Z2MC3.js → chunk-5ZUU23XF.js} +18 -1
- package/dist/{chunk-IVHCPQO2.js → chunk-ARFK3RZW.js} +1 -1
- package/dist/{chunk-IKAWIOXM.js → chunk-FUUYYDVG.js} +387 -73
- package/dist/{chunk-YQ36AK5A.js → chunk-JFQEATRC.js} +623 -327
- package/dist/{chunk-43SWNGYW.js → chunk-L475ND2Z.js} +9 -9
- package/dist/{chunk-6MOGZMGX.js → chunk-L4XDA3V7.js} +2 -2
- package/dist/{chunk-EI46G5WO.js → chunk-MKAHOQBI.js} +10 -10
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{config-6GJ4SVFH.js → config-BMXSDOZB.js} +3 -3
- package/dist/{init-UVZDOHMX.js → init-PLRTRSDC.js} +6 -6
- package/dist/{protocol-BJsm88OW.d.ts → protocol-BFFz3WM0.d.ts} +14 -3
- package/dist/{provider-LCE6WZA6.js → provider-ETVY64A2.js} +5 -5
- package/dist/{serve-27DZK34K.js → serve-EOKIXTWM.js} +8 -8
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +5 -5
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +1 -1
- package/dist/{tools-R4YQAYUF.js → tools-QMIIDJTV.js} +7 -5
- package/dist/web/assets/index-CAD7Iv_d.js +122 -0
- package/dist/web/assets/{index-BSlSWZrM.css → index-DHmZmhnR.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/workflow-defaults/default.workflow.json +45 -0
- package/package.json +34 -16
- package/dist/branch.api-WDHKZJS6.js.map +0 -1
- package/dist/chunk-26NRL3HX.js.map +0 -1
- package/dist/chunk-43SWNGYW.js.map +0 -1
- package/dist/chunk-4Z2OZ6NX.js.map +0 -1
- package/dist/chunk-6MOGZMGX.js.map +0 -1
- package/dist/chunk-AF7XS4OI.js.map +0 -1
- package/dist/chunk-EI46G5WO.js.map +0 -1
- package/dist/chunk-FF6Z2MC3.js.map +0 -1
- package/dist/chunk-IKAWIOXM.js.map +0 -1
- package/dist/chunk-IVHCPQO2.js.map +0 -1
- package/dist/chunk-MTX5Y3V3.js.map +0 -1
- package/dist/chunk-N2XYX4ZA.js.map +0 -1
- package/dist/chunk-QY7BMXWT.js.map +0 -1
- package/dist/chunk-U62ZECSQ.js.map +0 -1
- package/dist/chunk-YQ36AK5A.js.map +0 -1
- package/dist/cli/dev.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/config-6GJ4SVFH.js.map +0 -1
- package/dist/init-UVZDOHMX.js.map +0 -1
- package/dist/paths-4BPXWB2W.js.map +0 -1
- package/dist/project-creator-CWPKRIKI.js.map +0 -1
- package/dist/provider-LCE6WZA6.js.map +0 -1
- package/dist/serve-27DZK34K.js.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/settings-D5O3TMLD.js.map +0 -1
- package/dist/shared/index.js.map +0 -1
- package/dist/tools-R4YQAYUF.js.map +0 -1
- package/dist/web/assets/index-BMNDCsbJ.js +0 -120
- /package/dist/command-defaults/{defaults/commit-push.command.md → commit-push.command.md} +0 -0
- /package/dist/command-defaults/{defaults/init.command.md → init.command.md} +0 -0
- /package/dist/command-defaults/{defaults/test-ui.command.md → test-ui.command.md} +0 -0
- /package/dist/skill-defaults/{defaults/playwright-cli.skill.md → playwright-cli.skill.md} +0 -0
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
createServerMessage,
|
|
11
11
|
isClientMessage
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ARFK3RZW.js";
|
|
13
13
|
import {
|
|
14
14
|
streamWithSegments
|
|
15
15
|
} from "./chunk-26NRL3HX.js";
|
|
@@ -237,7 +237,8 @@ function storedEventToServerMessage(event) {
|
|
|
237
237
|
...data.subAgentType ? { subAgentType: data.subAgentType } : {},
|
|
238
238
|
...data.isSystemGenerated ? { isSystemGenerated: data.isSystemGenerated } : {},
|
|
239
239
|
...data.messageKind ? { messageKind: data.messageKind } : {},
|
|
240
|
-
...data.isCompactionSummary ? { isCompactionSummary: data.isCompactionSummary } : {}
|
|
240
|
+
...data.isCompactionSummary ? { isCompactionSummary: data.isCompactionSummary } : {},
|
|
241
|
+
...data.attachments ? { attachments: data.attachments } : {}
|
|
241
242
|
};
|
|
242
243
|
return createChatMessageMessage(message);
|
|
243
244
|
}
|
|
@@ -584,8 +585,8 @@ var PathAccessDeniedError = class extends Error {
|
|
|
584
585
|
};
|
|
585
586
|
var pendingConfirmations = /* @__PURE__ */ new Map();
|
|
586
587
|
function registerPathConfirmation(callId, paths, sessionId) {
|
|
587
|
-
return new Promise((
|
|
588
|
-
pendingConfirmations.set(callId, { resolve:
|
|
588
|
+
return new Promise((resolve8, reject) => {
|
|
589
|
+
pendingConfirmations.set(callId, { resolve: resolve8, reject, paths, sessionId });
|
|
589
590
|
});
|
|
590
591
|
}
|
|
591
592
|
function providePathConfirmation(callId, approved) {
|
|
@@ -829,21 +830,24 @@ var readFileTool = createTool(
|
|
|
829
830
|
const mimeType = detectImageType(rawBuffer, args.path);
|
|
830
831
|
if (mimeType) {
|
|
831
832
|
const base64Data = rawBuffer.toString("base64");
|
|
833
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
832
834
|
const contentHash2 = await computeFileHash(fullPath);
|
|
833
835
|
if (contentHash2) {
|
|
834
836
|
context.sessionManager.recordFileRead(context.sessionId, fullPath, contentHash2);
|
|
835
837
|
}
|
|
836
|
-
return
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
838
|
+
return helpers.success(
|
|
839
|
+
`[Image: ${args.path} (${mimeType}, ${rawBuffer.length} bytes)]`,
|
|
840
|
+
false,
|
|
841
|
+
{
|
|
842
|
+
metadata: {
|
|
843
|
+
mimeType,
|
|
844
|
+
size: rawBuffer.length,
|
|
845
|
+
base64Data,
|
|
846
|
+
dataUrl,
|
|
847
|
+
path: fullPath
|
|
848
|
+
}
|
|
845
849
|
}
|
|
846
|
-
|
|
850
|
+
);
|
|
847
851
|
}
|
|
848
852
|
const content = rawBuffer.toString("utf-8");
|
|
849
853
|
const lines = content.split("\n");
|
|
@@ -1178,13 +1182,13 @@ async function terminateProcessTree(proc, options) {
|
|
|
1178
1182
|
return;
|
|
1179
1183
|
}
|
|
1180
1184
|
if (process.platform === "win32") {
|
|
1181
|
-
await new Promise((
|
|
1185
|
+
await new Promise((resolve8) => {
|
|
1182
1186
|
const killer = spawn("taskkill", ["/pid", String(pid), "/f", "/t"], {
|
|
1183
1187
|
stdio: "ignore",
|
|
1184
1188
|
windowsHide: true
|
|
1185
1189
|
});
|
|
1186
|
-
killer.once("exit", () =>
|
|
1187
|
-
killer.once("error", () =>
|
|
1190
|
+
killer.once("exit", () => resolve8());
|
|
1191
|
+
killer.once("error", () => resolve8());
|
|
1188
1192
|
});
|
|
1189
1193
|
return;
|
|
1190
1194
|
}
|
|
@@ -1301,7 +1305,7 @@ ${result.stderr}`;
|
|
|
1301
1305
|
}
|
|
1302
1306
|
);
|
|
1303
1307
|
function executeCommand(command, cwd, timeout, signal, onProgress) {
|
|
1304
|
-
return new Promise((
|
|
1308
|
+
return new Promise((resolve8, reject) => {
|
|
1305
1309
|
if (signal?.aborted) {
|
|
1306
1310
|
reject(new Error("Command aborted before execution"));
|
|
1307
1311
|
return;
|
|
@@ -1351,7 +1355,7 @@ function executeCommand(command, cwd, timeout, signal, onProgress) {
|
|
|
1351
1355
|
let output = stdout.trim();
|
|
1352
1356
|
if (output) output += "\n\n";
|
|
1353
1357
|
output += "[interrupted by user]";
|
|
1354
|
-
|
|
1358
|
+
resolve8({
|
|
1355
1359
|
stdout: output,
|
|
1356
1360
|
stderr: stderr.trim(),
|
|
1357
1361
|
exitCode: 130
|
|
@@ -1359,7 +1363,7 @@ function executeCommand(command, cwd, timeout, signal, onProgress) {
|
|
|
1359
1363
|
});
|
|
1360
1364
|
return;
|
|
1361
1365
|
}
|
|
1362
|
-
|
|
1366
|
+
resolve8({
|
|
1363
1367
|
stdout: stdout.trim(),
|
|
1364
1368
|
stderr: stderr.trim(),
|
|
1365
1369
|
exitCode: code ?? 1
|
|
@@ -1661,7 +1665,7 @@ ${result.stderr}`;
|
|
|
1661
1665
|
}
|
|
1662
1666
|
};
|
|
1663
1667
|
function executeGitCommand(command, cwd, signal) {
|
|
1664
|
-
return new Promise((
|
|
1668
|
+
return new Promise((resolve8, reject) => {
|
|
1665
1669
|
if (signal?.aborted) {
|
|
1666
1670
|
reject(new Error("Git command aborted before execution"));
|
|
1667
1671
|
return;
|
|
@@ -1693,14 +1697,14 @@ function executeGitCommand(command, cwd, signal) {
|
|
|
1693
1697
|
exited = true;
|
|
1694
1698
|
signal?.removeEventListener("abort", onAbort);
|
|
1695
1699
|
if (aborted) {
|
|
1696
|
-
|
|
1700
|
+
resolve8({
|
|
1697
1701
|
stdout: stdout.trim() + "\n[interrupted by user]",
|
|
1698
1702
|
stderr: stderr.trim(),
|
|
1699
1703
|
exitCode: 130
|
|
1700
1704
|
});
|
|
1701
1705
|
return;
|
|
1702
1706
|
}
|
|
1703
|
-
|
|
1707
|
+
resolve8({
|
|
1704
1708
|
stdout: stdout.trim(),
|
|
1705
1709
|
stderr: stderr.trim(),
|
|
1706
1710
|
exitCode: code ?? 1
|
|
@@ -1715,13 +1719,13 @@ function executeGitCommand(command, cwd, signal) {
|
|
|
1715
1719
|
|
|
1716
1720
|
// src/server/utils/async.ts
|
|
1717
1721
|
function createDeferred() {
|
|
1718
|
-
let
|
|
1722
|
+
let resolve8;
|
|
1719
1723
|
let reject;
|
|
1720
1724
|
const promise = new Promise((res, rej) => {
|
|
1721
|
-
|
|
1725
|
+
resolve8 = res;
|
|
1722
1726
|
reject = rej;
|
|
1723
1727
|
});
|
|
1724
|
-
return { promise, resolve:
|
|
1728
|
+
return { promise, resolve: resolve8, reject };
|
|
1725
1729
|
}
|
|
1726
1730
|
var EventEmitter = class {
|
|
1727
1731
|
listeners = /* @__PURE__ */ new Map();
|
|
@@ -2416,7 +2420,8 @@ function parseAgentFile(raw, filename) {
|
|
|
2416
2420
|
description: String(meta["description"] ?? ""),
|
|
2417
2421
|
subagent: meta["subagent"] === true,
|
|
2418
2422
|
tools: Array.isArray(meta["tools"]) ? meta["tools"].map(String) : [],
|
|
2419
|
-
...typeof meta["color"] === "string" ? { color: meta["color"] } : {}
|
|
2423
|
+
...typeof meta["color"] === "string" ? { color: meta["color"] } : {},
|
|
2424
|
+
...Array.isArray(meta["results"]) ? { results: meta["results"].map(String) } : {}
|
|
2420
2425
|
};
|
|
2421
2426
|
return { metadata, prompt: content.trim() };
|
|
2422
2427
|
}
|
|
@@ -2733,6 +2738,8 @@ var COMPACTION_PROMPT = `Summarize the conversation history concisely, preservin
|
|
|
2733
2738
|
2. All errors encountered and how they were resolved
|
|
2734
2739
|
3. Current progress on each task
|
|
2735
2740
|
4. Any important decisions or learnings
|
|
2741
|
+
5. Next steps or pending actions that should be continued after compaction
|
|
2742
|
+
6. The user's current question, prompt, or active request
|
|
2736
2743
|
|
|
2737
2744
|
Be thorough but concise. Output as a structured summary.
|
|
2738
2745
|
|
|
@@ -3239,8 +3246,8 @@ var EventStore = class {
|
|
|
3239
3246
|
if (queued) {
|
|
3240
3247
|
return { value: queued, done: false };
|
|
3241
3248
|
}
|
|
3242
|
-
return new Promise((
|
|
3243
|
-
resolveNext =
|
|
3249
|
+
return new Promise((resolve8) => {
|
|
3250
|
+
resolveNext = resolve8;
|
|
3244
3251
|
});
|
|
3245
3252
|
},
|
|
3246
3253
|
async return() {
|
|
@@ -3741,14 +3748,25 @@ function buildContextMessagesFromStoredEvents(events, windowId, options) {
|
|
|
3741
3748
|
case "tool.result": {
|
|
3742
3749
|
const data = event.data;
|
|
3743
3750
|
if (messageMap.has(data.messageId)) {
|
|
3744
|
-
|
|
3751
|
+
const imageMeta = data.result.metadata;
|
|
3752
|
+
const msg = {
|
|
3745
3753
|
id: `tool-${data.toolCallId}`,
|
|
3746
3754
|
role: "tool",
|
|
3747
3755
|
content: data.result.success ? data.result.output ?? "Success" : data.result.output ? `${data.result.output}
|
|
3748
3756
|
|
|
3749
3757
|
Error: ${data.result.error}` : `Error: ${data.result.error}`,
|
|
3750
3758
|
toolCallId: data.toolCallId
|
|
3751
|
-
}
|
|
3759
|
+
};
|
|
3760
|
+
if (imageMeta?.dataUrl && imageMeta?.mimeType?.startsWith("image/")) {
|
|
3761
|
+
msg.attachments = [{
|
|
3762
|
+
id: crypto.randomUUID(),
|
|
3763
|
+
filename: imageMeta.path ?? "image",
|
|
3764
|
+
mimeType: imageMeta.mimeType,
|
|
3765
|
+
size: imageMeta.size ?? 0,
|
|
3766
|
+
data: imageMeta.dataUrl
|
|
3767
|
+
}];
|
|
3768
|
+
}
|
|
3769
|
+
messages.push(msg);
|
|
3752
3770
|
}
|
|
3753
3771
|
break;
|
|
3754
3772
|
}
|
|
@@ -4430,26 +4448,6 @@ function assembleAgentRequest(input) {
|
|
|
4430
4448
|
}
|
|
4431
4449
|
|
|
4432
4450
|
// src/server/context/auto-compaction.ts
|
|
4433
|
-
var MIN_SUMMARY_LENGTH = 50;
|
|
4434
|
-
var compactionCooldowns = /* @__PURE__ */ new Map();
|
|
4435
|
-
var COOLDOWN_BASE_MS = 3e4;
|
|
4436
|
-
var MAX_COOLDOWN_MS = 3e5;
|
|
4437
|
-
function isInCooldown(sessionId) {
|
|
4438
|
-
const cooldown = compactionCooldowns.get(sessionId);
|
|
4439
|
-
if (!cooldown) return false;
|
|
4440
|
-
const backoff = Math.min(COOLDOWN_BASE_MS * Math.pow(2, cooldown.attempts - 1), MAX_COOLDOWN_MS);
|
|
4441
|
-
return Date.now() - cooldown.failedAt < backoff;
|
|
4442
|
-
}
|
|
4443
|
-
function recordCooldown(sessionId) {
|
|
4444
|
-
const prev = compactionCooldowns.get(sessionId);
|
|
4445
|
-
compactionCooldowns.set(sessionId, {
|
|
4446
|
-
failedAt: Date.now(),
|
|
4447
|
-
attempts: (prev?.attempts ?? 0) + 1
|
|
4448
|
-
});
|
|
4449
|
-
}
|
|
4450
|
-
function clearCooldown(sessionId) {
|
|
4451
|
-
compactionCooldowns.delete(sessionId);
|
|
4452
|
-
}
|
|
4453
4451
|
function getCurrentWindowMessageOptions(sessionId) {
|
|
4454
4452
|
const contextWindowId = getCurrentContextWindowId(sessionId);
|
|
4455
4453
|
return contextWindowId ? { contextWindowId } : void 0;
|
|
@@ -4470,20 +4468,12 @@ async function maybeAutoCompactContext(options) {
|
|
|
4470
4468
|
if (!shouldCompact(contextState.currentTokens, contextState.maxTokens, config.context.compactionThreshold)) {
|
|
4471
4469
|
return false;
|
|
4472
4470
|
}
|
|
4473
|
-
if (isInCooldown(options.sessionId)) {
|
|
4474
|
-
logger.warn("Skipping auto-compaction (in cooldown after previous failure)", {
|
|
4475
|
-
sessionId: options.sessionId,
|
|
4476
|
-
currentTokens: contextState.currentTokens
|
|
4477
|
-
});
|
|
4478
|
-
return false;
|
|
4479
|
-
}
|
|
4480
4471
|
try {
|
|
4481
4472
|
await performContextCompaction({
|
|
4482
4473
|
...options,
|
|
4483
4474
|
tokenCountAtClose: contextState.currentTokens,
|
|
4484
4475
|
trigger: "auto"
|
|
4485
4476
|
});
|
|
4486
|
-
clearCooldown(options.sessionId);
|
|
4487
4477
|
return true;
|
|
4488
4478
|
} catch (error) {
|
|
4489
4479
|
if (error instanceof Error && error.message === "Aborted") {
|
|
@@ -4495,7 +4485,6 @@ async function maybeAutoCompactContext(options) {
|
|
|
4495
4485
|
currentTokens: contextState.currentTokens,
|
|
4496
4486
|
maxTokens: contextState.maxTokens
|
|
4497
4487
|
});
|
|
4498
|
-
recordCooldown(options.sessionId);
|
|
4499
4488
|
const eventStore = getEventStore();
|
|
4500
4489
|
eventStore.append(options.sessionId, {
|
|
4501
4490
|
type: "chat.error",
|
|
@@ -4548,7 +4537,6 @@ async function performContextCompaction(options) {
|
|
|
4548
4537
|
subAgentDefs,
|
|
4549
4538
|
workdir: session.workdir,
|
|
4550
4539
|
messages: requestMessages,
|
|
4551
|
-
includeRuntimeReminder: false,
|
|
4552
4540
|
injectedFiles,
|
|
4553
4541
|
promptTools: [],
|
|
4554
4542
|
requestTools: [],
|
|
@@ -4556,6 +4544,13 @@ async function performContextCompaction(options) {
|
|
|
4556
4544
|
disableThinking: true,
|
|
4557
4545
|
...instructions ? { customInstructions: instructions } : {}
|
|
4558
4546
|
});
|
|
4547
|
+
const compactionReminder = `<system-reminder>
|
|
4548
|
+
${COMPACTION_PROMPT}
|
|
4549
|
+
</system-reminder>`;
|
|
4550
|
+
const llmMessages = [
|
|
4551
|
+
...assembledRequest.messages,
|
|
4552
|
+
{ role: "user", content: compactionReminder }
|
|
4553
|
+
];
|
|
4559
4554
|
const compactPromptMsgId = crypto.randomUUID();
|
|
4560
4555
|
eventStore.append(sessionId, createMessageStartEvent(compactPromptMsgId, "user", COMPACTION_PROMPT, {
|
|
4561
4556
|
...getCurrentWindowMessageOptions(sessionId) ?? {},
|
|
@@ -4573,7 +4568,7 @@ async function performContextCompaction(options) {
|
|
|
4573
4568
|
messageId: assistantMsgId,
|
|
4574
4569
|
systemPrompt: assembledRequest.systemPrompt,
|
|
4575
4570
|
llmClient,
|
|
4576
|
-
messages: [...
|
|
4571
|
+
messages: [...llmMessages, ...correctionMessages],
|
|
4577
4572
|
tools: [],
|
|
4578
4573
|
toolChoice: "none",
|
|
4579
4574
|
disableThinking: true,
|
|
@@ -4611,10 +4606,8 @@ async function performContextCompaction(options) {
|
|
|
4611
4606
|
logger.info("Using thinking content as compaction summary (text content was empty)", { sessionId });
|
|
4612
4607
|
summary = result.thinkingContent.trim();
|
|
4613
4608
|
}
|
|
4614
|
-
if (!summary
|
|
4615
|
-
throw new Error(
|
|
4616
|
-
`Compaction produced insufficient summary (length=${summary.length}, completionTokens=${result.usage.completionTokens}). The model may not support the required context size.`
|
|
4617
|
-
);
|
|
4609
|
+
if (!summary) {
|
|
4610
|
+
throw new Error("Compaction produced empty summary");
|
|
4618
4611
|
}
|
|
4619
4612
|
sessionManager.compactContext(sessionId, summary, tokenCountAtClose);
|
|
4620
4613
|
logger.info(`${trigger === "auto" ? "Auto" : "Manual"} compaction complete`, {
|
|
@@ -4816,6 +4809,7 @@ async function executeToolBatch(assistantMsgId, toolCalls, ctx) {
|
|
|
4816
4809
|
const toolMessages = [];
|
|
4817
4810
|
let criteriaChanged = false;
|
|
4818
4811
|
let returnValueContent;
|
|
4812
|
+
let returnValueResult;
|
|
4819
4813
|
let session = ctx.sessionManager.requireSession(ctx.sessionId);
|
|
4820
4814
|
for (const toolCall of toolCalls) {
|
|
4821
4815
|
if (ctx.signal?.aborted) {
|
|
@@ -4870,6 +4864,7 @@ async function executeToolBatch(assistantMsgId, toolCalls, ctx) {
|
|
|
4870
4864
|
ctx.onToolExecuted?.(toolCall, toolResult);
|
|
4871
4865
|
if (toolCall.name === "return_value" && !toolCall.parseError) {
|
|
4872
4866
|
returnValueContent = toolCall.arguments["content"];
|
|
4867
|
+
returnValueResult = toolCall.arguments["result"];
|
|
4873
4868
|
}
|
|
4874
4869
|
toolMessages.push({
|
|
4875
4870
|
role: "tool",
|
|
@@ -4886,7 +4881,7 @@ Error: ${toolResult.error}` : `Error: ${toolResult.error}`,
|
|
|
4886
4881
|
criteriaChanged = true;
|
|
4887
4882
|
}
|
|
4888
4883
|
}
|
|
4889
|
-
return { toolMessages, criteriaChanged, returnValueContent };
|
|
4884
|
+
return { toolMessages, criteriaChanged, returnValueContent, returnValueResult };
|
|
4890
4885
|
}
|
|
4891
4886
|
var MAX_FORMAT_RETRIES2 = 10;
|
|
4892
4887
|
var FORMAT_CORRECTION_PROMPT2 = `IMPORTANT: You MUST use the JSON function calling API. Do NOT output XML tags like <tool_call>, <function=>, or <parameter=>. Your previous attempt was stopped because you used the wrong format. Use the proper tool_calls format.`;
|
|
@@ -4904,6 +4899,8 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
4904
4899
|
const { mode, sessionManager, sessionId, llmClient, signal, onMessage, statsIdentity } = config;
|
|
4905
4900
|
const eventStore = getEventStore();
|
|
4906
4901
|
let formatRetryCount = 0;
|
|
4902
|
+
let returnValueContent;
|
|
4903
|
+
let returnValueResult;
|
|
4907
4904
|
for (; ; ) {
|
|
4908
4905
|
await maybeAutoCompactContext({
|
|
4909
4906
|
sessionManager,
|
|
@@ -4912,11 +4909,13 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
4912
4909
|
statsIdentity,
|
|
4913
4910
|
...signal ? { signal } : {}
|
|
4914
4911
|
});
|
|
4912
|
+
if (signal?.aborted) throw new Error("Aborted");
|
|
4915
4913
|
const session = sessionManager.requireSession(sessionId);
|
|
4916
4914
|
if (formatRetryCount === 0) {
|
|
4917
4915
|
config.injectKickoff?.();
|
|
4918
4916
|
}
|
|
4919
4917
|
const { content: instructionContent, files } = await getAllInstructions(session.workdir, session.projectId);
|
|
4918
|
+
if (signal?.aborted) throw new Error("Aborted");
|
|
4920
4919
|
const injectedFiles = files.map((f) => ({
|
|
4921
4920
|
path: f.path,
|
|
4922
4921
|
content: f.content ?? "",
|
|
@@ -4937,6 +4936,7 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
4937
4936
|
}
|
|
4938
4937
|
const configDir = getGlobalConfigDir(getRuntimeConfig().mode ?? "production");
|
|
4939
4938
|
const skills = await getEnabledSkillMetadata(configDir);
|
|
4939
|
+
if (signal?.aborted) throw new Error("Aborted");
|
|
4940
4940
|
const assembledRequest = config.assembleRequest({
|
|
4941
4941
|
workdir: session.workdir,
|
|
4942
4942
|
messages: requestMessages,
|
|
@@ -4991,7 +4991,7 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
4991
4991
|
promptContext: assembledRequest.promptContext
|
|
4992
4992
|
}));
|
|
4993
4993
|
try {
|
|
4994
|
-
await executeToolBatch(assistantMsgId, result.toolCalls, {
|
|
4994
|
+
const batchResult = await executeToolBatch(assistantMsgId, result.toolCalls, {
|
|
4995
4995
|
toolRegistry,
|
|
4996
4996
|
sessionManager,
|
|
4997
4997
|
sessionId,
|
|
@@ -5003,6 +5003,12 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
5003
5003
|
statsIdentity,
|
|
5004
5004
|
onToolExecuted: config.onToolExecuted
|
|
5005
5005
|
});
|
|
5006
|
+
if (batchResult.returnValueContent) {
|
|
5007
|
+
returnValueContent = batchResult.returnValueContent;
|
|
5008
|
+
}
|
|
5009
|
+
if (batchResult.returnValueResult) {
|
|
5010
|
+
returnValueResult = batchResult.returnValueResult;
|
|
5011
|
+
}
|
|
5006
5012
|
} catch (error) {
|
|
5007
5013
|
if (error instanceof Error && error.message === "Aborted") {
|
|
5008
5014
|
const stats2 = turnMetrics.buildStats(statsIdentity, mode);
|
|
@@ -5050,13 +5056,17 @@ async function runTopLevelAgentLoop(config, turnMetrics) {
|
|
|
5050
5056
|
eventStore.append(sessionId, createChatDoneEvent(assistantMsgId, "complete", stats));
|
|
5051
5057
|
break;
|
|
5052
5058
|
}
|
|
5059
|
+
return {
|
|
5060
|
+
...returnValueContent ? { returnValueContent } : {},
|
|
5061
|
+
...returnValueResult ? { returnValueResult } : {}
|
|
5062
|
+
};
|
|
5053
5063
|
}
|
|
5054
5064
|
|
|
5055
5065
|
// src/server/sub-agents/manager.ts
|
|
5056
5066
|
var RETURN_VALUE_INSTRUCTION = `
|
|
5057
5067
|
|
|
5058
5068
|
## RETURN VALUE
|
|
5059
|
-
As the very last thing you do, call \`return_value\` with a structured summary of your work. This is how your findings get passed back to the calling agent. Do not finish without calling return_value.`;
|
|
5069
|
+
As the very last thing you do, call \`return_value\` ONCE with a structured summary of your work. This is how your findings get passed back to the calling agent. Do not finish without calling return_value.`;
|
|
5060
5070
|
var RETURN_VALUE_NUDGE = "You must call return_value with a summary of your findings before finishing. Call return_value now.";
|
|
5061
5071
|
async function resolveAgentDef(agentId) {
|
|
5062
5072
|
const allAgents = await loadAllAgentsDefault();
|
|
@@ -5133,6 +5143,7 @@ async function executeSubAgent(options) {
|
|
|
5133
5143
|
let consecutiveEmptyStops = 0;
|
|
5134
5144
|
let finalContent = "";
|
|
5135
5145
|
let returnValueContent = null;
|
|
5146
|
+
let returnValueResult = void 0;
|
|
5136
5147
|
let returnValueNudged = false;
|
|
5137
5148
|
for (; ; ) {
|
|
5138
5149
|
if (signal?.aborted) {
|
|
@@ -5266,6 +5277,9 @@ async function executeSubAgent(options) {
|
|
|
5266
5277
|
if (batchResult.returnValueContent) {
|
|
5267
5278
|
returnValueContent = batchResult.returnValueContent;
|
|
5268
5279
|
}
|
|
5280
|
+
if (batchResult.returnValueResult) {
|
|
5281
|
+
returnValueResult = batchResult.returnValueResult;
|
|
5282
|
+
}
|
|
5269
5283
|
customMessages = [...customMessages, ...batchResult.toolMessages];
|
|
5270
5284
|
session = sessionManager.requireSession(sessionId);
|
|
5271
5285
|
if (nudgeConfig) {
|
|
@@ -5286,11 +5300,12 @@ async function executeSubAgent(options) {
|
|
|
5286
5300
|
}));
|
|
5287
5301
|
return {
|
|
5288
5302
|
content: returnValueContent ?? finalContent,
|
|
5303
|
+
...returnValueResult ? { result: returnValueResult } : {},
|
|
5289
5304
|
allPassed: failed.length === 0 && remaining.length === 0,
|
|
5290
5305
|
failed
|
|
5291
5306
|
};
|
|
5292
5307
|
}
|
|
5293
|
-
return { content: returnValueContent ?? finalContent };
|
|
5308
|
+
return { content: returnValueContent ?? finalContent, ...returnValueResult ? { result: returnValueResult } : { result: "success" } };
|
|
5294
5309
|
}
|
|
5295
5310
|
|
|
5296
5311
|
// src/server/tools/sub-agent.ts
|
|
@@ -5358,7 +5373,7 @@ var callSubAgentTool = {
|
|
|
5358
5373
|
};
|
|
5359
5374
|
}
|
|
5360
5375
|
try {
|
|
5361
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
5376
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-QMIIDJTV.js");
|
|
5362
5377
|
const toolRegistry = getToolRegistryForAgent2(agentDef);
|
|
5363
5378
|
const turnMetrics = new TurnMetrics();
|
|
5364
5379
|
const result = await executeSubAgent({
|
|
@@ -5450,6 +5465,10 @@ var returnValueTool = {
|
|
|
5450
5465
|
content: {
|
|
5451
5466
|
type: "string",
|
|
5452
5467
|
description: "The return value content \u2014 a structured summary of findings, results, or recommendations"
|
|
5468
|
+
},
|
|
5469
|
+
result: {
|
|
5470
|
+
type: "string",
|
|
5471
|
+
description: 'Result classification (e.g. "passed", "failed", "error"). Used for workflow routing.'
|
|
5453
5472
|
}
|
|
5454
5473
|
},
|
|
5455
5474
|
required: ["content"]
|
|
@@ -5604,6 +5623,297 @@ var webFetchTool = createTool(
|
|
|
5604
5623
|
}
|
|
5605
5624
|
);
|
|
5606
5625
|
|
|
5626
|
+
// src/server/dev-server/manager.ts
|
|
5627
|
+
import { spawn as spawn4 } from "child_process";
|
|
5628
|
+
import { readFile as readFile8, writeFile as writeFile5, mkdir as mkdir4 } from "fs/promises";
|
|
5629
|
+
import { resolve as resolve7, join as join5 } from "path";
|
|
5630
|
+
var MAX_LOG_LINES = 2e3;
|
|
5631
|
+
var MAX_LOG_BYTES = 1e5;
|
|
5632
|
+
var CONFIG_PATH = ".openfox/dev.json";
|
|
5633
|
+
var ERROR_PATTERNS = [
|
|
5634
|
+
/EADDRINUSE/,
|
|
5635
|
+
/EACCES/,
|
|
5636
|
+
/ENOENT/,
|
|
5637
|
+
/Error: listen/,
|
|
5638
|
+
/Unhandled 'error' event/,
|
|
5639
|
+
/throw er;.*Unhandled/s,
|
|
5640
|
+
/Cannot find module/,
|
|
5641
|
+
/SyntaxError:/,
|
|
5642
|
+
/MODULE_NOT_FOUND/
|
|
5643
|
+
];
|
|
5644
|
+
function createInstance() {
|
|
5645
|
+
return {
|
|
5646
|
+
process: null,
|
|
5647
|
+
state: "off",
|
|
5648
|
+
config: null,
|
|
5649
|
+
logs: [],
|
|
5650
|
+
totalLogBytes: 0,
|
|
5651
|
+
errorMessage: void 0,
|
|
5652
|
+
exited: true
|
|
5653
|
+
};
|
|
5654
|
+
}
|
|
5655
|
+
var DevServerManager = class {
|
|
5656
|
+
instances = /* @__PURE__ */ new Map();
|
|
5657
|
+
outputListeners = /* @__PURE__ */ new Set();
|
|
5658
|
+
stateListeners = /* @__PURE__ */ new Set();
|
|
5659
|
+
resolveWorkdir(workdir) {
|
|
5660
|
+
return resolve7(workdir);
|
|
5661
|
+
}
|
|
5662
|
+
getInstance(workdir) {
|
|
5663
|
+
const key = this.resolveWorkdir(workdir);
|
|
5664
|
+
let instance = this.instances.get(key);
|
|
5665
|
+
if (!instance) {
|
|
5666
|
+
instance = createInstance();
|
|
5667
|
+
this.instances.set(key, instance);
|
|
5668
|
+
}
|
|
5669
|
+
return instance;
|
|
5670
|
+
}
|
|
5671
|
+
emitOutput(workdir, chunk) {
|
|
5672
|
+
const resolved = this.resolveWorkdir(workdir);
|
|
5673
|
+
for (const listener of this.outputListeners) {
|
|
5674
|
+
listener(resolved, chunk);
|
|
5675
|
+
}
|
|
5676
|
+
}
|
|
5677
|
+
emitStateChange(workdir, state, errorMessage) {
|
|
5678
|
+
const resolved = this.resolveWorkdir(workdir);
|
|
5679
|
+
for (const listener of this.stateListeners) {
|
|
5680
|
+
listener(resolved, state, errorMessage);
|
|
5681
|
+
}
|
|
5682
|
+
}
|
|
5683
|
+
async loadConfig(workdir) {
|
|
5684
|
+
try {
|
|
5685
|
+
const configPath = join5(this.resolveWorkdir(workdir), CONFIG_PATH);
|
|
5686
|
+
const raw = await readFile8(configPath, "utf-8");
|
|
5687
|
+
const parsed = JSON.parse(raw);
|
|
5688
|
+
if (!parsed.command || !parsed.url) return null;
|
|
5689
|
+
return {
|
|
5690
|
+
command: parsed.command,
|
|
5691
|
+
url: parsed.url,
|
|
5692
|
+
hotReload: parsed.hotReload ?? false
|
|
5693
|
+
};
|
|
5694
|
+
} catch {
|
|
5695
|
+
return null;
|
|
5696
|
+
}
|
|
5697
|
+
}
|
|
5698
|
+
async saveConfig(workdir, config) {
|
|
5699
|
+
const resolved = this.resolveWorkdir(workdir);
|
|
5700
|
+
const dirPath = join5(resolved, ".openfox");
|
|
5701
|
+
await mkdir4(dirPath, { recursive: true });
|
|
5702
|
+
const configPath = join5(resolved, CONFIG_PATH);
|
|
5703
|
+
await writeFile5(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
5704
|
+
}
|
|
5705
|
+
async start(workdir) {
|
|
5706
|
+
const instance = this.getInstance(workdir);
|
|
5707
|
+
if (instance.state === "running" && instance.process && !instance.exited) {
|
|
5708
|
+
await this.stop(workdir);
|
|
5709
|
+
}
|
|
5710
|
+
const config = await this.loadConfig(workdir);
|
|
5711
|
+
if (!config) {
|
|
5712
|
+
return this.getStatus(workdir);
|
|
5713
|
+
}
|
|
5714
|
+
instance.config = config;
|
|
5715
|
+
instance.logs = [];
|
|
5716
|
+
instance.totalLogBytes = 0;
|
|
5717
|
+
instance.errorMessage = void 0;
|
|
5718
|
+
instance.exited = false;
|
|
5719
|
+
const resolved = this.resolveWorkdir(workdir);
|
|
5720
|
+
const proc = spawn4("sh", ["-c", config.command], {
|
|
5721
|
+
cwd: resolved,
|
|
5722
|
+
env: { ...process.env, FORCE_COLOR: "1" },
|
|
5723
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
5724
|
+
detached: true
|
|
5725
|
+
});
|
|
5726
|
+
instance.process = proc;
|
|
5727
|
+
const appendLog = (line) => {
|
|
5728
|
+
instance.logs.push(line);
|
|
5729
|
+
instance.totalLogBytes += line.length;
|
|
5730
|
+
while (instance.logs.length > MAX_LOG_LINES || instance.totalLogBytes > MAX_LOG_BYTES) {
|
|
5731
|
+
const removed = instance.logs.shift();
|
|
5732
|
+
if (removed) instance.totalLogBytes -= removed.length;
|
|
5733
|
+
}
|
|
5734
|
+
};
|
|
5735
|
+
proc.stdout?.on("data", (data) => {
|
|
5736
|
+
const content = data.toString();
|
|
5737
|
+
appendLog(content);
|
|
5738
|
+
this.emitOutput(workdir, { stream: "stdout", content });
|
|
5739
|
+
});
|
|
5740
|
+
proc.stderr?.on("data", (data) => {
|
|
5741
|
+
const content = data.toString();
|
|
5742
|
+
appendLog(content);
|
|
5743
|
+
this.emitOutput(workdir, { stream: "stderr", content });
|
|
5744
|
+
if (instance.state === "running" && ERROR_PATTERNS.some((p) => p.test(content))) {
|
|
5745
|
+
instance.state = "warning";
|
|
5746
|
+
instance.errorMessage = content.trim().slice(0, 500);
|
|
5747
|
+
this.emitStateChange(workdir, "warning", instance.errorMessage);
|
|
5748
|
+
}
|
|
5749
|
+
});
|
|
5750
|
+
proc.on("close", (code) => {
|
|
5751
|
+
instance.exited = true;
|
|
5752
|
+
instance.process = null;
|
|
5753
|
+
if (code !== 0 && code !== null) {
|
|
5754
|
+
const recentLogs = instance.logs.slice(-10).join("");
|
|
5755
|
+
const errorMessage = `Process exited with code ${code}
|
|
5756
|
+
${recentLogs}`.trim();
|
|
5757
|
+
instance.state = "error";
|
|
5758
|
+
instance.errorMessage = errorMessage;
|
|
5759
|
+
this.emitStateChange(workdir, "error", errorMessage);
|
|
5760
|
+
} else {
|
|
5761
|
+
instance.state = "off";
|
|
5762
|
+
instance.errorMessage = void 0;
|
|
5763
|
+
this.emitStateChange(workdir, "off", void 0);
|
|
5764
|
+
}
|
|
5765
|
+
});
|
|
5766
|
+
proc.on("error", (err) => {
|
|
5767
|
+
instance.exited = true;
|
|
5768
|
+
instance.process = null;
|
|
5769
|
+
instance.state = "error";
|
|
5770
|
+
instance.errorMessage = err.message;
|
|
5771
|
+
this.emitStateChange(workdir, "error", err.message);
|
|
5772
|
+
});
|
|
5773
|
+
instance.state = "running";
|
|
5774
|
+
instance.errorMessage = void 0;
|
|
5775
|
+
this.emitStateChange(workdir, "running", void 0);
|
|
5776
|
+
logger.info("Dev server started", { workdir, command: config.command });
|
|
5777
|
+
return this.getStatus(workdir);
|
|
5778
|
+
}
|
|
5779
|
+
async stop(workdir) {
|
|
5780
|
+
const instance = this.getInstance(workdir);
|
|
5781
|
+
if (instance.process && !instance.exited) {
|
|
5782
|
+
await terminateProcessTree(instance.process, { exited: () => instance.exited });
|
|
5783
|
+
instance.process = null;
|
|
5784
|
+
instance.exited = true;
|
|
5785
|
+
instance.state = "off";
|
|
5786
|
+
instance.errorMessage = void 0;
|
|
5787
|
+
this.emitStateChange(workdir, "off", void 0);
|
|
5788
|
+
logger.info("Dev server stopped", { workdir });
|
|
5789
|
+
}
|
|
5790
|
+
return this.getStatus(workdir);
|
|
5791
|
+
}
|
|
5792
|
+
async restart(workdir) {
|
|
5793
|
+
await this.stop(workdir);
|
|
5794
|
+
return this.start(workdir);
|
|
5795
|
+
}
|
|
5796
|
+
getStatus(workdir) {
|
|
5797
|
+
const instance = this.getInstance(workdir);
|
|
5798
|
+
return {
|
|
5799
|
+
state: instance.state,
|
|
5800
|
+
url: instance.config?.url ?? null,
|
|
5801
|
+
hotReload: instance.config?.hotReload ?? false,
|
|
5802
|
+
config: instance.config,
|
|
5803
|
+
errorMessage: instance.errorMessage
|
|
5804
|
+
};
|
|
5805
|
+
}
|
|
5806
|
+
getLogs(workdir) {
|
|
5807
|
+
const instance = this.getInstance(workdir);
|
|
5808
|
+
return [...instance.logs];
|
|
5809
|
+
}
|
|
5810
|
+
/** Register a global listener for output from any dev server */
|
|
5811
|
+
onOutput(callback) {
|
|
5812
|
+
this.outputListeners.add(callback);
|
|
5813
|
+
return () => {
|
|
5814
|
+
this.outputListeners.delete(callback);
|
|
5815
|
+
};
|
|
5816
|
+
}
|
|
5817
|
+
/** Register a global listener for state changes from any dev server */
|
|
5818
|
+
onStateChange(callback) {
|
|
5819
|
+
this.stateListeners.add(callback);
|
|
5820
|
+
return () => {
|
|
5821
|
+
this.stateListeners.delete(callback);
|
|
5822
|
+
};
|
|
5823
|
+
}
|
|
5824
|
+
async stopAll() {
|
|
5825
|
+
const stops = Array.from(this.instances.keys()).map((workdir) => this.stop(workdir));
|
|
5826
|
+
await Promise.allSettled(stops);
|
|
5827
|
+
this.instances.clear();
|
|
5828
|
+
}
|
|
5829
|
+
};
|
|
5830
|
+
var devServerManager = new DevServerManager();
|
|
5831
|
+
|
|
5832
|
+
// src/server/tools/dev-server.ts
|
|
5833
|
+
var devServerTool = createTool(
|
|
5834
|
+
"dev_server",
|
|
5835
|
+
{
|
|
5836
|
+
type: "function",
|
|
5837
|
+
function: {
|
|
5838
|
+
name: "dev_server",
|
|
5839
|
+
description: "Control the project dev server. Start, stop, restart, or check status. The dev server command and URL are configured in .openfox/dev.json.",
|
|
5840
|
+
parameters: {
|
|
5841
|
+
type: "object",
|
|
5842
|
+
properties: {
|
|
5843
|
+
action: {
|
|
5844
|
+
type: "string",
|
|
5845
|
+
enum: ["start", "stop", "restart", "status"],
|
|
5846
|
+
description: "The action to perform on the dev server"
|
|
5847
|
+
}
|
|
5848
|
+
},
|
|
5849
|
+
required: ["action"]
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
},
|
|
5853
|
+
async (args, context, helpers) => {
|
|
5854
|
+
const workdir = context.workdir;
|
|
5855
|
+
let status;
|
|
5856
|
+
switch (args.action) {
|
|
5857
|
+
case "start":
|
|
5858
|
+
status = await devServerManager.start(workdir);
|
|
5859
|
+
break;
|
|
5860
|
+
case "stop":
|
|
5861
|
+
status = await devServerManager.stop(workdir);
|
|
5862
|
+
break;
|
|
5863
|
+
case "restart":
|
|
5864
|
+
status = await devServerManager.restart(workdir);
|
|
5865
|
+
break;
|
|
5866
|
+
case "status":
|
|
5867
|
+
status = devServerManager.getStatus(workdir);
|
|
5868
|
+
if (!status.config) {
|
|
5869
|
+
const config = await devServerManager.loadConfig(workdir);
|
|
5870
|
+
if (config) {
|
|
5871
|
+
status.config = config;
|
|
5872
|
+
status.url = config.url;
|
|
5873
|
+
status.hotReload = config.hotReload;
|
|
5874
|
+
}
|
|
5875
|
+
}
|
|
5876
|
+
break;
|
|
5877
|
+
}
|
|
5878
|
+
if (!status.config) {
|
|
5879
|
+
return helpers.error(
|
|
5880
|
+
'No .openfox/dev.json config found. Create one with:\n\n{\n "command": "npm run dev",\n "url": "http://localhost:3000",\n "hotReload": true\n}'
|
|
5881
|
+
);
|
|
5882
|
+
}
|
|
5883
|
+
return helpers.success(JSON.stringify({
|
|
5884
|
+
state: status.state,
|
|
5885
|
+
url: status.url,
|
|
5886
|
+
hotReload: status.hotReload,
|
|
5887
|
+
...status.errorMessage ? { error: status.errorMessage } : {}
|
|
5888
|
+
}, null, 2));
|
|
5889
|
+
}
|
|
5890
|
+
);
|
|
5891
|
+
|
|
5892
|
+
// src/server/tools/step-done.ts
|
|
5893
|
+
var stepDoneTool = {
|
|
5894
|
+
name: "step_done",
|
|
5895
|
+
definition: {
|
|
5896
|
+
type: "function",
|
|
5897
|
+
function: {
|
|
5898
|
+
name: "step_done",
|
|
5899
|
+
description: "Signal that you have completed the current workflow step. Call this exactly once when you have finished all work for this step. After calling this, no further tool calls should be made.",
|
|
5900
|
+
parameters: {
|
|
5901
|
+
type: "object",
|
|
5902
|
+
properties: {},
|
|
5903
|
+
required: []
|
|
5904
|
+
}
|
|
5905
|
+
}
|
|
5906
|
+
},
|
|
5907
|
+
async execute(_args, _context) {
|
|
5908
|
+
return {
|
|
5909
|
+
success: true,
|
|
5910
|
+
output: "Step completion signal recorded.",
|
|
5911
|
+
durationMs: 0,
|
|
5912
|
+
truncated: false
|
|
5913
|
+
};
|
|
5914
|
+
}
|
|
5915
|
+
};
|
|
5916
|
+
|
|
5607
5917
|
// src/server/tools/index.ts
|
|
5608
5918
|
function createRegistryFromTools(tools) {
|
|
5609
5919
|
const toolMap = /* @__PURE__ */ new Map();
|
|
@@ -5671,7 +5981,9 @@ var allToolsByName = new Map([
|
|
|
5671
5981
|
callSubAgentTool,
|
|
5672
5982
|
loadSkillTool,
|
|
5673
5983
|
returnValueTool,
|
|
5674
|
-
webFetchTool
|
|
5984
|
+
webFetchTool,
|
|
5985
|
+
devServerTool,
|
|
5986
|
+
stepDoneTool
|
|
5675
5987
|
].map((t) => [t.name, t])
|
|
5676
5988
|
]);
|
|
5677
5989
|
function getToolRegistryForSubAgent(toolNames) {
|
|
@@ -5810,8 +6122,10 @@ export {
|
|
|
5810
6122
|
deleteSkill,
|
|
5811
6123
|
runTopLevelAgentLoop,
|
|
5812
6124
|
executeSubAgent,
|
|
6125
|
+
devServerManager,
|
|
6126
|
+
stepDoneTool,
|
|
5813
6127
|
getToolRegistryForSubAgent,
|
|
5814
6128
|
getToolRegistryForAgent,
|
|
5815
6129
|
createToolRegistry
|
|
5816
6130
|
};
|
|
5817
|
-
//# sourceMappingURL=chunk-
|
|
6131
|
+
//# sourceMappingURL=chunk-FUUYYDVG.js.map
|