@rowan-agent/agent 0.15.4 → 0.15.5
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.d.ts +98 -4
- package/dist/index.js +831 -135
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7618,9 +7618,83 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7618
7618
|
eventSequence = 0;
|
|
7619
7619
|
retentionFloor = 1;
|
|
7620
7620
|
contextCompactions = /* @__PURE__ */ new Map();
|
|
7621
|
+
recorder;
|
|
7622
|
+
runReceiptKeys = /* @__PURE__ */ new Map();
|
|
7621
7623
|
constructor(options = {}) {
|
|
7622
7624
|
this.incarnation = options.incarnation ?? createId("store");
|
|
7623
7625
|
}
|
|
7626
|
+
setChangeRecorder(recorder) {
|
|
7627
|
+
this.recorder = recorder;
|
|
7628
|
+
}
|
|
7629
|
+
touchAgent(agent) {
|
|
7630
|
+
this.recorder?.onAgentUpsert(agent);
|
|
7631
|
+
}
|
|
7632
|
+
touchRun(run) {
|
|
7633
|
+
this.recorder?.onRunUpsert(run);
|
|
7634
|
+
}
|
|
7635
|
+
storeMessage(message) {
|
|
7636
|
+
this.messages.set(message.id, message);
|
|
7637
|
+
this.recorder?.onMessageInsert(message);
|
|
7638
|
+
}
|
|
7639
|
+
storeToolCall(toolCall) {
|
|
7640
|
+
this.toolCalls.set(toolCall.id, toolCall);
|
|
7641
|
+
this.recorder?.onToolCallUpsert(toolCall);
|
|
7642
|
+
}
|
|
7643
|
+
appendEvent(event) {
|
|
7644
|
+
this.events.push(event);
|
|
7645
|
+
this.recorder?.onEventAppend(event);
|
|
7646
|
+
}
|
|
7647
|
+
inferRunIdForReceipt(key, payload) {
|
|
7648
|
+
const parts = key.split(":");
|
|
7649
|
+
const prefix = parts[0];
|
|
7650
|
+
if (["queued_failure", "phase_entered", "input_required", "interaction_answer", "outcome", "cancel"].includes(prefix) && parts[1]) {
|
|
7651
|
+
return parts[1];
|
|
7652
|
+
}
|
|
7653
|
+
const match = payload.match(/^\[\s*"([^"]+)"/);
|
|
7654
|
+
if (match && match[1]) {
|
|
7655
|
+
const candidate = match[1];
|
|
7656
|
+
if (this.runs.has(candidate) || candidate.startsWith("run_") || candidate.startsWith("run-")) {
|
|
7657
|
+
return candidate;
|
|
7658
|
+
}
|
|
7659
|
+
}
|
|
7660
|
+
return void 0;
|
|
7661
|
+
}
|
|
7662
|
+
dropRunOperationReceipts(runId) {
|
|
7663
|
+
const keys = this.runReceiptKeys.get(runId);
|
|
7664
|
+
if (keys && keys.size > 0) {
|
|
7665
|
+
for (const key of keys) {
|
|
7666
|
+
this.operationReceipts.delete(key);
|
|
7667
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
7668
|
+
}
|
|
7669
|
+
this.runReceiptKeys.delete(runId);
|
|
7670
|
+
}
|
|
7671
|
+
for (const [key] of this.operationReceipts.entries()) {
|
|
7672
|
+
if (key.includes(`:${runId}:`) || key.endsWith(`:${runId}`) || key.startsWith(`phase_output:${runId}`) || key.startsWith(`tool_reserve_batch:${runId}`)) {
|
|
7673
|
+
this.operationReceipts.delete(key);
|
|
7674
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
7675
|
+
}
|
|
7676
|
+
}
|
|
7677
|
+
}
|
|
7678
|
+
compactTerminalReceipts() {
|
|
7679
|
+
let count = 0;
|
|
7680
|
+
for (const [key, receipt] of [...this.operationReceipts.entries()]) {
|
|
7681
|
+
const runId = this.inferRunIdForReceipt(key, receipt.payload);
|
|
7682
|
+
if (runId) {
|
|
7683
|
+
const run = this.runs.get(runId);
|
|
7684
|
+
if (!run || ["completed", "failed", "cancelled"].includes(run.state)) {
|
|
7685
|
+
this.operationReceipts.delete(key);
|
|
7686
|
+
const keys = this.runReceiptKeys.get(runId);
|
|
7687
|
+
if (keys) {
|
|
7688
|
+
keys.delete(key);
|
|
7689
|
+
if (keys.size === 0) this.runReceiptKeys.delete(runId);
|
|
7690
|
+
}
|
|
7691
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
7692
|
+
count += 1;
|
|
7693
|
+
}
|
|
7694
|
+
}
|
|
7695
|
+
}
|
|
7696
|
+
return count;
|
|
7697
|
+
}
|
|
7624
7698
|
static fromState(state) {
|
|
7625
7699
|
const store = new _InMemoryStore({ incarnation: state.incarnation });
|
|
7626
7700
|
for (const agent of state.agents) store.agents.set(agent.id, clone(agent));
|
|
@@ -7638,6 +7712,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7638
7712
|
clonedRun.updatedAt = createTimestamp();
|
|
7639
7713
|
store.runs.set(clonedRun.id, clonedRun);
|
|
7640
7714
|
store.appendTransition(clonedRun, "input_required", "cancelled", { reason: clonedRun.cancellationReason });
|
|
7715
|
+
store.dropRunOperationReceipts(clonedRun.id);
|
|
7641
7716
|
} else {
|
|
7642
7717
|
store.runs.set(clonedRun.id, clonedRun);
|
|
7643
7718
|
}
|
|
@@ -7646,7 +7721,18 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7646
7721
|
for (const toolCall of state.toolCalls ?? []) store.toolCalls.set(toolCall.id, clone(toolCall));
|
|
7647
7722
|
store.events.push(...clone(state.events));
|
|
7648
7723
|
for (const [key, receipt] of state.idempotency) store.idempotency.set(key, clone(receipt));
|
|
7649
|
-
for (const [key, receipt] of state.operationReceipts)
|
|
7724
|
+
for (const [key, receipt] of state.operationReceipts) {
|
|
7725
|
+
store.operationReceipts.set(key, clone(receipt));
|
|
7726
|
+
const runId = store.inferRunIdForReceipt(key, receipt.payload);
|
|
7727
|
+
if (runId) {
|
|
7728
|
+
let keys = store.runReceiptKeys.get(runId);
|
|
7729
|
+
if (!keys) {
|
|
7730
|
+
keys = /* @__PURE__ */ new Set();
|
|
7731
|
+
store.runReceiptKeys.set(runId, keys);
|
|
7732
|
+
}
|
|
7733
|
+
keys.add(key);
|
|
7734
|
+
}
|
|
7735
|
+
}
|
|
7650
7736
|
for (const [agentId, messages] of state.historySeeds ?? []) store.historySeeds.set(agentId, clone(messages));
|
|
7651
7737
|
for (const [consumerId, cursor] of state.consumerCheckpoints ?? []) store.consumerCheckpoints.set(consumerId, cursor);
|
|
7652
7738
|
for (const [agentId, sequence] of state.nextAgentSequence) store.nextAgentSequence.set(agentId, sequence);
|
|
@@ -7679,6 +7765,16 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7679
7765
|
contextCompactions: [...this.contextCompactions.entries()]
|
|
7680
7766
|
});
|
|
7681
7767
|
}
|
|
7768
|
+
exportMetadata() {
|
|
7769
|
+
return {
|
|
7770
|
+
incarnation: this.incarnation,
|
|
7771
|
+
eventSequence: this.eventSequence,
|
|
7772
|
+
nextAgentSequence: [...this.nextAgentSequence.entries()],
|
|
7773
|
+
nextReadySequence: [...this.nextReadySequence.entries()],
|
|
7774
|
+
historySeeds: [...this.historySeeds.entries()],
|
|
7775
|
+
contextCompactions: [...this.contextCompactions.entries()]
|
|
7776
|
+
};
|
|
7777
|
+
}
|
|
7682
7778
|
attachOwner(lease) {
|
|
7683
7779
|
this.owner = clone(lease);
|
|
7684
7780
|
this.ownerEpoch = Math.max(this.ownerEpoch, lease.epoch);
|
|
@@ -7701,6 +7797,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7701
7797
|
run.revision += 1;
|
|
7702
7798
|
run.updatedAt = createTimestamp();
|
|
7703
7799
|
this.appendTransition(run, "running", "failed", { failure });
|
|
7800
|
+
this.dropRunOperationReceipts(run.id);
|
|
7704
7801
|
}
|
|
7705
7802
|
}
|
|
7706
7803
|
async openOwner(input) {
|
|
@@ -7718,6 +7815,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7718
7815
|
}
|
|
7719
7816
|
if (this.owner) this.interruptOwner(this.owner.epoch);
|
|
7720
7817
|
this.dropSettledClaimReceipts();
|
|
7818
|
+
this.compactTerminalReceipts();
|
|
7721
7819
|
this.ownerEpoch += 1;
|
|
7722
7820
|
this.owner = {
|
|
7723
7821
|
ownerId: input.ownerId,
|
|
@@ -7764,6 +7862,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7764
7862
|
updatedAt: timestamp
|
|
7765
7863
|
};
|
|
7766
7864
|
this.agents.set(agent.id, agent);
|
|
7865
|
+
this.touchAgent(agent);
|
|
7767
7866
|
if (input.historySeed && input.historySeed.length > 0) this.historySeeds.set(agent.id, materializeHistorySeed(agent.id, input.historySeed));
|
|
7768
7867
|
this.nextAgentSequence.set(agent.id, 0);
|
|
7769
7868
|
this.nextReadySequence.set(agent.id, 0);
|
|
@@ -7777,6 +7876,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7777
7876
|
if (configToken !== void 0) agent.currentConfigToken = configToken;
|
|
7778
7877
|
if (configIdentity !== void 0) agent.currentConfigIdentity = configIdentity;
|
|
7779
7878
|
agent.updatedAt = createTimestamp();
|
|
7879
|
+
this.touchAgent(agent);
|
|
7780
7880
|
return clone(agent);
|
|
7781
7881
|
}
|
|
7782
7882
|
updateAgentConfigToken(lease, input) {
|
|
@@ -7789,6 +7889,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7789
7889
|
agent.currentConfigToken = input.token;
|
|
7790
7890
|
if (input.configIdentity !== void 0) agent.currentConfigIdentity = input.configIdentity;
|
|
7791
7891
|
agent.updatedAt = createTimestamp();
|
|
7892
|
+
this.touchAgent(agent);
|
|
7792
7893
|
this.writeReceipt(scope, payload, agent);
|
|
7793
7894
|
return clone(agent);
|
|
7794
7895
|
}
|
|
@@ -7810,24 +7911,48 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7810
7911
|
}
|
|
7811
7912
|
const runIds = new Set(runs.map((run) => run.id));
|
|
7812
7913
|
this.agents.delete(agent.id);
|
|
7914
|
+
this.recorder?.onAgentDelete(agent.id);
|
|
7813
7915
|
this.nextAgentSequence.delete(agent.id);
|
|
7814
7916
|
this.nextReadySequence.delete(agent.id);
|
|
7815
7917
|
this.historySeeds.delete(agent.id);
|
|
7816
|
-
for (const run of runs)
|
|
7918
|
+
for (const run of runs) {
|
|
7919
|
+
this.runs.delete(run.id);
|
|
7920
|
+
this.runReceiptKeys.delete(run.id);
|
|
7921
|
+
this.recorder?.onRunDelete(run.id);
|
|
7922
|
+
}
|
|
7817
7923
|
for (const [messageId, message] of this.messages) {
|
|
7818
|
-
if (runIds.has(message.runId))
|
|
7924
|
+
if (runIds.has(message.runId)) {
|
|
7925
|
+
this.messages.delete(messageId);
|
|
7926
|
+
this.recorder?.onMessageDelete(messageId);
|
|
7927
|
+
}
|
|
7819
7928
|
}
|
|
7820
7929
|
for (const [toolCallId, toolCall] of this.toolCalls) {
|
|
7821
|
-
if (runIds.has(toolCall.runId))
|
|
7930
|
+
if (runIds.has(toolCall.runId)) {
|
|
7931
|
+
this.toolCalls.delete(toolCallId);
|
|
7932
|
+
this.recorder?.onToolCallDelete(toolCallId);
|
|
7933
|
+
}
|
|
7822
7934
|
}
|
|
7935
|
+
const deletedEventIds = [];
|
|
7823
7936
|
for (let index = this.events.length - 1; index >= 0; index -= 1) {
|
|
7824
|
-
if (this.events[index].agentId === agent.id)
|
|
7937
|
+
if (this.events[index].agentId === agent.id) {
|
|
7938
|
+
deletedEventIds.push(this.events[index].id);
|
|
7939
|
+
this.events.splice(index, 1);
|
|
7940
|
+
}
|
|
7941
|
+
}
|
|
7942
|
+
if (deletedEventIds.length > 0) {
|
|
7943
|
+
this.recorder?.onEventsTruncate(deletedEventIds);
|
|
7825
7944
|
}
|
|
7826
7945
|
for (const [key] of this.idempotency) {
|
|
7827
|
-
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId))))
|
|
7946
|
+
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId)))) {
|
|
7947
|
+
this.idempotency.delete(key);
|
|
7948
|
+
this.recorder?.onIdempotencyDelete(key);
|
|
7949
|
+
}
|
|
7828
7950
|
}
|
|
7829
7951
|
for (const [key] of this.operationReceipts) {
|
|
7830
|
-
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId))))
|
|
7952
|
+
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId)))) {
|
|
7953
|
+
this.operationReceipts.delete(key);
|
|
7954
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
7955
|
+
}
|
|
7831
7956
|
}
|
|
7832
7957
|
}
|
|
7833
7958
|
reviseMessage(lease, input) {
|
|
@@ -7935,14 +8060,19 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7935
8060
|
run.revision += 1;
|
|
7936
8061
|
run.updatedAt = timestamp;
|
|
7937
8062
|
this.appendTransition(run, previousState, "cancelled", { reason: run.cancellationReason });
|
|
8063
|
+
this.dropRunOperationReceipts(run.id);
|
|
7938
8064
|
} else {
|
|
7939
8065
|
run.revision += 1;
|
|
7940
8066
|
run.updatedAt = timestamp;
|
|
8067
|
+
this.touchRun(run);
|
|
7941
8068
|
}
|
|
7942
8069
|
}
|
|
7943
8070
|
for (const [messageId, message] of this.messages) {
|
|
7944
8071
|
if (!affectedRunSet.has(message.runId)) continue;
|
|
7945
|
-
if (message.runId !== original.runId || message.sequenceWithinRun > original.sequenceWithinRun)
|
|
8072
|
+
if (message.runId !== original.runId || message.sequenceWithinRun > original.sequenceWithinRun) {
|
|
8073
|
+
this.messages.delete(messageId);
|
|
8074
|
+
this.recorder?.onMessageDelete(messageId);
|
|
8075
|
+
}
|
|
7946
8076
|
}
|
|
7947
8077
|
if (isSeedMessage) {
|
|
7948
8078
|
const targetIndex = seed.findIndex(({ id }) => id === original.id);
|
|
@@ -7956,10 +8086,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7956
8086
|
sequenceWithinRun: 0,
|
|
7957
8087
|
createdAt: timestamp
|
|
7958
8088
|
};
|
|
7959
|
-
this.
|
|
8089
|
+
this.storeMessage(revisedMessage);
|
|
7960
8090
|
this.runs.set(replacementRun.id, replacementRun);
|
|
8091
|
+
this.touchRun(replacementRun);
|
|
7961
8092
|
this.appendTransition(replacementRun, null, "queued");
|
|
7962
|
-
this.
|
|
8093
|
+
this.appendEvent({
|
|
7963
8094
|
...this.baseEvent(replacementRun),
|
|
7964
8095
|
kind: "message_revised",
|
|
7965
8096
|
message: revisedMessage,
|
|
@@ -7975,7 +8106,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7975
8106
|
affectedToolCallIds: affectedTools.map((toolCall) => toolCall.id),
|
|
7976
8107
|
...effectDigest === void 0 ? {} : { effectDigest }
|
|
7977
8108
|
};
|
|
7978
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8109
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, replacementRun.id);
|
|
7979
8110
|
return clone(result);
|
|
7980
8111
|
}
|
|
7981
8112
|
commitInteractionRecord(run, interaction, status, answer, reply) {
|
|
@@ -7997,7 +8128,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7997
8128
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
7998
8129
|
createdAt: now
|
|
7999
8130
|
};
|
|
8000
|
-
this.
|
|
8131
|
+
this.storeMessage(record);
|
|
8001
8132
|
this.appendMessage(run, record);
|
|
8002
8133
|
return record;
|
|
8003
8134
|
}
|
|
@@ -8046,12 +8177,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8046
8177
|
sequenceWithinRun: this.nextMessageSequence(waitingRun.id),
|
|
8047
8178
|
createdAt: now
|
|
8048
8179
|
};
|
|
8049
|
-
this.
|
|
8180
|
+
this.storeMessage(message);
|
|
8050
8181
|
this.appendMessage(waitingRun, message);
|
|
8051
8182
|
waitingRun.readySequence = this.nextReady(waitingRun.agentId);
|
|
8052
8183
|
waitingRun.state = "queued";
|
|
8053
8184
|
waitingRun.revision += 1;
|
|
8054
8185
|
waitingRun.updatedAt = now;
|
|
8186
|
+
this.touchRun(waitingRun);
|
|
8055
8187
|
this.appendTransition(waitingRun, "input_required", "queued");
|
|
8056
8188
|
this.writeReceipt(scope, payload, waitingRun);
|
|
8057
8189
|
return clone(waitingRun);
|
|
@@ -8073,6 +8205,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8073
8205
|
updatedAt: timestamp
|
|
8074
8206
|
};
|
|
8075
8207
|
this.runs.set(run.id, run);
|
|
8208
|
+
this.touchRun(run);
|
|
8076
8209
|
this.appendTransition(run, null, "queued");
|
|
8077
8210
|
this.writeReceipt(scope, payload, run);
|
|
8078
8211
|
return clone(run);
|
|
@@ -8115,7 +8248,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8115
8248
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
8116
8249
|
createdAt: createTimestamp()
|
|
8117
8250
|
};
|
|
8118
|
-
this.
|
|
8251
|
+
this.storeMessage(message);
|
|
8119
8252
|
committedMessages.push(message);
|
|
8120
8253
|
}
|
|
8121
8254
|
const execution = {
|
|
@@ -8127,10 +8260,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8127
8260
|
run.execution = execution;
|
|
8128
8261
|
run.revision += 1;
|
|
8129
8262
|
run.updatedAt = createTimestamp();
|
|
8263
|
+
this.touchRun(run);
|
|
8130
8264
|
for (const message of committedMessages) this.appendMessage(run, message);
|
|
8131
8265
|
this.appendTransition(run, "queued", "running");
|
|
8132
8266
|
const result = { run: clone(run), execution: clone(execution), history: this.activeHistory(run.agentId, run.agentSequence) };
|
|
8133
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8267
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8134
8268
|
return result;
|
|
8135
8269
|
}
|
|
8136
8270
|
failQueuedRun(lease, input) {
|
|
@@ -8146,9 +8280,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8146
8280
|
run.failure = clone(input.failure);
|
|
8147
8281
|
run.revision += 1;
|
|
8148
8282
|
run.updatedAt = createTimestamp();
|
|
8283
|
+
this.touchRun(run);
|
|
8149
8284
|
this.appendTransition(run, "queued", "failed", { failure: input.failure });
|
|
8285
|
+
this.dropRunOperationReceipts(run.id);
|
|
8150
8286
|
const result = clone(run);
|
|
8151
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8287
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8152
8288
|
return result;
|
|
8153
8289
|
}
|
|
8154
8290
|
commitPhaseEntered(lease, input) {
|
|
@@ -8164,10 +8300,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8164
8300
|
run.currentPhaseId = input.phaseId;
|
|
8165
8301
|
run.revision += 1;
|
|
8166
8302
|
run.updatedAt = createTimestamp();
|
|
8303
|
+
this.touchRun(run);
|
|
8167
8304
|
const visit2 = this.events.filter((event) => event.runId === run.id && event.kind === "phase_entered").length + 1;
|
|
8168
|
-
this.
|
|
8305
|
+
this.appendEvent(this.baseEvent(run, { kind: "phase_entered", executionId: input.execution.executionId, phaseId: input.phaseId, visit: visit2 }));
|
|
8169
8306
|
const result = clone(run);
|
|
8170
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8307
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8171
8308
|
return result;
|
|
8172
8309
|
}
|
|
8173
8310
|
/** Commit a parallel Phase's reply while its Run is still running. */
|
|
@@ -8188,12 +8325,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8188
8325
|
role: "assistant",
|
|
8189
8326
|
sequenceWithinRun: this.nextMessageSequence(run.id)
|
|
8190
8327
|
};
|
|
8191
|
-
this.
|
|
8328
|
+
this.storeMessage(message);
|
|
8192
8329
|
run.revision += 1;
|
|
8193
8330
|
run.updatedAt = createTimestamp();
|
|
8331
|
+
this.touchRun(run);
|
|
8194
8332
|
this.appendMessage(run, message);
|
|
8195
8333
|
const result = clone(run);
|
|
8196
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8334
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8197
8335
|
return result;
|
|
8198
8336
|
}
|
|
8199
8337
|
commitInputRequired(lease, input) {
|
|
@@ -8215,7 +8353,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8215
8353
|
...clone(input.prompt),
|
|
8216
8354
|
sequenceWithinRun: this.nextMessageSequence(run.id)
|
|
8217
8355
|
};
|
|
8218
|
-
this.
|
|
8356
|
+
this.storeMessage(prompt);
|
|
8219
8357
|
}
|
|
8220
8358
|
run.state = "input_required";
|
|
8221
8359
|
run.checkpoint = clone(input.checkpoint);
|
|
@@ -8230,12 +8368,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8230
8368
|
delete run.execution;
|
|
8231
8369
|
run.revision += 1;
|
|
8232
8370
|
run.updatedAt = createTimestamp();
|
|
8371
|
+
this.touchRun(run);
|
|
8233
8372
|
if (prompt) {
|
|
8234
8373
|
this.appendMessage(run, prompt);
|
|
8235
8374
|
}
|
|
8236
8375
|
this.appendTransition(run, "running", "input_required", { prompt, interactions, answers: run.interactionAnswers ?? {} });
|
|
8237
8376
|
const result = clone(run);
|
|
8238
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8377
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8239
8378
|
return result;
|
|
8240
8379
|
}
|
|
8241
8380
|
answerInteraction(lease, input) {
|
|
@@ -8283,8 +8422,9 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8283
8422
|
run.state = "queued";
|
|
8284
8423
|
this.appendTransition(run, "input_required", "queued");
|
|
8285
8424
|
}
|
|
8425
|
+
this.touchRun(run);
|
|
8286
8426
|
const result = clone(run);
|
|
8287
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8427
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8288
8428
|
return result;
|
|
8289
8429
|
}
|
|
8290
8430
|
reserveToolCall(lease, input) {
|
|
@@ -8358,17 +8498,18 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8358
8498
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
8359
8499
|
createdAt: timestamp
|
|
8360
8500
|
};
|
|
8361
|
-
for (const toolCall of toolCalls) this.
|
|
8362
|
-
this.
|
|
8501
|
+
for (const toolCall of toolCalls) this.storeToolCall(toolCall);
|
|
8502
|
+
this.storeMessage(requestMessage);
|
|
8363
8503
|
run.revision += 1;
|
|
8364
8504
|
run.updatedAt = timestamp;
|
|
8505
|
+
this.touchRun(run);
|
|
8365
8506
|
this.appendMessage(run, requestMessage);
|
|
8366
8507
|
for (const toolCall of toolCalls) this.appendToolTransition(run, { from: null, to: "pending" }, toolCall);
|
|
8367
8508
|
const result = {
|
|
8368
8509
|
run: clone(run),
|
|
8369
8510
|
toolCalls: toolCalls.map((toolCall) => clone(toolCall))
|
|
8370
8511
|
};
|
|
8371
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8512
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8372
8513
|
return result;
|
|
8373
8514
|
}
|
|
8374
8515
|
startToolCall(lease, input) {
|
|
@@ -8383,13 +8524,14 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8383
8524
|
if (toolCall.state !== "pending") throw new RuntimeError("run_state_conflict", { runId: run.id, expected: ["running"], actual: run.state });
|
|
8384
8525
|
toolCall.state = "running";
|
|
8385
8526
|
toolCall.executionId = input.execution.executionId;
|
|
8386
|
-
toolCall.executionId = input.execution.executionId;
|
|
8387
8527
|
toolCall.updatedAt = createTimestamp();
|
|
8528
|
+
this.storeToolCall(toolCall);
|
|
8388
8529
|
run.revision += 1;
|
|
8389
8530
|
run.updatedAt = toolCall.updatedAt;
|
|
8531
|
+
this.touchRun(run);
|
|
8390
8532
|
this.appendToolTransition(run, { from: "pending", to: "running" }, toolCall);
|
|
8391
8533
|
const result = { run: clone(run), toolCall: clone(toolCall) };
|
|
8392
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8534
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8393
8535
|
return result;
|
|
8394
8536
|
}
|
|
8395
8537
|
suspendToolCall(lease, input) {
|
|
@@ -8406,11 +8548,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8406
8548
|
}
|
|
8407
8549
|
toolCall.state = "pending";
|
|
8408
8550
|
toolCall.updatedAt = createTimestamp();
|
|
8551
|
+
this.storeToolCall(toolCall);
|
|
8409
8552
|
run.revision += 1;
|
|
8410
8553
|
run.updatedAt = toolCall.updatedAt;
|
|
8554
|
+
this.touchRun(run);
|
|
8411
8555
|
this.appendToolTransition(run, { from: "running", to: "pending" }, toolCall);
|
|
8412
8556
|
const result = { run: clone(run), toolCall: clone(toolCall) };
|
|
8413
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8557
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8414
8558
|
return result;
|
|
8415
8559
|
}
|
|
8416
8560
|
commitToolResult(lease, input) {
|
|
@@ -8442,15 +8586,17 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8442
8586
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
8443
8587
|
createdAt: createTimestamp()
|
|
8444
8588
|
};
|
|
8445
|
-
this.
|
|
8589
|
+
this.storeMessage(message);
|
|
8446
8590
|
toolCall.state = input.state;
|
|
8447
8591
|
toolCall.result = durableResult;
|
|
8448
8592
|
toolCall.resultMessageId = resultMessageId;
|
|
8449
8593
|
if (input.state === "indeterminate") toolCall.reason = input.reason;
|
|
8450
8594
|
else delete toolCall.reason;
|
|
8451
8595
|
toolCall.updatedAt = message.createdAt;
|
|
8596
|
+
this.storeToolCall(toolCall);
|
|
8452
8597
|
run.revision += 1;
|
|
8453
8598
|
run.updatedAt = message.createdAt;
|
|
8599
|
+
this.touchRun(run);
|
|
8454
8600
|
this.appendToolTransition(run, { from, to: input.state }, toolCall);
|
|
8455
8601
|
this.appendMessage(run, message);
|
|
8456
8602
|
if (input.state === "indeterminate") {
|
|
@@ -8471,10 +8617,12 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8471
8617
|
delete run.execution;
|
|
8472
8618
|
run.revision += 1;
|
|
8473
8619
|
run.updatedAt = createTimestamp();
|
|
8620
|
+
this.touchRun(run);
|
|
8474
8621
|
this.appendTransition(run, "running", "failed", { failure });
|
|
8622
|
+
this.dropRunOperationReceipts(run.id);
|
|
8475
8623
|
}
|
|
8476
8624
|
const result = { run: clone(run), toolCall: clone(toolCall) };
|
|
8477
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8625
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8478
8626
|
return result;
|
|
8479
8627
|
}
|
|
8480
8628
|
commitOutcome(lease, input) {
|
|
@@ -8492,7 +8640,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8492
8640
|
if (nextState === "failed" && !input.failure) throw new TypeError("failed Run requires a failure");
|
|
8493
8641
|
const output = input.output ? { ...clone(input.output), sequenceWithinRun: this.nextMessageSequence(run.id) } : void 0;
|
|
8494
8642
|
if (output) {
|
|
8495
|
-
this.
|
|
8643
|
+
this.storeMessage(output);
|
|
8496
8644
|
this.appendMessage(run, output);
|
|
8497
8645
|
}
|
|
8498
8646
|
run.state = nextState;
|
|
@@ -8504,9 +8652,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8504
8652
|
delete run.interactionAnswers;
|
|
8505
8653
|
run.revision += 1;
|
|
8506
8654
|
run.updatedAt = createTimestamp();
|
|
8655
|
+
this.touchRun(run);
|
|
8507
8656
|
this.appendTransition(run, "running", nextState, { outcome: input.outcome, failure: input.failure, output });
|
|
8657
|
+
this.dropRunOperationReceipts(run.id);
|
|
8508
8658
|
const result = clone(run);
|
|
8509
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8510
8659
|
return result;
|
|
8511
8660
|
}
|
|
8512
8661
|
cancelRun(lease, input) {
|
|
@@ -8526,7 +8675,6 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8526
8675
|
}
|
|
8527
8676
|
if (["completed", "failed", "cancelled"].includes(run.state)) {
|
|
8528
8677
|
const result2 = clone(run);
|
|
8529
|
-
if (input.expectedRevision !== void 0) this.writeOperationReceipt(operationKey, operationPayload, result2);
|
|
8530
8678
|
return result2;
|
|
8531
8679
|
}
|
|
8532
8680
|
const from = run.state;
|
|
@@ -8541,7 +8689,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8541
8689
|
for (const toolCall of activeToolCalls) this.interruptToolCall(run, toolCall, input.reason ?? "The Run was cancelled.");
|
|
8542
8690
|
if (input.output && (typeof input.output.content === "string" ? input.output.content.length > 0 : input.output.content.length > 0)) {
|
|
8543
8691
|
const output = { ...clone(input.output), sequenceWithinRun: this.nextMessageSequence(run.id) };
|
|
8544
|
-
this.
|
|
8692
|
+
this.storeMessage(output);
|
|
8545
8693
|
this.appendMessage(run, output);
|
|
8546
8694
|
}
|
|
8547
8695
|
if (run.openInteractions && run.openInteractions.length > 0) {
|
|
@@ -8564,9 +8712,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8564
8712
|
delete run.interactionAnswers;
|
|
8565
8713
|
run.revision += 1;
|
|
8566
8714
|
run.updatedAt = createTimestamp();
|
|
8715
|
+
this.touchRun(run);
|
|
8567
8716
|
this.appendTransition(run, from, "failed", { failure });
|
|
8717
|
+
this.dropRunOperationReceipts(run.id);
|
|
8568
8718
|
const result2 = clone(run);
|
|
8569
|
-
if (input.expectedRevision !== void 0) this.writeOperationReceipt(operationKey, operationPayload, result2);
|
|
8570
8719
|
return result2;
|
|
8571
8720
|
}
|
|
8572
8721
|
run.state = "cancelled";
|
|
@@ -8577,9 +8726,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8577
8726
|
delete run.interactionAnswers;
|
|
8578
8727
|
run.revision += 1;
|
|
8579
8728
|
run.updatedAt = createTimestamp();
|
|
8729
|
+
this.touchRun(run);
|
|
8580
8730
|
this.appendTransition(run, from, "cancelled", { reason: input.reason });
|
|
8731
|
+
this.dropRunOperationReceipts(run.id);
|
|
8581
8732
|
const result = clone(run);
|
|
8582
|
-
if (input.expectedRevision !== void 0) this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8583
8733
|
return result;
|
|
8584
8734
|
}
|
|
8585
8735
|
snapshotRun(lease, runId) {
|
|
@@ -8660,6 +8810,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8660
8810
|
const previous = this.consumerCheckpoints.get(input.consumerId);
|
|
8661
8811
|
if (previous !== void 0 && next <= this.parseCursor(previous)) return;
|
|
8662
8812
|
this.consumerCheckpoints.set(input.consumerId, input.cursor);
|
|
8813
|
+
this.recorder?.onConsumerCheckpointUpsert(input.consumerId, input.cursor);
|
|
8663
8814
|
}
|
|
8664
8815
|
compact(lease, input = {}) {
|
|
8665
8816
|
this.assertOwner(lease);
|
|
@@ -8693,11 +8844,15 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8693
8844
|
}
|
|
8694
8845
|
const deletedEvents = deleteThrough >= this.retentionFloor ? this.events.filter((event) => this.parseCursor(event.cursor) <= deleteThrough) : [];
|
|
8695
8846
|
if (deleteThrough >= this.retentionFloor) {
|
|
8847
|
+
const deletedEventIds = this.events.filter((event) => this.parseCursor(event.cursor) <= deleteThrough).map((event) => event.id);
|
|
8696
8848
|
this.events.splice(0, this.events.length, ...this.events.filter((event) => this.parseCursor(event.cursor) > deleteThrough));
|
|
8697
8849
|
this.retentionFloor = deleteThrough + 1;
|
|
8850
|
+
this.recorder?.onRetentionFloorChange(this.retentionFloor);
|
|
8851
|
+
this.recorder?.onEventsTruncate(deletedEventIds);
|
|
8698
8852
|
for (const [consumerId, cursor] of this.consumerCheckpoints) {
|
|
8699
8853
|
if (this.parseCursor(cursor) < this.retentionFloor - 1) {
|
|
8700
8854
|
this.consumerCheckpoints.delete(consumerId);
|
|
8855
|
+
this.recorder?.onConsumerCheckpointDelete(consumerId);
|
|
8701
8856
|
}
|
|
8702
8857
|
}
|
|
8703
8858
|
}
|
|
@@ -8706,11 +8861,21 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8706
8861
|
const deletedRunIds = deletableRuns.map((run) => run.id);
|
|
8707
8862
|
const deletedRunSet = new Set(deletedRunIds);
|
|
8708
8863
|
const deletedTools = [...this.toolCalls.values()].filter((tool) => deletedRunSet.has(tool.runId));
|
|
8709
|
-
for (const runId of deletedRunIds)
|
|
8864
|
+
for (const runId of deletedRunIds) {
|
|
8865
|
+
this.runs.delete(runId);
|
|
8866
|
+
this.runReceiptKeys.delete(runId);
|
|
8867
|
+
this.recorder?.onRunDelete(runId);
|
|
8868
|
+
}
|
|
8710
8869
|
for (const [messageId, message] of this.messages) {
|
|
8711
|
-
if (deletedRunSet.has(message.runId))
|
|
8870
|
+
if (deletedRunSet.has(message.runId)) {
|
|
8871
|
+
this.messages.delete(messageId);
|
|
8872
|
+
this.recorder?.onMessageDelete(messageId);
|
|
8873
|
+
}
|
|
8874
|
+
}
|
|
8875
|
+
for (const tool of deletedTools) {
|
|
8876
|
+
this.toolCalls.delete(tool.id);
|
|
8877
|
+
this.recorder?.onToolCallDelete(tool.id);
|
|
8712
8878
|
}
|
|
8713
|
-
for (const tool of deletedTools) this.toolCalls.delete(tool.id);
|
|
8714
8879
|
return {
|
|
8715
8880
|
deletedRunIds,
|
|
8716
8881
|
deletedToolCallIds: deletedTools.map((tool) => tool.id),
|
|
@@ -8732,7 +8897,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8732
8897
|
return receipt.result;
|
|
8733
8898
|
}
|
|
8734
8899
|
writeReceipt(scope, payload, result) {
|
|
8735
|
-
|
|
8900
|
+
const key = encodeIdempotencyScope(this.incarnation, scope);
|
|
8901
|
+
const receipt = { payload, result: clone(result) };
|
|
8902
|
+
this.idempotency.set(key, receipt);
|
|
8903
|
+
this.recorder?.onIdempotencyUpsert(key, receipt);
|
|
8736
8904
|
}
|
|
8737
8905
|
replayOperation(key, payload) {
|
|
8738
8906
|
const receipt = this.operationReceipts.get(key);
|
|
@@ -8740,8 +8908,19 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8740
8908
|
if (receipt.payload !== payload) throw new Error(`Idempotency payload conflict for ${key}.`);
|
|
8741
8909
|
return receipt.result;
|
|
8742
8910
|
}
|
|
8743
|
-
writeOperationReceipt(key, payload, result) {
|
|
8744
|
-
|
|
8911
|
+
writeOperationReceipt(key, payload, result, runId) {
|
|
8912
|
+
const receipt = { payload, result: clone(result) };
|
|
8913
|
+
this.operationReceipts.set(key, receipt);
|
|
8914
|
+
const resolvedRunId = runId ?? this.inferRunIdForReceipt(key, payload);
|
|
8915
|
+
if (resolvedRunId) {
|
|
8916
|
+
let keys = this.runReceiptKeys.get(resolvedRunId);
|
|
8917
|
+
if (!keys) {
|
|
8918
|
+
keys = /* @__PURE__ */ new Set();
|
|
8919
|
+
this.runReceiptKeys.set(resolvedRunId, keys);
|
|
8920
|
+
}
|
|
8921
|
+
keys.add(key);
|
|
8922
|
+
}
|
|
8923
|
+
this.recorder?.onOperationReceiptUpsert(key, receipt);
|
|
8745
8924
|
}
|
|
8746
8925
|
/**
|
|
8747
8926
|
* A Claim receipt exists for idempotent replay of one live Execution Attempt
|
|
@@ -8749,7 +8928,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8749
8928
|
* one history snapshot per Agent instead of one per Attempt.
|
|
8750
8929
|
*/
|
|
8751
8930
|
dropClaimReceipt(execution) {
|
|
8752
|
-
if (execution)
|
|
8931
|
+
if (execution) {
|
|
8932
|
+
const key = `claim:${execution.executionId}`;
|
|
8933
|
+
this.operationReceipts.delete(key);
|
|
8934
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
8935
|
+
}
|
|
8753
8936
|
}
|
|
8754
8937
|
/**
|
|
8755
8938
|
* A new owner fences the Execution Attempts of the previous one, so no Claim
|
|
@@ -8765,6 +8948,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8765
8948
|
for (const key of [...this.operationReceipts.keys()]) {
|
|
8766
8949
|
if (key.startsWith("claim:") && !liveExecutions.has(key.slice("claim:".length))) {
|
|
8767
8950
|
this.operationReceipts.delete(key);
|
|
8951
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
8768
8952
|
}
|
|
8769
8953
|
}
|
|
8770
8954
|
}
|
|
@@ -8803,14 +8987,16 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8803
8987
|
};
|
|
8804
8988
|
const from = toolCall.state;
|
|
8805
8989
|
const to = from === "running" ? "indeterminate" : "failed";
|
|
8806
|
-
this.
|
|
8990
|
+
this.storeMessage(message);
|
|
8807
8991
|
toolCall.state = to;
|
|
8808
8992
|
toolCall.result = durableResult;
|
|
8809
8993
|
toolCall.resultMessageId = message.id;
|
|
8810
8994
|
if (to === "indeterminate") toolCall.reason = reason;
|
|
8811
8995
|
toolCall.updatedAt = message.createdAt;
|
|
8996
|
+
this.storeToolCall(toolCall);
|
|
8812
8997
|
run.revision += 1;
|
|
8813
8998
|
run.updatedAt = message.createdAt;
|
|
8999
|
+
this.touchRun(run);
|
|
8814
9000
|
this.appendToolTransition(run, { from, to }, toolCall);
|
|
8815
9001
|
this.appendMessage(run, message);
|
|
8816
9002
|
}
|
|
@@ -8911,6 +9097,7 @@ ${record.summary}`,
|
|
|
8911
9097
|
if (existing?.id === record.id) return clone(existing);
|
|
8912
9098
|
const next = clone(record);
|
|
8913
9099
|
this.contextCompactions.set(record.agentId, next);
|
|
9100
|
+
this.recorder?.onContextCompactionUpsert(record.agentId, next);
|
|
8914
9101
|
return clone(next);
|
|
8915
9102
|
}
|
|
8916
9103
|
activeHistory(agentId, beforeSequence) {
|
|
@@ -8920,7 +9107,7 @@ ${record.summary}`,
|
|
|
8920
9107
|
].map((message) => ({ ...message, messageRevision: message.messageRevision ?? 0 })));
|
|
8921
9108
|
}
|
|
8922
9109
|
appendMessage(run, message) {
|
|
8923
|
-
this.
|
|
9110
|
+
this.appendEvent(this.baseEvent(run, {
|
|
8924
9111
|
kind: "message_committed",
|
|
8925
9112
|
message
|
|
8926
9113
|
}));
|
|
@@ -8936,13 +9123,14 @@ ${record.summary}`,
|
|
|
8936
9123
|
...to === "failed" && options?.failure ? { failure: options.failure } : {},
|
|
8937
9124
|
...to === "cancelled" && options?.reason ? { reason: options.reason } : {}
|
|
8938
9125
|
};
|
|
8939
|
-
this.
|
|
9126
|
+
this.touchRun(run);
|
|
9127
|
+
this.appendEvent(transition);
|
|
8940
9128
|
}
|
|
8941
9129
|
appendToolTransition(run, transition, toolCall) {
|
|
8942
|
-
this.
|
|
9130
|
+
this.appendEvent(this.baseEvent(run, {
|
|
8943
9131
|
kind: "tool_state_changed",
|
|
8944
9132
|
transition,
|
|
8945
|
-
toolCall
|
|
9133
|
+
toolCall: clone(toolCall)
|
|
8946
9134
|
}));
|
|
8947
9135
|
}
|
|
8948
9136
|
baseEvent(run, extra) {
|
|
@@ -9318,6 +9506,94 @@ var CURRENT_SCHEMA_SQL = `
|
|
|
9318
9506
|
CREATE INDEX runs_active_idx ON runs (agent_id, state, agent_sequence);
|
|
9319
9507
|
CREATE INDEX run_events_sequence_idx ON run_events (sequence);
|
|
9320
9508
|
`;
|
|
9509
|
+
var ChangeTracker = class {
|
|
9510
|
+
upsertedAgents = /* @__PURE__ */ new Map();
|
|
9511
|
+
deletedAgentIds = /* @__PURE__ */ new Set();
|
|
9512
|
+
upsertedRuns = /* @__PURE__ */ new Map();
|
|
9513
|
+
deletedRunIds = /* @__PURE__ */ new Set();
|
|
9514
|
+
insertedMessages = /* @__PURE__ */ new Map();
|
|
9515
|
+
deletedMessageIds = /* @__PURE__ */ new Set();
|
|
9516
|
+
upsertedToolCalls = /* @__PURE__ */ new Map();
|
|
9517
|
+
deletedToolCallIds = /* @__PURE__ */ new Set();
|
|
9518
|
+
appendedEvents = [];
|
|
9519
|
+
truncatedEventIds = /* @__PURE__ */ new Set();
|
|
9520
|
+
upsertedIdempotency = /* @__PURE__ */ new Map();
|
|
9521
|
+
deletedIdempotencyScopes = /* @__PURE__ */ new Set();
|
|
9522
|
+
upsertedOperationReceipts = /* @__PURE__ */ new Map();
|
|
9523
|
+
deletedOperationReceiptKeys = /* @__PURE__ */ new Set();
|
|
9524
|
+
upsertedConsumerCheckpoints = /* @__PURE__ */ new Map();
|
|
9525
|
+
deletedConsumerCheckpoints = /* @__PURE__ */ new Set();
|
|
9526
|
+
upsertedContextCompactions = /* @__PURE__ */ new Map();
|
|
9527
|
+
retentionFloorChanged;
|
|
9528
|
+
onAgentUpsert(agent) {
|
|
9529
|
+
this.deletedAgentIds.delete(agent.id);
|
|
9530
|
+
this.upsertedAgents.set(agent.id, agent);
|
|
9531
|
+
}
|
|
9532
|
+
onAgentDelete(agentId) {
|
|
9533
|
+
this.upsertedAgents.delete(agentId);
|
|
9534
|
+
this.deletedAgentIds.add(agentId);
|
|
9535
|
+
}
|
|
9536
|
+
onRunUpsert(run) {
|
|
9537
|
+
this.deletedRunIds.delete(run.id);
|
|
9538
|
+
this.upsertedRuns.set(run.id, run);
|
|
9539
|
+
}
|
|
9540
|
+
onRunDelete(runId) {
|
|
9541
|
+
this.upsertedRuns.delete(runId);
|
|
9542
|
+
this.deletedRunIds.add(runId);
|
|
9543
|
+
}
|
|
9544
|
+
onMessageInsert(message) {
|
|
9545
|
+
this.deletedMessageIds.delete(message.id);
|
|
9546
|
+
this.insertedMessages.set(message.id, message);
|
|
9547
|
+
}
|
|
9548
|
+
onMessageDelete(messageId) {
|
|
9549
|
+
this.insertedMessages.delete(messageId);
|
|
9550
|
+
this.deletedMessageIds.add(messageId);
|
|
9551
|
+
}
|
|
9552
|
+
onToolCallUpsert(toolCall) {
|
|
9553
|
+
this.deletedToolCallIds.delete(toolCall.id);
|
|
9554
|
+
this.upsertedToolCalls.set(toolCall.id, toolCall);
|
|
9555
|
+
}
|
|
9556
|
+
onToolCallDelete(toolCallId) {
|
|
9557
|
+
this.upsertedToolCalls.delete(toolCallId);
|
|
9558
|
+
this.deletedToolCallIds.add(toolCallId);
|
|
9559
|
+
}
|
|
9560
|
+
onEventAppend(event) {
|
|
9561
|
+
this.appendedEvents.push(event);
|
|
9562
|
+
}
|
|
9563
|
+
onEventsTruncate(deletedEventIds) {
|
|
9564
|
+
for (const id of deletedEventIds) this.truncatedEventIds.add(id);
|
|
9565
|
+
}
|
|
9566
|
+
onIdempotencyUpsert(scope, receipt) {
|
|
9567
|
+
this.deletedIdempotencyScopes.delete(scope);
|
|
9568
|
+
this.upsertedIdempotency.set(scope, receipt);
|
|
9569
|
+
}
|
|
9570
|
+
onIdempotencyDelete(scope) {
|
|
9571
|
+
this.upsertedIdempotency.delete(scope);
|
|
9572
|
+
this.deletedIdempotencyScopes.add(scope);
|
|
9573
|
+
}
|
|
9574
|
+
onOperationReceiptUpsert(key, receipt) {
|
|
9575
|
+
this.deletedOperationReceiptKeys.delete(key);
|
|
9576
|
+
this.upsertedOperationReceipts.set(key, receipt);
|
|
9577
|
+
}
|
|
9578
|
+
onOperationReceiptDelete(key) {
|
|
9579
|
+
this.upsertedOperationReceipts.delete(key);
|
|
9580
|
+
this.deletedOperationReceiptKeys.add(key);
|
|
9581
|
+
}
|
|
9582
|
+
onConsumerCheckpointUpsert(consumerId, cursor) {
|
|
9583
|
+
this.deletedConsumerCheckpoints.delete(consumerId);
|
|
9584
|
+
this.upsertedConsumerCheckpoints.set(consumerId, cursor);
|
|
9585
|
+
}
|
|
9586
|
+
onConsumerCheckpointDelete(consumerId) {
|
|
9587
|
+
this.upsertedConsumerCheckpoints.delete(consumerId);
|
|
9588
|
+
this.deletedConsumerCheckpoints.add(consumerId);
|
|
9589
|
+
}
|
|
9590
|
+
onContextCompactionUpsert(agentId, record) {
|
|
9591
|
+
this.upsertedContextCompactions.set(agentId, record);
|
|
9592
|
+
}
|
|
9593
|
+
onRetentionFloorChange(floor) {
|
|
9594
|
+
this.retentionFloorChanged = floor;
|
|
9595
|
+
}
|
|
9596
|
+
};
|
|
9321
9597
|
var SqliteStore = class {
|
|
9322
9598
|
database;
|
|
9323
9599
|
archiveRoot;
|
|
@@ -9326,6 +9602,25 @@ var SqliteStore = class {
|
|
|
9326
9602
|
mirroredAgents = /* @__PURE__ */ new Set();
|
|
9327
9603
|
closed = false;
|
|
9328
9604
|
configured = false;
|
|
9605
|
+
cachedMemory;
|
|
9606
|
+
cachedOwner;
|
|
9607
|
+
isLegacyState = false;
|
|
9608
|
+
stmtUpsertAgent;
|
|
9609
|
+
stmtDeleteAgent;
|
|
9610
|
+
stmtUpsertRun;
|
|
9611
|
+
stmtDeleteRun;
|
|
9612
|
+
stmtInsertMessage;
|
|
9613
|
+
stmtDeleteMessage;
|
|
9614
|
+
stmtUpsertToolCall;
|
|
9615
|
+
stmtDeleteToolCall;
|
|
9616
|
+
stmtInsertEvent;
|
|
9617
|
+
stmtDeleteEvent;
|
|
9618
|
+
stmtUpsertIdempotency;
|
|
9619
|
+
stmtDeleteIdempotency;
|
|
9620
|
+
stmtUpsertCheckpoint;
|
|
9621
|
+
stmtDeleteCheckpoint;
|
|
9622
|
+
stmtUpdateMeta;
|
|
9623
|
+
stmtUpdateState;
|
|
9329
9624
|
constructor(filename = ":memory:") {
|
|
9330
9625
|
this.database = new Database(filename, { create: true, readwrite: true, strict: true });
|
|
9331
9626
|
this.archiveRoot = filename === ":memory:" ? join6(tmpdir2(), `rowan-context-archives-${crypto.randomUUID()}`) : join6(dirname7(resolve8(filename)), "context-archives");
|
|
@@ -9346,7 +9641,26 @@ var SqliteStore = class {
|
|
|
9346
9641
|
}
|
|
9347
9642
|
const replay = ownerLease(row);
|
|
9348
9643
|
this.writeOwner({ ...row, expires_at: now + input.leaseMs });
|
|
9349
|
-
|
|
9644
|
+
const newLease2 = { ...replay, expiresAt: new Date(now + input.leaseMs).toISOString() };
|
|
9645
|
+
if (!this.cachedMemory || this.cachedOwner?.epoch !== replay.epoch) {
|
|
9646
|
+
const state2 = this.readState();
|
|
9647
|
+
const memory2 = InMemoryStore.fromState(state2);
|
|
9648
|
+
memory2.attachOwner(newLease2);
|
|
9649
|
+
const tracker2 = new ChangeTracker();
|
|
9650
|
+
memory2.setChangeRecorder(tracker2);
|
|
9651
|
+
try {
|
|
9652
|
+
memory2.dropSettledClaimReceipts();
|
|
9653
|
+
memory2.compactTerminalReceipts();
|
|
9654
|
+
} finally {
|
|
9655
|
+
memory2.setChangeRecorder(void 0);
|
|
9656
|
+
}
|
|
9657
|
+
this.ensureTableBackedStorage(memory2, tracker2, this.isLegacyState);
|
|
9658
|
+
this.cachedMemory = memory2;
|
|
9659
|
+
} else {
|
|
9660
|
+
this.cachedMemory.attachOwner(newLease2);
|
|
9661
|
+
}
|
|
9662
|
+
this.cachedOwner = newLease2;
|
|
9663
|
+
return newLease2;
|
|
9350
9664
|
}
|
|
9351
9665
|
const state = this.readState();
|
|
9352
9666
|
const memory = InMemoryStore.fromState(state);
|
|
@@ -9365,22 +9679,42 @@ var SqliteStore = class {
|
|
|
9365
9679
|
released_epoch: row.released_epoch
|
|
9366
9680
|
};
|
|
9367
9681
|
this.writeOwner(next);
|
|
9368
|
-
|
|
9369
|
-
this.persistState(memory.exportState());
|
|
9370
|
-
return {
|
|
9682
|
+
const newLease = {
|
|
9371
9683
|
ownerId: input.ownerId,
|
|
9372
9684
|
token,
|
|
9373
9685
|
epoch,
|
|
9374
9686
|
expiresAt: new Date(now + input.leaseMs).toISOString()
|
|
9375
9687
|
};
|
|
9688
|
+
memory.attachOwner(newLease);
|
|
9689
|
+
const tracker = new ChangeTracker();
|
|
9690
|
+
memory.setChangeRecorder(tracker);
|
|
9691
|
+
try {
|
|
9692
|
+
memory.dropSettledClaimReceipts();
|
|
9693
|
+
memory.compactTerminalReceipts();
|
|
9694
|
+
} finally {
|
|
9695
|
+
memory.setChangeRecorder(void 0);
|
|
9696
|
+
}
|
|
9697
|
+
this.ensureTableBackedStorage(memory, tracker, this.isLegacyState);
|
|
9698
|
+
this.cachedMemory = memory;
|
|
9699
|
+
this.cachedOwner = newLease;
|
|
9700
|
+
return newLease;
|
|
9376
9701
|
});
|
|
9377
9702
|
return new SqliteOwnedStore(this, lease);
|
|
9378
9703
|
}
|
|
9379
9704
|
close() {
|
|
9380
9705
|
if (this.closed) return;
|
|
9381
9706
|
this.closed = true;
|
|
9707
|
+
this.cachedMemory = void 0;
|
|
9708
|
+
this.cachedOwner = void 0;
|
|
9382
9709
|
this.database.close();
|
|
9383
9710
|
}
|
|
9711
|
+
exportState() {
|
|
9712
|
+
if (this.cachedMemory) {
|
|
9713
|
+
return this.cachedMemory.exportState();
|
|
9714
|
+
}
|
|
9715
|
+
const state = this.readState();
|
|
9716
|
+
return InMemoryStore.fromState(state).exportState();
|
|
9717
|
+
}
|
|
9384
9718
|
/** Filesystem location owned by this Store for one Agent's readable archive. */
|
|
9385
9719
|
contextArchiveDir(agentId) {
|
|
9386
9720
|
return join6(this.archiveRoot, String(agentId));
|
|
@@ -9465,31 +9799,7 @@ var SqliteStore = class {
|
|
|
9465
9799
|
}
|
|
9466
9800
|
async listEvents(lease, input = {}) {
|
|
9467
9801
|
this.assertOpen();
|
|
9468
|
-
return this.
|
|
9469
|
-
this.requireMatchingOwner(lease, true);
|
|
9470
|
-
const retentionRow = this.database.query(
|
|
9471
|
-
"SELECT value FROM runtime_meta WHERE key = ?"
|
|
9472
|
-
).get(RETENTION_FLOOR_KEY);
|
|
9473
|
-
const retentionFloor = Math.max(1, Number(retentionRow?.value ?? "1"));
|
|
9474
|
-
const after = input.after ? parseEventCursor(lease, input.after) : retentionFloor - 1;
|
|
9475
|
-
if (input.after && after < retentionFloor - 1) {
|
|
9476
|
-
throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "expired" });
|
|
9477
|
-
}
|
|
9478
|
-
if (input.after) {
|
|
9479
|
-
const latest = this.database.query(
|
|
9480
|
-
"SELECT max(sequence) AS sequence FROM run_events"
|
|
9481
|
-
).get();
|
|
9482
|
-
const waterline = latest.sequence ?? 0;
|
|
9483
|
-
if (after > waterline) {
|
|
9484
|
-
throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "beyond_waterline" });
|
|
9485
|
-
}
|
|
9486
|
-
if (after === waterline) return [];
|
|
9487
|
-
}
|
|
9488
|
-
const rows = this.database.query(
|
|
9489
|
-
"SELECT payload_json FROM run_events ORDER BY sequence"
|
|
9490
|
-
).all();
|
|
9491
|
-
return rows.map((row) => JSON.parse(row.payload_json)).filter((event) => parseEventCursor(lease, event.cursor) > after);
|
|
9492
|
-
});
|
|
9802
|
+
return this.read(lease, (memory) => memory.listEvents(lease, input));
|
|
9493
9803
|
}
|
|
9494
9804
|
async openConsumer(lease, consumerId) {
|
|
9495
9805
|
return this.invoke(lease, (store, current) => store.openConsumer(current, consumerId), false);
|
|
@@ -9513,7 +9823,12 @@ var SqliteStore = class {
|
|
|
9513
9823
|
const row = this.requireMatchingOwner(lease, false);
|
|
9514
9824
|
const expiresAt = Date.now() + leaseMs;
|
|
9515
9825
|
this.writeOwner({ ...row, expires_at: expiresAt });
|
|
9516
|
-
|
|
9826
|
+
const nextLease = { ...lease, expiresAt: new Date(expiresAt).toISOString() };
|
|
9827
|
+
if (this.cachedOwner && this.cachedOwner.token === lease.token) {
|
|
9828
|
+
this.cachedOwner = nextLease;
|
|
9829
|
+
this.cachedMemory?.attachOwner(nextLease);
|
|
9830
|
+
}
|
|
9831
|
+
return nextLease;
|
|
9517
9832
|
});
|
|
9518
9833
|
}
|
|
9519
9834
|
async sealAndReleaseOwner(lease) {
|
|
@@ -9524,27 +9839,75 @@ var SqliteStore = class {
|
|
|
9524
9839
|
if (row.owner_id !== lease.ownerId || row.owner_token !== lease.token || row.epoch !== lease.epoch) {
|
|
9525
9840
|
throw ownershipLost2(lease, row);
|
|
9526
9841
|
}
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9842
|
+
if (!this.cachedMemory || this.cachedOwner?.epoch !== lease.epoch) {
|
|
9843
|
+
this.cachedMemory = InMemoryStore.fromState(this.readState());
|
|
9844
|
+
this.cachedOwner = lease;
|
|
9845
|
+
}
|
|
9846
|
+
const tracker = new ChangeTracker();
|
|
9847
|
+
this.cachedMemory.setChangeRecorder(tracker);
|
|
9848
|
+
try {
|
|
9849
|
+
this.cachedMemory.attachOwner(lease);
|
|
9850
|
+
this.cachedMemory.interruptOwner(lease.epoch, "The Runtime owner was sealed.");
|
|
9851
|
+
} finally {
|
|
9852
|
+
this.cachedMemory.setChangeRecorder(void 0);
|
|
9853
|
+
}
|
|
9854
|
+
this.persistChanges(tracker, this.cachedMemory);
|
|
9855
|
+
this.mirrorChanges(tracker);
|
|
9531
9856
|
this.writeOwner({ ...row, owner_id: null, owner_token: null, expires_at: null, released_epoch: lease.epoch });
|
|
9857
|
+
this.cachedMemory = void 0;
|
|
9858
|
+
this.cachedOwner = void 0;
|
|
9532
9859
|
});
|
|
9533
9860
|
}
|
|
9534
|
-
|
|
9861
|
+
read(lease, operation) {
|
|
9862
|
+
this.assertOpen();
|
|
9863
|
+
this.requireMatchingOwner(lease, true);
|
|
9864
|
+
if (!this.cachedMemory || this.cachedOwner?.epoch !== lease.epoch) {
|
|
9865
|
+
this.cachedMemory = InMemoryStore.fromState(this.readState());
|
|
9866
|
+
this.cachedMemory.attachOwner(lease);
|
|
9867
|
+
this.cachedOwner = lease;
|
|
9868
|
+
} else {
|
|
9869
|
+
this.cachedMemory.attachOwner(lease);
|
|
9870
|
+
}
|
|
9871
|
+
return operation(this.cachedMemory);
|
|
9872
|
+
}
|
|
9873
|
+
write(lease, operation) {
|
|
9535
9874
|
this.assertOpen();
|
|
9536
9875
|
return this.immediateTransaction(() => {
|
|
9537
9876
|
this.requireMatchingOwner(lease, true);
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
this.
|
|
9877
|
+
if (!this.cachedMemory || this.cachedOwner?.epoch !== lease.epoch) {
|
|
9878
|
+
this.cachedMemory = InMemoryStore.fromState(this.readState());
|
|
9879
|
+
this.cachedMemory.attachOwner(lease);
|
|
9880
|
+
this.cachedOwner = lease;
|
|
9881
|
+
} else {
|
|
9882
|
+
this.cachedMemory.attachOwner(lease);
|
|
9883
|
+
}
|
|
9884
|
+
const tracker = new ChangeTracker();
|
|
9885
|
+
this.cachedMemory.setChangeRecorder(tracker);
|
|
9886
|
+
let result;
|
|
9887
|
+
try {
|
|
9888
|
+
result = operation(this.cachedMemory);
|
|
9889
|
+
} catch (error) {
|
|
9890
|
+
this.cachedMemory.setChangeRecorder(void 0);
|
|
9891
|
+
this.cachedMemory = void 0;
|
|
9892
|
+
throw error;
|
|
9893
|
+
}
|
|
9894
|
+
this.cachedMemory.setChangeRecorder(void 0);
|
|
9895
|
+
try {
|
|
9896
|
+
this.persistChanges(tracker, this.cachedMemory);
|
|
9897
|
+
this.mirrorChanges(tracker);
|
|
9898
|
+
} catch (error) {
|
|
9899
|
+
this.cachedMemory = void 0;
|
|
9900
|
+
throw error;
|
|
9544
9901
|
}
|
|
9545
9902
|
return result;
|
|
9546
9903
|
});
|
|
9547
9904
|
}
|
|
9905
|
+
invoke(lease, operation, persist = true) {
|
|
9906
|
+
if (persist) {
|
|
9907
|
+
return this.write(lease, (memory) => operation(memory, lease));
|
|
9908
|
+
}
|
|
9909
|
+
return this.read(lease, (memory) => operation(memory, lease));
|
|
9910
|
+
}
|
|
9548
9911
|
ensureSchema() {
|
|
9549
9912
|
const catalog = this.catalog();
|
|
9550
9913
|
if (catalog.length > 0 && !this.isCurrentSchema(catalog)) {
|
|
@@ -9561,7 +9924,7 @@ var SqliteStore = class {
|
|
|
9561
9924
|
this.database.run("INSERT INTO runtime_meta (key, value) VALUES (?, ?)", [RETENTION_FLOOR_KEY, "1"]);
|
|
9562
9925
|
const state = new InMemoryStore();
|
|
9563
9926
|
this.database.run("INSERT INTO runtime_owner (singleton, epoch) VALUES (?, ?)", [STATE_ROW, 0]);
|
|
9564
|
-
this.database.run("INSERT INTO runtime_state (singleton, state_json) VALUES (?, ?)", [STATE_ROW, JSON.stringify(state.
|
|
9927
|
+
this.database.run("INSERT INTO runtime_state (singleton, state_json) VALUES (?, ?)", [STATE_ROW, JSON.stringify(state.exportMetadata())]);
|
|
9565
9928
|
});
|
|
9566
9929
|
return;
|
|
9567
9930
|
}
|
|
@@ -9600,13 +9963,267 @@ var SqliteStore = class {
|
|
|
9600
9963
|
readState() {
|
|
9601
9964
|
const row = this.database.query("SELECT state_json FROM runtime_state WHERE singleton = ?").get(STATE_ROW);
|
|
9602
9965
|
if (!row) throw new RuntimeError("store_unavailable", { operation: "read_state", retryable: false, reason: "runtime_state row is missing" });
|
|
9603
|
-
|
|
9966
|
+
const parsed = JSON.parse(row.state_json);
|
|
9967
|
+
if (parsed.agents && Array.isArray(parsed.agents)) {
|
|
9968
|
+
this.isLegacyState = true;
|
|
9969
|
+
return parsed;
|
|
9970
|
+
}
|
|
9971
|
+
this.isLegacyState = false;
|
|
9972
|
+
return this.loadTableBackedState(parsed);
|
|
9973
|
+
}
|
|
9974
|
+
loadTableBackedState(metadata) {
|
|
9975
|
+
const agentRows = this.database.query(
|
|
9976
|
+
"SELECT id, metadata_json, config_token, config_identity, created_at, activated_at, updated_at FROM agents ORDER BY created_at"
|
|
9977
|
+
).all();
|
|
9978
|
+
const agents = agentRows.map((row) => ({
|
|
9979
|
+
id: row.id,
|
|
9980
|
+
...row.metadata_json ? { metadata: JSON.parse(row.metadata_json) } : {},
|
|
9981
|
+
...row.config_token ? { currentConfigToken: row.config_token } : {},
|
|
9982
|
+
...row.config_identity ? { currentConfigIdentity: row.config_identity } : {},
|
|
9983
|
+
createdAt: row.created_at,
|
|
9984
|
+
...row.activated_at ? { activatedAt: row.activated_at } : {},
|
|
9985
|
+
updatedAt: row.updated_at
|
|
9986
|
+
}));
|
|
9987
|
+
const runRows = this.database.query("SELECT payload_json FROM runs").all();
|
|
9988
|
+
const runs = runRows.map((r) => JSON.parse(r.payload_json));
|
|
9989
|
+
const messageRows = this.database.query("SELECT payload_json FROM messages ORDER BY run_id, sequence_within_run").all();
|
|
9990
|
+
const messages = messageRows.map((m) => JSON.parse(m.payload_json));
|
|
9991
|
+
const toolRows = this.database.query("SELECT payload_json FROM tool_calls").all();
|
|
9992
|
+
const toolCalls = toolRows.map((t) => JSON.parse(t.payload_json));
|
|
9993
|
+
const eventRows = this.database.query("SELECT payload_json FROM run_events ORDER BY sequence").all();
|
|
9994
|
+
const events = eventRows.map((e) => JSON.parse(e.payload_json));
|
|
9995
|
+
const idempotencyRows = this.database.query("SELECT scope, payload_json, result_json FROM idempotency").all();
|
|
9996
|
+
const idempotency = [];
|
|
9997
|
+
const operationReceipts = [];
|
|
9998
|
+
for (const row of idempotencyRows) {
|
|
9999
|
+
const receipt = { payload: row.payload_json, result: JSON.parse(row.result_json) };
|
|
10000
|
+
if (row.scope.startsWith("operation:")) {
|
|
10001
|
+
operationReceipts.push([row.scope.slice("operation:".length), receipt]);
|
|
10002
|
+
} else {
|
|
10003
|
+
idempotency.push([row.scope, receipt]);
|
|
10004
|
+
}
|
|
10005
|
+
}
|
|
10006
|
+
const cpRows = this.database.query("SELECT consumer_id, sequence FROM consumer_checkpoints").all();
|
|
10007
|
+
const consumerCheckpoints = cpRows.map((r) => [r.consumer_id, `${metadata.incarnation}:${r.sequence}`]);
|
|
10008
|
+
const retentionRow = this.database.query("SELECT value FROM runtime_meta WHERE key = ?").get(RETENTION_FLOOR_KEY);
|
|
10009
|
+
const retentionFloor = Math.max(1, Number(retentionRow?.value ?? metadata.retentionFloor ?? "1"));
|
|
10010
|
+
return {
|
|
10011
|
+
incarnation: metadata.incarnation,
|
|
10012
|
+
agents,
|
|
10013
|
+
runs,
|
|
10014
|
+
messages,
|
|
10015
|
+
toolCalls,
|
|
10016
|
+
events,
|
|
10017
|
+
idempotency,
|
|
10018
|
+
operationReceipts,
|
|
10019
|
+
historySeeds: metadata.historySeeds ?? [],
|
|
10020
|
+
consumerCheckpoints,
|
|
10021
|
+
retentionFloor,
|
|
10022
|
+
nextAgentSequence: metadata.nextAgentSequence ?? [],
|
|
10023
|
+
nextReadySequence: metadata.nextReadySequence ?? [],
|
|
10024
|
+
eventSequence: metadata.eventSequence ?? 0,
|
|
10025
|
+
contextCompactions: metadata.contextCompactions ?? []
|
|
10026
|
+
};
|
|
10027
|
+
}
|
|
10028
|
+
ensureTableBackedStorage(memory, tracker, isLegacy) {
|
|
10029
|
+
if (isLegacy) {
|
|
10030
|
+
this.writeFullStateToTables(memory);
|
|
10031
|
+
this.isLegacyState = false;
|
|
10032
|
+
} else {
|
|
10033
|
+
this.persistChanges(tracker, memory);
|
|
10034
|
+
this.mirrorChanges(tracker);
|
|
10035
|
+
}
|
|
10036
|
+
}
|
|
10037
|
+
getStmtUpsertAgent() {
|
|
10038
|
+
return this.stmtUpsertAgent ??= this.database.prepare(
|
|
10039
|
+
`INSERT INTO agents (id, metadata_json, config_token, config_identity, created_at, activated_at, updated_at)
|
|
10040
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
10041
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
10042
|
+
metadata_json = excluded.metadata_json,
|
|
10043
|
+
config_token = excluded.config_token,
|
|
10044
|
+
config_identity = excluded.config_identity,
|
|
10045
|
+
activated_at = excluded.activated_at,
|
|
10046
|
+
updated_at = excluded.updated_at`
|
|
10047
|
+
);
|
|
10048
|
+
}
|
|
10049
|
+
getStmtDeleteAgent() {
|
|
10050
|
+
return this.stmtDeleteAgent ??= this.database.prepare("DELETE FROM agents WHERE id = ?");
|
|
10051
|
+
}
|
|
10052
|
+
getStmtUpsertRun() {
|
|
10053
|
+
return this.stmtUpsertRun ??= this.database.prepare(
|
|
10054
|
+
`INSERT INTO runs (id, agent_id, agent_sequence, state, revision, payload_json, created_at, updated_at)
|
|
10055
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
10056
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
10057
|
+
state = excluded.state,
|
|
10058
|
+
revision = excluded.revision,
|
|
10059
|
+
payload_json = excluded.payload_json,
|
|
10060
|
+
updated_at = excluded.updated_at`
|
|
10061
|
+
);
|
|
10062
|
+
}
|
|
10063
|
+
getStmtDeleteRun() {
|
|
10064
|
+
return this.stmtDeleteRun ??= this.database.prepare("DELETE FROM runs WHERE id = ?");
|
|
10065
|
+
}
|
|
10066
|
+
getStmtInsertMessage() {
|
|
10067
|
+
return this.stmtInsertMessage ??= this.database.prepare(
|
|
10068
|
+
`INSERT INTO messages (id, run_id, sequence_within_run, payload_json, created_at)
|
|
10069
|
+
VALUES (?, ?, ?, ?, ?)
|
|
10070
|
+
ON CONFLICT(id) DO UPDATE SET payload_json = excluded.payload_json`
|
|
10071
|
+
);
|
|
10072
|
+
}
|
|
10073
|
+
getStmtDeleteMessage() {
|
|
10074
|
+
return this.stmtDeleteMessage ??= this.database.prepare("DELETE FROM messages WHERE id = ?");
|
|
10075
|
+
}
|
|
10076
|
+
getStmtUpsertToolCall() {
|
|
10077
|
+
return this.stmtUpsertToolCall ??= this.database.prepare(
|
|
10078
|
+
`INSERT INTO tool_calls (id, run_id, execution_id, state, payload_json)
|
|
10079
|
+
VALUES (?, ?, ?, ?, ?)
|
|
10080
|
+
ON CONFLICT(id) DO UPDATE SET state = excluded.state, payload_json = excluded.payload_json`
|
|
10081
|
+
);
|
|
10082
|
+
}
|
|
10083
|
+
getStmtDeleteToolCall() {
|
|
10084
|
+
return this.stmtDeleteToolCall ??= this.database.prepare("DELETE FROM tool_calls WHERE id = ?");
|
|
10085
|
+
}
|
|
10086
|
+
getStmtInsertEvent() {
|
|
10087
|
+
return this.stmtInsertEvent ??= this.database.prepare(
|
|
10088
|
+
"INSERT INTO run_events (id, run_id, payload_json, created_at) VALUES (?, ?, ?, ?)"
|
|
10089
|
+
);
|
|
10090
|
+
}
|
|
10091
|
+
getStmtDeleteEvent() {
|
|
10092
|
+
return this.stmtDeleteEvent ??= this.database.prepare("DELETE FROM run_events WHERE id = ?");
|
|
10093
|
+
}
|
|
10094
|
+
getStmtUpsertIdempotency() {
|
|
10095
|
+
return this.stmtUpsertIdempotency ??= this.database.prepare(
|
|
10096
|
+
`INSERT INTO idempotency (scope, payload_json, result_json)
|
|
10097
|
+
VALUES (?, ?, ?)
|
|
10098
|
+
ON CONFLICT(scope) DO UPDATE SET payload_json = excluded.payload_json, result_json = excluded.result_json`
|
|
10099
|
+
);
|
|
10100
|
+
}
|
|
10101
|
+
getStmtDeleteIdempotency() {
|
|
10102
|
+
return this.stmtDeleteIdempotency ??= this.database.prepare("DELETE FROM idempotency WHERE scope = ?");
|
|
10103
|
+
}
|
|
10104
|
+
getStmtUpsertCheckpoint() {
|
|
10105
|
+
return this.stmtUpsertCheckpoint ??= this.database.prepare(
|
|
10106
|
+
`INSERT INTO consumer_checkpoints (consumer_id, sequence, event_id, updated_at)
|
|
10107
|
+
VALUES (?, ?, ?, ?)
|
|
10108
|
+
ON CONFLICT(consumer_id) DO UPDATE SET sequence = excluded.sequence, updated_at = excluded.updated_at`
|
|
10109
|
+
);
|
|
10110
|
+
}
|
|
10111
|
+
getStmtDeleteCheckpoint() {
|
|
10112
|
+
return this.stmtDeleteCheckpoint ??= this.database.prepare("DELETE FROM consumer_checkpoints WHERE consumer_id = ?");
|
|
10113
|
+
}
|
|
10114
|
+
getStmtUpdateMeta() {
|
|
10115
|
+
return this.stmtUpdateMeta ??= this.database.prepare(
|
|
10116
|
+
"INSERT INTO runtime_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
10117
|
+
);
|
|
9604
10118
|
}
|
|
9605
|
-
|
|
9606
|
-
this.
|
|
10119
|
+
getStmtUpdateState() {
|
|
10120
|
+
return this.stmtUpdateState ??= this.database.prepare(
|
|
10121
|
+
"UPDATE runtime_state SET state_json = ? WHERE singleton = ?"
|
|
10122
|
+
);
|
|
10123
|
+
}
|
|
10124
|
+
persistChanges(tracker, memory) {
|
|
10125
|
+
for (const agent of tracker.upsertedAgents.values()) {
|
|
10126
|
+
this.getStmtUpsertAgent().run(
|
|
10127
|
+
agent.id,
|
|
10128
|
+
agent.metadata === void 0 ? null : JSON.stringify(agent.metadata),
|
|
10129
|
+
agent.currentConfigToken ?? null,
|
|
10130
|
+
agent.currentConfigIdentity ?? null,
|
|
10131
|
+
agent.createdAt,
|
|
10132
|
+
agent.activatedAt ?? null,
|
|
10133
|
+
agent.updatedAt
|
|
10134
|
+
);
|
|
10135
|
+
}
|
|
10136
|
+
for (const agentId of tracker.deletedAgentIds) {
|
|
10137
|
+
this.getStmtDeleteAgent().run(agentId);
|
|
10138
|
+
}
|
|
10139
|
+
for (const run of tracker.upsertedRuns.values()) {
|
|
10140
|
+
this.getStmtUpsertRun().run(
|
|
10141
|
+
run.id,
|
|
10142
|
+
run.agentId,
|
|
10143
|
+
run.agentSequence,
|
|
10144
|
+
run.state,
|
|
10145
|
+
run.revision,
|
|
10146
|
+
JSON.stringify(run),
|
|
10147
|
+
run.createdAt,
|
|
10148
|
+
run.updatedAt
|
|
10149
|
+
);
|
|
10150
|
+
}
|
|
10151
|
+
for (const runId of tracker.deletedRunIds) {
|
|
10152
|
+
this.getStmtDeleteRun().run(runId);
|
|
10153
|
+
}
|
|
10154
|
+
for (const message of tracker.insertedMessages.values()) {
|
|
10155
|
+
this.getStmtInsertMessage().run(
|
|
10156
|
+
message.id,
|
|
10157
|
+
message.runId,
|
|
10158
|
+
message.sequenceWithinRun,
|
|
10159
|
+
JSON.stringify(message),
|
|
10160
|
+
message.createdAt
|
|
10161
|
+
);
|
|
10162
|
+
}
|
|
10163
|
+
for (const messageId of tracker.deletedMessageIds) {
|
|
10164
|
+
this.getStmtDeleteMessage().run(messageId);
|
|
10165
|
+
}
|
|
10166
|
+
for (const toolCall of tracker.upsertedToolCalls.values()) {
|
|
10167
|
+
this.getStmtUpsertToolCall().run(
|
|
10168
|
+
toolCall.id,
|
|
10169
|
+
toolCall.runId,
|
|
10170
|
+
toolCall.executionId,
|
|
10171
|
+
toolCall.state,
|
|
10172
|
+
JSON.stringify(toolCall)
|
|
10173
|
+
);
|
|
10174
|
+
}
|
|
10175
|
+
for (const toolCallId of tracker.deletedToolCallIds) {
|
|
10176
|
+
this.getStmtDeleteToolCall().run(toolCallId);
|
|
10177
|
+
}
|
|
10178
|
+
for (const event of tracker.appendedEvents) {
|
|
10179
|
+
this.getStmtInsertEvent().run(
|
|
10180
|
+
event.id,
|
|
10181
|
+
event.runId,
|
|
10182
|
+
JSON.stringify(event),
|
|
10183
|
+
event.createdAt
|
|
10184
|
+
);
|
|
10185
|
+
}
|
|
10186
|
+
for (const eventId of tracker.truncatedEventIds) {
|
|
10187
|
+
this.getStmtDeleteEvent().run(eventId);
|
|
10188
|
+
}
|
|
10189
|
+
for (const [scope, receipt] of tracker.upsertedIdempotency) {
|
|
10190
|
+
this.getStmtUpsertIdempotency().run(
|
|
10191
|
+
scope,
|
|
10192
|
+
receipt.payload,
|
|
10193
|
+
JSON.stringify(receipt.result)
|
|
10194
|
+
);
|
|
10195
|
+
}
|
|
10196
|
+
for (const scope of tracker.deletedIdempotencyScopes) {
|
|
10197
|
+
this.getStmtDeleteIdempotency().run(scope);
|
|
10198
|
+
}
|
|
10199
|
+
for (const [key, receipt] of tracker.upsertedOperationReceipts) {
|
|
10200
|
+
this.getStmtUpsertIdempotency().run(
|
|
10201
|
+
`operation:${key}`,
|
|
10202
|
+
receipt.payload,
|
|
10203
|
+
JSON.stringify(receipt.result)
|
|
10204
|
+
);
|
|
10205
|
+
}
|
|
10206
|
+
for (const key of tracker.deletedOperationReceiptKeys) {
|
|
10207
|
+
this.getStmtDeleteIdempotency().run(`operation:${key}`);
|
|
10208
|
+
}
|
|
10209
|
+
for (const [consumerId, cursor] of tracker.upsertedConsumerCheckpoints) {
|
|
10210
|
+
this.getStmtUpsertCheckpoint().run(
|
|
10211
|
+
consumerId,
|
|
10212
|
+
Number(String(cursor).split(":").at(-1)),
|
|
10213
|
+
null,
|
|
10214
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
10215
|
+
);
|
|
10216
|
+
}
|
|
10217
|
+
for (const consumerId of tracker.deletedConsumerCheckpoints) {
|
|
10218
|
+
this.getStmtDeleteCheckpoint().run(consumerId);
|
|
10219
|
+
}
|
|
10220
|
+
if (tracker.retentionFloorChanged !== void 0) {
|
|
10221
|
+
this.getStmtUpdateMeta().run(RETENTION_FLOOR_KEY, String(tracker.retentionFloorChanged));
|
|
10222
|
+
}
|
|
10223
|
+
this.getStmtUpdateState().run(JSON.stringify(memory.exportMetadata()), STATE_ROW);
|
|
9607
10224
|
}
|
|
9608
|
-
|
|
9609
|
-
|
|
10225
|
+
writeFullStateToTables(memory) {
|
|
10226
|
+
const state = memory.exportState();
|
|
9610
10227
|
this.database.run(
|
|
9611
10228
|
"INSERT INTO runtime_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value",
|
|
9612
10229
|
[RETENTION_FLOOR_KEY, String(Math.max(1, state.retentionFloor ?? 1))]
|
|
@@ -9615,57 +10232,149 @@ var SqliteStore = class {
|
|
|
9615
10232
|
this.database.run(`DELETE FROM ${table}`);
|
|
9616
10233
|
}
|
|
9617
10234
|
for (const agent of state.agents) {
|
|
9618
|
-
this.
|
|
9619
|
-
|
|
9620
|
-
|
|
10235
|
+
this.getStmtUpsertAgent().run(
|
|
10236
|
+
agent.id,
|
|
10237
|
+
agent.metadata === void 0 ? null : JSON.stringify(agent.metadata),
|
|
10238
|
+
agent.currentConfigToken ?? null,
|
|
10239
|
+
agent.currentConfigIdentity ?? null,
|
|
10240
|
+
agent.createdAt,
|
|
10241
|
+
agent.activatedAt ?? null,
|
|
10242
|
+
agent.updatedAt
|
|
9621
10243
|
);
|
|
9622
10244
|
}
|
|
9623
10245
|
for (const run of state.runs) {
|
|
9624
|
-
this.
|
|
9625
|
-
|
|
9626
|
-
|
|
10246
|
+
this.getStmtUpsertRun().run(
|
|
10247
|
+
run.id,
|
|
10248
|
+
run.agentId,
|
|
10249
|
+
run.agentSequence,
|
|
10250
|
+
run.state,
|
|
10251
|
+
run.revision,
|
|
10252
|
+
JSON.stringify(run),
|
|
10253
|
+
run.createdAt,
|
|
10254
|
+
run.updatedAt
|
|
9627
10255
|
);
|
|
9628
10256
|
}
|
|
9629
10257
|
for (const message of state.messages) {
|
|
9630
|
-
this.
|
|
9631
|
-
|
|
9632
|
-
|
|
10258
|
+
this.getStmtInsertMessage().run(
|
|
10259
|
+
message.id,
|
|
10260
|
+
message.runId,
|
|
10261
|
+
message.sequenceWithinRun,
|
|
10262
|
+
JSON.stringify(message),
|
|
10263
|
+
message.createdAt
|
|
9633
10264
|
);
|
|
9634
10265
|
}
|
|
9635
10266
|
for (const toolCall of state.toolCalls) {
|
|
9636
|
-
this.
|
|
9637
|
-
|
|
9638
|
-
|
|
10267
|
+
this.getStmtUpsertToolCall().run(
|
|
10268
|
+
toolCall.id,
|
|
10269
|
+
toolCall.runId,
|
|
10270
|
+
toolCall.executionId,
|
|
10271
|
+
toolCall.state,
|
|
10272
|
+
JSON.stringify(toolCall)
|
|
9639
10273
|
);
|
|
9640
10274
|
}
|
|
9641
10275
|
for (const event of state.events) {
|
|
9642
|
-
this.
|
|
9643
|
-
|
|
9644
|
-
|
|
10276
|
+
this.getStmtInsertEvent().run(
|
|
10277
|
+
event.id,
|
|
10278
|
+
event.runId,
|
|
10279
|
+
JSON.stringify(event),
|
|
10280
|
+
event.createdAt
|
|
9645
10281
|
);
|
|
9646
10282
|
}
|
|
9647
10283
|
for (const [scope, receipt] of state.idempotency) {
|
|
9648
|
-
this.
|
|
9649
|
-
|
|
9650
|
-
|
|
10284
|
+
this.getStmtUpsertIdempotency().run(
|
|
10285
|
+
scope,
|
|
10286
|
+
receipt.payload,
|
|
10287
|
+
JSON.stringify(receipt.result)
|
|
9651
10288
|
);
|
|
9652
10289
|
}
|
|
9653
10290
|
for (const [scope, receipt] of state.operationReceipts) {
|
|
9654
|
-
this.
|
|
9655
|
-
|
|
9656
|
-
|
|
10291
|
+
this.getStmtUpsertIdempotency().run(
|
|
10292
|
+
`operation:${scope}`,
|
|
10293
|
+
receipt.payload,
|
|
10294
|
+
JSON.stringify(receipt.result)
|
|
9657
10295
|
);
|
|
9658
10296
|
}
|
|
9659
10297
|
for (const [consumerId, cursor] of state.consumerCheckpoints ?? []) {
|
|
9660
|
-
this.
|
|
9661
|
-
|
|
9662
|
-
|
|
10298
|
+
this.getStmtUpsertCheckpoint().run(
|
|
10299
|
+
consumerId,
|
|
10300
|
+
Number(String(cursor).split(":").at(-1)),
|
|
10301
|
+
null,
|
|
10302
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
9663
10303
|
);
|
|
9664
10304
|
}
|
|
9665
|
-
this.
|
|
10305
|
+
this.getStmtUpdateState().run(JSON.stringify(memory.exportMetadata()), STATE_ROW);
|
|
10306
|
+
this.mirrorInitialState(state);
|
|
10307
|
+
}
|
|
10308
|
+
mirrorChanges(tracker) {
|
|
10309
|
+
for (const agentId of tracker.deletedAgentIds) {
|
|
10310
|
+
const idStr = String(agentId);
|
|
10311
|
+
rmSync(join6(this.archiveRoot, idStr), { recursive: true, force: true });
|
|
10312
|
+
this.mirroredEventIds.delete(idStr);
|
|
10313
|
+
this.mirroredCompactionIds.delete(idStr);
|
|
10314
|
+
this.mirroredAgents.delete(idStr);
|
|
10315
|
+
}
|
|
10316
|
+
for (const agent of tracker.upsertedAgents.values()) {
|
|
10317
|
+
const idStr = String(agent.id);
|
|
10318
|
+
this.mirroredAgents.add(idStr);
|
|
10319
|
+
const archiveDir = join6(this.archiveRoot, idStr);
|
|
10320
|
+
const toolDir = join6(archiveDir, "tool-results");
|
|
10321
|
+
mkdirSync(toolDir, { recursive: true, mode: 448 });
|
|
10322
|
+
chmodSync(archiveDir, 448);
|
|
10323
|
+
chmodSync(toolDir, 448);
|
|
10324
|
+
}
|
|
10325
|
+
if (tracker.appendedEvents.length > 0) {
|
|
10326
|
+
mkdirSync(this.archiveRoot, { recursive: true, mode: 448 });
|
|
10327
|
+
chmodSync(this.archiveRoot, 448);
|
|
10328
|
+
const eventsByAgent = /* @__PURE__ */ new Map();
|
|
10329
|
+
for (const event of tracker.appendedEvents) {
|
|
10330
|
+
const agentId = String(event.agentId);
|
|
10331
|
+
let list = eventsByAgent.get(agentId);
|
|
10332
|
+
if (!list) {
|
|
10333
|
+
list = [];
|
|
10334
|
+
eventsByAgent.set(agentId, list);
|
|
10335
|
+
}
|
|
10336
|
+
list.push(event);
|
|
10337
|
+
}
|
|
10338
|
+
for (const [agentId, events] of eventsByAgent) {
|
|
10339
|
+
const archiveDir = join6(this.archiveRoot, agentId);
|
|
10340
|
+
const toolDir = join6(archiveDir, "tool-results");
|
|
10341
|
+
mkdirSync(toolDir, { recursive: true, mode: 448 });
|
|
10342
|
+
chmodSync(archiveDir, 448);
|
|
10343
|
+
chmodSync(toolDir, 448);
|
|
10344
|
+
const sessionPath = join6(archiveDir, "session.jsonl");
|
|
10345
|
+
try {
|
|
10346
|
+
chmodSync(sessionPath, 384);
|
|
10347
|
+
} catch {
|
|
10348
|
+
}
|
|
10349
|
+
const known = this.mirroredEventIds.get(agentId) ?? /* @__PURE__ */ new Set();
|
|
10350
|
+
const newEvents = events.filter((e) => !known.has(String(e.id)));
|
|
10351
|
+
if (newEvents.length > 0) {
|
|
10352
|
+
const lines = newEvents.map((e) => JSON.stringify({ schemaVersion: 1, kind: "rowan_event", event: e }) + "\n").join("");
|
|
10353
|
+
appendFileSync(sessionPath, lines, { encoding: "utf8", mode: 384 });
|
|
10354
|
+
chmodSync(sessionPath, 384);
|
|
10355
|
+
for (const e of newEvents) known.add(String(e.id));
|
|
10356
|
+
this.mirroredEventIds.set(agentId, known);
|
|
10357
|
+
}
|
|
10358
|
+
}
|
|
10359
|
+
}
|
|
10360
|
+
if (tracker.upsertedContextCompactions.size > 0) {
|
|
10361
|
+
for (const [agentId, record] of tracker.upsertedContextCompactions) {
|
|
10362
|
+
const idStr = String(agentId);
|
|
10363
|
+
const archiveDir = join6(this.archiveRoot, idStr);
|
|
10364
|
+
const sessionPath = join6(archiveDir, "session.jsonl");
|
|
10365
|
+
const knownCompactions = this.mirroredCompactionIds.get(idStr) ?? /* @__PURE__ */ new Set();
|
|
10366
|
+
if (!knownCompactions.has(record.id)) {
|
|
10367
|
+
const line = JSON.stringify({ schemaVersion: 1, kind: "context_compacted", record }) + "\n";
|
|
10368
|
+
appendFileSync(sessionPath, line, { encoding: "utf8", mode: 384 });
|
|
10369
|
+
chmodSync(sessionPath, 384);
|
|
10370
|
+
knownCompactions.add(record.id);
|
|
10371
|
+
this.mirroredCompactionIds.set(idStr, knownCompactions);
|
|
10372
|
+
}
|
|
10373
|
+
}
|
|
10374
|
+
}
|
|
9666
10375
|
}
|
|
9667
10376
|
/** Append the semantic durable event mirror and remove deleted Agent sidecars. */
|
|
9668
|
-
|
|
10377
|
+
mirrorInitialState(state) {
|
|
9669
10378
|
mkdirSync(this.archiveRoot, { recursive: true, mode: 448 });
|
|
9670
10379
|
chmodSync(this.archiveRoot, 448);
|
|
9671
10380
|
const currentAgents = new Set(state.agents.map((agent) => String(agent.id)));
|
|
@@ -9885,19 +10594,6 @@ function ownerLease(row) {
|
|
|
9885
10594
|
expiresAt: new Date(row.expires_at).toISOString()
|
|
9886
10595
|
};
|
|
9887
10596
|
}
|
|
9888
|
-
function parseEventCursor(lease, cursor) {
|
|
9889
|
-
const value = String(cursor);
|
|
9890
|
-
const separator = value.lastIndexOf(":");
|
|
9891
|
-
const incarnation = separator < 0 ? "" : value.slice(0, separator);
|
|
9892
|
-
const sequence = separator < 0 ? "" : value.slice(separator + 1);
|
|
9893
|
-
const token = String(lease.token);
|
|
9894
|
-
const ownerSuffix = `:${lease.epoch}:${lease.ownerId}`;
|
|
9895
|
-
const expectedIncarnation = token.endsWith(ownerSuffix) ? token.slice(0, -ownerSuffix.length) : "";
|
|
9896
|
-
if (incarnation !== expectedIncarnation || !/^\d+$/.test(sequence)) {
|
|
9897
|
-
throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "wrong_store" });
|
|
9898
|
-
}
|
|
9899
|
-
return Number(sequence);
|
|
9900
|
-
}
|
|
9901
10597
|
function ownershipLost2(lease, row) {
|
|
9902
10598
|
return new RuntimeError("runtime_ownership_lost", {
|
|
9903
10599
|
reason: row.epoch > lease.epoch ? "epoch_advanced" : row.owner_id ? "released" : "released",
|