@moxt-ai/mobius 0.0.331 → 0.0.332
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 +54 -116
- package/dist/cli.js.map +3 -3
- package/dist/runtime.js +52 -115
- package/dist/runtime.js.map +3 -3
- package/dist/schema/acp-session-store/execution-receipt.d.ts.map +1 -1
- package/dist/schema/acp-session-store/execution-receipt.js +1 -0
- package/dist/schema/acp-session-store/execution-receipt.js.map +1 -1
- package/dist/session/prompt/execute-prompt.d.ts.map +1 -1
- package/dist/session/prompt/execute-prompt.js +1 -4
- package/dist/session/prompt/execute-prompt.js.map +1 -1
- package/dist/session/prompt/prompt-lifecycle.d.ts.map +1 -1
- package/dist/session/prompt/prompt-lifecycle.js +0 -1
- package/dist/session/prompt/prompt-lifecycle.js.map +1 -1
- package/dist/session/turn/execution-receipts.d.ts +1 -5
- package/dist/session/turn/execution-receipts.d.ts.map +1 -1
- package/dist/session/turn/execution-receipts.js +20 -75
- package/dist/session/turn/execution-receipts.js.map +1 -1
- package/dist/storage/session/execution-receipt-table.d.ts +3 -26
- package/dist/storage/session/execution-receipt-table.d.ts.map +1 -1
- package/dist/storage/session/execution-receipt-table.js +47 -36
- package/dist/storage/session/execution-receipt-table.js.map +1 -1
- package/package.json +2 -2
package/dist/runtime.js
CHANGED
|
@@ -32545,7 +32545,7 @@ import { fetch as fetch3 } from "undici";
|
|
|
32545
32545
|
// package.json
|
|
32546
32546
|
var package_default = {
|
|
32547
32547
|
name: "@moxt-ai/mobius",
|
|
32548
|
-
version: "0.0.
|
|
32548
|
+
version: "0.0.332",
|
|
32549
32549
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
32550
32550
|
type: "module",
|
|
32551
32551
|
bin: {
|
|
@@ -83682,6 +83682,7 @@ var executionReceipt = sqliteTable("execution_receipt", {
|
|
|
83682
83682
|
sessionId: text("session_id").notNull(),
|
|
83683
83683
|
commandHash: text("command_hash").notNull(),
|
|
83684
83684
|
attemptId: text("attempt_id").notNull(),
|
|
83685
|
+
// Compatibility projection for older Runtimes; started and outcome own the facts.
|
|
83685
83686
|
state: text("state").notNull(),
|
|
83686
83687
|
started: integer2("started", { mode: "boolean" }).notNull(),
|
|
83687
83688
|
outcome: text("outcome"),
|
|
@@ -83730,23 +83731,23 @@ var AcpSessionTable = class {
|
|
|
83730
83731
|
};
|
|
83731
83732
|
|
|
83732
83733
|
// src/storage/session/execution-receipt-table.ts
|
|
83733
|
-
var
|
|
83734
|
+
var receiptSchema = external_exports.object({
|
|
83734
83735
|
commandId: external_exports.string(),
|
|
83735
83736
|
sessionId: external_exports.string(),
|
|
83736
83737
|
commandHash: external_exports.string(),
|
|
83737
83738
|
attemptId: external_exports.string(),
|
|
83738
|
-
updatedAt: external_exports.string()
|
|
83739
|
-
|
|
83740
|
-
|
|
83741
|
-
|
|
83742
|
-
receiptFields.extend({ state: external_exports.literal("running"), started: external_exports.literal(true), outcome: external_exports.string().nullable() }),
|
|
83743
|
-
receiptFields.extend({
|
|
83744
|
-
state: external_exports.enum(["succeeded", "failed", "cancelled"]),
|
|
83745
|
-
started: external_exports.boolean(),
|
|
83746
|
-
outcome: external_exports.string().nullable()
|
|
83747
|
-
})
|
|
83748
|
-
]).readonly();
|
|
83739
|
+
updatedAt: external_exports.string(),
|
|
83740
|
+
started: external_exports.boolean(),
|
|
83741
|
+
outcome: external_exports.string().nullable()
|
|
83742
|
+
}).readonly();
|
|
83749
83743
|
var identitySchema = external_exports.object({ sessionId: external_exports.string(), commandHash: external_exports.string() }).readonly();
|
|
83744
|
+
function legacyState(receipt) {
|
|
83745
|
+
if (receipt.outcome === null) {
|
|
83746
|
+
return receipt.started ? "running" : "dispatching";
|
|
83747
|
+
}
|
|
83748
|
+
const event = sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
|
|
83749
|
+
return event.type === "lifecycle-metadata" && event.payload.kind === "prompt.completed" ? event.payload.stopReason === "cancelled" ? "cancelled" : "succeeded" : "failed";
|
|
83750
|
+
}
|
|
83750
83751
|
var ExecutionReceiptTable = class {
|
|
83751
83752
|
#database;
|
|
83752
83753
|
constructor(database) {
|
|
@@ -83759,32 +83760,27 @@ var ExecutionReceiptTable = class {
|
|
|
83759
83760
|
list = () => receiptSchema.array().parse(
|
|
83760
83761
|
this.#database.orm.select().from(executionReceipt).orderBy(asc(executionReceipt.updatedAt), asc(executionReceipt.commandId)).all()
|
|
83761
83762
|
);
|
|
83762
|
-
save = (receipt) => {
|
|
83763
|
-
|
|
83764
|
-
|
|
83765
|
-
|
|
83766
|
-
|
|
83767
|
-
|
|
83768
|
-
|
|
83763
|
+
save = (receipt, terminalLimit) => this.#database.transaction(() => {
|
|
83764
|
+
const row = { ...receipt, state: legacyState(receipt) };
|
|
83765
|
+
this.#database.orm.insert(executionReceipt).values(row).onConflictDoUpdate({ target: executionReceipt.commandId, set: row }).run();
|
|
83766
|
+
if (receipt.outcome === null) {
|
|
83767
|
+
return [];
|
|
83768
|
+
}
|
|
83769
|
+
const retained = this.#database.orm.select({ commandId: executionReceipt.commandId }).from(executionReceipt).where(and(eq(executionReceipt.sessionId, receipt.sessionId), isNotNull(executionReceipt.outcome))).orderBy(desc(executionReceipt.updatedAt), desc(executionReceipt.commandId)).limit(terminalLimit).all();
|
|
83770
|
+
if (retained.length === terminalLimit) {
|
|
83771
|
+
return this.#remove(
|
|
83769
83772
|
and(
|
|
83770
83773
|
eq(executionReceipt.sessionId, receipt.sessionId),
|
|
83771
|
-
|
|
83772
|
-
|
|
83773
|
-
|
|
83774
|
-
|
|
83775
|
-
this.#remove(
|
|
83776
|
-
and(
|
|
83777
|
-
eq(executionReceipt.sessionId, receipt.sessionId),
|
|
83778
|
-
inArray(executionReceipt.state, ["succeeded", "failed", "cancelled"]),
|
|
83779
|
-
notInArray(
|
|
83780
|
-
executionReceipt.commandId,
|
|
83781
|
-
retained.map((row) => row.commandId)
|
|
83782
|
-
)
|
|
83774
|
+
isNotNull(executionReceipt.outcome),
|
|
83775
|
+
notInArray(
|
|
83776
|
+
executionReceipt.commandId,
|
|
83777
|
+
retained.map((row2) => row2.commandId)
|
|
83783
83778
|
)
|
|
83784
|
-
)
|
|
83785
|
-
|
|
83786
|
-
}
|
|
83787
|
-
|
|
83779
|
+
)
|
|
83780
|
+
);
|
|
83781
|
+
}
|
|
83782
|
+
return [];
|
|
83783
|
+
});
|
|
83788
83784
|
remove = (commandId) => {
|
|
83789
83785
|
this.#database.transaction(() => this.#remove(eq(executionReceipt.commandId, commandId)));
|
|
83790
83786
|
};
|
|
@@ -83799,7 +83795,7 @@ var ExecutionReceiptTable = class {
|
|
|
83799
83795
|
commandHash: executionReceipt.commandHash
|
|
83800
83796
|
}).from(executionReceipt).where(and(condition, eq(executionReceipt.started, true)))
|
|
83801
83797
|
).onConflictDoNothing().run();
|
|
83802
|
-
this.#database.orm.delete(executionReceipt).where(condition).
|
|
83798
|
+
return this.#database.orm.delete(executionReceipt).where(condition).returning({ commandId: executionReceipt.commandId }).all().map((row) => row.commandId);
|
|
83803
83799
|
};
|
|
83804
83800
|
};
|
|
83805
83801
|
|
|
@@ -87006,20 +87002,15 @@ async function settleAbandonedTurn(projection, operations, cancellation) {
|
|
|
87006
87002
|
"agent_execution_abandoned",
|
|
87007
87003
|
"The local Agent execution was abandoned before it completed"
|
|
87008
87004
|
);
|
|
87009
|
-
operations.transitionExecution(cancellation.commandId, "failed");
|
|
87010
87005
|
projection.publishTerminal(cancellation.sessionId, cancellation.commandId);
|
|
87011
87006
|
}
|
|
87012
87007
|
|
|
87013
87008
|
// src/session/turn/execution-receipts.ts
|
|
87014
87009
|
import { createHash as createHash6, randomUUID as randomUUID15 } from "node:crypto";
|
|
87015
87010
|
var MAX_TERMINAL_RECEIPTS = 1024;
|
|
87016
|
-
function isTerminal(state) {
|
|
87017
|
-
return state === "succeeded" || state === "failed" || state === "cancelled";
|
|
87018
|
-
}
|
|
87019
87011
|
var ExecutionReceipts = class {
|
|
87020
87012
|
#executions = /* @__PURE__ */ new Map();
|
|
87021
87013
|
#recoveredCommands = /* @__PURE__ */ new Set();
|
|
87022
|
-
#terminalCountBySession = /* @__PURE__ */ new Map();
|
|
87023
87014
|
#table;
|
|
87024
87015
|
#closing = false;
|
|
87025
87016
|
#activeCount = 0;
|
|
@@ -87030,36 +87021,22 @@ var ExecutionReceipts = class {
|
|
|
87030
87021
|
for (const row of table.list()) {
|
|
87031
87022
|
this.#executions.set(row.commandId, row);
|
|
87032
87023
|
this.#recoveredCommands.add(row.commandId);
|
|
87033
|
-
if (
|
|
87024
|
+
if (row.outcome === null) {
|
|
87034
87025
|
this.#activeCount += 1;
|
|
87035
87026
|
}
|
|
87036
|
-
if (isTerminal(row.state)) {
|
|
87037
|
-
this.#terminalCountBySession.set(
|
|
87038
|
-
row.sessionId,
|
|
87039
|
-
(this.#terminalCountBySession.get(row.sessionId) ?? 0) + 1
|
|
87040
|
-
);
|
|
87041
|
-
}
|
|
87042
87027
|
}
|
|
87043
87028
|
}
|
|
87044
87029
|
#save = (commandId, receipt) => {
|
|
87045
|
-
|
|
87046
|
-
this.#table.save({ ...receipt, commandId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
87047
|
-
}
|
|
87030
|
+
const evicted = this.#closing ? [] : this.#table.save({ ...receipt, commandId, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, MAX_TERMINAL_RECEIPTS);
|
|
87048
87031
|
const previous = this.#executions.get(commandId);
|
|
87049
|
-
const wasActive = previous
|
|
87050
|
-
if (isTerminal(receipt.state)) {
|
|
87051
|
-
this.#executions.delete(commandId);
|
|
87052
|
-
}
|
|
87032
|
+
const wasActive = previous?.outcome === null;
|
|
87053
87033
|
this.#executions.set(commandId, receipt);
|
|
87054
|
-
|
|
87055
|
-
|
|
87056
|
-
|
|
87057
|
-
this.#terminalCountBySession.set(
|
|
87058
|
-
receipt.sessionId,
|
|
87059
|
-
(this.#terminalCountBySession.get(receipt.sessionId) ?? 0) + 1
|
|
87060
|
-
);
|
|
87061
|
-
this.pruneTerminalReceipts(receipt.sessionId);
|
|
87034
|
+
for (const evictedCommandId of evicted) {
|
|
87035
|
+
this.#executions.delete(evictedCommandId);
|
|
87036
|
+
this.#recoveredCommands.delete(evictedCommandId);
|
|
87062
87037
|
}
|
|
87038
|
+
this.#activeCount += Number(receipt.outcome === null) - Number(wasActive);
|
|
87039
|
+
this.#onCount(this.#activeCount);
|
|
87063
87040
|
};
|
|
87064
87041
|
beginShutdown = () => {
|
|
87065
87042
|
this.#closing = true;
|
|
@@ -87072,7 +87049,7 @@ var ExecutionReceipts = class {
|
|
|
87072
87049
|
recordCancellationBeforeAdmission = (commandId, sessionId) => {
|
|
87073
87050
|
const existing = this.#executions.get(commandId);
|
|
87074
87051
|
if (existing !== void 0) {
|
|
87075
|
-
return existing.sessionId === sessionId
|
|
87052
|
+
return existing.sessionId === sessionId ? this.outcome(commandId) : void 0;
|
|
87076
87053
|
}
|
|
87077
87054
|
const outcome = {
|
|
87078
87055
|
type: "lifecycle-metadata",
|
|
@@ -87089,7 +87066,6 @@ var ExecutionReceipts = class {
|
|
|
87089
87066
|
attemptId: randomUUID15(),
|
|
87090
87067
|
commandHash,
|
|
87091
87068
|
sessionId,
|
|
87092
|
-
state: "cancelled",
|
|
87093
87069
|
started: false,
|
|
87094
87070
|
outcome: JSON.stringify({ ...outcome, recordedAt: (/* @__PURE__ */ new Date()).toISOString() })
|
|
87095
87071
|
});
|
|
@@ -87110,7 +87086,6 @@ var ExecutionReceipts = class {
|
|
|
87110
87086
|
const sanitized = payload.kind === "prompt.completed" ? payload : { ...payload, message: "The local Agent could not complete the request" };
|
|
87111
87087
|
this.#save(payload.commandId, {
|
|
87112
87088
|
...receipt,
|
|
87113
|
-
state: payload.kind === "prompt.completed" ? payload.stopReason === "cancelled" ? "cancelled" : "succeeded" : "failed",
|
|
87114
87089
|
outcome: JSON.stringify({ type: "lifecycle-metadata", payload: sanitized, recordedAt: event.recordedAt })
|
|
87115
87090
|
});
|
|
87116
87091
|
};
|
|
@@ -87134,9 +87109,8 @@ var ExecutionReceipts = class {
|
|
|
87134
87109
|
} : sessionEventPayloadSchema.parse(JSON.parse(receipt.outcome));
|
|
87135
87110
|
const recordedAt = receipt.outcome === null ? (/* @__PURE__ */ new Date()).toISOString() : external_exports.object({ recordedAt: external_exports.string() }).parse(JSON.parse(receipt.outcome)).recordedAt;
|
|
87136
87111
|
recovered.push({ sessionId: receipt.sessionId, event, recordedAt });
|
|
87137
|
-
if (
|
|
87138
|
-
|
|
87139
|
-
this.#save(commandId, { ...receipt, state, outcome: JSON.stringify({ ...event, recordedAt }) });
|
|
87112
|
+
if (receipt.outcome === null) {
|
|
87113
|
+
this.#save(commandId, { ...receipt, outcome: JSON.stringify({ ...event, recordedAt }) });
|
|
87140
87114
|
}
|
|
87141
87115
|
}
|
|
87142
87116
|
return recovered;
|
|
@@ -87149,10 +87123,6 @@ var ExecutionReceipts = class {
|
|
|
87149
87123
|
this.#table.remove(commandId);
|
|
87150
87124
|
this.#executions.delete(commandId);
|
|
87151
87125
|
this.#recoveredCommands.delete(commandId);
|
|
87152
|
-
this.#terminalCountBySession.set(
|
|
87153
|
-
sessionId,
|
|
87154
|
-
Math.max(0, (this.#terminalCountBySession.get(sessionId) ?? 1) - 1)
|
|
87155
|
-
);
|
|
87156
87126
|
existing = void 0;
|
|
87157
87127
|
}
|
|
87158
87128
|
if (existing !== void 0) {
|
|
@@ -87163,7 +87133,6 @@ var ExecutionReceipts = class {
|
|
|
87163
87133
|
attemptId: existing.attemptId,
|
|
87164
87134
|
commandId,
|
|
87165
87135
|
kind: "duplicate",
|
|
87166
|
-
state: existing.state,
|
|
87167
87136
|
outcome: this.#recoveredCommands.has(commandId) ? this.outcome(commandId) : void 0
|
|
87168
87137
|
};
|
|
87169
87138
|
}
|
|
@@ -87176,66 +87145,37 @@ var ExecutionReceipts = class {
|
|
|
87176
87145
|
attemptId,
|
|
87177
87146
|
commandHash,
|
|
87178
87147
|
sessionId,
|
|
87179
|
-
state: "dispatching",
|
|
87180
87148
|
started: false,
|
|
87181
87149
|
outcome: null
|
|
87182
87150
|
});
|
|
87183
|
-
return { attemptId, commandId, kind: "accepted"
|
|
87151
|
+
return { attemptId, commandId, kind: "accepted" };
|
|
87184
87152
|
};
|
|
87185
|
-
|
|
87153
|
+
markExecutionStarted = (commandId) => {
|
|
87186
87154
|
const current = this.#executions.get(commandId);
|
|
87187
87155
|
if (current === void 0) {
|
|
87188
87156
|
throw new Error("The runtime execution receipt does not exist");
|
|
87189
87157
|
}
|
|
87190
|
-
if (current.
|
|
87191
|
-
return;
|
|
87192
|
-
}
|
|
87193
|
-
const allowed = current.state === "dispatching" && (state === "running" || state === "failed" || state === "cancelled") || current.state === "running" && isTerminal(state);
|
|
87194
|
-
if (!allowed) {
|
|
87158
|
+
if (current.outcome !== null) {
|
|
87195
87159
|
throw new Error("The runtime execution transition is invalid");
|
|
87196
87160
|
}
|
|
87197
|
-
if (
|
|
87198
|
-
this.#save(commandId, { ...current,
|
|
87199
|
-
} else if (isTerminal(state)) {
|
|
87200
|
-
this.#save(commandId, { ...current, state });
|
|
87161
|
+
if (!current.started) {
|
|
87162
|
+
this.#save(commandId, { ...current, started: true });
|
|
87201
87163
|
}
|
|
87202
87164
|
};
|
|
87203
87165
|
/** Only commands without a terminal result can still be cancelled. */
|
|
87204
87166
|
findUnsettledAttemptId = (commandId, sessionId) => {
|
|
87205
87167
|
const receipt = this.#executions.get(commandId);
|
|
87206
|
-
return receipt?.sessionId === sessionId &&
|
|
87168
|
+
return receipt?.sessionId === sessionId && receipt.outcome === null ? receipt.attemptId : null;
|
|
87207
87169
|
};
|
|
87208
87170
|
isTerminalExecution = (commandId, sessionId) => {
|
|
87209
87171
|
const receipt = this.#executions.get(commandId);
|
|
87210
|
-
return receipt?.sessionId === sessionId &&
|
|
87172
|
+
return receipt?.sessionId === sessionId && receipt.outcome !== null;
|
|
87211
87173
|
};
|
|
87212
87174
|
close = () => {
|
|
87213
87175
|
this.#executions.clear();
|
|
87214
87176
|
this.#recoveredCommands.clear();
|
|
87215
|
-
this.#terminalCountBySession.clear();
|
|
87216
87177
|
this.#activeCount = 0;
|
|
87217
87178
|
};
|
|
87218
|
-
pruneTerminalReceipts = (sessionId) => {
|
|
87219
|
-
if ((this.#terminalCountBySession.get(sessionId) ?? 0) <= MAX_TERMINAL_RECEIPTS) {
|
|
87220
|
-
return;
|
|
87221
|
-
}
|
|
87222
|
-
for (const [commandId, receipt] of this.#executions) {
|
|
87223
|
-
if (receipt.sessionId === sessionId && isTerminal(receipt.state)) {
|
|
87224
|
-
this.#table.remove(commandId);
|
|
87225
|
-
this.#executions.delete(commandId);
|
|
87226
|
-
this.#recoveredCommands.delete(commandId);
|
|
87227
|
-
const remaining = (this.#terminalCountBySession.get(sessionId) ?? 1) - 1;
|
|
87228
|
-
if (remaining > 0) {
|
|
87229
|
-
this.#terminalCountBySession.set(sessionId, remaining);
|
|
87230
|
-
} else {
|
|
87231
|
-
this.#terminalCountBySession.delete(sessionId);
|
|
87232
|
-
}
|
|
87233
|
-
if ((this.#terminalCountBySession.get(sessionId) ?? 0) <= MAX_TERMINAL_RECEIPTS) {
|
|
87234
|
-
return;
|
|
87235
|
-
}
|
|
87236
|
-
}
|
|
87237
|
-
}
|
|
87238
|
-
};
|
|
87239
87179
|
};
|
|
87240
87180
|
|
|
87241
87181
|
// src/session/turn/runtime-turn-activity.ts
|
|
@@ -90364,7 +90304,7 @@ async function executePrompt({
|
|
|
90364
90304
|
);
|
|
90365
90305
|
prepared = await sessions.prepareExecutionSession(preparation);
|
|
90366
90306
|
}
|
|
90367
|
-
operations.
|
|
90307
|
+
operations.markExecutionStarted(command.commandId);
|
|
90368
90308
|
if (availability.disposition === SessionPromptDisposition.Steer) {
|
|
90369
90309
|
if (!recordSteeringPrompt()) {
|
|
90370
90310
|
throw new AcpExecutionError(
|
|
@@ -90420,18 +90360,15 @@ async function executePrompt({
|
|
|
90420
90360
|
stopReason = result.stopReason;
|
|
90421
90361
|
}
|
|
90422
90362
|
await eventProjection.completed(command.sessionId, command.commandId, stopReason);
|
|
90423
|
-
operations.transitionExecution(command.commandId, stopReason === "cancelled" ? "cancelled" : "succeeded");
|
|
90424
90363
|
} catch (error62) {
|
|
90425
90364
|
if (signal.aborted && cancellationRequested()) {
|
|
90426
90365
|
await eventProjection.completed(command.sessionId, command.commandId, "cancelled");
|
|
90427
|
-
operations.transitionExecution(command.commandId, "cancelled");
|
|
90428
90366
|
return;
|
|
90429
90367
|
}
|
|
90430
90368
|
const code = operationErrorCode(error62);
|
|
90431
90369
|
const failureCode = code === "session_operation_failed" ? "agent_execution_failed" : code;
|
|
90432
90370
|
const failureMessage = code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error62);
|
|
90433
90371
|
await eventProjection.failed(command.sessionId, command.commandId, failureCode, failureMessage);
|
|
90434
|
-
operations.transitionExecution(command.commandId, "failed");
|
|
90435
90372
|
reportFailure("session_prompt_failed", command.commandId, {
|
|
90436
90373
|
agentId: command.agentId,
|
|
90437
90374
|
code: failureCode,
|