@autohq/cli 0.1.334 → 0.1.336

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.334",
23437
+ version: "0.1.336",
23438
23438
  license: "SEE LICENSE IN README.md",
23439
23439
  publishConfig: {
23440
23440
  access: "public"
@@ -27651,6 +27651,9 @@ var SessionListItemSchema = external_exports.object({
27651
27651
  runtimePhase: SessionRuntimePhaseSchema.nullable(),
27652
27652
  displayTitle: RunDisplayTitleSchema,
27653
27653
  summary: external_exports.string(),
27654
+ // Additive and optional so older live frames/list payloads that predate the
27655
+ // projection keep parsing; new projections include null when no reason exists.
27656
+ failureReason: external_exports.string().nullable().optional(),
27654
27657
  agent: SessionListItemAgentSchema,
27655
27658
  createdAt: external_exports.string().datetime(),
27656
27659
  updatedAt: external_exports.string().datetime(),
@@ -43958,6 +43961,95 @@ var _a21;
43958
43961
  _a21 = symbol21;
43959
43962
  var defaultDownload2 = createDownload();
43960
43963
 
43964
+ // src/commands/agent-bridge/harness/envelope-bounds.ts
43965
+ import { Buffer as Buffer2 } from "buffer";
43966
+ var AGENT_BRIDGE_OUTPUT_MAX_ENVELOPE_BYTES = 512 * 1024;
43967
+ var AGENT_BRIDGE_OUTPUT_QUARANTINE_MAX_ENVELOPE_BYTES = 8 * 1024;
43968
+ var MIN_STRING_BUDGET_CHARS = 64;
43969
+ function boundOutputEnvelope(envelope, maxBytes = AGENT_BRIDGE_OUTPUT_MAX_ENVELOPE_BYTES) {
43970
+ const originalBytes = serializedByteLength(envelope);
43971
+ if (originalBytes <= maxBytes) {
43972
+ return { envelope, originalBytes, truncated: false };
43973
+ }
43974
+ for (let budget = initialStringBudget(maxBytes); budget >= MIN_STRING_BUDGET_CHARS; budget = Math.floor(budget / 8)) {
43975
+ const candidate = truncateLongStrings(envelope, budget);
43976
+ if (serializedByteLength(candidate) <= maxBytes) {
43977
+ return {
43978
+ envelope: RuntimeBridgeOutputEnvelopeSchema.parse(candidate),
43979
+ originalBytes,
43980
+ truncated: true
43981
+ };
43982
+ }
43983
+ }
43984
+ return {
43985
+ envelope: RuntimeBridgeOutputEnvelopeSchema.parse(
43986
+ replacePayloadWithMarker(envelope, originalBytes)
43987
+ ),
43988
+ originalBytes,
43989
+ truncated: true
43990
+ };
43991
+ }
43992
+ function serializedByteLength(value2) {
43993
+ return Buffer2.byteLength(JSON.stringify(value2), "utf8");
43994
+ }
43995
+ function initialStringBudget(maxBytes) {
43996
+ return Math.max(MIN_STRING_BUDGET_CHARS, Math.floor(maxBytes / 8));
43997
+ }
43998
+ function truncateLongStrings(value2, budget) {
43999
+ if (typeof value2 === "string") {
44000
+ if (value2.length <= budget) {
44001
+ return value2;
44002
+ }
44003
+ return `${value2.slice(0, budget)}${truncationMarker(value2.length - budget)}`;
44004
+ }
44005
+ if (Array.isArray(value2)) {
44006
+ return value2.map((item) => truncateLongStrings(item, budget));
44007
+ }
44008
+ if (typeof value2 === "object" && value2 !== null) {
44009
+ return Object.fromEntries(
44010
+ Object.entries(value2).map(([key, item]) => [
44011
+ key,
44012
+ truncateLongStrings(item, budget)
44013
+ ])
44014
+ );
44015
+ }
44016
+ return value2;
44017
+ }
44018
+ function truncationMarker(droppedChars) {
44019
+ return `\u2026 [agent-bridge truncated ${droppedChars} chars: output exceeded the bridge envelope size limit]`;
44020
+ }
44021
+ function replacePayloadWithMarker(envelope, originalBytes) {
44022
+ const text2 = `[agent-bridge removed a ${originalBytes}-byte payload: it exceeded the bridge envelope size limit and could not be truncated]`;
44023
+ switch (envelope.type) {
44024
+ case "conversation.entry":
44025
+ return { ...envelope, content: { parts: [{ type: "text", text: text2 }] } };
44026
+ case "conversation.delta":
44027
+ return { ...envelope, delta: { type: "text", text: text2 } };
44028
+ case "ui.message.chunk":
44029
+ return {
44030
+ ...envelope,
44031
+ chunk: {
44032
+ type: "text-delta",
44033
+ id: "agent-bridge-truncation",
44034
+ delta: text2
44035
+ }
44036
+ };
44037
+ case "ui.message.part": {
44038
+ const { messageMetadata: _dropped, ...rest } = envelope;
44039
+ return { ...rest, part: { type: "text", text: text2, state: "done" } };
44040
+ }
44041
+ case "ui.message.completed":
44042
+ return {
44043
+ ...envelope,
44044
+ message: {
44045
+ id: envelope.messageId,
44046
+ role: envelope.role,
44047
+ parts: [{ type: "text", text: text2, state: "done" }]
44048
+ }
44049
+ };
44050
+ }
44051
+ }
44052
+
43961
44053
  // src/commands/agent-bridge/harness/ui-message-part-tracker.ts
43962
44054
  var UiMessagePartTracker = class {
43963
44055
  messageId = null;
@@ -44298,6 +44390,7 @@ function providerMetadataField(providerMetadata) {
44298
44390
  var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
44299
44391
  var AGENT_BRIDGE_OUTPUT_UI_DELTA_MAX_CHARS = 32768;
44300
44392
  var AGENT_BRIDGE_OUTPUT_ACK_RETRY_BACKOFF_MS = [250, 1e3];
44393
+ var AGENT_BRIDGE_OUTPUT_QUARANTINE_AFTER_EXHAUSTS = 3;
44301
44394
  var AgentBridgeOutputBuffer = class {
44302
44395
  constructor(input) {
44303
44396
  this.input = input;
@@ -44314,6 +44407,9 @@ var AgentBridgeOutputBuffer = class {
44314
44407
  uiMessagePartTracker = new UiMessagePartTracker();
44315
44408
  drainBlocked = false;
44316
44409
  drainPromise = null;
44410
+ // Ack-retry-ladder exhausts per pending output sequence, for the poison
44411
+ // quarantine; entries clear when the sequence finally acks.
44412
+ ackExhaustsBySeq = /* @__PURE__ */ new Map();
44317
44413
  // ---------------------------------------------------------------------------
44318
44414
  // Public API
44319
44415
  // ---------------------------------------------------------------------------
@@ -44615,6 +44711,7 @@ var AgentBridgeOutputBuffer = class {
44615
44711
  for (let attempt = 0; ; attempt += 1) {
44616
44712
  try {
44617
44713
  await this.emitOnce(output);
44714
+ this.ackExhaustsBySeq.delete(output.outputSeq);
44618
44715
  return;
44619
44716
  } catch (error51) {
44620
44717
  if (!(error51 instanceof AgentBridgeOutputAckTimeoutError)) {
@@ -44630,6 +44727,7 @@ var AgentBridgeOutputBuffer = class {
44630
44727
  pending_count: this.pendingOutputs.size
44631
44728
  })
44632
44729
  );
44730
+ this.quarantineAfterRepeatedExhausts(output);
44633
44731
  this.input.cycleSocket?.();
44634
44732
  throw error51;
44635
44733
  }
@@ -44692,10 +44790,46 @@ var AgentBridgeOutputBuffer = class {
44692
44790
  await this.drainPendingOutputs();
44693
44791
  }
44694
44792
  enqueueOutput(output) {
44695
- this.pendingOutputs.set(output.outputSeq, output);
44793
+ const bounded = boundOutputEnvelope(output);
44794
+ if (bounded.truncated) {
44795
+ this.input.runtimeLogger?.warn(
44796
+ "agent_bridge_output_envelope_truncated",
44797
+ this.outputLogContext(bounded.envelope, {
44798
+ original_bytes: bounded.originalBytes,
44799
+ pending_count: this.pendingOutputs.size
44800
+ })
44801
+ );
44802
+ }
44803
+ this.pendingOutputs.set(bounded.envelope.outputSeq, bounded.envelope);
44696
44804
  this.input.runtimeLogger?.info(
44697
44805
  "agent_bridge_output_buffer_enqueued",
44698
- this.outputLogContext(output, {
44806
+ this.outputLogContext(bounded.envelope, {
44807
+ pending_count: this.pendingOutputs.size
44808
+ })
44809
+ );
44810
+ }
44811
+ // Shrinks a pending envelope to the quarantine size once it has exhausted
44812
+ // the ack-retry ladder AGENT_BRIDGE_OUTPUT_QUARANTINE_AFTER_EXHAUSTS times.
44813
+ // The shrunk envelope keeps its sequence and turn lifecycle fields, so the
44814
+ // drain resumes and the turn still settles; only bulky content is cut.
44815
+ quarantineAfterRepeatedExhausts(output) {
44816
+ const exhausts = (this.ackExhaustsBySeq.get(output.outputSeq) ?? 0) + 1;
44817
+ this.ackExhaustsBySeq.set(output.outputSeq, exhausts);
44818
+ if (exhausts < AGENT_BRIDGE_OUTPUT_QUARANTINE_AFTER_EXHAUSTS) {
44819
+ return;
44820
+ }
44821
+ const bounded = boundOutputEnvelope(
44822
+ output,
44823
+ AGENT_BRIDGE_OUTPUT_QUARANTINE_MAX_ENVELOPE_BYTES
44824
+ );
44825
+ this.pendingOutputs.set(bounded.envelope.outputSeq, bounded.envelope);
44826
+ this.ackExhaustsBySeq.delete(output.outputSeq);
44827
+ this.input.runtimeLogger?.error(
44828
+ "agent_bridge_output_envelope_quarantined",
44829
+ this.outputLogContext(bounded.envelope, {
44830
+ exhausts,
44831
+ original_bytes: bounded.originalBytes,
44832
+ truncated: bounded.truncated,
44699
44833
  pending_count: this.pendingOutputs.size
44700
44834
  })
44701
44835
  );
package/dist/index.js CHANGED
@@ -19308,6 +19308,9 @@ var init_sessions = __esm({
19308
19308
  runtimePhase: SessionRuntimePhaseSchema.nullable(),
19309
19309
  displayTitle: RunDisplayTitleSchema,
19310
19310
  summary: external_exports.string(),
19311
+ // Additive and optional so older live frames/list payloads that predate the
19312
+ // projection keep parsing; new projections include null when no reason exists.
19313
+ failureReason: external_exports.string().nullable().optional(),
19311
19314
  agent: SessionListItemAgentSchema,
19312
19315
  createdAt: external_exports.string().datetime(),
19313
19316
  updatedAt: external_exports.string().datetime(),
@@ -30435,7 +30438,7 @@ var init_package = __esm({
30435
30438
  "package.json"() {
30436
30439
  package_default = {
30437
30440
  name: "@autohq/cli",
30438
- version: "0.1.334",
30441
+ version: "0.1.336",
30439
30442
  license: "SEE LICENSE IN README.md",
30440
30443
  publishConfig: {
30441
30444
  access: "public"
@@ -41171,6 +41174,95 @@ import { setTimeout as sleep2 } from "timers/promises";
41171
41174
  init_src();
41172
41175
  import { readUIMessageStream } from "ai";
41173
41176
 
41177
+ // src/commands/agent-bridge/harness/envelope-bounds.ts
41178
+ import { Buffer as Buffer2 } from "buffer";
41179
+ var AGENT_BRIDGE_OUTPUT_MAX_ENVELOPE_BYTES = 512 * 1024;
41180
+ var AGENT_BRIDGE_OUTPUT_QUARANTINE_MAX_ENVELOPE_BYTES = 8 * 1024;
41181
+ var MIN_STRING_BUDGET_CHARS = 64;
41182
+ function boundOutputEnvelope(envelope, maxBytes = AGENT_BRIDGE_OUTPUT_MAX_ENVELOPE_BYTES) {
41183
+ const originalBytes = serializedByteLength(envelope);
41184
+ if (originalBytes <= maxBytes) {
41185
+ return { envelope, originalBytes, truncated: false };
41186
+ }
41187
+ for (let budget = initialStringBudget(maxBytes); budget >= MIN_STRING_BUDGET_CHARS; budget = Math.floor(budget / 8)) {
41188
+ const candidate = truncateLongStrings(envelope, budget);
41189
+ if (serializedByteLength(candidate) <= maxBytes) {
41190
+ return {
41191
+ envelope: RuntimeBridgeOutputEnvelopeSchema.parse(candidate),
41192
+ originalBytes,
41193
+ truncated: true
41194
+ };
41195
+ }
41196
+ }
41197
+ return {
41198
+ envelope: RuntimeBridgeOutputEnvelopeSchema.parse(
41199
+ replacePayloadWithMarker(envelope, originalBytes)
41200
+ ),
41201
+ originalBytes,
41202
+ truncated: true
41203
+ };
41204
+ }
41205
+ function serializedByteLength(value) {
41206
+ return Buffer2.byteLength(JSON.stringify(value), "utf8");
41207
+ }
41208
+ function initialStringBudget(maxBytes) {
41209
+ return Math.max(MIN_STRING_BUDGET_CHARS, Math.floor(maxBytes / 8));
41210
+ }
41211
+ function truncateLongStrings(value, budget) {
41212
+ if (typeof value === "string") {
41213
+ if (value.length <= budget) {
41214
+ return value;
41215
+ }
41216
+ return `${value.slice(0, budget)}${truncationMarker(value.length - budget)}`;
41217
+ }
41218
+ if (Array.isArray(value)) {
41219
+ return value.map((item) => truncateLongStrings(item, budget));
41220
+ }
41221
+ if (typeof value === "object" && value !== null) {
41222
+ return Object.fromEntries(
41223
+ Object.entries(value).map(([key, item]) => [
41224
+ key,
41225
+ truncateLongStrings(item, budget)
41226
+ ])
41227
+ );
41228
+ }
41229
+ return value;
41230
+ }
41231
+ function truncationMarker(droppedChars) {
41232
+ return `\u2026 [agent-bridge truncated ${droppedChars} chars: output exceeded the bridge envelope size limit]`;
41233
+ }
41234
+ function replacePayloadWithMarker(envelope, originalBytes) {
41235
+ const text = `[agent-bridge removed a ${originalBytes}-byte payload: it exceeded the bridge envelope size limit and could not be truncated]`;
41236
+ switch (envelope.type) {
41237
+ case "conversation.entry":
41238
+ return { ...envelope, content: { parts: [{ type: "text", text }] } };
41239
+ case "conversation.delta":
41240
+ return { ...envelope, delta: { type: "text", text } };
41241
+ case "ui.message.chunk":
41242
+ return {
41243
+ ...envelope,
41244
+ chunk: {
41245
+ type: "text-delta",
41246
+ id: "agent-bridge-truncation",
41247
+ delta: text
41248
+ }
41249
+ };
41250
+ case "ui.message.part": {
41251
+ const { messageMetadata: _dropped, ...rest } = envelope;
41252
+ return { ...rest, part: { type: "text", text, state: "done" } };
41253
+ }
41254
+ case "ui.message.completed":
41255
+ return {
41256
+ ...envelope,
41257
+ message: {
41258
+ id: envelope.messageId,
41259
+ role: envelope.role,
41260
+ parts: [{ type: "text", text, state: "done" }]
41261
+ }
41262
+ };
41263
+ }
41264
+ }
41265
+
41174
41266
  // src/commands/agent-bridge/harness/ui-message-part-tracker.ts
41175
41267
  init_src();
41176
41268
  var UiMessagePartTracker = class {
@@ -41512,6 +41604,7 @@ function providerMetadataField(providerMetadata) {
41512
41604
  var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
41513
41605
  var AGENT_BRIDGE_OUTPUT_UI_DELTA_MAX_CHARS = 32768;
41514
41606
  var AGENT_BRIDGE_OUTPUT_ACK_RETRY_BACKOFF_MS = [250, 1e3];
41607
+ var AGENT_BRIDGE_OUTPUT_QUARANTINE_AFTER_EXHAUSTS = 3;
41515
41608
  var AgentBridgeOutputBuffer = class {
41516
41609
  constructor(input) {
41517
41610
  this.input = input;
@@ -41528,6 +41621,9 @@ var AgentBridgeOutputBuffer = class {
41528
41621
  uiMessagePartTracker = new UiMessagePartTracker();
41529
41622
  drainBlocked = false;
41530
41623
  drainPromise = null;
41624
+ // Ack-retry-ladder exhausts per pending output sequence, for the poison
41625
+ // quarantine; entries clear when the sequence finally acks.
41626
+ ackExhaustsBySeq = /* @__PURE__ */ new Map();
41531
41627
  // ---------------------------------------------------------------------------
41532
41628
  // Public API
41533
41629
  // ---------------------------------------------------------------------------
@@ -41829,6 +41925,7 @@ var AgentBridgeOutputBuffer = class {
41829
41925
  for (let attempt = 0; ; attempt += 1) {
41830
41926
  try {
41831
41927
  await this.emitOnce(output);
41928
+ this.ackExhaustsBySeq.delete(output.outputSeq);
41832
41929
  return;
41833
41930
  } catch (error51) {
41834
41931
  if (!(error51 instanceof AgentBridgeOutputAckTimeoutError)) {
@@ -41844,6 +41941,7 @@ var AgentBridgeOutputBuffer = class {
41844
41941
  pending_count: this.pendingOutputs.size
41845
41942
  })
41846
41943
  );
41944
+ this.quarantineAfterRepeatedExhausts(output);
41847
41945
  this.input.cycleSocket?.();
41848
41946
  throw error51;
41849
41947
  }
@@ -41906,10 +42004,46 @@ var AgentBridgeOutputBuffer = class {
41906
42004
  await this.drainPendingOutputs();
41907
42005
  }
41908
42006
  enqueueOutput(output) {
41909
- this.pendingOutputs.set(output.outputSeq, output);
42007
+ const bounded = boundOutputEnvelope(output);
42008
+ if (bounded.truncated) {
42009
+ this.input.runtimeLogger?.warn(
42010
+ "agent_bridge_output_envelope_truncated",
42011
+ this.outputLogContext(bounded.envelope, {
42012
+ original_bytes: bounded.originalBytes,
42013
+ pending_count: this.pendingOutputs.size
42014
+ })
42015
+ );
42016
+ }
42017
+ this.pendingOutputs.set(bounded.envelope.outputSeq, bounded.envelope);
41910
42018
  this.input.runtimeLogger?.info(
41911
42019
  "agent_bridge_output_buffer_enqueued",
41912
- this.outputLogContext(output, {
42020
+ this.outputLogContext(bounded.envelope, {
42021
+ pending_count: this.pendingOutputs.size
42022
+ })
42023
+ );
42024
+ }
42025
+ // Shrinks a pending envelope to the quarantine size once it has exhausted
42026
+ // the ack-retry ladder AGENT_BRIDGE_OUTPUT_QUARANTINE_AFTER_EXHAUSTS times.
42027
+ // The shrunk envelope keeps its sequence and turn lifecycle fields, so the
42028
+ // drain resumes and the turn still settles; only bulky content is cut.
42029
+ quarantineAfterRepeatedExhausts(output) {
42030
+ const exhausts = (this.ackExhaustsBySeq.get(output.outputSeq) ?? 0) + 1;
42031
+ this.ackExhaustsBySeq.set(output.outputSeq, exhausts);
42032
+ if (exhausts < AGENT_BRIDGE_OUTPUT_QUARANTINE_AFTER_EXHAUSTS) {
42033
+ return;
42034
+ }
42035
+ const bounded = boundOutputEnvelope(
42036
+ output,
42037
+ AGENT_BRIDGE_OUTPUT_QUARANTINE_MAX_ENVELOPE_BYTES
42038
+ );
42039
+ this.pendingOutputs.set(bounded.envelope.outputSeq, bounded.envelope);
42040
+ this.ackExhaustsBySeq.delete(output.outputSeq);
42041
+ this.input.runtimeLogger?.error(
42042
+ "agent_bridge_output_envelope_quarantined",
42043
+ this.outputLogContext(bounded.envelope, {
42044
+ exhausts,
42045
+ original_bytes: bounded.originalBytes,
42046
+ truncated: bounded.truncated,
41913
42047
  pending_count: this.pendingOutputs.size
41914
42048
  })
41915
42049
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.334",
3
+ "version": "0.1.336",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"