@autohq/cli 0.1.325 → 0.1.327

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.
@@ -23434,7 +23434,7 @@ Object.assign(lookup, {
23434
23434
  // package.json
23435
23435
  var package_default = {
23436
23436
  name: "@autohq/cli",
23437
- version: "0.1.325",
23437
+ version: "0.1.327",
23438
23438
  license: "SEE LICENSE IN README.md",
23439
23439
  publishConfig: {
23440
23440
  access: "public"
@@ -28061,6 +28061,68 @@ var SessionDiagnosticEventSchema = external_exports.object({
28061
28061
  createdAt: external_exports.string().datetime()
28062
28062
  });
28063
28063
 
28064
+ // ../../packages/schemas/src/runtime-restart-diagnostics.ts
28065
+ var SANDBOX_CLASSIFICATIONS = [
28066
+ "running",
28067
+ "paused",
28068
+ "finished",
28069
+ "missing"
28070
+ ];
28071
+ var SandboxClassificationSchema = external_exports.enum(SANDBOX_CLASSIFICATIONS);
28072
+ var RUNTIME_RESTART_CAUSES = [
28073
+ // No active, unexpired bridge lease row exists for the session's runtime.
28074
+ "lease_missing",
28075
+ // The provider no longer knows the sandbox (killed, expired, host recycled).
28076
+ "sandbox_missing",
28077
+ // The provider paused the sandbox while the lease stayed current.
28078
+ "sandbox_paused",
28079
+ // The provider reports the sandbox finished.
28080
+ "sandbox_finished",
28081
+ // The sandbox is running but the bridge wrapper process is not.
28082
+ "wrapper_not_running",
28083
+ // The wrapper is running under a different lease than the current one.
28084
+ "lease_mismatch",
28085
+ // Socket delivery on an apparently healthy lease threw.
28086
+ "delivery_failed"
28087
+ ];
28088
+ var RuntimeRestartCauseSchema = external_exports.enum(RUNTIME_RESTART_CAUSES);
28089
+ var RuntimeRestartLeaseSnapshotSchema = external_exports.object({
28090
+ id: RuntimeBridgeLeaseIdSchema2,
28091
+ status: external_exports.enum(["active", "revoked"]),
28092
+ accessExpiresAt: external_exports.string().datetime(),
28093
+ lastUsedAt: external_exports.string().datetime().nullable(),
28094
+ revokedAt: external_exports.string().datetime().nullable(),
28095
+ createdAt: external_exports.string().datetime()
28096
+ });
28097
+ var RuntimeRestartInspectionSnapshotSchema = external_exports.object({
28098
+ sandboxClassification: SandboxClassificationSchema,
28099
+ sandboxId: external_exports.string().nullable(),
28100
+ wrapperRunning: external_exports.boolean(),
28101
+ wrapperBridgeLeaseId: external_exports.string().nullable()
28102
+ });
28103
+ var RuntimeRestartDiagnosticRecordSchema = external_exports.object({
28104
+ id: external_exports.string(),
28105
+ sessionId: SessionIdSchema2,
28106
+ runtimeId: RuntimeIdSchema2,
28107
+ providerId: external_exports.string(),
28108
+ cause: RuntimeRestartCauseSchema,
28109
+ /** Free-form detection detail, e.g. the delivery error message. */
28110
+ detail: external_exports.string().nullable(),
28111
+ sandboxId: external_exports.string().nullable(),
28112
+ /** The lease the restart decision was made against, when one existed. */
28113
+ bridgeLeaseId: RuntimeBridgeLeaseIdSchema2.nullable(),
28114
+ lease: RuntimeRestartLeaseSnapshotSchema.nullable(),
28115
+ inspection: RuntimeRestartInspectionSnapshotSchema.nullable(),
28116
+ /**
28117
+ * Bounded, secret-redacted tail of the durable in-sandbox runtime log,
28118
+ * captured only when the sandbox was still running. Contains the bridge
28119
+ * supervisor's `agent_bridge_exited status=N` markers when the wrapper died.
28120
+ */
28121
+ logTail: external_exports.string().nullable(),
28122
+ detectedAt: external_exports.string().datetime(),
28123
+ createdAt: external_exports.string().datetime()
28124
+ });
28125
+
28064
28126
  // ../../packages/schemas/src/session-introspection.ts
28065
28127
  var TruncatedValueSchema = external_exports.object({
28066
28128
  truncated: external_exports.literal(true),
@@ -28190,6 +28252,16 @@ var SessionToolStatSchema = external_exports.object({
28190
28252
  max: external_exports.number().nonnegative().nullable()
28191
28253
  })
28192
28254
  });
28255
+ var RunRuntimeRestartSchema = external_exports.object({
28256
+ cause: RuntimeRestartCauseSchema,
28257
+ detail: external_exports.string().nullable(),
28258
+ sandboxId: external_exports.string().nullable(),
28259
+ sandboxClassification: SandboxClassificationSchema.nullable(),
28260
+ wrapperRunning: external_exports.boolean().nullable(),
28261
+ detectedAt: external_exports.string().datetime(),
28262
+ logTail: external_exports.string().nullable(),
28263
+ logTailTruncated: external_exports.boolean()
28264
+ });
28193
28265
  var RunSummarySchema = external_exports.object({
28194
28266
  session: external_exports.object({
28195
28267
  id: SessionIdSchema2,
@@ -28259,7 +28331,12 @@ var RunSummarySchema = external_exports.object({
28259
28331
  conclusion: SessionCheckConclusionSchema.nullable(),
28260
28332
  completedAt: external_exports.string().datetime().nullable()
28261
28333
  })
28262
- )
28334
+ ),
28335
+ /** Runtime restart diagnostics, newest first, capped to the most recent. */
28336
+ runtimeRestarts: external_exports.object({
28337
+ count: external_exports.number().int().nonnegative(),
28338
+ recent: external_exports.array(RunRuntimeRestartSchema)
28339
+ })
28263
28340
  });
28264
28341
 
28265
28342
  // ../../packages/schemas/src/session-turns.ts
@@ -42355,6 +42432,7 @@ function providerMetadataField(providerMetadata) {
42355
42432
 
42356
42433
  // src/commands/agent-bridge/harness/output-buffer.ts
42357
42434
  var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
42435
+ var AGENT_BRIDGE_OUTPUT_UI_DELTA_MAX_CHARS = 32768;
42358
42436
  var AGENT_BRIDGE_OUTPUT_ACK_RETRY_BACKOFF_MS = [250, 1e3];
42359
42437
  var AgentBridgeOutputBuffer = class {
42360
42438
  constructor(input) {
@@ -42366,6 +42444,8 @@ var AgentBridgeOutputBuffer = class {
42366
42444
  pendingOutputs = /* @__PURE__ */ new Map();
42367
42445
  pendingDelta = null;
42368
42446
  deltaFlushTimer = null;
42447
+ pendingUiDelta = null;
42448
+ uiDeltaFlushTimer = null;
42369
42449
  activeUiMessageAssembler = null;
42370
42450
  uiMessagePartTracker = new UiMessagePartTracker();
42371
42451
  drainBlocked = false;
@@ -42375,6 +42455,12 @@ var AgentBridgeOutputBuffer = class {
42375
42455
  // ---------------------------------------------------------------------------
42376
42456
  async emitProjection(context, projection) {
42377
42457
  if (projection.type === "ui_message_chunk") {
42458
+ const coalescible = coalescibleUiDeltaChunk(projection);
42459
+ if (coalescible) {
42460
+ await this.bufferUiDeltaChunk(context, coalescible);
42461
+ return;
42462
+ }
42463
+ await this.flushPendingUiDelta();
42378
42464
  await this.emitUiMessageChunk(context, projection);
42379
42465
  return;
42380
42466
  }
@@ -42382,10 +42468,12 @@ var AgentBridgeOutputBuffer = class {
42382
42468
  await this.bufferDelta(context, projection.delta);
42383
42469
  return;
42384
42470
  }
42471
+ await this.flushPendingUiDelta();
42385
42472
  await this.flushPendingDelta();
42386
42473
  await this.enqueueProjectionAndDrain(context, projection);
42387
42474
  }
42388
42475
  async replayPendingOutputs() {
42476
+ await this.materializePendingUiDelta();
42389
42477
  await this.flushPendingDelta({ force: true });
42390
42478
  await this.drainPendingOutputs({ force: true });
42391
42479
  }
@@ -42509,10 +42597,15 @@ var AgentBridgeOutputBuffer = class {
42509
42597
  this.drainPromise ??= (async () => {
42510
42598
  while (true) {
42511
42599
  const output = this.nextPendingOutput();
42512
- if (!output) {
42513
- return;
42600
+ if (output) {
42601
+ await this.emitUntilAcked(output);
42602
+ continue;
42603
+ }
42604
+ if (this.pendingUiDelta) {
42605
+ await this.materializePendingUiDelta();
42606
+ continue;
42514
42607
  }
42515
- await this.emitUntilAcked(output);
42608
+ return;
42516
42609
  }
42517
42610
  })().catch((error51) => {
42518
42611
  this.drainBlocked = true;
@@ -42523,6 +42616,85 @@ var AgentBridgeOutputBuffer = class {
42523
42616
  await this.drainPromise;
42524
42617
  }
42525
42618
  // ---------------------------------------------------------------------------
42619
+ // UI chunk delta coalescing
42620
+ // ---------------------------------------------------------------------------
42621
+ async bufferUiDeltaChunk(context, chunk) {
42622
+ const pending = this.pendingUiDelta;
42623
+ if (pending && canCoalesceUiDelta(pending, context, chunk)) {
42624
+ pending.chunk = mergeUiDeltaChunks(pending.chunk, chunk);
42625
+ if (uiDeltaTextLength(pending.chunk) >= AGENT_BRIDGE_OUTPUT_UI_DELTA_MAX_CHARS) {
42626
+ await this.flushPendingUiDelta();
42627
+ }
42628
+ return;
42629
+ }
42630
+ await this.flushPendingUiDelta();
42631
+ this.pendingUiDelta = { context, chunk: { ...chunk }, createdAt: now2() };
42632
+ this.scheduleUiDeltaFlush();
42633
+ }
42634
+ scheduleUiDeltaFlush() {
42635
+ if (this.uiDeltaFlushTimer !== null) {
42636
+ return;
42637
+ }
42638
+ this.uiDeltaFlushTimer = setTimeout(() => {
42639
+ this.uiDeltaFlushTimer = null;
42640
+ if (!this.pendingUiDelta) {
42641
+ return;
42642
+ }
42643
+ if (this.drainPromise) {
42644
+ this.scheduleUiDeltaFlush();
42645
+ return;
42646
+ }
42647
+ void this.flushPendingUiDelta().catch((error51) => {
42648
+ this.drainBlocked = true;
42649
+ this.input.runtimeLogger?.warn(
42650
+ "agent_bridge_output_buffer_flush_failed",
42651
+ {
42652
+ error: error51 instanceof Error ? error51.message : String(error51),
42653
+ pending_count: this.pendingOutputs.size
42654
+ }
42655
+ );
42656
+ });
42657
+ }, AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS);
42658
+ }
42659
+ clearUiDeltaFlushTimer() {
42660
+ if (this.uiDeltaFlushTimer === null) {
42661
+ return;
42662
+ }
42663
+ clearTimeout(this.uiDeltaFlushTimer);
42664
+ this.uiDeltaFlushTimer = null;
42665
+ }
42666
+ async flushPendingUiDelta() {
42667
+ if (!this.pendingUiDelta) {
42668
+ return;
42669
+ }
42670
+ await this.materializePendingUiDelta();
42671
+ await this.drainPendingOutputs();
42672
+ }
42673
+ // Turns the parked coalesced chunk into a queued envelope and applies it to
42674
+ // the part tracker and message assembler, exactly as its source chunks would
42675
+ // have applied one by one (delta chunks never settle a part or complete a
42676
+ // message, so tracker/assembler side effects reduce to text accumulation).
42677
+ // Does not drain: the drain loop calls this mid-loop and keeps pulling.
42678
+ async materializePendingUiDelta() {
42679
+ const pending = this.pendingUiDelta;
42680
+ if (!pending) {
42681
+ return;
42682
+ }
42683
+ this.pendingUiDelta = null;
42684
+ this.clearUiDeltaFlushTimer();
42685
+ this.outputSeq += 1;
42686
+ this.enqueueOutput(
42687
+ buildUiMessageChunkOutputEnvelope({
42688
+ context: pending.context,
42689
+ outputSeq: this.outputSeq,
42690
+ chunk: pending.chunk,
42691
+ createdAt: pending.createdAt
42692
+ })
42693
+ );
42694
+ this.uiMessagePartTracker.append(pending.chunk);
42695
+ await this.appendUiChunkToAssembler(pending.chunk);
42696
+ }
42697
+ // ---------------------------------------------------------------------------
42526
42698
  // Delta coalescing
42527
42699
  // ---------------------------------------------------------------------------
42528
42700
  async bufferDelta(context, delta) {
@@ -42828,6 +43000,50 @@ function terminalEntryStatus(projection) {
42828
43000
  }
42829
43001
  return "completed";
42830
43002
  }
43003
+ function coalescibleUiDeltaChunk(projection) {
43004
+ if (projection.statusText !== void 0 || projection.turnStatus !== void 0 || projection.usage !== void 0 || projection.consumedCommandIds !== void 0) {
43005
+ return null;
43006
+ }
43007
+ const chunk = projection.chunk;
43008
+ switch (chunk.type) {
43009
+ case "text-delta":
43010
+ case "reasoning-delta":
43011
+ return chunk.providerMetadata === void 0 ? chunk : null;
43012
+ case "tool-input-delta":
43013
+ return chunk;
43014
+ default:
43015
+ return null;
43016
+ }
43017
+ }
43018
+ function canCoalesceUiDelta(pending, context, chunk) {
43019
+ if (pending.context.sessionId !== context.sessionId || pending.context.runtimeId !== context.runtimeId || pending.context.bridgeLeaseId !== context.bridgeLeaseId || pending.chunk.type !== chunk.type) {
43020
+ return false;
43021
+ }
43022
+ if (pending.chunk.type === "tool-input-delta" && chunk.type === "tool-input-delta") {
43023
+ return pending.chunk.toolCallId === chunk.toolCallId;
43024
+ }
43025
+ if (pending.chunk.type !== "tool-input-delta" && chunk.type !== "tool-input-delta") {
43026
+ return pending.chunk.id === chunk.id;
43027
+ }
43028
+ return false;
43029
+ }
43030
+ function mergeUiDeltaChunks(pending, chunk) {
43031
+ if (pending.type === "tool-input-delta" && chunk.type === "tool-input-delta") {
43032
+ return {
43033
+ ...pending,
43034
+ inputTextDelta: pending.inputTextDelta + chunk.inputTextDelta
43035
+ };
43036
+ }
43037
+ if (pending.type !== "tool-input-delta" && chunk.type !== "tool-input-delta") {
43038
+ return { ...pending, delta: pending.delta + chunk.delta };
43039
+ }
43040
+ throw new Error(
43041
+ `Cannot merge ui delta chunks of kinds ${pending.type} and ${chunk.type}`
43042
+ );
43043
+ }
43044
+ function uiDeltaTextLength(chunk) {
43045
+ return chunk.type === "tool-input-delta" ? chunk.inputTextDelta.length : chunk.delta.length;
43046
+ }
42831
43047
  function canCoalesceDelta(pending, context, delta) {
42832
43048
  return pending.context.sessionId === context.sessionId && pending.context.runtimeId === context.runtimeId && pending.context.bridgeLeaseId === context.bridgeLeaseId && pending.delta.messageId === delta.messageId && pending.delta.partId === delta.partId && pending.delta.role === delta.role && pending.delta.kind === delta.kind && pending.delta.delta.type === delta.delta.type;
42833
43049
  }
package/dist/index.js CHANGED
@@ -19787,8 +19787,78 @@ var init_session_diagnostics = __esm({
19787
19787
  }
19788
19788
  });
19789
19789
 
19790
+ // ../../packages/schemas/src/runtime-restart-diagnostics.ts
19791
+ var SANDBOX_CLASSIFICATIONS, SandboxClassificationSchema, RUNTIME_RESTART_CAUSES, RuntimeRestartCauseSchema, RuntimeRestartLeaseSnapshotSchema, RuntimeRestartInspectionSnapshotSchema, RuntimeRestartDiagnosticRecordSchema;
19792
+ var init_runtime_restart_diagnostics = __esm({
19793
+ "../../packages/schemas/src/runtime-restart-diagnostics.ts"() {
19794
+ "use strict";
19795
+ init_zod();
19796
+ init_ids();
19797
+ SANDBOX_CLASSIFICATIONS = [
19798
+ "running",
19799
+ "paused",
19800
+ "finished",
19801
+ "missing"
19802
+ ];
19803
+ SandboxClassificationSchema = external_exports.enum(SANDBOX_CLASSIFICATIONS);
19804
+ RUNTIME_RESTART_CAUSES = [
19805
+ // No active, unexpired bridge lease row exists for the session's runtime.
19806
+ "lease_missing",
19807
+ // The provider no longer knows the sandbox (killed, expired, host recycled).
19808
+ "sandbox_missing",
19809
+ // The provider paused the sandbox while the lease stayed current.
19810
+ "sandbox_paused",
19811
+ // The provider reports the sandbox finished.
19812
+ "sandbox_finished",
19813
+ // The sandbox is running but the bridge wrapper process is not.
19814
+ "wrapper_not_running",
19815
+ // The wrapper is running under a different lease than the current one.
19816
+ "lease_mismatch",
19817
+ // Socket delivery on an apparently healthy lease threw.
19818
+ "delivery_failed"
19819
+ ];
19820
+ RuntimeRestartCauseSchema = external_exports.enum(RUNTIME_RESTART_CAUSES);
19821
+ RuntimeRestartLeaseSnapshotSchema = external_exports.object({
19822
+ id: RuntimeBridgeLeaseIdSchema,
19823
+ status: external_exports.enum(["active", "revoked"]),
19824
+ accessExpiresAt: external_exports.string().datetime(),
19825
+ lastUsedAt: external_exports.string().datetime().nullable(),
19826
+ revokedAt: external_exports.string().datetime().nullable(),
19827
+ createdAt: external_exports.string().datetime()
19828
+ });
19829
+ RuntimeRestartInspectionSnapshotSchema = external_exports.object({
19830
+ sandboxClassification: SandboxClassificationSchema,
19831
+ sandboxId: external_exports.string().nullable(),
19832
+ wrapperRunning: external_exports.boolean(),
19833
+ wrapperBridgeLeaseId: external_exports.string().nullable()
19834
+ });
19835
+ RuntimeRestartDiagnosticRecordSchema = external_exports.object({
19836
+ id: external_exports.string(),
19837
+ sessionId: SessionIdSchema,
19838
+ runtimeId: RuntimeIdSchema,
19839
+ providerId: external_exports.string(),
19840
+ cause: RuntimeRestartCauseSchema,
19841
+ /** Free-form detection detail, e.g. the delivery error message. */
19842
+ detail: external_exports.string().nullable(),
19843
+ sandboxId: external_exports.string().nullable(),
19844
+ /** The lease the restart decision was made against, when one existed. */
19845
+ bridgeLeaseId: RuntimeBridgeLeaseIdSchema.nullable(),
19846
+ lease: RuntimeRestartLeaseSnapshotSchema.nullable(),
19847
+ inspection: RuntimeRestartInspectionSnapshotSchema.nullable(),
19848
+ /**
19849
+ * Bounded, secret-redacted tail of the durable in-sandbox runtime log,
19850
+ * captured only when the sandbox was still running. Contains the bridge
19851
+ * supervisor's `agent_bridge_exited status=N` markers when the wrapper died.
19852
+ */
19853
+ logTail: external_exports.string().nullable(),
19854
+ detectedAt: external_exports.string().datetime(),
19855
+ createdAt: external_exports.string().datetime()
19856
+ });
19857
+ }
19858
+ });
19859
+
19790
19860
  // ../../packages/schemas/src/session-introspection.ts
19791
- var TruncatedValueSchema, RunConversationSearchSnippetSchema, RunConversationSearchMatchSchema, RunConversationSearchResponseSchema, SessionToolExchangeSchema, SessionToolExchangesResponseSchema, SESSION_TRIGGER_DELIVERY_ACTIONS, SessionTriggerDeliveryActionSchema, SESSION_EVENT_ORIGIN_KINDS, SessionEventOriginKindSchema, SessionTriggerDeliveryRecordSchema, SessionTriggersResponseSchema, RunBindingRecordSchema, RunBindingsResponseSchema, RunTurnSchema, SessionToolStatSchema, RunSummarySchema;
19861
+ var TruncatedValueSchema, RunConversationSearchSnippetSchema, RunConversationSearchMatchSchema, RunConversationSearchResponseSchema, SessionToolExchangeSchema, SessionToolExchangesResponseSchema, SESSION_TRIGGER_DELIVERY_ACTIONS, SessionTriggerDeliveryActionSchema, SESSION_EVENT_ORIGIN_KINDS, SessionEventOriginKindSchema, SessionTriggerDeliveryRecordSchema, SessionTriggersResponseSchema, RunBindingRecordSchema, RunBindingsResponseSchema, RunTurnSchema, SessionToolStatSchema, RunRuntimeRestartSchema, RunSummarySchema;
19792
19862
  var init_session_introspection = __esm({
19793
19863
  "../../packages/schemas/src/session-introspection.ts"() {
19794
19864
  "use strict";
@@ -19797,6 +19867,7 @@ var init_session_introspection = __esm({
19797
19867
  init_conversation();
19798
19868
  init_ids();
19799
19869
  init_primitives();
19870
+ init_runtime_restart_diagnostics();
19800
19871
  init_session_bindings();
19801
19872
  init_sessions();
19802
19873
  TruncatedValueSchema = external_exports.object({
@@ -19927,6 +19998,16 @@ var init_session_introspection = __esm({
19927
19998
  max: external_exports.number().nonnegative().nullable()
19928
19999
  })
19929
20000
  });
20001
+ RunRuntimeRestartSchema = external_exports.object({
20002
+ cause: RuntimeRestartCauseSchema,
20003
+ detail: external_exports.string().nullable(),
20004
+ sandboxId: external_exports.string().nullable(),
20005
+ sandboxClassification: SandboxClassificationSchema.nullable(),
20006
+ wrapperRunning: external_exports.boolean().nullable(),
20007
+ detectedAt: external_exports.string().datetime(),
20008
+ logTail: external_exports.string().nullable(),
20009
+ logTailTruncated: external_exports.boolean()
20010
+ });
19930
20011
  RunSummarySchema = external_exports.object({
19931
20012
  session: external_exports.object({
19932
20013
  id: SessionIdSchema,
@@ -19996,7 +20077,12 @@ var init_session_introspection = __esm({
19996
20077
  conclusion: SessionCheckConclusionSchema.nullable(),
19997
20078
  completedAt: external_exports.string().datetime().nullable()
19998
20079
  })
19999
- )
20080
+ ),
20081
+ /** Runtime restart diagnostics, newest first, capped to the most recent. */
20082
+ runtimeRestarts: external_exports.object({
20083
+ count: external_exports.number().int().nonnegative(),
20084
+ recent: external_exports.array(RunRuntimeRestartSchema)
20085
+ })
20000
20086
  });
20001
20087
  }
20002
20088
  });
@@ -25731,6 +25817,7 @@ var init_src = __esm({
25731
25817
  init_pool_replace();
25732
25818
  init_runtime_log();
25733
25819
  init_runtime_log_tailer();
25820
+ init_runtime_restart_diagnostics();
25734
25821
  init_runtimes();
25735
25822
  init_sessions();
25736
25823
  init_agents();
@@ -28471,7 +28558,7 @@ var init_package = __esm({
28471
28558
  "package.json"() {
28472
28559
  package_default = {
28473
28560
  name: "@autohq/cli",
28474
- version: "0.1.325",
28561
+ version: "0.1.327",
28475
28562
  license: "SEE LICENSE IN README.md",
28476
28563
  publishConfig: {
28477
28564
  access: "public"
@@ -39475,6 +39562,7 @@ function providerMetadataField(providerMetadata) {
39475
39562
 
39476
39563
  // src/commands/agent-bridge/harness/output-buffer.ts
39477
39564
  var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
39565
+ var AGENT_BRIDGE_OUTPUT_UI_DELTA_MAX_CHARS = 32768;
39478
39566
  var AGENT_BRIDGE_OUTPUT_ACK_RETRY_BACKOFF_MS = [250, 1e3];
39479
39567
  var AgentBridgeOutputBuffer = class {
39480
39568
  constructor(input) {
@@ -39486,6 +39574,8 @@ var AgentBridgeOutputBuffer = class {
39486
39574
  pendingOutputs = /* @__PURE__ */ new Map();
39487
39575
  pendingDelta = null;
39488
39576
  deltaFlushTimer = null;
39577
+ pendingUiDelta = null;
39578
+ uiDeltaFlushTimer = null;
39489
39579
  activeUiMessageAssembler = null;
39490
39580
  uiMessagePartTracker = new UiMessagePartTracker();
39491
39581
  drainBlocked = false;
@@ -39495,6 +39585,12 @@ var AgentBridgeOutputBuffer = class {
39495
39585
  // ---------------------------------------------------------------------------
39496
39586
  async emitProjection(context, projection) {
39497
39587
  if (projection.type === "ui_message_chunk") {
39588
+ const coalescible = coalescibleUiDeltaChunk(projection);
39589
+ if (coalescible) {
39590
+ await this.bufferUiDeltaChunk(context, coalescible);
39591
+ return;
39592
+ }
39593
+ await this.flushPendingUiDelta();
39498
39594
  await this.emitUiMessageChunk(context, projection);
39499
39595
  return;
39500
39596
  }
@@ -39502,10 +39598,12 @@ var AgentBridgeOutputBuffer = class {
39502
39598
  await this.bufferDelta(context, projection.delta);
39503
39599
  return;
39504
39600
  }
39601
+ await this.flushPendingUiDelta();
39505
39602
  await this.flushPendingDelta();
39506
39603
  await this.enqueueProjectionAndDrain(context, projection);
39507
39604
  }
39508
39605
  async replayPendingOutputs() {
39606
+ await this.materializePendingUiDelta();
39509
39607
  await this.flushPendingDelta({ force: true });
39510
39608
  await this.drainPendingOutputs({ force: true });
39511
39609
  }
@@ -39629,10 +39727,15 @@ var AgentBridgeOutputBuffer = class {
39629
39727
  this.drainPromise ??= (async () => {
39630
39728
  while (true) {
39631
39729
  const output = this.nextPendingOutput();
39632
- if (!output) {
39633
- return;
39730
+ if (output) {
39731
+ await this.emitUntilAcked(output);
39732
+ continue;
39733
+ }
39734
+ if (this.pendingUiDelta) {
39735
+ await this.materializePendingUiDelta();
39736
+ continue;
39634
39737
  }
39635
- await this.emitUntilAcked(output);
39738
+ return;
39636
39739
  }
39637
39740
  })().catch((error51) => {
39638
39741
  this.drainBlocked = true;
@@ -39643,6 +39746,85 @@ var AgentBridgeOutputBuffer = class {
39643
39746
  await this.drainPromise;
39644
39747
  }
39645
39748
  // ---------------------------------------------------------------------------
39749
+ // UI chunk delta coalescing
39750
+ // ---------------------------------------------------------------------------
39751
+ async bufferUiDeltaChunk(context, chunk) {
39752
+ const pending = this.pendingUiDelta;
39753
+ if (pending && canCoalesceUiDelta(pending, context, chunk)) {
39754
+ pending.chunk = mergeUiDeltaChunks(pending.chunk, chunk);
39755
+ if (uiDeltaTextLength(pending.chunk) >= AGENT_BRIDGE_OUTPUT_UI_DELTA_MAX_CHARS) {
39756
+ await this.flushPendingUiDelta();
39757
+ }
39758
+ return;
39759
+ }
39760
+ await this.flushPendingUiDelta();
39761
+ this.pendingUiDelta = { context, chunk: { ...chunk }, createdAt: now2() };
39762
+ this.scheduleUiDeltaFlush();
39763
+ }
39764
+ scheduleUiDeltaFlush() {
39765
+ if (this.uiDeltaFlushTimer !== null) {
39766
+ return;
39767
+ }
39768
+ this.uiDeltaFlushTimer = setTimeout(() => {
39769
+ this.uiDeltaFlushTimer = null;
39770
+ if (!this.pendingUiDelta) {
39771
+ return;
39772
+ }
39773
+ if (this.drainPromise) {
39774
+ this.scheduleUiDeltaFlush();
39775
+ return;
39776
+ }
39777
+ void this.flushPendingUiDelta().catch((error51) => {
39778
+ this.drainBlocked = true;
39779
+ this.input.runtimeLogger?.warn(
39780
+ "agent_bridge_output_buffer_flush_failed",
39781
+ {
39782
+ error: error51 instanceof Error ? error51.message : String(error51),
39783
+ pending_count: this.pendingOutputs.size
39784
+ }
39785
+ );
39786
+ });
39787
+ }, AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS);
39788
+ }
39789
+ clearUiDeltaFlushTimer() {
39790
+ if (this.uiDeltaFlushTimer === null) {
39791
+ return;
39792
+ }
39793
+ clearTimeout(this.uiDeltaFlushTimer);
39794
+ this.uiDeltaFlushTimer = null;
39795
+ }
39796
+ async flushPendingUiDelta() {
39797
+ if (!this.pendingUiDelta) {
39798
+ return;
39799
+ }
39800
+ await this.materializePendingUiDelta();
39801
+ await this.drainPendingOutputs();
39802
+ }
39803
+ // Turns the parked coalesced chunk into a queued envelope and applies it to
39804
+ // the part tracker and message assembler, exactly as its source chunks would
39805
+ // have applied one by one (delta chunks never settle a part or complete a
39806
+ // message, so tracker/assembler side effects reduce to text accumulation).
39807
+ // Does not drain: the drain loop calls this mid-loop and keeps pulling.
39808
+ async materializePendingUiDelta() {
39809
+ const pending = this.pendingUiDelta;
39810
+ if (!pending) {
39811
+ return;
39812
+ }
39813
+ this.pendingUiDelta = null;
39814
+ this.clearUiDeltaFlushTimer();
39815
+ this.outputSeq += 1;
39816
+ this.enqueueOutput(
39817
+ buildUiMessageChunkOutputEnvelope({
39818
+ context: pending.context,
39819
+ outputSeq: this.outputSeq,
39820
+ chunk: pending.chunk,
39821
+ createdAt: pending.createdAt
39822
+ })
39823
+ );
39824
+ this.uiMessagePartTracker.append(pending.chunk);
39825
+ await this.appendUiChunkToAssembler(pending.chunk);
39826
+ }
39827
+ // ---------------------------------------------------------------------------
39646
39828
  // Delta coalescing
39647
39829
  // ---------------------------------------------------------------------------
39648
39830
  async bufferDelta(context, delta) {
@@ -39948,6 +40130,50 @@ function terminalEntryStatus(projection) {
39948
40130
  }
39949
40131
  return "completed";
39950
40132
  }
40133
+ function coalescibleUiDeltaChunk(projection) {
40134
+ if (projection.statusText !== void 0 || projection.turnStatus !== void 0 || projection.usage !== void 0 || projection.consumedCommandIds !== void 0) {
40135
+ return null;
40136
+ }
40137
+ const chunk = projection.chunk;
40138
+ switch (chunk.type) {
40139
+ case "text-delta":
40140
+ case "reasoning-delta":
40141
+ return chunk.providerMetadata === void 0 ? chunk : null;
40142
+ case "tool-input-delta":
40143
+ return chunk;
40144
+ default:
40145
+ return null;
40146
+ }
40147
+ }
40148
+ function canCoalesceUiDelta(pending, context, chunk) {
40149
+ if (pending.context.sessionId !== context.sessionId || pending.context.runtimeId !== context.runtimeId || pending.context.bridgeLeaseId !== context.bridgeLeaseId || pending.chunk.type !== chunk.type) {
40150
+ return false;
40151
+ }
40152
+ if (pending.chunk.type === "tool-input-delta" && chunk.type === "tool-input-delta") {
40153
+ return pending.chunk.toolCallId === chunk.toolCallId;
40154
+ }
40155
+ if (pending.chunk.type !== "tool-input-delta" && chunk.type !== "tool-input-delta") {
40156
+ return pending.chunk.id === chunk.id;
40157
+ }
40158
+ return false;
40159
+ }
40160
+ function mergeUiDeltaChunks(pending, chunk) {
40161
+ if (pending.type === "tool-input-delta" && chunk.type === "tool-input-delta") {
40162
+ return {
40163
+ ...pending,
40164
+ inputTextDelta: pending.inputTextDelta + chunk.inputTextDelta
40165
+ };
40166
+ }
40167
+ if (pending.type !== "tool-input-delta" && chunk.type !== "tool-input-delta") {
40168
+ return { ...pending, delta: pending.delta + chunk.delta };
40169
+ }
40170
+ throw new Error(
40171
+ `Cannot merge ui delta chunks of kinds ${pending.type} and ${chunk.type}`
40172
+ );
40173
+ }
40174
+ function uiDeltaTextLength(chunk) {
40175
+ return chunk.type === "tool-input-delta" ? chunk.inputTextDelta.length : chunk.delta.length;
40176
+ }
39951
40177
  function canCoalesceDelta(pending, context, delta) {
39952
40178
  return pending.context.sessionId === context.sessionId && pending.context.runtimeId === context.runtimeId && pending.context.bridgeLeaseId === context.bridgeLeaseId && pending.delta.messageId === delta.messageId && pending.delta.partId === delta.partId && pending.delta.role === delta.role && pending.delta.kind === delta.kind && pending.delta.delta.type === delta.delta.type;
39953
40179
  }
@@ -47144,6 +47370,18 @@ function formatRunShowText(result, writeLine, style) {
47144
47370
  `${style.label("check:")} ${check2.name} ${check2.status}${check2.conclusion ? ` ${styleCheckConclusion(style, check2.conclusion)}` : ""}`
47145
47371
  );
47146
47372
  }
47373
+ if ((summary.runtimeRestarts?.count ?? 0) > 0) {
47374
+ writeLine(
47375
+ `${style.label("runtime restarts:")} ${summary.runtimeRestarts.count}`
47376
+ );
47377
+ for (const restart of summary.runtimeRestarts.recent ?? []) {
47378
+ writeLine(
47379
+ ` ${restart.detectedAt} ${restart.cause}${style.dim(
47380
+ `${restart.sandboxId ? ` sandbox=${restart.sandboxId}` : ""}${restart.detail ? ` ${restart.detail}` : ""}${restart.logTail ? " (log tail captured)" : ""}`
47381
+ )}`
47382
+ );
47383
+ }
47384
+ }
47147
47385
  if (summary.session.error !== null) {
47148
47386
  writeLine(style.error(`error: ${JSON.stringify(summary.session.error)}`));
47149
47387
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.325",
3
+ "version": "0.1.327",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"