@autohq/cli 0.1.227 → 0.1.229

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.
@@ -23322,7 +23322,7 @@ Object.assign(lookup, {
23322
23322
  // package.json
23323
23323
  var package_default = {
23324
23324
  name: "@autohq/cli",
23325
- version: "0.1.227",
23325
+ version: "0.1.229",
23326
23326
  license: "SEE LICENSE IN README.md",
23327
23327
  publishConfig: {
23328
23328
  access: "public"
@@ -27646,6 +27646,7 @@ var UsageEventRecordSchema = UsageEventSchema.extend({
27646
27646
  });
27647
27647
 
27648
27648
  // src/commands/agent-bridge/harness/output-buffer.ts
27649
+ var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
27649
27650
  var AgentBridgeOutputBuffer = class {
27650
27651
  constructor(input) {
27651
27652
  this.input = input;
@@ -27654,26 +27655,23 @@ var AgentBridgeOutputBuffer = class {
27654
27655
  input;
27655
27656
  outputSeq;
27656
27657
  pendingOutputs = /* @__PURE__ */ new Map();
27658
+ pendingDelta = null;
27659
+ deltaFlushTimer = null;
27657
27660
  drainBlocked = false;
27658
27661
  drainPromise = null;
27659
27662
  // ---------------------------------------------------------------------------
27660
27663
  // Public API
27661
27664
  // ---------------------------------------------------------------------------
27662
27665
  async emitProjection(context, projection) {
27663
- this.outputSeq += 1;
27664
- this.pendingOutputs.set(
27665
- this.outputSeq,
27666
- buildOutputEnvelope(context, this.outputSeq, projection)
27667
- );
27668
- this.input.runtimeLogger?.info(
27669
- "agent_bridge_output_buffer_enqueued",
27670
- this.outputLogContext(this.pendingOutputs.get(this.outputSeq), {
27671
- pending_count: this.pendingOutputs.size
27672
- })
27673
- );
27674
- await this.drainPendingOutputs();
27666
+ if (projection.type === "delta") {
27667
+ await this.bufferDelta(context, projection.delta);
27668
+ return;
27669
+ }
27670
+ await this.flushPendingDelta();
27671
+ await this.enqueueProjectionAndDrain(context, projection);
27675
27672
  }
27676
27673
  async replayPendingOutputs() {
27674
+ await this.flushPendingDelta({ force: true });
27677
27675
  await this.drainPendingOutputs({ force: true });
27678
27676
  }
27679
27677
  // ---------------------------------------------------------------------------
@@ -27717,6 +27715,59 @@ var AgentBridgeOutputBuffer = class {
27717
27715
  });
27718
27716
  await this.drainPromise;
27719
27717
  }
27718
+ // ---------------------------------------------------------------------------
27719
+ // Delta coalescing
27720
+ // ---------------------------------------------------------------------------
27721
+ async bufferDelta(context, delta) {
27722
+ if (this.pendingDelta && canCoalesceDelta(this.pendingDelta, context, delta)) {
27723
+ this.pendingDelta = coalesceDelta(this.pendingDelta, delta);
27724
+ return;
27725
+ }
27726
+ await this.flushPendingDelta();
27727
+ this.pendingDelta = { context, delta, createdAt: now2() };
27728
+ this.scheduleDeltaFlush();
27729
+ }
27730
+ scheduleDeltaFlush() {
27731
+ if (this.deltaFlushTimer !== null) {
27732
+ return;
27733
+ }
27734
+ this.deltaFlushTimer = setTimeout(() => {
27735
+ void this.flushPendingDelta().catch((error51) => {
27736
+ this.drainBlocked = true;
27737
+ this.input.runtimeLogger?.warn(
27738
+ "agent_bridge_output_buffer_flush_failed",
27739
+ {
27740
+ error: error51 instanceof Error ? error51.message : String(error51),
27741
+ pending_count: this.pendingOutputs.size
27742
+ }
27743
+ );
27744
+ });
27745
+ }, AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS);
27746
+ }
27747
+ clearDeltaFlushTimer() {
27748
+ if (this.deltaFlushTimer === null) {
27749
+ return;
27750
+ }
27751
+ clearTimeout(this.deltaFlushTimer);
27752
+ this.deltaFlushTimer = null;
27753
+ }
27754
+ async flushPendingDelta(options = {}) {
27755
+ const pendingDelta = this.pendingDelta;
27756
+ if (!pendingDelta) {
27757
+ return;
27758
+ }
27759
+ this.clearDeltaFlushTimer();
27760
+ this.pendingDelta = null;
27761
+ this.outputSeq += 1;
27762
+ const output = buildDeltaOutputEnvelope({
27763
+ context: pendingDelta.context,
27764
+ outputSeq: this.outputSeq,
27765
+ delta: pendingDelta.delta,
27766
+ createdAt: pendingDelta.createdAt
27767
+ });
27768
+ this.enqueueOutput(output);
27769
+ await this.drainPendingOutputs(options);
27770
+ }
27720
27771
  async emitUntilAcked(output) {
27721
27772
  const startedAt = Date.now();
27722
27773
  this.input.runtimeLogger?.info(
@@ -27755,6 +27806,22 @@ var AgentBridgeOutputBuffer = class {
27755
27806
  (left, right) => left.outputSeq - right.outputSeq
27756
27807
  )[0] ?? null;
27757
27808
  }
27809
+ async enqueueProjectionAndDrain(context, projection) {
27810
+ this.outputSeq += 1;
27811
+ this.enqueueOutput(
27812
+ buildOutputEnvelope(context, this.outputSeq, projection)
27813
+ );
27814
+ await this.drainPendingOutputs();
27815
+ }
27816
+ enqueueOutput(output) {
27817
+ this.pendingOutputs.set(output.outputSeq, output);
27818
+ this.input.runtimeLogger?.info(
27819
+ "agent_bridge_output_buffer_enqueued",
27820
+ this.outputLogContext(output, {
27821
+ pending_count: this.pendingOutputs.size
27822
+ })
27823
+ );
27824
+ }
27758
27825
  outputLogContext(output, fields = {}) {
27759
27826
  return {
27760
27827
  output_seq: output?.outputSeq,
@@ -27767,20 +27834,27 @@ var AgentBridgeOutputBuffer = class {
27767
27834
  };
27768
27835
  }
27769
27836
  };
27837
+ function canCoalesceDelta(pending, context, delta) {
27838
+ 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 === "text" && delta.delta.type === "text";
27839
+ }
27840
+ function coalesceDelta(pending, delta) {
27841
+ return {
27842
+ ...pending,
27843
+ delta: {
27844
+ ...pending.delta,
27845
+ delta: {
27846
+ type: "text",
27847
+ text: pending.delta.delta.text + delta.delta.text
27848
+ }
27849
+ }
27850
+ };
27851
+ }
27770
27852
  function buildOutputEnvelope(context, outputSeq, projection) {
27771
27853
  if (projection.type === "delta") {
27772
- const { delta } = projection;
27773
- return RuntimeBridgeOutputEnvelopeSchema.parse({
27774
- type: "conversation.delta",
27775
- sessionId: context.sessionId,
27776
- runtimeId: context.runtimeId,
27777
- bridgeLeaseId: context.bridgeLeaseId,
27854
+ return buildDeltaOutputEnvelope({
27855
+ context,
27778
27856
  outputSeq,
27779
- messageId: delta.messageId,
27780
- partId: delta.partId,
27781
- role: delta.role,
27782
- kind: delta.kind,
27783
- delta: delta.delta,
27857
+ delta: projection.delta,
27784
27858
  createdAt: now2()
27785
27859
  });
27786
27860
  }
@@ -27802,6 +27876,22 @@ function buildOutputEnvelope(context, outputSeq, projection) {
27802
27876
  ...entry.turnStatus ? { turnStatus: entry.turnStatus } : {}
27803
27877
  });
27804
27878
  }
27879
+ function buildDeltaOutputEnvelope(input) {
27880
+ const { context, delta } = input;
27881
+ return RuntimeBridgeOutputEnvelopeSchema.parse({
27882
+ type: "conversation.delta",
27883
+ sessionId: context.sessionId,
27884
+ runtimeId: context.runtimeId,
27885
+ bridgeLeaseId: context.bridgeLeaseId,
27886
+ outputSeq: input.outputSeq,
27887
+ messageId: delta.messageId,
27888
+ partId: delta.partId,
27889
+ role: delta.role,
27890
+ kind: delta.kind,
27891
+ delta: delta.delta,
27892
+ createdAt: input.createdAt
27893
+ });
27894
+ }
27805
27895
  function isSuccessfulOutputAck(ack) {
27806
27896
  return ack.status === "persisted" || ack.status === "duplicate" || ack.status === "published";
27807
27897
  }
package/dist/index.js CHANGED
@@ -16552,7 +16552,7 @@ function reduceConversationRealtimeEvent(entries, event) {
16552
16552
  return next;
16553
16553
  }
16554
16554
  const existingByMessage = event.messageId === void 0 ? -1 : entries.findIndex(
16555
- (entry) => entry.messageId === event.messageId && entry.status === "in_progress" && entry.role === event.role && entry.kind === event.kind
16555
+ (entry) => entry.messageId === event.messageId && (entry.status === "in_progress" || isLocalOptimisticEntry(entry)) && entry.role === event.role && entry.kind === event.kind
16556
16556
  );
16557
16557
  if (existingByMessage >= 0) {
16558
16558
  const next = [...entries];
@@ -16561,6 +16561,9 @@ function reduceConversationRealtimeEvent(entries, event) {
16561
16561
  }
16562
16562
  return [...entries, event];
16563
16563
  }
16564
+ function isLocalOptimisticEntry(entry) {
16565
+ return entry.id.startsWith("local-");
16566
+ }
16564
16567
  function syntheticDeltaEntry(event) {
16565
16568
  return {
16566
16569
  type: "conversation.entry",
@@ -22238,7 +22241,7 @@ var init_package = __esm({
22238
22241
  "package.json"() {
22239
22242
  package_default = {
22240
22243
  name: "@autohq/cli",
22241
- version: "0.1.227",
22244
+ version: "0.1.229",
22242
22245
  license: "SEE LICENSE IN README.md",
22243
22246
  publishConfig: {
22244
22247
  access: "public"
@@ -32362,6 +32365,7 @@ function errorMessage(error51) {
32362
32365
  init_src();
32363
32366
 
32364
32367
  // src/commands/agent-bridge/harness/output-buffer.ts
32368
+ var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
32365
32369
  var AgentBridgeOutputBuffer = class {
32366
32370
  constructor(input) {
32367
32371
  this.input = input;
@@ -32370,26 +32374,23 @@ var AgentBridgeOutputBuffer = class {
32370
32374
  input;
32371
32375
  outputSeq;
32372
32376
  pendingOutputs = /* @__PURE__ */ new Map();
32377
+ pendingDelta = null;
32378
+ deltaFlushTimer = null;
32373
32379
  drainBlocked = false;
32374
32380
  drainPromise = null;
32375
32381
  // ---------------------------------------------------------------------------
32376
32382
  // Public API
32377
32383
  // ---------------------------------------------------------------------------
32378
32384
  async emitProjection(context, projection) {
32379
- this.outputSeq += 1;
32380
- this.pendingOutputs.set(
32381
- this.outputSeq,
32382
- buildOutputEnvelope(context, this.outputSeq, projection)
32383
- );
32384
- this.input.runtimeLogger?.info(
32385
- "agent_bridge_output_buffer_enqueued",
32386
- this.outputLogContext(this.pendingOutputs.get(this.outputSeq), {
32387
- pending_count: this.pendingOutputs.size
32388
- })
32389
- );
32390
- await this.drainPendingOutputs();
32385
+ if (projection.type === "delta") {
32386
+ await this.bufferDelta(context, projection.delta);
32387
+ return;
32388
+ }
32389
+ await this.flushPendingDelta();
32390
+ await this.enqueueProjectionAndDrain(context, projection);
32391
32391
  }
32392
32392
  async replayPendingOutputs() {
32393
+ await this.flushPendingDelta({ force: true });
32393
32394
  await this.drainPendingOutputs({ force: true });
32394
32395
  }
32395
32396
  // ---------------------------------------------------------------------------
@@ -32433,6 +32434,59 @@ var AgentBridgeOutputBuffer = class {
32433
32434
  });
32434
32435
  await this.drainPromise;
32435
32436
  }
32437
+ // ---------------------------------------------------------------------------
32438
+ // Delta coalescing
32439
+ // ---------------------------------------------------------------------------
32440
+ async bufferDelta(context, delta) {
32441
+ if (this.pendingDelta && canCoalesceDelta(this.pendingDelta, context, delta)) {
32442
+ this.pendingDelta = coalesceDelta(this.pendingDelta, delta);
32443
+ return;
32444
+ }
32445
+ await this.flushPendingDelta();
32446
+ this.pendingDelta = { context, delta, createdAt: now2() };
32447
+ this.scheduleDeltaFlush();
32448
+ }
32449
+ scheduleDeltaFlush() {
32450
+ if (this.deltaFlushTimer !== null) {
32451
+ return;
32452
+ }
32453
+ this.deltaFlushTimer = setTimeout(() => {
32454
+ void this.flushPendingDelta().catch((error51) => {
32455
+ this.drainBlocked = true;
32456
+ this.input.runtimeLogger?.warn(
32457
+ "agent_bridge_output_buffer_flush_failed",
32458
+ {
32459
+ error: error51 instanceof Error ? error51.message : String(error51),
32460
+ pending_count: this.pendingOutputs.size
32461
+ }
32462
+ );
32463
+ });
32464
+ }, AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS);
32465
+ }
32466
+ clearDeltaFlushTimer() {
32467
+ if (this.deltaFlushTimer === null) {
32468
+ return;
32469
+ }
32470
+ clearTimeout(this.deltaFlushTimer);
32471
+ this.deltaFlushTimer = null;
32472
+ }
32473
+ async flushPendingDelta(options = {}) {
32474
+ const pendingDelta = this.pendingDelta;
32475
+ if (!pendingDelta) {
32476
+ return;
32477
+ }
32478
+ this.clearDeltaFlushTimer();
32479
+ this.pendingDelta = null;
32480
+ this.outputSeq += 1;
32481
+ const output = buildDeltaOutputEnvelope({
32482
+ context: pendingDelta.context,
32483
+ outputSeq: this.outputSeq,
32484
+ delta: pendingDelta.delta,
32485
+ createdAt: pendingDelta.createdAt
32486
+ });
32487
+ this.enqueueOutput(output);
32488
+ await this.drainPendingOutputs(options);
32489
+ }
32436
32490
  async emitUntilAcked(output) {
32437
32491
  const startedAt = Date.now();
32438
32492
  this.input.runtimeLogger?.info(
@@ -32471,6 +32525,22 @@ var AgentBridgeOutputBuffer = class {
32471
32525
  (left, right) => left.outputSeq - right.outputSeq
32472
32526
  )[0] ?? null;
32473
32527
  }
32528
+ async enqueueProjectionAndDrain(context, projection) {
32529
+ this.outputSeq += 1;
32530
+ this.enqueueOutput(
32531
+ buildOutputEnvelope(context, this.outputSeq, projection)
32532
+ );
32533
+ await this.drainPendingOutputs();
32534
+ }
32535
+ enqueueOutput(output) {
32536
+ this.pendingOutputs.set(output.outputSeq, output);
32537
+ this.input.runtimeLogger?.info(
32538
+ "agent_bridge_output_buffer_enqueued",
32539
+ this.outputLogContext(output, {
32540
+ pending_count: this.pendingOutputs.size
32541
+ })
32542
+ );
32543
+ }
32474
32544
  outputLogContext(output, fields = {}) {
32475
32545
  return {
32476
32546
  output_seq: output?.outputSeq,
@@ -32483,20 +32553,27 @@ var AgentBridgeOutputBuffer = class {
32483
32553
  };
32484
32554
  }
32485
32555
  };
32556
+ function canCoalesceDelta(pending, context, delta) {
32557
+ 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 === "text" && delta.delta.type === "text";
32558
+ }
32559
+ function coalesceDelta(pending, delta) {
32560
+ return {
32561
+ ...pending,
32562
+ delta: {
32563
+ ...pending.delta,
32564
+ delta: {
32565
+ type: "text",
32566
+ text: pending.delta.delta.text + delta.delta.text
32567
+ }
32568
+ }
32569
+ };
32570
+ }
32486
32571
  function buildOutputEnvelope(context, outputSeq, projection) {
32487
32572
  if (projection.type === "delta") {
32488
- const { delta } = projection;
32489
- return RuntimeBridgeOutputEnvelopeSchema.parse({
32490
- type: "conversation.delta",
32491
- sessionId: context.sessionId,
32492
- runtimeId: context.runtimeId,
32493
- bridgeLeaseId: context.bridgeLeaseId,
32573
+ return buildDeltaOutputEnvelope({
32574
+ context,
32494
32575
  outputSeq,
32495
- messageId: delta.messageId,
32496
- partId: delta.partId,
32497
- role: delta.role,
32498
- kind: delta.kind,
32499
- delta: delta.delta,
32576
+ delta: projection.delta,
32500
32577
  createdAt: now2()
32501
32578
  });
32502
32579
  }
@@ -32518,6 +32595,22 @@ function buildOutputEnvelope(context, outputSeq, projection) {
32518
32595
  ...entry.turnStatus ? { turnStatus: entry.turnStatus } : {}
32519
32596
  });
32520
32597
  }
32598
+ function buildDeltaOutputEnvelope(input) {
32599
+ const { context, delta } = input;
32600
+ return RuntimeBridgeOutputEnvelopeSchema.parse({
32601
+ type: "conversation.delta",
32602
+ sessionId: context.sessionId,
32603
+ runtimeId: context.runtimeId,
32604
+ bridgeLeaseId: context.bridgeLeaseId,
32605
+ outputSeq: input.outputSeq,
32606
+ messageId: delta.messageId,
32607
+ partId: delta.partId,
32608
+ role: delta.role,
32609
+ kind: delta.kind,
32610
+ delta: delta.delta,
32611
+ createdAt: input.createdAt
32612
+ });
32613
+ }
32521
32614
  function isSuccessfulOutputAck(ack) {
32522
32615
  return ack.status === "persisted" || ack.status === "duplicate" || ack.status === "published";
32523
32616
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.227",
3
+ "version": "0.1.229",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"