@alan-ai-hq/agent-manager-darwin-arm64 0.1.158 → 0.1.160

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/alan-agent.cjs CHANGED
@@ -22501,6 +22501,56 @@ var init_run_log_upload = __esm({
22501
22501
  }
22502
22502
  });
22503
22503
 
22504
+ // ../shared/dist/runtime-v2/run-media.js
22505
+ function runMediaPath(runId) {
22506
+ return `/public/machines/me/runs/${encodeURIComponent(runId)}/media`;
22507
+ }
22508
+ function runMediaCompletePath(runId, mediaId) {
22509
+ return `${runMediaPath(runId)}/${encodeURIComponent(mediaId)}/complete`;
22510
+ }
22511
+ var INT4_MAX, runMediaSourceSchema, runMediaUploadRequestSchema, runMediaUploadTargetSchema, runMediaUploadResponseSchema, runMediaCompleteResponseSchema;
22512
+ var init_run_media = __esm({
22513
+ "../shared/dist/runtime-v2/run-media.js"() {
22514
+ "use strict";
22515
+ init_zod();
22516
+ INT4_MAX = 2147483647;
22517
+ runMediaSourceSchema = external_exports.enum(["generated_image", "session_media"]);
22518
+ runMediaUploadRequestSchema = external_exports.object({
22519
+ /** The `id` the transcript update carries; one upload per id and run. */
22520
+ mediaId: external_exports.string().min(1).max(200),
22521
+ source: runMediaSourceSchema,
22522
+ kind: external_exports.enum(["image", "video"]),
22523
+ mimeType: external_exports.string().min(1).max(200),
22524
+ filename: external_exports.string().min(1).max(500),
22525
+ bytes: external_exports.number().int().positive().max(INT4_MAX),
22526
+ sha256: external_exports.string().regex(/^[0-9a-f]{64}$/),
22527
+ width: external_exports.number().int().min(0).max(INT4_MAX).nullish(),
22528
+ height: external_exports.number().int().min(0).max(INT4_MAX).nullish(),
22529
+ toolId: external_exports.string().max(500).optional(),
22530
+ sourcePath: external_exports.string().max(4096).optional(),
22531
+ ts: external_exports.number().int().positive().optional()
22532
+ });
22533
+ runMediaUploadTargetSchema = external_exports.object({
22534
+ url: external_exports.url(),
22535
+ /** Every header the signed PUT expects, besides the body's `content-length`. */
22536
+ headers: external_exports.record(external_exports.string(), external_exports.string()),
22537
+ expiresAt: external_exports.iso.datetime()
22538
+ });
22539
+ runMediaUploadResponseSchema = external_exports.discriminatedUnion("status", [
22540
+ external_exports.object({
22541
+ status: external_exports.literal("upload"),
22542
+ mediaId: external_exports.string(),
22543
+ upload: runMediaUploadTargetSchema
22544
+ }),
22545
+ external_exports.object({ status: external_exports.literal("ready"), mediaId: external_exports.string() })
22546
+ ]);
22547
+ runMediaCompleteResponseSchema = external_exports.object({
22548
+ status: external_exports.literal("ready"),
22549
+ mediaId: external_exports.string()
22550
+ });
22551
+ }
22552
+ });
22553
+
22504
22554
  // ../shared/dist/runtime-v2/skills.js
22505
22555
  var MACHINE_SKILLS_SYNC_PATH, MAX_MACHINE_SKILLS, installedMachineSkillSchema, MAX_SKILL_UPLOADS, machineSkillScanRepositorySchema, machineSkillScanContextSchema, machineLocalSkillsReportSchema, machineSkillUploadSchema, machineSkillsSyncRequestSchema, desiredMachineSkillSchema, machineSkillDownloadSchema, machineSkillsSyncResponseSchema;
