@alan-ai-hq/agent-manager-darwin-arm64 0.1.148 → 0.1.149

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.
Files changed (3) hide show
  1. package/alan-agent.cjs +472 -121
  2. package/alan-holder.cjs +259 -51
  3. package/package.json +1 -1
package/alan-agent.cjs CHANGED
@@ -22236,6 +22236,7 @@ Team
22236
22236
  - Scan available context (task, subtasks, code, history) before asking questions you can answer yourself.
22237
22237
  - Challenge when off \u2014 never silently implement the wrong thing.
22238
22238
  - Act on the user's request and make reasonable implementation and tool choices within its scope. Do not ask again for permission already granted. Ask only when essential information is missing or an action requires additional authority.
22239
+ - When a user asks to create a Skill, default to a team-owned Alan platform Skill through \`alan-skill-authoring\`, whether this session runs locally or in a cloud sandbox. Use a repository or filesystem Skill only when the user explicitly requests that scope. Do not infer repository scope from the current checkout or from a procedure that mentions repository files. If repeated work suggests a reusable Skill, offer the platform Skill and its evidence; do not publish it without the approval required by the authoring workflow.
22239
22240
  - Own mistakes. Wrong ID, jumped too fast \u2014 say so and fix it.
22240
22241
  - Write for a human reader. Task, subtask and epic descriptions, documents, artifacts and comments are read by people in the app, not parsed by agents. Lead with the outcome in one sentence, then short sections with headings and bullet lists. Spell out internal shorthand, and keep commit hashes, IDs and migration numbers out of sentences \u2014 put them in a trailing "References" list when they matter.
22241
22242
  - Think visually, proactively \u2014 not only when asked. Mermaid over paragraphs for architecture, flows, state, and schema. The same applies to data: when you're about to present a comparison, trend, breakdown, or status across several items, reach for a \`\`\`chart fence instead of a paragraph of numbers or a markdown table, even if the user never said the word "chart."
@@ -22497,7 +22498,7 @@ var init_chunk_YXWJW7I5 = __esm({
22497
22498
  }
22498
22499
  });
22499
22500
 
22500
- // ../agent-core/dist/chunk-M6YHY2EZ.js
22501
+ // ../agent-core/dist/chunk-XE7BX6YP.js
22501
22502
  function windowsEnvValue(env, name) {
22502
22503
  const wanted = name.toLowerCase();
22503
22504
  for (const [key, value2] of Object.entries(env).reverse()) {
@@ -22546,6 +22547,36 @@ function unwrapNativeShim(shim, args, files) {
22546
22547
  const file2 = import_path.win32.resolve(directory, target.replace(/^%dp0%\\/i, ""));
22547
22548
  return files.isFile(file2) ? { kind: "native", file: file2, args } : void 0;
22548
22549
  }
22550
+ function binTargets(manifest) {
22551
+ if (typeof manifest !== "object" || manifest === null || !("bin" in manifest)) return [];
22552
+ const { bin } = manifest;
22553
+ if (typeof bin === "string") return [bin];
22554
+ if (typeof bin !== "object" || bin === null) return [];
22555
+ return Object.values(bin).filter((target) => typeof target === "string");
22556
+ }
22557
+ function parseManifest(text3) {
22558
+ try {
22559
+ return JSON.parse(text3);
22560
+ } catch {
22561
+ return void 0;
22562
+ }
22563
+ }
22564
+ function isDeclaredPackageBin(script, files) {
22565
+ const wanted = script.toLowerCase();
22566
+ let dir = import_path.win32.dirname(script);
22567
+ while (import_path.win32.basename(dir).toLowerCase() !== "node_modules") {
22568
+ const text3 = files.readShim(import_path.win32.join(dir, "package.json"));
22569
+ if (text3 !== void 0) {
22570
+ return binTargets(parseManifest(text3)).some(
22571
+ (target) => import_path.win32.resolve(dir, target).toLowerCase() === wanted
22572
+ );
22573
+ }
22574
+ const parent = import_path.win32.dirname(dir);
22575
+ if (parent === dir) return false;
22576
+ dir = parent;
22577
+ }
22578
+ return false;
22579
+ }
22549
22580
  function isSimpleNodeShim(text3) {
22550
22581
  return text3.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).every((line) => /^@?echo off$/i.test(line) || NODE_SHIM_ENTRY.test(line));
22551
22582
  }
@@ -22562,6 +22593,7 @@ function unwrapNodeShim(shim, args, env, files) {
22562
22593
  const dir = import_path.win32.dirname(shim);
22563
22594
  const script = import_path.win32.resolve(dir, scriptTemplate.replace(/%dp0%|%~dp0/gi, `${dir}\\`));
22564
22595
  if (script.includes("%") || !files.isFile(script)) return void 0;
22596
+ if (!SCRIPT_EXTENSION.test(script) && !isDeclaredPackageBin(script, files)) return void 0;
22565
22597
  const local = import_path.win32.join(dir, "node.exe");
22566
22598
  const node2 = program.toLowerCase() === "%_prog%" ? files.isFile(local) ? local : resolveWindowsCommand("node", env, files) : program;
22567
22599
  if (node2 === void 0 || node2.includes("%")) return void 0;
@@ -23105,9 +23137,9 @@ function waitForSpawn(child, command) {
23105
23137
  child.once("error", onError);
23106
23138
  });
23107
23139
  }
23108
- var import_child_process, import_fs, import_path, import_child_process2, import_promises9, import_child_process3, import_child_process4, import_child_process5, import_child_process6, import_crypto, import_fs2, import_promises10, import_os, import_path2, SHIM_MAX_BYTES, CMD_MAX_COMMAND_LINE, MAX_COMMAND_LINE, DEFAULT_PATHEXT, LAUNCHABLE_EXTENSIONS, nodeWindowsFiles, NODE_SHIM_ENTRY, NATIVE_SHIM_LINES, NATIVE_SHIM_ENTRY, CMD_META, NEVER_STARTED, HIDDEN_FLAG_PROBE_VALUE, NEWLINE, CARRIAGE_RETURN, EMPTY, MAX_LINE_BYTES, LineSplitter, PS_LINE, POLL_MS, DEFAULT_GRACE_MS, DEFAULT_KILL_WAIT_MS, DEFAULT_TASKKILL_TIMEOUT_MS, statuses, START_TIMEOUT_MS, spawnListeners;
23109
- var init_chunk_M6YHY2EZ = __esm({
23110
- "../agent-core/dist/chunk-M6YHY2EZ.js"() {
23140
+ var import_child_process, import_fs, import_path, import_child_process2, import_promises9, import_child_process3, import_child_process4, import_child_process5, import_child_process6, import_crypto, import_fs2, import_promises10, import_os, import_path2, SHIM_MAX_BYTES, CMD_MAX_COMMAND_LINE, MAX_COMMAND_LINE, DEFAULT_PATHEXT, LAUNCHABLE_EXTENSIONS, nodeWindowsFiles, NODE_SHIM_ENTRY, SCRIPT_EXTENSION, NATIVE_SHIM_LINES, NATIVE_SHIM_ENTRY, CMD_META, NEVER_STARTED, HIDDEN_FLAG_PROBE_VALUE, NEWLINE, CARRIAGE_RETURN, EMPTY, MAX_LINE_BYTES, LineSplitter, PS_LINE, POLL_MS, DEFAULT_GRACE_MS, DEFAULT_KILL_WAIT_MS, DEFAULT_TASKKILL_TIMEOUT_MS, statuses, START_TIMEOUT_MS, spawnListeners;
23141
+ var init_chunk_XE7BX6YP = __esm({
23142
+ "../agent-core/dist/chunk-XE7BX6YP.js"() {
23111
23143
  "use strict";
23112
23144
  init_chunk_YXWJW7I5();
23113
23145
  import_child_process = require("child_process");
@@ -23146,7 +23178,8 @@ var init_chunk_M6YHY2EZ = __esm({
23146
23178
  }
23147
23179
  }
23148
23180
  };
23149
- NODE_SHIM_ENTRY = /"(%_prog%|[^"\r\n]*node(?:\.exe)?)"\s+"([^"\r\n]+\.(?:c?js|mjs))"\s+%\*/i;
23181
+ NODE_SHIM_ENTRY = /"(%_prog%|[^"\r\n]*node(?:\.exe)?)"\s+"([^"\r\n]+)"\s+%\*/i;
23182
+ SCRIPT_EXTENSION = /\.(?:c?js|mjs)$/i;
23150
23183
  NATIVE_SHIM_LINES = [
23151
23184
  /^@echo off$/i,
23152
23185
  /^goto start$/i,
@@ -24959,18 +24992,66 @@ function toolContentText(content) {
24959
24992
  }
24960
24993
  return parts4.join("\n");
24961
24994
  }
24962
- function parsedFromRawOutput(update) {
24995
+ function isStringArray(value2) {
24996
+ return Array.isArray(value2) && value2.every((part) => typeof part === "string");
24997
+ }
24998
+ function quoteArg(arg) {
24999
+ return /^[\w@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replaceAll("'", `'\\''`)}'`;
25000
+ }
25001
+ function joinArgv(argv) {
25002
+ return argv.map(quoteArg).join(" ");
25003
+ }
25004
+ function unquote(value2) {
25005
+ const quote = value2[0];
25006
+ if (quote !== "'" && quote !== '"' || value2.at(-1) !== quote || value2.length < 2)
25007
+ return value2;
25008
+ const body = value2.slice(1, -1);
25009
+ return quote === "'" ? body.replaceAll(`'\\''`, "'") : body.replace(/\\(["\\$`])/g, "$1");
25010
+ }
25011
+ function unwrapShellCommand(command) {
25012
+ const match = /^\s*(?:\S*\/)?(?:ba|z|da|k)?sh\s+-[a-z]*c[a-z]*\s+([\s\S]+)$/.exec(command.trimEnd());
25013
+ if (!match)
25014
+ return command;
25015
+ const inner = unquote(match[1]);
25016
+ return inner.trim() ? inner : command;
25017
+ }
25018
+ function jsonRecord(value2) {
25019
+ if (!value2.trimStart().startsWith("{"))
25020
+ return void 0;
25021
+ try {
25022
+ const parsed = JSON.parse(value2);
25023
+ return isRecord8(parsed) ? parsed : void 0;
25024
+ } catch {
25025
+ return void 0;
25026
+ }
25027
+ }
25028
+ function toolInputRecord(input2) {
25029
+ if (isRecord8(input2))
25030
+ return input2;
25031
+ return typeof input2 === "string" ? jsonRecord(input2) : void 0;
25032
+ }
25033
+ function wrappedToolNames(input2) {
25034
+ const args = isRecord8(input2.args) ? input2.args : toolInputRecord(input2.arguments) ?? toolInputRecord(input2.Arguments);
25035
+ return [input2, args].flatMap((record2) => record2 ? WRAPPED_TOOL_NAME_KEYS.map((key) => record2[key]) : []);
25036
+ }
25037
+ function isContextSearchName(name) {
25038
+ if (typeof name !== "string" || name.length > 200)
25039
+ return false;
25040
+ const normalized2 = name.toLowerCase().replace(/[_\s"-]/g, "");
25041
+ return normalized2.endsWith("searchcontext") && !normalized2.endsWith("searchcodecontext");
25042
+ }
25043
+ function outputIsRead(update, input2 = toolInputRecord(update.rawInput)) {
24963
25044
  const name = typeof update.name === "string" ? update.name : typeof update.title === "string" ? update.title : "";
24964
- if (isAskUserQuestionTool(name, update.rawInput))
25045
+ if (isAskUserQuestionTool(name, input2 ?? update.rawInput))
24965
25046
  return true;
24966
- const input2 = typeof update.rawInput === "string" ? update.rawInput : JSON.stringify(update.rawInput ?? null);
24967
- return /search_?context/i.test(`${name} ${input2}`.replace(/search_?code_?context/gi, ""));
25047
+ const meta3 = isRecord8(update._meta) ? update._meta : {};
25048
+ return isContextSearchName(update.name) || isContextSearchName(update.title) || isContextSearchName(meta3["alan.dev/toolName"]) || input2 !== void 0 && wrappedToolNames(input2).some(isContextSearchName);
24968
25049
  }
24969
25050
  function repeatsContent(update) {
24970
25051
  const output2 = update.rawOutput;
24971
25052
  if (typeof output2 !== "string" || output2.length === 0)
24972
25053
  return false;
24973
- return output2 === toolContentText(update.content) && !parsedFromRawOutput(update);
25054
+ return output2 === toolContentText(update.content) && !outputIsRead(update);
24974
25055
  }
24975
25056
  function withoutProviderCopiesOf(value2) {
24976
25057
  if (!value2._meta || !hasProviderCopy(value2._meta))
@@ -25000,18 +25081,54 @@ function pageNode(node2) {
25000
25081
  children: node2.children.map(pageNode)
25001
25082
  };
25002
25083
  }
25003
- function rendersBesideSteps(update) {
25084
+ function rendersBesideSteps(update, input2) {
25004
25085
  const meta3 = isRecord8(update._meta) ? update._meta : {};
25005
- return parsedFromRawOutput(update) || meta3["alan.dev/subagentLauncher"] !== void 0 || meta3["alan.dev/backgroundTask"] !== void 0;
25086
+ return outputIsRead(update, input2) || meta3["alan.dev/subagentLauncher"] !== void 0 || meta3["alan.dev/backgroundTask"] !== void 0;
25006
25087
  }
25007
25088
  function diffWithoutText(block2) {
25008
25089
  const inner = isRecord8(block2) && block2.type === "content" ? block2.content : block2;
25009
25090
  if (!isRecord8(inner) || inner.type !== "diff")
25010
25091
  return null;
25011
- const path4 = typeof inner.path === "string" ? { path: inner.path } : {};
25012
- const stub = { type: "diff", ...path4 };
25092
+ const stub = {
25093
+ type: "diff",
25094
+ ...typeof inner.path === "string" ? { path: inner.path } : {},
25095
+ ...isRecord8(inner.diff) && Array.isArray(inner.diff.changes) ? { diff: { changes: inner.diff.changes } } : {}
25096
+ };
25013
25097
  return isRecord8(block2) && block2.type === "content" ? { ...block2, content: stub } : stub;
25014
25098
  }
25099
+ function cappedText(value2) {
25100
+ if (value2.length <= STEP_INPUT_TEXT_LIMIT)
25101
+ return value2;
25102
+ const head = value2.slice(0, STEP_INPUT_TEXT_LIMIT - STEP_INPUT_TEXT_TAIL - 1);
25103
+ return `${head}\u2026${value2.slice(-STEP_INPUT_TEXT_TAIL)}`;
25104
+ }
25105
+ function stepInputValue(value2, command) {
25106
+ const text3 = typeof value2 === "string" ? value2 : command && isStringArray(value2) ? joinArgv(value2) : void 0;
25107
+ if (text3 !== void 0 && text3.length > STEP_INPUT_TEXT_LIMIT)
25108
+ return { value: cappedText(command ? unwrapShellCommand(text3) : text3), truncated: true };
25109
+ if (text3 !== void 0 || value2 === null || typeof value2 !== "object")
25110
+ return { value: value2, truncated: false };
25111
+ return JSON.stringify(value2).length <= STEP_INPUT_TEXT_LIMIT ? { value: value2, truncated: false } : { value: void 0, truncated: true };
25112
+ }
25113
+ function stepInputRecord(input2) {
25114
+ const fields = {};
25115
+ let truncated = false;
25116
+ for (const key of Object.keys(input2)) {
25117
+ if (!STEP_INPUT_FIELDS.has(key))
25118
+ continue;
25119
+ const field3 = stepInputValue(input2[key], COMMAND_INPUT_FIELDS.has(key));
25120
+ truncated ||= field3.truncated;
25121
+ if (field3.value !== void 0)
25122
+ fields[key] = field3.value;
25123
+ }
25124
+ return { value: fields, truncated };
25125
+ }
25126
+ function stepInput(input2, record2) {
25127
+ if (!record2)
25128
+ return stepInputValue(input2, false);
25129
+ const projected = stepInputRecord(record2);
25130
+ return typeof input2 === "string" ? { value: JSON.stringify(projected.value), truncated: projected.truncated } : projected;
25131
+ }
25015
25132
  function stepSummary(node2) {
25016
25133
  const update = node2.event.update;
25017
25134
  const children = node2.children.map(stepSummary);
@@ -25019,13 +25136,25 @@ function stepSummary(node2) {
25019
25136
  const { output: _output, ...rest2 } = update;
25020
25137
  return { ...node2, event: { ...node2.event, update: rest2 }, children };
25021
25138
  }
25022
- if (update.sessionUpdate !== "tool_call_update" || rendersBesideSteps(update))
25139
+ if (update.sessionUpdate !== "tool_call_update")
25023
25140
  return { ...node2, children };
25024
- const { content, rawOutput: _rawOutput, ...rest } = update;
25141
+ const inputRecord = toolInputRecord(update.rawInput);
25142
+ if (rendersBesideSteps(update, inputRecord))
25143
+ return { ...node2, children };
25144
+ const { content, rawOutput: _rawOutput, rawInput, ...rest } = update;
25145
+ const input2 = stepInput(rawInput, inputRecord);
25025
25146
  const diffs = (Array.isArray(content) ? content : []).map(diffWithoutText).filter((block2) => block2 !== null);
25026
25147
  return {
25027
25148
  ...node2,
25028
- event: { ...node2.event, update: diffs.length > 0 ? { ...rest, content: diffs } : rest },
25149
+ event: {
25150
+ ...node2.event,
25151
+ update: {
25152
+ ...rest,
25153
+ ...input2.value === void 0 ? {} : { rawInput: input2.value },
25154
+ ...input2.truncated ? { inputTruncated: true } : {},
25155
+ ...diffs.length > 0 ? { content: diffs } : {}
25156
+ }
25157
+ },
25029
25158
  children
25030
25159
  };
25031
25160
  }
@@ -25054,35 +25183,53 @@ function compactDisplayTurn(displayTurn) {
25054
25183
  };
25055
25184
  }
25056
25185
  function compactConversationMessageTurns(turns, keepNewestEntries, includeStepOutputs = true) {
25057
- return turns.map((turn, index) => ({
25058
- ...turn,
25059
- display: turn.display.map((displayTurn) => {
25060
- const compacted = compactDisplayTurn(displayTurn);
25061
- return includeStepOutputs ? compacted : withStepSummaries(compacted, turn.ordinal);
25062
- }),
25063
- state: {
25064
- ...turn.state,
25065
- // Readers use only media updates from `unknown`; a provider's command list alone was 77 KB.
25066
- unknown: turn.state.unknown.filter((update) => MEDIA_SESSION_UPDATE_KINDS.has(update.sessionUpdate)),
25067
- entries: index === 0 && keepNewestEntries ? turn.state.entries.map((entry) => {
25068
- const kept = withoutProviderCopiesOf(entry);
25069
- if (kept.kind === "message")
25070
- return kept.role === "user" ? kept : { ...kept, content: [] };
25071
- const ask = isAskUserQuestionTool(kept.title || kept.toolKind, kept.rawInput);
25072
- return {
25073
- ...kept,
25074
- content: [],
25075
- locations: [],
25076
- rawInput: ask ? kept.rawInput : void 0,
25077
- rawOutput: void 0
25078
- };
25079
- }) : []
25080
- }
25081
- }));
25186
+ return turns.map((turn, index) => {
25187
+ const newest = index === 0 && keepNewestEntries;
25188
+ return {
25189
+ ...turn,
25190
+ // Summaries go first, so `pageNode` never compares the outputs they drop with their content.
25191
+ display: turn.display.map((displayTurn) => compactDisplayTurn(includeStepOutputs ? displayTurn : withStepSummaries(displayTurn, turn.ordinal))),
25192
+ // Readers look up interactive tools on the conversation's newest turn only.
25193
+ read: newest ? turn.read : { ...turn.read, interactiveTools: [] },
25194
+ state: {
25195
+ ...turn.state,
25196
+ // Readers use only media updates from `unknown`; a provider's command list alone was 77 KB.
25197
+ unknown: turn.state.unknown.filter((update) => MEDIA_SESSION_UPDATE_KINDS.has(update.sessionUpdate)),
25198
+ entries: newest ? turn.state.entries.map((entry) => {
25199
+ const kept = withoutProviderCopiesOf(entry);
25200
+ if (kept.kind === "message")
25201
+ return kept.role === "user" ? kept : { ...kept, content: [] };
25202
+ const ask = isAskUserQuestionTool(kept.title || kept.toolKind, kept.rawInput);
25203
+ return {
25204
+ ...kept,
25205
+ content: [],
25206
+ locations: [],
25207
+ rawInput: ask ? kept.rawInput : void 0,
25208
+ rawOutput: void 0
25209
+ };
25210
+ }) : []
25211
+ }
25212
+ };
25213
+ });
25214
+ }
25215
+ function messagePreview(text3) {
25216
+ return toPreviewText(text3.slice(0, 960).replace(attachmentMentionPattern(), ""), 240);
25217
+ }
25218
+ function replyPreview(replies) {
25219
+ for (let index = replies.length - 1; index >= 0; index -= 1) {
25220
+ const content = messageText2(replies[index]);
25221
+ if (!/\S/.test(content))
25222
+ continue;
25223
+ const preview = messagePreview(content);
25224
+ if (preview)
25225
+ return preview;
25226
+ }
25227
+ return void 0;
25082
25228
  }
25083
25229
  function prepareConversationTurnRead(state) {
25084
25230
  const prompts = [];
25085
25231
  const navigation = [];
25232
+ const replies = [];
25086
25233
  const interactiveTools = [];
25087
25234
  let modeChange = null;
25088
25235
  let latestAgentMessageId = null;
@@ -25100,20 +25247,16 @@ function prepareConversationTurnRead(state) {
25100
25247
  references: Array.isArray(meta3["alan.dev/references"]) ? meta3["alan.dev/references"] : void 0
25101
25248
  });
25102
25249
  }
25103
- const title = toPreviewText(messageText2(entry).slice(0, 960).replace(attachmentMentionPattern(), ""), 240);
25250
+ const title = messagePreview(messageText2(entry));
25104
25251
  navigation.push({ id: entry.id, title: title || "Message with attachments" });
25252
+ replies.push([]);
25105
25253
  continue;
25106
25254
  }
25107
25255
  if (entry.kind === "message" && entry.role === "agent" && navigation.length > 0) {
25108
25256
  latestAgentMessageId = entry.id;
25109
25257
  if (typeof entry._meta?.["alan.dev/parentToolCallId"] === "string")
25110
25258
  continue;
25111
- const content = messageText2(entry);
25112
- if (!/\S/.test(content))
25113
- continue;
25114
- const preview = toPreviewText(content.slice(0, 960).replace(attachmentMentionPattern(), ""), 240);
25115
- if (preview)
25116
- navigation[navigation.length - 1].preview = preview;
25259
+ replies[replies.length - 1].push(entry);
25117
25260
  continue;
25118
25261
  }
25119
25262
  if (entry.kind === "message" && entry.role === "agent") {
@@ -25152,7 +25295,10 @@ function prepareConversationTurnRead(state) {
25152
25295
  entryCount: state.entries.length,
25153
25296
  latestAgentMessageId,
25154
25297
  prompts,
25155
- navigation,
25298
+ navigation: navigation.map((item, index) => {
25299
+ const preview = replyPreview(replies[index]);
25300
+ return preview ? { ...item, preview } : item;
25301
+ }),
25156
25302
  modeChange,
25157
25303
  pendingAsk: findPendingAsk(state.entries),
25158
25304
  interactiveTools
@@ -25233,7 +25379,7 @@ function isConversationMessageTurn(value2) {
25233
25379
  function isConversationMessagesPage(value2) {
25234
25380
  return isRecord8(value2) && typeof value2.revision === "string" && typeof value2.streamCursor === "string" && (value2.before === null || typeof value2.before === "string") && Array.isArray(value2.turns) && value2.turns.every(isConversationMessageTurn);
25235
25381
  }
25236
- var PROVIDER_PAYLOAD_META_KEY, PROVIDER_EVENT_META_KEY, PROVIDER_COPY_META_KEYS, LIVE_TURN_FRAMES, LIVE_TURN_EVENT, SENT_LIVE_TURNS;
25382
+ var PROVIDER_PAYLOAD_META_KEY, PROVIDER_EVENT_META_KEY, PROVIDER_COPY_META_KEYS, WRAPPED_TOOL_NAME_KEYS, STEP_INPUT_FIELDS, COMMAND_INPUT_FIELDS, STEP_INPUT_TEXT_LIMIT, STEP_INPUT_TEXT_TAIL, LIVE_TURN_FRAMES, LIVE_TURN_EVENT, SENT_LIVE_TURNS;
25237
25383
  var init_conversation_messages = __esm({
25238
25384
  "../shared/dist/agent/acp/conversation-messages.js"() {
25239
25385
  "use strict";
@@ -25251,6 +25397,26 @@ var init_conversation_messages = __esm({
25251
25397
  PROVIDER_PAYLOAD_META_KEY,
25252
25398
  PROVIDER_EVENT_META_KEY
25253
25399
  ]);
25400
+ WRAPPED_TOOL_NAME_KEYS = ["toolName", "tool_name", "ToolName", "name"];
25401
+ STEP_INPUT_FIELDS = /* @__PURE__ */ new Set([
25402
+ "title",
25403
+ "description",
25404
+ "command",
25405
+ "cmd",
25406
+ "code",
25407
+ "path",
25408
+ "filePath",
25409
+ "file_path",
25410
+ "url",
25411
+ "query",
25412
+ "pattern",
25413
+ "search_query",
25414
+ "subagent_type",
25415
+ "run_in_background"
25416
+ ]);
25417
+ COMMAND_INPUT_FIELDS = /* @__PURE__ */ new Set(["command", "cmd", "code"]);
25418
+ STEP_INPUT_TEXT_LIMIT = 1024;
25419
+ STEP_INPUT_TEXT_TAIL = 256;
25254
25420
  LIVE_TURN_FRAMES = "patch";
25255
25421
  LIVE_TURN_EVENT = "live_turn";
25256
25422
  SENT_LIVE_TURNS = 8;
@@ -25308,7 +25474,7 @@ function scopeTranscriptEvent(value2) {
25308
25474
  meta3["alan.dev/parentToolCallId"] = `${turnId}:${parent}`;
25309
25475
  if (typeof update.toolCallId === "string")
25310
25476
  meta3[TRANSCRIPT_TOOL_RESPONSE_ID_META] = update.toolCallId;
25311
- if (typeof update.sessionUpdate === "string" && MEDIA_SESSION_UPDATE_KINDS.has(update.sessionUpdate))
25477
+ if (typeof update.sessionUpdate === "string" && (MEDIA_SESSION_UPDATE_KINDS.has(update.sessionUpdate) || update.sessionUpdate === "agent_message_chunk"))
25312
25478
  meta3[TRANSCRIPT_TURN_ID_META] = turnId;
25313
25479
  const scoped = { ...update, _meta: meta3 };
25314
25480
  for (const key of ["messageId", "toolCallId", "terminalId", "planId"]) {
@@ -26036,7 +26202,7 @@ var init_chunk_SBT5W7L4 = __esm({
26036
26202
  }
26037
26203
  });
26038
26204
 
26039
- // ../agent-core/dist/chunk-HBIPWAUI.js
26205
+ // ../agent-core/dist/chunk-ZCTKXKYY.js
26040
26206
  function readCapReset(text3) {
26041
26207
  const epoch = EPOCH_RESET.exec(text3);
26042
26208
  if (epoch) return { resetsAt: new Date(Number(epoch[1]) * 1e3).toISOString() };
@@ -26243,8 +26409,8 @@ function createCliProblem(observed, options) {
26243
26409
  });
26244
26410
  }
26245
26411
  var import_crypto2, EPOCH_RESET, WORDED_RESET, CODEX_RESET, ERROR_SPECS, AGENT_ERROR_KINDS, AGENT_SIGN_IN_BY_HARNESS, STATUS_PREFIX, TEXT_RULES, CODEX_TIMEOUT_MESSAGE, CODEX_EXPIRED_MESSAGE, COMMAND_NOT_FOUND, CODE_RULES, TEXT_REFINES, STATUS_LEAD, CLI_PROBLEM_CODE_BY_ERROR_KIND, KEY_REJECTION_KINDS;
26246
- var init_chunk_HBIPWAUI = __esm({
26247
- "../agent-core/dist/chunk-HBIPWAUI.js"() {
26412
+ var init_chunk_ZCTKXKYY = __esm({
26413
+ "../agent-core/dist/chunk-ZCTKXKYY.js"() {
26248
26414
  "use strict";
26249
26415
  init_chunk_YXWJW7I5();
26250
26416
  import_crypto2 = require("crypto");
@@ -26435,7 +26601,7 @@ var init_chunk_HBIPWAUI = __esm({
26435
26601
  },
26436
26602
  {
26437
26603
  kind: "overloaded",
26438
- pattern: /\boverloaded(?:_error)?\b|\bat capacity\b|\bserver_overloaded\b|\b(?:http|status|code|error)\s*:?\s*5\d\d\b|\[5\d\d\]|\bapi error:?\s*5\d\d\b|\b5\d\d (?:internal server error|bad gateway|service unavailable|gateway timeout)\b|\bservice unavailable\b|\bbad gateway\b|\bgateway timeout\b/
26604
+ pattern: /\boverloaded(?:_error)?\b|\bat capacity\b|\bserver_overloaded\b|\b(?:http|status|code|error)\s*:?\s*5\d\d\b|\[5\d\d\]|\bapi error:?\s*5\d\d\b|\b5\d\d (?:internal server error|bad gateway|service unavailable|gateway timeout)\b|\bservice unavailable\b|\bbad gateway\b|\bgateway timeout\b|\bapi server (?:encountered an error|returned an error|is unavailable)\b/
26439
26605
  },
26440
26606
  {
26441
26607
  kind: "context_length",
@@ -26443,7 +26609,7 @@ var init_chunk_HBIPWAUI = __esm({
26443
26609
  },
26444
26610
  {
26445
26611
  kind: "network",
26446
- pattern: /\b(?:econnrefused|econnreset|enotfound|etimedout|eai_again|ehostunreach|enetunreach)\b|\bfetch failed\b|\bnetwork (?:error|failure|is unreachable|connection (?:failed|lost))\b|\b(?:request|connection|socket) (?:timed out|timeout)\b|\bconnection reset by peer\b/
26612
+ pattern: /\b(?:econnrefused|econnreset|enotfound|etimedout|eai_again|ehostunreach|enetunreach)\b|\bfetch failed\b|\bnetwork (?:error|failure|is unreachable|connection (?:failed|lost))\b|\b(?:request|connection|socket) (?:timed out|timeout)\b|\bconnection reset by peer\b|\bunable to connect to the (?:api|server)\b|\bcould not connect to the (?:api|server)\b|\bplease check your network connection\b/
26447
26613
  },
26448
26614
  // launchd hands GUI daemons PATH=/usr/bin:/bin:/usr/sbin:/sbin, so `#!/usr/bin/env node`
