@aiden-ade/sandbox-agent 0.1.25 → 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/index.cjs +1060 -316
- package/package.json +1 -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"]
|
|
8701
8705
|
},
|
|
8702
|
-
gemini_cli: {
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8706
|
+
gemini_cli: {
|
|
8707
|
+
provider: "gemini_cli",
|
|
8708
|
+
command: "agy",
|
|
8709
|
+
envVars: ["AIDEN_ANTIGRAVITY_PATH", "AIDEN_GEMINI_PATH"]
|
|
8710
|
+
},
|
|
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
|
}
|
|
@@ -10225,10 +10316,7 @@ function createClaudeCliBackend(command = "claude", defaultArgs = []) {
|
|
|
10225
10316
|
stdin.write(`${message}
|
|
10226
10317
|
`);
|
|
10227
10318
|
},
|
|
10228
|
-
keepStdinOpen: true
|
|
10229
|
-
allowContinuation: true,
|
|
10230
|
-
continuationIdleMs: 10 * 60 * 1e3
|
|
10231
|
-
// 10 minutes
|
|
10319
|
+
keepStdinOpen: true
|
|
10232
10320
|
}).run(context);
|
|
10233
10321
|
}
|
|
10234
10322
|
};
|
|
@@ -11336,7 +11424,33 @@ function parseGeminiStructuredLine(line, context, state) {
|
|
|
11336
11424
|
break;
|
|
11337
11425
|
}
|
|
11338
11426
|
}
|
|
11339
|
-
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 = []) {
|
|
11340
11454
|
return {
|
|
11341
11455
|
kind: "gemini_cli",
|
|
11342
11456
|
supportTier: "structured",
|
|
@@ -11351,19 +11465,9 @@ function createGeminiCliBackend(command = "gemini", defaultArgs = []) {
|
|
|
11351
11465
|
supportTier: "structured",
|
|
11352
11466
|
command,
|
|
11353
11467
|
args: [],
|
|
11354
|
-
buildArgs: (ctx) =>
|
|
11355
|
-
const args = ["-p", "", "--output-format", "stream-json"];
|
|
11356
|
-
const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
|
|
11357
|
-
const approvalMode = shouldUseReadOnlyRuntimePermissions(ctx.config) ? "plan" : "yolo";
|
|
11358
|
-
args.push("--approval-mode", approvalMode);
|
|
11359
|
-
if (resumeId) args.push("--resume", resumeId);
|
|
11360
|
-
if (ctx.config.selectedModel?.trim())
|
|
11361
|
-
args.push("--model", ctx.config.selectedModel.trim());
|
|
11362
|
-
return [...args, ...defaultArgs];
|
|
11363
|
-
},
|
|
11364
|
-
promptViaStdin: true,
|
|
11468
|
+
buildArgs: (ctx, prompt) => buildAntigravityCliArgs(ctx, prompt, defaultArgs),
|
|
11365
11469
|
augmentPrompt: (ctx) => buildPromptWithImagePathReferences(ctx, imageFiles),
|
|
11366
|
-
parseStructuredLine:
|
|
11470
|
+
parseStructuredLine: parseAntigravityLine
|
|
11367
11471
|
}).run(context);
|
|
11368
11472
|
} finally {
|
|
11369
11473
|
cleanup();
|
|
@@ -11371,6 +11475,72 @@ function createGeminiCliBackend(command = "gemini", defaultArgs = []) {
|
|
|
11371
11475
|
}
|
|
11372
11476
|
};
|
|
11373
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
|
+
}
|
|
11374
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;
|
|
11375
11545
|
function parseKimiStderrLine(line, state) {
|
|
11376
11546
|
const match = line.match(KIMI_RESUME_SESSION_RE);
|
|
@@ -11473,7 +11643,13 @@ function createKimiCliBackend(command = "kimi-cli", defaultArgs = []) {
|
|
|
11473
11643
|
if (model) args.push("--model", model);
|
|
11474
11644
|
return [...args, ...defaultArgs, "--prompt", prompt];
|
|
11475
11645
|
},
|
|
11476
|
-
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
|
+
},
|
|
11477
11653
|
parseStructuredLine: parseKimiStructuredLine,
|
|
11478
11654
|
parseStderrLine: (line, _ctx, state) => parseKimiStderrLine(line, state)
|
|
11479
11655
|
}).run(context);
|
|
@@ -11816,40 +11992,40 @@ function parseSkillInvocation(text) {
|
|
|
11816
11992
|
function candidateRoots(cwd) {
|
|
11817
11993
|
const roots = [];
|
|
11818
11994
|
if (cwd) {
|
|
11819
|
-
roots.push((0,
|
|
11820
|
-
roots.push((0,
|
|
11821
|
-
roots.push((0,
|
|
11822
|
-
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)) {
|
|
11823
11999
|
let entries = [];
|
|
11824
12000
|
try {
|
|
11825
|
-
entries = (0,
|
|
12001
|
+
entries = (0, import_fs5.readdirSync)(cwd, { withFileTypes: true });
|
|
11826
12002
|
} catch {
|
|
11827
12003
|
}
|
|
11828
12004
|
for (const entry of entries) {
|
|
11829
12005
|
if (!entry.isDirectory()) continue;
|
|
11830
12006
|
if (entry.name.startsWith(".")) continue;
|
|
11831
|
-
const child = (0,
|
|
11832
|
-
roots.push((0,
|
|
11833
|
-
roots.push((0,
|
|
11834
|
-
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"));
|
|
11835
12011
|
}
|
|
11836
12012
|
}
|
|
11837
12013
|
}
|
|
11838
|
-
const home = (0,
|
|
11839
|
-
roots.push((0,
|
|
11840
|
-
roots.push((0,
|
|
11841
|
-
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"));
|
|
11842
12018
|
return Array.from(new Set(roots));
|
|
11843
12019
|
}
|
|
11844
12020
|
function resolveSkillInvocation(text, cwd) {
|
|
11845
12021
|
const parsed = parseSkillInvocation(text);
|
|
11846
12022
|
if (!parsed) return null;
|
|
11847
12023
|
for (const root of candidateRoots(cwd)) {
|
|
11848
|
-
const skillPath = (0,
|
|
11849
|
-
if (!(0,
|
|
12024
|
+
const skillPath = (0, import_path5.join)(root, parsed.command, "SKILL.md");
|
|
12025
|
+
if (!(0, import_fs5.existsSync)(skillPath)) continue;
|
|
11850
12026
|
let content;
|
|
11851
12027
|
try {
|
|
11852
|
-
content = (0,
|
|
12028
|
+
content = (0, import_fs5.readFileSync)(skillPath, "utf-8");
|
|
11853
12029
|
} catch {
|
|
11854
12030
|
continue;
|
|
11855
12031
|
}
|
|
@@ -11898,6 +12074,8 @@ function defaultSelectedModelForBackend(backendKind) {
|
|
|
11898
12074
|
return void 0;
|
|
11899
12075
|
case "opencode_cli":
|
|
11900
12076
|
return void 0;
|
|
12077
|
+
case "gemini_cli":
|
|
12078
|
+
return void 0;
|
|
11901
12079
|
case "supatest_cli":
|
|
11902
12080
|
return "medium";
|
|
11903
12081
|
default:
|
|
@@ -12099,7 +12277,7 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12099
12277
|
const promptText = this.buildPromptText(runtimeConfig);
|
|
12100
12278
|
const runtimeCommand = runtimeConfig.runtimeCommand || this.runtime.runtimeCommand;
|
|
12101
12279
|
const runtimeArgs = runtimeConfig.runtimeArgs || this.runtime.runtimeArgs || [];
|
|
12102
|
-
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(
|
|
12103
12281
|
runtimeCommand || "generic-cli",
|
|
12104
12282
|
runtimeArgs
|
|
12105
12283
|
);
|
|
@@ -12165,18 +12343,18 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12165
12343
|
`[base-machine-agent] Transient error (attempt ${attempt + 1}/${_BaseMachineAgent.MAX_RETRIES + 1}), retrying in ${delayMs}ms: ${lastResult.error}`
|
|
12166
12344
|
);
|
|
12167
12345
|
void this.presenter.onLog(`Transient error, retrying in ${Math.round(delayMs / 1e3)}s...`);
|
|
12168
|
-
await new Promise((
|
|
12346
|
+
await new Promise((resolve22) => {
|
|
12169
12347
|
const signal = this.abortController?.signal;
|
|
12170
12348
|
if (signal?.aborted) {
|
|
12171
|
-
|
|
12349
|
+
resolve22();
|
|
12172
12350
|
return;
|
|
12173
12351
|
}
|
|
12174
|
-
const timeoutId = setTimeout(
|
|
12352
|
+
const timeoutId = setTimeout(resolve22, delayMs);
|
|
12175
12353
|
signal?.addEventListener(
|
|
12176
12354
|
"abort",
|
|
12177
12355
|
() => {
|
|
12178
12356
|
clearTimeout(timeoutId);
|
|
12179
|
-
|
|
12357
|
+
resolve22();
|
|
12180
12358
|
},
|
|
12181
12359
|
{ once: true }
|
|
12182
12360
|
);
|
|
@@ -12246,6 +12424,195 @@ Prefer relative paths and keep your work scoped to this project.`
|
|
|
12246
12424
|
}
|
|
12247
12425
|
}
|
|
12248
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
|
+
}
|
|
12249
12616
|
|
|
12250
12617
|
// src/core-agent.ts
|
|
12251
12618
|
var CoreAgent = class _CoreAgent extends BaseMachineAgent {
|
|
@@ -12544,149 +12911,179 @@ ${meta.description}`);
|
|
|
12544
12911
|
}
|
|
12545
12912
|
};
|
|
12546
12913
|
|
|
12547
|
-
// src/
|
|
12548
|
-
var
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
var
|
|
12552
|
-
"
|
|
12553
|
-
"
|
|
12554
|
-
"
|
|
12555
|
-
".
|
|
12556
|
-
"
|
|
12557
|
-
|
|
12558
|
-
var
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
"edit_image",
|
|
12568
|
-
"text_to_image",
|
|
12569
|
-
"images_generate"
|
|
12570
|
-
].some((token) => normalized.includes(token));
|
|
12571
|
-
}
|
|
12572
|
-
function shouldExtractGeneratedImagesFromToolResult(toolName) {
|
|
12573
|
-
return isGeneratedImageToolName(toolName);
|
|
12574
|
-
}
|
|
12575
|
-
function collectStringValues(value2, out) {
|
|
12576
|
-
if (typeof value2 === "string") {
|
|
12577
|
-
out.push(value2);
|
|
12578
|
-
return;
|
|
12579
|
-
}
|
|
12580
|
-
if (Array.isArray(value2)) {
|
|
12581
|
-
for (const item of value2) collectStringValues(item, out);
|
|
12582
|
-
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`);
|
|
12583
12934
|
}
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
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`);
|
|
12587
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`);
|
|
12588
12946
|
}
|
|
12589
|
-
function
|
|
12590
|
-
const
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
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`);
|
|
12594
12954
|
}
|
|
12595
|
-
return values;
|
|
12596
12955
|
}
|
|
12597
|
-
function
|
|
12598
|
-
const
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
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());
|
|
12604
12965
|
}
|
|
12605
|
-
return
|
|
12966
|
+
return result.stdout.trim();
|
|
12606
12967
|
}
|
|
12607
|
-
function
|
|
12608
|
-
let path = candidate.trim().replace(/^file:\/\//, "");
|
|
12968
|
+
function gitSafe(cwd, args) {
|
|
12609
12969
|
try {
|
|
12610
|
-
|
|
12970
|
+
return git(cwd, args);
|
|
12611
12971
|
} catch {
|
|
12972
|
+
return "";
|
|
12612
12973
|
}
|
|
12613
|
-
if (path.startsWith("~/")) return null;
|
|
12614
|
-
if ((0, import_node_path3.isAbsolute)(path)) return path;
|
|
12615
|
-
return cwd ? (0, import_node_path3.join)(cwd, path) : null;
|
|
12616
12974
|
}
|
|
12617
|
-
function
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
|
|
12622
|
-
|
|
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;
|
|
12623
12993
|
}
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
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
|
+
});
|
|
12632
13045
|
return {
|
|
12633
|
-
|
|
12634
|
-
|
|
13046
|
+
repoId: repo.repoId ?? null,
|
|
13047
|
+
repoUrl: repo.repoUrl,
|
|
13048
|
+
worktreePath: worktreePath2,
|
|
13049
|
+
branchName: input.branchName,
|
|
13050
|
+
baseBranch
|
|
12635
13051
|
};
|
|
12636
|
-
}
|
|
12637
|
-
|
|
12638
|
-
}
|
|
13052
|
+
})
|
|
13053
|
+
};
|
|
12639
13054
|
}
|
|
12640
|
-
|
|
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
|
+
};
|
|
12641
13064
|
}
|
|
12642
|
-
function
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
width,
|
|
12664
|
-
height,
|
|
12665
|
-
data: buffer.toString("base64"),
|
|
12666
|
-
sourcePath: path,
|
|
12667
|
-
sourceHash: (0, import_node_crypto.createHash)("sha256").update(buffer).digest("hex"),
|
|
12668
|
-
toolId,
|
|
12669
|
-
ts: Date.now()
|
|
12670
|
-
});
|
|
12671
|
-
}
|
|
12672
|
-
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();
|
|
13069
|
+
}
|
|
13070
|
+
function correlationLogFields(input) {
|
|
13071
|
+
return Object.fromEntries(
|
|
13072
|
+
Object.entries({
|
|
13073
|
+
taskId: input.taskId,
|
|
13074
|
+
conversationId: input.conversationId,
|
|
13075
|
+
runId: input.runId,
|
|
13076
|
+
messageId: input.messageId,
|
|
13077
|
+
cloudEnvironmentId: input.cloudEnvironmentId,
|
|
13078
|
+
provider: input.backendKind,
|
|
13079
|
+
backendKind: input.backendKind,
|
|
13080
|
+
agentVersion: input.agentVersion
|
|
13081
|
+
}).filter((entry) => {
|
|
13082
|
+
const value2 = entry[1];
|
|
13083
|
+
return typeof value2 === "string" && value2.trim().length > 0;
|
|
13084
|
+
}).map(([key, value2]) => [key, value2.trim()])
|
|
13085
|
+
);
|
|
12673
13086
|
}
|
|
12674
|
-
|
|
12675
|
-
// src/version.ts
|
|
12676
|
-
var AGENT_VERSION = "0.1.25";
|
|
12677
|
-
|
|
12678
|
-
// src/daemon.ts
|
|
12679
|
-
var OPENCODE_FREE_MODEL_IDS = [
|
|
12680
|
-
"opencode/north-mini-code-free",
|
|
12681
|
-
"opencode/nemotron-3-ultra-free",
|
|
12682
|
-
"opencode/deepseek-v4-flash-free",
|
|
12683
|
-
"opencode/mimo-v2.5-free",
|
|
12684
|
-
"opencode/big-pickle"
|
|
12685
|
-
];
|
|
12686
|
-
var PRODUCTION_API_URL = "https://api.aiden-platform.com";
|
|
12687
|
-
var PRODUCTION_WS_URL = "wss://ws.aiden-platform.com";
|
|
12688
|
-
var LOCAL_API_URL = "http://localhost:8400";
|
|
12689
|
-
var LOCAL_WS_URL = "ws://localhost:8401";
|
|
12690
13087
|
async function probeLocalDaemonEndpoint(port, token, timeoutMs = 750) {
|
|
12691
13088
|
try {
|
|
12692
13089
|
const headers = {};
|
|
@@ -12708,33 +13105,33 @@ function describeOccupiedLocalDaemon(port) {
|
|
|
12708
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.`;
|
|
12709
13106
|
}
|
|
12710
13107
|
function getConfigPath() {
|
|
12711
|
-
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");
|
|
12712
13109
|
}
|
|
12713
13110
|
function getEndpointDefaultsPath() {
|
|
12714
|
-
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");
|
|
12715
13112
|
}
|
|
12716
13113
|
function readConfig() {
|
|
12717
13114
|
const configPath = getConfigPath();
|
|
12718
|
-
if (!(0,
|
|
12719
|
-
return JSON.parse((0,
|
|
13115
|
+
if (!(0, import_node_fs3.existsSync)(configPath)) return {};
|
|
13116
|
+
return JSON.parse((0, import_node_fs3.readFileSync)(configPath, "utf8"));
|
|
12720
13117
|
}
|
|
12721
13118
|
function readEndpointDefaults() {
|
|
12722
13119
|
const endpointsPath = getEndpointDefaultsPath();
|
|
12723
|
-
if (!(0,
|
|
13120
|
+
if (!(0, import_node_fs3.existsSync)(endpointsPath)) return {};
|
|
12724
13121
|
try {
|
|
12725
|
-
return JSON.parse((0,
|
|
13122
|
+
return JSON.parse((0, import_node_fs3.readFileSync)(endpointsPath, "utf8"));
|
|
12726
13123
|
} catch {
|
|
12727
13124
|
return {};
|
|
12728
13125
|
}
|
|
12729
13126
|
}
|
|
12730
13127
|
function writeConfig(config) {
|
|
12731
13128
|
const configPath = getConfigPath();
|
|
12732
|
-
(0,
|
|
12733
|
-
(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 });
|
|
12734
13131
|
}
|
|
12735
13132
|
function removeConfig() {
|
|
12736
13133
|
const configPath = getConfigPath();
|
|
12737
|
-
if ((0,
|
|
13134
|
+
if ((0, import_node_fs3.existsSync)(configPath)) (0, import_node_fs3.rmSync)(configPath, { force: true });
|
|
12738
13135
|
}
|
|
12739
13136
|
function argValue(args, name) {
|
|
12740
13137
|
const index = args.indexOf(name);
|
|
@@ -12770,7 +13167,7 @@ function getLocalApiPort(args, stored) {
|
|
|
12770
13167
|
}
|
|
12771
13168
|
function sleep(ms) {
|
|
12772
13169
|
if (ms <= 0) return Promise.resolve();
|
|
12773
|
-
return new Promise((
|
|
13170
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
12774
13171
|
}
|
|
12775
13172
|
function normalizeBackendKind(backendKind) {
|
|
12776
13173
|
if (backendKind === "codex") return "codex_app_server";
|
|
@@ -12802,6 +13199,14 @@ function extractModelIdsFromJson(value2) {
|
|
|
12802
13199
|
}
|
|
12803
13200
|
return [];
|
|
12804
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
|
+
}
|
|
12805
13210
|
function discoverOpenCodeModels(executable, env) {
|
|
12806
13211
|
for (const args of [
|
|
12807
13212
|
["models", "--json"],
|
|
@@ -12810,7 +13215,7 @@ function discoverOpenCodeModels(executable, env) {
|
|
|
12810
13215
|
]) {
|
|
12811
13216
|
const result = (0, import_node_child_process3.spawnSync)(executable, args, {
|
|
12812
13217
|
encoding: "utf8",
|
|
12813
|
-
timeout:
|
|
13218
|
+
timeout: MODEL_DISCOVERY_TIMEOUT_MS,
|
|
12814
13219
|
env,
|
|
12815
13220
|
windowsHide: true
|
|
12816
13221
|
});
|
|
@@ -12823,7 +13228,27 @@ function discoverOpenCodeModels(executable, env) {
|
|
|
12823
13228
|
}
|
|
12824
13229
|
return OPENCODE_FREE_MODEL_IDS;
|
|
12825
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
|
+
}
|
|
12826
13250
|
function discoverProviderModels(provider, executable, env) {
|
|
13251
|
+
if (provider === "gemini_cli") return discoverAntigravityModels(executable, env);
|
|
12827
13252
|
if (provider === "opencode_cli") return discoverOpenCodeModels(executable, env);
|
|
12828
13253
|
return [];
|
|
12829
13254
|
}
|
|
@@ -12904,7 +13329,7 @@ function collectRuntimeMetadata() {
|
|
|
12904
13329
|
metadata.cpuCores = cpuList.length;
|
|
12905
13330
|
}
|
|
12906
13331
|
try {
|
|
12907
|
-
const disk = (0,
|
|
13332
|
+
const disk = (0, import_node_fs3.statfsSync)((0, import_node_os4.homedir)());
|
|
12908
13333
|
metadata.diskFreeBytes = disk.bavail * disk.bsize;
|
|
12909
13334
|
metadata.diskTotalBytes = disk.blocks * disk.bsize;
|
|
12910
13335
|
} catch {
|
|
@@ -12923,15 +13348,19 @@ async function collectRuntimeMetadataWithProviderLimits() {
|
|
|
12923
13348
|
return metadata;
|
|
12924
13349
|
}
|
|
12925
13350
|
var RuntimePresenter = class {
|
|
12926
|
-
constructor(socket, conversationId, runId, cwd, touchRunnerActivity) {
|
|
13351
|
+
constructor(socket, conversationId, runId, cwd, touchRunnerActivity, onRunComplete) {
|
|
12927
13352
|
this.socket = socket;
|
|
12928
13353
|
this.conversationId = conversationId;
|
|
12929
13354
|
this.runId = runId;
|
|
12930
13355
|
this.cwd = cwd;
|
|
12931
13356
|
this.touchRunnerActivity = touchRunnerActivity;
|
|
13357
|
+
this.onRunComplete = onRunComplete;
|
|
12932
13358
|
}
|
|
12933
13359
|
emittedGeneratedImageKeys = /* @__PURE__ */ new Set();
|
|
13360
|
+
emittedSessionMediaKeys = /* @__PURE__ */ new Set();
|
|
12934
13361
|
toolNamesById = /* @__PURE__ */ new Map();
|
|
13362
|
+
toolInputsById = /* @__PURE__ */ new Map();
|
|
13363
|
+
browserRecordingPathHints = /* @__PURE__ */ new Set();
|
|
12935
13364
|
emitEvent(event) {
|
|
12936
13365
|
this.touchRunnerActivity?.();
|
|
12937
13366
|
this.socket.emit("agent.event", {
|
|
@@ -12954,6 +13383,12 @@ var RuntimePresenter = class {
|
|
|
12954
13383
|
}
|
|
12955
13384
|
onToolUse(tool, input, toolId) {
|
|
12956
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
|
+
}
|
|
12957
13392
|
this.emitEvent({ type: "tool_use", id: toolId, name: tool, input, ts: Date.now() });
|
|
12958
13393
|
}
|
|
12959
13394
|
onToolResult(toolId, content, isError) {
|
|
@@ -12966,9 +13401,27 @@ var RuntimePresenter = class {
|
|
|
12966
13401
|
});
|
|
12967
13402
|
if (isError) return;
|
|
12968
13403
|
const toolName = this.toolNamesById.get(toolId);
|
|
12969
|
-
|
|
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
|
+
)) {
|
|
12970
13413
|
this.emitGeneratedImage(image);
|
|
12971
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
|
+
}
|
|
12972
13425
|
}
|
|
12973
13426
|
onGeneratedImage(image) {
|
|
12974
13427
|
this.emitGeneratedImage(image);
|
|
@@ -12979,6 +13432,15 @@ var RuntimePresenter = class {
|
|
|
12979
13432
|
this.emittedGeneratedImageKeys.add(key);
|
|
12980
13433
|
this.emitEvent(image);
|
|
12981
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
|
+
}
|
|
12982
13444
|
onTurnComplete(content) {
|
|
12983
13445
|
this.emitEvent({ type: "turn_complete", content, ts: Date.now() });
|
|
12984
13446
|
}
|
|
@@ -13015,6 +13477,7 @@ var RuntimePresenter = class {
|
|
|
13015
13477
|
}
|
|
13016
13478
|
onComplete(result) {
|
|
13017
13479
|
this.emitEvent({ type: "query_complete", result, ts: Date.now() });
|
|
13480
|
+
this.onRunComplete?.();
|
|
13018
13481
|
}
|
|
13019
13482
|
};
|
|
13020
13483
|
async function setupDaemon(args) {
|
|
@@ -13068,7 +13531,7 @@ async function setupDaemon(args) {
|
|
|
13068
13531
|
runtimeId: body.runtime.id,
|
|
13069
13532
|
runtimeToken: body.runtimeToken,
|
|
13070
13533
|
localApiPort: getLocalApiPort(args, {}),
|
|
13071
|
-
localApiToken: (0,
|
|
13534
|
+
localApiToken: (0, import_node_crypto.randomBytes)(24).toString("hex"),
|
|
13072
13535
|
displayName: body.runtime.displayName ?? displayName
|
|
13073
13536
|
});
|
|
13074
13537
|
console.info("[aiden-agent] Runtime registered", {
|
|
@@ -13119,7 +13582,7 @@ async function loginWithDeviceCode(args) {
|
|
|
13119
13582
|
runtimeId: body.runtime.id,
|
|
13120
13583
|
runtimeToken: body.runtimeToken,
|
|
13121
13584
|
localApiPort: getLocalApiPort(args, {}),
|
|
13122
|
-
localApiToken: (0,
|
|
13585
|
+
localApiToken: (0, import_node_crypto.randomBytes)(24).toString("hex"),
|
|
13123
13586
|
displayName: body.runtime.displayName ?? displayName
|
|
13124
13587
|
});
|
|
13125
13588
|
console.info("[aiden-agent] Runtime registered", {
|
|
@@ -13136,7 +13599,7 @@ async function startDaemon(args) {
|
|
|
13136
13599
|
const runtimeToken = argValue(args, "--token") ?? process.env.AIDEN_RUNTIME_TOKEN ?? stored.runtimeToken;
|
|
13137
13600
|
const wsUrl = argValue(args, "--ws-url") ?? process.env.AIDEN_WS_URL ?? stored.wsUrl;
|
|
13138
13601
|
let localApiPort = getLocalApiPort(args, stored);
|
|
13139
|
-
const localApiToken = stored.localApiToken ?? (0,
|
|
13602
|
+
const localApiToken = stored.localApiToken ?? (0, import_node_crypto.randomBytes)(24).toString("hex");
|
|
13140
13603
|
if (!runtimeId || !runtimeToken || !wsUrl) {
|
|
13141
13604
|
throw new Error(
|
|
13142
13605
|
"daemon requires runtimeId, runtime token, and wsUrl. Run setup first or pass --runtime-id/--token/--ws-url."
|
|
@@ -13195,6 +13658,23 @@ async function startDaemon(args) {
|
|
|
13195
13658
|
pushLog(`disconnected ${reason}`);
|
|
13196
13659
|
console.info("[aiden-agent] Daemon disconnected:", reason);
|
|
13197
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
|
+
});
|
|
13198
13678
|
socket.on("agent.execute", (payload) => {
|
|
13199
13679
|
if (!payload?.runId || !payload.conversationId || typeof payload.content !== "string") {
|
|
13200
13680
|
return;
|
|
@@ -13213,19 +13693,34 @@ async function startDaemon(args) {
|
|
|
13213
13693
|
return;
|
|
13214
13694
|
}
|
|
13215
13695
|
socket.emit("agent.accepted", { runId: payload.runId });
|
|
13696
|
+
const correlation = correlationLogFields({
|
|
13697
|
+
taskId: payload.taskId ?? payload.taskMeta?.id,
|
|
13698
|
+
conversationId: payload.conversationId,
|
|
13699
|
+
runId: payload.runId,
|
|
13700
|
+
messageId: payload.messageId,
|
|
13701
|
+
cloudEnvironmentId: payload.cloudEnvironmentId,
|
|
13702
|
+
backendKind,
|
|
13703
|
+
agentVersion: AGENT_VERSION
|
|
13704
|
+
});
|
|
13216
13705
|
pushLog(`accepted run=${payload.runId}`);
|
|
13217
|
-
|
|
13706
|
+
console.info("[aiden-agent] Agent run accepted", correlation);
|
|
13707
|
+
const cwd = resolveRuntimeCwd(payload);
|
|
13218
13708
|
const nowMs = Date.now();
|
|
13219
13709
|
const touchActivity = () => {
|
|
13220
13710
|
const entry = activeAgents.get(payload.runId);
|
|
13221
13711
|
if (entry) entry.lastActivityAtMs = Date.now();
|
|
13222
13712
|
};
|
|
13713
|
+
const releaseActiveRun = () => {
|
|
13714
|
+
if (!activeAgents.delete(payload.runId)) return;
|
|
13715
|
+
console.info("[aiden-agent] Agent run finished", correlation);
|
|
13716
|
+
};
|
|
13223
13717
|
const presenter = new RuntimePresenter(
|
|
13224
13718
|
socket,
|
|
13225
13719
|
payload.conversationId,
|
|
13226
13720
|
payload.runId,
|
|
13227
13721
|
cwd,
|
|
13228
|
-
touchActivity
|
|
13722
|
+
touchActivity,
|
|
13723
|
+
releaseActiveRun
|
|
13229
13724
|
);
|
|
13230
13725
|
const agent = new CoreAgent(presenter, {
|
|
13231
13726
|
backendKind,
|
|
@@ -13254,7 +13749,7 @@ async function startDaemon(args) {
|
|
|
13254
13749
|
taskMeta: payload.taskMeta,
|
|
13255
13750
|
prMeta: payload.prMeta,
|
|
13256
13751
|
conversationId: payload.conversationId,
|
|
13257
|
-
taskId: payload.taskMeta?.id,
|
|
13752
|
+
taskId: payload.taskId ?? payload.taskMeta?.id,
|
|
13258
13753
|
teamId: payload.teamId,
|
|
13259
13754
|
currentUser: payload.currentUser,
|
|
13260
13755
|
workflowTools: payload.workflowTools,
|
|
@@ -13263,13 +13758,17 @@ async function startDaemon(args) {
|
|
|
13263
13758
|
}).catch((error) => {
|
|
13264
13759
|
const message = error instanceof Error ? error.message : String(error);
|
|
13265
13760
|
pushLog(`failed run=${payload.runId} ${message}`);
|
|
13761
|
+
console.error("[aiden-agent] Agent run failed", {
|
|
13762
|
+
...correlation,
|
|
13763
|
+
error: message
|
|
13764
|
+
});
|
|
13266
13765
|
socket.emit("agent.event", {
|
|
13267
13766
|
conversationId: payload.conversationId,
|
|
13268
13767
|
runId: payload.runId,
|
|
13269
13768
|
event: { type: "session_error", error: message }
|
|
13270
13769
|
});
|
|
13271
13770
|
}).finally(() => {
|
|
13272
|
-
|
|
13771
|
+
releaseActiveRun();
|
|
13273
13772
|
});
|
|
13274
13773
|
});
|
|
13275
13774
|
socket.on("agent.abort", (payload) => {
|
|
@@ -13279,6 +13778,10 @@ async function startDaemon(args) {
|
|
|
13279
13778
|
abortActiveAgent(entry);
|
|
13280
13779
|
activeAgents.delete(payload.runId);
|
|
13281
13780
|
pushLog(`aborted run=${payload.runId}`);
|
|
13781
|
+
console.info("[aiden-agent] Agent run aborted", {
|
|
13782
|
+
runId: payload.runId,
|
|
13783
|
+
agentVersion: AGENT_VERSION
|
|
13784
|
+
});
|
|
13282
13785
|
});
|
|
13283
13786
|
socket.on(
|
|
13284
13787
|
"agent.tool_response",
|
|
@@ -13362,7 +13865,7 @@ async function startDaemon(args) {
|
|
|
13362
13865
|
`${describeOccupiedLocalDaemon(localApiPort)} The token in ${getConfigPath()} no longer matches the running daemon; quit Aiden desktop or run setup again.`
|
|
13363
13866
|
);
|
|
13364
13867
|
}
|
|
13365
|
-
await new Promise((
|
|
13868
|
+
await new Promise((resolve3, reject) => {
|
|
13366
13869
|
const onError = (error) => {
|
|
13367
13870
|
clearInterval(heartbeat);
|
|
13368
13871
|
socket.disconnect();
|
|
@@ -13389,7 +13892,7 @@ async function startDaemon(args) {
|
|
|
13389
13892
|
if (address && typeof address === "object") localApiPort = address.port;
|
|
13390
13893
|
pushLog(`local_api listening port=${localApiPort}`);
|
|
13391
13894
|
console.info("[aiden-agent] Local daemon API listening", { port: localApiPort });
|
|
13392
|
-
|
|
13895
|
+
resolve3();
|
|
13393
13896
|
});
|
|
13394
13897
|
});
|
|
13395
13898
|
let stopped = false;
|
|
@@ -13402,8 +13905,8 @@ async function startDaemon(args) {
|
|
|
13402
13905
|
}
|
|
13403
13906
|
activeAgents.clear();
|
|
13404
13907
|
socket.disconnect();
|
|
13405
|
-
await new Promise((
|
|
13406
|
-
localServer.close(() =>
|
|
13908
|
+
await new Promise((resolve3) => {
|
|
13909
|
+
localServer.close(() => resolve3());
|
|
13407
13910
|
});
|
|
13408
13911
|
};
|
|
13409
13912
|
const controller = {
|
|
@@ -13607,6 +14110,78 @@ async function printDoctor(args = []) {
|
|
|
13607
14110
|
);
|
|
13608
14111
|
}
|
|
13609
14112
|
|
|
14113
|
+
// src/lifecycle-logger.ts
|
|
14114
|
+
var AgentLifecycleLogger = class _AgentLifecycleLogger {
|
|
14115
|
+
context;
|
|
14116
|
+
constructor(context = {}) {
|
|
14117
|
+
this.context = normalizeContext(context);
|
|
14118
|
+
}
|
|
14119
|
+
setContext(context) {
|
|
14120
|
+
this.context = normalizeContext({ ...this.context, ...context });
|
|
14121
|
+
}
|
|
14122
|
+
child(context) {
|
|
14123
|
+
return new _AgentLifecycleLogger({ ...this.context, ...context });
|
|
14124
|
+
}
|
|
14125
|
+
debug(event, fields = {}) {
|
|
14126
|
+
this.log("debug", event, fields);
|
|
14127
|
+
}
|
|
14128
|
+
info(event, fields = {}) {
|
|
14129
|
+
this.log("info", event, fields);
|
|
14130
|
+
}
|
|
14131
|
+
warn(event, fields = {}) {
|
|
14132
|
+
this.log("warn", event, fields);
|
|
14133
|
+
}
|
|
14134
|
+
error(event, fields = {}) {
|
|
14135
|
+
this.log("error", event, fields);
|
|
14136
|
+
}
|
|
14137
|
+
log(level, event, fields) {
|
|
14138
|
+
const record = omitUndefined({
|
|
14139
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14140
|
+
level,
|
|
14141
|
+
component: "sandbox-agent",
|
|
14142
|
+
event,
|
|
14143
|
+
...this.context,
|
|
14144
|
+
...normalizeFields(fields)
|
|
14145
|
+
});
|
|
14146
|
+
console[level](JSON.stringify(record));
|
|
14147
|
+
}
|
|
14148
|
+
};
|
|
14149
|
+
function lifecycleContextFromEnv(env) {
|
|
14150
|
+
return normalizeContext({
|
|
14151
|
+
taskId: env.AIDEN_TASK_ID,
|
|
14152
|
+
conversationId: env.AIDEN_SESSION_ID,
|
|
14153
|
+
runId: env.AIDEN_RUN_ID,
|
|
14154
|
+
sandboxId: env.AIDEN_SANDBOX_ID,
|
|
14155
|
+
provider: env.AIDEN_SANDBOX_PROVIDER,
|
|
14156
|
+
backendKind: env.AIDEN_BACKEND_KIND,
|
|
14157
|
+
agentVersion: AGENT_VERSION
|
|
14158
|
+
});
|
|
14159
|
+
}
|
|
14160
|
+
function normalizeContext(context) {
|
|
14161
|
+
return omitUndefined({
|
|
14162
|
+
...context,
|
|
14163
|
+
agentVersion: context.agentVersion ?? AGENT_VERSION
|
|
14164
|
+
});
|
|
14165
|
+
}
|
|
14166
|
+
function normalizeFields(fields) {
|
|
14167
|
+
const normalized = {};
|
|
14168
|
+
for (const [key, value2] of Object.entries(fields)) {
|
|
14169
|
+
if (value2 instanceof Error) {
|
|
14170
|
+
normalized[key] = {
|
|
14171
|
+
name: value2.name,
|
|
14172
|
+
message: value2.message,
|
|
14173
|
+
stack: value2.stack
|
|
14174
|
+
};
|
|
14175
|
+
} else {
|
|
14176
|
+
normalized[key] = value2;
|
|
14177
|
+
}
|
|
14178
|
+
}
|
|
14179
|
+
return normalized;
|
|
14180
|
+
}
|
|
14181
|
+
function omitUndefined(record) {
|
|
14182
|
+
return Object.fromEntries(Object.entries(record).filter(([, value2]) => value2 !== void 0));
|
|
14183
|
+
}
|
|
14184
|
+
|
|
13610
14185
|
// src/web-presenter.ts
|
|
13611
14186
|
var WebPresenter = class {
|
|
13612
14187
|
constructor(wsClient, _conversationId, cwd) {
|
|
@@ -13615,7 +14190,10 @@ var WebPresenter = class {
|
|
|
13615
14190
|
}
|
|
13616
14191
|
wsClient;
|
|
13617
14192
|
emittedGeneratedImageKeys = /* @__PURE__ */ new Set();
|
|
14193
|
+
emittedSessionMediaKeys = /* @__PURE__ */ new Set();
|
|
13618
14194
|
toolNamesById = /* @__PURE__ */ new Map();
|
|
14195
|
+
toolInputsById = /* @__PURE__ */ new Map();
|
|
14196
|
+
browserRecordingPathHints = /* @__PURE__ */ new Set();
|
|
13619
14197
|
suppressSessionLifecycle = false;
|
|
13620
14198
|
setSuppressSessionLifecycle(suppress) {
|
|
13621
14199
|
this.suppressSessionLifecycle = suppress;
|
|
@@ -13634,6 +14212,12 @@ var WebPresenter = class {
|
|
|
13634
14212
|
}
|
|
13635
14213
|
onToolUse(tool, input, toolId) {
|
|
13636
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
|
+
}
|
|
13637
14221
|
this.wsClient.emitEvent({ type: "tool_use", id: toolId, name: tool, input, ts: Date.now() });
|
|
13638
14222
|
}
|
|
13639
14223
|
onToolResult(toolId, content, isError) {
|
|
@@ -13646,9 +14230,27 @@ var WebPresenter = class {
|
|
|
13646
14230
|
});
|
|
13647
14231
|
if (isError) return;
|
|
13648
14232
|
const toolName = this.toolNamesById.get(toolId);
|
|
13649
|
-
|
|
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
|
+
)) {
|
|
13650
14242
|
this.emitGeneratedImage(image);
|
|
13651
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
|
+
}
|
|
13652
14254
|
}
|
|
13653
14255
|
onGeneratedImage(image) {
|
|
13654
14256
|
this.emitGeneratedImage(image);
|
|
@@ -13659,6 +14261,15 @@ var WebPresenter = class {
|
|
|
13659
14261
|
this.emittedGeneratedImageKeys.add(key);
|
|
13660
14262
|
this.wsClient.emitEvent(image);
|
|
13661
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
|
+
}
|
|
13662
14273
|
onTurnComplete(content) {
|
|
13663
14274
|
this.wsClient.emitEvent({ type: "turn_complete", content, ts: Date.now() });
|
|
13664
14275
|
}
|
|
@@ -13725,8 +14336,9 @@ var WebPresenter = class {
|
|
|
13725
14336
|
|
|
13726
14337
|
// src/ws-client.ts
|
|
13727
14338
|
var WSClient = class {
|
|
13728
|
-
|
|
13729
|
-
|
|
14339
|
+
constructor(wsUrl, sessionId, taskId, token, callbacks, agentVersion, lifecycle) {
|
|
14340
|
+
this.lifecycle = lifecycle;
|
|
14341
|
+
this.lifecycle?.info("sandbox_agent_ws_socket_create", { wsUrl });
|
|
13730
14342
|
this.socket = lookup(wsUrl, {
|
|
13731
14343
|
query: { type: "agent", sessionId, taskId, agentVersion: agentVersion ?? "" },
|
|
13732
14344
|
auth: { token },
|
|
@@ -13741,13 +14353,14 @@ var WSClient = class {
|
|
|
13741
14353
|
});
|
|
13742
14354
|
this.setupListeners(callbacks);
|
|
13743
14355
|
}
|
|
14356
|
+
socket;
|
|
13744
14357
|
emitEvent(event) {
|
|
13745
14358
|
this.socket.emit("agent_event", event);
|
|
13746
14359
|
}
|
|
13747
14360
|
waitForConnection(timeoutMs = 15e3) {
|
|
13748
|
-
return new Promise((
|
|
14361
|
+
return new Promise((resolve3, reject) => {
|
|
13749
14362
|
if (this.socket.connected) {
|
|
13750
|
-
|
|
14363
|
+
resolve3();
|
|
13751
14364
|
return;
|
|
13752
14365
|
}
|
|
13753
14366
|
const timeout = setTimeout(
|
|
@@ -13756,7 +14369,7 @@ var WSClient = class {
|
|
|
13756
14369
|
);
|
|
13757
14370
|
this.socket.once("connect", () => {
|
|
13758
14371
|
clearTimeout(timeout);
|
|
13759
|
-
|
|
14372
|
+
resolve3();
|
|
13760
14373
|
});
|
|
13761
14374
|
this.socket.once("connect_error", (err) => {
|
|
13762
14375
|
clearTimeout(timeout);
|
|
@@ -13767,20 +14380,26 @@ var WSClient = class {
|
|
|
13767
14380
|
get connected() {
|
|
13768
14381
|
return this.socket.connected;
|
|
13769
14382
|
}
|
|
14383
|
+
setLifecycleContext(context) {
|
|
14384
|
+
this.lifecycle?.setContext(context);
|
|
14385
|
+
}
|
|
13770
14386
|
close() {
|
|
14387
|
+
this.lifecycle?.info("sandbox_agent_ws_close_requested");
|
|
13771
14388
|
this.socket.disconnect();
|
|
13772
14389
|
}
|
|
13773
14390
|
setupListeners(callbacks) {
|
|
13774
14391
|
this.socket.on("connect", () => {
|
|
13775
|
-
|
|
14392
|
+
this.lifecycle?.info("sandbox_agent_ws_socket_connected", { socketId: this.socket.id });
|
|
13776
14393
|
callbacks.onConnect?.();
|
|
13777
14394
|
});
|
|
13778
14395
|
this.socket.on("disconnect", (reason) => {
|
|
13779
|
-
|
|
14396
|
+
this.lifecycle?.info("sandbox_agent_ws_socket_disconnected", { reason });
|
|
13780
14397
|
callbacks.onDisconnect?.(reason);
|
|
13781
14398
|
});
|
|
13782
14399
|
this.socket.on("connect_error", (error) => {
|
|
13783
|
-
|
|
14400
|
+
this.lifecycle?.warn("sandbox_agent_ws_socket_connect_error", {
|
|
14401
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
14402
|
+
});
|
|
13784
14403
|
});
|
|
13785
14404
|
this.socket.on(
|
|
13786
14405
|
"user_message",
|
|
@@ -13805,6 +14424,7 @@ var WSClient = class {
|
|
|
13805
14424
|
messageId: data.messageId,
|
|
13806
14425
|
maxIterations: data.maxIterations,
|
|
13807
14426
|
taskId: data.taskId,
|
|
14427
|
+
cloudEnvironmentId: data.cloudEnvironmentId,
|
|
13808
14428
|
conversationId: data.conversationId,
|
|
13809
14429
|
teamId: data.teamId,
|
|
13810
14430
|
currentUser: data.currentUser
|
|
@@ -13820,12 +14440,32 @@ var WSClient = class {
|
|
|
13820
14440
|
}
|
|
13821
14441
|
});
|
|
13822
14442
|
this.socket.on("error", (data) => {
|
|
13823
|
-
|
|
14443
|
+
this.lifecycle?.error("sandbox_agent_ws_server_error", {
|
|
14444
|
+
message: data.message,
|
|
14445
|
+
code: data.code
|
|
14446
|
+
});
|
|
13824
14447
|
});
|
|
13825
14448
|
}
|
|
13826
14449
|
};
|
|
13827
14450
|
|
|
13828
14451
|
// src/sandbox.ts
|
|
14452
|
+
function correlationLogFields2(input) {
|
|
14453
|
+
return Object.fromEntries(
|
|
14454
|
+
Object.entries({
|
|
14455
|
+
taskId: input.taskId,
|
|
14456
|
+
conversationId: input.conversationId,
|
|
14457
|
+
runId: input.runId,
|
|
14458
|
+
messageId: input.messageId,
|
|
14459
|
+
cloudEnvironmentId: input.cloudEnvironmentId,
|
|
14460
|
+
provider: input.backendKind,
|
|
14461
|
+
backendKind: input.backendKind,
|
|
14462
|
+
agentVersion: input.agentVersion
|
|
14463
|
+
}).filter((entry) => {
|
|
14464
|
+
const value2 = entry[1];
|
|
14465
|
+
return typeof value2 === "string" && value2.trim().length > 0;
|
|
14466
|
+
}).map(([key, value2]) => [key, value2.trim()])
|
|
14467
|
+
);
|
|
14468
|
+
}
|
|
13829
14469
|
async function runSandbox(config) {
|
|
13830
14470
|
let currentTask = config.task;
|
|
13831
14471
|
let currentImages = [];
|
|
@@ -13840,15 +14480,26 @@ async function runSandbox(config) {
|
|
|
13840
14480
|
let currentMaxIterations = config.maxIterations ?? 50;
|
|
13841
14481
|
let currentTaskId = config.taskId;
|
|
13842
14482
|
let currentConversationId = config.sessionId;
|
|
14483
|
+
let currentRunId;
|
|
14484
|
+
let currentMessageId;
|
|
14485
|
+
let currentCloudEnvironmentId;
|
|
13843
14486
|
let currentTeamId = config.teamId;
|
|
13844
14487
|
const workflowId = config.workflowId;
|
|
13845
14488
|
const workflowExecutionId = config.workflowExecutionId;
|
|
13846
14489
|
let currentUser = config.currentUser;
|
|
13847
14490
|
let currentTerminalContextRefs;
|
|
13848
14491
|
let currentTerminalSnapshots;
|
|
13849
|
-
|
|
13850
|
-
|
|
13851
|
-
|
|
14492
|
+
const lifecycle = config.lifecycle ?? new AgentLifecycleLogger({
|
|
14493
|
+
taskId: config.taskId,
|
|
14494
|
+
conversationId: config.sessionId,
|
|
14495
|
+
runId: config.runId,
|
|
14496
|
+
sandboxId: config.sandboxId,
|
|
14497
|
+
provider: config.provider,
|
|
14498
|
+
backendKind: config.backendKind,
|
|
14499
|
+
agentVersion: AGENT_VERSION
|
|
14500
|
+
});
|
|
14501
|
+
lifecycle.info("sandbox_agent_ws_connect_attempt", {
|
|
14502
|
+
wsUrl: config.wsUrl
|
|
13852
14503
|
});
|
|
13853
14504
|
const wsClient = new WSClient(
|
|
13854
14505
|
config.wsUrl,
|
|
@@ -13857,16 +14508,41 @@ async function runSandbox(config) {
|
|
|
13857
14508
|
config.sessionToken,
|
|
13858
14509
|
{
|
|
13859
14510
|
onUserMessage: (payload) => {
|
|
14511
|
+
if (payload === null) {
|
|
14512
|
+
if (pendingMessageResolve) {
|
|
14513
|
+
const resolve3 = pendingMessageResolve;
|
|
14514
|
+
pendingMessageResolve = null;
|
|
14515
|
+
resolve3(null);
|
|
14516
|
+
}
|
|
14517
|
+
return;
|
|
14518
|
+
}
|
|
14519
|
+
lifecycle.setContext({
|
|
14520
|
+
runId: payload.runId,
|
|
14521
|
+
taskId: payload.taskId,
|
|
14522
|
+
conversationId: payload.conversationId,
|
|
14523
|
+
backendKind: payload.backendKind
|
|
14524
|
+
});
|
|
14525
|
+
wsClient.setLifecycleContext({
|
|
14526
|
+
runId: payload.runId,
|
|
14527
|
+
taskId: payload.taskId,
|
|
14528
|
+
conversationId: payload.conversationId,
|
|
14529
|
+
backendKind: payload.backendKind
|
|
14530
|
+
});
|
|
14531
|
+
lifecycle.info("sandbox_agent_user_message_received", {
|
|
14532
|
+
messageId: payload.messageId,
|
|
14533
|
+
hasImages: Boolean(payload.images?.length),
|
|
14534
|
+
fileCount: payload.files?.length ?? 0
|
|
14535
|
+
});
|
|
13860
14536
|
if (pendingMessageResolve) {
|
|
13861
|
-
const
|
|
14537
|
+
const resolve3 = pendingMessageResolve;
|
|
13862
14538
|
pendingMessageResolve = null;
|
|
13863
|
-
|
|
14539
|
+
resolve3(payload);
|
|
13864
14540
|
} else {
|
|
13865
14541
|
queuedMessages.push(payload);
|
|
13866
14542
|
}
|
|
13867
14543
|
},
|
|
13868
14544
|
onStop: () => {
|
|
13869
|
-
|
|
14545
|
+
lifecycle.info("sandbox_agent_stop_received");
|
|
13870
14546
|
if (currentAgent) {
|
|
13871
14547
|
const killed = currentAgent.kill();
|
|
13872
14548
|
if (!killed) currentAgent.abort();
|
|
@@ -13876,21 +14552,24 @@ async function runSandbox(config) {
|
|
|
13876
14552
|
if (currentAgent) {
|
|
13877
14553
|
const sent = currentAgent.sendToolResponse(toolId, response);
|
|
13878
14554
|
if (!sent) {
|
|
13879
|
-
|
|
14555
|
+
lifecycle.warn("sandbox_agent_tool_response_delivery_failed", { toolId });
|
|
13880
14556
|
}
|
|
13881
14557
|
} else {
|
|
13882
|
-
|
|
14558
|
+
lifecycle.warn("sandbox_agent_tool_response_without_active_agent", { toolId });
|
|
13883
14559
|
}
|
|
13884
14560
|
},
|
|
13885
|
-
onConnect: () =>
|
|
13886
|
-
onDisconnect: (reason) =>
|
|
14561
|
+
onConnect: () => lifecycle.info("sandbox_agent_ws_connected"),
|
|
14562
|
+
onDisconnect: (reason) => lifecycle.info("sandbox_agent_ws_disconnected", { reason })
|
|
13887
14563
|
},
|
|
13888
|
-
AGENT_VERSION
|
|
14564
|
+
AGENT_VERSION,
|
|
14565
|
+
lifecycle
|
|
13889
14566
|
);
|
|
13890
14567
|
try {
|
|
13891
14568
|
await wsClient.waitForConnection();
|
|
13892
14569
|
} catch (error) {
|
|
13893
|
-
|
|
14570
|
+
lifecycle.error("sandbox_agent_ws_connect_failed", {
|
|
14571
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
14572
|
+
});
|
|
13894
14573
|
process.exit(1);
|
|
13895
14574
|
}
|
|
13896
14575
|
const presenter = new WebPresenter(wsClient, config.sessionId, config.projectPath);
|
|
@@ -13909,8 +14588,33 @@ async function runSandbox(config) {
|
|
|
13909
14588
|
backendKind: activeBackendKind
|
|
13910
14589
|
});
|
|
13911
14590
|
currentAgent = agent;
|
|
14591
|
+
const correlation = correlationLogFields2({
|
|
14592
|
+
taskId: currentTaskId,
|
|
14593
|
+
conversationId: currentConversationId,
|
|
14594
|
+
runId: currentRunId,
|
|
14595
|
+
messageId: currentMessageId,
|
|
14596
|
+
cloudEnvironmentId: currentCloudEnvironmentId,
|
|
14597
|
+
backendKind: activeBackendKind,
|
|
14598
|
+
agentVersion: AGENT_VERSION
|
|
14599
|
+
});
|
|
14600
|
+
console.info("[sandbox] Agent run started", correlation);
|
|
13912
14601
|
let result;
|
|
13913
14602
|
try {
|
|
14603
|
+
lifecycle.setContext({
|
|
14604
|
+
taskId: currentTaskId,
|
|
14605
|
+
conversationId: currentConversationId,
|
|
14606
|
+
backendKind: activeBackendKind
|
|
14607
|
+
});
|
|
14608
|
+
wsClient.setLifecycleContext({
|
|
14609
|
+
taskId: currentTaskId,
|
|
14610
|
+
conversationId: currentConversationId,
|
|
14611
|
+
backendKind: activeBackendKind
|
|
14612
|
+
});
|
|
14613
|
+
lifecycle.info("sandbox_agent_run_start", {
|
|
14614
|
+
mode: activeMode,
|
|
14615
|
+
model: activeModel,
|
|
14616
|
+
maxIterations: currentMaxIterations
|
|
14617
|
+
});
|
|
13914
14618
|
result = await agent.run({
|
|
13915
14619
|
task: currentTask,
|
|
13916
14620
|
maxIterations: currentMaxIterations,
|
|
@@ -13954,7 +14658,13 @@ async function runSandbox(config) {
|
|
|
13954
14658
|
});
|
|
13955
14659
|
} catch (error) {
|
|
13956
14660
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
13957
|
-
console.error("[sandbox] Agent run failed
|
|
14661
|
+
console.error("[sandbox] Agent run failed", {
|
|
14662
|
+
...correlation,
|
|
14663
|
+
error: errorMessage
|
|
14664
|
+
});
|
|
14665
|
+
lifecycle.error("sandbox_agent_run_failed", {
|
|
14666
|
+
error: error instanceof Error ? error : new Error(errorMessage)
|
|
14667
|
+
});
|
|
13958
14668
|
result = {
|
|
13959
14669
|
success: false,
|
|
13960
14670
|
summary: "Agent run failed",
|
|
@@ -13965,13 +14675,23 @@ async function runSandbox(config) {
|
|
|
13965
14675
|
};
|
|
13966
14676
|
}
|
|
13967
14677
|
currentAgent = null;
|
|
14678
|
+
lifecycle.info("sandbox_agent_run_complete", {
|
|
14679
|
+
success: result.success,
|
|
14680
|
+
iterations: result.iterations,
|
|
14681
|
+
error: result.error
|
|
14682
|
+
});
|
|
13968
14683
|
if (result?.providerSessionId) {
|
|
13969
14684
|
lastProviderSessionId = result.providerSessionId;
|
|
13970
14685
|
}
|
|
14686
|
+
console.info("[sandbox] Agent run finished", {
|
|
14687
|
+
...correlation,
|
|
14688
|
+
success: String(result.success),
|
|
14689
|
+
iterations: String(result.iterations)
|
|
14690
|
+
});
|
|
13971
14691
|
if (stopped) break;
|
|
13972
14692
|
}
|
|
13973
|
-
const nextPayload = queuedMessages.shift() ?? await new Promise((
|
|
13974
|
-
pendingMessageResolve =
|
|
14693
|
+
const nextPayload = queuedMessages.shift() ?? await new Promise((resolve3) => {
|
|
14694
|
+
pendingMessageResolve = resolve3;
|
|
13975
14695
|
});
|
|
13976
14696
|
if (nextPayload === null || stopped) {
|
|
13977
14697
|
break;
|
|
@@ -14018,6 +14738,15 @@ async function runSandbox(config) {
|
|
|
14018
14738
|
if (nextPayload.taskId !== void 0) {
|
|
14019
14739
|
currentTaskId = nextPayload.taskId;
|
|
14020
14740
|
}
|
|
14741
|
+
if (nextPayload.runId !== void 0) {
|
|
14742
|
+
currentRunId = nextPayload.runId;
|
|
14743
|
+
}
|
|
14744
|
+
if (nextPayload.messageId !== void 0) {
|
|
14745
|
+
currentMessageId = nextPayload.messageId;
|
|
14746
|
+
}
|
|
14747
|
+
if (nextPayload.cloudEnvironmentId !== void 0) {
|
|
14748
|
+
currentCloudEnvironmentId = nextPayload.cloudEnvironmentId;
|
|
14749
|
+
}
|
|
14021
14750
|
if (nextPayload.conversationId !== void 0) {
|
|
14022
14751
|
currentConversationId = nextPayload.conversationId;
|
|
14023
14752
|
}
|
|
@@ -14035,6 +14764,7 @@ async function runSandbox(config) {
|
|
|
14035
14764
|
}
|
|
14036
14765
|
}
|
|
14037
14766
|
presenter.setSuppressSessionLifecycle(false);
|
|
14767
|
+
lifecycle.info("sandbox_agent_process_exit");
|
|
14038
14768
|
wsClient.close();
|
|
14039
14769
|
}
|
|
14040
14770
|
|
|
@@ -14057,20 +14787,28 @@ async function runSessionFromEnv() {
|
|
|
14057
14787
|
const providerSessionId = process.env.AIDEN_PROVIDER_SESSION_ID || void 0;
|
|
14058
14788
|
const workflowId = process.env.AIDEN_WORKFLOW_ID || void 0;
|
|
14059
14789
|
const workflowExecutionId = process.env.AIDEN_WORKFLOW_EXECUTION_ID || void 0;
|
|
14790
|
+
const sandboxId = process.env.AIDEN_SANDBOX_ID || void 0;
|
|
14791
|
+
const provider = process.env.AIDEN_SANDBOX_PROVIDER || void 0;
|
|
14792
|
+
const runId = process.env.AIDEN_RUN_ID || void 0;
|
|
14793
|
+
const lifecycle = new AgentLifecycleLogger(lifecycleContextFromEnv(process.env));
|
|
14060
14794
|
if (!wsUrl || !sessionId || !taskId || !sessionToken || task == null) {
|
|
14795
|
+
lifecycle.error("sandbox_agent_bootstrap_missing_env", {
|
|
14796
|
+
hasWsUrl: Boolean(wsUrl),
|
|
14797
|
+
hasConversationId: Boolean(sessionId),
|
|
14798
|
+
hasTaskId: Boolean(taskId),
|
|
14799
|
+
hasSessionToken: Boolean(sessionToken),
|
|
14800
|
+
hasTask: task != null
|
|
14801
|
+
});
|
|
14061
14802
|
throw new Error(
|
|
14062
14803
|
"run-session is an internal Aiden sandbox/session command and must be launched by Aiden with session env vars. Missing required env vars: AIDEN_WS_URL, AIDEN_SESSION_ID, AIDEN_TASK_ID, AIDEN_SESSION_TOKEN, AIDEN_TASK"
|
|
14063
14804
|
);
|
|
14064
14805
|
}
|
|
14065
|
-
|
|
14806
|
+
lifecycle.info("sandbox_agent_process_start", {
|
|
14066
14807
|
sessionId,
|
|
14067
|
-
taskId,
|
|
14068
14808
|
projectPath,
|
|
14069
|
-
backendKind,
|
|
14070
14809
|
agentId,
|
|
14071
14810
|
mode,
|
|
14072
|
-
model
|
|
14073
|
-
version: AGENT_VERSION
|
|
14811
|
+
model
|
|
14074
14812
|
});
|
|
14075
14813
|
await runSandbox({
|
|
14076
14814
|
wsUrl,
|
|
@@ -14090,6 +14828,10 @@ async function runSessionFromEnv() {
|
|
|
14090
14828
|
providerSessionId,
|
|
14091
14829
|
workflowId,
|
|
14092
14830
|
workflowExecutionId,
|
|
14831
|
+
sandboxId,
|
|
14832
|
+
provider,
|
|
14833
|
+
runId,
|
|
14834
|
+
lifecycle,
|
|
14093
14835
|
maxIterations: 50
|
|
14094
14836
|
});
|
|
14095
14837
|
}
|
|
@@ -14149,7 +14891,9 @@ async function main() {
|
|
|
14149
14891
|
${HELP_TEXT}`);
|
|
14150
14892
|
}
|
|
14151
14893
|
main().catch((error) => {
|
|
14152
|
-
|
|
14894
|
+
new AgentLifecycleLogger(lifecycleContextFromEnv(process.env)).error("sandbox_agent_fatal", {
|
|
14895
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
14896
|
+
});
|
|
14153
14897
|
process.exit(1);
|
|
14154
14898
|
});
|
|
14155
14899
|
/*! Bundled license information:
|