@agimon-ai/doompi-core 0.0.1-alpha.111 → 0.0.1-alpha.113

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.
@@ -493,7 +493,8 @@ async function createDirectHarnessRuntime(options) {
493
493
  }, context);
494
494
  const storedFastMode = await harness.snapshot(FastModeDoc, context);
495
495
  fastMode = storedFastMode?.enabled ?? options.initialFastMode ?? false;
496
- const sessionId = (await harness.snapshot(SessionIdentityDoc, context))?.id || options.sessionId || randomUUID();
496
+ const storedIdentity = await harness.snapshot(SessionIdentityDoc, context);
497
+ const sessionId = storedIdentity?.id || options.sessionId || randomUUID();
497
498
  await writable(() => harness.commit(async (tx) => {
498
499
  const identity = await tx.doc(SessionIdentityDoc);
499
500
  if (!identity.id) {
@@ -515,7 +516,7 @@ async function createDirectHarnessRuntime(options) {
515
516
  const metadata = await tx.doc(SessionMetadataDoc);
516
517
  metadata.workspaceRoot ||= options.cwd;
517
518
  if (options.lane !== void 0) metadata.laneName = options.lane;
518
- if (options.sessionName !== void 0) metadata.name = options.sessionName;
519
+ if (!storedIdentity?.id && options.sessionName !== void 0) metadata.name = options.sessionName;
519
520
  }, context));
520
521
  const laneName = options.lane ?? "main";
521
522
  let resolveExited;
@@ -565,7 +566,7 @@ async function createDirectHarnessRuntime(options) {
565
566
  return {
566
567
  revision: record.revision,
567
568
  paused: record.paused,
568
- queue: record.queue.filter((item) => item.disposition !== "consumed" && item.disposition !== "removed").map(({ submissionId: _s, conversationId: _c, message: _m, operationId: _o, attempt: _a, ...item }) => item),
569
+ queue: record.queue.filter((item) => item.explicitQueue === true && item.disposition !== "consumed" && item.disposition !== "removed").map(({ explicitQueue: _q, submissionId: _s, conversationId: _c, message: _m, operationId: _o, attempt: _a, ...item }) => item),
569
570
  operation: await execution()
570
571
  };
571
572
  };
@@ -1051,13 +1052,13 @@ async function createDirectHarnessRuntime(options) {
1051
1052
  }
1052
1053
  });
1053
1054
  };