26449
26615
  // fails even though node is installed under nvm/fnm/volta.
@@ -26508,7 +26674,7 @@ var init_chunk_HBIPWAUI = __esm({
26508
26674
  }
26509
26675
  });
26510
26676
 
26511
- // ../agent-core/dist/chunk-4G77APXN.js
26677
+ // ../agent-core/dist/chunk-A2TG6ROT.js
26512
26678
  function detectImageMimeType(buffer) {
26513
26679
  if (buffer.length >= 8 && buffer.subarray(0, 8).equals(PNG_SIGNATURE)) return "image/png";
26514
26680
  if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) {
@@ -26826,10 +26992,26 @@ function createNdjsonWriter(stream) {
26826
26992
  }
26827
26993
  function hostProcess(child, tree, options, handlers) {
26828
26994
  const writer = createNdjsonWriter(child.stdin);
26829
- const flags = { closing: false, outputClosedEarly: false, lastScan: Number.NEGATIVE_INFINITY };
26995
+ const flags = {
26996
+ closing: false,
26997
+ outputClosedEarly: false,
26998
+ lastScan: Number.NEGATIVE_INFINITY,
26999
+ lastOutputAt: void 0
27000
+ };
26830
27001
  const terminate = () => tree.terminate({ graceMs: options.terminateGraceMs });
26831
- readNdjson(child.stdout, { onLine: (line) => handlers.onLine(line) });
26832
- const stderr = new LineSplitter((line) => handlers.onStderrLine(line));
27002
+ const heard = () => {
27003
+ flags.lastOutputAt = options.clock.monotonic();
27004
+ };
27005
+ readNdjson(child.stdout, {
27006
+ onLine: (line) => {
27007
+ heard();
27008
+ handlers.onLine(line);
27009
+ }
27010
+ });
27011
+ const stderr = new LineSplitter((line) => {
27012
+ heard();
27013
+ handlers.onStderrLine(line);
27014
+ });
26833
27015
  child.stderr.on("data", (chunk) => stderr.push(chunk));
26834
27016
  child.stderr.once("end", () => stderr.flush());
26835
27017
  const processExit = new Promise((resolve14) => {
@@ -26862,6 +27044,9 @@ function hostProcess(child, tree, options, handlers) {
26862
27044
  };
26863
27045
  return {
26864
27046
  pid: child.pid,
27047
+ get lastOutputAt() {
27048
+ return flags.lastOutputAt;
27049
+ },
26865
27050
  writer,
26866
27051
  exited: watch(),
26867
27052
  terminate,
@@ -26892,12 +27077,12 @@ function silentStartError(name, timeoutMs) {
26892
27077
  };
26893
27078
  }
26894
27079
  var import_crypto3, import_fs4, import_path3, PNG_SIGNATURE, IMAGE_MIME_BY_EXT, VIDEO_MIME_BY_EXT, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, AGENT_BROWSER_MENTION, LocalMediaReader, SessionOpenRefusal, JsonRpcError, ACP_PROTOCOL_VERSION, ACP_ERROR, STDERR_TAIL_LINES, RESULT_EXIT_GRACE_MS, PerTurnSession;
26895
- var init_chunk_4G77APXN = __esm({
26896
- "../agent-core/dist/chunk-4G77APXN.js"() {
27080
+ var init_chunk_A2TG6ROT = __esm({
27081
+ "../agent-core/dist/chunk-A2TG6ROT.js"() {
26897
27082
  "use strict";
26898
27083
  init_chunk_XC5676SG();
26899
- init_chunk_HBIPWAUI();
26900
- init_chunk_M6YHY2EZ();
27084
+ init_chunk_ZCTKXKYY();
27085
+ init_chunk_XE7BX6YP();
26901
27086
  init_chunk_YXWJW7I5();
26902
27087
  import_crypto3 = require("crypto");
26903
27088
  import_fs4 = require("fs");
@@ -27056,6 +27241,7 @@ var init_chunk_4G77APXN = __esm({
27056
27241
  #sessionId;
27057
27242
  #pid;
27058
27243
  #current;
27244
+ #host;
27059
27245
  constructor(provider4, options, resumeId) {
27060
27246
  this.#provider = provider4;
27061
27247
  this.#options = options;
@@ -27071,6 +27257,9 @@ var init_chunk_4G77APXN = __esm({
27071
27257
  get pid() {
27072
27258
  return this.#current ? this.#pid : void 0;
27073
27259
  }
27260
+ get lastOutputAt() {
27261
+ return this.#current ? this.#host?.lastOutputAt : void 0;
27262
+ }
27074
27263
  onEvent(listener) {
27075
27264
  return this.#listeners.add(listener);
27076
27265
  }
@@ -27210,6 +27399,7 @@ var init_chunk_4G77APXN = __esm({
27210
27399
  }
27211
27400
  }
27212
27401
  );
27402
+ this.#host = host;
27213
27403
  active.interrupt = () => tree.interrupt();
27214
27404
  active.terminate = () => host.terminate();
27215
27405
  try {
@@ -29310,11 +29500,11 @@ var init_claude = __esm({
29310
29500
  "../agent-core/dist/providers/claude.js"() {
29311
29501
  "use strict";
29312
29502
  init_chunk_SBT5W7L4();
29313
- init_chunk_4G77APXN();
29503
+ init_chunk_A2TG6ROT();
29314
29504
  init_chunk_XC5676SG();
29315
- init_chunk_HBIPWAUI();
29505
+ init_chunk_ZCTKXKYY();
29316
29506
  init_chunk_J2KTV5FP();
29317
- init_chunk_M6YHY2EZ();
29507
+ init_chunk_XE7BX6YP();
29318
29508
  init_chunk_GI3ZGXTY();
29319
29509
  init_chunk_YXWJW7I5();
29320
29510
  init_effort();
@@ -29964,6 +30154,9 @@ var init_claude = __esm({
29964
30154
  get pid() {
29965
30155
  return this.#host.pid;
29966
30156
  }
30157
+ get lastOutputAt() {
30158
+ return this.#host.lastOutputAt;
30159
+ }
29967
30160
  onEvent(listener) {
29968
30161
  return this.#listeners.add(listener);
29969
30162
  }
@@ -32169,11 +32362,11 @@ var init_codex = __esm({
32169
32362
  "../agent-core/dist/providers/codex.js"() {
32170
32363
  "use strict";
32171
32364
  init_chunk_SBT5W7L4();
32172
- init_chunk_4G77APXN();
32365
+ init_chunk_A2TG6ROT();
32173
32366
  init_chunk_XC5676SG();
32174
- init_chunk_HBIPWAUI();
32367
+ init_chunk_ZCTKXKYY();
32175
32368
  init_chunk_J2KTV5FP();
32176
- init_chunk_M6YHY2EZ();
32369
+ init_chunk_XE7BX6YP();
32177
32370
  init_chunk_GI3ZGXTY();
32178
32371
  init_chunk_YXWJW7I5();
32179
32372
  import_fs6 = require("fs");
@@ -32722,6 +32915,9 @@ var init_codex = __esm({
32722
32915
  get pid() {
32723
32916
  return this.#host.pid;
32724
32917
  }
32918
+ get lastOutputAt() {
32919
+ return this.#host.lastOutputAt;
32920
+ }
32725
32921
  get exited() {
32726
32922
  return this.#host.exited;
32727
32923
  }
@@ -33395,7 +33591,8 @@ function alanCodeConfigContent(existing, input2) {
33395
33591
  baseURL: input2.baseURL,
33396
33592
  apiKey: `{env:${ALAN_CODE_API_KEY_ENV}}`,
33397
33593
  headers: { [MANAGED_MCP_CONVERSATION_HEADER]: `{env:${ALAN_CODE_CONVERSATION_ID_ENV}}` },
33398
- setCacheKey: true
33594
+ setCacheKey: true,
33595
+ chunkTimeout: ALAN_CODE_CHUNK_TIMEOUT_MS
33399
33596
  },
33400
33597
  models: Object.fromEntries(input2.models.map((model) => [model.id, engineModel(model)]))
33401
33598
  }
@@ -33687,7 +33884,7 @@ function alanCodeSystemPrompt(alanSystemPrompt) {
33687
33884
 
33688
33885
  ${instructions}` : ALAN_CODE_TOOL_NAMING_PROMPT;
33689
33886
  }
33690
- var import_http9, import_https, import_fs7, import_path7, import_crypto12, import_promises34, import_path8, import_url, ALAN_CODE_BASELINE_PROMPT, ALAN_CODE_ENGINE_PROVIDER_ID, DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_OUTPUT_TOKENS, ALAN_CODE_API_KEY_ENV, ALAN_CODE_CONVERSATION_ID_ENV, ALAN_CODE_PROXY_PATH, ALAN_CODE_WEBSEARCH_PATH, ALAN_CODE_CATALOG_PATH, CATALOG_TIMEOUT_MS, MAX_CATALOG_BYTES, ACTIVATION_WAIT_MS, ACTIVATION_POLL_MS, CatalogResponseError, ALAN_CODE_ENGINE_PATH_ENV, ALAN_CODE_ENGINE_COMMAND, ALAN_CODE_ENGINE_NAME, WINDOWS_RUNNABLE_EXTENSION, ALAN_CODE_ENGINE_PLUGIN_VERSION, ALAN_CODE_TOOL_NAMING_PROMPT;
33887
+ var import_http9, import_https, import_fs7, import_path7, import_crypto12, import_promises34, import_path8, import_url, ALAN_CODE_BASELINE_PROMPT, ALAN_CODE_ENGINE_PROVIDER_ID, DEFAULT_CONTEXT_WINDOW, DEFAULT_MAX_OUTPUT_TOKENS, ALAN_CODE_API_KEY_ENV, ALAN_CODE_CONVERSATION_ID_ENV, ALAN_CODE_PROXY_PATH, ALAN_CODE_WEBSEARCH_PATH, ALAN_CODE_CATALOG_PATH, ALAN_CODE_CHUNK_TIMEOUT_MS, CATALOG_TIMEOUT_MS, MAX_CATALOG_BYTES, ACTIVATION_WAIT_MS, ACTIVATION_POLL_MS, CatalogResponseError, ALAN_CODE_ENGINE_PATH_ENV, ALAN_CODE_ENGINE_COMMAND, ALAN_CODE_ENGINE_NAME, WINDOWS_RUNNABLE_EXTENSION, ALAN_CODE_ENGINE_PLUGIN_VERSION, ALAN_CODE_TOOL_NAMING_PROMPT;
33691
33888
  var init_alan_code = __esm({
33692
33889
  "../agent-core/dist/providers/alan-code.js"() {
33693
33890
  "use strict";
@@ -33713,6 +33910,7 @@ var init_alan_code = __esm({
33713
33910
  ALAN_CODE_PROXY_PATH = "/public/harness/v1";
33714
33911
  ALAN_CODE_WEBSEARCH_PATH = "/public/harness/v1/websearch";
33715
33912
  ALAN_CODE_CATALOG_PATH = "/public/harness/models";
33913
+ ALAN_CODE_CHUNK_TIMEOUT_MS = 18e4;
33716
33914
  CATALOG_TIMEOUT_MS = 5e3;
33717
33915
  MAX_CATALOG_BYTES = 1024 * 1024;
33718
33916
  ACTIVATION_WAIT_MS = 1e4;
@@ -43506,10 +43704,10 @@ var require_tar_stream = __commonJS({
43506
43704
  var init_dist = __esm({
43507
43705
  "../agent-core/dist/index.js"() {
43508
43706
  "use strict";
43509
- init_chunk_4G77APXN();
43707
+ init_chunk_A2TG6ROT();
43510
43708
  init_chunk_XC5676SG();
43511
- init_chunk_HBIPWAUI();
43512
- init_chunk_M6YHY2EZ();
43709
+ init_chunk_ZCTKXKYY();
43710
+ init_chunk_XE7BX6YP();
43513
43711
  init_chunk_YXWJW7I5();
43514
43712
  }
43515
43713
  });
@@ -44253,11 +44451,11 @@ var import_promises50, import_path9, import_crypto13, import_promises51, CURSOR_
44253
44451
  var init_acp3 = __esm({
44254
44452
  "../agent-core/dist/providers/acp.js"() {
44255
44453
  "use strict";
44256
- init_chunk_4G77APXN();
44454
+ init_chunk_A2TG6ROT();
44257
44455
  init_chunk_XC5676SG();
44258
- init_chunk_HBIPWAUI();
44456
+ init_chunk_ZCTKXKYY();
44259
44457
  init_chunk_J2KTV5FP();
44260
- init_chunk_M6YHY2EZ();
44458
+ init_chunk_XE7BX6YP();
44261
44459
  init_chunk_GI3ZGXTY();
44262
44460
  init_chunk_YXWJW7I5();
44263
44461
  import_promises50 = require("fs/promises");
@@ -44596,6 +44794,9 @@ var init_acp3 = __esm({
44596
44794
  get pid() {
44597
44795
  return this.#host.pid;
44598
44796
  }
44797
+ get lastOutputAt() {
44798
+ return this.#host.lastOutputAt;
44799
+ }
44599
44800
  get exited() {
44600
44801
  return this.#host.exited;
44601
44802
  }
@@ -45070,7 +45271,7 @@ var init_acp3 = __esm({
45070
45271
  var init_classify = __esm({
45071
45272
  "../agent-core/dist/classify.js"() {
45072
45273
  "use strict";
45073
- init_chunk_HBIPWAUI();
45274
+ init_chunk_ZCTKXKYY();
45074
45275
  init_chunk_YXWJW7I5();
45075
45276
  }
45076
45277
  });
@@ -45088,6 +45289,65 @@ var init_driver = __esm({
45088
45289
  function sessionContextFor(opened, inputs) {
45089
45290
  return opened.fresh ? inputs.agentContext?.full : inputs.agentContext?.update;
45090
45291
  }
45292
+ function autoRetryDelayMs(attempt2) {
45293
+ return AUTO_RETRY_BASE_DELAY_MS * 2 ** (attempt2 - 1);
45294
+ }
45295
+ function isAutoRecoverable(error61) {
45296
+ return error61.recoveryClass === "auto_recovering";
45297
+ }
45298
+ function countsAsProviderWork(update) {
45299
+ return !NON_WORK_UPDATE_KINDS.has(update.sessionUpdate);
45300
+ }
45301
+ function silentTurnError(displayName, timeoutMs) {
45302
+ return {
45303
+ ...specForErrorKind("provider_timeout"),
45304
+ message: `${displayName} printed nothing for ${Math.round(timeoutMs / 1e3)}s after the message was sent and was stopped. Send your message again.`
45305
+ };
45306
+ }
45307
+ async function sendWithFirstOutputDeadline(deadline, send2) {
45308
+ const { session, clock, timeoutMs } = deadline;
45309
+ const startedAt = clock.monotonic();
45310
+ const stop = new AbortController();
45311
+ const state = { expired: false };
45312
+ const silent = () => !deadline.heard() && !deadline.signal.aborted && (session.lastOutputAt === void 0 || session.lastOutputAt <= startedAt);
45313
+ void clock.sleep(timeoutMs, stop.signal).then(() => {
45314
+ if (clock.monotonic() - startedAt < timeoutMs || !silent()) return;
45315
+ state.expired = true;
45316
+ deadline.onExpired();
45317
+ void session.cancel();
45318
+ }).catch(() => void 0);
45319
+ try {
45320
+ const result = await send2();
45321
+ if (!state.expired) return result;
45322
+ await session.suspend().catch(() => void 0);
45323
+ return {
45324
+ ...result,
45325
+ outcome: { status: "failed", error: silentTurnError(deadline.displayName, timeoutMs) }
45326
+ };
45327
+ } finally {
45328
+ stop.abort();
45329
+ }
45330
+ }
45331
+ async function sendTurnWithRetry(options) {
45332
+ let result = await options.send();
45333
+ for (let attempt2 = 1; ; attempt2 += 1) {
45334
+ const failure6 = result.outcome.status === "failed" ? result.outcome.error : void 0;
45335
+ if (failure6 === void 0 || !isAutoRecoverable(failure6) || options.sawWork() || options.signal.aborted || attempt2 > MAX_AUTO_RETRIES) {
45336
+ return result;
45337
+ }
45338
+ options.log.info("holder.turn_auto_retry", {
45339
+ harness: options.harness,
45340
+ runId: options.runId,
45341
+ attempt: attempt2,
45342
+ errorKind: failure6.errorKind
45343
+ });
45344
+ options.reportRetry(attempt2);
45345
+ options.beginRetry();
45346
+ await options.clock.sleep(autoRetryDelayMs(attempt2), options.signal).catch(() => void 0);
45347
+ if (options.signal.aborted) return { ...result, outcome: { status: "cancelled" } };
45348
+ result = await options.send();
45349
+ }
45350
+ }
45091
45351
  function errorMessage(error61) {
45092
45352
  return error61 instanceof Error ? error61.message : String(error61);
45093
45353
  }
@@ -45188,7 +45448,16 @@ function createPersistentDriver(provider4, options) {
45188
45448
  try {
45189
45449
  const { session } = opened;
45190
45450
  const seq = { next: 1 };
45451
+ let sawWork = false;
45452
+ let heardFromProvider = false;
45453
+ let announcedSpawn = false;
45454
+ const announceSpawn = (pid) => {
45455
+ if (announcedSpawn) return;
45456
+ announcedSpawn = true;
45457
+ sink.onSpawned(pid);
45458
+ };
45191
45459
  const record2 = (update) => {
45460
+ if (countsAsProviderWork(update)) sawWork = true;
45192
45461
  sink.onEvent({
45193
45462
  seq: seq.next++,
45194
45463
  at: clock.now(),
@@ -45210,13 +45479,16 @@ function createPersistentDriver(provider4, options) {
45210
45479
  if (!("turnId" in event) || event.turnId !== spec.runId) return;
45211
45480
  switch (event.type) {
45212
45481
  case "spawned":
45213
- sink.onSpawned(event.pid);
45482
+ announceSpawn(event.pid);
45214
45483
  return;
45215
45484
  case "awaiting_input":
45485
+ heardFromProvider = true;
45486
+ sawWork = true;
45216
45487
  for (const toolCallId of event.toolCallIds) turn.waiting.add(toolCallId);
45217
45488
  record2(awaitingUpdate(turn.waiting));
45218
45489
  return;
45219
45490
  case "update":
45491
+ heardFromProvider = true;
45220
45492
  recordWithMedia(event.update);
45221
45493
  return;
45222
45494
  default:
@@ -45226,7 +45498,7 @@ function createPersistentDriver(provider4, options) {
45226
45498
  const _events = __using(_stack, session.onEvent(forward));
45227
45499
  live.turn = turn;
45228
45500
  record2({ sessionUpdate: "state_update", state: "running" });
45229
- if (session.pid !== void 0) sink.onSpawned(session.pid);
45501
+ if (session.pid !== void 0) announceSpawn(session.pid);
45230
45502
  const onAbort = () => {
45231
45503
  void session.cancel();
45232
45504
  };
@@ -45235,7 +45507,44 @@ function createPersistentDriver(provider4, options) {
45235
45507
  const contextPrefix = [sessionContextFor(opened, inputs), opened.contextPrefix].filter((part) => part !== void 0).join("\n\n");
45236
45508
  const input2 = await provider4.turnInput(spec, inputs, contextPrefix || void 0);
45237
45509
  if (signal.aborted) return { outcome: "aborted" };
45238
- const result = await session.sendTurn(input2);
45510
+ const timeoutMs = options.firstOutputTimeoutMs ?? FIRST_OUTPUT_TIMEOUT_MS;
45511
+ const deadline = {
45512
+ session,
45513
+ displayName: provider4.displayName,
45514
+ clock,
45515
+ signal,
45516
+ timeoutMs,
45517
+ heard: () => heardFromProvider,
45518
+ onExpired: () => log.warn("holder.first_output_timeout", {
45519
+ harness: provider4.harness,
45520
+ runId: spec.runId,
45521
+ pid: session.pid,
45522
+ timeoutMs
45523
+ })
45524
+ };
45525
+ const result = await sendWithFirstOutputDeadline(
45526
+ deadline,
45527
+ () => sendTurnWithRetry({
45528
+ harness: provider4.harness,
45529
+ runId: spec.runId,
45530
+ log,
45531
+ clock,
45532
+ signal,
45533
+ send: () => session.sendTurn(input2),
45534
+ sawWork: () => sawWork,
45535
+ beginRetry: () => {
45536
+ sawWork = false;
45537
+ turn.waiting.clear();
45538
+ },
45539
+ reportRetry: (attempt2) => record2(
45540
+ noticeUpdate(
45541
+ "info",
45542
+ "provider_retry",
45543
+ `Provider error \u2014 retrying (attempt ${attempt2 + 1} of ${MAX_AUTO_RETRIES + 1}).`
45544
+ )
45545
+ )
45546
+ })
45547
+ );
45239
45548
  live.providerSessionId = result.providerSessionId ?? live.providerSessionId;
45240
45549
  if (result.outcome.status === "failed" && result.outcome.error.errorKind === "history_rejected") {
45241
45550
  await forgetRejectedSession(session);
@@ -45342,7 +45651,7 @@ function awaitingUpdate(waiting) {
45342
45651
  _meta: { [AWAITING_TOOL_CALLS_META2]: [...waiting] }
45343
45652
  };
45344
45653
  }
45345
- var RESUME_UNAVAILABLE;
45654
+ var RESUME_UNAVAILABLE, MAX_AUTO_RETRIES, AUTO_RETRY_BASE_DELAY_MS, NON_WORK_UPDATE_KINDS, FIRST_OUTPUT_TIMEOUT_MS;
45346
45655
  var init_persistent = __esm({
45347
45656
  "src/holder/drivers/persistent.ts"() {
45348
45657
  "use strict";
@@ -45351,6 +45660,21 @@ var init_persistent = __esm({
45351
45660
  init_classify();
45352
45661
  init_driver();
45353
45662
  RESUME_UNAVAILABLE = "The previous session could not be resumed on this machine, so a fresh session was started.";
45663
+ MAX_AUTO_RETRIES = 2;
45664
+ AUTO_RETRY_BASE_DELAY_MS = 1e3;
45665
+ NON_WORK_UPDATE_KINDS = /* @__PURE__ */ new Set([
45666
+ "notice",
45667
+ "usage_update",
45668
+ "state_update",
45669
+ "session_info_update",
45670
+ "available_commands_update",
45671
+ "config_option_update",
45672
+ "user_message",
45673
+ "user_message_chunk",
45674
+ "_alan/log",
45675
+ "_alan/thinking_tokens"
45676
+ ]);
45677
+ FIRST_OUTPUT_TIMEOUT_MS = 3e5;
45354
45678
  }
45355
45679
  });
45356
45680
 
@@ -45989,15 +46313,15 @@ function openCodeTurnInput(run2, context) {
45989
46313
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
45990
46314
  };
45991
46315
  }
45992
- var import_http10, import_crypto14, import_promises52, import_path10, import_path11, import_url2, import_crypto15, IDLE_SOCKET_MS3, OpenCodeHttpError, OpenCodeClient, OPENCODE_CONFIG_ENV, OPENCODE_ENGINE, TEXT_PARTS, STEP_PARTS, STOPPED_BY_USER, OpenCodeSubagents, NAMED_KINDS, OPENCODE_ABORTED_ERROR, PROVIDER_EVENT_META, TASK_TOOL_NAME, TASK_RESULT_TAG, TASK_ERROR_TAG, PERMISSION_DENIED, FILE_OPERATIONS2, PartReader, NOTHING, NON_INTERACTIVE_PERMISSIONS, CONTENT_FILTER_FINISHES, OUTPUT_PARTS, OpenCodeTurn, LISTENING, OUTPUT_TAIL_LINES, IMAGE_TYPES, OpenCodeSession, OPENCODE_MIN_VERSION, OPENCODE_REQUIREMENT, OPENCODE_TESTED_LINE, OPENCODE_SUPPORTED_MAJOR, DEFAULTS4, STORE_LOCKED, NON_INTERACTIVE_RULES, TITLE_LENGTH, MAX_VARIANT_LENGTH;
46316
+ var import_http10, import_crypto14, import_promises52, import_path10, import_path11, import_url2, import_crypto15, IDLE_SOCKET_MS3, OpenCodeHttpError, OpenCodeClient, OPENCODE_CONFIG_ENV, OPENCODE_ENGINE, TEXT_PARTS, STEP_PARTS, STOPPED_BY_USER, OpenCodeSubagents, NAMED_KINDS, OPENCODE_ABORTED_ERROR, PROVIDER_EVENT_META, TASK_TOOL_NAME, TASK_RESULT_TAG, TASK_ERROR_TAG, PERMISSION_DENIED, FILE_OPERATIONS2, PartReader, NOTHING, NON_INTERACTIVE_PERMISSIONS, CONTENT_FILTER_FINISHES, TRUNCATED_FINISHES, OUTPUT_PARTS, OpenCodeTurn, LISTENING, OUTPUT_TAIL_LINES, IMAGE_TYPES, OpenCodeSession, OPENCODE_MIN_VERSION, OPENCODE_REQUIREMENT, OPENCODE_TESTED_LINE, OPENCODE_SUPPORTED_MAJOR, DEFAULTS4, STORE_LOCKED, NON_INTERACTIVE_RULES, TITLE_LENGTH, MAX_VARIANT_LENGTH;
45993
46317
  var init_opencode = __esm({
45994
46318
  "../agent-core/dist/providers/opencode.js"() {
45995
46319
  "use strict";
45996
- init_chunk_4G77APXN();
46320
+ init_chunk_A2TG6ROT();
45997
46321
  init_chunk_XC5676SG();
45998
- init_chunk_HBIPWAUI();
46322
+ init_chunk_ZCTKXKYY();
45999
46323
  init_chunk_J2KTV5FP();
46000
- init_chunk_M6YHY2EZ();
46324
+ init_chunk_XE7BX6YP();
46001
46325
  init_chunk_GI3ZGXTY();
46002
46326
  init_chunk_YXWJW7I5();
46003
46327
  import_http10 = require("http");
@@ -46475,6 +46799,7 @@ var init_opencode = __esm({
46475
46799
  "plan_exit"
46476
46800
  ]);
46477
46801
  CONTENT_FILTER_FINISHES = /* @__PURE__ */ new Set(["content-filter", "content_filter"]);
46802
+ TRUNCATED_FINISHES = /* @__PURE__ */ new Set(["unknown", "error"]);
46478
46803
  OUTPUT_PARTS = /* @__PURE__ */ new Set(["text", "reasoning", "thinking", "tool"]);
46479
46804
  OpenCodeTurn = class {
46480
46805
  #root;
@@ -46689,6 +47014,15 @@ var init_opencode = __esm({
46689
47014
  }
46690
47015
  };
46691
47016
  }
47017
+ if (this.#finish && TRUNCATED_FINISHES.has(this.#finish)) {
47018
+ return {
47019
+ status: "failed",
47020
+ error: {
47021
+ ...specForErrorKind("provider_error"),
47022
+ message: "The model's response stream ended before the turn finished. Send your message again to continue."
47023
+ }
47024
+ };
47025
+ }
46692
47026
  if (this.#finish && this.#outputParts.size === 0) {
46693
47027
  return {
46694
47028
  status: "failed",
@@ -46812,6 +47146,9 @@ var init_opencode = __esm({
46812
47146
  get pid() {
46813
47147
  return this.#host.pid;
46814
47148
  }
47149
+ get lastOutputAt() {
47150
+ return this.#host.lastOutputAt;
47151
+ }
46815
47152
  get exited() {
46816
47153
  return this.#host.exited;
46817
47154
  }
@@ -47028,6 +47365,7 @@ var init_opencode = __esm({
47028
47365
  const info = asRecord(last?.info);
47029
47366
  if (asString(info?.role) !== "assistant" || this.#current !== active) return;
47030
47367
  if (asFiniteNumber(asRecord(info?.time)?.completed) === void 0) return;
47368
+ if (asString(info?.finish) === "tool-calls") return;
47031
47369
  if (active.earlierUserMessages.has(asString(info?.parentID))) return;
47032
47370
  const parts22 = asArray(last?.parts).flatMap((part) => {
47033
47371
  const record2 = asRecord(part);
@@ -47813,11 +48151,11 @@ var import_crypto16, import_promises53, FACTORY_API_VERSION, FACTORY_PROTOCOL_VE
47813
48151
  var init_droid = __esm({
47814
48152
  "../agent-core/dist/providers/droid.js"() {
47815
48153
  "use strict";
47816
- init_chunk_4G77APXN();
48154
+ init_chunk_A2TG6ROT();
47817
48155
  init_chunk_XC5676SG();
47818
- init_chunk_HBIPWAUI();
48156
+ init_chunk_ZCTKXKYY();
47819
48157
  init_chunk_J2KTV5FP();
47820
- init_chunk_M6YHY2EZ();
48158
+ init_chunk_XE7BX6YP();
47821
48159
  init_chunk_GI3ZGXTY();
47822
48160
  init_chunk_YXWJW7I5();
47823
48161
  init_runtime_v2();
@@ -48004,6 +48342,9 @@ var init_droid = __esm({
48004
48342
  get pid() {
48005
48343
  return this.#host.pid;
48006
48344
  }
48345
+ get lastOutputAt() {
48346
+ return this.#host.lastOutputAt;
48347
+ }
48007
48348
  get exited() {
48008
48349
  return this.#host.exited;
48009
48350
  }
@@ -48920,10 +49261,10 @@ var init_antigravity = __esm({
48920
49261
  "../agent-core/dist/providers/antigravity.js"() {
48921
49262
  "use strict";
48922
49263
  init_chunk_SBT5W7L4();
48923
- init_chunk_4G77APXN();
49264
+ init_chunk_A2TG6ROT();
48924
49265
  init_chunk_XC5676SG();
48925
- init_chunk_HBIPWAUI();
48926
- init_chunk_M6YHY2EZ();
49266
+ init_chunk_ZCTKXKYY();
49267
+ init_chunk_XE7BX6YP();
48927
49268
  init_chunk_GI3ZGXTY();
48928
49269
  init_chunk_YXWJW7I5();
48929
49270
  import_promises54 = require("fs/promises");
@@ -49624,11 +49965,11 @@ var import_promises55, import_path15, import_crypto18, COMMAND_CODE_GRAMMAR_NAME
49624
49965
  var init_command_code = __esm({
49625
49966
  "../agent-core/dist/providers/command-code.js"() {
49626
49967
  "use strict";
49627
- init_chunk_4G77APXN();
49968
+ init_chunk_A2TG6ROT();
49628
49969
  init_chunk_XC5676SG();
49629
- init_chunk_HBIPWAUI();
49970
+ init_chunk_ZCTKXKYY();
49630
49971
  init_chunk_J2KTV5FP();
49631
- init_chunk_M6YHY2EZ();
49972
+ init_chunk_XE7BX6YP();
49632
49973
  init_chunk_GI3ZGXTY();
49633
49974
  init_chunk_YXWJW7I5();
49634
49975
  import_promises55 = require("fs/promises");
@@ -55027,7 +55368,7 @@ var require_websocket_server = __commonJS({
55027
55368
  // package.json
55028
55369
  var package_default = {
55029
55370
  name: "@alan-ai-hq/agent-manager",
55030
- version: "0.1.148",
55371
+ version: "0.1.149",
55031
55372
  private: true,
55032
55373
  type: "module",
55033
55374
  description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
@@ -57131,7 +57472,7 @@ async function push(context, request2) {
57131
57472
  var import_node_child_process = require("child_process");
57132
57473
 
57133
57474
  // ../agent-core/dist/process.js
57134
- init_chunk_M6YHY2EZ();
57475
+ init_chunk_XE7BX6YP();
57135
57476
  init_chunk_YXWJW7I5();
57136
57477
 
57137
57478
  // src/capabilities/git/run-git.ts
@@ -71134,6 +71475,36 @@ init_runtime_v2();
71134
71475
  // src/identity/credential.ts
71135
71476
  init_runtime_v2();
71136
71477
  init_zod();
71478
+
71479
+ // src/identity/installation.ts
71480
+ var import_node_crypto33 = require("crypto");
71481
+ var import_node_path72 = require("path");
71482
+ init_runtime_v2();
71483
+ init_zod();
71484
+ var installationFileSchema = external_exports.object({
71485
+ installationId: external_exports.uuid(),
71486
+ machineId: machineIdSchema.optional()
71487
+ });
71488
+ function installationPath(paths) {
71489
+ return (0, import_node_path72.join)(paths.stateDir, "installation.json");
71490
+ }
71491
+ async function readInstallation(paths) {
71492
+ const result = await readJsonFile(installationPath(paths), installationFileSchema);
71493
+ return result.kind === "ok" ? result.value : null;
71494
+ }
71495
+ async function ensureInstallationId(paths) {
71496
+ const existing = await readInstallation(paths);
71497
+ if (existing !== null) return existing.installationId;
71498
+ const created = { installationId: (0, import_node_crypto33.randomUUID)() };
71499
+ await writeJsonFileAtomic(installationPath(paths), created);
71500
+ return created.installationId;
71501
+ }
71502
+ async function rememberInstallationMachine(paths, machineId) {
71503
+ const installationId = await ensureInstallationId(paths);
71504
+ await writeJsonFileAtomic(installationPath(paths), { installationId, machineId });
71505
+ }
71506
+
71507
+ // src/identity/credential.ts
71137
71508
  var machineFileSchema = external_exports.object({
71138
71509
  machineId: machineIdSchema,
71139
71510
  endpoints: machineEndpointsSchema,
@@ -71183,6 +71554,7 @@ async function saveGrant({
71183
71554
  credentialStore: storeKind
71184
71555
  };
71185
71556
  await writeJsonFileAtomic(paths.machine, machine);
71557
+ await rememberInstallationMachine(paths, machine.machineId);
71186
71558
  if (previous !== null && previous.credentialStore !== storeKind) {
71187
71559
  await credentialStoreFor(paths, previous.credentialStore, access7).clear();
71188
71560
  }
@@ -71307,29 +71679,8 @@ async function authorizeDevice(input2) {
71307
71679
  // src/identity/enroll.ts
71308
71680
  var import_promises72 = require("fs/promises");
71309
71681
  init_runtime_v2();
71310
-
71311
- // src/identity/installation.ts
71312
- var import_node_crypto33 = require("crypto");
71313
- var import_node_path72 = require("path");
71314
- init_zod();
71315
- var installationFileSchema = external_exports.object({
71316
- installationId: external_exports.uuid()
71317
- });
71318
- function installationPath(paths) {
71319
- return (0, import_node_path72.join)(paths.stateDir, "installation.json");
71320
- }
71321
- async function ensureInstallationId(paths) {
71322
- const path4 = installationPath(paths);
71323
- const existing = await readJsonFile(path4, installationFileSchema);
71324
- if (existing.kind === "ok") return existing.value.installationId;
71325
- const created = { installationId: (0, import_node_crypto33.randomUUID)() };
71326
- await writeJsonFileAtomic(path4, created);
71327
- return created.installationId;
71328
- }
71329
-
71330
- // src/identity/enroll.ts
71331
71682
  async function enrollMachine(input2) {
71332
- const machineId = input2.machineId ?? (await readMachineFile(input2.paths))?.machineId;
71683
+ const machineId = input2.machineId ?? (await readMachineFile(input2.paths))?.machineId ?? (await readInstallation(input2.paths))?.machineId;
71333
71684
  const installationId = await ensureInstallationId(input2.paths);
71334
71685
  const outcome2 = await input2.enrollment.register(
71335
71686
  {