@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/index.js CHANGED
@@ -21026,6 +21026,23 @@ var activeTurnActivitySchema = external_exports.strictObject({
21026
21026
  title: external_exports.string().max(500),
21027
21027
  toolKind: external_exports.string().max(64)
21028
21028
  }).readonly();
21029
+ var activeTurnUserMessageSchema = external_exports.strictObject({
21030
+ id: identifierStringSchema,
21031
+ images: external_exports.array(promptImageSchema).max(8).readonly().optional(),
21032
+ role: external_exports.literal("user"),
21033
+ text: external_exports.string().max(SESSION_HISTORY_CHARACTER_LIMIT)
21034
+ }).readonly();
21035
+ var activeTurnAssistantMessageSchema = external_exports.strictObject({
21036
+ activities: external_exports.array(activeTurnActivitySchema).max(100).readonly().default([]),
21037
+ content: external_exports.array(displayContentSchema).max(100).readonly().default([]),
21038
+ id: identifierStringSchema,
21039
+ role: external_exports.literal("assistant"),
21040
+ text: external_exports.string().max(SESSION_HISTORY_CHARACTER_LIMIT)
21041
+ }).readonly();
21042
+ var activeTurnMessageSchema = external_exports.discriminatedUnion("role", [
21043
+ activeTurnUserMessageSchema,
21044
+ activeTurnAssistantMessageSchema
21045
+ ]);
21029
21046
  var activeTurnSnapshotSchema = external_exports.strictObject({
21030
21047
  activities: external_exports.array(activeTurnActivitySchema).readonly(),
21031
21048
  commandId: identifierStringSchema,
@@ -21035,7 +21052,7 @@ var activeTurnSnapshotSchema = external_exports.strictObject({
21035
21052
  truncated: external_exports.boolean(),
21036
21053
  epoch: identifierStringSchema,
21037
21054
  interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
21038
- messages: external_exports.array(assistantHistoryMessageSchema).max(SESSION_HISTORY_MESSAGE_LIMIT).readonly(),
21055
+ messages: external_exports.array(activeTurnMessageSchema).max(SESSION_HISTORY_MESSAGE_LIMIT).readonly(),
21039
21056
  sequence: external_exports.number().int().nonnegative(),
21040
21057
  state: external_exports.literal("running")
21041
21058
  }).readonly();
@@ -38658,7 +38675,7 @@ var ActiveDaemonTurn = class {
38658
38675
  #text = "";
38659
38676
  #activities = /* @__PURE__ */ new Map();
38660
38677
  #content = /* @__PURE__ */ new Map();
38661
- #timeline = [];
38678
+ #timeline;
38662
38679
  #sequence = 0;
38663
38680
  #interaction = null;
38664
38681
  #epoch = decodeIdentifier(randomUUID2());
@@ -38667,6 +38684,9 @@ var ActiveDaemonTurn = class {
38667
38684
  this.command = command;
38668
38685
  this.#controller = new AbortController();
38669
38686
  this.#dispatch = { kind: "pending" };
38687
+ this.#timeline = [
38688
+ { id: decodeIdentifier(command.commandId), images: command.images, kind: "user", text: command.prompt }
38689
+ ];
38670
38690
  }
38671
38691
  enqueue = () => {
38672
38692
  if (this.#dispatch.kind !== "pending") {
@@ -38710,7 +38730,10 @@ var ActiveDaemonTurn = class {
38710
38730
  }
38711
38731
  if (event.kind === AGENT_ACTIVITY_KIND) {
38712
38732
  if (!this.#activities.has(event.activityId)) {
38713
- this.#timeline = [...this.#timeline, { activityId: event.activityId, kind: "activity" }];
38733
+ this.#timeline = [
38734
+ ...this.#timeline,
38735
+ { activityId: event.activityId, id: decodeIdentifier(randomUUID2()), kind: "activity" }
38736
+ ];
38714
38737
  }
38715
38738
  this.#activities.set(event.activityId, {
38716
38739
  activityId: event.activityId,
@@ -38728,7 +38751,10 @@ var ActiveDaemonTurn = class {
38728
38751
  } else if (event.kind === AGENT_ACTIVITY_NARRATION_KIND) {
38729
38752
  const previous = this.#activities.get(event.activityId);
38730
38753
  if (previous === void 0) {
38731
- this.#timeline = [...this.#timeline, { activityId: event.activityId, kind: "activity" }];
38754
+ this.#timeline = [
38755
+ ...this.#timeline,
38756
+ { activityId: event.activityId, id: decodeIdentifier(randomUUID2()), kind: "activity" }
38757
+ ];
38732
38758
  }
38733
38759
  this.#activities.set(event.activityId, {
38734
38760
  activityId: event.activityId,
@@ -38746,15 +38772,16 @@ var ActiveDaemonTurn = class {
38746
38772
  } else if (event.kind === AGENT_CONTENT_KIND) {
38747
38773
  this.#content.set(event.contentId, event.content);
38748
38774
  const target = this.#timeline.findLastIndex(
38749
- (entry) => entry.kind === "message" && entry.messageId === event.messageId
38775
+ (entry) => entry.kind === "message" && entry.sourceMessageId === event.messageId
38750
38776
  );
38751
38777
  if (target < 0) {
38752
38778
  this.#timeline = [
38753
38779
  ...this.#timeline,
38754
38780
  {
38755
38781
  content: /* @__PURE__ */ new Map([[event.contentId, event.content]]),
38782
+ id: decodeIdentifier(randomUUID2()),
38756
38783
  kind: "message",
38757
- messageId: event.messageId,
38784
+ sourceMessageId: event.messageId,
38758
38785
  text: ""
38759
38786
  }
38760
38787
  ];
@@ -38777,7 +38804,7 @@ var ActiveDaemonTurn = class {
38777
38804
  let remaining = text2;
38778
38805
  while (remaining.length > 0) {
38779
38806
  const latest = this.#timeline.at(-1);
38780
- if (latest?.kind === "message" && latest.messageId === messageId) {
38807
+ if (latest?.kind === "message" && latest.sourceMessageId === messageId) {
38781
38808
  const available = SESSION_HISTORY_CHARACTER_LIMIT - latest.text.length;
38782
38809
  if (available > 0) {
38783
38810
  this.#timeline = [
@@ -38792,28 +38819,43 @@ var ActiveDaemonTurn = class {
38792
38819
  ...this.#timeline,
38793
38820
  {
38794
38821
  content: /* @__PURE__ */ new Map(),
38822
+ id: decodeIdentifier(randomUUID2()),
38795
38823
  kind: "message",
38796
- messageId,
38824
+ sourceMessageId: messageId,
38797
38825
  text: remaining.slice(0, SESSION_HISTORY_CHARACTER_LIMIT)
38798
38826
  }
38799
38827
  ];
38800
38828
  remaining = remaining.slice(SESSION_HISTORY_CHARACTER_LIMIT);
38801
38829
  }
38802
38830
  }
38831
+ recordSteeringPrompt = (command) => {
38832
+ if (this.#dispatch.kind !== "running" || command.sessionId !== this.command.sessionId || command.targetCommandId !== this.command.commandId) {
38833
+ return null;
38834
+ }
38835
+ this.#timeline = [
38836
+ ...this.#timeline,
38837
+ { id: decodeIdentifier(command.commandId), images: command.images, kind: "user", text: command.prompt }
38838
+ ];
38839
+ return this.updated();
38840
+ };
38803
38841
  timelineMessages() {
38804
38842
  return this.#timeline.flatMap((entry) => {
38843
+ if (entry.kind === "user") {
38844
+ return [{ id: entry.id, images: entry.images, role: "user", text: entry.text }];
38845
+ }
38805
38846
  if (entry.kind === "message") {
38806
38847
  return [
38807
38848
  {
38808
38849
  activities: [],
38809
38850
  content: [...entry.content.values()],
38851
+ id: entry.id,
38810
38852
  role: "assistant",
38811
38853
  text: entry.text
38812
38854
  }
38813
38855
  ];
38814
38856
  }
38815
38857
  const activity2 = this.#activities.get(entry.activityId);
38816
- return activity2 === void 0 ? [] : [{ activities: [activity2], content: [], role: "assistant", text: "" }];
38858
+ return activity2 === void 0 ? [] : [{ activities: [activity2], content: [], id: entry.id, role: "assistant", text: "" }];
38817
38859
  });
38818
38860
  }
38819
38861
  updated = () => {
@@ -38923,6 +38965,10 @@ var DaemonTurnRegistry = class {
38923
38965
  }
38924
38966
  return event;
38925
38967
  };
38968
+ recordSteeringPrompt = (command) => {
38969
+ const target = this.#turns.get(command.targetCommandId);
38970
+ return target?.recordSteeringPrompt(command) ?? null;
38971
+ };
38926
38972
  executionSnapshot = async (matches) => {
38927
38973
  const matching = [];
38928
38974
  for (const turn of this.#turns.values()) {
@@ -39029,15 +39075,21 @@ var turnsSchema = external_exports.object({
39029
39075
  });
39030
39076
  var itemTypeSchema = external_exports.object({ type: external_exports.string().min(1).max(80) });
39031
39077
  var userMessageSchema = external_exports.object({
39032
- content: external_exports.array(external_exports.unknown()).max(1e4)
39078
+ content: external_exports.array(external_exports.unknown()).max(1e4),
39079
+ type: external_exports.literal("userMessage")
39033
39080
  });
39034
39081
  var textSchema = external_exports.object({ text: external_exports.string() });
39035
39082
  var imageSchema = external_exports.object({ url: external_exports.string() });
39036
- var agentMessageSchema = textSchema.extend({ phase: external_exports.string().nullish() });
39083
+ var agentMessageSchema = textSchema.extend({
39084
+ id: external_exports.string().optional(),
39085
+ phase: external_exports.string().nullish(),
39086
+ type: external_exports.literal("agentMessage")
39087
+ });
39037
39088
  var reasoningSchema = external_exports.object({
39038
39089
  id: external_exports.string(),
39039
39090
  summary: external_exports.array(external_exports.string()).max(1e4),
39040
- content: external_exports.array(external_exports.string()).max(1e4)
39091
+ content: external_exports.array(external_exports.string()).max(1e4),
39092
+ type: external_exports.literal("reasoning")
39041
39093
  });
39042
39094
  var commandExecutionSchema = external_exports.object({
39043
39095
  id: external_exports.string(),
@@ -39046,8 +39098,45 @@ var commandExecutionSchema = external_exports.object({
39046
39098
  status: external_exports.string(),
39047
39099
  commandActions: external_exports.array(external_exports.object({ type: external_exports.string() }).passthrough()).max(100),
39048
39100
  aggregatedOutput: external_exports.string().nullish(),
39049
- exitCode: external_exports.number().int().nullish()
39101
+ exitCode: external_exports.number().int().nullish(),
39102
+ type: external_exports.literal("commandExecution")
39050
39103
  });
39104
+ var fileChangeSchema = external_exports.object({
39105
+ changes: external_exports.array(external_exports.object({ diff: external_exports.string(), path: external_exports.string() })).max(1e4),
39106
+ id: external_exports.string(),
39107
+ status: external_exports.string(),
39108
+ type: external_exports.literal("fileChange")
39109
+ });
39110
+ var mcpToolCallSchema = external_exports.object({
39111
+ arguments: external_exports.unknown().optional(),
39112
+ error: external_exports.unknown().nullish(),
39113
+ id: external_exports.string(),
39114
+ result: external_exports.unknown().nullish(),
39115
+ server: external_exports.string(),
39116
+ status: external_exports.string(),
39117
+ tool: external_exports.string(),
39118
+ type: external_exports.literal("mcpToolCall")
39119
+ });
39120
+ var dynamicToolCallSchema = external_exports.object({
39121
+ arguments: external_exports.unknown().optional(),
39122
+ contentItems: external_exports.array(external_exports.unknown()).max(1e4).nullish(),
39123
+ id: external_exports.string(),
39124
+ namespace: external_exports.string().nullish(),
39125
+ status: external_exports.string(),
39126
+ tool: external_exports.string(),
39127
+ type: external_exports.literal("dynamicToolCall")
39128
+ });
39129
+ var planSchema = external_exports.object({ id: external_exports.string(), text: external_exports.string(), type: external_exports.literal("plan") });
39130
+ var historyItemSchema = external_exports.discriminatedUnion("type", [
39131
+ userMessageSchema,
39132
+ agentMessageSchema,
39133
+ reasoningSchema,
39134
+ commandExecutionSchema,
39135
+ fileChangeSchema,
39136
+ mcpToolCallSchema,
39137
+ dynamicToolCallSchema,
39138
+ planSchema
39139
+ ]);
39051
39140
  function bounded(value, maximum) {
39052
39141
  return value.slice(0, maximum);
39053
39142
  }
@@ -39078,6 +39167,33 @@ function errorMessage(value) {
39078
39167
  }
39079
39168
  return JSON.stringify(value) ?? "Codex stopped before completing this turn.";
39080
39169
  }
39170
+ function formatted(value) {
39171
+ if (value === void 0) {
39172
+ return "";
39173
+ }
39174
+ if (typeof value === "string") {
39175
+ return value;
39176
+ }
39177
+ return JSON.stringify(value) ?? "";
39178
+ }
39179
+ function toolStatus(status) {
39180
+ return status === "inProgress" ? "running" : status === "completed" ? "completed" : "failed";
39181
+ }
39182
+ function diffDisplayContent(path2, newText) {
39183
+ return {
39184
+ artifactId: "",
39185
+ data: "",
39186
+ mimeType: "",
39187
+ name: "",
39188
+ newText,
39189
+ oldText: "",
39190
+ path: path2,
39191
+ terminalId: "",
39192
+ text: "",
39193
+ type: "diff",
39194
+ uri: ""
39195
+ };
39196
+ }
39081
39197
  function messageSize(message) {
39082
39198
  return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
39083
39199
  }
@@ -39115,8 +39231,8 @@ function fitActivities(activities, maximumCharacters) {
39115
39231
  const maximumActivityCharacters = Math.floor(Math.max(0, maximumCharacters - arrayCharacters) / activities.length);
39116
39232
  return activities.map((activity2) => fitActivity(activity2, maximumActivityCharacters));
39117
39233
  }
39118
- function fitHistoryMessage(message) {
39119
- const text2 = message.text.slice(-SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT);
39234
+ function fitHistoryMessage(message, maximumCharacters = SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT) {
39235
+ const text2 = message.text.slice(-maximumCharacters);
39120
39236
  if (message.role === "user") {
39121
39237
  return {
39122
39238
  message: { ...message, text: text2 },
@@ -39126,12 +39242,12 @@ function fitHistoryMessage(message) {
39126
39242
  let activities = message.activities;
39127
39243
  const content = message.content;
39128
39244
  let fitted = { ...message, activities, content, text: text2 };
39129
- if (messageSize(fitted) > SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT && activities.length > 0) {
39130
- const maximumCharacters = SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT - text2.length - JSON.stringify(content).length;
39131
- activities = fitActivities(activities, maximumCharacters);
39245
+ if (messageSize(fitted) > maximumCharacters && activities.length > 0) {
39246
+ const maximumActivityCharacters = maximumCharacters - text2.length - JSON.stringify(content).length;
39247
+ activities = fitActivities(activities, maximumActivityCharacters);
39132
39248
  fitted = { ...fitted, activities };
39133
39249
  }
39134
- const excess = Math.max(0, messageSize(fitted) - SESSION_HISTORY_MESSAGE_CHARACTER_LIMIT);
39250
+ const excess = Math.max(0, messageSize(fitted) - maximumCharacters);
39135
39251
  if (excess > 0) {
39136
39252
  const maximumTextLength = Math.max(0, fitted.text.length - excess);
39137
39253
  fitted = {
@@ -39169,128 +39285,209 @@ function decodeHistory(thread, value, options) {
39169
39285
  let truncated = page.nextCursor != null;
39170
39286
  for (const turn of page.data.toReversed()) {
39171
39287
  const outcome = turnOutcome(turn.status);
39172
- const activities = [];
39173
- let assignedActivityCount = 0;
39288
+ const turnMessageCharacterLimit = Math.max(
39289
+ 1,
39290
+ Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / Math.max(1, turn.items.length + (turn.error == null ? 0 : 1)))
39291
+ );
39174
39292
  let sequence = 0;
39175
39293
  let assistantMessageIndex = null;
39176
- const activitySlice = () => {
39177
- const assigned = activities.slice(assignedActivityCount).slice(-100);
39178
- assignedActivityCount = activities.length;
39179
- return assigned;
39294
+ const append = (message) => {
39295
+ const fitted = fitHistoryMessage(message, turnMessageCharacterLimit);
39296
+ 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)) {
39297
+ return;
39298
+ }
39299
+ truncated ||= fitted.truncated;
39300
+ messages.push(fitted.message);
39301
+ if (fitted.message.role === "assistant") {
39302
+ assistantMessageIndex = messages.length - 1;
39303
+ }
39304
+ characters += messageSize(fitted.message);
39180
39305
  };
39181
39306
  for (const item of turn.items) {
39182
- const { type } = itemTypeSchema.parse(item);
39183
- let message;
39184
- if (type === "userMessage") {
39185
- const { content } = userMessageSchema.parse(item);
39186
- const text2 = content.map((block) => {
39187
- const { type: type2 } = itemTypeSchema.parse(block);
39188
- if (type2 === "text") {
39307
+ const decoded = historyItemSchema.safeParse(item);
39308
+ if (!decoded.success) {
39309
+ continue;
39310
+ }
39311
+ const historyItem = decoded.data;
39312
+ if (historyItem.type === "userMessage") {
39313
+ const text2 = historyItem.content.map((block) => {
39314
+ const { type } = itemTypeSchema.parse(block);
39315
+ if (type === "text") {
39189
39316
  return textSchema.parse(block).text;
39190
39317
  }
39191
- if (type2 === "image") {
39318
+ if (type === "image") {
39192
39319
  return `[@image](${imageSchema.parse(block).url})`;
39193
39320
  }
39194
39321
  return "[Attachment]";
39195
39322
  }).join("");
39196
- message = {
39323
+ append({
39197
39324
  role: "user",
39198
39325
  text: text2
39199
- };
39200
- } else if (type === "agentMessage") {
39201
- const agent = agentMessageSchema.parse(item);
39202
- if (agent.phase === "commentary") {
39203
- if (options.detail === "rich" && agent.text.length > 0) {
39204
- activities.push(
39205
- activity(`progress-${sequence.toString()}`, "progress", sequence, {
39326
+ });
39327
+ } else if (historyItem.type === "agentMessage") {
39328
+ if (historyItem.phase === "commentary") {
39329
+ if (options.detail === "rich" && historyItem.text.length > 0) {
39330
+ append({
39331
+ activities: [
39332
+ activity(historyItem.id ?? `progress-${sequence.toString()}`, "progress", sequence, {
39333
+ input: "",
39334
+ locations: [],
39335
+ name: "",
39336
+ output: historyItem.text,
39337
+ status: "completed",
39338
+ title: "Progress",
39339
+ toolKind: ""
39340
+ })
39341
+ ],
39342
+ content: [],
39343
+ role: "assistant",
39344
+ text: ""
39345
+ });
39346
+ sequence += 1;
39347
+ }
39348
+ continue;
39349
+ }
39350
+ append({ activities: [], content: [], role: "assistant", text: historyItem.text });
39351
+ } else if (historyItem.type === "reasoning" && options.detail === "rich") {
39352
+ const output2 = (historyItem.summary.length > 0 ? historyItem.summary : historyItem.content).join(
39353
+ "\n\n"
39354
+ );
39355
+ if (output2.length > 0) {
39356
+ append({
39357
+ activities: [
39358
+ activity(historyItem.id, "reasoning", sequence, {
39206
39359
  input: "",
39207
39360
  locations: [],
39208
39361
  name: "",
39209
- output: agent.text,
39362
+ output: output2,
39210
39363
  status: "completed",
39211
- title: "Progress",
39364
+ title: "Reasoning",
39212
39365
  toolKind: ""
39213
39366
  })
39214
- );
39215
- sequence += 1;
39216
- }
39217
- continue;
39367
+ ],
39368
+ content: [],
39369
+ role: "assistant",
39370
+ text: ""
39371
+ });
39372
+ sequence += 1;
39218
39373
  }
39219
- message = { activities: activitySlice(), content: [], role: "assistant", text: agent.text };
39220
- } else if (type === "reasoning" && options.detail === "rich") {
39221
- const reasoning = reasoningSchema.parse(item);
39222
- const output2 = (reasoning.summary.length > 0 ? reasoning.summary : reasoning.content).join("\n\n");
39223
- if (output2.length > 0) {
39224
- activities.push(
39225
- activity(reasoning.id, "reasoning", sequence, {
39374
+ } else if (historyItem.type === "commandExecution" && options.detail === "rich") {
39375
+ const action = historyItem.commandActions[0]?.type ?? "execute";
39376
+ append({
39377
+ activities: [
39378
+ activity(historyItem.id, "tool", sequence, {
39379
+ input: JSON.stringify({ command: historyItem.command, cwd: historyItem.cwd }),
39380
+ locations: [historyItem.cwd],
39381
+ name: "",
39382
+ output: JSON.stringify({
39383
+ formatted_output: historyItem.aggregatedOutput ?? "",
39384
+ ...historyItem.exitCode == null ? {} : { exit_code: historyItem.exitCode }
39385
+ }),
39386
+ status: toolStatus(historyItem.status),
39387
+ title: historyItem.command,
39388
+ toolKind: action
39389
+ })
39390
+ ],
39391
+ content: [],
39392
+ role: "assistant",
39393
+ text: ""
39394
+ });
39395
+ sequence += 1;
39396
+ } else if (historyItem.type === "fileChange" && options.detail === "rich") {
39397
+ const paths = historyItem.changes.map((change) => change.path);
39398
+ const content = historyItem.changes.map(
39399
+ (change) => diffDisplayContent(change.path, change.diff)
39400
+ );
39401
+ append({
39402
+ activities: [
39403
+ activity(historyItem.id, "tool", sequence, {
39404
+ input: JSON.stringify({ changes: paths }),
39405
+ locations: paths,
39406
+ name: "",
39407
+ output: "",
39408
+ status: toolStatus(historyItem.status),
39409
+ title: paths.join(", "),
39410
+ toolKind: "edit"
39411
+ })
39412
+ ].map((entry) => ({ ...entry, content })),
39413
+ content: [],
39414
+ role: "assistant",
39415
+ text: ""
39416
+ });
39417
+ sequence += 1;
39418
+ } else if (historyItem.type === "mcpToolCall" && options.detail === "rich") {
39419
+ append({
39420
+ activities: [
39421
+ activity(historyItem.id, "tool", sequence, {
39422
+ input: formatted(historyItem.arguments),
39423
+ locations: [],
39424
+ name: historyItem.tool,
39425
+ output: formatted(historyItem.error ?? historyItem.result),
39426
+ status: toolStatus(historyItem.status),
39427
+ title: `${historyItem.server}/${historyItem.tool}`,
39428
+ toolKind: "other"
39429
+ })
39430
+ ],
39431
+ content: [],
39432
+ role: "assistant",
39433
+ text: ""
39434
+ });
39435
+ sequence += 1;
39436
+ } else if (historyItem.type === "dynamicToolCall" && options.detail === "rich") {
39437
+ append({
39438
+ activities: [
39439
+ activity(historyItem.id, "tool", sequence, {
39440
+ input: formatted(historyItem.arguments),
39441
+ locations: [],
39442
+ name: historyItem.tool,
39443
+ output: formatted(historyItem.contentItems),
39444
+ status: toolStatus(historyItem.status),
39445
+ title: historyItem.namespace == null ? historyItem.tool : `${historyItem.namespace}/${historyItem.tool}`,
39446
+ toolKind: "other"
39447
+ })
39448
+ ],
39449
+ content: [],
39450
+ role: "assistant",
39451
+ text: ""
39452
+ });
39453
+ sequence += 1;
39454
+ } else if (historyItem.type === "plan" && options.detail === "rich") {
39455
+ append({
39456
+ activities: [
39457
+ activity(historyItem.id, "plan", sequence, {
39226
39458
  input: "",
39227
39459
  locations: [],
39228
39460
  name: "",
39229
- output: output2,
39461
+ output: historyItem.text,
39230
39462
  status: "completed",
39231
- title: "Reasoning",
39463
+ title: "Plan",
39232
39464
  toolKind: ""
39233
39465
  })
39234
- );
39235
- sequence += 1;
39236
- }
39237
- continue;
39238
- } else if (type === "commandExecution" && options.detail === "rich") {
39239
- const command = commandExecutionSchema.parse(item);
39240
- const action = command.commandActions[0]?.type ?? "execute";
39241
- activities.push(
39242
- activity(command.id, "tool", sequence, {
39243
- input: JSON.stringify({ command: command.command, cwd: command.cwd }),
39244
- locations: [command.cwd],
39245
- name: "",
39246
- output: JSON.stringify({
39247
- formatted_output: command.aggregatedOutput ?? "",
39248
- ...command.exitCode == null ? {} : { exit_code: command.exitCode }
39249
- }),
39250
- status: command.status === "completed" ? "completed" : "failed",
39251
- title: command.command,
39252
- toolKind: action
39253
- })
39254
- );
39466
+ ],
39467
+ content: [],
39468
+ role: "assistant",
39469
+ text: ""
39470
+ });
39255
39471
  sequence += 1;
39256
- continue;
39257
- } else {
39258
- continue;
39259
39472
  }
39260
- const fitted = fitHistoryMessage(message);
39261
- if (fitted.message.text.length === 0 && (fitted.message.images?.length ?? 0) === 0) {
39262
- continue;
39263
- }
39264
- truncated ||= fitted.truncated;
39265
- messages.push(fitted.message);
39266
- if (message.role === "assistant") {
39267
- assistantMessageIndex = messages.length - 1;
39268
- }
39269
- characters += messageSize(fitted.message);
39270
39473
  }
39271
39474
  if (options.detail === "rich" && turn.error != null) {
39272
- activities.push(
39273
- activity(`agent-error-${sequence.toString()}`, "tool", sequence, {
39274
- input: "",
39275
- locations: [],
39276
- name: "",
39277
- output: errorMessage(turn.error),
39278
- status: "failed",
39279
- title: "Agent error",
39280
- toolKind: "other"
39281
- })
39282
- );
39283
- }
39284
- if (options.detail === "rich" && activities.length > assignedActivityCount) {
39285
- const message = {
39286
- activities: activitySlice(),
39475
+ append({
39476
+ activities: [
39477
+ activity(`agent-error-${sequence.toString()}`, "tool", sequence, {
39478
+ input: "",
39479
+ locations: [],
39480
+ name: "",
39481
+ output: errorMessage(turn.error),
39482
+ status: "failed",
39483
+ title: "Agent error",
39484
+ toolKind: "other"
39485
+ })
39486
+ ],
39287
39487
  content: [],
39288
39488
  role: "assistant",
39289
39489
  text: ""
39290
- };
39291
- messages.push(message);
39292
- assistantMessageIndex = messages.length - 1;
39293
- characters += messageSize(message);
39490
+ });
39294
39491
  }
39295
39492
  if (assistantMessageIndex !== null) {
39296
39493
  const assistant = messages[assistantMessageIndex];
@@ -39300,20 +39497,20 @@ function decodeHistory(thread, value, options) {
39300
39497
  ...assistant,
39301
39498
  ...outcome === void 0 ? {} : { outcome }
39302
39499
  };
39303
- const fitted = fitHistoryMessage(updated);
39500
+ const fitted = fitHistoryMessage(updated, turnMessageCharacterLimit);
39304
39501
  truncated ||= fitted.truncated;
39305
39502
  messages[assistantMessageIndex] = fitted.message;
39306
39503
  characters += messageSize(fitted.message);
39307
39504
  }
39308
- } else if (activities.length > 0 || outcome !== void 0) {
39505
+ } else if (outcome !== void 0) {
39309
39506
  const message = {
39310
- activities: activities.slice(-100),
39507
+ activities: [],
39311
39508
  content: [],
39312
39509
  role: "assistant",
39313
39510
  ...outcome === void 0 ? {} : { outcome },
39314
39511
  text: ""
39315
39512
  };
39316
- const fitted = fitHistoryMessage(message);
39513
+ const fitted = fitHistoryMessage(message, turnMessageCharacterLimit);
39317
39514
  truncated ||= fitted.truncated;
39318
39515
  messages.push(fitted.message);
39319
39516
  characters += messageSize(fitted.message);
@@ -41181,6 +41378,14 @@ function boundedActiveMessages(messages, messageLimit, characterLimit) {
41181
41378
  truncated: selected.length !== messages.length
41182
41379
  };
41183
41380
  }
41381
+ function nativeActiveMessage(message) {
41382
+ return message.role === "user" ? { role: "user", text: message.text } : {
41383
+ activities: message.activities,
41384
+ content: message.content,
41385
+ role: "assistant",
41386
+ text: message.text
41387
+ };
41388
+ }
41184
41389
  function paginateAcpSessionHistory(history, sessionId, cursor, limit) {
41185
41390
  if (history.status === "unavailable") {
41186
41391
  if (cursor !== null) {
@@ -41213,20 +41418,27 @@ function paginateLiveSessionHistory(history, activeTurn, sessionId, cursor, limi
41213
41418
  }
41214
41419
  if (history.status === "unavailable") {
41215
41420
  const bounded3 = boundedActiveMessages(
41216
- activeTurn.messages,
41217
- Math.max(0, limit - 1),
41218
- Math.max(0, SESSION_HISTORY_CHARACTER_LIMIT - activeTurn.prompt.length)
41421
+ activeTurn.messages.map(nativeActiveMessage),
41422
+ limit,
41423
+ SESSION_HISTORY_CHARACTER_LIMIT
41219
41424
  );
41220
41425
  return {
41221
41426
  coveredCommandIds: [],
41222
41427
  coveredMessageIds: [],
41223
- messages: [{ role: "user", text: activeTurn.prompt }, ...bounded3.messages],
41428
+ messages: bounded3.messages,
41224
41429
  nextCursor: null,
41225
41430
  status: "available",
41226
41431
  truncated: activeTurn.truncated || bounded3.truncated
41227
41432
  };
41228
41433
  }
41229
- const activeUserIndex = history.coveredCommandIds.includes(activeTurn.commandId) ? history.messages.findLastIndex((message) => message.role === "user") : -1;
41434
+ const activeRoot = activeTurn.messages.find(
41435
+ (message) => message.role === "user" && message.id === activeTurn.commandId
41436
+ );
41437
+ const coveredActiveRoot = history.coveredCommandIds.includes(activeTurn.commandId);
41438
+ const matchingActiveUserIndex = coveredActiveRoot ? history.messages.findLastIndex(
41439
+ (message) => message.role === "user" && message.text === (activeRoot?.text ?? activeTurn.prompt)
41440
+ ) : -1;
41441
+ const activeUserIndex = matchingActiveUserIndex >= 0 ? matchingActiveUserIndex : liveHistoryCoveredTurnRanges(history).find((range) => range.commandId === activeTurn.commandId)?.userIndex ?? -1;
41230
41442
  if (activeUserIndex >= 0) {
41231
41443
  history = {
41232
41444
  ...history,
@@ -41238,19 +41450,13 @@ function paginateLiveSessionHistory(history, activeTurn, sessionId, cursor, limi
41238
41450
  };
41239
41451
  }
41240
41452
  const latestNativeMessage = history.messages.at(-1);
41241
- const includeActivePrompt = activeUserIndex < 0 && !(latestNativeMessage?.role === "user" && latestNativeMessage.text === activeTurn.prompt);
41242
- const bounded2 = boundedActiveMessages(
41243
- activeTurn.messages,
41244
- Math.max(0, limit - (includeActivePrompt ? 1 : 0)),
41245
- Math.max(0, SESSION_HISTORY_CHARACTER_LIMIT - (includeActivePrompt ? activeTurn.prompt.length : 0))
41246
- );
41247
- const activeMessages = [
41248
- ...includeActivePrompt ? [{ role: "user", text: activeTurn.prompt }] : [],
41249
- ...bounded2.messages
41250
- ];
41453
+ const firstActiveMessage = activeTurn.messages[0];
41454
+ const preserveNativeRoot = activeUserIndex >= 0 || firstActiveMessage?.role === "user" && latestNativeMessage?.role === "user" && latestNativeMessage.text === firstActiveMessage.text;
41455
+ const activeMessages = activeTurn.messages.slice(preserveNativeRoot ? 1 : 0).map(nativeActiveMessage);
41456
+ const bounded2 = boundedActiveMessages(activeMessages, limit, SESSION_HISTORY_CHARACTER_LIMIT);
41251
41457
  let historicalMessageCount = 0;
41252
- let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT - bounded2.characters - (includeActivePrompt ? activeTurn.prompt.length : 0);
41253
- const historicalMessageLimit = Math.max(0, limit - activeMessages.length);
41458
+ let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT - bounded2.characters;
41459
+ const historicalMessageLimit = Math.max(0, limit - bounded2.messages.length);
41254
41460
  for (let index = history.messages.length - 1; index >= 0 && historicalMessageCount < historicalMessageLimit; index -= 1) {
41255
41461
  const message = history.messages[index];
41256
41462
  if (message === void 0) {
@@ -41273,7 +41479,7 @@ function paginateLiveSessionHistory(history, activeTurn, sessionId, cursor, limi
41273
41479
  } : paginateAcpSessionHistory(history, sessionId, null, historicalMessageCount);
41274
41480
  return {
41275
41481
  ...page,
41276
- messages: [...page.messages, ...activeMessages],
41482
+ messages: [...page.messages, ...bounded2.messages],
41277
41483
  truncated: page.truncated || activeTurn.truncated || bounded2.truncated
41278
41484
  };
41279
41485
  }
@@ -41724,6 +41930,7 @@ async function executePrompt({
41724
41930
  timer,
41725
41931
  signal,
41726
41932
  recordLiveEvent,
41933
+ recordSteeringPrompt,
41727
41934
  cancellationRequested
41728
41935
  }) {
41729
41936
  const events = new CoalescingAgentEventPublisher(timer, (event) => {
@@ -41804,6 +42011,17 @@ async function executePrompt({
41804
42011
  sessionId: command.sessionId
41805
42012
  });
41806
42013
  operations.transitionExecution(command.commandId, "running");
42014
+ if (availability.disposition === SessionPromptDisposition.Steer) {
42015
+ const updated = recordSteeringPrompt();
42016
+ if (updated === null) {
42017
+ throw new AcpExecutionError(
42018
+ "The steering target is unavailable",
42019
+ {},
42020
+ "prompt_queue_target_unavailable"
42021
+ );
42022
+ }
42023
+ publisher.publish(command.sessionId, updated);
42024
+ }
41807
42025
  const stream = activateAttempt();
41808
42026
  publisher.publish(command.sessionId, {
41809
42027
  commandId: command.commandId,
@@ -42423,6 +42641,7 @@ function createDaemonCommandHandler({
42423
42641
  timer,
42424
42642
  signal: turn.signal,
42425
42643
  recordLiveEvent: turn.recordEvent,
42644
+ recordSteeringPrompt: () => activeTurns.recordSteeringPrompt(command),
42426
42645
  cancellationRequested: turn.cancellationRequested
42427
42646
  }).catch((error62) => {
42428
42647
  console.error("Mobius daemon turn failed", error62);