1054
- const handoff = async (item, mode, recovering = false) => {
1055
+ const handoff = async (item, mode, recovering = false, allowPaused = false) => {
1055
1056
  if (handingOff.has(item.id)) return void 0;
1056
1057
  handingOff.add(item.id);
1057
1058
  try {
1058
1059
  const claimed = await changeRecord((r) => {
1059
1060
  const q = r.queue.find((q) => q.id === item.id);
1060
- if (!q || r.paused && !recovering) return void 0;
1061
+ if (!q || r.paused && !recovering && !allowPaused) return void 0;
1061
1062
  if (recovering ? q.disposition !== "handoff" || q.submissionId !== void 0 : q.disposition !== "pending") return void 0;
1062
1063
  q.disposition = "handoff";
1063
1064
  q.conversationId = conversation.id;
@@ -1118,7 +1119,7 @@ async function createDirectHarnessRuntime(options) {
1118
1119
  text: message
1119
1120
  }, ...images] : message;
1120
1121
  };
1121
- const enqueue = async (message, images, delivery, scheduling) => {
1122
+ const enqueue = async (message, images, delivery, scheduling, explicitQueue = false) => {
1122
1123
  const id = randomUUID();
1123
1124
  await changeRecord((r) => {
1124
1125
  r.queue.push({
@@ -1128,6 +1129,7 @@ async function createDirectHarnessRuntime(options) {
1128
1129
  ...typeof message === "string" ? {} : { message },
1129
1130
  delivery,
1130
1131
  scheduling,
1132
+ explicitQueue,
1131
1133
  disposition: "pending"
1132
1134
  });
1133
1135
  });
@@ -1151,17 +1153,9 @@ async function createDirectHarnessRuntime(options) {
1151
1153
  handledCommand: true
1152
1154
  };
1153
1155
  const record = await readRecord();
1154
- if (record.paused) {
1155
- if (record.queue.some((q) => q.disposition !== "consumed" && q.disposition !== "removed")) throw new Error("The queue is paused");
1156
- await changeRecord((r) => {
1157
- r.paused = false;
1158
- delete r.abortOperationId;
1159
- delete r.abortTaskId;
1160
- });
1161
- }
1162
1156
  await flushNextTurn();
1163
1157
  const { id } = await enqueue(message, images, mode ?? "nextRun", "automatic");
1164
- const submission = await handoff((await readRecord()).queue.find((q) => q.id === id), mode ?? "reject");
1158
+ const submission = await handoff((await readRecord()).queue.find((q) => q.id === id), mode ?? "reject", false, record.paused);
1165
1159
  if (!submission) return { settled: Promise.resolve() };
1166
1160
  let resolveDelivery;
1167
1161
  const delivered = new Promise((resolve) => {
@@ -1220,7 +1214,7 @@ async function createDirectHarnessRuntime(options) {
1220
1214
  const doc = await tx.doc(LifecycleDoc);
1221
1215
  const record = JSON.parse(doc.json);
1222
1216
  const q = record.queue.find((q) => q.id === selection.id);
1223
- if (!q) return "not_found";
1217
+ if (!q || q.explicitQueue !== true) return "not_found";
1224
1218
  const requestId = `${q.id}:${q.attempt ?? 0}`;
1225
1219
  const accepted = await tx.submissionByRequest(conversation.id, requestId);
1226
1220
  if (accepted && accepted.type !== "input") throw new Error(`Request ${requestId} already identifies a submission of type ${accepted.type}`);
@@ -1385,7 +1379,7 @@ async function createDirectHarnessRuntime(options) {
1385
1379
  if (selection) {
1386
1380
  const outcome = await changeRecord((r) => {
1387
1381
  const q = r.queue.find((q) => q.id === selection.id);
1388
- if (!q || q.disposition === "removed" || q.disposition === "consumed") return "not_found";
1382
+ if (!q || q.explicitQueue !== true || q.disposition === "removed" || q.disposition === "consumed") return "not_found";
1389
1383
  if (q.disposition !== "pending") return "in_flight";
1390
1384
  if (current?.id !== selection.operationId || current?.status === "aborting") return "target_changed";
1391
1385
  if (q.message && q.message.role !== "user") throw new Error("Only user input can interrupt and respond");
@@ -1602,6 +1596,31 @@ async function createDirectHarnessRuntime(options) {
1602
1596
  }, context));
1603
1597
  return entryId;
1604
1598
  };
1599
+ const removeQueued = async (id) => {
1600
+ const item = (await readRecord()).queue.find((q) => q.id === id);
1601
+ if (!item || item.explicitQueue !== true) return "not_found";
1602
+ if (item.disposition === "consumed") return "already_consumed";
1603
+ if (item.disposition === "removed") return "removed";
1604
+ if (item.submissionId) {
1605
+ const result = await harness.abortSubmission(item.submissionId, context, conversation.id);
1606
+ if (result === "already_placed") return "in_flight";
1607
+ if (result === "settled") return "already_consumed";
1608
+ } else if (item.disposition !== "pending") return "in_flight";
1609
+ const result = await changeRecord((r) => {
1610
+ const q = r.queue.find((q) => q.id === id);
1611
+ if (!q || q.explicitQueue !== true) return "not_found";
1612
+ if (q.disposition === "consumed") return "already_consumed";
1613
+ if (q.disposition === "removed") return "removed";
1614
+ if (q.submissionId !== item.submissionId || item.submissionId === void 0 && q.disposition !== "pending") return "in_flight";
1615
+ q.disposition = "removed";
1616
+ q.text = "";
1617
+ delete q.message;
1618
+ delete q.images;
1619
+ return "removed";
1620
+ });
1621
+ await publish();
1622
+ return result;
1623
+ };
1605
1624
  return {
1606
1625
  sessionId,
1607
1626
  sessionFile: storage.sessionFile,
@@ -1641,7 +1660,8 @@ async function createDirectHarnessRuntime(options) {
1641
1660
  const metadata = await harness.snapshot(SessionMetadataDoc, context);
1642
1661
  const stats = await getSessionStats();
1643
1662
  const inbox = await harness.snapshot(InboxDoc, conversation.id, context);
1644
- const retainedSubmissions = new Set((await readRecord()).queue.map((item) => item.submissionId));
1663
+ const retained = (await readRecord()).queue;
1664
+ const retainedSubmissions = new Set(retained.map((item) => item.submissionId));
1645
1665
  const nativePending = inbox?.items.filter((item) => item.mode !== "write" && !retainedSubmissions.has(item.id)).length ?? 0;
1646
1666
  return json({
1647
1667
  sessionId,
@@ -1663,42 +1683,18 @@ async function createDirectHarnessRuntime(options) {
1663
1683
  followUpMode: settings.followUpMode ?? "one-at-a-time",
1664
1684
  autoCompactionEnabled: settings.compaction?.enabled ?? true,
1665
1685
  messageCount: stats.messageCount,
1666
- pendingMessageCount: lifecycle.queue.length + nativePending + nextTurnMessages.length + deferredInternalCount
1686
+ pendingMessageCount: retained.filter((item) => item.disposition !== "consumed" && item.disposition !== "removed").length + nativePending + nextTurnMessages.length + deferredInternalCount
1667
1687
  });
1668
1688
  },
1669
1689
  enqueueAutomatic: async (value, images) => {
1670
- const result = await enqueue(value, images, "nextRun", "automatic");
1690
+ const result = await enqueue(value, images, "nextRun", "automatic", true);
1671
1691
  drain().catch((error) => emit({
1672
1692
  type: "error",
1673
1693
  error: String(error)
1674
1694
  }));
1675
1695
  return result;
1676
1696
  },
1677
- async removeQueued(id) {
1678
- const item = (await readRecord()).queue.find((q) => q.id === id);
1679
- if (!item) return "not_found";
1680
- if (item.disposition === "consumed") return "already_consumed";
1681
- if (item.disposition === "removed") return "removed";
1682
- if (item.submissionId) {
1683
- const result = await harness.abortSubmission(item.submissionId, context, conversation.id);
1684
- if (result === "already_placed") return "in_flight";
1685
- if (result === "settled") return "already_consumed";
1686
- } else if (item.disposition !== "pending") return "in_flight";
1687
- const result = await changeRecord((r) => {
1688
- const q = r.queue.find((q) => q.id === id);
1689
- if (!q) return "not_found";
1690
- if (q.disposition === "consumed") return "already_consumed";
1691
- if (q.disposition === "removed") return "removed";
1692
- if (q.submissionId !== item.submissionId || item.submissionId === void 0 && q.disposition !== "pending") return "in_flight";
1693
- q.disposition = "removed";
1694
- q.text = "";
1695
- delete q.message;
1696
- delete q.images;
1697
- return "removed";
1698
- });
1699
- await publish();
1700
- return result;
1701
- },
1697
+ removeQueued,
1702
1698
  async promoteQueued(id, operationId) {
1703
1699
  return (await submitUserPrompt("", void 0, {
1704
1700
  id,
@@ -1921,19 +1917,23 @@ async function createDirectHarnessRuntime(options) {
1921
1917
  }
1922
1918
  }),
1923
1919
  async clearQueue() {
1924
- for (const item of (await readRecord()).queue) if (item.submissionId) await harness.abortSubmission(item.submissionId, context);
1925
- await changeRecord((r) => {
1926
- r.queue = [];
1927
- });
1920
+ const selected = (await readRecord()).queue.filter((item) => item.explicitQueue === true && item.disposition !== "consumed" && item.disposition !== "removed");
1921
+ for (const item of selected) await removeQueued(item.id);
1928
1922
  await publish();
1929
1923
  return {
1930
1924
  steering: [],
1931
1925
  followUp: []
1932
1926
  };
1933
1927
  },
1934
- setName: (name) => writable(() => harness.commit(async (tx) => {
1935
- (await tx.doc(SessionMetadataDoc)).name = name;
1936
- }, context)),
1928
+ async setName(name) {
1929
+ await writable(() => harness.commit(async (tx) => {
1930
+ (await tx.doc(SessionMetadataDoc)).name = name;
1931
+ }, context));
1932
+ emit({
1933
+ type: "session_info_changed",
1934
+ name
1935
+ });
1936
+ },
1937
1937
  getSessionStats,
1938
1938
  async replaceTools(replacement) {
1939
1939
  tools = replacement;