@aiden-ade/sandbox-agent 0.1.26 → 0.1.27
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/core-agent.d.ts +2 -6
- package/dist/core-agent.d.ts.map +1 -1
- package/dist/core-agent.js +21 -140
- package/dist/core-agent.js.map +1 -1
- package/dist/index.cjs +787 -287
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +42 -107
- package/dist/index.js.map +1 -1
- package/dist/sandbox.d.ts +0 -6
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +10 -40
- package/dist/sandbox.js.map +1 -1
- package/dist/updater.d.ts.map +1 -1
- package/dist/updater.js +4 -0
- package/dist/updater.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/web-presenter.d.ts +4 -7
- package/dist/web-presenter.d.ts.map +1 -1
- package/dist/web-presenter.js +4 -29
- package/dist/web-presenter.js.map +1 -1
- package/dist/ws-client.d.ts +0 -35
- package/dist/ws-client.d.ts.map +1 -1
- package/dist/ws-client.js +9 -32
- package/dist/ws-client.js.map +1 -1
- package/package.json +3 -3
- package/dist/__tests__/cli-executable.test.d.ts +0 -2
- package/dist/__tests__/cli-executable.test.d.ts.map +0 -1
- package/dist/__tests__/cli-executable.test.js +0 -83
- package/dist/__tests__/cli-executable.test.js.map +0 -1
- package/dist/__tests__/cli-help.test.d.ts +0 -2
- package/dist/__tests__/cli-help.test.d.ts.map +0 -1
- package/dist/__tests__/cli-help.test.js +0 -33
- package/dist/__tests__/cli-help.test.js.map +0 -1
- package/dist/__tests__/core-agent-workflow-context.test.d.ts +0 -2
- package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +0 -1
- package/dist/__tests__/core-agent-workflow-context.test.js +0 -50
- package/dist/__tests__/core-agent-workflow-context.test.js.map +0 -1
- package/dist/__tests__/daemon-socket.integration.test.d.ts +0 -2
- package/dist/__tests__/daemon-socket.integration.test.d.ts.map +0 -1
- package/dist/__tests__/daemon-socket.integration.test.js +0 -156
- package/dist/__tests__/daemon-socket.integration.test.js.map +0 -1
- package/dist/__tests__/daemon.test.d.ts +0 -2
- package/dist/__tests__/daemon.test.d.ts.map +0 -1
- package/dist/__tests__/daemon.test.js +0 -1014
- package/dist/__tests__/daemon.test.js.map +0 -1
- package/dist/__tests__/generated-images.test.d.ts +0 -2
- package/dist/__tests__/generated-images.test.d.ts.map +0 -1
- package/dist/__tests__/generated-images.test.js +0 -50
- package/dist/__tests__/generated-images.test.js.map +0 -1
- package/dist/__tests__/sandbox-workflow-context.test.d.ts +0 -2
- package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +0 -1
- package/dist/__tests__/sandbox-workflow-context.test.js +0 -66
- package/dist/__tests__/sandbox-workflow-context.test.js.map +0 -1
- package/dist/aiden-system-prompt.d.ts +0 -6
- package/dist/aiden-system-prompt.d.ts.map +0 -1
- package/dist/aiden-system-prompt.js +0 -6
- package/dist/aiden-system-prompt.js.map +0 -1
- package/dist/cli-executable.d.ts +0 -58
- package/dist/cli-executable.d.ts.map +0 -1
- package/dist/cli-executable.js +0 -301
- package/dist/cli-executable.js.map +0 -1
- package/dist/cli-help.d.ts +0 -7
- package/dist/cli-help.d.ts.map +0 -1
- package/dist/cli-help.js +0 -45
- package/dist/cli-help.js.map +0 -1
- package/dist/daemon.d.ts +0 -46
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js +0 -876
- package/dist/daemon.js.map +0 -1
- package/dist/generated-images.d.ts +0 -4
- package/dist/generated-images.d.ts.map +0 -1
- package/dist/generated-images.js +0 -142
- package/dist/generated-images.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -4856,11 +4856,11 @@ function resolveCommand(args, env) {
|
|
|
4856
4856
|
|
|
4857
4857
|
// src/daemon.ts
|
|
4858
4858
|
var import_node_child_process3 = require("child_process");
|
|
4859
|
-
var
|
|
4860
|
-
var
|
|
4859
|
+
var import_node_crypto = require("crypto");
|
|
4860
|
+
var import_node_fs3 = require("fs");
|
|
4861
4861
|
var import_node_http = __toESM(require("http"), 1);
|
|
4862
4862
|
var import_node_os4 = require("os");
|
|
4863
|
-
var
|
|
4863
|
+
var import_node_path3 = require("path");
|
|
4864
4864
|
|
|
4865
4865
|
// ../shared/dist/node/provider-limits.js
|
|
4866
4866
|
var import_node_child_process = require("child_process");
|
|
@@ -4974,8 +4974,8 @@ async function withTimeout(promise, timeoutMs, fallback) {
|
|
|
4974
4974
|
try {
|
|
4975
4975
|
return await Promise.race([
|
|
4976
4976
|
promise,
|
|
4977
|
-
new Promise((
|
|
4978
|
-
timer = setTimeout(() =>
|
|
4977
|
+
new Promise((resolve3) => {
|
|
4978
|
+
timer = setTimeout(() => resolve3(fallback), timeoutMs);
|
|
4979
4979
|
})
|
|
4980
4980
|
]);
|
|
4981
4981
|
} finally {
|
|
@@ -4988,7 +4988,7 @@ async function collectCodexLimits(env) {
|
|
|
4988
4988
|
const codexCommand = resolveExecutable("codex", runtimeEnv, "AIDEN_CODEX_PATH");
|
|
4989
4989
|
if (!codexCommand)
|
|
4990
4990
|
return [];
|
|
4991
|
-
return withTimeout(new Promise((
|
|
4991
|
+
return withTimeout(new Promise((resolve3) => {
|
|
4992
4992
|
const child = (0, import_node_child_process.spawn)(codexCommand, ["-s", "read-only", "-a", "untrusted", "app-server"], {
|
|
4993
4993
|
env: runtimeEnv,
|
|
4994
4994
|
stdio: ["pipe", "pipe", "ignore"]
|
|
@@ -5000,7 +5000,7 @@ async function collectCodexLimits(env) {
|
|
|
5000
5000
|
pending.clear();
|
|
5001
5001
|
if (!child.killed)
|
|
5002
5002
|
child.kill();
|
|
5003
|
-
|
|
5003
|
+
resolve3(windows);
|
|
5004
5004
|
};
|
|
5005
5005
|
const request = (method, params = {}) => {
|
|
5006
5006
|
const id = nextId++;
|
|
@@ -7685,9 +7685,9 @@ var Socket2 = class extends Emitter {
|
|
|
7685
7685
|
* @return a Promise that will be fulfilled when the server acknowledges the event
|
|
7686
7686
|
*/
|
|
7687
7687
|
emitWithAck(ev, ...args) {
|
|
7688
|
-
return new Promise((
|
|
7688
|
+
return new Promise((resolve3, reject) => {
|
|
7689
7689
|
const fn = (arg1, arg2) => {
|
|
7690
|
-
return arg1 ? reject(arg1) :
|
|
7690
|
+
return arg1 ? reject(arg1) : resolve3(arg2);
|
|
7691
7691
|
};
|
|
7692
7692
|
fn.withError = true;
|
|
7693
7693
|
args.push(fn);
|
|
@@ -8691,22 +8691,33 @@ var import_node_fs2 = require("fs");
|
|
|
8691
8691
|
var import_node_os2 = require("os");
|
|
8692
8692
|
var import_node_path2 = require("path");
|
|
8693
8693
|
var PROVIDER_CLI_COMMANDS = {
|
|
8694
|
-
claude_cli: { provider: "claude_cli", command: "claude",
|
|
8695
|
-
codex_app_server: {
|
|
8696
|
-
|
|
8694
|
+
claude_cli: { provider: "claude_cli", command: "claude", envVars: ["AIDEN_CLAUDE_PATH"] },
|
|
8695
|
+
codex_app_server: {
|
|
8696
|
+
provider: "codex_app_server",
|
|
8697
|
+
command: "codex",
|
|
8698
|
+
envVars: ["AIDEN_CODEX_PATH"]
|
|
8699
|
+
},
|
|
8700
|
+
copilot_cli: { provider: "copilot_cli", command: "copilot", envVars: ["AIDEN_COPILOT_PATH"] },
|
|
8697
8701
|
cursor_agent_cli: {
|
|
8698
8702
|
provider: "cursor_agent_cli",
|
|
8699
8703
|
command: "cursor-agent",
|
|
8700
|
-
|
|
8704
|
+
envVars: ["AIDEN_CURSOR_AGENT_PATH"]
|
|
8705
|
+
},
|
|
8706
|
+
gemini_cli: {
|
|
8707
|
+
provider: "gemini_cli",
|
|
8708
|
+
command: "agy",
|
|
8709
|
+
envVars: ["AIDEN_ANTIGRAVITY_PATH", "AIDEN_GEMINI_PATH"]
|
|
8701
8710
|
},
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
supatest_cli: { provider: "supatest_cli", command: "supatest", envVar: "AIDEN_SUPATEST_PATH" }
|
|
8711
|
+
kimi_cli: { provider: "kimi_cli", command: "kimi-cli", envVars: ["AIDEN_KIMI_PATH"] },
|
|
8712
|
+
opencode_cli: { provider: "opencode_cli", command: "opencode", envVars: ["AIDEN_OPENCODE_PATH"] },
|
|
8713
|
+
droid_cli: { provider: "droid_cli", command: "droid", envVars: ["AIDEN_DROID_PATH"] },
|
|
8714
|
+
supatest_cli: { provider: "supatest_cli", command: "supatest", envVars: ["AIDEN_SUPATEST_PATH"] }
|
|
8707
8715
|
};
|
|
8708
8716
|
var DISCOVERABLE_PROVIDER_KINDS = Object.keys(PROVIDER_CLI_COMMANDS);
|
|
8709
8717
|
var PROVIDER_ALIASES = {
|
|
8718
|
+
agy: "gemini_cli",
|
|
8719
|
+
antigravity: "gemini_cli",
|
|
8720
|
+
antigravity_cli: "gemini_cli",
|
|
8710
8721
|
codex: "codex_app_server",
|
|
8711
8722
|
gemini: "gemini_cli"
|
|
8712
8723
|
};
|
|
@@ -8716,8 +8727,11 @@ var BACKEND_CLI_COMMANDS = {
|
|
|
8716
8727
|
codex_app_server: "codex",
|
|
8717
8728
|
copilot_cli: "copilot",
|
|
8718
8729
|
cursor_agent_cli: "cursor-agent",
|
|
8719
|
-
|
|
8720
|
-
|
|
8730
|
+
agy: "agy",
|
|
8731
|
+
antigravity: "agy",
|
|
8732
|
+
antigravity_cli: "agy",
|
|
8733
|
+
gemini_cli: "agy",
|
|
8734
|
+
gemini: "agy",
|
|
8721
8735
|
kimi_cli: "kimi-cli",
|
|
8722
8736
|
opencode_cli: "opencode",
|
|
8723
8737
|
droid_cli: "droid",
|
|
@@ -8905,7 +8919,7 @@ function resolveProviderCliCommand(provider, env = getDaemonCliEnvironment()) {
|
|
|
8905
8919
|
const normalized = normalizeDiscoverableProvider(provider);
|
|
8906
8920
|
if (!normalized) return null;
|
|
8907
8921
|
const spec = PROVIDER_CLI_COMMANDS[normalized];
|
|
8908
|
-
const override = process.env[
|
|
8922
|
+
const override = spec.envVars.map((name) => process.env[name]?.trim() || env[name]?.trim()).find(Boolean);
|
|
8909
8923
|
if (override) {
|
|
8910
8924
|
const resolved2 = resolveCliExecutable(override, env) ?? (isRunnableFile(override) ? override : null);
|
|
8911
8925
|
if (resolved2) cacheResolvedCli(spec.command, resolved2);
|
|
@@ -8922,7 +8936,7 @@ function resolveBackendRuntimeCommand(backendKind, env = getDaemonCliEnvironment
|
|
|
8922
8936
|
const cached = getCachedResolvedCli(command);
|
|
8923
8937
|
if (cached && isRunnableFile(cached)) return cached;
|
|
8924
8938
|
const spec = Object.values(PROVIDER_CLI_COMMANDS).find((entry) => entry.command === command);
|
|
8925
|
-
const envOverride = spec ? env[
|
|
8939
|
+
const envOverride = spec ? spec.envVars.map((name) => env[name]?.trim()).find(Boolean) : void 0;
|
|
8926
8940
|
const resolved = resolveCliExecutable(envOverride?.trim() || command, env);
|
|
8927
8941
|
if (resolved) cacheResolvedCli(command, resolved);
|
|
8928
8942
|
return resolved ?? void 0;
|
|
@@ -9321,6 +9335,64 @@ function isReadOnlyAgent(agentId) {
|
|
|
9321
9335
|
return !agent.capabilities.canEditFiles;
|
|
9322
9336
|
}
|
|
9323
9337
|
|
|
9338
|
+
// ../shared/dist/agent/generated-images.js
|
|
9339
|
+
var GENERATED_IMAGE_TOOL_NAMES = [
|
|
9340
|
+
"image_generation",
|
|
9341
|
+
"image_generate",
|
|
9342
|
+
"image_gen",
|
|
9343
|
+
"imagegen",
|
|
9344
|
+
"generate_image",
|
|
9345
|
+
"generate_images",
|
|
9346
|
+
"edit_image",
|
|
9347
|
+
"edit_images",
|
|
9348
|
+
"image_edit",
|
|
9349
|
+
"images_edit",
|
|
9350
|
+
"text_to_image",
|
|
9351
|
+
"images_generate"
|
|
9352
|
+
];
|
|
9353
|
+
var BROWSER_SCREENSHOT_TOOL_NAMES = [
|
|
9354
|
+
"agent_browser_screenshot",
|
|
9355
|
+
"agent_browser_take_screenshot",
|
|
9356
|
+
"agent_browser_capture_screenshot",
|
|
9357
|
+
"browser_screenshot",
|
|
9358
|
+
"browser_take_screenshot",
|
|
9359
|
+
"browser_capture_screenshot",
|
|
9360
|
+
"screenshot"
|
|
9361
|
+
];
|
|
9362
|
+
var BROWSER_RECORDING_TOOL_NAMES = [
|
|
9363
|
+
"agent_browser_record",
|
|
9364
|
+
"agent_browser_recording",
|
|
9365
|
+
"agent_browser_video",
|
|
9366
|
+
"agent_browser_capture_video",
|
|
9367
|
+
"agent_browser_screen_recording",
|
|
9368
|
+
"browser_record",
|
|
9369
|
+
"browser_recording",
|
|
9370
|
+
"browser_video",
|
|
9371
|
+
"browser_capture_video",
|
|
9372
|
+
"browser_screen_recording"
|
|
9373
|
+
];
|
|
9374
|
+
function normalizeToolName(toolName) {
|
|
9375
|
+
return toolName?.toLowerCase().replace(/[^a-z0-9]+/g, "_") ?? "";
|
|
9376
|
+
}
|
|
9377
|
+
function isGeneratedImageToolName(toolName) {
|
|
9378
|
+
const normalized = normalizeToolName(toolName);
|
|
9379
|
+
if (!normalized)
|
|
9380
|
+
return false;
|
|
9381
|
+
return GENERATED_IMAGE_TOOL_NAMES.some((token) => normalized.includes(token));
|
|
9382
|
+
}
|
|
9383
|
+
function isBrowserScreenshotToolName(toolName) {
|
|
9384
|
+
const normalized = normalizeToolName(toolName);
|
|
9385
|
+
if (!normalized)
|
|
9386
|
+
return false;
|
|
9387
|
+
return BROWSER_SCREENSHOT_TOOL_NAMES.some((token) => normalized === token || normalized.endsWith(`_${token}`));
|
|
9388
|
+
}
|
|
9389
|
+
function isBrowserRecordingToolName(toolName) {
|
|
9390
|
+
const normalized = normalizeToolName(toolName);
|
|
9391
|
+
if (!normalized)
|
|
9392
|
+
return false;
|
|
9393
|
+
return BROWSER_RECORDING_TOOL_NAMES.some((token) => normalized === token || normalized.endsWith(`_${token}`));
|
|
9394
|
+
}
|
|
9395
|
+
|
|
9324
9396
|
// ../shared/dist/agent/session-result.js
|
|
9325
9397
|
var SESSION_RESUME_FAILED_MESSAGE = "Session resume failed. The previous session may have expired or is no longer available. Please start a new session.";
|
|
9326
9398
|
|
|
@@ -9621,6 +9693,12 @@ var import_path3 = require("path");
|
|
|
9621
9693
|
var import_fs4 = require("fs");
|
|
9622
9694
|
var import_os4 = require("os");
|
|
9623
9695
|
var import_path4 = require("path");
|
|
9696
|
+
var import_fs5 = require("fs");
|
|
9697
|
+
var import_os5 = require("os");
|
|
9698
|
+
var import_path5 = require("path");
|
|
9699
|
+
var import_crypto2 = require("crypto");
|
|
9700
|
+
var import_fs6 = require("fs");
|
|
9701
|
+
var import_path6 = require("path");
|
|
9624
9702
|
function shouldUseReadOnlyRuntimePermissions(config) {
|
|
9625
9703
|
if (isReadOnlyAgent(config.agentId)) return true;
|
|
9626
9704
|
switch (config.mode) {
|
|
@@ -9761,8 +9839,7 @@ function createGenericCliBackend(options) {
|
|
|
9761
9839
|
const state = {
|
|
9762
9840
|
process: null,
|
|
9763
9841
|
iterations: 0,
|
|
9764
|
-
summary: ""
|
|
9765
|
-
allowContinuation: options.allowContinuation ?? false
|
|
9842
|
+
summary: ""
|
|
9766
9843
|
};
|
|
9767
9844
|
const prompt = options.augmentPrompt?.(context) ?? (context.config.mode === "plan" ? buildPlanModePrefix(buildPromptWithSystem(context.config, context.promptText)) : buildPromptWithSystem(context.config, context.promptText));
|
|
9768
9845
|
const args = options.buildArgs?.(context, prompt) ?? options.args.map((arg) => arg === "{{prompt}}" ? prompt : arg);
|
|
@@ -9819,12 +9896,13 @@ function createGenericCliBackend(options) {
|
|
|
9819
9896
|
}
|
|
9820
9897
|
});
|
|
9821
9898
|
let exitCode;
|
|
9899
|
+
let idleTimedOut = false;
|
|
9822
9900
|
try {
|
|
9823
|
-
const exitPromise = new Promise((
|
|
9901
|
+
const exitPromise = new Promise((resolve22, reject) => {
|
|
9824
9902
|
child.on("error", (error) => {
|
|
9825
9903
|
reject(formatCliSpawnError(options.command, error));
|
|
9826
9904
|
});
|
|
9827
|
-
child.on("exit", (code) =>
|
|
9905
|
+
child.on("exit", (code) => resolve22(code ?? 0));
|
|
9828
9906
|
const onAbort = () => {
|
|
9829
9907
|
const pid = child.pid;
|
|
9830
9908
|
if (!pid) return;
|
|
@@ -9840,53 +9918,67 @@ function createGenericCliBackend(options) {
|
|
|
9840
9918
|
context.abortController.signal.addEventListener("abort", onAbort, { once: true });
|
|
9841
9919
|
});
|
|
9842
9920
|
if (options.keepStdinOpen) {
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9921
|
+
const resultPromise = new Promise((resolve22) => {
|
|
9922
|
+
state.onResultReceived = () => resolve22("result_received");
|
|
9923
|
+
if (state.resultReceived) resolve22("result_received");
|
|
9924
|
+
});
|
|
9925
|
+
const IDLE_MS = options.resultIdleTimeoutMs ?? 10 * 60 * 1e3;
|
|
9926
|
+
let idleTimer = null;
|
|
9927
|
+
const idlePromise = new Promise((resolve22) => {
|
|
9928
|
+
const armIdleTimer = () => {
|
|
9847
9929
|
if (idleTimer) clearTimeout(idleTimer);
|
|
9848
9930
|
idleTimer = setTimeout(() => {
|
|
9849
|
-
if (
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
);
|
|
9931
|
+
if (presenter.pendingAskUserToolIds?.size) {
|
|
9932
|
+
resolve22("idle_timeout");
|
|
9933
|
+
} else {
|
|
9934
|
+
armIdleTimer();
|
|
9854
9935
|
}
|
|
9855
9936
|
}, IDLE_MS);
|
|
9856
9937
|
};
|
|
9857
|
-
state.onNewOutput =
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
9938
|
+
state.onNewOutput = armIdleTimer;
|
|
9939
|
+
armIdleTimer();
|
|
9940
|
+
});
|
|
9941
|
+
const raceResult = await Promise.race([exitPromise, resultPromise, idlePromise]);
|
|
9942
|
+
if (idleTimer) clearTimeout(idleTimer);
|
|
9943
|
+
if (raceResult === "idle_timeout") {
|
|
9944
|
+
idleTimedOut = true;
|
|
9945
|
+
console.warn(
|
|
9946
|
+
`[${options.kind}] Idle timeout (${IDLE_MS}ms) waiting for a pending user answer \u2014 force-killing orphaned process`
|
|
9947
|
+
);
|
|
9948
|
+
try {
|
|
9949
|
+
if (process.platform === "win32") {
|
|
9950
|
+
child.kill("SIGKILL");
|
|
9951
|
+
} else if (child.pid) {
|
|
9952
|
+
process.kill(-child.pid, "SIGKILL");
|
|
9953
|
+
}
|
|
9954
|
+
} catch {
|
|
9955
|
+
}
|
|
9956
|
+
exitCode = await Promise.race([
|
|
9957
|
+
exitPromise,
|
|
9958
|
+
new Promise((resolve22) => setTimeout(() => resolve22(1), 5e3))
|
|
9959
|
+
]);
|
|
9960
|
+
} else if (raceResult === "result_received") {
|
|
9961
|
+
const GRACE_MS = 5e3;
|
|
9962
|
+
const gracedExit = await Promise.race([
|
|
9963
|
+
exitPromise,
|
|
9964
|
+
new Promise((resolve22) => setTimeout(() => resolve22(0), GRACE_MS))
|
|
9965
|
+
]);
|
|
9966
|
+
exitCode = typeof gracedExit === "number" ? gracedExit : 0;
|
|
9967
|
+
if (child.exitCode === null && !child.killed) {
|
|
9968
|
+
console.warn(
|
|
9969
|
+
`[${options.kind}] Process still alive ${GRACE_MS}ms after result event, killing`
|
|
9970
|
+
);
|
|
9971
|
+
try {
|
|
9972
|
+
if (process.platform === "win32") {
|
|
9973
|
+
child.kill("SIGKILL");
|
|
9974
|
+
} else if (child.pid) {
|
|
9975
|
+
process.kill(-child.pid, "SIGKILL");
|
|
9885
9976
|
}
|
|
9977
|
+
} catch {
|
|
9886
9978
|
}
|
|
9887
|
-
} else {
|
|
9888
|
-
exitCode = raceResult;
|
|
9889
9979
|
}
|
|
9980
|
+
} else {
|
|
9981
|
+
exitCode = raceResult;
|
|
9890
9982
|
}
|
|
9891
9983
|
} else {
|
|
9892
9984
|
exitCode = await exitPromise;
|
|
@@ -9910,6 +10002,31 @@ function createGenericCliBackend(options) {
|
|
|
9910
10002
|
usage: state.usage
|
|
9911
10003
|
};
|
|
9912
10004
|
}
|
|
10005
|
+
if (idleTimedOut) {
|
|
10006
|
+
console.error(`[${options.kind}] Process force-killed after idle timeout`, {
|
|
10007
|
+
stderrLines: stderrLines.slice(-10),
|
|
10008
|
+
summaryPreview: state.summary.slice(0, 200),
|
|
10009
|
+
runtimeSessionId: state.runtimeSessionId
|
|
10010
|
+
});
|
|
10011
|
+
await options.afterExit?.(context, state);
|
|
10012
|
+
const hasRenderableTurn2 = state.summary.trim().length > 0 || state.iterations > 0;
|
|
10013
|
+
if (hasRenderableTurn2) {
|
|
10014
|
+
await presenter.onTurnComplete([]);
|
|
10015
|
+
}
|
|
10016
|
+
return {
|
|
10017
|
+
success: false,
|
|
10018
|
+
summary: state.summary.trim() || "Agent execution timed out",
|
|
10019
|
+
filesModified: [],
|
|
10020
|
+
planFilesCreated: [],
|
|
10021
|
+
iterations: Math.max(state.iterations, 1),
|
|
10022
|
+
error: "Agent timed out waiting for your answer to its question \u2014 no response arrived, so the run was stopped. Send your reply as a new message to continue.",
|
|
10023
|
+
providerSessionId: state.runtimeSessionId,
|
|
10024
|
+
runtimeSessionId: state.runtimeSessionId,
|
|
10025
|
+
backendKind: options.kind,
|
|
10026
|
+
supportTier: options.supportTier,
|
|
10027
|
+
usage: state.usage
|
|
10028
|
+
};
|
|
10029
|
+
}
|
|
9913
10030
|
if (exitCode !== 0) {
|
|
9914
10031
|
console.error(`[${options.kind}] Process exited with code ${exitCode}`, {
|
|
9915
10032
|
stderrLines: stderrLines.slice(-10),
|
|
@@ -9982,11 +10099,6 @@ function parseClaudeStructuredLine(line, context, state) {
|
|
|
9982
10099
|
);
|
|
9983
10100
|
break;
|
|
9984
10101
|
}
|
|
9985
|
-
if (state.resultReceived && state.allowContinuation) {
|
|
9986
|
-
console.info("[claude_cli] Continuation turn detected \u2014 restarting presenter");
|
|
9987
|
-
state.resultReceived = false;
|
|
9988
|
-
void presenter.onStart(context.config);
|
|
9989
|
-
}
|
|
9990
10102
|
state.onNewOutput?.();
|
|
9991
10103
|
state.iterations += 1;
|
|
9992
10104
|
const message = typeof parsed.message === "object" && parsed.message !== null ? parsed.message : null;
|
|
@@ -10115,31 +10227,10 @@ function parseClaudeStructuredLine(line, context, state) {
|
|
|
10115
10227
|
break;
|
|
10116
10228
|
}
|
|
10117
10229
|
state.resultReceived = true;
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
filesModified: [],
|
|
10123
|
-
planFilesCreated: [],
|
|
10124
|
-
iterations: Math.max(state.iterations, 1),
|
|
10125
|
-
error: state.error ? classifyCliError(state.error, 0) : void 0,
|
|
10126
|
-
providerSessionId: state.runtimeSessionId,
|
|
10127
|
-
runtimeSessionId: state.runtimeSessionId,
|
|
10128
|
-
backendKind: context.config.backendKind,
|
|
10129
|
-
supportTier: context.config.supportTier,
|
|
10130
|
-
usage: state.usage
|
|
10131
|
-
};
|
|
10132
|
-
void presenter.onComplete(continuationResult);
|
|
10133
|
-
state.onNewOutput?.();
|
|
10134
|
-
console.info(
|
|
10135
|
-
"[claude_cli] Result received in continuation mode \u2014 keeping stdin open for background work"
|
|
10136
|
-
);
|
|
10137
|
-
} else {
|
|
10138
|
-
state.onResultReceived?.();
|
|
10139
|
-
if (state.stdin && !state.stdin.destroyed) {
|
|
10140
|
-
state.stdin.end();
|
|
10141
|
-
console.info("[claude_cli] Closed stdin after result event to signal CLI exit");
|
|
10142
|
-
}
|
|
10230
|
+
state.onResultReceived?.();
|
|
10231
|
+
if (state.stdin && !state.stdin.destroyed) {
|
|
10232
|
+
state.stdin.end();
|
|
10233
|
+
console.info("[claude_cli] Closed stdin after result event to signal CLI exit");
|
|
10143
10234
|
}
|
|
10144
10235
|
break;
|
|
10145
10236
|
}
|
|
@@ -11333,7 +11424,33 @@ function parseGeminiStructuredLine(line, context, state) {
|
|
|
11333
11424
|
break;
|
|
11334
11425
|
}
|
|
11335
11426
|
}
|
|
11336
|
-
function
|
|
11427
|
+
function parseAntigravityLine(line, context, state) {
|
|
11428
|
+
try {
|
|
11429
|
+
JSON.parse(line);
|
|
11430
|
+
parseGeminiStructuredLine(line, context, state);
|
|
11431
|
+
return;
|
|
11432
|
+
} catch {
|
|
11433
|
+
}
|
|
11434
|
+
if (!line.trim()) return;
|
|
11435
|
+
state.iterations = Math.max(state.iterations, 1);
|
|
11436
|
+
state.summary += `${line}
|
|
11437
|
+
`;
|
|
11438
|
+
void context.presenter.onAssistantText(`${line}
|
|
11439
|
+
`);
|
|
11440
|
+
}
|
|
11441
|
+
function buildAntigravityCliArgs(context, prompt, defaultArgs = []) {
|
|
11442
|
+
const args = [];
|
|
11443
|
+
const selectedModel = context.config.selectedModel?.trim();
|
|
11444
|
+
const resumeId = context.config.runtimeSessionId?.trim() || context.config.providerSessionId?.trim();
|
|
11445
|
+
if (selectedModel) args.push("--model", selectedModel);
|
|
11446
|
+
if (resumeId) args.push("--conversation", resumeId);
|
|
11447
|
+
if (!shouldUseReadOnlyRuntimePermissions(context.config)) {
|
|
11448
|
+
args.push("--dangerously-skip-permissions");
|
|
11449
|
+
}
|
|
11450
|
+
args.push("--print-timeout", "10m");
|
|
11451
|
+
return [...args, ...defaultArgs, "-p", prompt];
|
|
11452
|
+
}
|
|
11453
|
+
function createAntigravityCliBackend(command = "agy", defaultArgs = []) {
|
|
11337
11454
|
return {
|
|
11338
11455
|
kind: "gemini_cli",
|
|
11339
11456
|
supportTier: "structured",
|
|
@@ -11348,19 +11465,9 @@ function createGeminiCliBackend(command = "gemini", defaultArgs = []) {
|
|
|
11348
11465
|
supportTier: "structured",
|
|
11349
11466
|
command,
|
|
11350
11467
|
args: [],
|
|
11351
|
-
buildArgs: (ctx) =>
|
|
11352
|
-
const args = ["-p", "", "--output-format", "stream-json"];
|
|
11353
|
-
const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
|
|
11354
|
-
const approvalMode = shouldUseReadOnlyRuntimePermissions(ctx.config) ? "plan" : "yolo";
|
|
11355
|
-
args.push("--approval-mode", approvalMode);
|
|
11356
|
-
if (resumeId) args.push("--resume", resumeId);
|
|
11357
|
-
if (ctx.config.selectedModel?.trim())
|
|
11358
|
-
args.push("--model", ctx.config.selectedModel.trim());
|
|
11359
|
-
return [...args, ...defaultArgs];
|
|
11360
|
-
},
|
|
11361
|
-
promptViaStdin: true,
|
|
11468
|
+
buildArgs: (ctx, prompt) => buildAntigravityCliArgs(ctx, prompt, defaultArgs),
|
|
11362
11469
|
augmentPrompt: (ctx) => buildPromptWithImagePathReferences(ctx, imageFiles),
|
|
11363
|
-
parseStructuredLine:
|
|
11470
|
+
parseStructuredLine: parseAntigravityLine
|
|
11364
11471
|
}).run(context);
|
|
11365
11472
|
} finally {
|
|
11366
11473
|
cleanup();
|
|
@@ -11368,6 +11475,72 @@ function createGeminiCliBackend(command = "gemini", defaultArgs = []) {
|
|
|
11368
11475
|
}
|
|
11369
11476
|
};
|
|
11370
11477
|
}
|
|
11478
|
+
function createGeminiCliBackend(command = "agy", defaultArgs = []) {
|
|
11479
|
+
return createAntigravityCliBackend(command, defaultArgs);
|
|
11480
|
+
}
|
|
11481
|
+
var DEFAULT_SKILL_ROOTS = [
|
|
11482
|
+
(0, import_path4.join)((0, import_os4.homedir)(), ".agents", "skills"),
|
|
11483
|
+
(0, import_path4.join)((0, import_os4.homedir)(), ".claude", "skills"),
|
|
11484
|
+
(0, import_path4.join)((0, import_os4.homedir)(), ".config", "opencode", "skills")
|
|
11485
|
+
];
|
|
11486
|
+
function parseFrontmatter(content) {
|
|
11487
|
+
if (!content.startsWith("---\n")) return {};
|
|
11488
|
+
const end = content.indexOf("\n---", 4);
|
|
11489
|
+
if (end === -1) return {};
|
|
11490
|
+
const result = {};
|
|
11491
|
+
for (const line of content.slice(4, end).split("\n")) {
|
|
11492
|
+
const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line.trim());
|
|
11493
|
+
if (!match) continue;
|
|
11494
|
+
const [, key, rawValue] = match;
|
|
11495
|
+
result[key] = rawValue.replace(/^["']|["']$/g, "").trim();
|
|
11496
|
+
}
|
|
11497
|
+
return result;
|
|
11498
|
+
}
|
|
11499
|
+
function listSkillFiles(root) {
|
|
11500
|
+
if (!(0, import_fs4.existsSync)(root)) return [];
|
|
11501
|
+
const files = [];
|
|
11502
|
+
for (const entry of (0, import_fs4.readdirSync)(root, { withFileTypes: true })) {
|
|
11503
|
+
if (!entry.isDirectory()) continue;
|
|
11504
|
+
const skillPath = (0, import_path4.join)(root, entry.name, "SKILL.md");
|
|
11505
|
+
if ((0, import_fs4.existsSync)(skillPath)) files.push(skillPath);
|
|
11506
|
+
}
|
|
11507
|
+
return files;
|
|
11508
|
+
}
|
|
11509
|
+
function loadInstalledSkills(roots = DEFAULT_SKILL_ROOTS) {
|
|
11510
|
+
const skills = /* @__PURE__ */ new Map();
|
|
11511
|
+
for (const root of roots) {
|
|
11512
|
+
for (const skillPath of listSkillFiles(root)) {
|
|
11513
|
+
try {
|
|
11514
|
+
const frontmatter = parseFrontmatter((0, import_fs4.readFileSync)(skillPath, "utf8"));
|
|
11515
|
+
const name = frontmatter.name;
|
|
11516
|
+
const description = frontmatter.description;
|
|
11517
|
+
if (!name || !description || skills.has(name)) continue;
|
|
11518
|
+
skills.set(name, { name, description, path: skillPath });
|
|
11519
|
+
} catch {
|
|
11520
|
+
}
|
|
11521
|
+
}
|
|
11522
|
+
}
|
|
11523
|
+
return [...skills.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
11524
|
+
}
|
|
11525
|
+
function buildInstalledSkillsPrompt(roots = DEFAULT_SKILL_ROOTS) {
|
|
11526
|
+
const skills = loadInstalledSkills(roots);
|
|
11527
|
+
if (skills.length === 0) return void 0;
|
|
11528
|
+
return [
|
|
11529
|
+
"## Installed Skills",
|
|
11530
|
+
"",
|
|
11531
|
+
"Use an installed skill before improvising when the task matches a skill description.",
|
|
11532
|
+
"",
|
|
11533
|
+
"Protocol:",
|
|
11534
|
+
"1. Match the request against the skill names and descriptions below.",
|
|
11535
|
+
"2. Before acting on a matching skill, read its SKILL.md file completely.",
|
|
11536
|
+
"3. Resolve any referenced files such as references/, scripts/, or assets/ relative to the skill directory.",
|
|
11537
|
+
"4. Use the smallest set of matching skills for the current turn only.",
|
|
11538
|
+
"5. If a named skill is missing or unreadable, say so briefly and continue with the best fallback.",
|
|
11539
|
+
"",
|
|
11540
|
+
"Available skills:",
|
|
11541
|
+
...skills.map((skill) => `- ${skill.name}: ${skill.description} (file: ${skill.path})`)
|
|
11542
|
+
].join("\n");
|
|
11543
|
+
}
|
|
11371
11544
|
var KIMI_RESUME_SESSION_RE = /To resume this session:\s*kimi(?:-cli)?\s+(?:-[rS]|--session|--resume)\s+([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
11372
11545
|
function parseKimiStderrLine(line, state) {
|
|
11373
11546
|
const match = line.match(KIMI_RESUME_SESSION_RE);
|
|
@@ -11470,7 +11643,13 @@ function createKimiCliBackend(command = "kimi-cli", defaultArgs = []) {
|
|
|
11470
11643
|
if (model) args.push("--model", model);
|
|
11471
11644
|
return [...args, ...defaultArgs, "--prompt", prompt];
|
|
11472
11645
|
},
|
|
11473
|
-
augmentPrompt: (ctx) =>
|
|
11646
|
+
augmentPrompt: (ctx) => {
|
|
11647
|
+
const skillPrompt = buildInstalledSkillsPrompt();
|
|
11648
|
+
const promptText = [skillPrompt, ctx.promptText].filter(Boolean).join("\n\n");
|
|
11649
|
+
const basePrompt = buildPromptWithSystem(ctx.config, promptText);
|
|
11650
|
+
const modePrompt = ctx.config.mode === "plan" ? buildPlanModePrefix(basePrompt) : basePrompt;
|
|
11651
|
+
return appendImagePathReferences(modePrompt, imageFiles);
|
|
11652
|
+
},
|
|
11474
11653
|
parseStructuredLine: parseKimiStructuredLine,
|
|
11475
11654
|
parseStderrLine: (line, _ctx, state) => parseKimiStderrLine(line, state)
|
|
11476
11655
|
}).run(context);
|
|
@@ -11813,40 +11992,40 @@ function parseSkillInvocation(text) {
|
|
|
11813
11992
|
function candidateRoots(cwd) {
|
|
11814
11993
|
const roots = [];
|
|
11815
11994
|
if (cwd) {
|
|
11816
|
-
roots.push((0,
|
|
11817
|
-
roots.push((0,
|
|
11818
|
-
roots.push((0,
|
|
11819
|
-
if ((0,
|
|
11995
|
+
roots.push((0, import_path5.join)(cwd, ".agents", "skills"));
|
|
11996
|
+
roots.push((0, import_path5.join)(cwd, ".claude", "skills"));
|
|
11997
|
+
roots.push((0, import_path5.join)(cwd, ".codex", "skills"));
|
|
11998
|
+
if ((0, import_fs5.existsSync)(cwd)) {
|
|
11820
11999
|
let entries = [];
|
|
11821
12000
|
try {
|
|
11822
|
-
entries = (0,
|
|
12001
|
+
entries = (0, import_fs5.readdirSync)(cwd, { withFileTypes: true });
|
|
11823
12002
|
} catch {
|
|
11824
12003
|
}
|
|
11825
12004
|
for (const entry of entries) {
|
|
11826
12005
|
if (!entry.isDirectory()) continue;
|
|
11827
12006
|
if (entry.name.startsWith(".")) continue;
|
|
11828
|
-
const child = (0,
|
|
11829
|
-
roots.push((0,
|
|
11830
|
-
roots.push((0,
|
|
11831
|
-
roots.push((0,
|
|
12007
|
+
const child = (0, import_path5.join)(cwd, entry.name);
|
|
12008
|
+
roots.push((0, import_path5.join)(child, ".agents", "skills"));
|
|
12009
|
+
roots.push((0, import_path5.join)(child, ".claude", "skills"));
|
|
12010
|
+
roots.push((0, import_path5.join)(child, ".codex", "skills"));
|
|
11832
12011
|
}
|
|
11833
12012
|
}
|
|
11834
12013
|
}
|
|
11835
|
-
const home = (0,
|
|
11836
|
-
roots.push((0,
|
|
11837
|
-
roots.push((0,
|
|
11838
|
-
roots.push((0,
|
|
12014
|
+
const home = (0, import_os5.homedir)();
|
|
12015
|
+
roots.push((0, import_path5.join)(home, ".agents", "skills"));
|
|
12016
|
+
roots.push((0, import_path5.join)(home, ".claude", "skills"));
|
|
12017
|
+
roots.push((0, import_path5.join)(home, ".codex", "skills"));
|
|
11839
12018
|
return Array.from(new Set(roots));
|
|
11840
12019
|
}
|
|
11841
12020
|
function resolveSkillInvocation(text, cwd) {
|
|
11842
12021
|
const parsed = parseSkillInvocation(text);
|
|
11843
12022
|
if (!parsed) return null;
|
|
11844
12023
|
for (const root of candidateRoots(cwd)) {
|
|
11845
|
-
const skillPath = (0,
|
|
11846
|
-
if (!(0,
|
|
12024
|
+
const skillPath = (0, import_path5.join)(root, parsed.command, "SKILL.md");
|
|
12025
|
+
if (!(0, import_fs5.existsSync)(skillPath)) continue;
|
|
11847
12026
|
let content;
|
|
11848
12027
|
try {
|
|
11849
|
-
content = (0,
|
|
12028
|
+
content = (0, import_fs5.readFileSync)(skillPath, "utf-8");
|
|
11850
12029
|
} catch {
|
|
11851
12030
|
continue;
|
|
11852
12031
|
}
|
|
@@ -11895,6 +12074,8 @@ function defaultSelectedModelForBackend(backendKind) {
|
|
|
11895
12074
|
return void 0;
|
|
11896
12075
|
case "opencode_cli":
|
|
11897
12076
|
return void 0;
|
|
12077
|
+
case "gemini_cli":
|
|
12078
|
+
return void 0;
|
|
11898
12079
|
case "supatest_cli":
|
|
11899
12080
|
return "medium";
|
|
11900
12081
|
default:
|
|
@@ -12096,7 +12277,7 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12096
12277
|
const promptText = this.buildPromptText(runtimeConfig);
|
|
12097
12278
|
const runtimeCommand = runtimeConfig.runtimeCommand || this.runtime.runtimeCommand;
|
|
12098
12279
|
const runtimeArgs = runtimeConfig.runtimeArgs || this.runtime.runtimeArgs || [];
|
|
12099
|
-
const backend = backendKind === "claude_cli" ? createClaudeCliBackend(runtimeCommand || "claude", runtimeArgs) : backendKind === "codex_app_server" ? createCodexRuntimeBackend(runtimeCommand || "codex", runtimeArgs) : backendKind === "copilot_cli" ? createCopilotCliBackend(runtimeCommand || "copilot", runtimeArgs) : backendKind === "cursor_agent_cli" ? createCursorAgentCliBackend(runtimeCommand || "cursor-agent", runtimeArgs) : backendKind === "gemini_cli" ? createGeminiCliBackend(runtimeCommand || "
|
|
12280
|
+
const backend = backendKind === "claude_cli" ? createClaudeCliBackend(runtimeCommand || "claude", runtimeArgs) : backendKind === "codex_app_server" ? createCodexRuntimeBackend(runtimeCommand || "codex", runtimeArgs) : backendKind === "copilot_cli" ? createCopilotCliBackend(runtimeCommand || "copilot", runtimeArgs) : backendKind === "cursor_agent_cli" ? createCursorAgentCliBackend(runtimeCommand || "cursor-agent", runtimeArgs) : backendKind === "gemini_cli" ? createGeminiCliBackend(runtimeCommand || "agy", runtimeArgs) : backendKind === "droid_cli" ? createDroidCliBackend(runtimeCommand || "droid", runtimeArgs) : backendKind === "opencode_cli" ? createOpencodeCliBackend(runtimeCommand || "opencode", runtimeArgs) : backendKind === "kimi_cli" ? createKimiCliBackend(runtimeCommand || "kimi-cli", runtimeArgs) : backendKind === "supatest_cli" ? createSupatestCliBackend(runtimeCommand || "supatest", runtimeArgs) : createGenericCliPassthroughBackend(
|
|
12100
12281
|
runtimeCommand || "generic-cli",
|
|
12101
12282
|
runtimeArgs
|
|
12102
12283
|
);
|
|
@@ -12162,18 +12343,18 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12162
12343
|
`[base-machine-agent] Transient error (attempt ${attempt + 1}/${_BaseMachineAgent.MAX_RETRIES + 1}), retrying in ${delayMs}ms: ${lastResult.error}`
|
|
12163
12344
|
);
|
|
12164
12345
|
void this.presenter.onLog(`Transient error, retrying in ${Math.round(delayMs / 1e3)}s...`);
|
|
12165
|
-
await new Promise((
|
|
12346
|
+
await new Promise((resolve22) => {
|
|
12166
12347
|
const signal = this.abortController?.signal;
|
|
12167
12348
|
if (signal?.aborted) {
|
|
12168
|
-
|
|
12349
|
+
resolve22();
|
|
12169
12350
|
return;
|
|
12170
12351
|
}
|
|
12171
|
-
const timeoutId = setTimeout(
|
|
12352
|
+
const timeoutId = setTimeout(resolve22, delayMs);
|
|
12172
12353
|
signal?.addEventListener(
|
|
12173
12354
|
"abort",
|
|
12174
12355
|
() => {
|
|
12175
12356
|
clearTimeout(timeoutId);
|
|
12176
|
-
|
|
12357
|
+
resolve22();
|
|
12177
12358
|
},
|
|
12178
12359
|
{ once: true }
|
|
12179
12360
|
);
|
|
@@ -12243,6 +12424,195 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12243
12424
|
}
|
|
12244
12425
|
}
|
|
12245
12426
|
};
|
|
12427
|
+
var IMAGE_MIME_BY_EXT = {
|
|
12428
|
+
".gif": "image/gif",
|
|
12429
|
+
".jpeg": "image/jpeg",
|
|
12430
|
+
".jpg": "image/jpeg",
|
|
12431
|
+
".png": "image/png",
|
|
12432
|
+
".webp": "image/webp"
|
|
12433
|
+
};
|
|
12434
|
+
var VIDEO_MIME_BY_EXT = {
|
|
12435
|
+
".mov": "video/quicktime",
|
|
12436
|
+
".mp4": "video/mp4",
|
|
12437
|
+
".webm": "video/webm"
|
|
12438
|
+
};
|
|
12439
|
+
var MAX_GENERATED_IMAGE_BYTES = 20 * 1024 * 1024;
|
|
12440
|
+
var MAX_SESSION_VIDEO_BYTES = 100 * 1024 * 1024;
|
|
12441
|
+
function isRecord(value2) {
|
|
12442
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
12443
|
+
}
|
|
12444
|
+
function shouldExtractGeneratedImagesFromToolResult(toolName, content, options = {}) {
|
|
12445
|
+
return isGeneratedImageToolName(toolName) || isBrowserScreenshotToolName(toolName) || isAgentBrowserMediaInvocation(toolName, content, options.toolInput, "image");
|
|
12446
|
+
}
|
|
12447
|
+
function collectStringValues(value2, out) {
|
|
12448
|
+
if (typeof value2 === "string") {
|
|
12449
|
+
out.push(value2);
|
|
12450
|
+
return;
|
|
12451
|
+
}
|
|
12452
|
+
if (Array.isArray(value2)) {
|
|
12453
|
+
for (const item of value2) collectStringValues(item, out);
|
|
12454
|
+
return;
|
|
12455
|
+
}
|
|
12456
|
+
if (!value2 || typeof value2 !== "object") return;
|
|
12457
|
+
for (const entry of Object.values(value2)) {
|
|
12458
|
+
collectStringValues(entry, out);
|
|
12459
|
+
}
|
|
12460
|
+
}
|
|
12461
|
+
function collectContentStrings(content, toolInput) {
|
|
12462
|
+
const values = [];
|
|
12463
|
+
if (content) {
|
|
12464
|
+
values.push(content);
|
|
12465
|
+
try {
|
|
12466
|
+
collectStringValues(JSON.parse(content), values);
|
|
12467
|
+
} catch {
|
|
12468
|
+
}
|
|
12469
|
+
}
|
|
12470
|
+
collectStringValues(toolInput, values);
|
|
12471
|
+
return values;
|
|
12472
|
+
}
|
|
12473
|
+
function isAgentBrowserMediaInvocation(toolName, content, toolInput, kind) {
|
|
12474
|
+
if (kind === "image" && isBrowserScreenshotToolName(toolName)) return true;
|
|
12475
|
+
if (kind === "video" && isBrowserRecordingToolName(toolName)) return true;
|
|
12476
|
+
const haystack = collectContentStrings(content, toolInput).join("\n").toLowerCase();
|
|
12477
|
+
if (!/(^|[^a-z0-9_-])agent[-_]browser([^a-z0-9_-]|$)/.test(haystack)) return false;
|
|
12478
|
+
return kind === "image" ? /\b(screenshot|capture)\b/.test(haystack) : /\b(record|recording|video)\b/.test(haystack);
|
|
12479
|
+
}
|
|
12480
|
+
function extractPathCandidatesFromValues(values, extensionsPattern = "png|jpe?g|gif|webp") {
|
|
12481
|
+
const paths = /* @__PURE__ */ new Set();
|
|
12482
|
+
const filePathPattern = new RegExp(
|
|
12483
|
+
`(?:file:\\/\\/)?(?:~|\\.{1,2}|\\/)?[^\\s"'\`)\\]}<>]+?\\.(?:${extensionsPattern})\\b`,
|
|
12484
|
+
"gi"
|
|
12485
|
+
);
|
|
12486
|
+
for (const value2 of values) {
|
|
12487
|
+
for (const match of value2.matchAll(filePathPattern)) {
|
|
12488
|
+
paths.add(match[0]);
|
|
12489
|
+
}
|
|
12490
|
+
}
|
|
12491
|
+
return [...paths];
|
|
12492
|
+
}
|
|
12493
|
+
function extractPathCandidates(content, options, extensionsPattern = "png|jpe?g|gif|webp") {
|
|
12494
|
+
return [
|
|
12495
|
+
...extractPathCandidatesFromValues(
|
|
12496
|
+
collectContentStrings(content, options.toolInput),
|
|
12497
|
+
extensionsPattern
|
|
12498
|
+
),
|
|
12499
|
+
...options.pathHints ?? []
|
|
12500
|
+
];
|
|
12501
|
+
}
|
|
12502
|
+
function normalizePath(candidate, cwd) {
|
|
12503
|
+
let path = candidate.trim().replace(/^file:\/\//, "");
|
|
12504
|
+
try {
|
|
12505
|
+
path = decodeURI(path);
|
|
12506
|
+
} catch {
|
|
12507
|
+
}
|
|
12508
|
+
if (path.startsWith("~/")) return null;
|
|
12509
|
+
if ((0, import_path6.isAbsolute)(path)) return path;
|
|
12510
|
+
return cwd ? (0, import_path6.join)(cwd, path) : null;
|
|
12511
|
+
}
|
|
12512
|
+
function resolveToolCwd(cwd, toolInput) {
|
|
12513
|
+
if (!isRecord(toolInput)) return cwd;
|
|
12514
|
+
const raw = typeof toolInput.cwd === "string" ? toolInput.cwd : typeof toolInput.workdir === "string" ? toolInput.workdir : typeof toolInput.workingDirectory === "string" ? toolInput.workingDirectory : null;
|
|
12515
|
+
if (!raw) return cwd;
|
|
12516
|
+
return (0, import_path6.isAbsolute)(raw) || !cwd ? raw : (0, import_path6.join)(cwd, raw);
|
|
12517
|
+
}
|
|
12518
|
+
function extractBrowserMediaPathHints(content, cwd, toolName, options = {}, kind = "video") {
|
|
12519
|
+
if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, kind)) return [];
|
|
12520
|
+
const extensionsPattern = kind === "video" ? "mp4|webm|mov" : "png|jpe?g|gif|webp";
|
|
12521
|
+
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
12522
|
+
return extractPathCandidatesFromValues(
|
|
12523
|
+
collectContentStrings(content, options.toolInput),
|
|
12524
|
+
extensionsPattern
|
|
12525
|
+
).map((candidate) => normalizePath(candidate, effectiveCwd)).filter((path) => Boolean(path));
|
|
12526
|
+
}
|
|
12527
|
+
function readImageDimensions2(buffer, mimeType) {
|
|
12528
|
+
if (mimeType === "image/png" && buffer.length >= 24 && buffer.toString("ascii", 1, 4) === "PNG") {
|
|
12529
|
+
return { width: buffer.readUInt32BE(16), height: buffer.readUInt32BE(20) };
|
|
12530
|
+
}
|
|
12531
|
+
if (mimeType === "image/gif" && buffer.length >= 10 && buffer.toString("ascii", 0, 3) === "GIF") {
|
|
12532
|
+
return { width: buffer.readUInt16LE(6), height: buffer.readUInt16LE(8) };
|
|
12533
|
+
}
|
|
12534
|
+
if (mimeType === "image/jpeg" && buffer.length > 4) {
|
|
12535
|
+
let offset = 2;
|
|
12536
|
+
while (offset + 9 < buffer.length) {
|
|
12537
|
+
if (buffer[offset] !== 255) break;
|
|
12538
|
+
const marker = buffer[offset + 1];
|
|
12539
|
+
const length = buffer.readUInt16BE(offset + 2);
|
|
12540
|
+
if (length < 2) break;
|
|
12541
|
+
if (marker >= 192 && marker <= 207 && ![196, 200, 204].includes(marker)) {
|
|
12542
|
+
return {
|
|
12543
|
+
width: buffer.readUInt16BE(offset + 7),
|
|
12544
|
+
height: buffer.readUInt16BE(offset + 5)
|
|
12545
|
+
};
|
|
12546
|
+
}
|
|
12547
|
+
offset += 2 + length;
|
|
12548
|
+
}
|
|
12549
|
+
}
|
|
12550
|
+
return { width: null, height: null };
|
|
12551
|
+
}
|
|
12552
|
+
function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, options = {}) {
|
|
12553
|
+
if (!shouldExtractGeneratedImagesFromToolResult(toolName, content, options)) return [];
|
|
12554
|
+
const images = [];
|
|
12555
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12556
|
+
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
12557
|
+
for (const candidate of extractPathCandidates(content, options)) {
|
|
12558
|
+
const path = normalizePath(candidate, effectiveCwd);
|
|
12559
|
+
if (!path || seen.has(path) || !(0, import_fs6.existsSync)(path)) continue;
|
|
12560
|
+
seen.add(path);
|
|
12561
|
+
const ext = (0, import_path6.extname)(path).toLowerCase();
|
|
12562
|
+
const mimeType = IMAGE_MIME_BY_EXT[ext];
|
|
12563
|
+
if (!mimeType) continue;
|
|
12564
|
+
const stat = (0, import_fs6.statSync)(path);
|
|
12565
|
+
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
|
|
12566
|
+
const buffer = (0, import_fs6.readFileSync)(path);
|
|
12567
|
+
const { width, height } = readImageDimensions2(buffer, mimeType);
|
|
12568
|
+
images.push({
|
|
12569
|
+
type: "generated_image",
|
|
12570
|
+
id: (0, import_crypto2.randomUUID)(),
|
|
12571
|
+
filename: (0, import_path6.basename)(path),
|
|
12572
|
+
mimeType,
|
|
12573
|
+
size: buffer.length,
|
|
12574
|
+
width,
|
|
12575
|
+
height,
|
|
12576
|
+
data: buffer.toString("base64"),
|
|
12577
|
+
sourcePath: path,
|
|
12578
|
+
sourceHash: (0, import_crypto2.createHash)("sha256").update(buffer).digest("hex"),
|
|
12579
|
+
toolId,
|
|
12580
|
+
ts: Date.now()
|
|
12581
|
+
});
|
|
12582
|
+
}
|
|
12583
|
+
return images;
|
|
12584
|
+
}
|
|
12585
|
+
function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, options = {}) {
|
|
12586
|
+
if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, "video")) return [];
|
|
12587
|
+
const media = [];
|
|
12588
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12589
|
+
const effectiveCwd = resolveToolCwd(cwd, options.toolInput);
|
|
12590
|
+
for (const candidate of extractPathCandidates(content, options, "mp4|webm|mov")) {
|
|
12591
|
+
const path = normalizePath(candidate, effectiveCwd);
|
|
12592
|
+
if (!path || seen.has(path) || !(0, import_fs6.existsSync)(path)) continue;
|
|
12593
|
+
seen.add(path);
|
|
12594
|
+
const ext = (0, import_path6.extname)(path).toLowerCase();
|
|
12595
|
+
const mimeType = VIDEO_MIME_BY_EXT[ext];
|
|
12596
|
+
if (!mimeType) continue;
|
|
12597
|
+
const stat = (0, import_fs6.statSync)(path);
|
|
12598
|
+
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_SESSION_VIDEO_BYTES) continue;
|
|
12599
|
+
const buffer = (0, import_fs6.readFileSync)(path);
|
|
12600
|
+
media.push({
|
|
12601
|
+
type: "session_media",
|
|
12602
|
+
kind: "video",
|
|
12603
|
+
id: (0, import_crypto2.randomUUID)(),
|
|
12604
|
+
filename: (0, import_path6.basename)(path),
|
|
12605
|
+
mimeType,
|
|
12606
|
+
size: buffer.length,
|
|
12607
|
+
data: buffer.toString("base64"),
|
|
12608
|
+
sourcePath: path,
|
|
12609
|
+
sourceHash: (0, import_crypto2.createHash)("sha256").update(buffer).digest("hex"),
|
|
12610
|
+
toolId,
|
|
12611
|
+
ts: Date.now()
|
|
12612
|
+
});
|
|
12613
|
+
}
|
|
12614
|
+
return media;
|
|
12615
|
+
}
|
|
12246
12616
|
|
|
12247
12617
|
// src/core-agent.ts
|
|
12248
12618
|
var CoreAgent = class _CoreAgent extends BaseMachineAgent {
|
|
@@ -12541,149 +12911,162 @@ ${meta.description}`);
|
|
|
12541
12911
|
}
|
|
12542
12912
|
};
|
|
12543
12913
|
|
|
12544
|
-
// src/
|
|
12545
|
-
var
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
var
|
|
12549
|
-
"
|
|
12550
|
-
"
|
|
12551
|
-
"
|
|
12552
|
-
".
|
|
12553
|
-
"
|
|
12554
|
-
|
|
12555
|
-
var
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
"edit_image",
|
|
12565
|
-
"text_to_image",
|
|
12566
|
-
"images_generate"
|
|
12567
|
-
].some((token) => normalized.includes(token));
|
|
12568
|
-
}
|
|
12569
|
-
function shouldExtractGeneratedImagesFromToolResult(toolName) {
|
|
12570
|
-
return isGeneratedImageToolName(toolName);
|
|
12571
|
-
}
|
|
12572
|
-
function collectStringValues(value2, out) {
|
|
12573
|
-
if (typeof value2 === "string") {
|
|
12574
|
-
out.push(value2);
|
|
12575
|
-
return;
|
|
12576
|
-
}
|
|
12577
|
-
if (Array.isArray(value2)) {
|
|
12578
|
-
for (const item of value2) collectStringValues(item, out);
|
|
12579
|
-
return;
|
|
12914
|
+
// src/version.ts
|
|
12915
|
+
var AGENT_VERSION = "0.1.27";
|
|
12916
|
+
|
|
12917
|
+
// src/daemon.ts
|
|
12918
|
+
var OPENCODE_FREE_MODEL_IDS = [
|
|
12919
|
+
"opencode/north-mini-code-free",
|
|
12920
|
+
"opencode/nemotron-3-ultra-free",
|
|
12921
|
+
"opencode/deepseek-v4-flash-free",
|
|
12922
|
+
"opencode/mimo-v2.5-free",
|
|
12923
|
+
"opencode/big-pickle"
|
|
12924
|
+
];
|
|
12925
|
+
var MODEL_DISCOVERY_TIMEOUT_MS = 15e3;
|
|
12926
|
+
var PRODUCTION_API_URL = "https://api.aiden-platform.com";
|
|
12927
|
+
var PRODUCTION_WS_URL = "wss://ws.aiden-platform.com";
|
|
12928
|
+
var LOCAL_API_URL = "http://localhost:8400";
|
|
12929
|
+
var LOCAL_WS_URL = "ws://localhost:8401";
|
|
12930
|
+
function requiredString(params, key) {
|
|
12931
|
+
const value2 = params[key];
|
|
12932
|
+
if (typeof value2 !== "string" || value2.trim() === "") {
|
|
12933
|
+
throw new Error(`${key} is required`);
|
|
12580
12934
|
}
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12935
|
+
return value2;
|
|
12936
|
+
}
|
|
12937
|
+
function assertValidGitRef(ref, label) {
|
|
12938
|
+
if (!ref || ref.startsWith("-") || ref.includes("\0")) {
|
|
12939
|
+
throw new Error(`${label} is not a safe git ref`);
|
|
12584
12940
|
}
|
|
12941
|
+
const result = (0, import_node_child_process3.spawnSync)("git", ["check-ref-format", "--branch", ref], {
|
|
12942
|
+
env: getDaemonCliEnvironment(),
|
|
12943
|
+
encoding: "utf8"
|
|
12944
|
+
});
|
|
12945
|
+
if (result.status !== 0) throw new Error(`${label} is not a valid git ref`);
|
|
12585
12946
|
}
|
|
12586
|
-
function
|
|
12587
|
-
const
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12947
|
+
function isPathContained(childPath, parentPath) {
|
|
12948
|
+
const rel = (0, import_node_path3.relative)((0, import_node_path3.resolve)(parentPath), (0, import_node_path3.resolve)(childPath));
|
|
12949
|
+
return rel === "" || !(0, import_node_path3.isAbsolute)(rel) && rel !== ".." && !rel.startsWith(`..${import_node_path3.sep}`);
|
|
12950
|
+
}
|
|
12951
|
+
function assertPathContained(childPath, parentPath, label) {
|
|
12952
|
+
if (!isPathContained(childPath, parentPath)) {
|
|
12953
|
+
throw new Error(`${label} escapes allowed directory`);
|
|
12591
12954
|
}
|
|
12592
|
-
return values;
|
|
12593
12955
|
}
|
|
12594
|
-
function
|
|
12595
|
-
const
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12956
|
+
function git(cwd, args) {
|
|
12957
|
+
const result = (0, import_node_child_process3.spawnSync)("git", args, {
|
|
12958
|
+
cwd,
|
|
12959
|
+
env: getDaemonCliEnvironment(),
|
|
12960
|
+
encoding: "utf8",
|
|
12961
|
+
maxBuffer: 10 * 1024 * 1024
|
|
12962
|
+
});
|
|
12963
|
+
if (result.status !== 0) {
|
|
12964
|
+
throw new Error((result.stderr || result.stdout || "git command failed").trim());
|
|
12601
12965
|
}
|
|
12602
|
-
return
|
|
12966
|
+
return result.stdout.trim();
|
|
12603
12967
|
}
|
|
12604
|
-
function
|
|
12605
|
-
let path = candidate.trim().replace(/^file:\/\//, "");
|
|
12968
|
+
function gitSafe(cwd, args) {
|
|
12606
12969
|
try {
|
|
12607
|
-
|
|
12970
|
+
return git(cwd, args);
|
|
12608
12971
|
} catch {
|
|
12972
|
+
return "";
|
|
12609
12973
|
}
|
|
12610
|
-
if (path.startsWith("~/")) return null;
|
|
12611
|
-
if ((0, import_node_path3.isAbsolute)(path)) return path;
|
|
12612
|
-
return cwd ? (0, import_node_path3.join)(cwd, path) : null;
|
|
12613
12974
|
}
|
|
12614
|
-
function
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
12975
|
+
function worktreeDir(projectPath) {
|
|
12976
|
+
const resolved = (0, import_node_path3.resolve)(projectPath);
|
|
12977
|
+
return (0, import_node_path3.join)((0, import_node_path3.dirname)(resolved), `${(0, import_node_path3.basename)(resolved)}-aiden-worktrees`);
|
|
12978
|
+
}
|
|
12979
|
+
function pathSegment(value2) {
|
|
12980
|
+
return value2.toLowerCase().replace(/^aiden\//, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "task";
|
|
12981
|
+
}
|
|
12982
|
+
function repoName(repoUrl, localPath) {
|
|
12983
|
+
return repoUrl.replace(/\.git$/, "").split("/").pop() || (0, import_node_path3.basename)(localPath) || "repo";
|
|
12984
|
+
}
|
|
12985
|
+
function findWorktreeByBranch(repoPath, branchName) {
|
|
12986
|
+
const output = gitSafe(repoPath, ["worktree", "list", "--porcelain"]);
|
|
12987
|
+
const entries = output ? output.split("\n\n") : [];
|
|
12988
|
+
for (const entry of entries) {
|
|
12989
|
+
const lines = entry.split("\n");
|
|
12990
|
+
const path = lines.find((line) => line.startsWith("worktree "))?.slice("worktree ".length);
|
|
12991
|
+
const branch = lines.find((line) => line.startsWith("branch "))?.slice("branch ".length).replace("refs/heads/", "");
|
|
12992
|
+
if (path && branch === branchName) return path;
|
|
12620
12993
|
}
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12994
|
+
return null;
|
|
12995
|
+
}
|
|
12996
|
+
function ensureGitWorktree(input) {
|
|
12997
|
+
assertValidGitRef(input.branchName, "branchName");
|
|
12998
|
+
assertValidGitRef(input.baseBranch, "baseBranch");
|
|
12999
|
+
const repoPath = (0, import_node_path3.resolve)(input.repoPath);
|
|
13000
|
+
const root = input.allowedRoot ?? worktreeDir(repoPath);
|
|
13001
|
+
const existingPath = findWorktreeByBranch(input.repoPath, input.branchName);
|
|
13002
|
+
if (existingPath) {
|
|
13003
|
+
if ((0, import_node_path3.resolve)(existingPath) === repoPath) {
|
|
13004
|
+
throw new Error(`${input.branchName} is checked out in the shared checkout`);
|
|
13005
|
+
}
|
|
13006
|
+
return existingPath;
|
|
13007
|
+
}
|
|
13008
|
+
assertPathContained(input.worktreePath, root, "worktreePath");
|
|
13009
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path3.dirname)(input.worktreePath), { recursive: true });
|
|
13010
|
+
if (!gitSafe(input.repoPath, ["branch", "--list", input.branchName])) {
|
|
13011
|
+
git(input.repoPath, ["branch", input.branchName, input.baseBranch]);
|
|
13012
|
+
}
|
|
13013
|
+
if ((0, import_node_fs3.existsSync)(input.worktreePath)) {
|
|
13014
|
+
if (gitSafe(input.worktreePath, ["branch", "--show-current"]) === input.branchName) {
|
|
13015
|
+
return input.worktreePath;
|
|
13016
|
+
}
|
|
13017
|
+
throw new Error("worktree path already exists for a different checkout");
|
|
13018
|
+
}
|
|
13019
|
+
git(input.repoPath, ["worktree", "add", input.worktreePath, input.branchName]);
|
|
13020
|
+
return input.worktreePath;
|
|
13021
|
+
}
|
|
13022
|
+
function ensureWorktree(params) {
|
|
13023
|
+
const input = {
|
|
13024
|
+
projectPath: requiredString(params, "projectPath"),
|
|
13025
|
+
taskId: requiredString(params, "taskId"),
|
|
13026
|
+
branchName: requiredString(params, "branchName"),
|
|
13027
|
+
baseBranch: typeof params.baseBranch === "string" ? params.baseBranch : "main",
|
|
13028
|
+
repoLocalPaths: Array.isArray(params.repoLocalPaths) ? params.repoLocalPaths : []
|
|
13029
|
+
};
|
|
13030
|
+
const taskRoot = (0, import_node_path3.join)(
|
|
13031
|
+
worktreeDir(input.projectPath),
|
|
13032
|
+
`${pathSegment(input.branchName)}-${input.taskId.slice(0, 8)}`
|
|
13033
|
+
);
|
|
13034
|
+
if (input.repoLocalPaths?.length) {
|
|
13035
|
+
return {
|
|
13036
|
+
worktrees: input.repoLocalPaths.map((repo) => {
|
|
13037
|
+
const baseBranch = repo.branch || input.baseBranch || "main";
|
|
13038
|
+
const worktreePath2 = ensureGitWorktree({
|
|
13039
|
+
repoPath: repo.localPath,
|
|
13040
|
+
worktreePath: (0, import_node_path3.join)(taskRoot, pathSegment(repoName(repo.repoUrl, repo.localPath))),
|
|
13041
|
+
branchName: input.branchName,
|
|
13042
|
+
baseBranch,
|
|
13043
|
+
allowedRoot: worktreeDir(input.projectPath)
|
|
13044
|
+
});
|
|
12629
13045
|
return {
|
|
12630
|
-
|
|
12631
|
-
|
|
13046
|
+
repoId: repo.repoId ?? null,
|
|
13047
|
+
repoUrl: repo.repoUrl,
|
|
13048
|
+
worktreePath: worktreePath2,
|
|
13049
|
+
branchName: input.branchName,
|
|
13050
|
+
baseBranch
|
|
12632
13051
|
};
|
|
12633
|
-
}
|
|
12634
|
-
|
|
12635
|
-
}
|
|
13052
|
+
})
|
|
13053
|
+
};
|
|
12636
13054
|
}
|
|
12637
|
-
|
|
13055
|
+
const worktreePath = ensureGitWorktree({
|
|
13056
|
+
repoPath: input.projectPath,
|
|
13057
|
+
worktreePath: taskRoot,
|
|
13058
|
+
branchName: input.branchName,
|
|
13059
|
+
baseBranch: input.baseBranch
|
|
13060
|
+
});
|
|
13061
|
+
return {
|
|
13062
|
+
worktrees: [{ worktreePath, branchName: input.branchName, baseBranch: input.baseBranch }]
|
|
13063
|
+
};
|
|
12638
13064
|
}
|
|
12639
|
-
function
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
for (const candidate of extractPathCandidates(content)) {
|
|
12644
|
-
const path = normalizePath(candidate, cwd);
|
|
12645
|
-
if (!path || seen.has(path) || !(0, import_node_fs3.existsSync)(path)) continue;
|
|
12646
|
-
seen.add(path);
|
|
12647
|
-
const ext = (0, import_node_path3.extname)(path).toLowerCase();
|
|
12648
|
-
const mimeType = IMAGE_MIME_BY_EXT[ext];
|
|
12649
|
-
if (!mimeType) continue;
|
|
12650
|
-
const stat = (0, import_node_fs3.statSync)(path);
|
|
12651
|
-
if (!stat.isFile() || stat.size <= 0 || stat.size > MAX_GENERATED_IMAGE_BYTES) continue;
|
|
12652
|
-
const buffer = (0, import_node_fs3.readFileSync)(path);
|
|
12653
|
-
const { width, height } = readImageDimensions2(buffer, mimeType);
|
|
12654
|
-
images.push({
|
|
12655
|
-
type: "generated_image",
|
|
12656
|
-
id: (0, import_node_crypto.randomUUID)(),
|
|
12657
|
-
filename: (0, import_node_path3.basename)(path),
|
|
12658
|
-
mimeType,
|
|
12659
|
-
size: buffer.length,
|
|
12660
|
-
width,
|
|
12661
|
-
height,
|
|
12662
|
-
data: buffer.toString("base64"),
|
|
12663
|
-
sourcePath: path,
|
|
12664
|
-
sourceHash: (0, import_node_crypto.createHash)("sha256").update(buffer).digest("hex"),
|
|
12665
|
-
toolId,
|
|
12666
|
-
ts: Date.now()
|
|
12667
|
-
});
|
|
12668
|
-
}
|
|
12669
|
-
return images;
|
|
13065
|
+
function resolveRuntimeCwd(payload) {
|
|
13066
|
+
const multiRepoWorktree = payload.worktreeInfo?.allWorktrees?.[0]?.worktreePath;
|
|
13067
|
+
if (multiRepoWorktree) return (0, import_node_path3.dirname)(multiRepoWorktree);
|
|
13068
|
+
return payload.worktreeInfo?.worktreePath ?? payload.projectPath ?? process.cwd();
|
|
12670
13069
|
}
|
|
12671
|
-
|
|
12672
|
-
// src/version.ts
|
|
12673
|
-
var AGENT_VERSION = "0.1.26";
|
|
12674
|
-
|
|
12675
|
-
// src/daemon.ts
|
|
12676
|
-
var OPENCODE_FREE_MODEL_IDS = [
|
|
12677
|
-
"opencode/north-mini-code-free",
|
|
12678
|
-
"opencode/nemotron-3-ultra-free",
|
|
12679
|
-
"opencode/deepseek-v4-flash-free",
|
|
12680
|
-
"opencode/mimo-v2.5-free",
|
|
12681
|
-
"opencode/big-pickle"
|
|
12682
|
-
];
|
|
12683
|
-
var PRODUCTION_API_URL = "https://api.aiden-platform.com";
|
|
12684
|
-
var PRODUCTION_WS_URL = "wss://ws.aiden-platform.com";
|
|
12685
|
-
var LOCAL_API_URL = "http://localhost:8400";
|
|
12686
|
-
var LOCAL_WS_URL = "ws://localhost:8401";
|
|
12687
13070
|
function correlationLogFields(input) {
|
|
12688
13071
|
return Object.fromEntries(
|
|
12689
13072
|
Object.entries({
|
|
@@ -12722,33 +13105,33 @@ function describeOccupiedLocalDaemon(port) {
|
|
|
12722
13105
|
return `local daemon API port ${port} is already in use. If Aiden desktop is open, it manages the daemon automatically. Quit Aiden desktop or stop the existing daemon before starting another.`;
|
|
12723
13106
|
}
|
|
12724
13107
|
function getConfigPath() {
|
|
12725
|
-
return process.env.AIDEN_AGENT_CONFIG_PATH ?? (0,
|
|
13108
|
+
return process.env.AIDEN_AGENT_CONFIG_PATH ?? (0, import_node_path3.join)((0, import_node_os4.homedir)(), ".aiden", "agent", "config.json");
|
|
12726
13109
|
}
|
|
12727
13110
|
function getEndpointDefaultsPath() {
|
|
12728
|
-
return process.env.AIDEN_AGENT_ENDPOINTS_PATH ?? (0,
|
|
13111
|
+
return process.env.AIDEN_AGENT_ENDPOINTS_PATH ?? (0, import_node_path3.join)((0, import_node_path3.dirname)(getConfigPath()), "endpoints.json");
|
|
12729
13112
|
}
|
|
12730
13113
|
function readConfig() {
|
|
12731
13114
|
const configPath = getConfigPath();
|
|
12732
|
-
if (!(0,
|
|
12733
|
-
return JSON.parse((0,
|
|
13115
|
+
if (!(0, import_node_fs3.existsSync)(configPath)) return {};
|
|
13116
|
+
return JSON.parse((0, import_node_fs3.readFileSync)(configPath, "utf8"));
|
|
12734
13117
|
}
|
|
12735
13118
|
function readEndpointDefaults() {
|
|
12736
13119
|
const endpointsPath = getEndpointDefaultsPath();
|
|
12737
|
-
if (!(0,
|
|
13120
|
+
if (!(0, import_node_fs3.existsSync)(endpointsPath)) return {};
|
|
12738
13121
|
try {
|
|
12739
|
-
return JSON.parse((0,
|
|
13122
|
+
return JSON.parse((0, import_node_fs3.readFileSync)(endpointsPath, "utf8"));
|
|
12740
13123
|
} catch {
|
|
12741
13124
|
return {};
|
|
12742
13125
|
}
|
|
12743
13126
|
}
|
|
12744
13127
|
function writeConfig(config) {
|
|
12745
13128
|
const configPath = getConfigPath();
|
|
12746
|
-
(0,
|
|
12747
|
-
(0,
|
|
13129
|
+
(0, import_node_fs3.mkdirSync)((0, import_node_path3.dirname)(configPath), { recursive: true, mode: 448 });
|
|
13130
|
+
(0, import_node_fs3.writeFileSync)(configPath, JSON.stringify(config, null, 2), { mode: 384 });
|
|
12748
13131
|
}
|
|
12749
13132
|
function removeConfig() {
|
|
12750
13133
|
const configPath = getConfigPath();
|
|
12751
|
-
if ((0,
|
|
13134
|
+
if ((0, import_node_fs3.existsSync)(configPath)) (0, import_node_fs3.rmSync)(configPath, { force: true });
|
|
12752
13135
|
}
|
|
12753
13136
|
function argValue(args, name) {
|
|
12754
13137
|
const index = args.indexOf(name);
|
|
@@ -12784,7 +13167,7 @@ function getLocalApiPort(args, stored) {
|
|
|
12784
13167
|
}
|
|
12785
13168
|
function sleep(ms) {
|
|
12786
13169
|
if (ms <= 0) return Promise.resolve();
|
|
12787
|
-
return new Promise((
|
|
13170
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
12788
13171
|
}
|
|
12789
13172
|
function normalizeBackendKind(backendKind) {
|
|
12790
13173
|
if (backendKind === "codex") return "codex_app_server";
|
|
@@ -12816,6 +13199,14 @@ function extractModelIdsFromJson(value2) {
|
|
|
12816
13199
|
}
|
|
12817
13200
|
return [];
|
|
12818
13201
|
}
|
|
13202
|
+
function extractModelIdsFromText(value2) {
|
|
13203
|
+
const ansiPattern = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
|
|
13204
|
+
const ignoredLinePattern = /^(available models|models|usage|error|flag provided|try |agy\b)/i;
|
|
13205
|
+
const ids = value2.split(/\r?\n/).map(
|
|
13206
|
+
(line) => line.replace(ansiPattern, "").replace(/^[-*•]\s*/, "").trim()
|
|
13207
|
+
).filter((line) => line.length > 0 && !ignoredLinePattern.test(line));
|
|
13208
|
+
return [...new Set(ids)];
|
|
13209
|
+
}
|
|
12819
13210
|
function discoverOpenCodeModels(executable, env) {
|
|
12820
13211
|
for (const args of [
|
|
12821
13212
|
["models", "--json"],
|
|
@@ -12824,7 +13215,7 @@ function discoverOpenCodeModels(executable, env) {
|
|
|
12824
13215
|
]) {
|
|
12825
13216
|
const result = (0, import_node_child_process3.spawnSync)(executable, args, {
|
|
12826
13217
|
encoding: "utf8",
|
|
12827
|
-
timeout:
|
|
13218
|
+
timeout: MODEL_DISCOVERY_TIMEOUT_MS,
|
|
12828
13219
|
env,
|
|
12829
13220
|
windowsHide: true
|
|
12830
13221
|
});
|
|
@@ -12837,7 +13228,27 @@ function discoverOpenCodeModels(executable, env) {
|
|
|
12837
13228
|
}
|
|
12838
13229
|
return OPENCODE_FREE_MODEL_IDS;
|
|
12839
13230
|
}
|
|
13231
|
+
function discoverAntigravityModels(executable, env) {
|
|
13232
|
+
for (const args of [["models", "--json"], ["models"]]) {
|
|
13233
|
+
const result = (0, import_node_child_process3.spawnSync)(executable, args, {
|
|
13234
|
+
encoding: "utf8",
|
|
13235
|
+
timeout: MODEL_DISCOVERY_TIMEOUT_MS,
|
|
13236
|
+
env,
|
|
13237
|
+
windowsHide: true
|
|
13238
|
+
});
|
|
13239
|
+
if (!result || result.error || result.status !== 0 || !result.stdout.trim()) continue;
|
|
13240
|
+
try {
|
|
13241
|
+
const models = extractModelIdsFromJson(JSON.parse(result.stdout));
|
|
13242
|
+
if (models.length > 0) return models;
|
|
13243
|
+
} catch {
|
|
13244
|
+
const models = extractModelIdsFromText(result.stdout);
|
|
13245
|
+
if (models.length > 0) return models;
|
|
13246
|
+
}
|
|
13247
|
+
}
|
|
13248
|
+
return [];
|
|
13249
|
+
}
|
|
12840
13250
|
function discoverProviderModels(provider, executable, env) {
|
|
13251
|
+
if (provider === "gemini_cli") return discoverAntigravityModels(executable, env);
|
|
12841
13252
|
if (provider === "opencode_cli") return discoverOpenCodeModels(executable, env);
|
|
12842
13253
|
return [];
|
|
12843
13254
|
}
|
|
@@ -12918,7 +13329,7 @@ function collectRuntimeMetadata() {
|
|
|
12918
13329
|
metadata.cpuCores = cpuList.length;
|
|
12919
13330
|
}
|
|
12920
13331
|
try {
|
|
12921
|
-
const disk = (0,
|
|
13332
|
+
const disk = (0, import_node_fs3.statfsSync)((0, import_node_os4.homedir)());
|
|
12922
13333
|
metadata.diskFreeBytes = disk.bavail * disk.bsize;
|
|
12923
13334
|
metadata.diskTotalBytes = disk.blocks * disk.bsize;
|
|
12924
13335
|
} catch {
|
|
@@ -12946,7 +13357,10 @@ var RuntimePresenter = class {
|
|
|
12946
13357
|
this.onRunComplete = onRunComplete;
|
|
12947
13358
|
}
|
|
12948
13359
|
emittedGeneratedImageKeys = /* @__PURE__ */ new Set();
|
|
13360
|
+
emittedSessionMediaKeys = /* @__PURE__ */ new Set();
|
|
12949
13361
|
toolNamesById = /* @__PURE__ */ new Map();
|
|
13362
|
+
toolInputsById = /* @__PURE__ */ new Map();
|
|
13363
|
+
browserRecordingPathHints = /* @__PURE__ */ new Set();
|
|
12950
13364
|
emitEvent(event) {
|
|
12951
13365
|
this.touchRunnerActivity?.();
|
|
12952
13366
|
this.socket.emit("agent.event", {
|
|
@@ -12969,6 +13383,12 @@ var RuntimePresenter = class {
|
|
|
12969
13383
|
}
|
|
12970
13384
|
onToolUse(tool, input, toolId) {
|
|
12971
13385
|
this.toolNamesById.set(toolId, tool);
|
|
13386
|
+
this.toolInputsById.set(toolId, input);
|
|
13387
|
+
for (const path of extractBrowserMediaPathHints(void 0, this.cwd, tool, {
|
|
13388
|
+
toolInput: input
|
|
13389
|
+
})) {
|
|
13390
|
+
this.browserRecordingPathHints.add(path);
|
|
13391
|
+
}
|
|
12972
13392
|
this.emitEvent({ type: "tool_use", id: toolId, name: tool, input, ts: Date.now() });
|
|
12973
13393
|
}
|
|
12974
13394
|
onToolResult(toolId, content, isError) {
|
|
@@ -12981,9 +13401,27 @@ var RuntimePresenter = class {
|
|
|
12981
13401
|
});
|
|
12982
13402
|
if (isError) return;
|
|
12983
13403
|
const toolName = this.toolNamesById.get(toolId);
|
|
12984
|
-
|
|
13404
|
+
const toolInput = this.toolInputsById.get(toolId);
|
|
13405
|
+
const options = { toolInput, pathHints: [...this.browserRecordingPathHints] };
|
|
13406
|
+
for (const image of extractGeneratedImagesFromToolResult(
|
|
13407
|
+
toolId,
|
|
13408
|
+
content,
|
|
13409
|
+
this.cwd,
|
|
13410
|
+
toolName,
|
|
13411
|
+
options
|
|
13412
|
+
)) {
|
|
12985
13413
|
this.emitGeneratedImage(image);
|
|
12986
13414
|
}
|
|
13415
|
+
for (const media of extractSessionMediaFromToolResult(
|
|
13416
|
+
toolId,
|
|
13417
|
+
content,
|
|
13418
|
+
this.cwd,
|
|
13419
|
+
toolName,
|
|
13420
|
+
options
|
|
13421
|
+
)) {
|
|
13422
|
+
this.emitSessionMedia(media);
|
|
13423
|
+
if (media.sourcePath) this.browserRecordingPathHints.delete(media.sourcePath);
|
|
13424
|
+
}
|
|
12987
13425
|
}
|
|
12988
13426
|
onGeneratedImage(image) {
|
|
12989
13427
|
this.emitGeneratedImage(image);
|
|
@@ -12994,6 +13432,15 @@ var RuntimePresenter = class {
|
|
|
12994
13432
|
this.emittedGeneratedImageKeys.add(key);
|
|
12995
13433
|
this.emitEvent(image);
|
|
12996
13434
|
}
|
|
13435
|
+
onSessionMedia(media) {
|
|
13436
|
+
this.emitSessionMedia(media);
|
|
13437
|
+
}
|
|
13438
|
+
emitSessionMedia(media) {
|
|
13439
|
+
const key = media.sourceHash ?? `${media.sourcePath ?? media.id}:${media.size}`;
|
|
13440
|
+
if (this.emittedSessionMediaKeys.has(key)) return;
|
|
13441
|
+
this.emittedSessionMediaKeys.add(key);
|
|
13442
|
+
this.emitEvent(media);
|
|
13443
|
+
}
|
|
12997
13444
|
onTurnComplete(content) {
|
|
12998
13445
|
this.emitEvent({ type: "turn_complete", content, ts: Date.now() });
|
|
12999
13446
|
}
|
|
@@ -13084,7 +13531,7 @@ async function setupDaemon(args) {
|
|
|
13084
13531
|
runtimeId: body.runtime.id,
|
|
13085
13532
|
runtimeToken: body.runtimeToken,
|
|
13086
13533
|
localApiPort: getLocalApiPort(args, {}),
|
|
13087
|
-
localApiToken: (0,
|
|
13534
|
+
localApiToken: (0, import_node_crypto.randomBytes)(24).toString("hex"),
|
|
13088
13535
|
displayName: body.runtime.displayName ?? displayName
|
|
13089
13536
|
});
|
|
13090
13537
|
console.info("[aiden-agent] Runtime registered", {
|
|
@@ -13135,7 +13582,7 @@ async function loginWithDeviceCode(args) {
|
|
|
13135
13582
|
runtimeId: body.runtime.id,
|
|
13136
13583
|
runtimeToken: body.runtimeToken,
|
|
13137
13584
|
localApiPort: getLocalApiPort(args, {}),
|
|
13138
|
-
localApiToken: (0,
|
|
13585
|
+
localApiToken: (0, import_node_crypto.randomBytes)(24).toString("hex"),
|
|
13139
13586
|
displayName: body.runtime.displayName ?? displayName
|
|
13140
13587
|
});
|
|
13141
13588
|
console.info("[aiden-agent] Runtime registered", {
|
|
@@ -13152,7 +13599,7 @@ async function startDaemon(args) {
|
|
|
13152
13599
|
const runtimeToken = argValue(args, "--token") ?? process.env.AIDEN_RUNTIME_TOKEN ?? stored.runtimeToken;
|
|
13153
13600
|
const wsUrl = argValue(args, "--ws-url") ?? process.env.AIDEN_WS_URL ?? stored.wsUrl;
|
|
13154
13601
|
let localApiPort = getLocalApiPort(args, stored);
|
|
13155
|
-
const localApiToken = stored.localApiToken ?? (0,
|
|
13602
|
+
const localApiToken = stored.localApiToken ?? (0, import_node_crypto.randomBytes)(24).toString("hex");
|
|
13156
13603
|
if (!runtimeId || !runtimeToken || !wsUrl) {
|
|
13157
13604
|
throw new Error(
|
|
13158
13605
|
"daemon requires runtimeId, runtime token, and wsUrl. Run setup first or pass --runtime-id/--token/--ws-url."
|
|
@@ -13211,6 +13658,23 @@ async function startDaemon(args) {
|
|
|
13211
13658
|
pushLog(`disconnected ${reason}`);
|
|
13212
13659
|
console.info("[aiden-agent] Daemon disconnected:", reason);
|
|
13213
13660
|
});
|
|
13661
|
+
socket.on("desktop:rpc", (message) => {
|
|
13662
|
+
if (!message?.id || !message.method) return;
|
|
13663
|
+
try {
|
|
13664
|
+
const params = message.params ?? {};
|
|
13665
|
+
if (message.method !== "worktree.ensure") {
|
|
13666
|
+
throw new Error(`Method not found: ${message.method}`);
|
|
13667
|
+
}
|
|
13668
|
+
const result = ensureWorktree(params);
|
|
13669
|
+
socket.emit("desktop:rpc", { jsonrpc: "2.0", id: message.id, result });
|
|
13670
|
+
} catch (error) {
|
|
13671
|
+
socket.emit("desktop:rpc", {
|
|
13672
|
+
jsonrpc: "2.0",
|
|
13673
|
+
id: message.id,
|
|
13674
|
+
error: { code: -32e3, message: error.message }
|
|
13675
|
+
});
|
|
13676
|
+
}
|
|
13677
|
+
});
|
|
13214
13678
|
socket.on("agent.execute", (payload) => {
|
|
13215
13679
|
if (!payload?.runId || !payload.conversationId || typeof payload.content !== "string") {
|
|
13216
13680
|
return;
|
|
@@ -13240,7 +13704,7 @@ async function startDaemon(args) {
|
|
|
13240
13704
|
});
|
|
13241
13705
|
pushLog(`accepted run=${payload.runId}`);
|
|
13242
13706
|
console.info("[aiden-agent] Agent run accepted", correlation);
|
|
13243
|
-
const cwd = payload
|
|
13707
|
+
const cwd = resolveRuntimeCwd(payload);
|
|
13244
13708
|
const nowMs = Date.now();
|
|
13245
13709
|
const touchActivity = () => {
|
|
13246
13710
|
const entry = activeAgents.get(payload.runId);
|
|
@@ -13401,7 +13865,7 @@ async function startDaemon(args) {
|
|
|
13401
13865
|
`${describeOccupiedLocalDaemon(localApiPort)} The token in ${getConfigPath()} no longer matches the running daemon; quit Aiden desktop or run setup again.`
|
|
13402
13866
|
);
|
|
13403
13867
|
}
|
|
13404
|
-
await new Promise((
|
|
13868
|
+
await new Promise((resolve3, reject) => {
|
|
13405
13869
|
const onError = (error) => {
|
|
13406
13870
|
clearInterval(heartbeat);
|
|
13407
13871
|
socket.disconnect();
|
|
@@ -13428,7 +13892,7 @@ async function startDaemon(args) {
|
|
|
13428
13892
|
if (address && typeof address === "object") localApiPort = address.port;
|
|
13429
13893
|
pushLog(`local_api listening port=${localApiPort}`);
|
|
13430
13894
|
console.info("[aiden-agent] Local daemon API listening", { port: localApiPort });
|
|
13431
|
-
|
|
13895
|
+
resolve3();
|
|
13432
13896
|
});
|
|
13433
13897
|
});
|
|
13434
13898
|
let stopped = false;
|
|
@@ -13441,8 +13905,8 @@ async function startDaemon(args) {
|
|
|
13441
13905
|
}
|
|
13442
13906
|
activeAgents.clear();
|
|
13443
13907
|
socket.disconnect();
|
|
13444
|
-
await new Promise((
|
|
13445
|
-
localServer.close(() =>
|
|
13908
|
+
await new Promise((resolve3) => {
|
|
13909
|
+
localServer.close(() => resolve3());
|
|
13446
13910
|
});
|
|
13447
13911
|
};
|
|
13448
13912
|
const controller = {
|
|
@@ -13726,7 +14190,10 @@ var WebPresenter = class {
|
|
|
13726
14190
|
}
|
|
13727
14191
|
wsClient;
|
|
13728
14192
|
emittedGeneratedImageKeys = /* @__PURE__ */ new Set();
|
|
14193
|
+
emittedSessionMediaKeys = /* @__PURE__ */ new Set();
|
|
13729
14194
|
toolNamesById = /* @__PURE__ */ new Map();
|
|
14195
|
+
toolInputsById = /* @__PURE__ */ new Map();
|
|
14196
|
+
browserRecordingPathHints = /* @__PURE__ */ new Set();
|
|
13730
14197
|
suppressSessionLifecycle = false;
|
|
13731
14198
|
setSuppressSessionLifecycle(suppress) {
|
|
13732
14199
|
this.suppressSessionLifecycle = suppress;
|
|
@@ -13745,6 +14212,12 @@ var WebPresenter = class {
|
|
|
13745
14212
|
}
|
|
13746
14213
|
onToolUse(tool, input, toolId) {
|
|
13747
14214
|
this.toolNamesById.set(toolId, tool);
|
|
14215
|
+
this.toolInputsById.set(toolId, input);
|
|
14216
|
+
for (const path of extractBrowserMediaPathHints(void 0, this.cwd, tool, {
|
|
14217
|
+
toolInput: input
|
|
14218
|
+
})) {
|
|
14219
|
+
this.browserRecordingPathHints.add(path);
|
|
14220
|
+
}
|
|
13748
14221
|
this.wsClient.emitEvent({ type: "tool_use", id: toolId, name: tool, input, ts: Date.now() });
|
|
13749
14222
|
}
|
|
13750
14223
|
onToolResult(toolId, content, isError) {
|
|
@@ -13757,9 +14230,27 @@ var WebPresenter = class {
|
|
|
13757
14230
|
});
|
|
13758
14231
|
if (isError) return;
|
|
13759
14232
|
const toolName = this.toolNamesById.get(toolId);
|
|
13760
|
-
|
|
14233
|
+
const toolInput = this.toolInputsById.get(toolId);
|
|
14234
|
+
const options = { toolInput, pathHints: [...this.browserRecordingPathHints] };
|
|
14235
|
+
for (const image of extractGeneratedImagesFromToolResult(
|
|
14236
|
+
toolId,
|
|
14237
|
+
content,
|
|
14238
|
+
this.cwd,
|
|
14239
|
+
toolName,
|
|
14240
|
+
options
|
|
14241
|
+
)) {
|
|
13761
14242
|
this.emitGeneratedImage(image);
|
|
13762
14243
|
}
|
|
14244
|
+
for (const media of extractSessionMediaFromToolResult(
|
|
14245
|
+
toolId,
|
|
14246
|
+
content,
|
|
14247
|
+
this.cwd,
|
|
14248
|
+
toolName,
|
|
14249
|
+
options
|
|
14250
|
+
)) {
|
|
14251
|
+
this.emitSessionMedia(media);
|
|
14252
|
+
if (media.sourcePath) this.browserRecordingPathHints.delete(media.sourcePath);
|
|
14253
|
+
}
|
|
13763
14254
|
}
|
|
13764
14255
|
onGeneratedImage(image) {
|
|
13765
14256
|
this.emitGeneratedImage(image);
|
|
@@ -13770,6 +14261,15 @@ var WebPresenter = class {
|
|
|
13770
14261
|
this.emittedGeneratedImageKeys.add(key);
|
|
13771
14262
|
this.wsClient.emitEvent(image);
|
|
13772
14263
|
}
|
|
14264
|
+
onSessionMedia(media) {
|
|
14265
|
+
this.emitSessionMedia(media);
|
|
14266
|
+
}
|
|
14267
|
+
emitSessionMedia(media) {
|
|
14268
|
+
const key = media.sourceHash ?? `${media.sourcePath ?? media.id}:${media.size}`;
|
|
14269
|
+
if (this.emittedSessionMediaKeys.has(key)) return;
|
|
14270
|
+
this.emittedSessionMediaKeys.add(key);
|
|
14271
|
+
this.wsClient.emitEvent(media);
|
|
14272
|
+
}
|
|
13773
14273
|
onTurnComplete(content) {
|
|
13774
14274
|
this.wsClient.emitEvent({ type: "turn_complete", content, ts: Date.now() });
|
|
13775
14275
|
}
|
|
@@ -13858,9 +14358,9 @@ var WSClient = class {
|
|
|
13858
14358
|
this.socket.emit("agent_event", event);
|
|
13859
14359
|
}
|
|
13860
14360
|
waitForConnection(timeoutMs = 15e3) {
|
|
13861
|
-
return new Promise((
|
|
14361
|
+
return new Promise((resolve3, reject) => {
|
|
13862
14362
|
if (this.socket.connected) {
|
|
13863
|
-
|
|
14363
|
+
resolve3();
|
|
13864
14364
|
return;
|
|
13865
14365
|
}
|
|
13866
14366
|
const timeout = setTimeout(
|
|
@@ -13869,7 +14369,7 @@ var WSClient = class {
|
|
|
13869
14369
|
);
|
|
13870
14370
|
this.socket.once("connect", () => {
|
|
13871
14371
|
clearTimeout(timeout);
|
|
13872
|
-
|
|
14372
|
+
resolve3();
|
|
13873
14373
|
});
|
|
13874
14374
|
this.socket.once("connect_error", (err) => {
|
|
13875
14375
|
clearTimeout(timeout);
|
|
@@ -14010,9 +14510,9 @@ async function runSandbox(config) {
|
|
|
14010
14510
|
onUserMessage: (payload) => {
|
|
14011
14511
|
if (payload === null) {
|
|
14012
14512
|
if (pendingMessageResolve) {
|
|
14013
|
-
const
|
|
14513
|
+
const resolve3 = pendingMessageResolve;
|
|
14014
14514
|
pendingMessageResolve = null;
|
|
14015
|
-
|
|
14515
|
+
resolve3(null);
|
|
14016
14516
|
}
|
|
14017
14517
|
return;
|
|
14018
14518
|
}
|
|
@@ -14034,9 +14534,9 @@ async function runSandbox(config) {
|
|
|
14034
14534
|
fileCount: payload.files?.length ?? 0
|
|
14035
14535
|
});
|
|
14036
14536
|
if (pendingMessageResolve) {
|
|
14037
|
-
const
|
|
14537
|
+
const resolve3 = pendingMessageResolve;
|
|
14038
14538
|
pendingMessageResolve = null;
|
|
14039
|
-
|
|
14539
|
+
resolve3(payload);
|
|
14040
14540
|
} else {
|
|
14041
14541
|
queuedMessages.push(payload);
|
|
14042
14542
|
}
|
|
@@ -14190,8 +14690,8 @@ async function runSandbox(config) {
|
|
|
14190
14690
|
});
|
|
14191
14691
|
if (stopped) break;
|
|
14192
14692
|
}
|
|
14193
|
-
const nextPayload = queuedMessages.shift() ?? await new Promise((
|
|
14194
|
-
pendingMessageResolve =
|
|
14693
|
+
const nextPayload = queuedMessages.shift() ?? await new Promise((resolve3) => {
|
|
14694
|
+
pendingMessageResolve = resolve3;
|
|
14195
14695
|
});
|
|
14196
14696
|
if (nextPayload === null || stopped) {
|
|
14197
14697
|
break;
|