@moxt-ai/mobius 0.0.143 → 0.0.145

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/cli.js CHANGED
@@ -3381,7 +3381,7 @@ var program = new Command();
3381
3381
  // package.json
3382
3382
  var package_default = {
3383
3383
  name: "@moxt-ai/mobius",
3384
- version: "0.0.143",
3384
+ version: "0.0.145",
3385
3385
  description: "Mobius CLI for pairing and running local AI agent services.",
3386
3386
  type: "module",
3387
3387
  bin: {
@@ -29512,6 +29512,23 @@ var activeTurnActivitySchema = external_exports.strictObject({
29512
29512
  title: external_exports.string().max(500),
29513
29513
  toolKind: external_exports.string().max(64)
29514
29514
  }).readonly();
29515
+ var activeTurnUserMessageSchema = external_exports.strictObject({
29516
+ id: identifierStringSchema,
29517
+ images: external_exports.array(promptImageSchema).max(8).readonly().optional(),
29518
+ role: external_exports.literal("user"),
29519
+ text: external_exports.string().max(SESSION_HISTORY_CHARACTER_LIMIT)
29520
+ }).readonly();
29521
+ var activeTurnAssistantMessageSchema = external_exports.strictObject({
29522
+ activities: external_exports.array(activeTurnActivitySchema).max(100).readonly().default([]),
29523
+ content: external_exports.array(displayContentSchema).max(100).readonly().default([]),
29524
+ id: identifierStringSchema,
29525
+ role: external_exports.literal("assistant"),
29526
+ text: external_exports.string().max(SESSION_HISTORY_CHARACTER_LIMIT)
29527
+ }).readonly();
29528
+ var activeTurnMessageSchema = external_exports.discriminatedUnion("role", [
29529
+ activeTurnUserMessageSchema,
29530
+ activeTurnAssistantMessageSchema
29531
+ ]);
29515
29532
  var activeTurnSnapshotSchema = external_exports.strictObject({
29516
29533
  activities: external_exports.array(activeTurnActivitySchema).readonly(),
29517
29534
  commandId: identifierStringSchema,
@@ -29521,7 +29538,7 @@ var activeTurnSnapshotSchema = external_exports.strictObject({
29521
29538
  truncated: external_exports.boolean(),
29522
29539
  epoch: identifierStringSchema,
29523
29540
  interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
29524
- messages: external_exports.array(assistantHistoryMessageSchema).max(SESSION_HISTORY_MESSAGE_LIMIT).readonly(),
29541
+ messages: external_exports.array(activeTurnMessageSchema).max(SESSION_HISTORY_MESSAGE_LIMIT).readonly(),
29525
29542
  sequence: external_exports.number().int().nonnegative(),
29526
29543
  state: external_exports.literal("running")
29527
29544
  }).readonly();
@@ -42099,7 +42116,7 @@ var ActiveDaemonTurn = class {
42099
42116
  #text = "";
42100
42117
  #activities = /* @__PURE__ */ new Map();
42101
42118
  #content = /* @__PURE__ */ new Map();
42102
- #timeline = [];
42119
+ #timeline;
42103
42120
  #sequence = 0;
42104
42121
  #interaction = null;
42105
42122
  #epoch = decodeIdentifier(randomUUID2());
@@ -42108,6 +42125,9 @@ var ActiveDaemonTurn = class {
42108
42125
  this.command = command;
42109
42126
  this.#controller = new AbortController();
42110
42127
  this.#dispatch = { kind: "pending" };
42128
+ this.#timeline = [
42129
+ { id: decodeIdentifier(command.commandId), images: command.images, kind: "user", text: command.prompt }
42130
+ ];
42111
42131
  }
42112
42132
  enqueue = () => {
42113
42133
  if (this.#dispatch.kind !== "pending") {
@@ -42151,7 +42171,10 @@ var ActiveDaemonTurn = class {
42151
42171
  }
42152
42172
  if (event.kind === AGENT_ACTIVITY_KIND) {
42153
42173
  if (!this.#activities.has(event.activityId)) {
42154
- this.#timeline = [...this.#timeline, { activityId: event.activityId, kind: "activity" }];
42174
+ this.#timeline = [
42175
+ ...this.#timeline,
42176
+ { activityId: event.activityId, id: decodeIdentifier(randomUUID2()), kind: "activity" }
42177
+ ];
42155
42178
  }
42156
42179
  this.#activities.set(event.activityId, {
42157
42180
  activityId: event.activityId,
@@ -42169,7 +42192,10 @@ var ActiveDaemonTurn = class {
42169
42192
  } else if (event.kind === AGENT_ACTIVITY_NARRATION_KIND) {
42170
42193
  const previous = this.#activities.get(event.activityId);
42171
42194
  if (previous === void 0) {
42172
- this.#timeline = [...this.#timeline, { activityId: event.activityId, kind: "activity" }];
42195
+ this.#timeline = [
42196
+ ...this.#timeline,
42197
+ { activityId: event.activityId, id: decodeIdentifier(randomUUID2()), kind: "activity" }
42198
+ ];
42173
42199
  }
42174
42200
  this.#activities.set(event.activityId, {
42175
42201
  activityId: event.activityId,
@@ -42187,15 +42213,16 @@ var ActiveDaemonTurn = class {
42187
42213
  } else if (event.kind === AGENT_CONTENT_KIND) {
42188
42214
  this.#content.set(event.contentId, event.content);
42189
42215
  const target = this.#timeline.findLastIndex(
42190
- (entry) => entry.kind === "message" && entry.messageId === event.messageId
42216
+ (entry) => entry.kind === "message" && entry.sourceMessageId === event.messageId
42191
42217
  );
42192
42218
  if (target < 0) {
42193
42219
  this.#timeline = [
42194
42220
  ...this.#timeline,
42195
42221
  {
42196
42222
  content: /* @__PURE__ */ new Map([[event.contentId, event.content]]),
42223
+ id: decodeIdentifier(randomUUID2()),
42197
42224
  kind: "message",
42198
- messageId: event.messageId,
42225
+ sourceMessageId: event.messageId,
42199
42226
  text: ""
42200
42227
  }
42201
42228
  ];
@@ -42218,7 +42245,7 @@ var ActiveDaemonTurn = class {
42218
42245
  let remaining = text2;
42219
42246
  while (remaining.length > 0) {
42220
42247
  const latest = this.#timeline.at(-1);
42221
- if (latest?.kind === "message" && latest.messageId === messageId) {
42248
+ if (latest?.kind === "message" && latest.sourceMessageId === messageId) {
42222
42249
  const available = SESSION_HISTORY_CHARACTER_LIMIT - latest.text.length;
42223
42250
  if (available > 0) {
42224
42251
  this.#timeline = [
@@ -42233,28 +42260,43 @@ var ActiveDaemonTurn = class {
42233
42260
  ...this.#timeline,
42234
42261
  {
42235
42262
  content: /* @__PURE__ */ new Map(),
42263
+ id: decodeIdentifier(randomUUID2()),
42236
42264
  kind: "message",
42237
- messageId,
42265
+ sourceMessageId: messageId,
42238
42266
  text: remaining.slice(0, SESSION_HISTORY_CHARACTER_LIMIT)
42239
42267
  }
42240
42268
  ];
42241
42269
  remaining = remaining.slice(SESSION_HISTORY_CHARACTER_LIMIT);
42242
42270
  }
42243
42271
  }
42272
+ recordSteeringPrompt = (command) => {
42273
+ if (this.#dispatch.kind !== "running" || command.sessionId !== this.command.sessionId || command.targetCommandId !== this.command.commandId) {
42274
+ return null;
42275
+ }
42276
+ this.#timeline = [
42277
+ ...this.#timeline,
42278
+ { id: decodeIdentifier(command.commandId), images: command.images, kind: "user", text: command.prompt }
42279
+ ];
42280
+ return this.updated();
42281
+ };
42244
42282
  timelineMessages() {
42245
42283
  return this.#timeline.flatMap((entry) => {
42284
+ if (entry.kind === "user") {
42285
+ return [{ id: entry.id, images: entry.images, role: "user", text: entry.text }];
42286
+ }
42246
42287
  if (entry.kind === "message") {
42247
42288
  return [
42248
42289
  {
42249
42290
  activities: [],
42250
42291
  content: [...entry.content.values()],
42292
+ id: entry.id,
42251
42293
  role: "assistant",
42252
42294
  text: entry.text
42253
42295
  }
42254
42296
  ];
42255
42297
  }
42256
42298
  const activity2 = this.#activities.get(entry.activityId);
42257
- return activity2 === void 0 ? [] : [{ activities: [activity2], content: [], role: "assistant", text: "" }];
42299
+ return activity2 === void 0 ? [] : [{ activities: [activity2], content: [], id: entry.id, role: "assistant", text: "" }];
42258
42300
  });
42259
42301
  }
42260
42302
  updated = () => {
@@ -42364,6 +42406,10 @@ var DaemonTurnRegistry = class {
42364
42406
  }
42365
42407
  return event;
42366
42408
  };
42409
+ recordSteeringPrompt = (command) => {
42410
+ const target = this.#turns.get(command.targetCommandId);
42411
+ return target?.recordSteeringPrompt(command) ?? null;
42412
+ };
42367
42413
  executionSnapshot = async (matches) => {
42368
42414
  const matching = [];
42369
42415
  for (const turn of this.#turns.values()) {
@@ -42470,15 +42516,21 @@ var turnsSchema = external_exports.object({
42470
42516
  });
42471
42517
  var itemTypeSchema = external_exports.object({ type: external_exports.string().min(1).max(80) });
42472
42518
  var userMessageSchema = external_exports.object({
42473
- content: external_exports.array(external_exports.unknown()).max(1e4)
42519
+ content: external_exports.array(external_exports.unknown()).max(1e4),
42520
+ type: external_exports.literal("userMessage")
42474
42521
  });
42475
42522
  var textSchema = external_exports.object({ text: external_exports.string() });
42476
42523
  var imageSchema = external_exports.object({ url: external_exports.string() });
42477
- var agentMessageSchema = textSchema.extend({ phase: external_exports.string().nullish() });
42524
+ var agentMessageSchema = textSchema.extend({
42525
+ id: external_exports.string().optional(),
42526
+ phase: external_exports.string().nullish(),
42527
+ type: external_exports.literal("agentMessage")
42528
+ });
42478
42529
  var reasoningSchema = external_exports.object({
42479
42530
  id: external_exports.string(),
42480
42531
  summary: external_exports.array(external_exports.string()).max(1e4),
42481
- content: external_exports.array(external_exports.string()).max(1e4)
42532
+ content: external_exports.array(external_exports.string()).max(1e4),
42533
+ type: external_exports.literal("reasoning")
42482
42534
  });
42483
42535
  var commandExecutionSchema = external_exports.object({
42484
42536
  id: external_exports.string(),
@@ -42487,8 +42539,45 @@ var commandExecutionSchema = external_exports.object({
42487
42539
  status: external_exports.string(),
42488
42540
  commandActions: external_exports.array(external_exports.object({ type: external_exports.string() }).passthrough()).max(100),
42489
42541
  aggregatedOutput: external_exports.string().nullish(),
42490
- exitCode: external_exports.number().int().nullish()
42542
+ exitCode: external_exports.number().int().nullish(),
42543
+ type: external_exports.literal("commandExecution")
42544
+ });
42545
+ var fileChangeSchema = external_exports.object({
42546
+ changes: external_exports.array(external_exports.object({ diff: external_exports.string(), path: external_exports.string() })).max(1e4),
42547
+ id: external_exports.string(),
42548
+ status: external_exports.string(),
42549
+ type: external_exports.literal("fileChange")
42550
+ });
42551
+ var mcpToolCallSchema = external_exports.object({
42552
+ arguments: external_exports.unknown().optional(),
42553
+ error: external_exports.unknown().nullish(),
42554
+ id: external_exports.string(),
42555
+ result: external_exports.unknown().nullish(),
42556
+ server: external_exports.string(),
42557
+ status: external_exports.string(),
42558
+ tool: external_exports.string(),
42559
+ type: external_exports.literal("mcpToolCall")
42491
42560
  });
42561
+ var dynamicToolCallSchema = external_exports.object({
42562
+ arguments: external_exports.unknown().optional(),
42563
+ contentItems: external_exports.array(external_exports.unknown()).max(1e4).nullish(),
42564
+ id: external_exports.string(),
42565
+ namespace: external_exports.string().nullish(),
42566
+ status: external_exports.string(),
42567
+ tool: external_exports.string(),
42568
+ type: external_exports.literal("dynamicToolCall")
42569
+ });
42570
+ var planSchema = external_exports.object({ id: external_exports.string(), text: external_exports.string(), type: external_exports.literal("plan") });
42571
+ var historyItemSchema = external_exports.discriminatedUnion("type", [
42572
+ userMessageSchema,
42573
+ agentMessageSchema,
42574
+ reasoningSchema,
42575
+ commandExecutionSchema,
42576
+ fileChangeSchema,
42577
+ mcpToolCallSchema,
42578
+ dynamicToolCallSchema,
42579
+ planSchema
42580
+ ]);
42492
42581
  function bounded(value, maximum) {
42493
42582
  return value.slice(0, maximum);
42494
42583
  }
@@ -42519,6 +42608,33 @@ function errorMessage(value) {
42519
42608
  }
42520
42609
  return JSON.stringify(value) ?? "Codex stopped before completing this turn.";
42521
42610
  }
42611
+ function formatted(value) {
42612
+ if (value === void 0) {
42613
+ return "";
42614
+ }
42615
+ if (typeof value === "string") {
42616
+ return value;
42617
+ }
42618
+ return JSON.stringify(value) ?? "";
42619
+ }
42620
+ function toolStatus(status) {
42621
+ return status === "inProgress" ? "running" : status === "completed" ? "completed" : "failed";
42622
+ }
42623
+ function diffDisplayContent(path3, newText) {
42624
+ return {
42625
+ artifactId: "",
42626
+ data: "",
42627
+ mimeType: "",
42628
+ name: "",
42629
+ newText,
42630
+ oldText: "",
42631
+ path: path3,
42632
+ terminalId: "",
42633
+ text: "",
42634
+ type: "diff",
42635
+ uri: ""
42636
+ };
42637
+ }
42522
42638
  function messageSize(message) {
42523
42639
  return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
42524
42640
  }
@@ -42556,8 +42672,8 @@ function fitActivities(activities, maximumCharacters) {
42556
42672
  const maximumActivityCharacters = Math.floor(Math.max(0, maximumCharacters - arrayCharacters) / activities.length);
42557
42673
  return activities.map((activity2) => fitActivity(activity2, maximumActivityCharacters));
42558
42674
  }
42559
- function fitHistoryMessage(message) {
42560
- const text2 = message.text.slice(-SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT);
42675
+ function fitHistoryMessage(message, maximumCharacters = SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT) {
42676
+ const text2 = message.text.slice(-maximumCharacters);
42561
42677
  if (message.role === "user") {
42562
42678
  return {
42563
42679
  message: { ...message, text: text2 },
@@ -42567,12 +42683,12 @@ function fitHistoryMessage(message) {
42567
42683
  let activities = message.activities;
42568
42684
  const content = message.content;
42569
42685
  let fitted = { ...message, activities, content, text: text2 };
42570
- if (messageSize(fitted) > SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT && activities.length > 0) {
42571
- const maximumCharacters = SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT - text2.length - JSON.stringify(content).length;
42572
- activities = fitActivities(activities, maximumCharacters);
42686
+ if (messageSize(fitted) > maximumCharacters && activities.length > 0) {
42687
+ const maximumActivityCharacters = maximumCharacters - text2.length - JSON.stringify(content).length;
42688
+ activities = fitActivities(activities, maximumActivityCharacters);
42573
42689
  fitted = { ...fitted, activities };
42574
42690
  }
42575
- const excess = Math.max(0, messageSize(fitted) - SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT);
42691
+ const excess = Math.max(0, messageSize(fitted) - maximumCharacters);
42576
42692
  if (excess > 0) {
42577
42693
  const maximumTextLength = Math.max(0, fitted.text.length - excess);
42578
42694
  fitted = {
@@ -42610,128 +42726,209 @@ function decodeHistory(thread, value, options) {
42610
42726
  let truncated = page.nextCursor != null;
42611
42727
  for (const turn of page.data.toReversed()) {
42612
42728
  const outcome = turnOutcome(turn.status);
42613
- const activities = [];
42614
- let assignedActivityCount = 0;
42729
+ const turnMessageCharacterLimit = Math.max(
42730
+ 1,
42731
+ Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / Math.max(1, turn.items.length + (turn.error == null ? 0 : 1)))
42732
+ );
42615
42733
  let sequence = 0;
42616
42734
  let assistantMessageIndex = null;
42617
- const activitySlice = () => {
42618
- const assigned = activities.slice(assignedActivityCount).slice(-100);
42619
- assignedActivityCount = activities.length;
42620
- return assigned;
42735
+ const append = (message) => {
42736
+ const fitted = fitHistoryMessage(message, turnMessageCharacterLimit);
42737
+ if (fitted.message.text.length === 0 && (fitted.message.images?.length ?? 0) === 0 && (fitted.message.role === "user" || fitted.message.activities.length === 0 && fitted.message.content.length === 0)) {
42738
+ return;
42739
+ }
42740
+ truncated ||= fitted.truncated;
42741
+ messages.push(fitted.message);
42742
+ if (fitted.message.role === "assistant") {
42743
+ assistantMessageIndex = messages.length - 1;
42744
+ }
42745
+ characters += messageSize(fitted.message);
42621
42746
  };
42622
42747
  for (const item of turn.items) {
42623
- const { type } = itemTypeSchema.parse(item);
42624
- let message;
42625
- if (type === "userMessage") {
42626
- const { content } = userMessageSchema.parse(item);
42627
- const text2 = content.map((block) => {
42628
- const { type: type2 } = itemTypeSchema.parse(block);
42629
- if (type2 === "text") {
42748
+ const decoded = historyItemSchema.safeParse(item);
42749
+ if (!decoded.success) {
42750
+ continue;
42751
+ }
42752
+ const historyItem = decoded.data;
42753
+ if (historyItem.type === "userMessage") {
42754
+ const text2 = historyItem.content.map((block) => {
42755
+ const { type } = itemTypeSchema.parse(block);
42756
+ if (type === "text") {
42630
42757
  return textSchema.parse(block).text;
42631
42758
  }
42632
- if (type2 === "image") {
42759
+ if (type === "image") {
42633
42760
  return `[@image](${imageSchema.parse(block).url})`;
42634
42761
  }
42635
42762
  return "[Attachment]";
42636
42763
  }).join("");
42637
- message = {
42764
+ append({
42638
42765
  role: "user",
42639
42766
  text: text2
42640
- };
42641
- } else if (type === "agentMessage") {
42642
- const agent = agentMessageSchema.parse(item);
42643
- if (agent.phase === "commentary") {
42644
- if (options.detail === "rich" && agent.text.length > 0) {
42645
- activities.push(
42646
- activity(`progress-${sequence.toString()}`, "progress", sequence, {
42767
+ });
42768
+ } else if (historyItem.type === "agentMessage") {
42769
+ if (historyItem.phase === "commentary") {
42770
+ if (options.detail === "rich" && historyItem.text.length > 0) {
42771
+ append({
42772
+ activities: [
42773
+ activity(historyItem.id ?? `progress-${sequence.toString()}`, "progress", sequence, {
42774
+ input: "",
42775
+ locations: [],
42776
+ name: "",
42777
+ output: historyItem.text,
42778
+ status: "completed",
42779
+ title: "Progress",
42780
+ toolKind: ""
42781
+ })
42782
+ ],
42783
+ content: [],
42784
+ role: "assistant",
42785
+ text: ""
42786
+ });
42787
+ sequence += 1;
42788
+ }
42789
+ continue;
42790
+ }
42791
+ append({ activities: [], content: [], role: "assistant", text: historyItem.text });
42792
+ } else if (historyItem.type === "reasoning" && options.detail === "rich") {
42793
+ const output2 = (historyItem.summary.length > 0 ? historyItem.summary : historyItem.content).join(
42794
+ "\n\n"
42795
+ );
42796
+ if (output2.length > 0) {
42797
+ append({
42798
+ activities: [
42799
+ activity(historyItem.id, "reasoning", sequence, {
42647
42800
  input: "",
42648
42801
  locations: [],
42649
42802
  name: "",
42650
- output: agent.text,
42803
+ output: output2,
42651
42804
  status: "completed",
42652
- title: "Progress",
42805
+ title: "Reasoning",
42653
42806
  toolKind: ""
42654
42807
  })
42655
- );
42656
- sequence += 1;
42657
- }
42658
- continue;
42808
+ ],
42809
+ content: [],
42810
+ role: "assistant",
42811
+ text: ""
42812
+ });
42813
+ sequence += 1;
42659
42814
  }
42660
- message = { activities: activitySlice(), content: [], role: "assistant", text: agent.text };
42661
- } else if (type === "reasoning" && options.detail === "rich") {
42662
- const reasoning = reasoningSchema.parse(item);
42663
- const output2 = (reasoning.summary.length > 0 ? reasoning.summary : reasoning.content).join("\n\n");
42664
- if (output2.length > 0) {
42665
- activities.push(
42666
- activity(reasoning.id, "reasoning", sequence, {
42815
+ } else if (historyItem.type === "commandExecution" && options.detail === "rich") {
42816
+ const action = historyItem.commandActions[0]?.type ?? "execute";
42817
+ append({
42818
+ activities: [
42819
+ activity(historyItem.id, "tool", sequence, {
42820
+ input: JSON.stringify({ command: historyItem.command, cwd: historyItem.cwd }),
42821
+ locations: [historyItem.cwd],
42822
+ name: "",
42823
+ output: JSON.stringify({
42824
+ formatted_output: historyItem.aggregatedOutput ?? "",
42825
+ ...historyItem.exitCode == null ? {} : { exit_code: historyItem.exitCode }
42826
+ }),
42827
+ status: toolStatus(historyItem.status),
42828
+ title: historyItem.command,
42829
+ toolKind: action
42830
+ })
42831
+ ],
42832
+ content: [],
42833
+ role: "assistant",
42834
+ text: ""
42835
+ });
42836
+ sequence += 1;
42837
+ } else if (historyItem.type === "fileChange" && options.detail === "rich") {
42838
+ const paths = historyItem.changes.map((change) => change.path);
42839
+ const content = historyItem.changes.map(
42840
+ (change) => diffDisplayContent(change.path, change.diff)
42841
+ );
42842
+ append({
42843
+ activities: [
42844
+ activity(historyItem.id, "tool", sequence, {
42845
+ input: JSON.stringify({ changes: paths }),
42846
+ locations: paths,
42847
+ name: "",
42848
+ output: "",
42849
+ status: toolStatus(historyItem.status),
42850
+ title: paths.join(", "),
42851
+ toolKind: "edit"
42852
+ })
42853
+ ].map((entry) => ({ ...entry, content })),
42854
+ content: [],
42855
+ role: "assistant",
42856
+ text: ""
42857
+ });
42858
+ sequence += 1;
42859
+ } else if (historyItem.type === "mcpToolCall" && options.detail === "rich") {
42860
+ append({
42861
+ activities: [
42862
+ activity(historyItem.id, "tool", sequence, {
42863
+ input: formatted(historyItem.arguments),
42864
+ locations: [],
42865
+ name: historyItem.tool,
42866
+ output: formatted(historyItem.error ?? historyItem.result),
42867
+ status: toolStatus(historyItem.status),
42868
+ title: `${historyItem.server}/${historyItem.tool}`,
42869
+ toolKind: "other"
42870
+ })
42871
+ ],
42872
+ content: [],
42873
+ role: "assistant",
42874
+ text: ""
42875
+ });
42876
+ sequence += 1;
42877
+ } else if (historyItem.type === "dynamicToolCall" && options.detail === "rich") {
42878
+ append({
42879
+ activities: [
42880
+ activity(historyItem.id, "tool", sequence, {
42881
+ input: formatted(historyItem.arguments),
42882
+ locations: [],
42883
+ name: historyItem.tool,
42884
+ output: formatted(historyItem.contentItems),
42885
+ status: toolStatus(historyItem.status),
42886
+ title: historyItem.namespace == null ? historyItem.tool : `${historyItem.namespace}/${historyItem.tool}`,
42887
+ toolKind: "other"
42888
+ })
42889
+ ],
42890
+ content: [],
42891
+ role: "assistant",
42892
+ text: ""
42893
+ });
42894
+ sequence += 1;
42895
+ } else if (historyItem.type === "plan" && options.detail === "rich") {
42896
+ append({
42897
+ activities: [
42898
+ activity(historyItem.id, "plan", sequence, {
42667
42899
  input: "",
42668
42900
  locations: [],
42669
42901
  name: "",
42670
- output: output2,
42902
+ output: historyItem.text,
42671
42903
  status: "completed",
42672
- title: "Reasoning",
42904
+ title: "Plan",
42673
42905
  toolKind: ""
42674
42906
  })
42675
- );
42676
- sequence += 1;
42677
- }
42678
- continue;
42679
- } else if (type === "commandExecution" && options.detail === "rich") {
42680
- const command = commandExecutionSchema.parse(item);
42681
- const action = command.commandActions[0]?.type ?? "execute";
42682
- activities.push(
42683
- activity(command.id, "tool", sequence, {
42684
- input: JSON.stringify({ command: command.command, cwd: command.cwd }),
42685
- locations: [command.cwd],
42686
- name: "",
42687
- output: JSON.stringify({
42688
- formatted_output: command.aggregatedOutput ?? "",
42689
- ...command.exitCode == null ? {} : { exit_code: command.exitCode }
42690
- }),
42691
- status: command.status === "completed" ? "completed" : "failed",
42692
- title: command.command,
42693
- toolKind: action
42694
- })
42695
- );
42907
+ ],
42908
+ content: [],
42909
+ role: "assistant",
42910
+ text: ""
42911
+ });
42696
42912
  sequence += 1;
42697
- continue;
42698
- } else {
42699
- continue;
42700
42913
  }
42701
- const fitted = fitHistoryMessage(message);
42702
- if (fitted.message.text.length === 0 && (fitted.message.images?.length ?? 0) === 0) {
42703
- continue;
42704
- }
42705
- truncated ||= fitted.truncated;
42706
- messages.push(fitted.message);
42707
- if (message.role === "assistant") {
42708
- assistantMessageIndex = messages.length - 1;
42709
- }
42710
- characters += messageSize(fitted.message);
42711
42914
  }
42712
42915
  if (options.detail === "rich" && turn.error != null) {
42713
- activities.push(
42714
- activity(`agent-error-${sequence.toString()}`, "tool", sequence, {
42715
- input: "",
42716
- locations: [],
42717
- name: "",
42718
- output: errorMessage(turn.error),
42719
- status: "failed",
42720
- title: "Agent error",
42721
- toolKind: "other"
42722
- })
42723
- );
42724
- }
42725
- if (options.detail === "rich" && activities.length > assignedActivityCount) {
42726
- const message = {
42727
- activities: activitySlice(),
42916
+ append({
42917
+ activities: [
42918
+ activity(`agent-error-${sequence.toString()}`, "tool", sequence, {
42919
+ input: "",
42920
+ locations: [],
42921
+ name: "",
42922
+ output: errorMessage(turn.error),
42923
+ status: "failed",
42924
+ title: "Agent error",
42925
+ toolKind: "other"
42926
+ })
42927
+ ],
42728
42928
  content: [],
42729
42929
  role: "assistant",
42730
42930
  text: ""
42731
- };
42732
- messages.push(message);
42733
- assistantMessageIndex = messages.length - 1;
42734
- characters += messageSize(message);
42931
+ });
42735
42932
  }
42736
42933
  if (assistantMessageIndex !== null) {
42737
42934
  const assistant = messages[assistantMessageIndex];
@@ -42741,20 +42938,20 @@ function decodeHistory(thread, value, options) {
42741
42938
  ...assistant,
42742
42939
  ...outcome === void 0 ? {} : { outcome }
42743
42940
  };
42744
- const fitted = fitHistoryMessage(updated);
42941
+ const fitted = fitHistoryMessage(updated, turnMessageCharacterLimit);
42745
42942
  truncated ||= fitted.truncated;
42746
42943
  messages[assistantMessageIndex] = fitted.message;
42747
42944
  characters += messageSize(fitted.message);
42748
42945
  }
42749
- } else if (activities.length > 0 || outcome !== void 0) {
42946
+ } else if (outcome !== void 0) {
42750
42947
  const message = {
42751
- activities: activities.slice(-100),
42948
+ activities: [],
42752
42949
  content: [],
42753
42950
  role: "assistant",
42754
42951
  ...outcome === void 0 ? {} : { outcome },
42755
42952
  text: ""
42756
42953
  };
42757
- const fitted = fitHistoryMessage(message);
42954
+ const fitted = fitHistoryMessage(message, turnMessageCharacterLimit);
42758
42955
  truncated ||= fitted.truncated;
42759
42956
  messages.push(fitted.message);
42760
42957
  characters += messageSize(fitted.message);
@@ -44622,6 +44819,14 @@ function boundedActiveMessages(messages, messageLimit, characterLimit) {
44622
44819
  truncated: selected.length !== messages.length
44623
44820
  };
44624
44821
  }
44822
+ function nativeActiveMessage(message) {
44823
+ return message.role === "user" ? { role: "user", text: message.text } : {
44824
+ activities: message.activities,
44825
+ content: message.content,
44826
+ role: "assistant",
44827
+ text: message.text
44828
+ };
44829
+ }
44625
44830
  function paginateAcpSessionHistory(history, sessionId, cursor, limit) {
44626
44831
  if (history.status === "unavailable") {
44627
44832
  if (cursor !== null) {
@@ -44654,20 +44859,27 @@ function paginateLiveSessionHistory(history, activeTurn, sessionId, cursor, limi
44654
44859
  }
44655
44860
  if (history.status === "unavailable") {
44656
44861
  const bounded3 = boundedActiveMessages(
44657
- activeTurn.messages,
44658
- Math.max(0, limit - 1),
44659
- Math.max(0, SESSION_HISTORY_CHARACTER_LIMIT - activeTurn.prompt.length)
44862
+ activeTurn.messages.map(nativeActiveMessage),
44863
+ limit,
44864
+ SESSION_HISTORY_CHARACTER_LIMIT
44660
44865
  );
44661
44866
  return {
44662
44867
  coveredCommandIds: [],
44663
44868
  coveredMessageIds: [],
44664
- messages: [{ role: "user", text: activeTurn.prompt }, ...bounded3.messages],
44869
+ messages: bounded3.messages,
44665
44870
  nextCursor: null,
44666
44871
  status: "available",
44667
44872
  truncated: activeTurn.truncated || bounded3.truncated
44668
44873
  };
44669
44874
  }
44670
- const activeUserIndex = history.coveredCommandIds.includes(activeTurn.commandId) ? history.messages.findLastIndex((message) => message.role === "user") : -1;
44875
+ const activeRoot = activeTurn.messages.find(
44876
+ (message) => message.role === "user" && message.id === activeTurn.commandId
44877
+ );
44878
+ const coveredActiveRoot = history.coveredCommandIds.includes(activeTurn.commandId);
44879
+ const matchingActiveUserIndex = coveredActiveRoot ? history.messages.findLastIndex(
44880
+ (message) => message.role === "user" && message.text === (activeRoot?.text ?? activeTurn.prompt)
44881
+ ) : -1;
44882
+ const activeUserIndex = matchingActiveUserIndex >= 0 ? matchingActiveUserIndex : liveHistoryCoveredTurnRanges(history).find((range) => range.commandId === activeTurn.commandId)?.userIndex ?? -1;
44671
44883
  if (activeUserIndex >= 0) {
44672
44884
  history = {
44673
44885
  ...history,
@@ -44679,19 +44891,13 @@ function paginateLiveSessionHistory(history, activeTurn, sessionId, cursor, limi
44679
44891
  };
44680
44892
  }
44681
44893
  const latestNativeMessage = history.messages.at(-1);
44682
- const includeActivePrompt = activeUserIndex < 0 && !(latestNativeMessage?.role === "user" && latestNativeMessage.text === activeTurn.prompt);
44683
- const bounded2 = boundedActiveMessages(
44684
- activeTurn.messages,
44685
- Math.max(0, limit - (includeActivePrompt ? 1 : 0)),
44686
- Math.max(0, SESSION_HISTORY_CHARACTER_LIMIT - (includeActivePrompt ? activeTurn.prompt.length : 0))
44687
- );
44688
- const activeMessages = [
44689
- ...includeActivePrompt ? [{ role: "user", text: activeTurn.prompt }] : [],
44690
- ...bounded2.messages
44691
- ];
44894
+ const firstActiveMessage = activeTurn.messages[0];
44895
+ const preserveNativeRoot = activeUserIndex >= 0 || firstActiveMessage?.role === "user" && latestNativeMessage?.role === "user" && latestNativeMessage.text === firstActiveMessage.text;
44896
+ const activeMessages = activeTurn.messages.slice(preserveNativeRoot ? 1 : 0).map(nativeActiveMessage);
44897
+ const bounded2 = boundedActiveMessages(activeMessages, limit, SESSION_HISTORY_CHARACTER_LIMIT);
44692
44898
  let historicalMessageCount = 0;
44693
- let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT - bounded2.characters - (includeActivePrompt ? activeTurn.prompt.length : 0);
44694
- const historicalMessageLimit = Math.max(0, limit - activeMessages.length);
44899
+ let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT - bounded2.characters;
44900
+ const historicalMessageLimit = Math.max(0, limit - bounded2.messages.length);
44695
44901
  for (let index = history.messages.length - 1; index >= 0 && historicalMessageCount < historicalMessageLimit; index -= 1) {
44696
44902
  const message = history.messages[index];
44697
44903
  if (message === void 0) {
@@ -44714,7 +44920,7 @@ function paginateLiveSessionHistory(history, activeTurn, sessionId, cursor, limi
44714
44920
  } : paginateAcpSessionHistory(history, sessionId, null, historicalMessageCount);
44715
44921
  return {
44716
44922
  ...page,
44717
- messages: [...page.messages, ...activeMessages],
44923
+ messages: [...page.messages, ...bounded2.messages],
44718
44924
  truncated: page.truncated || activeTurn.truncated || bounded2.truncated
44719
44925
  };
44720
44926
  }
@@ -45165,6 +45371,7 @@ async function executePrompt({
45165
45371
  timer,
45166
45372
  signal,
45167
45373
  recordLiveEvent,
45374
+ recordSteeringPrompt,
45168
45375
  cancellationRequested
45169
45376
  }) {
45170
45377
  const events = new CoalescingAgentEventPublisher(timer, (event) => {
@@ -45245,6 +45452,17 @@ async function executePrompt({
45245
45452
  sessionId: command.sessionId
45246
45453
  });
45247
45454
  operations.transitionExecution(command.commandId, "running");
45455
+ if (availability.disposition === SessionPromptDisposition.Steer) {
45456
+ const updated = recordSteeringPrompt();
45457
+ if (updated === null) {
45458
+ throw new AcpExecutionError(
45459
+ "The steering target is unavailable",
45460
+ {},
45461
+ "prompt_queue_target_unavailable"
45462
+ );
45463
+ }
45464
+ publisher.publish(command.sessionId, updated);
45465
+ }
45248
45466
  const stream = activateAttempt();
45249
45467
  publisher.publish(command.sessionId, {
45250
45468
  commandId: command.commandId,
@@ -45864,6 +46082,7 @@ function createDaemonCommandHandler({
45864
46082
  timer,
45865
46083
  signal: turn.signal,
45866
46084
  recordLiveEvent: turn.recordEvent,
46085
+ recordSteeringPrompt: () => activeTurns.recordSteeringPrompt(command),
45867
46086
  cancellationRequested: turn.cancellationRequested
45868
46087
  }).catch((error62) => {
45869
46088
  console.error("Mobius daemon turn failed", error62);