22506
22556
  var init_skills = __esm({
@@ -22624,6 +22674,7 @@ var init_runtime_v2 = __esm({
22624
22674
  init_mcp();
22625
22675
  init_run_log();
22626
22676
  init_run_log_upload();
22677
+ init_run_media();
22627
22678
  init_skills();
22628
22679
  init_workspace();
22629
22680
  }
@@ -25967,6 +26018,12 @@ var init_event = __esm({
25967
26018
  });
25968
26019
 
25969
26020
  // ../shared/dist/agent/acp/reduce.js
26021
+ function upsertMcpServers(current, reported) {
26022
+ const byName = new Map((current ?? []).map((server) => [server.name, server]));
26023
+ for (const server of reported)
26024
+ byName.set(server.name, server);
26025
+ return [...byName.values()];
26026
+ }
25970
26027
  function emptyTranscript() {
25971
26028
  return { entries: [], state: "idle", notices: [], unknown: [] };
25972
26029
  }
@@ -26123,6 +26180,12 @@ ${update.description}` : update.title,
26123
26180
  state.thinkingTokens = update.estimated;
26124
26181
  return;
26125
26182
  }
26183
+ case "_alan/mcp_servers": {
26184
+ if (!isUpdate(update, "_alan/mcp_servers"))
26185
+ return;
26186
+ state.mcpServers = upsertMcpServers(state.mcpServers, update.servers);
26187
+ return;
26188
+ }
26126
26189
  // Owned by the tool call that references it, but kept so a terminal-aware
26127
26190
  // renderer can still consume the raw update.
26128
26191
  case "terminal_update":
@@ -26436,17 +26499,20 @@ function stepSummary(node2) {
26436
26499
  const update = node2.event.update;
26437
26500
  const children = node2.children.map(stepSummary);
26438
26501
  if (update.sessionUpdate === "terminal_update") {
26439
- const { output: _output, ...rest2 } = update;
26440
- return { ...node2, event: { ...node2.event, update: rest2 }, children };
26502
+ const { output: output2, ...rest2 } = update;
26503
+ const omitted = output2 === void 0 ? {} : { outputTruncated: true };
26504
+ return { ...node2, event: { ...node2.event, update: { ...rest2, ...omitted } }, children };
26441
26505
  }
26442
26506
  if (update.sessionUpdate !== "tool_call_update")
26443
26507
  return { ...node2, children };
26444
26508
  const inputRecord = toolInputRecord(update.rawInput);
26445
26509
  if (rendersBesideSteps(update, inputRecord))
26446
26510
  return { ...node2, children };
26447
- const { content, rawOutput: _rawOutput, rawInput, ...rest } = update;
26511
+ const { content, rawOutput, rawInput, ...rest } = update;
26448
26512
  const input2 = stepInput(rawInput, inputRecord);
26449
- const diffs = (Array.isArray(content) ? content : []).map(diffWithoutText).filter((block2) => block2 !== null);
26513
+ const blocks = Array.isArray(content) ? content : [];
26514
+ const diffs = blocks.map(diffWithoutText).filter((block2) => block2 !== null);
26515
+ const outputOmitted = rawOutput !== void 0 && rawOutput !== null && rawOutput !== "" || blocks.length > 0;
26450
26516
  return {
26451
26517
  ...node2,
26452
26518
  event: {
@@ -26455,6 +26521,7 @@ function stepSummary(node2) {
26455
26521
  ...rest,
26456
26522
  ...input2.value === void 0 ? {} : { rawInput: input2.value },
26457
26523
  ...input2.truncated ? { inputTruncated: true } : {},
26524
+ ...outputOmitted ? { outputTruncated: true } : {},
26458
26525
  ...diffs.length > 0 ? { content: diffs } : {}
26459
26526
  }
26460
26527
  },
@@ -26771,9 +26838,14 @@ var init_session_activity = __esm({
26771
26838
  });
26772
26839
 
26773
26840
  // ../shared/dist/agent/acp/transcript-byte-decoder.js
26841
+ var MIN_ELIDED_DATA_BYTES, DATA_KEY, MEDIA_MARKERS;
26774
26842
  var init_transcript_byte_decoder = __esm({
26775
26843
  "../shared/dist/agent/acp/transcript-byte-decoder.js"() {
26776
26844
  "use strict";
26845
+ init_types2();
26846
+ MIN_ELIDED_DATA_BYTES = 16 * 1024;
26847
+ DATA_KEY = new TextEncoder().encode('"data":"');
26848
+ MEDIA_MARKERS = [...MEDIA_SESSION_UPDATE_KINDS].map((kind) => new TextEncoder().encode(JSON.stringify(kind)));
26777
26849
  }
26778
26850
  });
26779
26851
 
@@ -26933,6 +27005,8 @@ function mergeTranscriptMessages(messages, cache2) {
26933
27005
  merged.usage = state.usage;
26934
27006
  if (state.title)
26935
27007
  merged.title = state.title;
27008
+ if (state.mcpServers)
27009
+ merged.mcpServers = upsertMcpServers(merged.mcpServers, state.mcpServers);
26936
27010
  updateOffset += state.updateCount ?? 0;
26937
27011
  }
26938
27012
  merged.updateCount = updateOffset;
@@ -28023,7 +28097,7 @@ var init_chunk_ZCTKXKYY = __esm({
28023
28097
  }
28024
28098
  });
28025
28099
 
28026
- // ../agent-core/dist/chunk-FYZKVT3E.js
28100
+ // ../agent-core/dist/chunk-WD7O4DYQ.js
28027
28101
  function detectImageMimeType(buffer) {
28028
28102
  if (buffer.length >= 8 && buffer.subarray(0, 8).equals(PNG_SIGNATURE)) return "image/png";
28029
28103
  if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) {
@@ -28159,6 +28233,27 @@ function resultText2(update) {
28159
28233
  if (typeof raw === "string") return raw;
28160
28234
  return raw === void 0 ? "" : JSON.stringify(raw);
28161
28235
  }
28236
+ function mediaUpdate(file2, body) {
28237
+ const fields = {
28238
+ id: file2.mediaId,
28239
+ filename: file2.filename,
28240
+ mimeType: file2.mimeType,
28241
+ size: file2.data.length,
28242
+ ...body,
28243
+ sourcePath: file2.sourcePath,
28244
+ sourceHash: file2.sha256,
28245
+ toolId: file2.toolId,
28246
+ ts: file2.ts,
28247
+ ...file2.width === void 0 ? {} : { width: file2.width },
28248
+ ...file2.height === void 0 ? {} : { height: file2.height }
28249
+ };
28250
+ if (file2.source === "generated_image") {
28251
+ const image = { type: "generated_image", ...fields };
28252
+ return { sessionUpdate: "_alan/generated_image", image };
28253
+ }
28254
+ const media = { type: "session_media", kind: file2.kind, ...fields };
28255
+ return { sessionUpdate: "_alan/session_media", media };
28256
+ }
28162
28257
  function updateRequiredMessage(requirement, found) {
28163
28258
  const { cli, minimumVersion, feature } = requirement;
28164
28259
  const installed = found ? `${cli} ${found}` : `The ${cli} CLI`;
@@ -28443,8 +28538,8 @@ function silentStartError(name, timeoutMs) {
28443
28538
  };
28444
28539
  }
28445
28540
  var import_crypto4, import_fs5, import_path4, PNG_SIGNATURE, IMAGE_MIME_BY_EXT, VIDEO_MIME_BY_EXT, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, MAX_TURN_MEDIA_DATA_CHARS, MTIME_SLACK_MS, AGENT_BROWSER_MENTION, AGENT_BROWSER_CAPTURE_COMMAND, LocalMediaReader, SessionOpenRefusal, JsonRpcError, ACP_PROTOCOL_VERSION, ACP_ERROR, STDERR_TAIL_LINES, RESULT_EXIT_GRACE_MS, PerTurnSession;
28446
- var init_chunk_FYZKVT3E = __esm({
28447
- "../agent-core/dist/chunk-FYZKVT3E.js"() {
28541
+ var init_chunk_WD7O4DYQ = __esm({
28542
+ "../agent-core/dist/chunk-WD7O4DYQ.js"() {
28448
28543
  "use strict";
28449
28544
  init_chunk_OUEMTEUX();
28450
28545
  init_chunk_ZCTKXKYY();
@@ -28486,8 +28581,12 @@ var init_chunk_FYZKVT3E = __esm({
28486
28581
  this.#cwd = cwd;
28487
28582
  this.#clock = clock;
28488
28583
  }
28489
- /** Updates to record after `update`; nothing for anything but a tool call, which is almost all. */
28584
+ /** Updates to record after `update`, with the bytes inline; nothing for most updates. */
28490
28585
  read(update) {
28586
+ return this.find(update).map((found) => this.inline(found));
28587
+ }
28588
+ /** The media files a completed tool call wrote; nothing for anything but a tool call. */
28589
+ find(update) {
28491
28590
  if (!isUpdate(update, "tool_call_update")) return [];
28492
28591
  const toolCallId = update.toolCallId;
28493
28592
  if (update.name !== void 0 || update.rawInput !== void 0) {
@@ -28533,20 +28632,42 @@ var init_chunk_FYZKVT3E = __esm({
28533
28632
  named: /* @__PURE__ */ new Set([...capturePaths(tool, content, extensions, cwd), ...this.#pathHints])
28534
28633
  });
28535
28634
  }
28536
- #payloadFields(file2, toolId, explicit) {
28537
- const dataChars = base64Length(file2.buffer.length);
28538
- const inline = explicit || this.#mediaDataChars + dataChars <= MAX_TURN_MEDIA_DATA_CHARS;
28635
+ /** The update carrying the file's bytes, unless the turn's budget is spent on media nobody asked for. */
28636
+ inline(found) {
28637
+ const { file: file2 } = found;
28638
+ const dataChars = base64Length(file2.data.length);
28639
+ const inline = found.explicit || this.#mediaDataChars + dataChars <= MAX_TURN_MEDIA_DATA_CHARS;
28539
28640
  if (inline) this.#mediaDataChars += dataChars;
28641
+ return mediaUpdate(
28642
+ file2,
28643
+ inline ? { data: file2.data.toString("base64") } : { inlineDataOmitted: true }
28644
+ );
28645
+ }
28646
+ /** Uploads the file and returns a reference to it; inline as `inline` does when the upload fails. */
28647
+ async publish(found, uploader, signal) {
28648
+ try {
28649
+ await uploader.upload(found.file, signal);
28650
+ return mediaUpdate(found.file, { uploaded: true });
28651
+ } catch {
28652
+ return this.inline(found);
28653
+ }
28654
+ }
28655
+ #found(file2, toolId, source, kind, explicit) {
28540
28656
  return {
28541
- id: (0, import_crypto4.randomUUID)(),
28542
- filename: (0, import_path4.basename)(file2.path),
28543
- mimeType: file2.mimeType,
28544
- size: file2.buffer.length,
28545
- ...inline ? { data: file2.buffer.toString("base64") } : { inlineDataOmitted: true },
28546
- sourcePath: file2.path,
28547
- sourceHash: (0, import_crypto4.createHash)("sha256").update(file2.buffer).digest("hex"),
28548
- toolId,
28549
- ts: this.#clock.now()
28657
+ explicit,
28658
+ file: {
28659
+ mediaId: (0, import_crypto4.randomUUID)(),
28660
+ source,
28661
+ kind,
28662
+ mimeType: file2.mimeType,
28663
+ filename: (0, import_path4.basename)(file2.path),
28664
+ data: file2.buffer,
28665
+ sha256: (0, import_crypto4.createHash)("sha256").update(file2.buffer).digest("hex"),
28666
+ ...kind === "image" ? imageDimensions(file2.buffer, file2.mimeType) : {},
28667
+ toolId,
28668
+ sourcePath: file2.path,
28669
+ ts: this.#clock.now()
28670
+ }
28550
28671
  };
28551
28672
  }
28552
28673
  #generatedImages(toolId, tool, content) {
@@ -28555,14 +28676,7 @@ var init_chunk_FYZKVT3E = __esm({
28555
28676
  mimeByExt: IMAGE_MIME_BY_EXT,
28556
28677
  maxBytes: MAX_IMAGE_BYTES
28557
28678
  });
28558
- return files.map((file2) => {
28559
- const image = {
28560
- type: "generated_image",
28561
- ...this.#payloadFields(file2, toolId, true),
28562
- ...imageDimensions(file2.buffer, file2.mimeType)
28563
- };
28564
- return { sessionUpdate: "_alan/generated_image", image };
28565
- });
28679
+ return files.map((file2) => this.#found(file2, toolId, "generated_image", "image", true));
28566
28680
  }
28567
28681
  #sessionMedia(toolId, tool, content) {
28568
28682
  const isVideo = isAgentBrowserMedia(tool, content, "video");
@@ -28577,13 +28691,7 @@ var init_chunk_FYZKVT3E = __esm({
28577
28691
  );
28578
28692
  return files.map((file2) => {
28579
28693
  this.#pathHints.delete(file2.path);
28580
- const media = {
28581
- type: "session_media",
28582
- kind,
28583
- ...this.#payloadFields(file2, toolId, explicit),
28584
- ...kind === "image" ? imageDimensions(file2.buffer, file2.mimeType) : {}
28585
- };
28586
- return { sessionUpdate: "_alan/session_media", media };
28694
+ return this.#found(file2, toolId, "session_media", kind, explicit);
28587
28695
  });
28588
28696
  }
28589
28697
  };
@@ -29778,16 +29886,16 @@ function externalServerConfig(server) {
29778
29886
  };
29779
29887
  }
29780
29888
  function claudeMcpConfig(mcp) {
29781
- const mcpServers = /* @__PURE__ */ Object.create(null);
29889
+ const mcpServers2 = /* @__PURE__ */ Object.create(null);
29782
29890
  for (const [name, server] of Object.entries(mcp.externalServers ?? {})) {
29783
- mcpServers[name] = externalServerConfig(server);
29891
+ mcpServers2[name] = externalServerConfig(server);
29784
29892
  }
29785
- mcpServers.alan = {
29893
+ mcpServers2.alan = {
29786
29894
  type: "http",
29787
29895
  url: mcp.alanMcpUrl,
29788
29896
  headers: managedMcpHeaders(mcp.identity)
29789
29897
  };
29790
- return { mcpServers };
29898
+ return { mcpServers: mcpServers2 };
29791
29899
  }
29792
29900
  function carriesCredential(mcp) {
29793
29901
  return mcp.identity.scope === "conversation" && mcp.identity.authorization !== void 0;
@@ -30012,11 +30120,27 @@ function parseStreamEvent(event, state) {
30012
30120
  function stringList(value2) {
30013
30121
  return asArray(value2).map((item) => asString(item)).filter(Boolean);
30014
30122
  }
30123
+ function mcpServers(value2) {
30124
+ const servers = [];
30125
+ for (const item of asArray(value2)) {
30126
+ const record2 = asRecord(item);
30127
+ const name = asString(record2?.name);
30128
+ if (!record2 || !name) continue;
30129
+ const source = asString(record2.source);
30130
+ servers.push({
30131
+ name,
30132
+ status: CLAUDE_MCP_STATUS[asString(record2.status)] ?? "unknown",
30133
+ ...source ? { source } : {}
30134
+ });
30135
+ }
30136
+ return servers;
30137
+ }
30015
30138
  function initUpdates(event, state) {
30016
30139
  const model = asString(event.model);
30017
30140
  if (model) state.model = model;
30018
30141
  const tools = stringList(event.tools);
30019
30142
  const slashCommands = stringList(event.slash_commands);
30143
+ const servers = mcpServers(event.mcp_servers);
30020
30144
  return [
30021
30145
  {
30022
30146
  sessionUpdate: "_alan/log",
@@ -30030,7 +30154,8 @@ function initUpdates(event, state) {
30030
30154
  ...tools.length > 0 ? { [TOOLS_META]: tools } : {},
30031
30155
  ...slashCommands.length > 0 ? { [SLASH_COMMANDS_META]: slashCommands } : {}
30032
30156
  }
30033
- }
30157
+ },
30158
+ ...servers.length > 0 ? [{ sessionUpdate: "_alan/mcp_servers", servers }] : []
30034
30159
  ];
30035
30160
  }
30036
30161
  function thinkingTokens(event) {
@@ -30984,12 +31109,12 @@ function claudeTurnClosingUpdates(records, state) {
30984
31109
  function readClaudeTranscriptTurns(chunk, baseOffset, skipped) {
30985
31110
  return readTranscriptTurns(claudeTranscriptFile, chunk, baseOffset, skipped);
30986
31111
  }
30987
- var import_crypto7, import_fs6, import_path6, import_crypto8, import_promises31, EDIT_TOOLS, ThoughtBlocks, UNDERSTOOD_SYSTEM_SUBTYPES, RATE_LIMIT_WARN_AT, CLAUDE_GRAMMAR_NAME, SUBAGENT_TOOL_NAMES, controlResponseSchema, STOPPED_STATUSES, TaskRecords, TERMINAL_BACKGROUND_STATUSES, NON_TERMINAL_BACKGROUND_STATUSES, ASYNC_LAUNCH_ACK, BackgroundTasks, FAILED_STATUSES, STOPPED_BY_USER_TEXT, ClaudeTurn, STDERR_TAIL_LINES2, MAX_EARLY_LINES, UNSUPPORTED_STOP, OUTPUT_CLOSED_REASON, ClaudeSession, DEFAULTS, READ_ONLY_DISALLOWED_TOOLS, DEFAULT_MCP_TIMEOUT_MS, SYNTHETIC_MODEL, INTERRUPT_MARKER, NON_PROMPT_PREFIXES, PRELUDE_TYPES, claudeTranscriptFile;
31112
+ var import_crypto7, import_fs6, import_path6, import_crypto8, import_promises31, EDIT_TOOLS, ThoughtBlocks, UNDERSTOOD_SYSTEM_SUBTYPES, CLAUDE_MCP_STATUS, RATE_LIMIT_WARN_AT, CLAUDE_GRAMMAR_NAME, SUBAGENT_TOOL_NAMES, controlResponseSchema, STOPPED_STATUSES, TaskRecords, TERMINAL_BACKGROUND_STATUSES, NON_TERMINAL_BACKGROUND_STATUSES, ASYNC_LAUNCH_ACK, BackgroundTasks, FAILED_STATUSES, STOPPED_BY_USER_TEXT, ClaudeTurn, STDERR_TAIL_LINES2, MAX_EARLY_LINES, UNSUPPORTED_STOP, OUTPUT_CLOSED_REASON, ClaudeSession, DEFAULTS, READ_ONLY_DISALLOWED_TOOLS, DEFAULT_MCP_TIMEOUT_MS, SYNTHETIC_MODEL, INTERRUPT_MARKER, NON_PROMPT_PREFIXES, PRELUDE_TYPES, claudeTranscriptFile;
30988
31113
  var init_claude = __esm({
30989
31114
  "../agent-core/dist/providers/claude.js"() {
30990
31115
  "use strict";
30991
31116
  init_chunk_D4TIXPWZ();
30992
- init_chunk_FYZKVT3E();
31117
+ init_chunk_WD7O4DYQ();
30993
31118
  init_chunk_OUEMTEUX();
30994
31119
  init_chunk_ZCTKXKYY();
30995
31120
  init_chunk_6VWVDJ2A();
@@ -31053,6 +31178,13 @@ var init_claude = __esm({
31053
31178
  "status",
31054
31179
  "commands_changed"
31055
31180
  ]);
31181
+ CLAUDE_MCP_STATUS = {
31182
+ connected: "connected",
31183
+ pending: "starting",
31184
+ "needs-auth": "needs_auth",
31185
+ failed: "failed",
31186
+ disabled: "disabled"
31187
+ };
31056
31188
  RATE_LIMIT_WARN_AT = 0.8;
31057
31189
  CLAUDE_GRAMMAR_NAME = "claude_cli";
31058
31190
  SUBAGENT_TOOL_NAMES = /* @__PURE__ */ new Set(["agent", "task"]);
@@ -33840,12 +33972,12 @@ function codexTurnInput(run2, context) {
33840
33972
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
33841
33973
  };
33842
33974
  }
33843
- var import_fs7, import_path7, import_crypto9, import_crypto10, import_crypto11, import_crypto12, TokenRefresher, MCP_STARTUP_TIMEOUT_SEC, FIELD_TYPES, YES_NO, ACCEPT_DECLINE, MAX_INLINE_GENERATED_IMAGE_BYTES, PNG_SIGNATURE2, JPEG_NON_FRAME_MARKERS, IMAGE_GEN_CALL, PROMPT_LITERAL, RELOCATE_EVERY_MS, CodexImageGenerationFold, CodexRolloutImages, CodexRateLimits, USER_INPUT_METHOD, PERMISSIONS_METHOD, ELICITATION_METHOD, COMMAND_OR_FILE, LEGACY, DECISIONS, COORDINATION_TOOLS, SETTLED_AGENT, STATUS, CHANGE_OPERATIONS, SILENT_ON_START, IGNORED_ITEMS, PLAN_STATUS, WORKER_LIFECYCLE, INFO_KINDS, SILENT, CodexTurn, STDERR_TAIL_LINES3, MAX_BETWEEN_UPDATES, UNSUPPORTED_REQUEST, DECLINED_ELICITATION, IMAGE_CATCH_UP_MS, IMAGE_POLL_MS, CodexSession, CODEX_MIN_VERSION, CODEX_REQUIREMENT, CODEX_TESTED_LINE, DEFAULTS2, CLIENT_INFO, STATUS2, EXITED_WITHOUT_RESPONSE, CodexExecTurn, DEFAULTS22, CodexExecSession, INJECTED_USER_PREFIXES, SHELL_TOOL_NAMES, ANNOUNCING_ITEM_TYPES, OUTPUT_MARKER, OPEN_PAGE_ACTIONS, FIND_IN_PAGE_ACTIONS, FILE_OPERATIONS, UNDERSTOOD_ITEM_TYPES, PRELUDE_TYPES2, PRELUDE_EVENTS, codexRolloutFile;
33975
+ var import_fs7, import_path7, import_crypto9, import_crypto10, import_crypto11, import_crypto12, TokenRefresher, MCP_STARTUP_TIMEOUT_SEC, FIELD_TYPES, YES_NO, ACCEPT_DECLINE, MAX_INLINE_GENERATED_IMAGE_BYTES, PNG_SIGNATURE2, JPEG_NON_FRAME_MARKERS, IMAGE_GEN_CALL, PROMPT_LITERAL, RELOCATE_EVERY_MS, CodexImageGenerationFold, CodexRolloutImages, CodexRateLimits, USER_INPUT_METHOD, PERMISSIONS_METHOD, ELICITATION_METHOD, COMMAND_OR_FILE, LEGACY, DECISIONS, COORDINATION_TOOLS, SETTLED_AGENT, STATUS, CHANGE_OPERATIONS, SILENT_ON_START, IGNORED_ITEMS, PLAN_STATUS, CODEX_MCP_STATUS, WORKER_LIFECYCLE, INFO_KINDS, SILENT, CodexTurn, STDERR_TAIL_LINES3, MAX_BETWEEN_UPDATES, UNSUPPORTED_REQUEST, DECLINED_ELICITATION, IMAGE_CATCH_UP_MS, IMAGE_POLL_MS, CodexSession, CODEX_MIN_VERSION, CODEX_REQUIREMENT, CODEX_TESTED_LINE, DEFAULTS2, CLIENT_INFO, STATUS2, EXITED_WITHOUT_RESPONSE, CodexExecTurn, DEFAULTS22, CodexExecSession, INJECTED_USER_PREFIXES, SHELL_TOOL_NAMES, ANNOUNCING_ITEM_TYPES, OUTPUT_MARKER, OPEN_PAGE_ACTIONS, FIND_IN_PAGE_ACTIONS, FILE_OPERATIONS, UNDERSTOOD_ITEM_TYPES, PRELUDE_TYPES2, PRELUDE_EVENTS, codexRolloutFile;
33844
33976
  var init_codex = __esm({
33845
33977
  "../agent-core/dist/providers/codex.js"() {
33846
33978
  "use strict";
33847
33979
  init_chunk_D4TIXPWZ();
33848
- init_chunk_FYZKVT3E();
33980
+ init_chunk_WD7O4DYQ();
33849
33981
  init_chunk_OUEMTEUX();
33850
33982
  init_chunk_ZCTKXKYY();
33851
33983
  init_chunk_6VWVDJ2A();
@@ -34133,6 +34265,12 @@ var init_codex = __esm({
34133
34265
  ["inProgress", "in_progress"],
34134
34266
  ["completed", "completed"]
34135
34267
  ]);
34268
+ CODEX_MCP_STATUS = {
34269
+ starting: "starting",
34270
+ ready: "connected",
34271
+ failed: "failed",
34272
+ cancelled: "failed"
34273
+ };
34136
34274
  WORKER_LIFECYCLE = /* @__PURE__ */ new Set([
34137
34275
  "turn/started",
34138
34276
  "turn/completed",
@@ -34284,20 +34422,29 @@ var init_codex = __esm({
34284
34422
  )
34285
34423
  ];
34286
34424
  }
34425
+ #mcpStatus(params) {
34426
+ const name = asString(params.name);
34427
+ if (!name) return [];
34428
+ const reported = asString(params.status);
34429
+ const reason = asString(params.error) || asString(params.failureReason);
34430
+ const status = CODEX_MCP_STATUS[reported] ?? "unknown";
34431
+ const listed = {
34432
+ sessionUpdate: "_alan/mcp_servers",
34433
+ servers: [{ name, status, ...status === "failed" && reason ? { error: reason } : {} }]
34434
+ };
34435
+ if (reported !== "failed") return [listed];
34436
+ return [listed, ...this.#mcpFailure(name, reason)];
34437
+ }
34287
34438
  /**
34288
34439
  * Only Alan's own MCP server failing matters in the chat: its tools are gone for the session.
34289
34440
  * The user's other servers (and their logins) belong to their Codex setup, not to Alan.
34290
34441
  */
34291
- #mcpStatus(params) {
34292
- if (asString(params.status) !== "failed") return [];
34293
- const name = asString(params.name);
34442
+ #mcpFailure(name, reason) {
34294
34443
  if (canonicalizeManagedMcpServerName(name) !== MANAGED_MCP_SERVER_NAME) {
34295
- const reason2 = asString(params.error) || asString(params.failureReason);
34296
34444
  return [
34297
- logUpdate("codex/mcp", `MCP server ${name} failed to start${reason2 ? `: ${reason2}` : "."}`)
34445
+ logUpdate("codex/mcp", `MCP server ${name} failed to start${reason ? `: ${reason}` : "."}`)
34298
34446
  ];
34299
34447
  }
34300
- const reason = asString(params.error) || asString(params.failureReason);
34301
34448
  const key = `mcp_server_failed\0${reason}`;
34302
34449
  if (this.#memory.shownWarnings.has(key)) return [];
34303
34450
  this.#memory.shownWarnings.add(key);
@@ -45242,7 +45389,7 @@ var require_tar_stream = __commonJS({
45242
45389
  var init_dist = __esm({
45243
45390
  "../agent-core/dist/index.js"() {
45244
45391
  "use strict";
45245
- init_chunk_FYZKVT3E();
45392
+ init_chunk_WD7O4DYQ();
45246
45393
  init_chunk_OUEMTEUX();
45247
45394
  init_chunk_ZCTKXKYY();
45248
45395
  init_chunk_6VWVDJ2A();
@@ -45989,7 +46136,7 @@ var import_promises50, import_path10, import_crypto14, import_promises51, CURSOR
45989
46136
  var init_acp3 = __esm({
45990
46137
  "../agent-core/dist/providers/acp.js"() {
45991
46138
  "use strict";
45992
- init_chunk_FYZKVT3E();
46139
+ init_chunk_WD7O4DYQ();
45993
46140
  init_chunk_OUEMTEUX();
45994
46141
  init_chunk_ZCTKXKYY();
45995
46142
  init_chunk_6VWVDJ2A();
@@ -47027,9 +47174,19 @@ function createPersistentDriver(provider4, options) {
47027
47174
  }
47028
47175
  };
47029
47176
  const media = new LocalMediaReader(spec.projectPath, clock);
47177
+ const uploader = inputs.media;
47178
+ let uploads = Promise.resolve();
47030
47179
  const recordWithMedia = (update) => {
47031
47180
  record2(update);
47032
- for (const found of media.read(update)) record2(found);
47181
+ const found = media.find(update);
47182
+ if (found.length === 0) return;
47183
+ if (uploader === void 0) {
47184
+ for (const item of found) record2(media.inline(item));
47185
+ return;
47186
+ }
47187
+ uploads = uploads.then(async () => {
47188
+ for (const item of found) record2(await media.publish(item, uploader, signal));
47189
+ });
47033
47190
  };
47034
47191
  const forward = (event) => {
47035
47192
  if (event.type === "session_id") {
@@ -47123,6 +47280,7 @@ function createPersistentDriver(provider4, options) {
47123
47280
  } catch (error62) {
47124
47281
  return { outcome: "failed", message: errorMessage(error62) };
47125
47282
  } finally {
47283
+ await uploads;
47126
47284
  signal.removeEventListener("abort", onAbort);
47127
47285
  if (live.turn === turn) live.turn = void 0;
47128
47286
  }
@@ -47252,7 +47410,8 @@ var init_persistent = __esm({
47252
47410
  "user_message",
47253
47411
  "user_message_chunk",
47254
47412
  "_alan/log",
47255
- "_alan/thinking_tokens"
47413
+ "_alan/thinking_tokens",
47414
+ "_alan/mcp_servers"
47256
47415
  ]);
47257
47416
  FIRST_OUTPUT_TIMEOUT_MS = 3e5;
47258
47417
  }
@@ -47956,7 +48115,7 @@ var import_crypto15, import_http10, import_crypto16, import_promises52, import_p
47956
48115
  var init_opencode = __esm({
47957
48116
  "../agent-core/dist/providers/opencode.js"() {
47958
48117
  "use strict";
47959
- init_chunk_FYZKVT3E();
48118
+ init_chunk_WD7O4DYQ();
47960
48119
  init_chunk_OUEMTEUX();
47961
48120
  init_chunk_ZCTKXKYY();
47962
48121
  init_chunk_6VWVDJ2A();
@@ -50007,7 +50166,7 @@ var import_crypto18, import_promises53, FACTORY_API_VERSION, FACTORY_PROTOCOL_VE
50007
50166
  var init_droid = __esm({
50008
50167
  "../agent-core/dist/providers/droid.js"() {
50009
50168
  "use strict";
50010
- init_chunk_FYZKVT3E();
50169
+ init_chunk_WD7O4DYQ();
50011
50170
  init_chunk_OUEMTEUX();
50012
50171
  init_chunk_ZCTKXKYY();
50013
50172
  init_chunk_6VWVDJ2A();
@@ -51117,7 +51276,7 @@ var init_antigravity = __esm({
51117
51276
  "../agent-core/dist/providers/antigravity.js"() {
51118
51277
  "use strict";
51119
51278
  init_chunk_D4TIXPWZ();
51120
- init_chunk_FYZKVT3E();
51279
+ init_chunk_WD7O4DYQ();
51121
51280
  init_chunk_OUEMTEUX();
51122
51281
  init_chunk_ZCTKXKYY();
51123
51282
  init_chunk_6VWVDJ2A();
@@ -51821,7 +51980,7 @@ var import_promises55, import_path16, import_crypto20, COMMAND_CODE_GRAMMAR_NAME
51821
51980
  var init_command_code = __esm({
51822
51981
  "../agent-core/dist/providers/command-code.js"() {
51823
51982
  "use strict";
51824
- init_chunk_FYZKVT3E();
51983
+ init_chunk_WD7O4DYQ();
51825
51984
  init_chunk_OUEMTEUX();
51826
51985
  init_chunk_ZCTKXKYY();
51827
51986
  init_chunk_6VWVDJ2A();
@@ -57224,7 +57383,7 @@ var require_websocket_server = __commonJS({
57224
57383
  // package.json
57225
57384
  var package_default = {
57226
57385
  name: "@alan-ai-hq/agent-manager",
57227
- version: "0.1.158",
57386
+ version: "0.1.160",
57228
57387
  private: true,
57229
57388
  type: "module",
57230
57389
  description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
@@ -58044,6 +58203,7 @@ function createGitHubProxyForwarder(options) {
58044
58203
  init_runtime_v2();
58045
58204
  init_zod();
58046
58205
  var REQUEST_TIMEOUT_MS3 = 3e4;
58206
+ var MEDIA_PUT_TIMEOUT_MS = 3e5;
58047
58207
  var credentialRefusalSchema = external_exports.object({ message: external_exports.string().trim().min(1) });
58048
58208
  function credentialFailureMessage(response, fallback) {
58049
58209
  if (response.status !== 409) return fallback;
@@ -58112,6 +58272,33 @@ function createHolderApiClient({
58112
58272
  throw new RuntimeFault("io_failed", `MCP credential request failed: ${response.status}`);
58113
58273
  }
58114
58274
  return machineMcpCredentialSchema.parse(jsonBody(response));
58275
+ },
58276
+ uploadRunMedia: async (runId, media, data, signal) => {
58277
+ const reserved = await request2("POST", runMediaPath(runId), signal, media);
58278
+ if (!isOk(reserved)) {
58279
+ throw new RuntimeFault("io_failed", `Media upload request failed: ${reserved.status}`);
58280
+ }
58281
+ const reservation = runMediaUploadResponseSchema.parse(jsonBody(reserved));
58282
+ if (reservation.status === "ready") return;
58283
+ const stored = await transport.send({
58284
+ method: "PUT",
58285
+ url: new URL(reservation.upload.url),
58286
+ headers: {
58287
+ ...reservation.upload.headers,
58288
+ "content-length": String(data.byteLength)
58289
+ },
58290
+ body: data,
58291
+ redirect: "error",
58292
+ signal: AbortSignal.any([signal, AbortSignal.timeout(MEDIA_PUT_TIMEOUT_MS)])
58293
+ });
58294
+ if (!isOk(stored)) {
58295
+ throw new RuntimeFault("io_failed", `Media upload failed: ${stored.status}`);
58296
+ }
58297
+ const completed = await request2("POST", runMediaCompletePath(runId, media.mediaId), signal);
58298
+ if (!isOk(completed)) {
58299
+ throw new RuntimeFault("io_failed", `Media upload completion failed: ${completed.status}`);
58300
+ }
58301
+ runMediaCompleteResponseSchema.parse(jsonBody(completed));
58115
58302
  }
58116
58303
  };
58117
58304
  }
@@ -70777,6 +70964,13 @@ function attachmentPath(spec, attachment, index, runDir) {
70777
70964
  }
70778
70965
  return (0, import_node_path54.join)(runDir, `${index}-${safeFilename(attachment.filename)}`);
70779
70966
  }
70967
+ function runMediaUploader(source, runId) {
70968
+ const upload = source.uploadMedia?.bind(source);
70969
+ if (upload === void 0) return void 0;
70970
+ return {
70971
+ upload: ({ data, ...media }, signal) => upload(runId, { ...media, bytes: data.byteLength }, data, signal)
70972
+ };
70973
+ }
70780
70974
  async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
70781
70975
  const dir = (0, import_node_path54.join)(tmpDir, "runs", spec.runId);
70782
70976
  const cleanup = async () => {
@@ -70803,9 +70997,11 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
70803
70997
  ...attachment.height === void 0 ? {} : { height: attachment.height }
70804
70998
  });
70805
70999
  }
71000
+ const media = runMediaUploader(source, spec.runId);
70806
71001
  return {
70807
71002
  attachments,
70808
71003
  providerEnv: credential.env,
71004
+ ...media === void 0 ? {} : { media },
70809
71005
  ...credential.codex === void 0 ? {} : { codex: credential.codex },
70810
71006
  skills,
70811
71007
  [Symbol.asyncDispose]: cleanup
@@ -74461,7 +74657,8 @@ async function machineAccess(paths, log, conversationId, transport) {
74461
74657
  fetchProviderCredential: async (runId, signal) => {
74462
74658
  void managedMcp?.authorization(signal);
74463
74659
  return (await api()).fetchProviderCredential(runId, signal);
74464
- }
74660
+ },
74661
+ uploadMedia: async (runId, media, data, signal) => (await api()).uploadRunMedia(runId, media, data, signal)
74465
74662
  };
74466
74663
  const codexCredentials = {
74467
74664
  refresh: async (runId, rejectedAccessTokenSha256) => (await api()).refreshCodexCredential(
@@ -80592,6 +80789,9 @@ init_zod();
80592
80789
  var RETRY_DELAYS_MS = [250, 500, 1e3, 2e3, 5e3, 1e4, 3e4];
80593
80790
  var PARK_MS = 5 * 6e4;
80594
80791
  var UNAUTHORIZED = 401;
80792
+ var CREDENTIAL_PARK_MS = 5 * 6e4;
80793
+ var CREDENTIAL_PARK_MAX_MS = 60 * 6e4;
80794
+ var UPLOAD_COALESCE_MS = 500;
80595
80795
  var RETRY_JITTER = 0.2;
80596
80796
  var uploadProgressSchema = external_exports.object({
80597
80797
  admittedOffset: external_exports.number().int().nonnegative(),
@@ -80612,43 +80812,78 @@ function startUploader({
80612
80812
  log,
80613
80813
  archive,
80614
80814
  random = Math.random,
80615
- onUnauthorized
80815
+ onUnauthorized,
80816
+ accessToken = () => ""
80616
80817
  }) {
80617
80818
  const controller = new AbortController();
80618
80819
  const active = /* @__PURE__ */ new Map();
80619
80820
  const again = /* @__PURE__ */ new Set();
80821
+ const againNow = /* @__PURE__ */ new Set();
80822
+ const lastSentAt = /* @__PURE__ */ new Map();
80823
+ const coalescing = /* @__PURE__ */ new Map();
80620
80824
  const sealed = /* @__PURE__ */ new Set();
80621
80825
  const receiptBackoff = /* @__PURE__ */ new Map();
80622
80826
  let pendingRuns = /* @__PURE__ */ new Map();
80623
80827
  const retrying = /* @__PURE__ */ new Set();
80624
80828
  let renewing = null;
80625
- const retryDelay = (failures) => {
80626
- const base = RETRY_DELAYS_MS[Math.min(failures, RETRY_DELAYS_MS.length - 1)] ?? 3e4;
80627
- return Math.round(base * (1 - RETRY_JITTER + 2 * RETRY_JITTER * random()));
80628
- };
80829
+ let credentialPark = null;
80830
+ let revoked = false;
80831
+ const jitter = (ms) => Math.round(ms * (1 - RETRY_JITTER + 2 * RETRY_JITTER * random()));
80832
+ const retryDelay = (failures) => jitter(RETRY_DELAYS_MS[Math.min(failures, RETRY_DELAYS_MS.length - 1)] ?? 3e4);
80629
80833
  const renewCredential = () => {
80630
- if (onUnauthorized === void 0) return Promise.resolve();
80631
- renewing ??= onUnauthorized().catch((error62) => log.warn("upload.renew_failed", { error: error62 })).finally(() => {
80834
+ if (onUnauthorized === void 0) return Promise.resolve("unchanged");
80835
+ renewing ??= onUnauthorized().catch((error62) => {
80836
+ log.warn("upload.renew_failed", { error: error62 });
80837
+ return "unchanged";
80838
+ }).finally(() => {
80632
80839
  renewing = null;
80633
80840
  });
80634
80841
  return renewing;
80635
80842
  };
80843
+ const credentialParked = () => {
80844
+ if (credentialPark === null) return false;
80845
+ if (accessToken() !== credentialPark.token) {
80846
+ credentialPark = null;
80847
+ return false;
80848
+ }
80849
+ return credentialPark.until > clock.now();
80850
+ };
80851
+ const parkForCredential = (token) => {
80852
+ if (credentialParked()) return;
80853
+ const failures = (credentialPark?.failures ?? 0) + 1;
80854
+ const delay4 = Math.min(CREDENTIAL_PARK_MS * 2 ** (failures - 1), CREDENTIAL_PARK_MAX_MS);
80855
+ credentialPark = { failures, until: clock.now() + jitter(delay4), token };
80856
+ log.warn("upload.credential_parked", { failures, parkedUntil: credentialPark.until });
80857
+ };
80858
+ const unauthorized = async (runId, tokenAtStart) => {
80859
+ const renewal = await renewCredential();
80860
+ if (renewal === "revoked") {
80861
+ revoked = true;
80862
+ log.error("upload.credential_revoked", { runId });
80863
+ return;
80864
+ }
80865
+ if (renewal === "renewed" || accessToken() !== tokenAtStart) {
80866
+ credentialPark = null;
80867
+ deferReceipt(runId);
80868
+ return;
80869
+ }
80870
+ parkForCredential(tokenAtStart);
80871
+ };
80636
80872
  const deferReceipt = (runId) => {
80637
80873
  const failures = (receiptBackoff.get(runId)?.failures ?? 0) + 1;
80638
80874
  receiptBackoff.set(runId, { failures, notBefore: clock.now() + retryDelay(failures) });
80639
80875
  };
80640
- const reject = async (runId, progressPath, progress, rejection2) => {
80876
+ const reject = async (runId, progressPath, progress, rejection2, tokenAtStart) => {
80641
80877
  log.error("upload.rejected", { runId, status: rejection2.status, message: rejection2.message });
80642
80878
  if (rejection2.status === UNAUTHORIZED) {
80643
- await renewCredential();
80644
- deferReceipt(runId);
80879
+ await unauthorized(runId, tokenAtStart);
80645
80880
  return;
80646
80881
  }
80647
80882
  const parkedUntil = clock.now() + PARK_MS;
80648
80883
  await writeJsonFileAtomic(progressPath, { ...progress, parkedUntil });
80649
80884
  log.warn("upload.parked", { runId, parkedUntil });
80650
80885
  };
80651
- const progressOf = async (runId, target, path4) => {
80886
+ const progressOf = async (runId, target, path4, tokenAtStart) => {
80652
80887
  const stored = await readJsonFile(path4, uploadProgressSchema);
80653
80888
  if (stored.kind === "ok") return stored.value;
80654
80889
  const listed = pendingRuns.get(runId);
@@ -80661,6 +80896,7 @@ function startUploader({
80661
80896
  switch (receipt.kind) {
80662
80897
  case "read": {
80663
80898
  receiptBackoff.delete(runId);
80899
+ credentialPark = null;
80664
80900
  log.debug("upload.resumed", {
80665
80901
  runId,
80666
80902
  admittedOffset: receipt.receipt?.admittedOffset ?? 0
@@ -80670,7 +80906,7 @@ function startUploader({
80670
80906
  return progress;
80671
80907
  }
80672
80908
  case "rejected":
80673
- await reject(runId, path4, progressFromReceipt(null), receipt);
80909
+ await reject(runId, path4, progressFromReceipt(null), receipt, tokenAtStart);
80674
80910
  return null;
80675
80911
  case "retry": {
80676
80912
  deferReceipt(runId);
@@ -80682,6 +80918,7 @@ function startUploader({
80682
80918
  };
80683
80919
  const sendNext = async (upload2, progress) => {
80684
80920
  const ended = (await readLastRecord(upload2.logPath))?.update.sessionUpdate === "_alan/run.ended";
80921
+ const size = await upload2.reader.size();
80685
80922
  const chunk = await upload2.reader.readFrom(
80686
80923
  toByteOffset(progress.admittedOffset),
80687
80924
  MAX_RUN_LOG_CHUNK_BYTES
@@ -80696,14 +80933,14 @@ function startUploader({
80696
80933
  sealed: atEnd || outcome2.receipt.finalOffset !== null
80697
80934
  };
80698
80935
  await writeJsonFileAtomic(upload2.progressPath, next);
80699
- return { kind: "advanced", progress: next };
80936
+ return { kind: "advanced", progress: next, more: ended || chunk.to < size };
80700
80937
  }
80701
80938
  case "offset_conflict": {
80702
80939
  const receipt = await api.readReceipt(upload2.target, controller.signal);
80703
80940
  if (receipt.kind === "read") {
80704
80941
  const next = progressFromReceipt(receipt.receipt);
80705
80942
  await writeJsonFileAtomic(upload2.progressPath, next);
80706
- return { kind: "advanced", progress: next };
80943
+ return { kind: "advanced", progress: next, more: true };
80707
80944
  }
80708
80945
  return receipt.kind === "retry" ? receipt : { kind: "rejected", rejection: receipt };
80709
80946
  }
@@ -80720,7 +80957,18 @@ function startUploader({
80720
80957
  log.warn("upload.retrying", { runId, status, delayMs: delay4 });
80721
80958
  await clock.sleep(delay4, controller.signal);
80722
80959
  };
80723
- const drain = async (runUpload, initial) => {
80960
+ const recordAccepted = (runId, progress) => {
80961
+ receiptBackoff.delete(runId);
80962
+ credentialPark = null;
80963
+ if (!progress.sealed) {
80964
+ lastSentAt.set(runId, clock.monotonic());
80965
+ return;
80966
+ }
80967
+ sealed.add(runId);
80968
+ lastSentAt.delete(runId);
80969
+ log.info("upload.sealed", { runId, bytes: progress.admittedOffset });
80970
+ };
80971
+ const drain = async (runUpload, initial, tokenAtStart) => {
80724
80972
  const { runId } = runUpload.target;
80725
80973
  let progress = initial;
80726
80974
  let failures = 0;
@@ -80728,7 +80976,7 @@ function startUploader({
80728
80976
  const step = await sendNext(runUpload, progress);
80729
80977
  if (step.kind === "caught_up") return "settled";
80730
80978
  if (step.kind === "rejected") {
80731
- await reject(runId, runUpload.progressPath, progress, step.rejection);
80979
+ await reject(runId, runUpload.progressPath, progress, step.rejection, tokenAtStart);
80732
80980
  return "retry_later";
80733
80981
  }
80734
80982
  if (step.kind === "retry") {
@@ -80737,13 +80985,9 @@ function startUploader({
80737
80985
  continue;
80738
80986
  }
80739
80987
  failures = 0;
80740
- receiptBackoff.delete(runId);
80741
80988
  progress = step.progress;
80742
- if (progress.sealed) {
80743
- sealed.add(runId);
80744
- log.info("upload.sealed", { runId, bytes: progress.admittedOffset });
80745
- return "settled";
80746
- }
80989
+ recordAccepted(runId, progress);
80990
+ if (progress.sealed || !step.more) return "settled";
80747
80991
  }
80748
80992
  return "settled";
80749
80993
  };
@@ -80754,9 +80998,11 @@ function startUploader({
80754
80998
  const meta3 = await readRunMeta(dir.meta);
80755
80999
  if (meta3 === null) return "settled";
80756
81000
  const target = { conversationId: meta3.conversationId, runId };
81001
+ if (credentialParked()) return "retry_later";
80757
81002
  const backoff = receiptBackoff.get(runId);
80758
81003
  if (backoff !== void 0 && backoff.notBefore > clock.now()) return "retry_later";
80759
- const progress = await progressOf(runId, target, dir.upload);
81004
+ const tokenAtStart = accessToken();
81005
+ const progress = await progressOf(runId, target, dir.upload, tokenAtStart);
80760
81006
  if (progress === null) return "retry_later";
80761
81007
  if (progress.sealed) {
80762
81008
  sealed.add(runId);
@@ -80766,11 +81012,12 @@ function startUploader({
80766
81012
  return "retry_later";
80767
81013
  }
80768
81014
  const reader = __using(_stack, await openRunLogReader(dir.log), true);
80769
- const attempt2 = await drain(
81015
+ const attempt3 = await drain(
80770
81016
  { target, reader, logPath: dir.log, progressPath: dir.upload },
80771
- progress
81017
+ progress,
81018
+ tokenAtStart
80772
81019
  );
80773
- return attempt2;
81020
+ return attempt3;
80774
81021
  } catch (_) {
80775
81022
  var _error = _, _hasError = true;
80776
81023
  } finally {
@@ -80778,20 +81025,48 @@ function startUploader({
80778
81025
  _promise2 && await _promise2;
80779
81026
  }
80780
81027
  };
80781
- const run2 = (runId) => {
81028
+ const coalesce = async (runId) => {
81029
+ const delay4 = (lastSentAt.get(runId) ?? Number.NEGATIVE_INFINITY) + UPLOAD_COALESCE_MS;
81030
+ const remaining = delay4 - clock.monotonic();
81031
+ if (remaining <= 0) return;
81032
+ const wake = new AbortController();
81033
+ coalescing.set(runId, wake);
81034
+ try {
81035
+ await clock.sleep(remaining, AbortSignal.any([wake.signal, controller.signal]));
81036
+ } catch {
81037
+ } finally {
81038
+ coalescing.delete(runId);
81039
+ }
81040
+ };
81041
+ const attempt2 = async (runId, timing) => {
81042
+ if (timing === "coalesced") await coalesce(runId);
81043
+ again.delete(runId);
81044
+ againNow.delete(runId);
81045
+ if (controller.signal.aborted) return "settled";
81046
+ return upload(runId);
81047
+ };
81048
+ const run2 = (runId, timing = "immediate") => {
81049
+ if (revoked) return;
80782
81050
  if (active.has(runId)) {
80783
81051
  again.add(runId);
81052
+ if (timing === "immediate") {
81053
+ againNow.add(runId);
81054
+ coalescing.get(runId)?.abort();
81055
+ }
80784
81056
  return;
80785
81057
  }
80786
- const task = upload(runId).then((attempt2) => {
80787
- if (attempt2 === "settled") retrying.delete(runId);
81058
+ const task = attempt2(runId, timing).then((attempt3) => {
81059
+ if (attempt3 === "settled") retrying.delete(runId);
80788
81060
  else retrying.add(runId);
80789
81061
  }).catch((error62) => {
80790
81062
  retrying.add(runId);
80791
81063
  if (!controller.signal.aborted) log.warn("upload.failed", { runId, error: error62 });
80792
81064
  }).finally(() => {
80793
81065
  active.delete(runId);
80794
- if (again.delete(runId) && !controller.signal.aborted) run2(runId);
81066
+ const now = againNow.delete(runId);
81067
+ if (again.delete(runId) && !controller.signal.aborted) {
81068
+ run2(runId, now ? "immediate" : "coalesced");
81069
+ }
80795
81070
  });
80796
81071
  active.set(runId, task);
80797
81072
  };
@@ -80838,7 +81113,8 @@ function startUploader({
80838
81113
  return found;
80839
81114
  };
80840
81115
  return {
80841
- notify: run2,
81116
+ notify: (runId) => run2(runId, "coalesced"),
81117
+ uploadNow: (runId) => run2(runId, "immediate"),
80842
81118
  sweep: sweep2,
80843
81119
  pending: (uploads) => {
80844
81120
  pendingRuns = new Map(
@@ -81246,6 +81522,7 @@ async function startMachinePlane(deps) {
81246
81522
  () => identity.renewAfterRejection(stopped.signal)
81247
81523
  );
81248
81524
  if (renewal.kind === "revoked") deps.onRevoked();
81525
+ return renewal;
81249
81526
  };
81250
81527
  const sessionsOpened = Promise.withResolvers();
81251
81528
  const planeOpened = Promise.withResolvers();
@@ -81288,7 +81565,9 @@ async function startMachinePlane(deps) {
81288
81565
  refreshDesired();
81289
81566
  },
81290
81567
  onConnectRefused: (error62) => updates.connectRefused(error62),
81291
- refreshCredential: renewAfterRejection,
81568
+ refreshCredential: async () => {
81569
+ await renewAfterRejection();
81570
+ },
81292
81571
  onStateChange: deps.onStatusChange,
81293
81572
  answerWorkspaceQuery: (request2) => workspaces.answer(request2),
81294
81573
  respond: (request2) => sessions.respond(request2),
@@ -81350,7 +81629,11 @@ async function startMachinePlane(deps) {
81350
81629
  clock,
81351
81630
  log,
81352
81631
  archive,
81353
- onUnauthorized: renewAfterRejection
81632
+ onUnauthorized: async () => {
81633
+ const renewal = await renewAfterRejection();
81634
+ return renewal.kind === "renewed" || renewal.kind === "revoked" ? renewal.kind : "unchanged";
81635
+ },
81636
+ accessToken: identity.accessToken
81354
81637
  })
81355
81638
  );
81356
81639
  const nativeIngest = stack.use(
@@ -81414,7 +81697,7 @@ async function startMachinePlane(deps) {
81414
81697
  onTurnEnded: (runId) => {
81415
81698
  runsShownRunning.delete(runId);
81416
81699
  deps.onStatusChange();
81417
- uploader.notify(runId);
81700
+ uploader.uploadNow(runId);
81418
81701
  appends.notify(runId);
81419
81702
  nativeIngest.runEnded(runId);
81420
81703
  followActiveRuns().catch((error62) => log.warn("power.follow_failed", { error: error62 }));