@autohq/cli 0.1.610 → 0.1.611

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.
@@ -37751,7 +37751,7 @@ Object.assign(lookup, {
37751
37751
  // package.json
37752
37752
  var package_default = {
37753
37753
  name: "@autohq/cli",
37754
- version: "0.1.610",
37754
+ version: "0.1.611",
37755
37755
  license: "SEE LICENSE IN README.md",
37756
37756
  publishConfig: {
37757
37757
  access: "public"
@@ -83353,9 +83353,170 @@ var defaultDownload2 = createDownload();
83353
83353
 
83354
83354
  // src/commands/agent-bridge/harness/envelope-bounds.ts
83355
83355
  import { Buffer as Buffer2 } from "buffer";
83356
+
83357
+ // src/commands/agent-bridge/harness/mcp-result-canonicalization.ts
83358
+ function canonicalizeEnvelopeMcpResults(envelope) {
83359
+ switch (envelope.type) {
83360
+ case "conversation.entry": {
83361
+ const content = canonicalizeMcpResultValue(envelope.content);
83362
+ return toCanonicalizedEnvelope(
83363
+ envelope,
83364
+ { ...envelope, content: content.value },
83365
+ content.deduplicatedBranches
83366
+ );
83367
+ }
83368
+ case "conversation.delta": {
83369
+ const delta = canonicalizeMcpResultValue(envelope.delta);
83370
+ return toCanonicalizedEnvelope(
83371
+ envelope,
83372
+ { ...envelope, delta: delta.value },
83373
+ delta.deduplicatedBranches
83374
+ );
83375
+ }
83376
+ case "ui.message.chunk": {
83377
+ const chunk = canonicalizeMcpResultValue(envelope.chunk);
83378
+ return toCanonicalizedEnvelope(
83379
+ envelope,
83380
+ { ...envelope, chunk: chunk.value },
83381
+ chunk.deduplicatedBranches
83382
+ );
83383
+ }
83384
+ case "ui.message.part": {
83385
+ const part = canonicalizeMcpResultValue(envelope.part);
83386
+ const metadata = canonicalizeMcpResultValue(envelope.messageMetadata);
83387
+ const deduplicatedBranches = part.deduplicatedBranches + metadata.deduplicatedBranches;
83388
+ return toCanonicalizedEnvelope(
83389
+ envelope,
83390
+ {
83391
+ ...envelope,
83392
+ part: part.value,
83393
+ ...envelope.messageMetadata === void 0 ? {} : { messageMetadata: metadata.value }
83394
+ },
83395
+ deduplicatedBranches
83396
+ );
83397
+ }
83398
+ case "ui.message.completed": {
83399
+ const message = canonicalizeMcpResultValue(envelope.message);
83400
+ return toCanonicalizedEnvelope(
83401
+ envelope,
83402
+ { ...envelope, message: message.value },
83403
+ message.deduplicatedBranches
83404
+ );
83405
+ }
83406
+ case "runtime.liveness":
83407
+ case "runtime.usage_turn":
83408
+ return { value: envelope, deduplicatedBranches: 0 };
83409
+ }
83410
+ }
83411
+ function toCanonicalizedEnvelope(original, candidate, deduplicatedBranches) {
83412
+ return {
83413
+ value: deduplicatedBranches > 0 ? RuntimeBridgeOutputEnvelopeSchema.parse(candidate) : original,
83414
+ deduplicatedBranches
83415
+ };
83416
+ }
83417
+ function canonicalizeMcpResultValue(value2) {
83418
+ if (Array.isArray(value2)) {
83419
+ let deduplicatedBranches2 = 0;
83420
+ let changed2 = false;
83421
+ const items = value2.map((item) => {
83422
+ const canonical2 = canonicalizeMcpResultValue(item);
83423
+ deduplicatedBranches2 += canonical2.deduplicatedBranches;
83424
+ changed2 ||= canonical2.value !== item;
83425
+ return canonical2.value;
83426
+ });
83427
+ return {
83428
+ value: changed2 ? items : value2,
83429
+ deduplicatedBranches: deduplicatedBranches2
83430
+ };
83431
+ }
83432
+ if (typeof value2 !== "object" || value2 === null) {
83433
+ return { value: value2, deduplicatedBranches: 0 };
83434
+ }
83435
+ const record2 = value2;
83436
+ const duplicateContentIndexes = equivalentMcpTextContentIndexes(record2);
83437
+ let deduplicatedBranches = duplicateContentIndexes.size;
83438
+ let changed = duplicateContentIndexes.size > 0;
83439
+ const canonical = /* @__PURE__ */ Object.create(null);
83440
+ for (const [key, item] of Object.entries(record2)) {
83441
+ if (key === "content" && Array.isArray(item)) {
83442
+ const retainedContent = duplicateContentIndexes.size > 0 ? item.filter(
83443
+ (_contentItem, index) => !duplicateContentIndexes.has(index)
83444
+ ) : item;
83445
+ if (retainedContent.length === 0 && duplicateContentIndexes.size > 0) {
83446
+ continue;
83447
+ }
83448
+ const content = canonicalizeMcpResultValue(retainedContent);
83449
+ canonical[key] = content.value;
83450
+ deduplicatedBranches += content.deduplicatedBranches;
83451
+ changed ||= content.value !== item;
83452
+ continue;
83453
+ }
83454
+ const child = canonicalizeMcpResultValue(item);
83455
+ canonical[key] = child.value;
83456
+ deduplicatedBranches += child.deduplicatedBranches;
83457
+ changed ||= child.value !== item;
83458
+ }
83459
+ return {
83460
+ value: changed ? canonical : value2,
83461
+ deduplicatedBranches
83462
+ };
83463
+ }
83464
+ function equivalentMcpTextContentIndexes(value2) {
83465
+ if (!Array.isArray(value2.content) || !Object.hasOwn(value2, "structuredContent") || value2.structuredContent === void 0) {
83466
+ return /* @__PURE__ */ new Set();
83467
+ }
83468
+ const indexes = /* @__PURE__ */ new Set();
83469
+ for (const [index, item] of value2.content.entries()) {
83470
+ if (!isPlainMcpTextBlock(item)) {
83471
+ continue;
83472
+ }
83473
+ const parsed = parseJson(item.text);
83474
+ if (parsed.parsed && jsonValuesEqual(parsed.value, value2.structuredContent)) {
83475
+ indexes.add(index);
83476
+ }
83477
+ }
83478
+ return indexes;
83479
+ }
83480
+ function isPlainMcpTextBlock(value2) {
83481
+ if (typeof value2 !== "object" || value2 === null || Array.isArray(value2)) {
83482
+ return false;
83483
+ }
83484
+ const record2 = value2;
83485
+ const keys = Object.keys(record2);
83486
+ return keys.length === 2 && record2.type === "text" && typeof record2.text === "string";
83487
+ }
83488
+ function parseJson(value2) {
83489
+ try {
83490
+ return { parsed: true, value: JSON.parse(value2) };
83491
+ } catch {
83492
+ return { parsed: false, value: null };
83493
+ }
83494
+ }
83495
+ function jsonValuesEqual(left, right) {
83496
+ if (Object.is(left, right)) {
83497
+ return true;
83498
+ }
83499
+ if (Array.isArray(left) || Array.isArray(right)) {
83500
+ if (!Array.isArray(left) || !Array.isArray(right)) {
83501
+ return false;
83502
+ }
83503
+ return left.length === right.length && left.every((item, index) => jsonValuesEqual(item, right[index]));
83504
+ }
83505
+ if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) {
83506
+ return false;
83507
+ }
83508
+ const leftRecord = left;
83509
+ const rightRecord = right;
83510
+ const leftKeys = Object.keys(leftRecord);
83511
+ const rightKeys = Object.keys(rightRecord);
83512
+ return leftKeys.length === rightKeys.length && leftKeys.every(
83513
+ (key) => Object.hasOwn(rightRecord, key) && jsonValuesEqual(leftRecord[key], rightRecord[key])
83514
+ );
83515
+ }
83516
+
83517
+ // src/commands/agent-bridge/harness/envelope-bounds.ts
83356
83518
  var AGENT_BRIDGE_OUTPUT_MAX_ENVELOPE_BYTES = 512 * 1024;
83357
83519
  var AGENT_BRIDGE_OUTPUT_QUARANTINE_MAX_ENVELOPE_BYTES = 8 * 1024;
83358
- var MAX_TARGETED_PAYLOAD_NOTICES = 4;
83359
83520
  var PAYLOAD_FIELD_RULES = {
83360
83521
  output: { label: "tool output", priority: 0 },
83361
83522
  errorText: { label: "tool error", priority: 0 },
@@ -83390,48 +83551,97 @@ var STRUCTURAL_STRING_FIELDS = /* @__PURE__ */ new Set([
83390
83551
  "completedAt"
83391
83552
  ]);
83392
83553
  function boundOutputEnvelope(envelope, maxBytes = AGENT_BRIDGE_OUTPUT_MAX_ENVELOPE_BYTES) {
83393
- const originalBytes = serializedByteLength(envelope);
83554
+ const original = envelopeSerializationInfo(envelope);
83555
+ const originalBytes = original.bytes;
83394
83556
  if (originalBytes <= maxBytes) {
83395
- return { envelope, originalBytes, truncated: false };
83557
+ return {
83558
+ envelope,
83559
+ originalBytes,
83560
+ boundedBytes: originalBytes,
83561
+ kind: "none",
83562
+ deduplicatedMcpResultBranches: 0,
83563
+ truncated: false
83564
+ };
83565
+ }
83566
+ const canonicalized = original.hasStructuredContent ? canonicalizeEnvelopeMcpResults(envelope) : { value: envelope, deduplicatedBranches: 0 };
83567
+ const canonicalEnvelope = canonicalized.value;
83568
+ const canonicalBytes = serializedByteLength(canonicalEnvelope);
83569
+ if (canonicalBytes <= maxBytes) {
83570
+ return {
83571
+ envelope: canonicalEnvelope,
83572
+ originalBytes,
83573
+ boundedBytes: canonicalBytes,
83574
+ kind: "mcp-result-deduplicated",
83575
+ deduplicatedMcpResultBranches: canonicalized.deduplicatedBranches,
83576
+ truncated: true
83577
+ };
83396
83578
  }
83397
- const targeted = truncatePayloads(envelope, maxBytes);
83579
+ const targeted = truncatePayloads(canonicalEnvelope, maxBytes);
83398
83580
  if (targeted) {
83581
+ const boundedEnvelope = RuntimeBridgeOutputEnvelopeSchema.parse(targeted);
83399
83582
  return {
83400
- envelope: RuntimeBridgeOutputEnvelopeSchema.parse(targeted),
83583
+ envelope: boundedEnvelope,
83401
83584
  originalBytes,
83585
+ boundedBytes: serializedByteLength(boundedEnvelope),
83586
+ kind: canonicalized.deduplicatedBranches > 0 ? "mcp-result-deduplicated+targeted-truncation" : "targeted-truncation",
83587
+ deduplicatedMcpResultBranches: canonicalized.deduplicatedBranches,
83402
83588
  truncated: true
83403
83589
  };
83404
83590
  }
83591
+ const fallbackEnvelope = RuntimeBridgeOutputEnvelopeSchema.parse(
83592
+ replacePayloadWithMarker(canonicalEnvelope)
83593
+ );
83405
83594
  return {
83406
- envelope: RuntimeBridgeOutputEnvelopeSchema.parse(
83407
- replacePayloadWithMarker(envelope)
83408
- ),
83595
+ envelope: fallbackEnvelope,
83409
83596
  originalBytes,
83597
+ boundedBytes: serializedByteLength(fallbackEnvelope),
83598
+ kind: canonicalized.deduplicatedBranches > 0 ? "mcp-result-deduplicated+payload-fallback" : "payload-fallback",
83599
+ deduplicatedMcpResultBranches: canonicalized.deduplicatedBranches,
83410
83600
  truncated: true
83411
83601
  };
83412
83602
  }
83413
83603
  function truncatePayloads(envelope, maxBytes) {
83414
83604
  const candidateEnvelope = structuredClone(envelope);
83415
83605
  const candidates = collectPayloadCandidates(envelope);
83416
- for (let noticeCount = 0; noticeCount < MAX_TARGETED_PAYLOAD_NOTICES; noticeCount += 1) {
83606
+ const truncatedCandidates = [];
83607
+ while (true) {
83417
83608
  const currentBytes = serializedByteLength(candidateEnvelope);
83418
83609
  if (currentBytes <= maxBytes) {
83419
83610
  return candidateEnvelope;
83420
83611
  }
83421
83612
  const candidate = takePayloadCandidate(candidates, currentBytes - maxBytes);
83422
83613
  if (!candidate) {
83423
- return null;
83614
+ break;
83424
83615
  }
83425
83616
  setValueAtPath(
83426
83617
  candidateEnvelope,
83427
83618
  candidate.path,
83428
83619
  truncationNotice(candidate, "")
83429
83620
  );
83430
- if (serializedByteLength(candidateEnvelope) <= maxBytes) {
83621
+ const truncatedBytes = serializedByteLength(candidateEnvelope);
83622
+ if (truncatedBytes >= currentBytes) {
83623
+ setValueAtPath(candidateEnvelope, candidate.path, candidate.value);
83624
+ continue;
83625
+ }
83626
+ truncatedCandidates.push(candidate);
83627
+ if (truncatedBytes <= maxBytes) {
83431
83628
  maximizePreview(candidateEnvelope, candidate, maxBytes);
83432
83629
  return candidateEnvelope;
83433
83630
  }
83434
83631
  }
83632
+ for (const candidate of truncatedCandidates) {
83633
+ setValueAtPath(
83634
+ candidateEnvelope,
83635
+ candidate.path,
83636
+ compactTruncationNotice(candidate)
83637
+ );
83638
+ }
83639
+ if (serializedByteLength(candidateEnvelope) <= maxBytes) {
83640
+ return candidateEnvelope;
83641
+ }
83642
+ for (const candidate of truncatedCandidates) {
83643
+ setValueAtPath(candidateEnvelope, candidate.path, "");
83644
+ }
83435
83645
  return serializedByteLength(candidateEnvelope) <= maxBytes ? candidateEnvelope : null;
83436
83646
  }
83437
83647
  function collectPayloadCandidates(envelope) {
@@ -83596,10 +83806,20 @@ function truncationNotice(candidate, preview) {
83596
83806
  const separator = preview.length > 0 ? "\n" : "";
83597
83807
  return `${preview}${separator}[agent-bridge ${candidate.label} truncated: original ${candidate.originalBytes} UTF-8 bytes; kept ${keptBytes}; omitted ${omittedBytes}. Omitted content was not persisted in this transcript.]`;
83598
83808
  }
83809
+ function compactTruncationNotice(candidate) {
83810
+ return `[agent-bridge ${candidate.label} truncated: original ${candidate.originalBytes} UTF-8 bytes.]`;
83811
+ }
83599
83812
  function serializedByteLength(value2) {
83600
83813
  const serialized = JSON.stringify(value2);
83601
83814
  return serialized === void 0 ? 0 : Buffer2.byteLength(serialized, "utf8");
83602
83815
  }
83816
+ function envelopeSerializationInfo(envelope) {
83817
+ const serialized = JSON.stringify(envelope);
83818
+ return {
83819
+ bytes: Buffer2.byteLength(serialized, "utf8"),
83820
+ hasStructuredContent: serialized.includes('"structuredContent":')
83821
+ };
83822
+ }
83603
83823
  function replacePayloadWithMarker(envelope) {
83604
83824
  switch (envelope.type) {
83605
83825
  case "conversation.entry": {
@@ -84560,6 +84780,9 @@ var AgentBridgeOutputBuffer = class {
84560
84780
  "agent_bridge_output_envelope_truncated",
84561
84781
  this.outputLogContext(bounded.envelope, {
84562
84782
  original_bytes: bounded.originalBytes,
84783
+ bounded_bytes: bounded.boundedBytes,
84784
+ bound_kind: bounded.kind,
84785
+ deduplicated_mcp_result_branches: bounded.deduplicatedMcpResultBranches,
84563
84786
  pending_count: this.pendingOutputs.size
84564
84787
  })
84565
84788
  );
@@ -84593,6 +84816,9 @@ var AgentBridgeOutputBuffer = class {
84593
84816
  this.outputLogContext(bounded.envelope, {
84594
84817
  exhausts,
84595
84818
  original_bytes: bounded.originalBytes,
84819
+ bounded_bytes: bounded.boundedBytes,
84820
+ bound_kind: bounded.kind,
84821
+ deduplicated_mcp_result_branches: bounded.deduplicatedMcpResultBranches,
84596
84822
  truncated: bounded.truncated,
84597
84823
  pending_count: this.pendingOutputs.size
84598
84824
  })
package/dist/index.js CHANGED
@@ -93169,7 +93169,7 @@ var init_package = __esm({
93169
93169
  "package.json"() {
93170
93170
  package_default = {
93171
93171
  name: "@autohq/cli",
93172
- version: "0.1.610",
93172
+ version: "0.1.611",
93173
93173
  license: "SEE LICENSE IN README.md",
93174
93174
  publishConfig: {
93175
93175
  access: "public"
@@ -106602,9 +106602,170 @@ import { readUIMessageStream } from "ai";
106602
106602
 
106603
106603
  // src/commands/agent-bridge/harness/envelope-bounds.ts
106604
106604
  import { Buffer as Buffer2 } from "buffer";
106605
+
106606
+ // src/commands/agent-bridge/harness/mcp-result-canonicalization.ts
106607
+ function canonicalizeEnvelopeMcpResults(envelope) {
106608
+ switch (envelope.type) {
106609
+ case "conversation.entry": {
106610
+ const content = canonicalizeMcpResultValue(envelope.content);
106611
+ return toCanonicalizedEnvelope(
106612
+ envelope,
106613
+ { ...envelope, content: content.value },
106614
+ content.deduplicatedBranches
106615
+ );
106616
+ }
106617
+ case "conversation.delta": {
106618
+ const delta = canonicalizeMcpResultValue(envelope.delta);
106619
+ return toCanonicalizedEnvelope(
106620
+ envelope,
106621
+ { ...envelope, delta: delta.value },
106622
+ delta.deduplicatedBranches
106623
+ );
106624
+ }
106625
+ case "ui.message.chunk": {
106626
+ const chunk = canonicalizeMcpResultValue(envelope.chunk);
106627
+ return toCanonicalizedEnvelope(
106628
+ envelope,
106629
+ { ...envelope, chunk: chunk.value },
106630
+ chunk.deduplicatedBranches
106631
+ );
106632
+ }
106633
+ case "ui.message.part": {
106634
+ const part = canonicalizeMcpResultValue(envelope.part);
106635
+ const metadata = canonicalizeMcpResultValue(envelope.messageMetadata);
106636
+ const deduplicatedBranches = part.deduplicatedBranches + metadata.deduplicatedBranches;
106637
+ return toCanonicalizedEnvelope(
106638
+ envelope,
106639
+ {
106640
+ ...envelope,
106641
+ part: part.value,
106642
+ ...envelope.messageMetadata === void 0 ? {} : { messageMetadata: metadata.value }
106643
+ },
106644
+ deduplicatedBranches
106645
+ );
106646
+ }
106647
+ case "ui.message.completed": {
106648
+ const message = canonicalizeMcpResultValue(envelope.message);
106649
+ return toCanonicalizedEnvelope(
106650
+ envelope,
106651
+ { ...envelope, message: message.value },
106652
+ message.deduplicatedBranches
106653
+ );
106654
+ }
106655
+ case "runtime.liveness":
106656
+ case "runtime.usage_turn":
106657
+ return { value: envelope, deduplicatedBranches: 0 };
106658
+ }
106659
+ }
106660
+ function toCanonicalizedEnvelope(original, candidate, deduplicatedBranches) {
106661
+ return {
106662
+ value: deduplicatedBranches > 0 ? RuntimeBridgeOutputEnvelopeSchema.parse(candidate) : original,
106663
+ deduplicatedBranches
106664
+ };
106665
+ }
106666
+ function canonicalizeMcpResultValue(value) {
106667
+ if (Array.isArray(value)) {
106668
+ let deduplicatedBranches2 = 0;
106669
+ let changed2 = false;
106670
+ const items = value.map((item) => {
106671
+ const canonical2 = canonicalizeMcpResultValue(item);
106672
+ deduplicatedBranches2 += canonical2.deduplicatedBranches;
106673
+ changed2 ||= canonical2.value !== item;
106674
+ return canonical2.value;
106675
+ });
106676
+ return {
106677
+ value: changed2 ? items : value,
106678
+ deduplicatedBranches: deduplicatedBranches2
106679
+ };
106680
+ }
106681
+ if (typeof value !== "object" || value === null) {
106682
+ return { value, deduplicatedBranches: 0 };
106683
+ }
106684
+ const record2 = value;
106685
+ const duplicateContentIndexes = equivalentMcpTextContentIndexes(record2);
106686
+ let deduplicatedBranches = duplicateContentIndexes.size;
106687
+ let changed = duplicateContentIndexes.size > 0;
106688
+ const canonical = /* @__PURE__ */ Object.create(null);
106689
+ for (const [key, item] of Object.entries(record2)) {
106690
+ if (key === "content" && Array.isArray(item)) {
106691
+ const retainedContent = duplicateContentIndexes.size > 0 ? item.filter(
106692
+ (_contentItem, index) => !duplicateContentIndexes.has(index)
106693
+ ) : item;
106694
+ if (retainedContent.length === 0 && duplicateContentIndexes.size > 0) {
106695
+ continue;
106696
+ }
106697
+ const content = canonicalizeMcpResultValue(retainedContent);
106698
+ canonical[key] = content.value;
106699
+ deduplicatedBranches += content.deduplicatedBranches;
106700
+ changed ||= content.value !== item;
106701
+ continue;
106702
+ }
106703
+ const child = canonicalizeMcpResultValue(item);
106704
+ canonical[key] = child.value;
106705
+ deduplicatedBranches += child.deduplicatedBranches;
106706
+ changed ||= child.value !== item;
106707
+ }
106708
+ return {
106709
+ value: changed ? canonical : value,
106710
+ deduplicatedBranches
106711
+ };
106712
+ }
106713
+ function equivalentMcpTextContentIndexes(value) {
106714
+ if (!Array.isArray(value.content) || !Object.hasOwn(value, "structuredContent") || value.structuredContent === void 0) {
106715
+ return /* @__PURE__ */ new Set();
106716
+ }
106717
+ const indexes = /* @__PURE__ */ new Set();
106718
+ for (const [index, item] of value.content.entries()) {
106719
+ if (!isPlainMcpTextBlock(item)) {
106720
+ continue;
106721
+ }
106722
+ const parsed = parseJson(item.text);
106723
+ if (parsed.parsed && jsonValuesEqual(parsed.value, value.structuredContent)) {
106724
+ indexes.add(index);
106725
+ }
106726
+ }
106727
+ return indexes;
106728
+ }
106729
+ function isPlainMcpTextBlock(value) {
106730
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
106731
+ return false;
106732
+ }
106733
+ const record2 = value;
106734
+ const keys = Object.keys(record2);
106735
+ return keys.length === 2 && record2.type === "text" && typeof record2.text === "string";
106736
+ }
106737
+ function parseJson(value) {
106738
+ try {
106739
+ return { parsed: true, value: JSON.parse(value) };
106740
+ } catch {
106741
+ return { parsed: false, value: null };
106742
+ }
106743
+ }
106744
+ function jsonValuesEqual(left, right) {
106745
+ if (Object.is(left, right)) {
106746
+ return true;
106747
+ }
106748
+ if (Array.isArray(left) || Array.isArray(right)) {
106749
+ if (!Array.isArray(left) || !Array.isArray(right)) {
106750
+ return false;
106751
+ }
106752
+ return left.length === right.length && left.every((item, index) => jsonValuesEqual(item, right[index]));
106753
+ }
106754
+ if (typeof left !== "object" || left === null || typeof right !== "object" || right === null) {
106755
+ return false;
106756
+ }
106757
+ const leftRecord = left;
106758
+ const rightRecord = right;
106759
+ const leftKeys = Object.keys(leftRecord);
106760
+ const rightKeys = Object.keys(rightRecord);
106761
+ return leftKeys.length === rightKeys.length && leftKeys.every(
106762
+ (key) => Object.hasOwn(rightRecord, key) && jsonValuesEqual(leftRecord[key], rightRecord[key])
106763
+ );
106764
+ }
106765
+
106766
+ // src/commands/agent-bridge/harness/envelope-bounds.ts
106605
106767
  var AGENT_BRIDGE_OUTPUT_MAX_ENVELOPE_BYTES = 512 * 1024;
106606
106768
  var AGENT_BRIDGE_OUTPUT_QUARANTINE_MAX_ENVELOPE_BYTES = 8 * 1024;
106607
- var MAX_TARGETED_PAYLOAD_NOTICES = 4;
106608
106769
  var PAYLOAD_FIELD_RULES = {
106609
106770
  output: { label: "tool output", priority: 0 },
106610
106771
  errorText: { label: "tool error", priority: 0 },
@@ -106639,48 +106800,97 @@ var STRUCTURAL_STRING_FIELDS = /* @__PURE__ */ new Set([
106639
106800
  "completedAt"
106640
106801
  ]);
106641
106802
  function boundOutputEnvelope(envelope, maxBytes = AGENT_BRIDGE_OUTPUT_MAX_ENVELOPE_BYTES) {
106642
- const originalBytes = serializedByteLength(envelope);
106803
+ const original = envelopeSerializationInfo(envelope);
106804
+ const originalBytes = original.bytes;
106643
106805
  if (originalBytes <= maxBytes) {
106644
- return { envelope, originalBytes, truncated: false };
106806
+ return {
106807
+ envelope,
106808
+ originalBytes,
106809
+ boundedBytes: originalBytes,
106810
+ kind: "none",
106811
+ deduplicatedMcpResultBranches: 0,
106812
+ truncated: false
106813
+ };
106814
+ }
106815
+ const canonicalized = original.hasStructuredContent ? canonicalizeEnvelopeMcpResults(envelope) : { value: envelope, deduplicatedBranches: 0 };
106816
+ const canonicalEnvelope = canonicalized.value;
106817
+ const canonicalBytes = serializedByteLength(canonicalEnvelope);
106818
+ if (canonicalBytes <= maxBytes) {
106819
+ return {
106820
+ envelope: canonicalEnvelope,
106821
+ originalBytes,
106822
+ boundedBytes: canonicalBytes,
106823
+ kind: "mcp-result-deduplicated",
106824
+ deduplicatedMcpResultBranches: canonicalized.deduplicatedBranches,
106825
+ truncated: true
106826
+ };
106645
106827
  }
106646
- const targeted = truncatePayloads(envelope, maxBytes);
106828
+ const targeted = truncatePayloads(canonicalEnvelope, maxBytes);
106647
106829
  if (targeted) {
106830
+ const boundedEnvelope = RuntimeBridgeOutputEnvelopeSchema.parse(targeted);
106648
106831
  return {
106649
- envelope: RuntimeBridgeOutputEnvelopeSchema.parse(targeted),
106832
+ envelope: boundedEnvelope,
106650
106833
  originalBytes,
106834
+ boundedBytes: serializedByteLength(boundedEnvelope),
106835
+ kind: canonicalized.deduplicatedBranches > 0 ? "mcp-result-deduplicated+targeted-truncation" : "targeted-truncation",
106836
+ deduplicatedMcpResultBranches: canonicalized.deduplicatedBranches,
106651
106837
  truncated: true
106652
106838
  };
106653
106839
  }
106840
+ const fallbackEnvelope = RuntimeBridgeOutputEnvelopeSchema.parse(
106841
+ replacePayloadWithMarker(canonicalEnvelope)
106842
+ );
106654
106843
  return {
106655
- envelope: RuntimeBridgeOutputEnvelopeSchema.parse(
106656
- replacePayloadWithMarker(envelope)
106657
- ),
106844
+ envelope: fallbackEnvelope,
106658
106845
  originalBytes,
106846
+ boundedBytes: serializedByteLength(fallbackEnvelope),
106847
+ kind: canonicalized.deduplicatedBranches > 0 ? "mcp-result-deduplicated+payload-fallback" : "payload-fallback",
106848
+ deduplicatedMcpResultBranches: canonicalized.deduplicatedBranches,
106659
106849
  truncated: true
106660
106850
  };
106661
106851
  }
106662
106852
  function truncatePayloads(envelope, maxBytes) {
106663
106853
  const candidateEnvelope = structuredClone(envelope);
106664
106854
  const candidates = collectPayloadCandidates(envelope);
106665
- for (let noticeCount = 0; noticeCount < MAX_TARGETED_PAYLOAD_NOTICES; noticeCount += 1) {
106855
+ const truncatedCandidates = [];
106856
+ while (true) {
106666
106857
  const currentBytes = serializedByteLength(candidateEnvelope);
106667
106858
  if (currentBytes <= maxBytes) {
106668
106859
  return candidateEnvelope;
106669
106860
  }
106670
106861
  const candidate = takePayloadCandidate(candidates, currentBytes - maxBytes);
106671
106862
  if (!candidate) {
106672
- return null;
106863
+ break;
106673
106864
  }
106674
106865
  setValueAtPath(
106675
106866
  candidateEnvelope,
106676
106867
  candidate.path,
106677
106868
  truncationNotice(candidate, "")
106678
106869
  );
106679
- if (serializedByteLength(candidateEnvelope) <= maxBytes) {
106870
+ const truncatedBytes = serializedByteLength(candidateEnvelope);
106871
+ if (truncatedBytes >= currentBytes) {
106872
+ setValueAtPath(candidateEnvelope, candidate.path, candidate.value);
106873
+ continue;
106874
+ }
106875
+ truncatedCandidates.push(candidate);
106876
+ if (truncatedBytes <= maxBytes) {
106680
106877
  maximizePreview(candidateEnvelope, candidate, maxBytes);
106681
106878
  return candidateEnvelope;
106682
106879
  }
106683
106880
  }
106881
+ for (const candidate of truncatedCandidates) {
106882
+ setValueAtPath(
106883
+ candidateEnvelope,
106884
+ candidate.path,
106885
+ compactTruncationNotice(candidate)
106886
+ );
106887
+ }
106888
+ if (serializedByteLength(candidateEnvelope) <= maxBytes) {
106889
+ return candidateEnvelope;
106890
+ }
106891
+ for (const candidate of truncatedCandidates) {
106892
+ setValueAtPath(candidateEnvelope, candidate.path, "");
106893
+ }
106684
106894
  return serializedByteLength(candidateEnvelope) <= maxBytes ? candidateEnvelope : null;
106685
106895
  }
106686
106896
  function collectPayloadCandidates(envelope) {
@@ -106845,10 +107055,20 @@ function truncationNotice(candidate, preview2) {
106845
107055
  const separator = preview2.length > 0 ? "\n" : "";
106846
107056
  return `${preview2}${separator}[agent-bridge ${candidate.label} truncated: original ${candidate.originalBytes} UTF-8 bytes; kept ${keptBytes}; omitted ${omittedBytes}. Omitted content was not persisted in this transcript.]`;
106847
107057
  }
107058
+ function compactTruncationNotice(candidate) {
107059
+ return `[agent-bridge ${candidate.label} truncated: original ${candidate.originalBytes} UTF-8 bytes.]`;
107060
+ }
106848
107061
  function serializedByteLength(value) {
106849
107062
  const serialized = JSON.stringify(value);
106850
107063
  return serialized === void 0 ? 0 : Buffer2.byteLength(serialized, "utf8");
106851
107064
  }
107065
+ function envelopeSerializationInfo(envelope) {
107066
+ const serialized = JSON.stringify(envelope);
107067
+ return {
107068
+ bytes: Buffer2.byteLength(serialized, "utf8"),
107069
+ hasStructuredContent: serialized.includes('"structuredContent":')
107070
+ };
107071
+ }
106852
107072
  function replacePayloadWithMarker(envelope) {
106853
107073
  switch (envelope.type) {
106854
107074
  case "conversation.entry": {
@@ -107810,6 +108030,9 @@ var AgentBridgeOutputBuffer = class {
107810
108030
  "agent_bridge_output_envelope_truncated",
107811
108031
  this.outputLogContext(bounded.envelope, {
107812
108032
  original_bytes: bounded.originalBytes,
108033
+ bounded_bytes: bounded.boundedBytes,
108034
+ bound_kind: bounded.kind,
108035
+ deduplicated_mcp_result_branches: bounded.deduplicatedMcpResultBranches,
107813
108036
  pending_count: this.pendingOutputs.size
107814
108037
  })
107815
108038
  );
@@ -107843,6 +108066,9 @@ var AgentBridgeOutputBuffer = class {
107843
108066
  this.outputLogContext(bounded.envelope, {
107844
108067
  exhausts,
107845
108068
  original_bytes: bounded.originalBytes,
108069
+ bounded_bytes: bounded.boundedBytes,
108070
+ bound_kind: bounded.kind,
108071
+ deduplicated_mcp_result_branches: bounded.deduplicatedMcpResultBranches,
107846
108072
  truncated: bounded.truncated,
107847
108073
  pending_count: this.pendingOutputs.size
107848
108074
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.610",
3
+ "version": "0.1.611",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"