@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.
- package/dist/agent-bridge.js +238 -12
- package/dist/index.js +238 -12
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -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.
|
|
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
|
|
83554
|
+
const original = envelopeSerializationInfo(envelope);
|
|
83555
|
+
const originalBytes = original.bytes;
|
|
83394
83556
|
if (originalBytes <= maxBytes) {
|
|
83395
|
-
return {
|
|
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(
|
|
83579
|
+
const targeted = truncatePayloads(canonicalEnvelope, maxBytes);
|
|
83398
83580
|
if (targeted) {
|
|
83581
|
+
const boundedEnvelope = RuntimeBridgeOutputEnvelopeSchema.parse(targeted);
|
|
83399
83582
|
return {
|
|
83400
|
-
envelope:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
83614
|
+
break;
|
|
83424
83615
|
}
|
|
83425
83616
|
setValueAtPath(
|
|
83426
83617
|
candidateEnvelope,
|
|
83427
83618
|
candidate.path,
|
|
83428
83619
|
truncationNotice(candidate, "")
|
|
83429
83620
|
);
|
|
83430
|
-
|
|
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.
|
|
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
|
|
106803
|
+
const original = envelopeSerializationInfo(envelope);
|
|
106804
|
+
const originalBytes = original.bytes;
|
|
106643
106805
|
if (originalBytes <= maxBytes) {
|
|
106644
|
-
return {
|
|
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(
|
|
106828
|
+
const targeted = truncatePayloads(canonicalEnvelope, maxBytes);
|
|
106647
106829
|
if (targeted) {
|
|
106830
|
+
const boundedEnvelope = RuntimeBridgeOutputEnvelopeSchema.parse(targeted);
|
|
106648
106831
|
return {
|
|
106649
|
-
envelope:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
106863
|
+
break;
|
|
106673
106864
|
}
|
|
106674
106865
|
setValueAtPath(
|
|
106675
106866
|
candidateEnvelope,
|
|
106676
106867
|
candidate.path,
|
|
106677
106868
|
truncationNotice(candidate, "")
|
|
106678
106869
|
);
|
|
106679
|
-
|
|
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
|
})
|