@autohq/cli 0.1.292 → 0.1.293

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.
@@ -23399,7 +23399,7 @@ Object.assign(lookup, {
23399
23399
  // package.json
23400
23400
  var package_default = {
23401
23401
  name: "@autohq/cli",
23402
- version: "0.1.292",
23402
+ version: "0.1.293",
23403
23403
  license: "SEE LICENSE IN README.md",
23404
23404
  publishConfig: {
23405
23405
  access: "public"
@@ -36694,6 +36694,295 @@ var _a21;
36694
36694
  _a21 = symbol21;
36695
36695
  var defaultDownload2 = createDownload();
36696
36696
 
36697
+ // src/commands/agent-bridge/harness/ui-message-part-tracker.ts
36698
+ var UiMessagePartTracker = class {
36699
+ messageId = null;
36700
+ messageMetadata;
36701
+ metadataEmitted = false;
36702
+ parts = [];
36703
+ textPartIndexById = /* @__PURE__ */ new Map();
36704
+ reasoningPartIndexById = /* @__PURE__ */ new Map();
36705
+ toolPartIndexByCallId = /* @__PURE__ */ new Map();
36706
+ dataPartIndexById = /* @__PURE__ */ new Map();
36707
+ append(chunk) {
36708
+ switch (chunk.type) {
36709
+ case "start": {
36710
+ this.reset();
36711
+ const messageId = chunk.messageId?.trim();
36712
+ this.messageId = messageId && messageId !== UNKNOWN_MESSAGE_ID ? messageId : null;
36713
+ this.messageMetadata = chunk.messageMetadata;
36714
+ return [];
36715
+ }
36716
+ case "finish":
36717
+ case "error":
36718
+ case "abort": {
36719
+ this.reset();
36720
+ return [];
36721
+ }
36722
+ case "text-start": {
36723
+ const index = this.pushPart({
36724
+ type: "text",
36725
+ text: "",
36726
+ state: "streaming",
36727
+ ...providerMetadataField(chunk.providerMetadata)
36728
+ });
36729
+ this.textPartIndexById.set(chunk.id, index);
36730
+ return [];
36731
+ }
36732
+ case "text-delta": {
36733
+ const part = this.partById(this.textPartIndexById, chunk.id);
36734
+ if (part) {
36735
+ part.text = String(part.text ?? "") + chunk.delta;
36736
+ }
36737
+ return [];
36738
+ }
36739
+ case "text-end": {
36740
+ const index = this.textPartIndexById.get(chunk.id);
36741
+ const part = this.partById(this.textPartIndexById, chunk.id);
36742
+ this.textPartIndexById.delete(chunk.id);
36743
+ if (!part || index === void 0) {
36744
+ return [];
36745
+ }
36746
+ part.state = "done";
36747
+ if (chunk.providerMetadata !== void 0) {
36748
+ part.providerMetadata = chunk.providerMetadata;
36749
+ }
36750
+ return this.persistable(index);
36751
+ }
36752
+ case "reasoning-start": {
36753
+ const index = this.pushPart({
36754
+ type: "reasoning",
36755
+ text: "",
36756
+ state: "streaming",
36757
+ ...providerMetadataField(chunk.providerMetadata)
36758
+ });
36759
+ this.reasoningPartIndexById.set(chunk.id, index);
36760
+ return [];
36761
+ }
36762
+ case "reasoning-delta": {
36763
+ const part = this.partById(this.reasoningPartIndexById, chunk.id);
36764
+ if (part) {
36765
+ part.text = String(part.text ?? "") + chunk.delta;
36766
+ if (chunk.providerMetadata !== void 0) {
36767
+ part.providerMetadata = chunk.providerMetadata;
36768
+ }
36769
+ }
36770
+ return [];
36771
+ }
36772
+ case "reasoning-end": {
36773
+ const index = this.reasoningPartIndexById.get(chunk.id);
36774
+ const part = this.partById(this.reasoningPartIndexById, chunk.id);
36775
+ this.reasoningPartIndexById.delete(chunk.id);
36776
+ if (!part || index === void 0) {
36777
+ return [];
36778
+ }
36779
+ part.state = "done";
36780
+ if (chunk.providerMetadata !== void 0) {
36781
+ part.providerMetadata = chunk.providerMetadata;
36782
+ }
36783
+ return this.persistable(index);
36784
+ }
36785
+ case "tool-input-start": {
36786
+ const index = this.pushPart(
36787
+ toolPartShape({
36788
+ toolCallId: chunk.toolCallId,
36789
+ toolName: chunk.toolName,
36790
+ dynamic: chunk.dynamic,
36791
+ state: "input-streaming"
36792
+ })
36793
+ );
36794
+ this.toolPartIndexByCallId.set(chunk.toolCallId, index);
36795
+ return [];
36796
+ }
36797
+ case "tool-input-available": {
36798
+ const index = this.upsertToolPart(chunk.toolCallId, {
36799
+ ...toolPartShape({
36800
+ toolCallId: chunk.toolCallId,
36801
+ toolName: chunk.toolName,
36802
+ dynamic: chunk.dynamic,
36803
+ state: "input-available"
36804
+ }),
36805
+ input: chunk.input,
36806
+ ...chunk.providerExecuted !== void 0 ? { providerExecuted: chunk.providerExecuted } : {},
36807
+ ...chunk.providerMetadata !== void 0 ? { callProviderMetadata: chunk.providerMetadata } : {}
36808
+ });
36809
+ return this.persistable(index);
36810
+ }
36811
+ case "tool-input-error": {
36812
+ const index = this.upsertToolPart(chunk.toolCallId, {
36813
+ ...toolPartShape({
36814
+ toolCallId: chunk.toolCallId,
36815
+ toolName: chunk.toolName,
36816
+ dynamic: chunk.dynamic,
36817
+ state: "output-error"
36818
+ }),
36819
+ input: chunk.input,
36820
+ errorText: chunk.errorText
36821
+ });
36822
+ return this.persistable(index);
36823
+ }
36824
+ case "tool-output-available": {
36825
+ const part = this.partById(
36826
+ this.toolPartIndexByCallId,
36827
+ chunk.toolCallId
36828
+ );
36829
+ const index = this.toolPartIndexByCallId.get(chunk.toolCallId);
36830
+ if (!part || index === void 0) {
36831
+ return [];
36832
+ }
36833
+ part.state = "output-available";
36834
+ part.output = chunk.output;
36835
+ part.preliminary = chunk.preliminary;
36836
+ return this.persistable(index);
36837
+ }
36838
+ case "tool-output-error": {
36839
+ const part = this.partById(
36840
+ this.toolPartIndexByCallId,
36841
+ chunk.toolCallId
36842
+ );
36843
+ const index = this.toolPartIndexByCallId.get(chunk.toolCallId);
36844
+ if (!part || index === void 0) {
36845
+ return [];
36846
+ }
36847
+ part.state = "output-error";
36848
+ part.errorText = chunk.errorText;
36849
+ return this.persistable(index);
36850
+ }
36851
+ case "start-step": {
36852
+ const index = this.pushPart({ type: "step-start" });
36853
+ return this.persistable(index);
36854
+ }
36855
+ case "finish-step": {
36856
+ this.textPartIndexById.clear();
36857
+ this.reasoningPartIndexById.clear();
36858
+ return [];
36859
+ }
36860
+ case "file": {
36861
+ const index = this.pushPart({
36862
+ type: "file",
36863
+ mediaType: chunk.mediaType,
36864
+ url: chunk.url
36865
+ });
36866
+ return this.persistable(index);
36867
+ }
36868
+ case "source-url": {
36869
+ const index = this.pushPart({
36870
+ type: "source-url",
36871
+ sourceId: chunk.sourceId,
36872
+ url: chunk.url,
36873
+ ...chunk.title !== void 0 ? { title: chunk.title } : {}
36874
+ });
36875
+ return this.persistable(index);
36876
+ }
36877
+ case "source-document": {
36878
+ const index = this.pushPart({
36879
+ type: "source-document",
36880
+ sourceId: chunk.sourceId,
36881
+ mediaType: chunk.mediaType,
36882
+ title: chunk.title,
36883
+ ...chunk.filename !== void 0 ? { filename: chunk.filename } : {}
36884
+ });
36885
+ return this.persistable(index);
36886
+ }
36887
+ default: {
36888
+ return this.appendDataChunk(chunk);
36889
+ }
36890
+ }
36891
+ }
36892
+ appendDataChunk(chunk) {
36893
+ if (!chunk.type.startsWith("data-") || chunk.type === "data-auto-question") {
36894
+ return [];
36895
+ }
36896
+ const dataChunk = chunk;
36897
+ if (dataChunk.transient) {
36898
+ return [];
36899
+ }
36900
+ const part = {
36901
+ type: dataChunk.type,
36902
+ ...dataChunk.id !== void 0 ? { id: dataChunk.id } : {},
36903
+ data: dataChunk.data
36904
+ };
36905
+ const dataKey = dataChunk.id ? `${dataChunk.type}:${dataChunk.id}` : null;
36906
+ const existingIndex = dataKey ? this.dataPartIndexById.get(dataKey) : void 0;
36907
+ if (existingIndex !== void 0) {
36908
+ this.parts[existingIndex] = part;
36909
+ return this.persistable(existingIndex);
36910
+ }
36911
+ const index = this.pushPart(part);
36912
+ if (dataKey) {
36913
+ this.dataPartIndexById.set(dataKey, index);
36914
+ }
36915
+ return this.persistable(index);
36916
+ }
36917
+ upsertToolPart(toolCallId, part) {
36918
+ const existingIndex = this.toolPartIndexByCallId.get(toolCallId);
36919
+ if (existingIndex !== void 0) {
36920
+ this.parts[existingIndex] = part;
36921
+ return existingIndex;
36922
+ }
36923
+ const index = this.pushPart(part);
36924
+ this.toolPartIndexByCallId.set(toolCallId, index);
36925
+ return index;
36926
+ }
36927
+ persistable(partIndex) {
36928
+ const part = this.parts[partIndex];
36929
+ if (!this.messageId || !part) {
36930
+ return [];
36931
+ }
36932
+ const includeMetadata = !this.metadataEmitted && this.messageMetadata !== void 0;
36933
+ if (includeMetadata) {
36934
+ this.metadataEmitted = true;
36935
+ }
36936
+ return [
36937
+ {
36938
+ messageId: this.messageId,
36939
+ partIndex,
36940
+ part: toJsonValue(part),
36941
+ ...includeMetadata ? { messageMetadata: toJsonValue(this.messageMetadata) } : {}
36942
+ }
36943
+ ];
36944
+ }
36945
+ pushPart(part) {
36946
+ this.parts.push(part);
36947
+ return this.parts.length - 1;
36948
+ }
36949
+ partById(indexById, id) {
36950
+ const index = indexById.get(id);
36951
+ if (index === void 0) {
36952
+ return null;
36953
+ }
36954
+ return this.parts[index] ?? null;
36955
+ }
36956
+ reset() {
36957
+ this.messageId = null;
36958
+ this.messageMetadata = void 0;
36959
+ this.metadataEmitted = false;
36960
+ this.parts = [];
36961
+ this.textPartIndexById = /* @__PURE__ */ new Map();
36962
+ this.reasoningPartIndexById = /* @__PURE__ */ new Map();
36963
+ this.toolPartIndexByCallId = /* @__PURE__ */ new Map();
36964
+ this.dataPartIndexById = /* @__PURE__ */ new Map();
36965
+ }
36966
+ };
36967
+ function toolPartShape(input) {
36968
+ if (input.dynamic) {
36969
+ return {
36970
+ type: "dynamic-tool",
36971
+ toolName: input.toolName,
36972
+ toolCallId: input.toolCallId,
36973
+ state: input.state
36974
+ };
36975
+ }
36976
+ return {
36977
+ type: `tool-${input.toolName}`,
36978
+ toolCallId: input.toolCallId,
36979
+ state: input.state
36980
+ };
36981
+ }
36982
+ function providerMetadataField(providerMetadata) {
36983
+ return providerMetadata !== void 0 ? { providerMetadata } : {};
36984
+ }
36985
+
36697
36986
  // src/commands/agent-bridge/harness/output-buffer.ts
36698
36987
  var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
36699
36988
  var AgentBridgeOutputBuffer = class {
@@ -36707,6 +36996,7 @@ var AgentBridgeOutputBuffer = class {
36707
36996
  pendingDelta = null;
36708
36997
  deltaFlushTimer = null;
36709
36998
  activeUiMessageAssembler = null;
36999
+ uiMessagePartTracker = new UiMessagePartTracker();
36710
37000
  drainBlocked = false;
36711
37001
  drainPromise = null;
36712
37002
  // ---------------------------------------------------------------------------
@@ -36747,6 +37037,9 @@ var AgentBridgeOutputBuffer = class {
36747
37037
  }
36748
37038
  await this.flushPendingDelta();
36749
37039
  await this.emitLiveUiMessageChunk(context, projection.chunk);
37040
+ await this.emitUiMessagePartSnapshots(context, projection.chunk, {
37041
+ coveredSeq: this.outputSeq
37042
+ });
36750
37043
  const completedMessage = await this.appendUiChunkToAssembler(
36751
37044
  projection.chunk
36752
37045
  );
@@ -36805,6 +37098,25 @@ var AgentBridgeOutputBuffer = class {
36805
37098
  this.enqueueOutput(output);
36806
37099
  await this.drainPendingOutputs();
36807
37100
  }
37101
+ async emitUiMessagePartSnapshots(context, chunk, input) {
37102
+ const snapshots = this.uiMessagePartTracker.append(chunk);
37103
+ if (snapshots.length === 0) {
37104
+ return;
37105
+ }
37106
+ for (const snapshot of snapshots) {
37107
+ this.outputSeq += 1;
37108
+ this.enqueueOutput(
37109
+ buildUiMessagePartOutputEnvelope({
37110
+ context,
37111
+ outputSeq: this.outputSeq,
37112
+ coveredSeq: input.coveredSeq,
37113
+ snapshot,
37114
+ createdAt: now2()
37115
+ })
37116
+ );
37117
+ }
37118
+ await this.drainPendingOutputs();
37119
+ }
36808
37120
  // ---------------------------------------------------------------------------
36809
37121
  // Transport emit
36810
37122
  // ---------------------------------------------------------------------------
@@ -37117,6 +37429,23 @@ function buildUiMessageChunkOutputEnvelope(input) {
37117
37429
  createdAt: input.createdAt
37118
37430
  });
37119
37431
  }
37432
+ function buildUiMessagePartOutputEnvelope(input) {
37433
+ const { context, snapshot } = input;
37434
+ return RuntimeBridgeOutputEnvelopeSchema.parse({
37435
+ type: "ui.message.part",
37436
+ sessionId: context.sessionId,
37437
+ runtimeId: context.runtimeId,
37438
+ bridgeLeaseId: context.bridgeLeaseId,
37439
+ outputSeq: input.outputSeq,
37440
+ messageId: snapshot.messageId,
37441
+ role: "assistant",
37442
+ partIndex: snapshot.partIndex,
37443
+ part: snapshot.part,
37444
+ coveredSeq: input.coveredSeq,
37445
+ ...snapshot.messageMetadata !== void 0 ? { messageMetadata: snapshot.messageMetadata } : {},
37446
+ createdAt: input.createdAt
37447
+ });
37448
+ }
37120
37449
  function buildUiMessageCompletedOutputEnvelope(input) {
37121
37450
  const { context } = input;
37122
37451
  return RuntimeBridgeOutputEnvelopeSchema.parse({
package/dist/index.js CHANGED
@@ -23182,7 +23182,7 @@ var init_package = __esm({
23182
23182
  "package.json"() {
23183
23183
  package_default = {
23184
23184
  name: "@autohq/cli",
23185
- version: "0.1.292",
23185
+ version: "0.1.293",
23186
23186
  license: "SEE LICENSE IN README.md",
23187
23187
  publishConfig: {
23188
23188
  access: "public"
@@ -33712,6 +33712,298 @@ init_src();
33712
33712
  // src/commands/agent-bridge/harness/output-buffer.ts
33713
33713
  init_src();
33714
33714
  import { readUIMessageStream } from "ai";
33715
+
33716
+ // src/commands/agent-bridge/harness/ui-message-part-tracker.ts
33717
+ init_src();
33718
+ var UiMessagePartTracker = class {
33719
+ messageId = null;
33720
+ messageMetadata;
33721
+ metadataEmitted = false;
33722
+ parts = [];
33723
+ textPartIndexById = /* @__PURE__ */ new Map();
33724
+ reasoningPartIndexById = /* @__PURE__ */ new Map();
33725
+ toolPartIndexByCallId = /* @__PURE__ */ new Map();
33726
+ dataPartIndexById = /* @__PURE__ */ new Map();
33727
+ append(chunk) {
33728
+ switch (chunk.type) {
33729
+ case "start": {
33730
+ this.reset();
33731
+ const messageId = chunk.messageId?.trim();
33732
+ this.messageId = messageId && messageId !== UNKNOWN_MESSAGE_ID ? messageId : null;
33733
+ this.messageMetadata = chunk.messageMetadata;
33734
+ return [];
33735
+ }
33736
+ case "finish":
33737
+ case "error":
33738
+ case "abort": {
33739
+ this.reset();
33740
+ return [];
33741
+ }
33742
+ case "text-start": {
33743
+ const index = this.pushPart({
33744
+ type: "text",
33745
+ text: "",
33746
+ state: "streaming",
33747
+ ...providerMetadataField(chunk.providerMetadata)
33748
+ });
33749
+ this.textPartIndexById.set(chunk.id, index);
33750
+ return [];
33751
+ }
33752
+ case "text-delta": {
33753
+ const part = this.partById(this.textPartIndexById, chunk.id);
33754
+ if (part) {
33755
+ part.text = String(part.text ?? "") + chunk.delta;
33756
+ }
33757
+ return [];
33758
+ }
33759
+ case "text-end": {
33760
+ const index = this.textPartIndexById.get(chunk.id);
33761
+ const part = this.partById(this.textPartIndexById, chunk.id);
33762
+ this.textPartIndexById.delete(chunk.id);
33763
+ if (!part || index === void 0) {
33764
+ return [];
33765
+ }
33766
+ part.state = "done";
33767
+ if (chunk.providerMetadata !== void 0) {
33768
+ part.providerMetadata = chunk.providerMetadata;
33769
+ }
33770
+ return this.persistable(index);
33771
+ }
33772
+ case "reasoning-start": {
33773
+ const index = this.pushPart({
33774
+ type: "reasoning",
33775
+ text: "",
33776
+ state: "streaming",
33777
+ ...providerMetadataField(chunk.providerMetadata)
33778
+ });
33779
+ this.reasoningPartIndexById.set(chunk.id, index);
33780
+ return [];
33781
+ }
33782
+ case "reasoning-delta": {
33783
+ const part = this.partById(this.reasoningPartIndexById, chunk.id);
33784
+ if (part) {
33785
+ part.text = String(part.text ?? "") + chunk.delta;
33786
+ if (chunk.providerMetadata !== void 0) {
33787
+ part.providerMetadata = chunk.providerMetadata;
33788
+ }
33789
+ }
33790
+ return [];
33791
+ }
33792
+ case "reasoning-end": {
33793
+ const index = this.reasoningPartIndexById.get(chunk.id);
33794
+ const part = this.partById(this.reasoningPartIndexById, chunk.id);
33795
+ this.reasoningPartIndexById.delete(chunk.id);
33796
+ if (!part || index === void 0) {
33797
+ return [];
33798
+ }
33799
+ part.state = "done";
33800
+ if (chunk.providerMetadata !== void 0) {
33801
+ part.providerMetadata = chunk.providerMetadata;
33802
+ }
33803
+ return this.persistable(index);
33804
+ }
33805
+ case "tool-input-start": {
33806
+ const index = this.pushPart(
33807
+ toolPartShape({
33808
+ toolCallId: chunk.toolCallId,
33809
+ toolName: chunk.toolName,
33810
+ dynamic: chunk.dynamic,
33811
+ state: "input-streaming"
33812
+ })
33813
+ );
33814
+ this.toolPartIndexByCallId.set(chunk.toolCallId, index);
33815
+ return [];
33816
+ }
33817
+ case "tool-input-available": {
33818
+ const index = this.upsertToolPart(chunk.toolCallId, {
33819
+ ...toolPartShape({
33820
+ toolCallId: chunk.toolCallId,
33821
+ toolName: chunk.toolName,
33822
+ dynamic: chunk.dynamic,
33823
+ state: "input-available"
33824
+ }),
33825
+ input: chunk.input,
33826
+ ...chunk.providerExecuted !== void 0 ? { providerExecuted: chunk.providerExecuted } : {},
33827
+ ...chunk.providerMetadata !== void 0 ? { callProviderMetadata: chunk.providerMetadata } : {}
33828
+ });
33829
+ return this.persistable(index);
33830
+ }
33831
+ case "tool-input-error": {
33832
+ const index = this.upsertToolPart(chunk.toolCallId, {
33833
+ ...toolPartShape({
33834
+ toolCallId: chunk.toolCallId,
33835
+ toolName: chunk.toolName,
33836
+ dynamic: chunk.dynamic,
33837
+ state: "output-error"
33838
+ }),
33839
+ input: chunk.input,
33840
+ errorText: chunk.errorText
33841
+ });
33842
+ return this.persistable(index);
33843
+ }
33844
+ case "tool-output-available": {
33845
+ const part = this.partById(
33846
+ this.toolPartIndexByCallId,
33847
+ chunk.toolCallId
33848
+ );
33849
+ const index = this.toolPartIndexByCallId.get(chunk.toolCallId);
33850
+ if (!part || index === void 0) {
33851
+ return [];
33852
+ }
33853
+ part.state = "output-available";
33854
+ part.output = chunk.output;
33855
+ part.preliminary = chunk.preliminary;
33856
+ return this.persistable(index);
33857
+ }
33858
+ case "tool-output-error": {
33859
+ const part = this.partById(
33860
+ this.toolPartIndexByCallId,
33861
+ chunk.toolCallId
33862
+ );
33863
+ const index = this.toolPartIndexByCallId.get(chunk.toolCallId);
33864
+ if (!part || index === void 0) {
33865
+ return [];
33866
+ }
33867
+ part.state = "output-error";
33868
+ part.errorText = chunk.errorText;
33869
+ return this.persistable(index);
33870
+ }
33871
+ case "start-step": {
33872
+ const index = this.pushPart({ type: "step-start" });
33873
+ return this.persistable(index);
33874
+ }
33875
+ case "finish-step": {
33876
+ this.textPartIndexById.clear();
33877
+ this.reasoningPartIndexById.clear();
33878
+ return [];
33879
+ }
33880
+ case "file": {
33881
+ const index = this.pushPart({
33882
+ type: "file",
33883
+ mediaType: chunk.mediaType,
33884
+ url: chunk.url
33885
+ });
33886
+ return this.persistable(index);
33887
+ }
33888
+ case "source-url": {
33889
+ const index = this.pushPart({
33890
+ type: "source-url",
33891
+ sourceId: chunk.sourceId,
33892
+ url: chunk.url,
33893
+ ...chunk.title !== void 0 ? { title: chunk.title } : {}
33894
+ });
33895
+ return this.persistable(index);
33896
+ }
33897
+ case "source-document": {
33898
+ const index = this.pushPart({
33899
+ type: "source-document",
33900
+ sourceId: chunk.sourceId,
33901
+ mediaType: chunk.mediaType,
33902
+ title: chunk.title,
33903
+ ...chunk.filename !== void 0 ? { filename: chunk.filename } : {}
33904
+ });
33905
+ return this.persistable(index);
33906
+ }
33907
+ default: {
33908
+ return this.appendDataChunk(chunk);
33909
+ }
33910
+ }
33911
+ }
33912
+ appendDataChunk(chunk) {
33913
+ if (!chunk.type.startsWith("data-") || chunk.type === "data-auto-question") {
33914
+ return [];
33915
+ }
33916
+ const dataChunk = chunk;
33917
+ if (dataChunk.transient) {
33918
+ return [];
33919
+ }
33920
+ const part = {
33921
+ type: dataChunk.type,
33922
+ ...dataChunk.id !== void 0 ? { id: dataChunk.id } : {},
33923
+ data: dataChunk.data
33924
+ };
33925
+ const dataKey = dataChunk.id ? `${dataChunk.type}:${dataChunk.id}` : null;
33926
+ const existingIndex = dataKey ? this.dataPartIndexById.get(dataKey) : void 0;
33927
+ if (existingIndex !== void 0) {
33928
+ this.parts[existingIndex] = part;
33929
+ return this.persistable(existingIndex);
33930
+ }
33931
+ const index = this.pushPart(part);
33932
+ if (dataKey) {
33933
+ this.dataPartIndexById.set(dataKey, index);
33934
+ }
33935
+ return this.persistable(index);
33936
+ }
33937
+ upsertToolPart(toolCallId, part) {
33938
+ const existingIndex = this.toolPartIndexByCallId.get(toolCallId);
33939
+ if (existingIndex !== void 0) {
33940
+ this.parts[existingIndex] = part;
33941
+ return existingIndex;
33942
+ }
33943
+ const index = this.pushPart(part);
33944
+ this.toolPartIndexByCallId.set(toolCallId, index);
33945
+ return index;
33946
+ }
33947
+ persistable(partIndex) {
33948
+ const part = this.parts[partIndex];
33949
+ if (!this.messageId || !part) {
33950
+ return [];
33951
+ }
33952
+ const includeMetadata = !this.metadataEmitted && this.messageMetadata !== void 0;
33953
+ if (includeMetadata) {
33954
+ this.metadataEmitted = true;
33955
+ }
33956
+ return [
33957
+ {
33958
+ messageId: this.messageId,
33959
+ partIndex,
33960
+ part: toJsonValue(part),
33961
+ ...includeMetadata ? { messageMetadata: toJsonValue(this.messageMetadata) } : {}
33962
+ }
33963
+ ];
33964
+ }
33965
+ pushPart(part) {
33966
+ this.parts.push(part);
33967
+ return this.parts.length - 1;
33968
+ }
33969
+ partById(indexById, id) {
33970
+ const index = indexById.get(id);
33971
+ if (index === void 0) {
33972
+ return null;
33973
+ }
33974
+ return this.parts[index] ?? null;
33975
+ }
33976
+ reset() {
33977
+ this.messageId = null;
33978
+ this.messageMetadata = void 0;
33979
+ this.metadataEmitted = false;
33980
+ this.parts = [];
33981
+ this.textPartIndexById = /* @__PURE__ */ new Map();
33982
+ this.reasoningPartIndexById = /* @__PURE__ */ new Map();
33983
+ this.toolPartIndexByCallId = /* @__PURE__ */ new Map();
33984
+ this.dataPartIndexById = /* @__PURE__ */ new Map();
33985
+ }
33986
+ };
33987
+ function toolPartShape(input) {
33988
+ if (input.dynamic) {
33989
+ return {
33990
+ type: "dynamic-tool",
33991
+ toolName: input.toolName,
33992
+ toolCallId: input.toolCallId,
33993
+ state: input.state
33994
+ };
33995
+ }
33996
+ return {
33997
+ type: `tool-${input.toolName}`,
33998
+ toolCallId: input.toolCallId,
33999
+ state: input.state
34000
+ };
34001
+ }
34002
+ function providerMetadataField(providerMetadata) {
34003
+ return providerMetadata !== void 0 ? { providerMetadata } : {};
34004
+ }
34005
+
34006
+ // src/commands/agent-bridge/harness/output-buffer.ts
33715
34007
  var AGENT_BRIDGE_OUTPUT_DELTA_FLUSH_MS = 50;
33716
34008
  var AgentBridgeOutputBuffer = class {
33717
34009
  constructor(input) {
@@ -33724,6 +34016,7 @@ var AgentBridgeOutputBuffer = class {
33724
34016
  pendingDelta = null;
33725
34017
  deltaFlushTimer = null;
33726
34018
  activeUiMessageAssembler = null;
34019
+ uiMessagePartTracker = new UiMessagePartTracker();
33727
34020
  drainBlocked = false;
33728
34021
  drainPromise = null;
33729
34022
  // ---------------------------------------------------------------------------
@@ -33764,6 +34057,9 @@ var AgentBridgeOutputBuffer = class {
33764
34057
  }
33765
34058
  await this.flushPendingDelta();
33766
34059
  await this.emitLiveUiMessageChunk(context, projection.chunk);
34060
+ await this.emitUiMessagePartSnapshots(context, projection.chunk, {
34061
+ coveredSeq: this.outputSeq
34062
+ });
33767
34063
  const completedMessage = await this.appendUiChunkToAssembler(
33768
34064
  projection.chunk
33769
34065
  );
@@ -33822,6 +34118,25 @@ var AgentBridgeOutputBuffer = class {
33822
34118
  this.enqueueOutput(output);
33823
34119
  await this.drainPendingOutputs();
33824
34120
  }
34121
+ async emitUiMessagePartSnapshots(context, chunk, input) {
34122
+ const snapshots = this.uiMessagePartTracker.append(chunk);
34123
+ if (snapshots.length === 0) {
34124
+ return;
34125
+ }
34126
+ for (const snapshot of snapshots) {
34127
+ this.outputSeq += 1;
34128
+ this.enqueueOutput(
34129
+ buildUiMessagePartOutputEnvelope({
34130
+ context,
34131
+ outputSeq: this.outputSeq,
34132
+ coveredSeq: input.coveredSeq,
34133
+ snapshot,
34134
+ createdAt: now2()
34135
+ })
34136
+ );
34137
+ }
34138
+ await this.drainPendingOutputs();
34139
+ }
33825
34140
  // ---------------------------------------------------------------------------
33826
34141
  // Transport emit
33827
34142
  // ---------------------------------------------------------------------------
@@ -34134,6 +34449,23 @@ function buildUiMessageChunkOutputEnvelope(input) {
34134
34449
  createdAt: input.createdAt
34135
34450
  });
34136
34451
  }
34452
+ function buildUiMessagePartOutputEnvelope(input) {
34453
+ const { context, snapshot } = input;
34454
+ return RuntimeBridgeOutputEnvelopeSchema.parse({
34455
+ type: "ui.message.part",
34456
+ sessionId: context.sessionId,
34457
+ runtimeId: context.runtimeId,
34458
+ bridgeLeaseId: context.bridgeLeaseId,
34459
+ outputSeq: input.outputSeq,
34460
+ messageId: snapshot.messageId,
34461
+ role: "assistant",
34462
+ partIndex: snapshot.partIndex,
34463
+ part: snapshot.part,
34464
+ coveredSeq: input.coveredSeq,
34465
+ ...snapshot.messageMetadata !== void 0 ? { messageMetadata: snapshot.messageMetadata } : {},
34466
+ createdAt: input.createdAt
34467
+ });
34468
+ }
34137
34469
  function buildUiMessageCompletedOutputEnvelope(input) {
34138
34470
  const { context } = input;
34139
34471
  return RuntimeBridgeOutputEnvelopeSchema.parse({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.292",
3
+ "version": "0.1.293",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"