@rowan-agent/agent 0.15.4 → 0.16.0
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 +242 -6
- package/dist/index.js +1345 -145
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1247,6 +1247,56 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1247
1247
|
assertActive();
|
|
1248
1248
|
hooks?.off(eventType, handler);
|
|
1249
1249
|
},
|
|
1250
|
+
config: {
|
|
1251
|
+
get: async (scope) => {
|
|
1252
|
+
assertActive();
|
|
1253
|
+
return await options?.config?.get(scope) ?? null;
|
|
1254
|
+
},
|
|
1255
|
+
changed: (handler) => {
|
|
1256
|
+
assertActive();
|
|
1257
|
+
options?.config?.changed(handler);
|
|
1258
|
+
}
|
|
1259
|
+
},
|
|
1260
|
+
state: {
|
|
1261
|
+
run: (runId) => {
|
|
1262
|
+
assertActive();
|
|
1263
|
+
const store = options?.state?.run(runId);
|
|
1264
|
+
return {
|
|
1265
|
+
get: async (key) => {
|
|
1266
|
+
assertActive();
|
|
1267
|
+
return store?.get(key);
|
|
1268
|
+
},
|
|
1269
|
+
set: async (key, value) => {
|
|
1270
|
+
assertActive();
|
|
1271
|
+
assertJsonValue(value);
|
|
1272
|
+
return store?.set(key, value);
|
|
1273
|
+
},
|
|
1274
|
+
delete: async (key) => {
|
|
1275
|
+
assertActive();
|
|
1276
|
+
return store?.delete(key);
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
},
|
|
1280
|
+
agent: (agentId) => {
|
|
1281
|
+
assertActive();
|
|
1282
|
+
const store = options?.state?.agent(agentId);
|
|
1283
|
+
return {
|
|
1284
|
+
get: async (key) => {
|
|
1285
|
+
assertActive();
|
|
1286
|
+
return store?.get(key);
|
|
1287
|
+
},
|
|
1288
|
+
set: async (key, value) => {
|
|
1289
|
+
assertActive();
|
|
1290
|
+
assertJsonValue(value);
|
|
1291
|
+
return store?.set(key, value);
|
|
1292
|
+
},
|
|
1293
|
+
delete: async (key) => {
|
|
1294
|
+
assertActive();
|
|
1295
|
+
return store?.delete(key);
|
|
1296
|
+
}
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
},
|
|
1250
1300
|
tool: {
|
|
1251
1301
|
register: (tool) => {
|
|
1252
1302
|
assertActive();
|
|
@@ -1257,6 +1307,25 @@ function createExtensionAPI(hooks, options, runtime, eventBus) {
|
|
|
1257
1307
|
options?.unregisterTool?.(toolName);
|
|
1258
1308
|
}
|
|
1259
1309
|
},
|
|
1310
|
+
capabilities: {
|
|
1311
|
+
contribute: (contribution) => {
|
|
1312
|
+
assertActive();
|
|
1313
|
+
if (!contribution || typeof contribution !== "object") {
|
|
1314
|
+
throw new TypeError("Capability contribution must be an object.");
|
|
1315
|
+
}
|
|
1316
|
+
if (contribution.kind !== "tool") {
|
|
1317
|
+
throw new TypeError(`Unsupported capability contribution kind: "${contribution.kind}".`);
|
|
1318
|
+
}
|
|
1319
|
+
if (typeof contribution.name !== "string" || contribution.name.trim() === "") {
|
|
1320
|
+
throw new TypeError("Capability contribution requires a non-empty name.");
|
|
1321
|
+
}
|
|
1322
|
+
if (typeof contribution.description !== "string") {
|
|
1323
|
+
throw new TypeError("Capability contribution requires a description string.");
|
|
1324
|
+
}
|
|
1325
|
+
return options?.contributeCapability ? options.contributeCapability(contribution) : () => {
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
},
|
|
1260
1329
|
registerProvider: (config) => {
|
|
1261
1330
|
assertActive();
|
|
1262
1331
|
options?.registerProvider?.(config);
|
|
@@ -4518,7 +4587,9 @@ function assembleRegisteredExtensions(snapshot, runner, options = {}) {
|
|
|
4518
4587
|
agentId: input.context.agentId,
|
|
4519
4588
|
toolCallId: input.context.toolCallId,
|
|
4520
4589
|
metadata: input.context.runMetadata,
|
|
4521
|
-
answer: input.answer
|
|
4590
|
+
answer: input.answer,
|
|
4591
|
+
scope: input.context.scope,
|
|
4592
|
+
turn: input.context.turn
|
|
4522
4593
|
});
|
|
4523
4594
|
if (decision.interaction !== void 0) {
|
|
4524
4595
|
return { interaction: decision.interaction };
|
|
@@ -4534,7 +4605,9 @@ function assembleRegisteredExtensions(snapshot, runner, options = {}) {
|
|
|
4534
4605
|
runId: input.context.runId,
|
|
4535
4606
|
agentId: input.context.agentId,
|
|
4536
4607
|
toolCallId: input.context.toolCallId,
|
|
4537
|
-
metadata: input.context.runMetadata
|
|
4608
|
+
metadata: input.context.runMetadata,
|
|
4609
|
+
scope: input.context.scope,
|
|
4610
|
+
turn: input.context.turn
|
|
4538
4611
|
}
|
|
4539
4612
|
);
|
|
4540
4613
|
return fromLoopResult(result);
|
|
@@ -4792,6 +4865,126 @@ var HooksManager = class {
|
|
|
4792
4865
|
}
|
|
4793
4866
|
};
|
|
4794
4867
|
|
|
4868
|
+
// src/extensions/host.ts
|
|
4869
|
+
var InMemoryExtensionHost = class {
|
|
4870
|
+
configs = /* @__PURE__ */ new Map();
|
|
4871
|
+
agentState = /* @__PURE__ */ new Map();
|
|
4872
|
+
listeners = /* @__PURE__ */ new Set();
|
|
4873
|
+
constructor(options = {}) {
|
|
4874
|
+
if (options.configs) {
|
|
4875
|
+
for (const [scopeKey, extMap] of Object.entries(options.configs)) {
|
|
4876
|
+
const map = /* @__PURE__ */ new Map();
|
|
4877
|
+
for (const [extId, cfg] of Object.entries(extMap)) {
|
|
4878
|
+
assertJsonValue(cfg);
|
|
4879
|
+
map.set(extId, structuredClone(cfg));
|
|
4880
|
+
}
|
|
4881
|
+
this.configs.set(scopeKey, map);
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4884
|
+
if (options.agentState) {
|
|
4885
|
+
for (const [agentId, extMap] of Object.entries(options.agentState)) {
|
|
4886
|
+
const agentMap = /* @__PURE__ */ new Map();
|
|
4887
|
+
for (const [extId, stateMap] of Object.entries(extMap)) {
|
|
4888
|
+
const map = /* @__PURE__ */ new Map();
|
|
4889
|
+
for (const [key, val] of Object.entries(stateMap)) {
|
|
4890
|
+
assertJsonValue(val);
|
|
4891
|
+
map.set(key, structuredClone(val));
|
|
4892
|
+
}
|
|
4893
|
+
agentMap.set(extId, map);
|
|
4894
|
+
}
|
|
4895
|
+
this.agentState.set(agentId, agentMap);
|
|
4896
|
+
}
|
|
4897
|
+
}
|
|
4898
|
+
}
|
|
4899
|
+
setConfig(extensionId, config, scope = { kind: "global" }) {
|
|
4900
|
+
const scopeKey = scopeToKey(scope);
|
|
4901
|
+
if (!this.configs.has(scopeKey)) {
|
|
4902
|
+
this.configs.set(scopeKey, /* @__PURE__ */ new Map());
|
|
4903
|
+
}
|
|
4904
|
+
const scopeConfigs = this.configs.get(scopeKey);
|
|
4905
|
+
if (config === null) {
|
|
4906
|
+
scopeConfigs.delete(extensionId);
|
|
4907
|
+
} else {
|
|
4908
|
+
assertJsonValue(config);
|
|
4909
|
+
scopeConfigs.set(extensionId, structuredClone(config));
|
|
4910
|
+
}
|
|
4911
|
+
this.notifyConfigChanged(extensionId, scope);
|
|
4912
|
+
}
|
|
4913
|
+
getConfig(extensionId, scope = { kind: "global" }) {
|
|
4914
|
+
const globalConfig = this.configs.get("global")?.get(extensionId);
|
|
4915
|
+
let merged = globalConfig ? { ...globalConfig } : null;
|
|
4916
|
+
if (scope.kind === "team" || scope.kind === "project") {
|
|
4917
|
+
const teamConfig = this.configs.get(`team:${scope.teamId}`)?.get(extensionId);
|
|
4918
|
+
if (teamConfig) {
|
|
4919
|
+
merged = { ...merged ?? {}, ...teamConfig };
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
if (scope.kind === "project") {
|
|
4923
|
+
const projectConfig = this.configs.get(`project:${scope.teamId}:${scope.projectId}`)?.get(extensionId);
|
|
4924
|
+
if (projectConfig) {
|
|
4925
|
+
merged = { ...merged ?? {}, ...projectConfig };
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
return merged ? structuredClone(merged) : null;
|
|
4929
|
+
}
|
|
4930
|
+
onConfigChanged(listener) {
|
|
4931
|
+
this.listeners.add(listener);
|
|
4932
|
+
return () => this.listeners.delete(listener);
|
|
4933
|
+
}
|
|
4934
|
+
notifyConfigChanged(extensionId, scope = { kind: "global" }) {
|
|
4935
|
+
for (const listener of this.listeners) {
|
|
4936
|
+
try {
|
|
4937
|
+
listener(extensionId, scope);
|
|
4938
|
+
} catch {
|
|
4939
|
+
}
|
|
4940
|
+
}
|
|
4941
|
+
}
|
|
4942
|
+
getAgentState(extensionId, agentId, key) {
|
|
4943
|
+
const val = this.agentState.get(agentId)?.get(extensionId)?.get(key);
|
|
4944
|
+
return val !== void 0 ? structuredClone(val) : void 0;
|
|
4945
|
+
}
|
|
4946
|
+
setAgentState(extensionId, agentId, key, value) {
|
|
4947
|
+
assertJsonValue(value);
|
|
4948
|
+
let agentMap = this.agentState.get(agentId);
|
|
4949
|
+
if (!agentMap) {
|
|
4950
|
+
agentMap = /* @__PURE__ */ new Map();
|
|
4951
|
+
this.agentState.set(agentId, agentMap);
|
|
4952
|
+
}
|
|
4953
|
+
let extMap = agentMap.get(extensionId);
|
|
4954
|
+
if (!extMap) {
|
|
4955
|
+
extMap = /* @__PURE__ */ new Map();
|
|
4956
|
+
agentMap.set(extensionId, extMap);
|
|
4957
|
+
}
|
|
4958
|
+
extMap.set(key, structuredClone(value));
|
|
4959
|
+
}
|
|
4960
|
+
deleteAgentState(extensionId, agentId, key) {
|
|
4961
|
+
this.agentState.get(agentId)?.get(extensionId)?.delete(key);
|
|
4962
|
+
}
|
|
4963
|
+
};
|
|
4964
|
+
function scopeToKey(scope) {
|
|
4965
|
+
switch (scope.kind) {
|
|
4966
|
+
case "global":
|
|
4967
|
+
return "global";
|
|
4968
|
+
case "team":
|
|
4969
|
+
return `team:${scope.teamId}`;
|
|
4970
|
+
case "project":
|
|
4971
|
+
return `project:${scope.teamId}:${scope.projectId}`;
|
|
4972
|
+
}
|
|
4973
|
+
}
|
|
4974
|
+
function resolveScopeFromMetadata(metadata) {
|
|
4975
|
+
if (metadata) {
|
|
4976
|
+
const teamId = typeof metadata.teamId === "string" ? metadata.teamId : void 0;
|
|
4977
|
+
const projectId = typeof metadata.projectId === "string" ? metadata.projectId : void 0;
|
|
4978
|
+
if (teamId && projectId) {
|
|
4979
|
+
return { kind: "project", teamId, projectId };
|
|
4980
|
+
}
|
|
4981
|
+
if (teamId) {
|
|
4982
|
+
return { kind: "team", teamId };
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
return { kind: "global" };
|
|
4986
|
+
}
|
|
4987
|
+
|
|
4795
4988
|
// src/extensions/runner.ts
|
|
4796
4989
|
import { execFile } from "child_process";
|
|
4797
4990
|
import { dirname as dirname5, resolve as resolve5 } from "path";
|
|
@@ -4934,11 +5127,17 @@ var ExtensionRunner = class {
|
|
|
4934
5127
|
hooks;
|
|
4935
5128
|
runtime;
|
|
4936
5129
|
events;
|
|
5130
|
+
host;
|
|
4937
5131
|
cwd;
|
|
4938
5132
|
abortController = new AbortController();
|
|
4939
5133
|
_idle = true;
|
|
4940
5134
|
// Per-extension tracking
|
|
4941
5135
|
extensions = [];
|
|
5136
|
+
// Run state: runId -> extensionId -> key -> value
|
|
5137
|
+
runState = /* @__PURE__ */ new Map();
|
|
5138
|
+
// Config change listeners: extensionId -> Set of handlers
|
|
5139
|
+
configChangeListeners = /* @__PURE__ */ new Map();
|
|
5140
|
+
hostUnsubscribers = [];
|
|
4942
5141
|
// Phase management
|
|
4943
5142
|
phases = /* @__PURE__ */ new Map();
|
|
4944
5143
|
_phaseCache = null;
|
|
@@ -4947,6 +5146,8 @@ var ExtensionRunner = class {
|
|
|
4947
5146
|
bound = false;
|
|
4948
5147
|
// Error listeners
|
|
4949
5148
|
errorListeners = /* @__PURE__ */ new Set();
|
|
5149
|
+
// Capability change listeners
|
|
5150
|
+
capabilityListeners = /* @__PURE__ */ new Set();
|
|
4950
5151
|
/** Current agent context — set by the agent before each phase */
|
|
4951
5152
|
currentContext;
|
|
4952
5153
|
constructor(options) {
|
|
@@ -4954,6 +5155,15 @@ var ExtensionRunner = class {
|
|
|
4954
5155
|
this.runtime = createExtensionRuntime();
|
|
4955
5156
|
this.events = createEventBus();
|
|
4956
5157
|
this.cwd = options?.cwd ?? process.cwd();
|
|
5158
|
+
this.host = options?.host ?? new InMemoryExtensionHost();
|
|
5159
|
+
if (this.host.onConfigChanged) {
|
|
5160
|
+
const unsub = this.host.onConfigChanged((extensionId, scope) => {
|
|
5161
|
+
this.notifyConfigChanged(extensionId, scope);
|
|
5162
|
+
});
|
|
5163
|
+
if (typeof unsub === "function") {
|
|
5164
|
+
this.hostUnsubscribers.push(unsub);
|
|
5165
|
+
}
|
|
5166
|
+
}
|
|
4957
5167
|
}
|
|
4958
5168
|
/** Whether the agent is currently idle (not streaming). */
|
|
4959
5169
|
get isIdle() {
|
|
@@ -5034,10 +5244,13 @@ var ExtensionRunner = class {
|
|
|
5034
5244
|
*/
|
|
5035
5245
|
async loadExtensions(extensions) {
|
|
5036
5246
|
for (const ext of extensions) {
|
|
5247
|
+
const extensionId = ext.id ?? ext.manifest?.id ?? ext.name;
|
|
5037
5248
|
const extension = {
|
|
5249
|
+
id: extensionId,
|
|
5038
5250
|
path: ext.path,
|
|
5039
5251
|
tools: /* @__PURE__ */ new Map(),
|
|
5040
5252
|
phases: /* @__PURE__ */ new Set(),
|
|
5253
|
+
capabilities: /* @__PURE__ */ new Map(),
|
|
5041
5254
|
cleanup: [],
|
|
5042
5255
|
runtime: createExtensionRuntime()
|
|
5043
5256
|
};
|
|
@@ -5047,6 +5260,9 @@ var ExtensionRunner = class {
|
|
|
5047
5260
|
if (typeof disposer === "function") extension.disposer = disposer;
|
|
5048
5261
|
this.extensions.push(extension);
|
|
5049
5262
|
this._phaseCache = null;
|
|
5263
|
+
if (extension.capabilities.size > 0) {
|
|
5264
|
+
this.notifyCapabilitiesChanged();
|
|
5265
|
+
}
|
|
5050
5266
|
} catch (error) {
|
|
5051
5267
|
await this.rollbackExtension(extension);
|
|
5052
5268
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -5063,14 +5279,67 @@ var ExtensionRunner = class {
|
|
|
5063
5279
|
/** Dispose all active Extensions in reverse activation order. */
|
|
5064
5280
|
async close() {
|
|
5065
5281
|
this.abortController.abort();
|
|
5282
|
+
for (const unsub of this.hostUnsubscribers) {
|
|
5283
|
+
try {
|
|
5284
|
+
unsub();
|
|
5285
|
+
} catch {
|
|
5286
|
+
}
|
|
5287
|
+
}
|
|
5288
|
+
this.hostUnsubscribers.length = 0;
|
|
5289
|
+
this.configChangeListeners.clear();
|
|
5290
|
+
this.runState.clear();
|
|
5066
5291
|
for (const extension of [...this.extensions].reverse()) {
|
|
5067
5292
|
await this.disposeExtension(extension, "This Extension Runtime has been closed.");
|
|
5068
5293
|
}
|
|
5069
5294
|
this.extensions.length = 0;
|
|
5295
|
+
this.capabilityListeners.clear();
|
|
5070
5296
|
this.phases.clear();
|
|
5071
5297
|
this._phaseCache = null;
|
|
5072
5298
|
this.runtime.invalidate("This Extension Runtime has been closed.");
|
|
5073
5299
|
}
|
|
5300
|
+
get extensionHost() {
|
|
5301
|
+
return this.host;
|
|
5302
|
+
}
|
|
5303
|
+
notifyConfigChanged(extensionId, scope) {
|
|
5304
|
+
const listeners = this.configChangeListeners.get(extensionId);
|
|
5305
|
+
if (!listeners) return;
|
|
5306
|
+
for (const listener of listeners) {
|
|
5307
|
+
try {
|
|
5308
|
+
listener(scope);
|
|
5309
|
+
} catch (error) {
|
|
5310
|
+
this.emitError({
|
|
5311
|
+
extensionPath: "<runtime>",
|
|
5312
|
+
event: "config_changed",
|
|
5313
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5314
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
5315
|
+
});
|
|
5316
|
+
}
|
|
5317
|
+
}
|
|
5318
|
+
}
|
|
5319
|
+
getRunState(runId, extensionId, key) {
|
|
5320
|
+
const val = this.runState.get(runId)?.get(extensionId)?.get(key);
|
|
5321
|
+
return val !== void 0 ? structuredClone(val) : void 0;
|
|
5322
|
+
}
|
|
5323
|
+
setRunState(runId, extensionId, key, value) {
|
|
5324
|
+
assertJsonValue(value);
|
|
5325
|
+
let runMap = this.runState.get(runId);
|
|
5326
|
+
if (!runMap) {
|
|
5327
|
+
runMap = /* @__PURE__ */ new Map();
|
|
5328
|
+
this.runState.set(runId, runMap);
|
|
5329
|
+
}
|
|
5330
|
+
let extMap = runMap.get(extensionId);
|
|
5331
|
+
if (!extMap) {
|
|
5332
|
+
extMap = /* @__PURE__ */ new Map();
|
|
5333
|
+
runMap.set(extensionId, extMap);
|
|
5334
|
+
}
|
|
5335
|
+
extMap.set(key, structuredClone(value));
|
|
5336
|
+
}
|
|
5337
|
+
deleteRunState(runId, extensionId, key) {
|
|
5338
|
+
this.runState.get(runId)?.get(extensionId)?.delete(key);
|
|
5339
|
+
}
|
|
5340
|
+
dropRunState(runId) {
|
|
5341
|
+
this.runState.delete(runId);
|
|
5342
|
+
}
|
|
5074
5343
|
// ---------------------------------------------------------------------------
|
|
5075
5344
|
// Tool management
|
|
5076
5345
|
// ---------------------------------------------------------------------------
|
|
@@ -5097,6 +5366,32 @@ var ExtensionRunner = class {
|
|
|
5097
5366
|
return void 0;
|
|
5098
5367
|
}
|
|
5099
5368
|
// ---------------------------------------------------------------------------
|
|
5369
|
+
// Capability management
|
|
5370
|
+
// ---------------------------------------------------------------------------
|
|
5371
|
+
/** Get all contributed capabilities across all extensions. */
|
|
5372
|
+
getCapabilities() {
|
|
5373
|
+
const result = [];
|
|
5374
|
+
for (const ext of this.extensions) {
|
|
5375
|
+
for (const contrib of ext.capabilities.values()) {
|
|
5376
|
+
result.push({
|
|
5377
|
+
extensionId: ext.id,
|
|
5378
|
+
kind: contrib.kind,
|
|
5379
|
+
name: contrib.name,
|
|
5380
|
+
description: contrib.description
|
|
5381
|
+
});
|
|
5382
|
+
}
|
|
5383
|
+
}
|
|
5384
|
+
return Object.freeze(result);
|
|
5385
|
+
}
|
|
5386
|
+
/**
|
|
5387
|
+
* Subscribe to capability changes (contributions added, removed, or extensions disposed).
|
|
5388
|
+
* Returns an unsubscribe function.
|
|
5389
|
+
*/
|
|
5390
|
+
onCapabilitiesChanged(listener) {
|
|
5391
|
+
this.capabilityListeners.add(listener);
|
|
5392
|
+
return () => this.capabilityListeners.delete(listener);
|
|
5393
|
+
}
|
|
5394
|
+
// ---------------------------------------------------------------------------
|
|
5100
5395
|
// Phase management
|
|
5101
5396
|
// ---------------------------------------------------------------------------
|
|
5102
5397
|
getPhase(name) {
|
|
@@ -5182,7 +5477,39 @@ var ExtensionRunner = class {
|
|
|
5182
5477
|
});
|
|
5183
5478
|
return result?.input ?? input;
|
|
5184
5479
|
}
|
|
5480
|
+
async emitRunStart(event) {
|
|
5481
|
+
try {
|
|
5482
|
+
await this.hooks.emit("run_start", {
|
|
5483
|
+
type: "run_start",
|
|
5484
|
+
...event
|
|
5485
|
+
});
|
|
5486
|
+
} catch (error) {
|
|
5487
|
+
this.emitError({
|
|
5488
|
+
extensionPath: "<runtime>",
|
|
5489
|
+
event: "run_start",
|
|
5490
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5491
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
5492
|
+
});
|
|
5493
|
+
}
|
|
5494
|
+
}
|
|
5495
|
+
async emitRunEnd(event) {
|
|
5496
|
+
try {
|
|
5497
|
+
await this.hooks.emit("run_end", {
|
|
5498
|
+
type: "run_end",
|
|
5499
|
+
...event
|
|
5500
|
+
});
|
|
5501
|
+
} catch (error) {
|
|
5502
|
+
this.emitError({
|
|
5503
|
+
extensionPath: "<runtime>",
|
|
5504
|
+
event: "run_end",
|
|
5505
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5506
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
5507
|
+
});
|
|
5508
|
+
}
|
|
5509
|
+
}
|
|
5185
5510
|
async emitBeforeToolCall(tool, args, context) {
|
|
5511
|
+
const scope = context?.scope ?? resolveScopeFromMetadata(context?.metadata);
|
|
5512
|
+
const turn = context?.turn ?? {};
|
|
5186
5513
|
const result = await this.emitHook("before_tool_call", {
|
|
5187
5514
|
type: "before_tool_call",
|
|
5188
5515
|
tool,
|
|
@@ -5191,11 +5518,15 @@ var ExtensionRunner = class {
|
|
|
5191
5518
|
...context?.agentId !== void 0 ? { agentId: context.agentId } : {},
|
|
5192
5519
|
...context?.toolCallId !== void 0 ? { toolCallId: context.toolCallId } : {},
|
|
5193
5520
|
...context?.metadata !== void 0 ? { metadata: context.metadata } : {},
|
|
5194
|
-
...context?.answer !== void 0 ? { answer: context.answer } : {}
|
|
5521
|
+
...context?.answer !== void 0 ? { answer: context.answer } : {},
|
|
5522
|
+
scope,
|
|
5523
|
+
turn
|
|
5195
5524
|
});
|
|
5196
5525
|
return result ?? { allow: true };
|
|
5197
5526
|
}
|
|
5198
5527
|
async emitAfterToolCall(tool, result, context) {
|
|
5528
|
+
const scope = context?.scope ?? resolveScopeFromMetadata(context?.metadata);
|
|
5529
|
+
const turn = context?.turn ?? {};
|
|
5199
5530
|
const hookResult = await this.emitHook("after_tool_call", {
|
|
5200
5531
|
type: "after_tool_call",
|
|
5201
5532
|
tool,
|
|
@@ -5203,7 +5534,9 @@ var ExtensionRunner = class {
|
|
|
5203
5534
|
...context?.runId !== void 0 ? { runId: context.runId } : {},
|
|
5204
5535
|
...context?.agentId !== void 0 ? { agentId: context.agentId } : {},
|
|
5205
5536
|
...context?.toolCallId !== void 0 ? { toolCallId: context.toolCallId } : {},
|
|
5206
|
-
...context?.metadata !== void 0 ? { metadata: context.metadata } : {}
|
|
5537
|
+
...context?.metadata !== void 0 ? { metadata: context.metadata } : {},
|
|
5538
|
+
scope,
|
|
5539
|
+
turn
|
|
5207
5540
|
});
|
|
5208
5541
|
return hookResult?.result ?? result;
|
|
5209
5542
|
}
|
|
@@ -5271,9 +5604,43 @@ var ExtensionRunner = class {
|
|
|
5271
5604
|
unregisterProvider: (name) => this.unregisterProvider(name),
|
|
5272
5605
|
registerTool: (tool) => this.registerTool(extension, tool),
|
|
5273
5606
|
unregisterTool: (toolName) => this.unregisterTool(extension, toolName),
|
|
5607
|
+
contributeCapability: (contribution) => this.contributeCapability(extension, contribution),
|
|
5274
5608
|
context: extContext,
|
|
5275
5609
|
manifest,
|
|
5276
|
-
trackCleanup: (cleanup) => extension.cleanup.push(cleanup)
|
|
5610
|
+
trackCleanup: (cleanup) => extension.cleanup.push(cleanup),
|
|
5611
|
+
config: {
|
|
5612
|
+
get: async (scope) => {
|
|
5613
|
+
const effectiveScope = scope ?? { kind: "global" };
|
|
5614
|
+
const res = await runner.host.getConfig(extension.id, effectiveScope);
|
|
5615
|
+
return res ?? null;
|
|
5616
|
+
},
|
|
5617
|
+
changed: (handler) => {
|
|
5618
|
+
let listeners = runner.configChangeListeners.get(extension.id);
|
|
5619
|
+
if (!listeners) {
|
|
5620
|
+
listeners = /* @__PURE__ */ new Set();
|
|
5621
|
+
runner.configChangeListeners.set(extension.id, listeners);
|
|
5622
|
+
}
|
|
5623
|
+
listeners.add(handler);
|
|
5624
|
+
extension.cleanup.push(() => {
|
|
5625
|
+
listeners?.delete(handler);
|
|
5626
|
+
if (listeners && listeners.size === 0) {
|
|
5627
|
+
runner.configChangeListeners.delete(extension.id);
|
|
5628
|
+
}
|
|
5629
|
+
});
|
|
5630
|
+
}
|
|
5631
|
+
},
|
|
5632
|
+
state: {
|
|
5633
|
+
run: (runId) => ({
|
|
5634
|
+
get: async (key) => runner.getRunState(runId, extension.id, key),
|
|
5635
|
+
set: async (key, value) => runner.setRunState(runId, extension.id, key, value),
|
|
5636
|
+
delete: async (key) => runner.deleteRunState(runId, extension.id, key)
|
|
5637
|
+
}),
|
|
5638
|
+
agent: (agentId) => ({
|
|
5639
|
+
get: async (key) => runner.host.getAgentState(extension.id, agentId, key),
|
|
5640
|
+
set: async (key, value) => runner.host.setAgentState(extension.id, agentId, key, value),
|
|
5641
|
+
delete: async (key) => runner.host.deleteAgentState(extension.id, agentId, key)
|
|
5642
|
+
})
|
|
5643
|
+
}
|
|
5277
5644
|
}, extension.runtime, this.events);
|
|
5278
5645
|
}
|
|
5279
5646
|
registerTool(extension, tool) {
|
|
@@ -5302,6 +5669,46 @@ var ExtensionRunner = class {
|
|
|
5302
5669
|
extension.tools.delete(toolName);
|
|
5303
5670
|
}
|
|
5304
5671
|
}
|
|
5672
|
+
contributeCapability(extension, contribution) {
|
|
5673
|
+
const key = `${contribution.kind}:${contribution.name}`;
|
|
5674
|
+
const entry = {
|
|
5675
|
+
kind: contribution.kind,
|
|
5676
|
+
name: contribution.name,
|
|
5677
|
+
description: contribution.description
|
|
5678
|
+
};
|
|
5679
|
+
extension.capabilities.set(key, entry);
|
|
5680
|
+
if (this.extensions.includes(extension)) {
|
|
5681
|
+
this.notifyCapabilitiesChanged();
|
|
5682
|
+
}
|
|
5683
|
+
let disposed = false;
|
|
5684
|
+
const dispose = () => {
|
|
5685
|
+
if (disposed) return;
|
|
5686
|
+
disposed = true;
|
|
5687
|
+
if (extension.capabilities.get(key) === entry) {
|
|
5688
|
+
extension.capabilities.delete(key);
|
|
5689
|
+
if (this.extensions.includes(extension)) {
|
|
5690
|
+
this.notifyCapabilitiesChanged();
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
};
|
|
5694
|
+
extension.cleanup.push(dispose);
|
|
5695
|
+
return dispose;
|
|
5696
|
+
}
|
|
5697
|
+
notifyCapabilitiesChanged() {
|
|
5698
|
+
const capabilities = this.getCapabilities();
|
|
5699
|
+
for (const listener of this.capabilityListeners) {
|
|
5700
|
+
try {
|
|
5701
|
+
listener(capabilities);
|
|
5702
|
+
} catch (error) {
|
|
5703
|
+
this.emitError({
|
|
5704
|
+
extensionPath: "<runtime>",
|
|
5705
|
+
event: "capabilities_changed",
|
|
5706
|
+
error: error instanceof Error ? error.message : String(error),
|
|
5707
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
5708
|
+
});
|
|
5709
|
+
}
|
|
5710
|
+
}
|
|
5711
|
+
}
|
|
5305
5712
|
async registerPhase(extension, registration) {
|
|
5306
5713
|
if (typeof registration === "string") {
|
|
5307
5714
|
if (registration.length === 0) {
|
|
@@ -5388,6 +5795,8 @@ var ExtensionRunner = class {
|
|
|
5388
5795
|
async disposeExtension(extension, message) {
|
|
5389
5796
|
extension.runtime.invalidate(message);
|
|
5390
5797
|
for (const name of extension.phases) this.phases.delete(name);
|
|
5798
|
+
const hadCapabilities = extension.capabilities.size > 0;
|
|
5799
|
+
extension.capabilities.clear();
|
|
5391
5800
|
for (const cleanup of [...extension.cleanup].reverse()) {
|
|
5392
5801
|
await Promise.resolve().then(() => cleanup()).catch(() => void 0);
|
|
5393
5802
|
}
|
|
@@ -5395,6 +5804,9 @@ var ExtensionRunner = class {
|
|
|
5395
5804
|
await Promise.resolve().then(() => extension.disposer()).catch(() => void 0);
|
|
5396
5805
|
}
|
|
5397
5806
|
this._phaseCache = null;
|
|
5807
|
+
if (hadCapabilities) {
|
|
5808
|
+
this.notifyCapabilitiesChanged();
|
|
5809
|
+
}
|
|
5398
5810
|
}
|
|
5399
5811
|
};
|
|
5400
5812
|
function createExtensionRunner(options) {
|
|
@@ -5425,6 +5837,8 @@ function readManifestSync(dir) {
|
|
|
5425
5837
|
const rowan = pkg.rowan;
|
|
5426
5838
|
if (!rowan) return void 0;
|
|
5427
5839
|
return {
|
|
5840
|
+
id: rowan.id ?? pkg.name,
|
|
5841
|
+
name: pkg.name,
|
|
5428
5842
|
entry: rowan.extensions?.[0]
|
|
5429
5843
|
};
|
|
5430
5844
|
} catch {
|
|
@@ -5507,13 +5921,15 @@ async function discoverExtensionsInDir(dir) {
|
|
|
5507
5921
|
}
|
|
5508
5922
|
return paths;
|
|
5509
5923
|
}
|
|
5510
|
-
function loadExtensionFromFactory(factory, cwd, extensionPath = "<inline>") {
|
|
5924
|
+
function loadExtensionFromFactory(factory, cwd, extensionPath = "<inline>", options = {}) {
|
|
5511
5925
|
const resolvedCwd = resolve6(cwd);
|
|
5512
5926
|
const resolvedPath = isSyntheticPath(extensionPath) ? extensionPath : resolve6(resolvedCwd, extensionPath);
|
|
5513
|
-
const name = isSyntheticPath(extensionPath) ? extensionPath : basename3(dirname6(resolvedPath)) || "unknown";
|
|
5927
|
+
const name = options.name ?? (isSyntheticPath(extensionPath) ? extensionPath : basename3(dirname6(resolvedPath)) || "unknown");
|
|
5514
5928
|
const manifestDir = isSyntheticPath(extensionPath) ? resolvedCwd : dirname6(resolvedPath);
|
|
5515
5929
|
const manifest = readManifestSync(manifestDir);
|
|
5930
|
+
const id = options.id ?? manifest?.id ?? name;
|
|
5516
5931
|
return {
|
|
5932
|
+
id,
|
|
5517
5933
|
path: resolvedPath,
|
|
5518
5934
|
name,
|
|
5519
5935
|
factory,
|
|
@@ -5983,6 +6399,12 @@ var RuntimeExtensionLifetime = class {
|
|
|
5983
6399
|
get extensionRunner() {
|
|
5984
6400
|
return this.runner;
|
|
5985
6401
|
}
|
|
6402
|
+
get extensionHost() {
|
|
6403
|
+
return this.runner.extensionHost;
|
|
6404
|
+
}
|
|
6405
|
+
dropRunState(runId) {
|
|
6406
|
+
this.runner.dropRunState(runId);
|
|
6407
|
+
}
|
|
5986
6408
|
async close() {
|
|
5987
6409
|
if (this.closed) return;
|
|
5988
6410
|
this.closed = true;
|
|
@@ -5996,6 +6418,9 @@ var RuntimeBootstrapRegistry = class extends ResourceRegistry {
|
|
|
5996
6418
|
}
|
|
5997
6419
|
extensions;
|
|
5998
6420
|
extensionSourceId = "rowan.extensions";
|
|
6421
|
+
get extensionHost() {
|
|
6422
|
+
return this.extensions.extensionHost;
|
|
6423
|
+
}
|
|
5999
6424
|
/** Install Rowan-owned implicit resources before any host source is read. */
|
|
6000
6425
|
async ensureCoreResources() {
|
|
6001
6426
|
await this.replaceImplicit("tool", "rowan.core", [createRouteTool([])]);
|
|
@@ -6134,11 +6559,14 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6134
6559
|
autoCompactionRuns = /* @__PURE__ */ new Set();
|
|
6135
6560
|
consumers = /* @__PURE__ */ new Map();
|
|
6136
6561
|
transientEvents = new TransientRunEventHub();
|
|
6562
|
+
host;
|
|
6137
6563
|
resources;
|
|
6564
|
+
startedRuns = /* @__PURE__ */ new Set();
|
|
6138
6565
|
heartbeat;
|
|
6139
6566
|
pumping = false;
|
|
6140
6567
|
closed = false;
|
|
6141
6568
|
constructor(options, owned, resources) {
|
|
6569
|
+
this.host = options.host;
|
|
6142
6570
|
this.owned = owned;
|
|
6143
6571
|
this.commands = new ConfigCommandService(owned, options.configs, String(owned.lease.token).split(":")[0]);
|
|
6144
6572
|
this.storeIncarnation = String(owned.lease.token).split(":")[0];
|
|
@@ -6148,10 +6576,12 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6148
6576
|
static async init(options) {
|
|
6149
6577
|
if (!options.store) throw new TypeError("AgentRuntime requires a DurableStore");
|
|
6150
6578
|
const configs = options.configs ?? new InMemoryConfigProvider();
|
|
6579
|
+
const host = options.host ?? new InMemoryExtensionHost();
|
|
6151
6580
|
const concurrency = options.concurrency ?? DEFAULT_CONCURRENCY;
|
|
6152
6581
|
if (!Number.isInteger(concurrency) || concurrency <= 0) throw new TypeError("concurrency must be a positive integer");
|
|
6153
6582
|
const owned = await options.store.openOwner({ ownerId: createId("owner"), leaseMs: OWNER_LEASE_MS });
|
|
6154
|
-
const
|
|
6583
|
+
const extensions = new RuntimeExtensionLifetime({ host });
|
|
6584
|
+
const runtime = new _AgentRuntime({ ...options, configs, concurrency, host }, owned, new RuntimeBootstrapRegistry(extensions));
|
|
6155
6585
|
try {
|
|
6156
6586
|
await runtime.resources.ensureCoreResources();
|
|
6157
6587
|
await options.bootstrap?.(runtime.resources);
|
|
@@ -6164,6 +6594,20 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6164
6594
|
throw error;
|
|
6165
6595
|
}
|
|
6166
6596
|
}
|
|
6597
|
+
async handleRunEnd(runId, agentId, outcome) {
|
|
6598
|
+
if (this.startedRuns.has(runId)) {
|
|
6599
|
+
this.startedRuns.delete(runId);
|
|
6600
|
+
try {
|
|
6601
|
+
await this.resources.extensionRunner.emitRunEnd({
|
|
6602
|
+
runId,
|
|
6603
|
+
agentId,
|
|
6604
|
+
outcome
|
|
6605
|
+
});
|
|
6606
|
+
} catch {
|
|
6607
|
+
}
|
|
6608
|
+
}
|
|
6609
|
+
this.resources.extensionRunner.dropRunState(runId);
|
|
6610
|
+
}
|
|
6167
6611
|
async loadAgents(input) {
|
|
6168
6612
|
this.assertOpen();
|
|
6169
6613
|
return this.resources.loadAgents(input);
|
|
@@ -6374,6 +6818,14 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6374
6818
|
});
|
|
6375
6819
|
return { caughtUp: subscription.caughtUp.promise, done: subscription.done.promise, stop: () => controller.abort() };
|
|
6376
6820
|
}
|
|
6821
|
+
listCapabilities() {
|
|
6822
|
+
this.assertOpen();
|
|
6823
|
+
return this.resources.extensionRunner.getCapabilities();
|
|
6824
|
+
}
|
|
6825
|
+
onCapabilitiesChanged(listener) {
|
|
6826
|
+
this.assertOpen();
|
|
6827
|
+
return this.resources.extensionRunner.onCapabilitiesChanged(listener);
|
|
6828
|
+
}
|
|
6377
6829
|
async close() {
|
|
6378
6830
|
if (this.closed) return;
|
|
6379
6831
|
this.closed = true;
|
|
@@ -6417,6 +6869,11 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6417
6869
|
const active = this.executions.get(runId);
|
|
6418
6870
|
if (active) this.transientEvents.clear(runId, active.executionId);
|
|
6419
6871
|
active?.controller.abort();
|
|
6872
|
+
if (this.startedRuns.has(runId)) {
|
|
6873
|
+
await this.handleRunEnd(runId, snapshot.agentId, { id: createId("out"), status: "cancelled", message: reason ?? "Agent run stopped." });
|
|
6874
|
+
} else {
|
|
6875
|
+
this.resources.extensionRunner.dropRunState(runId);
|
|
6876
|
+
}
|
|
6420
6877
|
return boundaryFromSnapshot(await this.owned.snapshotRun(runId));
|
|
6421
6878
|
}
|
|
6422
6879
|
async pump() {
|
|
@@ -6528,6 +6985,19 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6528
6985
|
const controller = new AbortController();
|
|
6529
6986
|
this.executions.set(run.id, { controller, executionId });
|
|
6530
6987
|
if (this.cancellationRequested.has(run.id)) controller.abort();
|
|
6988
|
+
if (!this.startedRuns.has(run.id)) {
|
|
6989
|
+
this.startedRuns.add(run.id);
|
|
6990
|
+
const turn = typeof run.input === "object" && run.input !== null && !Array.isArray(run.input) ? run.input : {};
|
|
6991
|
+
try {
|
|
6992
|
+
await this.resources.extensionRunner.emitRunStart({
|
|
6993
|
+
runId: run.id,
|
|
6994
|
+
agentId: run.agentId,
|
|
6995
|
+
metadata: run.metadata ?? {},
|
|
6996
|
+
turn
|
|
6997
|
+
});
|
|
6998
|
+
} catch {
|
|
6999
|
+
}
|
|
7000
|
+
}
|
|
6531
7001
|
const assembly = assembleRegisteredExtensions(config, this.resources.extensionRunner, {
|
|
6532
7002
|
toolArchiveDir: this.archiveDirFor(run.agentId)
|
|
6533
7003
|
});
|
|
@@ -6754,6 +7224,11 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6754
7224
|
...output && hasVisibleAssistantText(output) ? { output } : {}
|
|
6755
7225
|
});
|
|
6756
7226
|
this.transientEvents.clear(run.id, claim.execution.executionId);
|
|
7227
|
+
await this.handleRunEnd(run.id, run.agentId, {
|
|
7228
|
+
id: createId("out"),
|
|
7229
|
+
status: "cancelled",
|
|
7230
|
+
message: reason
|
|
7231
|
+
});
|
|
6757
7232
|
return;
|
|
6758
7233
|
}
|
|
6759
7234
|
if (result.type === "input_required") {
|
|
@@ -6789,33 +7264,53 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6789
7264
|
const output = latestAssistant(run, result.messages, executionContext.messages.length);
|
|
6790
7265
|
await this.owned.commitOutcome({ runId: run.id, execution: claim.execution, expectedRevision: executionRevision, outcome: durableOutcome(result.outcome), ...output ? { output } : {} });
|
|
6791
7266
|
this.transientEvents.clear(run.id, claim.execution.executionId, true);
|
|
7267
|
+
await this.handleRunEnd(run.id, run.agentId, result.outcome);
|
|
6792
7268
|
return;
|
|
6793
7269
|
}
|
|
6794
7270
|
const failure = { code: "execution_failed", message: result.error instanceof Error ? result.error.message : "Execution failed." };
|
|
6795
7271
|
await this.owned.commitOutcome({ runId: run.id, execution: claim.execution, expectedRevision: executionRevision, failure });
|
|
6796
7272
|
this.transientEvents.clear(run.id, claim.execution.executionId);
|
|
7273
|
+
await this.handleRunEnd(run.id, run.agentId, {
|
|
7274
|
+
id: createId("out"),
|
|
7275
|
+
status: "failed",
|
|
7276
|
+
message: failure.message,
|
|
7277
|
+
error: failure
|
|
7278
|
+
});
|
|
6797
7279
|
} catch (error) {
|
|
6798
7280
|
if (!claim && error instanceof RuntimeError && ["run_state_conflict", "runtime_ownership_lost", "run_not_found"].includes(error.code)) return;
|
|
6799
7281
|
if (claim) {
|
|
6800
7282
|
if (this.cancellationRequested.has(run.id)) {
|
|
7283
|
+
const reason = this.cancellationReasons.get(run.id) ?? "Agent run stopped.";
|
|
6801
7284
|
await this.owned.cancelRun({
|
|
6802
7285
|
runId: run.id,
|
|
6803
7286
|
expectedRevision: executionRevision,
|
|
6804
|
-
reason
|
|
7287
|
+
reason
|
|
6805
7288
|
}).catch(() => void 0);
|
|
7289
|
+
await this.handleRunEnd(run.id, run.agentId, {
|
|
7290
|
+
id: createId("out"),
|
|
7291
|
+
status: "cancelled",
|
|
7292
|
+
message: reason
|
|
7293
|
+
});
|
|
6806
7294
|
return;
|
|
6807
7295
|
}
|
|
7296
|
+
const failureMessage = error instanceof Error ? error.message : "Execution failed.";
|
|
6808
7297
|
await this.owned.commitOutcome({
|
|
6809
7298
|
runId: run.id,
|
|
6810
7299
|
execution: claim.execution,
|
|
6811
7300
|
expectedRevision: executionRevision,
|
|
6812
|
-
failure: { code: "execution_failed", message:
|
|
7301
|
+
failure: { code: "execution_failed", message: failureMessage }
|
|
6813
7302
|
}).catch(async (commitError) => {
|
|
6814
7303
|
await this.owned.cancelRun({
|
|
6815
7304
|
runId: run.id,
|
|
6816
7305
|
reason: commitError instanceof Error ? commitError.message : "Run failure could not be committed."
|
|
6817
7306
|
}).catch(() => void 0);
|
|
6818
7307
|
});
|
|
7308
|
+
await this.handleRunEnd(run.id, run.agentId, {
|
|
7309
|
+
id: createId("out"),
|
|
7310
|
+
status: "failed",
|
|
7311
|
+
message: failureMessage,
|
|
7312
|
+
error: { code: "execution_failed", message: failureMessage }
|
|
7313
|
+
});
|
|
6819
7314
|
return;
|
|
6820
7315
|
}
|
|
6821
7316
|
throw error;
|
|
@@ -6838,6 +7333,8 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6838
7333
|
return { result: batch.results[0], revision: batch.revision };
|
|
6839
7334
|
}
|
|
6840
7335
|
async executeToolBatch(input) {
|
|
7336
|
+
const scope = resolveScopeFromMetadata(input.run.metadata);
|
|
7337
|
+
const turn = typeof input.run.input === "object" && input.run.input !== null && !Array.isArray(input.run.input) ? input.run.input : {};
|
|
6841
7338
|
const checkpoint = input.driver?.checkpoint();
|
|
6842
7339
|
const isSuspensionResume = checkpoint && typeof checkpoint === "object" && checkpoint.kind === "tool_call_suspension";
|
|
6843
7340
|
const suspension = isSuspensionResume ? checkpoint : void 0;
|
|
@@ -6864,6 +7361,8 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6864
7361
|
...input.agentMetadata === void 0 ? {} : { agentMetadata: input.agentMetadata },
|
|
6865
7362
|
...input.run.metadata === void 0 ? {} : { runMetadata: input.run.metadata },
|
|
6866
7363
|
toolCallId,
|
|
7364
|
+
scope,
|
|
7365
|
+
turn,
|
|
6867
7366
|
interaction: createRunInteractionDriver({
|
|
6868
7367
|
currentPhase: "default",
|
|
6869
7368
|
attempt: 0,
|
|
@@ -6951,6 +7450,8 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
6951
7450
|
...input.agentMetadata === void 0 ? {} : { agentMetadata: input.agentMetadata },
|
|
6952
7451
|
...input.run.metadata === void 0 ? {} : { runMetadata: input.run.metadata },
|
|
6953
7452
|
toolCallId,
|
|
7453
|
+
scope,
|
|
7454
|
+
turn,
|
|
6954
7455
|
interaction: createToolInteractionDriver(input.driver, {
|
|
6955
7456
|
toolCallId,
|
|
6956
7457
|
toolCallIds,
|
|
@@ -7105,6 +7606,8 @@ var AgentRuntime = class _AgentRuntime {
|
|
|
7105
7606
|
...input.agentMetadata === void 0 ? {} : { agentMetadata: input.agentMetadata },
|
|
7106
7607
|
...input.run.metadata === void 0 ? {} : { runMetadata: input.run.metadata },
|
|
7107
7608
|
toolCallId,
|
|
7609
|
+
scope,
|
|
7610
|
+
turn,
|
|
7108
7611
|
interaction: createToolInteractionDriver(input.driver, {
|
|
7109
7612
|
toolCallId,
|
|
7110
7613
|
...suspension?.toolCallIds === void 0 ? {} : { toolCallIds: suspension.toolCallIds },
|
|
@@ -7618,9 +8121,83 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7618
8121
|
eventSequence = 0;
|
|
7619
8122
|
retentionFloor = 1;
|
|
7620
8123
|
contextCompactions = /* @__PURE__ */ new Map();
|
|
8124
|
+
recorder;
|
|
8125
|
+
runReceiptKeys = /* @__PURE__ */ new Map();
|
|
7621
8126
|
constructor(options = {}) {
|
|
7622
8127
|
this.incarnation = options.incarnation ?? createId("store");
|
|
7623
8128
|
}
|
|
8129
|
+
setChangeRecorder(recorder) {
|
|
8130
|
+
this.recorder = recorder;
|
|
8131
|
+
}
|
|
8132
|
+
touchAgent(agent) {
|
|
8133
|
+
this.recorder?.onAgentUpsert(agent);
|
|
8134
|
+
}
|
|
8135
|
+
touchRun(run) {
|
|
8136
|
+
this.recorder?.onRunUpsert(run);
|
|
8137
|
+
}
|
|
8138
|
+
storeMessage(message) {
|
|
8139
|
+
this.messages.set(message.id, message);
|
|
8140
|
+
this.recorder?.onMessageInsert(message);
|
|
8141
|
+
}
|
|
8142
|
+
storeToolCall(toolCall) {
|
|
8143
|
+
this.toolCalls.set(toolCall.id, toolCall);
|
|
8144
|
+
this.recorder?.onToolCallUpsert(toolCall);
|
|
8145
|
+
}
|
|
8146
|
+
appendEvent(event) {
|
|
8147
|
+
this.events.push(event);
|
|
8148
|
+
this.recorder?.onEventAppend(event);
|
|
8149
|
+
}
|
|
8150
|
+
inferRunIdForReceipt(key, payload) {
|
|
8151
|
+
const parts = key.split(":");
|
|
8152
|
+
const prefix = parts[0];
|
|
8153
|
+
if (["queued_failure", "phase_entered", "input_required", "interaction_answer", "outcome", "cancel"].includes(prefix) && parts[1]) {
|
|
8154
|
+
return parts[1];
|
|
8155
|
+
}
|
|
8156
|
+
const match = payload.match(/^\[\s*"([^"]+)"/);
|
|
8157
|
+
if (match && match[1]) {
|
|
8158
|
+
const candidate = match[1];
|
|
8159
|
+
if (this.runs.has(candidate) || candidate.startsWith("run_") || candidate.startsWith("run-")) {
|
|
8160
|
+
return candidate;
|
|
8161
|
+
}
|
|
8162
|
+
}
|
|
8163
|
+
return void 0;
|
|
8164
|
+
}
|
|
8165
|
+
dropRunOperationReceipts(runId) {
|
|
8166
|
+
const keys = this.runReceiptKeys.get(runId);
|
|
8167
|
+
if (keys && keys.size > 0) {
|
|
8168
|
+
for (const key of keys) {
|
|
8169
|
+
this.operationReceipts.delete(key);
|
|
8170
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
8171
|
+
}
|
|
8172
|
+
this.runReceiptKeys.delete(runId);
|
|
8173
|
+
}
|
|
8174
|
+
for (const [key] of this.operationReceipts.entries()) {
|
|
8175
|
+
if (key.includes(`:${runId}:`) || key.endsWith(`:${runId}`) || key.startsWith(`phase_output:${runId}`) || key.startsWith(`tool_reserve_batch:${runId}`)) {
|
|
8176
|
+
this.operationReceipts.delete(key);
|
|
8177
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
8178
|
+
}
|
|
8179
|
+
}
|
|
8180
|
+
}
|
|
8181
|
+
compactTerminalReceipts() {
|
|
8182
|
+
let count = 0;
|
|
8183
|
+
for (const [key, receipt] of [...this.operationReceipts.entries()]) {
|
|
8184
|
+
const runId = this.inferRunIdForReceipt(key, receipt.payload);
|
|
8185
|
+
if (runId) {
|
|
8186
|
+
const run = this.runs.get(runId);
|
|
8187
|
+
if (!run || ["completed", "failed", "cancelled"].includes(run.state)) {
|
|
8188
|
+
this.operationReceipts.delete(key);
|
|
8189
|
+
const keys = this.runReceiptKeys.get(runId);
|
|
8190
|
+
if (keys) {
|
|
8191
|
+
keys.delete(key);
|
|
8192
|
+
if (keys.size === 0) this.runReceiptKeys.delete(runId);
|
|
8193
|
+
}
|
|
8194
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
8195
|
+
count += 1;
|
|
8196
|
+
}
|
|
8197
|
+
}
|
|
8198
|
+
}
|
|
8199
|
+
return count;
|
|
8200
|
+
}
|
|
7624
8201
|
static fromState(state) {
|
|
7625
8202
|
const store = new _InMemoryStore({ incarnation: state.incarnation });
|
|
7626
8203
|
for (const agent of state.agents) store.agents.set(agent.id, clone(agent));
|
|
@@ -7638,6 +8215,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7638
8215
|
clonedRun.updatedAt = createTimestamp();
|
|
7639
8216
|
store.runs.set(clonedRun.id, clonedRun);
|
|
7640
8217
|
store.appendTransition(clonedRun, "input_required", "cancelled", { reason: clonedRun.cancellationReason });
|
|
8218
|
+
store.dropRunOperationReceipts(clonedRun.id);
|
|
7641
8219
|
} else {
|
|
7642
8220
|
store.runs.set(clonedRun.id, clonedRun);
|
|
7643
8221
|
}
|
|
@@ -7646,7 +8224,18 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7646
8224
|
for (const toolCall of state.toolCalls ?? []) store.toolCalls.set(toolCall.id, clone(toolCall));
|
|
7647
8225
|
store.events.push(...clone(state.events));
|
|
7648
8226
|
for (const [key, receipt] of state.idempotency) store.idempotency.set(key, clone(receipt));
|
|
7649
|
-
for (const [key, receipt] of state.operationReceipts)
|
|
8227
|
+
for (const [key, receipt] of state.operationReceipts) {
|
|
8228
|
+
store.operationReceipts.set(key, clone(receipt));
|
|
8229
|
+
const runId = store.inferRunIdForReceipt(key, receipt.payload);
|
|
8230
|
+
if (runId) {
|
|
8231
|
+
let keys = store.runReceiptKeys.get(runId);
|
|
8232
|
+
if (!keys) {
|
|
8233
|
+
keys = /* @__PURE__ */ new Set();
|
|
8234
|
+
store.runReceiptKeys.set(runId, keys);
|
|
8235
|
+
}
|
|
8236
|
+
keys.add(key);
|
|
8237
|
+
}
|
|
8238
|
+
}
|
|
7650
8239
|
for (const [agentId, messages] of state.historySeeds ?? []) store.historySeeds.set(agentId, clone(messages));
|
|
7651
8240
|
for (const [consumerId, cursor] of state.consumerCheckpoints ?? []) store.consumerCheckpoints.set(consumerId, cursor);
|
|
7652
8241
|
for (const [agentId, sequence] of state.nextAgentSequence) store.nextAgentSequence.set(agentId, sequence);
|
|
@@ -7679,6 +8268,16 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7679
8268
|
contextCompactions: [...this.contextCompactions.entries()]
|
|
7680
8269
|
});
|
|
7681
8270
|
}
|
|
8271
|
+
exportMetadata() {
|
|
8272
|
+
return {
|
|
8273
|
+
incarnation: this.incarnation,
|
|
8274
|
+
eventSequence: this.eventSequence,
|
|
8275
|
+
nextAgentSequence: [...this.nextAgentSequence.entries()],
|
|
8276
|
+
nextReadySequence: [...this.nextReadySequence.entries()],
|
|
8277
|
+
historySeeds: [...this.historySeeds.entries()],
|
|
8278
|
+
contextCompactions: [...this.contextCompactions.entries()]
|
|
8279
|
+
};
|
|
8280
|
+
}
|
|
7682
8281
|
attachOwner(lease) {
|
|
7683
8282
|
this.owner = clone(lease);
|
|
7684
8283
|
this.ownerEpoch = Math.max(this.ownerEpoch, lease.epoch);
|
|
@@ -7701,6 +8300,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7701
8300
|
run.revision += 1;
|
|
7702
8301
|
run.updatedAt = createTimestamp();
|
|
7703
8302
|
this.appendTransition(run, "running", "failed", { failure });
|
|
8303
|
+
this.dropRunOperationReceipts(run.id);
|
|
7704
8304
|
}
|
|
7705
8305
|
}
|
|
7706
8306
|
async openOwner(input) {
|
|
@@ -7718,6 +8318,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7718
8318
|
}
|
|
7719
8319
|
if (this.owner) this.interruptOwner(this.owner.epoch);
|
|
7720
8320
|
this.dropSettledClaimReceipts();
|
|
8321
|
+
this.compactTerminalReceipts();
|
|
7721
8322
|
this.ownerEpoch += 1;
|
|
7722
8323
|
this.owner = {
|
|
7723
8324
|
ownerId: input.ownerId,
|
|
@@ -7764,6 +8365,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7764
8365
|
updatedAt: timestamp
|
|
7765
8366
|
};
|
|
7766
8367
|
this.agents.set(agent.id, agent);
|
|
8368
|
+
this.touchAgent(agent);
|
|
7767
8369
|
if (input.historySeed && input.historySeed.length > 0) this.historySeeds.set(agent.id, materializeHistorySeed(agent.id, input.historySeed));
|
|
7768
8370
|
this.nextAgentSequence.set(agent.id, 0);
|
|
7769
8371
|
this.nextReadySequence.set(agent.id, 0);
|
|
@@ -7777,6 +8379,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7777
8379
|
if (configToken !== void 0) agent.currentConfigToken = configToken;
|
|
7778
8380
|
if (configIdentity !== void 0) agent.currentConfigIdentity = configIdentity;
|
|
7779
8381
|
agent.updatedAt = createTimestamp();
|
|
8382
|
+
this.touchAgent(agent);
|
|
7780
8383
|
return clone(agent);
|
|
7781
8384
|
}
|
|
7782
8385
|
updateAgentConfigToken(lease, input) {
|
|
@@ -7789,6 +8392,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7789
8392
|
agent.currentConfigToken = input.token;
|
|
7790
8393
|
if (input.configIdentity !== void 0) agent.currentConfigIdentity = input.configIdentity;
|
|
7791
8394
|
agent.updatedAt = createTimestamp();
|
|
8395
|
+
this.touchAgent(agent);
|
|
7792
8396
|
this.writeReceipt(scope, payload, agent);
|
|
7793
8397
|
return clone(agent);
|
|
7794
8398
|
}
|
|
@@ -7810,24 +8414,48 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7810
8414
|
}
|
|
7811
8415
|
const runIds = new Set(runs.map((run) => run.id));
|
|
7812
8416
|
this.agents.delete(agent.id);
|
|
8417
|
+
this.recorder?.onAgentDelete(agent.id);
|
|
7813
8418
|
this.nextAgentSequence.delete(agent.id);
|
|
7814
8419
|
this.nextReadySequence.delete(agent.id);
|
|
7815
8420
|
this.historySeeds.delete(agent.id);
|
|
7816
|
-
for (const run of runs)
|
|
8421
|
+
for (const run of runs) {
|
|
8422
|
+
this.runs.delete(run.id);
|
|
8423
|
+
this.runReceiptKeys.delete(run.id);
|
|
8424
|
+
this.recorder?.onRunDelete(run.id);
|
|
8425
|
+
}
|
|
7817
8426
|
for (const [messageId, message] of this.messages) {
|
|
7818
|
-
if (runIds.has(message.runId))
|
|
8427
|
+
if (runIds.has(message.runId)) {
|
|
8428
|
+
this.messages.delete(messageId);
|
|
8429
|
+
this.recorder?.onMessageDelete(messageId);
|
|
8430
|
+
}
|
|
7819
8431
|
}
|
|
7820
8432
|
for (const [toolCallId, toolCall] of this.toolCalls) {
|
|
7821
|
-
if (runIds.has(toolCall.runId))
|
|
8433
|
+
if (runIds.has(toolCall.runId)) {
|
|
8434
|
+
this.toolCalls.delete(toolCallId);
|
|
8435
|
+
this.recorder?.onToolCallDelete(toolCallId);
|
|
8436
|
+
}
|
|
7822
8437
|
}
|
|
8438
|
+
const deletedEventIds = [];
|
|
7823
8439
|
for (let index = this.events.length - 1; index >= 0; index -= 1) {
|
|
7824
|
-
if (this.events[index].agentId === agent.id)
|
|
8440
|
+
if (this.events[index].agentId === agent.id) {
|
|
8441
|
+
deletedEventIds.push(this.events[index].id);
|
|
8442
|
+
this.events.splice(index, 1);
|
|
8443
|
+
}
|
|
8444
|
+
}
|
|
8445
|
+
if (deletedEventIds.length > 0) {
|
|
8446
|
+
this.recorder?.onEventsTruncate(deletedEventIds);
|
|
7825
8447
|
}
|
|
7826
8448
|
for (const [key] of this.idempotency) {
|
|
7827
|
-
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId))))
|
|
8449
|
+
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId)))) {
|
|
8450
|
+
this.idempotency.delete(key);
|
|
8451
|
+
this.recorder?.onIdempotencyDelete(key);
|
|
8452
|
+
}
|
|
7828
8453
|
}
|
|
7829
8454
|
for (const [key] of this.operationReceipts) {
|
|
7830
|
-
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId))))
|
|
8455
|
+
if (key.includes(String(agent.id)) || [...runIds].some((runId) => key.includes(String(runId)))) {
|
|
8456
|
+
this.operationReceipts.delete(key);
|
|
8457
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
8458
|
+
}
|
|
7831
8459
|
}
|
|
7832
8460
|
}
|
|
7833
8461
|
reviseMessage(lease, input) {
|
|
@@ -7935,14 +8563,19 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7935
8563
|
run.revision += 1;
|
|
7936
8564
|
run.updatedAt = timestamp;
|
|
7937
8565
|
this.appendTransition(run, previousState, "cancelled", { reason: run.cancellationReason });
|
|
8566
|
+
this.dropRunOperationReceipts(run.id);
|
|
7938
8567
|
} else {
|
|
7939
8568
|
run.revision += 1;
|
|
7940
8569
|
run.updatedAt = timestamp;
|
|
8570
|
+
this.touchRun(run);
|
|
7941
8571
|
}
|
|
7942
8572
|
}
|
|
7943
8573
|
for (const [messageId, message] of this.messages) {
|
|
7944
8574
|
if (!affectedRunSet.has(message.runId)) continue;
|
|
7945
|
-
if (message.runId !== original.runId || message.sequenceWithinRun > original.sequenceWithinRun)
|
|
8575
|
+
if (message.runId !== original.runId || message.sequenceWithinRun > original.sequenceWithinRun) {
|
|
8576
|
+
this.messages.delete(messageId);
|
|
8577
|
+
this.recorder?.onMessageDelete(messageId);
|
|
8578
|
+
}
|
|
7946
8579
|
}
|
|
7947
8580
|
if (isSeedMessage) {
|
|
7948
8581
|
const targetIndex = seed.findIndex(({ id }) => id === original.id);
|
|
@@ -7956,10 +8589,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7956
8589
|
sequenceWithinRun: 0,
|
|
7957
8590
|
createdAt: timestamp
|
|
7958
8591
|
};
|
|
7959
|
-
this.
|
|
8592
|
+
this.storeMessage(revisedMessage);
|
|
7960
8593
|
this.runs.set(replacementRun.id, replacementRun);
|
|
8594
|
+
this.touchRun(replacementRun);
|
|
7961
8595
|
this.appendTransition(replacementRun, null, "queued");
|
|
7962
|
-
this.
|
|
8596
|
+
this.appendEvent({
|
|
7963
8597
|
...this.baseEvent(replacementRun),
|
|
7964
8598
|
kind: "message_revised",
|
|
7965
8599
|
message: revisedMessage,
|
|
@@ -7975,7 +8609,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7975
8609
|
affectedToolCallIds: affectedTools.map((toolCall) => toolCall.id),
|
|
7976
8610
|
...effectDigest === void 0 ? {} : { effectDigest }
|
|
7977
8611
|
};
|
|
7978
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8612
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, replacementRun.id);
|
|
7979
8613
|
return clone(result);
|
|
7980
8614
|
}
|
|
7981
8615
|
commitInteractionRecord(run, interaction, status, answer, reply) {
|
|
@@ -7997,7 +8631,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
7997
8631
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
7998
8632
|
createdAt: now
|
|
7999
8633
|
};
|
|
8000
|
-
this.
|
|
8634
|
+
this.storeMessage(record);
|
|
8001
8635
|
this.appendMessage(run, record);
|
|
8002
8636
|
return record;
|
|
8003
8637
|
}
|
|
@@ -8046,12 +8680,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8046
8680
|
sequenceWithinRun: this.nextMessageSequence(waitingRun.id),
|
|
8047
8681
|
createdAt: now
|
|
8048
8682
|
};
|
|
8049
|
-
this.
|
|
8683
|
+
this.storeMessage(message);
|
|
8050
8684
|
this.appendMessage(waitingRun, message);
|
|
8051
8685
|
waitingRun.readySequence = this.nextReady(waitingRun.agentId);
|
|
8052
8686
|
waitingRun.state = "queued";
|
|
8053
8687
|
waitingRun.revision += 1;
|
|
8054
8688
|
waitingRun.updatedAt = now;
|
|
8689
|
+
this.touchRun(waitingRun);
|
|
8055
8690
|
this.appendTransition(waitingRun, "input_required", "queued");
|
|
8056
8691
|
this.writeReceipt(scope, payload, waitingRun);
|
|
8057
8692
|
return clone(waitingRun);
|
|
@@ -8073,6 +8708,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8073
8708
|
updatedAt: timestamp
|
|
8074
8709
|
};
|
|
8075
8710
|
this.runs.set(run.id, run);
|
|
8711
|
+
this.touchRun(run);
|
|
8076
8712
|
this.appendTransition(run, null, "queued");
|
|
8077
8713
|
this.writeReceipt(scope, payload, run);
|
|
8078
8714
|
return clone(run);
|
|
@@ -8115,7 +8751,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8115
8751
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
8116
8752
|
createdAt: createTimestamp()
|
|
8117
8753
|
};
|
|
8118
|
-
this.
|
|
8754
|
+
this.storeMessage(message);
|
|
8119
8755
|
committedMessages.push(message);
|
|
8120
8756
|
}
|
|
8121
8757
|
const execution = {
|
|
@@ -8127,10 +8763,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8127
8763
|
run.execution = execution;
|
|
8128
8764
|
run.revision += 1;
|
|
8129
8765
|
run.updatedAt = createTimestamp();
|
|
8766
|
+
this.touchRun(run);
|
|
8130
8767
|
for (const message of committedMessages) this.appendMessage(run, message);
|
|
8131
8768
|
this.appendTransition(run, "queued", "running");
|
|
8132
8769
|
const result = { run: clone(run), execution: clone(execution), history: this.activeHistory(run.agentId, run.agentSequence) };
|
|
8133
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8770
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8134
8771
|
return result;
|
|
8135
8772
|
}
|
|
8136
8773
|
failQueuedRun(lease, input) {
|
|
@@ -8146,9 +8783,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8146
8783
|
run.failure = clone(input.failure);
|
|
8147
8784
|
run.revision += 1;
|
|
8148
8785
|
run.updatedAt = createTimestamp();
|
|
8786
|
+
this.touchRun(run);
|
|
8149
8787
|
this.appendTransition(run, "queued", "failed", { failure: input.failure });
|
|
8788
|
+
this.dropRunOperationReceipts(run.id);
|
|
8150
8789
|
const result = clone(run);
|
|
8151
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8790
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8152
8791
|
return result;
|
|
8153
8792
|
}
|
|
8154
8793
|
commitPhaseEntered(lease, input) {
|
|
@@ -8164,10 +8803,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8164
8803
|
run.currentPhaseId = input.phaseId;
|
|
8165
8804
|
run.revision += 1;
|
|
8166
8805
|
run.updatedAt = createTimestamp();
|
|
8806
|
+
this.touchRun(run);
|
|
8167
8807
|
const visit2 = this.events.filter((event) => event.runId === run.id && event.kind === "phase_entered").length + 1;
|
|
8168
|
-
this.
|
|
8808
|
+
this.appendEvent(this.baseEvent(run, { kind: "phase_entered", executionId: input.execution.executionId, phaseId: input.phaseId, visit: visit2 }));
|
|
8169
8809
|
const result = clone(run);
|
|
8170
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8810
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8171
8811
|
return result;
|
|
8172
8812
|
}
|
|
8173
8813
|
/** Commit a parallel Phase's reply while its Run is still running. */
|
|
@@ -8188,12 +8828,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8188
8828
|
role: "assistant",
|
|
8189
8829
|
sequenceWithinRun: this.nextMessageSequence(run.id)
|
|
8190
8830
|
};
|
|
8191
|
-
this.
|
|
8831
|
+
this.storeMessage(message);
|
|
8192
8832
|
run.revision += 1;
|
|
8193
8833
|
run.updatedAt = createTimestamp();
|
|
8834
|
+
this.touchRun(run);
|
|
8194
8835
|
this.appendMessage(run, message);
|
|
8195
8836
|
const result = clone(run);
|
|
8196
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8837
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8197
8838
|
return result;
|
|
8198
8839
|
}
|
|
8199
8840
|
commitInputRequired(lease, input) {
|
|
@@ -8215,7 +8856,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8215
8856
|
...clone(input.prompt),
|
|
8216
8857
|
sequenceWithinRun: this.nextMessageSequence(run.id)
|
|
8217
8858
|
};
|
|
8218
|
-
this.
|
|
8859
|
+
this.storeMessage(prompt);
|
|
8219
8860
|
}
|
|
8220
8861
|
run.state = "input_required";
|
|
8221
8862
|
run.checkpoint = clone(input.checkpoint);
|
|
@@ -8230,12 +8871,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8230
8871
|
delete run.execution;
|
|
8231
8872
|
run.revision += 1;
|
|
8232
8873
|
run.updatedAt = createTimestamp();
|
|
8874
|
+
this.touchRun(run);
|
|
8233
8875
|
if (prompt) {
|
|
8234
8876
|
this.appendMessage(run, prompt);
|
|
8235
8877
|
}
|
|
8236
8878
|
this.appendTransition(run, "running", "input_required", { prompt, interactions, answers: run.interactionAnswers ?? {} });
|
|
8237
8879
|
const result = clone(run);
|
|
8238
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8880
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8239
8881
|
return result;
|
|
8240
8882
|
}
|
|
8241
8883
|
answerInteraction(lease, input) {
|
|
@@ -8283,8 +8925,9 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8283
8925
|
run.state = "queued";
|
|
8284
8926
|
this.appendTransition(run, "input_required", "queued");
|
|
8285
8927
|
}
|
|
8928
|
+
this.touchRun(run);
|
|
8286
8929
|
const result = clone(run);
|
|
8287
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8930
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8288
8931
|
return result;
|
|
8289
8932
|
}
|
|
8290
8933
|
reserveToolCall(lease, input) {
|
|
@@ -8358,17 +9001,18 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8358
9001
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
8359
9002
|
createdAt: timestamp
|
|
8360
9003
|
};
|
|
8361
|
-
for (const toolCall of toolCalls) this.
|
|
8362
|
-
this.
|
|
9004
|
+
for (const toolCall of toolCalls) this.storeToolCall(toolCall);
|
|
9005
|
+
this.storeMessage(requestMessage);
|
|
8363
9006
|
run.revision += 1;
|
|
8364
9007
|
run.updatedAt = timestamp;
|
|
9008
|
+
this.touchRun(run);
|
|
8365
9009
|
this.appendMessage(run, requestMessage);
|
|
8366
9010
|
for (const toolCall of toolCalls) this.appendToolTransition(run, { from: null, to: "pending" }, toolCall);
|
|
8367
9011
|
const result = {
|
|
8368
9012
|
run: clone(run),
|
|
8369
9013
|
toolCalls: toolCalls.map((toolCall) => clone(toolCall))
|
|
8370
9014
|
};
|
|
8371
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
9015
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8372
9016
|
return result;
|
|
8373
9017
|
}
|
|
8374
9018
|
startToolCall(lease, input) {
|
|
@@ -8383,13 +9027,14 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8383
9027
|
if (toolCall.state !== "pending") throw new RuntimeError("run_state_conflict", { runId: run.id, expected: ["running"], actual: run.state });
|
|
8384
9028
|
toolCall.state = "running";
|
|
8385
9029
|
toolCall.executionId = input.execution.executionId;
|
|
8386
|
-
toolCall.executionId = input.execution.executionId;
|
|
8387
9030
|
toolCall.updatedAt = createTimestamp();
|
|
9031
|
+
this.storeToolCall(toolCall);
|
|
8388
9032
|
run.revision += 1;
|
|
8389
9033
|
run.updatedAt = toolCall.updatedAt;
|
|
9034
|
+
this.touchRun(run);
|
|
8390
9035
|
this.appendToolTransition(run, { from: "pending", to: "running" }, toolCall);
|
|
8391
9036
|
const result = { run: clone(run), toolCall: clone(toolCall) };
|
|
8392
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
9037
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8393
9038
|
return result;
|
|
8394
9039
|
}
|
|
8395
9040
|
suspendToolCall(lease, input) {
|
|
@@ -8406,11 +9051,13 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8406
9051
|
}
|
|
8407
9052
|
toolCall.state = "pending";
|
|
8408
9053
|
toolCall.updatedAt = createTimestamp();
|
|
9054
|
+
this.storeToolCall(toolCall);
|
|
8409
9055
|
run.revision += 1;
|
|
8410
9056
|
run.updatedAt = toolCall.updatedAt;
|
|
9057
|
+
this.touchRun(run);
|
|
8411
9058
|
this.appendToolTransition(run, { from: "running", to: "pending" }, toolCall);
|
|
8412
9059
|
const result = { run: clone(run), toolCall: clone(toolCall) };
|
|
8413
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
9060
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8414
9061
|
return result;
|
|
8415
9062
|
}
|
|
8416
9063
|
commitToolResult(lease, input) {
|
|
@@ -8442,15 +9089,17 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8442
9089
|
sequenceWithinRun: this.nextMessageSequence(run.id),
|
|
8443
9090
|
createdAt: createTimestamp()
|
|
8444
9091
|
};
|
|
8445
|
-
this.
|
|
9092
|
+
this.storeMessage(message);
|
|
8446
9093
|
toolCall.state = input.state;
|
|
8447
9094
|
toolCall.result = durableResult;
|
|
8448
9095
|
toolCall.resultMessageId = resultMessageId;
|
|
8449
9096
|
if (input.state === "indeterminate") toolCall.reason = input.reason;
|
|
8450
9097
|
else delete toolCall.reason;
|
|
8451
9098
|
toolCall.updatedAt = message.createdAt;
|
|
9099
|
+
this.storeToolCall(toolCall);
|
|
8452
9100
|
run.revision += 1;
|
|
8453
9101
|
run.updatedAt = message.createdAt;
|
|
9102
|
+
this.touchRun(run);
|
|
8454
9103
|
this.appendToolTransition(run, { from, to: input.state }, toolCall);
|
|
8455
9104
|
this.appendMessage(run, message);
|
|
8456
9105
|
if (input.state === "indeterminate") {
|
|
@@ -8471,10 +9120,12 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8471
9120
|
delete run.execution;
|
|
8472
9121
|
run.revision += 1;
|
|
8473
9122
|
run.updatedAt = createTimestamp();
|
|
9123
|
+
this.touchRun(run);
|
|
8474
9124
|
this.appendTransition(run, "running", "failed", { failure });
|
|
9125
|
+
this.dropRunOperationReceipts(run.id);
|
|
8475
9126
|
}
|
|
8476
9127
|
const result = { run: clone(run), toolCall: clone(toolCall) };
|
|
8477
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
9128
|
+
this.writeOperationReceipt(operationKey, operationPayload, result, run.id);
|
|
8478
9129
|
return result;
|
|
8479
9130
|
}
|
|
8480
9131
|
commitOutcome(lease, input) {
|
|
@@ -8492,7 +9143,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8492
9143
|
if (nextState === "failed" && !input.failure) throw new TypeError("failed Run requires a failure");
|
|
8493
9144
|
const output = input.output ? { ...clone(input.output), sequenceWithinRun: this.nextMessageSequence(run.id) } : void 0;
|
|
8494
9145
|
if (output) {
|
|
8495
|
-
this.
|
|
9146
|
+
this.storeMessage(output);
|
|
8496
9147
|
this.appendMessage(run, output);
|
|
8497
9148
|
}
|
|
8498
9149
|
run.state = nextState;
|
|
@@ -8504,9 +9155,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8504
9155
|
delete run.interactionAnswers;
|
|
8505
9156
|
run.revision += 1;
|
|
8506
9157
|
run.updatedAt = createTimestamp();
|
|
9158
|
+
this.touchRun(run);
|
|
8507
9159
|
this.appendTransition(run, "running", nextState, { outcome: input.outcome, failure: input.failure, output });
|
|
9160
|
+
this.dropRunOperationReceipts(run.id);
|
|
8508
9161
|
const result = clone(run);
|
|
8509
|
-
this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8510
9162
|
return result;
|
|
8511
9163
|
}
|
|
8512
9164
|
cancelRun(lease, input) {
|
|
@@ -8526,7 +9178,6 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8526
9178
|
}
|
|
8527
9179
|
if (["completed", "failed", "cancelled"].includes(run.state)) {
|
|
8528
9180
|
const result2 = clone(run);
|
|
8529
|
-
if (input.expectedRevision !== void 0) this.writeOperationReceipt(operationKey, operationPayload, result2);
|
|
8530
9181
|
return result2;
|
|
8531
9182
|
}
|
|
8532
9183
|
const from = run.state;
|
|
@@ -8541,7 +9192,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8541
9192
|
for (const toolCall of activeToolCalls) this.interruptToolCall(run, toolCall, input.reason ?? "The Run was cancelled.");
|
|
8542
9193
|
if (input.output && (typeof input.output.content === "string" ? input.output.content.length > 0 : input.output.content.length > 0)) {
|
|
8543
9194
|
const output = { ...clone(input.output), sequenceWithinRun: this.nextMessageSequence(run.id) };
|
|
8544
|
-
this.
|
|
9195
|
+
this.storeMessage(output);
|
|
8545
9196
|
this.appendMessage(run, output);
|
|
8546
9197
|
}
|
|
8547
9198
|
if (run.openInteractions && run.openInteractions.length > 0) {
|
|
@@ -8564,9 +9215,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8564
9215
|
delete run.interactionAnswers;
|
|
8565
9216
|
run.revision += 1;
|
|
8566
9217
|
run.updatedAt = createTimestamp();
|
|
9218
|
+
this.touchRun(run);
|
|
8567
9219
|
this.appendTransition(run, from, "failed", { failure });
|
|
9220
|
+
this.dropRunOperationReceipts(run.id);
|
|
8568
9221
|
const result2 = clone(run);
|
|
8569
|
-
if (input.expectedRevision !== void 0) this.writeOperationReceipt(operationKey, operationPayload, result2);
|
|
8570
9222
|
return result2;
|
|
8571
9223
|
}
|
|
8572
9224
|
run.state = "cancelled";
|
|
@@ -8577,9 +9229,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8577
9229
|
delete run.interactionAnswers;
|
|
8578
9230
|
run.revision += 1;
|
|
8579
9231
|
run.updatedAt = createTimestamp();
|
|
9232
|
+
this.touchRun(run);
|
|
8580
9233
|
this.appendTransition(run, from, "cancelled", { reason: input.reason });
|
|
9234
|
+
this.dropRunOperationReceipts(run.id);
|
|
8581
9235
|
const result = clone(run);
|
|
8582
|
-
if (input.expectedRevision !== void 0) this.writeOperationReceipt(operationKey, operationPayload, result);
|
|
8583
9236
|
return result;
|
|
8584
9237
|
}
|
|
8585
9238
|
snapshotRun(lease, runId) {
|
|
@@ -8660,6 +9313,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8660
9313
|
const previous = this.consumerCheckpoints.get(input.consumerId);
|
|
8661
9314
|
if (previous !== void 0 && next <= this.parseCursor(previous)) return;
|
|
8662
9315
|
this.consumerCheckpoints.set(input.consumerId, input.cursor);
|
|
9316
|
+
this.recorder?.onConsumerCheckpointUpsert(input.consumerId, input.cursor);
|
|
8663
9317
|
}
|
|
8664
9318
|
compact(lease, input = {}) {
|
|
8665
9319
|
this.assertOwner(lease);
|
|
@@ -8693,11 +9347,15 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8693
9347
|
}
|
|
8694
9348
|
const deletedEvents = deleteThrough >= this.retentionFloor ? this.events.filter((event) => this.parseCursor(event.cursor) <= deleteThrough) : [];
|
|
8695
9349
|
if (deleteThrough >= this.retentionFloor) {
|
|
9350
|
+
const deletedEventIds = this.events.filter((event) => this.parseCursor(event.cursor) <= deleteThrough).map((event) => event.id);
|
|
8696
9351
|
this.events.splice(0, this.events.length, ...this.events.filter((event) => this.parseCursor(event.cursor) > deleteThrough));
|
|
8697
9352
|
this.retentionFloor = deleteThrough + 1;
|
|
9353
|
+
this.recorder?.onRetentionFloorChange(this.retentionFloor);
|
|
9354
|
+
this.recorder?.onEventsTruncate(deletedEventIds);
|
|
8698
9355
|
for (const [consumerId, cursor] of this.consumerCheckpoints) {
|
|
8699
9356
|
if (this.parseCursor(cursor) < this.retentionFloor - 1) {
|
|
8700
9357
|
this.consumerCheckpoints.delete(consumerId);
|
|
9358
|
+
this.recorder?.onConsumerCheckpointDelete(consumerId);
|
|
8701
9359
|
}
|
|
8702
9360
|
}
|
|
8703
9361
|
}
|
|
@@ -8706,11 +9364,21 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8706
9364
|
const deletedRunIds = deletableRuns.map((run) => run.id);
|
|
8707
9365
|
const deletedRunSet = new Set(deletedRunIds);
|
|
8708
9366
|
const deletedTools = [...this.toolCalls.values()].filter((tool) => deletedRunSet.has(tool.runId));
|
|
8709
|
-
for (const runId of deletedRunIds)
|
|
9367
|
+
for (const runId of deletedRunIds) {
|
|
9368
|
+
this.runs.delete(runId);
|
|
9369
|
+
this.runReceiptKeys.delete(runId);
|
|
9370
|
+
this.recorder?.onRunDelete(runId);
|
|
9371
|
+
}
|
|
8710
9372
|
for (const [messageId, message] of this.messages) {
|
|
8711
|
-
if (deletedRunSet.has(message.runId))
|
|
9373
|
+
if (deletedRunSet.has(message.runId)) {
|
|
9374
|
+
this.messages.delete(messageId);
|
|
9375
|
+
this.recorder?.onMessageDelete(messageId);
|
|
9376
|
+
}
|
|
9377
|
+
}
|
|
9378
|
+
for (const tool of deletedTools) {
|
|
9379
|
+
this.toolCalls.delete(tool.id);
|
|
9380
|
+
this.recorder?.onToolCallDelete(tool.id);
|
|
8712
9381
|
}
|
|
8713
|
-
for (const tool of deletedTools) this.toolCalls.delete(tool.id);
|
|
8714
9382
|
return {
|
|
8715
9383
|
deletedRunIds,
|
|
8716
9384
|
deletedToolCallIds: deletedTools.map((tool) => tool.id),
|
|
@@ -8732,7 +9400,10 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8732
9400
|
return receipt.result;
|
|
8733
9401
|
}
|
|
8734
9402
|
writeReceipt(scope, payload, result) {
|
|
8735
|
-
|
|
9403
|
+
const key = encodeIdempotencyScope(this.incarnation, scope);
|
|
9404
|
+
const receipt = { payload, result: clone(result) };
|
|
9405
|
+
this.idempotency.set(key, receipt);
|
|
9406
|
+
this.recorder?.onIdempotencyUpsert(key, receipt);
|
|
8736
9407
|
}
|
|
8737
9408
|
replayOperation(key, payload) {
|
|
8738
9409
|
const receipt = this.operationReceipts.get(key);
|
|
@@ -8740,8 +9411,19 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8740
9411
|
if (receipt.payload !== payload) throw new Error(`Idempotency payload conflict for ${key}.`);
|
|
8741
9412
|
return receipt.result;
|
|
8742
9413
|
}
|
|
8743
|
-
writeOperationReceipt(key, payload, result) {
|
|
8744
|
-
|
|
9414
|
+
writeOperationReceipt(key, payload, result, runId) {
|
|
9415
|
+
const receipt = { payload, result: clone(result) };
|
|
9416
|
+
this.operationReceipts.set(key, receipt);
|
|
9417
|
+
const resolvedRunId = runId ?? this.inferRunIdForReceipt(key, payload);
|
|
9418
|
+
if (resolvedRunId) {
|
|
9419
|
+
let keys = this.runReceiptKeys.get(resolvedRunId);
|
|
9420
|
+
if (!keys) {
|
|
9421
|
+
keys = /* @__PURE__ */ new Set();
|
|
9422
|
+
this.runReceiptKeys.set(resolvedRunId, keys);
|
|
9423
|
+
}
|
|
9424
|
+
keys.add(key);
|
|
9425
|
+
}
|
|
9426
|
+
this.recorder?.onOperationReceiptUpsert(key, receipt);
|
|
8745
9427
|
}
|
|
8746
9428
|
/**
|
|
8747
9429
|
* A Claim receipt exists for idempotent replay of one live Execution Attempt
|
|
@@ -8749,7 +9431,11 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8749
9431
|
* one history snapshot per Agent instead of one per Attempt.
|
|
8750
9432
|
*/
|
|
8751
9433
|
dropClaimReceipt(execution) {
|
|
8752
|
-
if (execution)
|
|
9434
|
+
if (execution) {
|
|
9435
|
+
const key = `claim:${execution.executionId}`;
|
|
9436
|
+
this.operationReceipts.delete(key);
|
|
9437
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
9438
|
+
}
|
|
8753
9439
|
}
|
|
8754
9440
|
/**
|
|
8755
9441
|
* A new owner fences the Execution Attempts of the previous one, so no Claim
|
|
@@ -8765,6 +9451,7 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8765
9451
|
for (const key of [...this.operationReceipts.keys()]) {
|
|
8766
9452
|
if (key.startsWith("claim:") && !liveExecutions.has(key.slice("claim:".length))) {
|
|
8767
9453
|
this.operationReceipts.delete(key);
|
|
9454
|
+
this.recorder?.onOperationReceiptDelete(key);
|
|
8768
9455
|
}
|
|
8769
9456
|
}
|
|
8770
9457
|
}
|
|
@@ -8803,14 +9490,16 @@ var InMemoryStore = class _InMemoryStore {
|
|
|
8803
9490
|
};
|
|
8804
9491
|
const from = toolCall.state;
|
|
8805
9492
|
const to = from === "running" ? "indeterminate" : "failed";
|
|
8806
|
-
this.
|
|
9493
|
+
this.storeMessage(message);
|
|
8807
9494
|
toolCall.state = to;
|
|
8808
9495
|
toolCall.result = durableResult;
|
|
8809
9496
|
toolCall.resultMessageId = message.id;
|
|
8810
9497
|
if (to === "indeterminate") toolCall.reason = reason;
|
|
8811
9498
|
toolCall.updatedAt = message.createdAt;
|
|
9499
|
+
this.storeToolCall(toolCall);
|
|
8812
9500
|
run.revision += 1;
|
|
8813
9501
|
run.updatedAt = message.createdAt;
|
|
9502
|
+
this.touchRun(run);
|
|
8814
9503
|
this.appendToolTransition(run, { from, to }, toolCall);
|
|
8815
9504
|
this.appendMessage(run, message);
|
|
8816
9505
|
}
|
|
@@ -8911,6 +9600,7 @@ ${record.summary}`,
|
|
|
8911
9600
|
if (existing?.id === record.id) return clone(existing);
|
|
8912
9601
|
const next = clone(record);
|
|
8913
9602
|
this.contextCompactions.set(record.agentId, next);
|
|
9603
|
+
this.recorder?.onContextCompactionUpsert(record.agentId, next);
|
|
8914
9604
|
return clone(next);
|
|
8915
9605
|
}
|
|
8916
9606
|
activeHistory(agentId, beforeSequence) {
|
|
@@ -8920,7 +9610,7 @@ ${record.summary}`,
|
|
|
8920
9610
|
].map((message) => ({ ...message, messageRevision: message.messageRevision ?? 0 })));
|
|
8921
9611
|
}
|
|
8922
9612
|
appendMessage(run, message) {
|
|
8923
|
-
this.
|
|
9613
|
+
this.appendEvent(this.baseEvent(run, {
|
|
8924
9614
|
kind: "message_committed",
|
|
8925
9615
|
message
|
|
8926
9616
|
}));
|
|
@@ -8936,13 +9626,14 @@ ${record.summary}`,
|
|
|
8936
9626
|
...to === "failed" && options?.failure ? { failure: options.failure } : {},
|
|
8937
9627
|
...to === "cancelled" && options?.reason ? { reason: options.reason } : {}
|
|
8938
9628
|
};
|
|
8939
|
-
this.
|
|
9629
|
+
this.touchRun(run);
|
|
9630
|
+
this.appendEvent(transition);
|
|
8940
9631
|
}
|
|
8941
9632
|
appendToolTransition(run, transition, toolCall) {
|
|
8942
|
-
this.
|
|
9633
|
+
this.appendEvent(this.baseEvent(run, {
|
|
8943
9634
|
kind: "tool_state_changed",
|
|
8944
9635
|
transition,
|
|
8945
|
-
toolCall
|
|
9636
|
+
toolCall: clone(toolCall)
|
|
8946
9637
|
}));
|
|
8947
9638
|
}
|
|
8948
9639
|
baseEvent(run, extra) {
|
|
@@ -9318,6 +10009,94 @@ var CURRENT_SCHEMA_SQL = `
|
|
|
9318
10009
|
CREATE INDEX runs_active_idx ON runs (agent_id, state, agent_sequence);
|
|
9319
10010
|
CREATE INDEX run_events_sequence_idx ON run_events (sequence);
|
|
9320
10011
|
`;
|
|
10012
|
+
var ChangeTracker = class {
|
|
10013
|
+
upsertedAgents = /* @__PURE__ */ new Map();
|
|
10014
|
+
deletedAgentIds = /* @__PURE__ */ new Set();
|
|
10015
|
+
upsertedRuns = /* @__PURE__ */ new Map();
|
|
10016
|
+
deletedRunIds = /* @__PURE__ */ new Set();
|
|
10017
|
+
insertedMessages = /* @__PURE__ */ new Map();
|
|
10018
|
+
deletedMessageIds = /* @__PURE__ */ new Set();
|
|
10019
|
+
upsertedToolCalls = /* @__PURE__ */ new Map();
|
|
10020
|
+
deletedToolCallIds = /* @__PURE__ */ new Set();
|
|
10021
|
+
appendedEvents = [];
|
|
10022
|
+
truncatedEventIds = /* @__PURE__ */ new Set();
|
|
10023
|
+
upsertedIdempotency = /* @__PURE__ */ new Map();
|
|
10024
|
+
deletedIdempotencyScopes = /* @__PURE__ */ new Set();
|
|
10025
|
+
upsertedOperationReceipts = /* @__PURE__ */ new Map();
|
|
10026
|
+
deletedOperationReceiptKeys = /* @__PURE__ */ new Set();
|
|
10027
|
+
upsertedConsumerCheckpoints = /* @__PURE__ */ new Map();
|
|
10028
|
+
deletedConsumerCheckpoints = /* @__PURE__ */ new Set();
|
|
10029
|
+
upsertedContextCompactions = /* @__PURE__ */ new Map();
|
|
10030
|
+
retentionFloorChanged;
|
|
10031
|
+
onAgentUpsert(agent) {
|
|
10032
|
+
this.deletedAgentIds.delete(agent.id);
|
|
10033
|
+
this.upsertedAgents.set(agent.id, agent);
|
|
10034
|
+
}
|
|
10035
|
+
onAgentDelete(agentId) {
|
|
10036
|
+
this.upsertedAgents.delete(agentId);
|
|
10037
|
+
this.deletedAgentIds.add(agentId);
|
|
10038
|
+
}
|
|
10039
|
+
onRunUpsert(run) {
|
|
10040
|
+
this.deletedRunIds.delete(run.id);
|
|
10041
|
+
this.upsertedRuns.set(run.id, run);
|
|
10042
|
+
}
|
|
10043
|
+
onRunDelete(runId) {
|
|
10044
|
+
this.upsertedRuns.delete(runId);
|
|
10045
|
+
this.deletedRunIds.add(runId);
|
|
10046
|
+
}
|
|
10047
|
+
onMessageInsert(message) {
|
|
10048
|
+
this.deletedMessageIds.delete(message.id);
|
|
10049
|
+
this.insertedMessages.set(message.id, message);
|
|
10050
|
+
}
|
|
10051
|
+
onMessageDelete(messageId) {
|
|
10052
|
+
this.insertedMessages.delete(messageId);
|
|
10053
|
+
this.deletedMessageIds.add(messageId);
|
|
10054
|
+
}
|
|
10055
|
+
onToolCallUpsert(toolCall) {
|
|
10056
|
+
this.deletedToolCallIds.delete(toolCall.id);
|
|
10057
|
+
this.upsertedToolCalls.set(toolCall.id, toolCall);
|
|
10058
|
+
}
|
|
10059
|
+
onToolCallDelete(toolCallId) {
|
|
10060
|
+
this.upsertedToolCalls.delete(toolCallId);
|
|
10061
|
+
this.deletedToolCallIds.add(toolCallId);
|
|
10062
|
+
}
|
|
10063
|
+
onEventAppend(event) {
|
|
10064
|
+
this.appendedEvents.push(event);
|
|
10065
|
+
}
|
|
10066
|
+
onEventsTruncate(deletedEventIds) {
|
|
10067
|
+
for (const id of deletedEventIds) this.truncatedEventIds.add(id);
|
|
10068
|
+
}
|
|
10069
|
+
onIdempotencyUpsert(scope, receipt) {
|
|
10070
|
+
this.deletedIdempotencyScopes.delete(scope);
|
|
10071
|
+
this.upsertedIdempotency.set(scope, receipt);
|
|
10072
|
+
}
|
|
10073
|
+
onIdempotencyDelete(scope) {
|
|
10074
|
+
this.upsertedIdempotency.delete(scope);
|
|
10075
|
+
this.deletedIdempotencyScopes.add(scope);
|
|
10076
|
+
}
|
|
10077
|
+
onOperationReceiptUpsert(key, receipt) {
|
|
10078
|
+
this.deletedOperationReceiptKeys.delete(key);
|
|
10079
|
+
this.upsertedOperationReceipts.set(key, receipt);
|
|
10080
|
+
}
|
|
10081
|
+
onOperationReceiptDelete(key) {
|
|
10082
|
+
this.upsertedOperationReceipts.delete(key);
|
|
10083
|
+
this.deletedOperationReceiptKeys.add(key);
|
|
10084
|
+
}
|
|
10085
|
+
onConsumerCheckpointUpsert(consumerId, cursor) {
|
|
10086
|
+
this.deletedConsumerCheckpoints.delete(consumerId);
|
|
10087
|
+
this.upsertedConsumerCheckpoints.set(consumerId, cursor);
|
|
10088
|
+
}
|
|
10089
|
+
onConsumerCheckpointDelete(consumerId) {
|
|
10090
|
+
this.upsertedConsumerCheckpoints.delete(consumerId);
|
|
10091
|
+
this.deletedConsumerCheckpoints.add(consumerId);
|
|
10092
|
+
}
|
|
10093
|
+
onContextCompactionUpsert(agentId, record) {
|
|
10094
|
+
this.upsertedContextCompactions.set(agentId, record);
|
|
10095
|
+
}
|
|
10096
|
+
onRetentionFloorChange(floor) {
|
|
10097
|
+
this.retentionFloorChanged = floor;
|
|
10098
|
+
}
|
|
10099
|
+
};
|
|
9321
10100
|
var SqliteStore = class {
|
|
9322
10101
|
database;
|
|
9323
10102
|
archiveRoot;
|
|
@@ -9326,6 +10105,25 @@ var SqliteStore = class {
|
|
|
9326
10105
|
mirroredAgents = /* @__PURE__ */ new Set();
|
|
9327
10106
|
closed = false;
|
|
9328
10107
|
configured = false;
|
|
10108
|
+
cachedMemory;
|
|
10109
|
+
cachedOwner;
|
|
10110
|
+
isLegacyState = false;
|
|
10111
|
+
stmtUpsertAgent;
|
|
10112
|
+
stmtDeleteAgent;
|
|
10113
|
+
stmtUpsertRun;
|
|
10114
|
+
stmtDeleteRun;
|
|
10115
|
+
stmtInsertMessage;
|
|
10116
|
+
stmtDeleteMessage;
|
|
10117
|
+
stmtUpsertToolCall;
|
|
10118
|
+
stmtDeleteToolCall;
|
|
10119
|
+
stmtInsertEvent;
|
|
10120
|
+
stmtDeleteEvent;
|
|
10121
|
+
stmtUpsertIdempotency;
|
|
10122
|
+
stmtDeleteIdempotency;
|
|
10123
|
+
stmtUpsertCheckpoint;
|
|
10124
|
+
stmtDeleteCheckpoint;
|
|
10125
|
+
stmtUpdateMeta;
|
|
10126
|
+
stmtUpdateState;
|
|
9329
10127
|
constructor(filename = ":memory:") {
|
|
9330
10128
|
this.database = new Database(filename, { create: true, readwrite: true, strict: true });
|
|
9331
10129
|
this.archiveRoot = filename === ":memory:" ? join6(tmpdir2(), `rowan-context-archives-${crypto.randomUUID()}`) : join6(dirname7(resolve8(filename)), "context-archives");
|
|
@@ -9346,7 +10144,26 @@ var SqliteStore = class {
|
|
|
9346
10144
|
}
|
|
9347
10145
|
const replay = ownerLease(row);
|
|
9348
10146
|
this.writeOwner({ ...row, expires_at: now + input.leaseMs });
|
|
9349
|
-
|
|
10147
|
+
const newLease2 = { ...replay, expiresAt: new Date(now + input.leaseMs).toISOString() };
|
|
10148
|
+
if (!this.cachedMemory || this.cachedOwner?.epoch !== replay.epoch) {
|
|
10149
|
+
const state2 = this.readState();
|
|
10150
|
+
const memory2 = InMemoryStore.fromState(state2);
|
|
10151
|
+
memory2.attachOwner(newLease2);
|
|
10152
|
+
const tracker2 = new ChangeTracker();
|
|
10153
|
+
memory2.setChangeRecorder(tracker2);
|
|
10154
|
+
try {
|
|
10155
|
+
memory2.dropSettledClaimReceipts();
|
|
10156
|
+
memory2.compactTerminalReceipts();
|
|
10157
|
+
} finally {
|
|
10158
|
+
memory2.setChangeRecorder(void 0);
|
|
10159
|
+
}
|
|
10160
|
+
this.ensureTableBackedStorage(memory2, tracker2, this.isLegacyState);
|
|
10161
|
+
this.cachedMemory = memory2;
|
|
10162
|
+
} else {
|
|
10163
|
+
this.cachedMemory.attachOwner(newLease2);
|
|
10164
|
+
}
|
|
10165
|
+
this.cachedOwner = newLease2;
|
|
10166
|
+
return newLease2;
|
|
9350
10167
|
}
|
|
9351
10168
|
const state = this.readState();
|
|
9352
10169
|
const memory = InMemoryStore.fromState(state);
|
|
@@ -9365,22 +10182,42 @@ var SqliteStore = class {
|
|
|
9365
10182
|
released_epoch: row.released_epoch
|
|
9366
10183
|
};
|
|
9367
10184
|
this.writeOwner(next);
|
|
9368
|
-
|
|
9369
|
-
this.persistState(memory.exportState());
|
|
9370
|
-
return {
|
|
10185
|
+
const newLease = {
|
|
9371
10186
|
ownerId: input.ownerId,
|
|
9372
10187
|
token,
|
|
9373
10188
|
epoch,
|
|
9374
10189
|
expiresAt: new Date(now + input.leaseMs).toISOString()
|
|
9375
10190
|
};
|
|
10191
|
+
memory.attachOwner(newLease);
|
|
10192
|
+
const tracker = new ChangeTracker();
|
|
10193
|
+
memory.setChangeRecorder(tracker);
|
|
10194
|
+
try {
|
|
10195
|
+
memory.dropSettledClaimReceipts();
|
|
10196
|
+
memory.compactTerminalReceipts();
|
|
10197
|
+
} finally {
|
|
10198
|
+
memory.setChangeRecorder(void 0);
|
|
10199
|
+
}
|
|
10200
|
+
this.ensureTableBackedStorage(memory, tracker, this.isLegacyState);
|
|
10201
|
+
this.cachedMemory = memory;
|
|
10202
|
+
this.cachedOwner = newLease;
|
|
10203
|
+
return newLease;
|
|
9376
10204
|
});
|
|
9377
10205
|
return new SqliteOwnedStore(this, lease);
|
|
9378
10206
|
}
|
|
9379
10207
|
close() {
|
|
9380
10208
|
if (this.closed) return;
|
|
9381
10209
|
this.closed = true;
|
|
10210
|
+
this.cachedMemory = void 0;
|
|
10211
|
+
this.cachedOwner = void 0;
|
|
9382
10212
|
this.database.close();
|
|
9383
10213
|
}
|
|
10214
|
+
exportState() {
|
|
10215
|
+
if (this.cachedMemory) {
|
|
10216
|
+
return this.cachedMemory.exportState();
|
|
10217
|
+
}
|
|
10218
|
+
const state = this.readState();
|
|
10219
|
+
return InMemoryStore.fromState(state).exportState();
|
|
10220
|
+
}
|
|
9384
10221
|
/** Filesystem location owned by this Store for one Agent's readable archive. */
|
|
9385
10222
|
contextArchiveDir(agentId) {
|
|
9386
10223
|
return join6(this.archiveRoot, String(agentId));
|
|
@@ -9465,31 +10302,7 @@ var SqliteStore = class {
|
|
|
9465
10302
|
}
|
|
9466
10303
|
async listEvents(lease, input = {}) {
|
|
9467
10304
|
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
|
-
});
|
|
10305
|
+
return this.read(lease, (memory) => memory.listEvents(lease, input));
|
|
9493
10306
|
}
|
|
9494
10307
|
async openConsumer(lease, consumerId) {
|
|
9495
10308
|
return this.invoke(lease, (store, current) => store.openConsumer(current, consumerId), false);
|
|
@@ -9513,7 +10326,12 @@ var SqliteStore = class {
|
|
|
9513
10326
|
const row = this.requireMatchingOwner(lease, false);
|
|
9514
10327
|
const expiresAt = Date.now() + leaseMs;
|
|
9515
10328
|
this.writeOwner({ ...row, expires_at: expiresAt });
|
|
9516
|
-
|
|
10329
|
+
const nextLease = { ...lease, expiresAt: new Date(expiresAt).toISOString() };
|
|
10330
|
+
if (this.cachedOwner && this.cachedOwner.token === lease.token) {
|
|
10331
|
+
this.cachedOwner = nextLease;
|
|
10332
|
+
this.cachedMemory?.attachOwner(nextLease);
|
|
10333
|
+
}
|
|
10334
|
+
return nextLease;
|
|
9517
10335
|
});
|
|
9518
10336
|
}
|
|
9519
10337
|
async sealAndReleaseOwner(lease) {
|
|
@@ -9524,27 +10342,75 @@ var SqliteStore = class {
|
|
|
9524
10342
|
if (row.owner_id !== lease.ownerId || row.owner_token !== lease.token || row.epoch !== lease.epoch) {
|
|
9525
10343
|
throw ownershipLost2(lease, row);
|
|
9526
10344
|
}
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
10345
|
+
if (!this.cachedMemory || this.cachedOwner?.epoch !== lease.epoch) {
|
|
10346
|
+
this.cachedMemory = InMemoryStore.fromState(this.readState());
|
|
10347
|
+
this.cachedOwner = lease;
|
|
10348
|
+
}
|
|
10349
|
+
const tracker = new ChangeTracker();
|
|
10350
|
+
this.cachedMemory.setChangeRecorder(tracker);
|
|
10351
|
+
try {
|
|
10352
|
+
this.cachedMemory.attachOwner(lease);
|
|
10353
|
+
this.cachedMemory.interruptOwner(lease.epoch, "The Runtime owner was sealed.");
|
|
10354
|
+
} finally {
|
|
10355
|
+
this.cachedMemory.setChangeRecorder(void 0);
|
|
10356
|
+
}
|
|
10357
|
+
this.persistChanges(tracker, this.cachedMemory);
|
|
10358
|
+
this.mirrorChanges(tracker);
|
|
9531
10359
|
this.writeOwner({ ...row, owner_id: null, owner_token: null, expires_at: null, released_epoch: lease.epoch });
|
|
10360
|
+
this.cachedMemory = void 0;
|
|
10361
|
+
this.cachedOwner = void 0;
|
|
9532
10362
|
});
|
|
9533
10363
|
}
|
|
9534
|
-
|
|
10364
|
+
read(lease, operation) {
|
|
10365
|
+
this.assertOpen();
|
|
10366
|
+
this.requireMatchingOwner(lease, true);
|
|
10367
|
+
if (!this.cachedMemory || this.cachedOwner?.epoch !== lease.epoch) {
|
|
10368
|
+
this.cachedMemory = InMemoryStore.fromState(this.readState());
|
|
10369
|
+
this.cachedMemory.attachOwner(lease);
|
|
10370
|
+
this.cachedOwner = lease;
|
|
10371
|
+
} else {
|
|
10372
|
+
this.cachedMemory.attachOwner(lease);
|
|
10373
|
+
}
|
|
10374
|
+
return operation(this.cachedMemory);
|
|
10375
|
+
}
|
|
10376
|
+
write(lease, operation) {
|
|
9535
10377
|
this.assertOpen();
|
|
9536
10378
|
return this.immediateTransaction(() => {
|
|
9537
10379
|
this.requireMatchingOwner(lease, true);
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
this.
|
|
10380
|
+
if (!this.cachedMemory || this.cachedOwner?.epoch !== lease.epoch) {
|
|
10381
|
+
this.cachedMemory = InMemoryStore.fromState(this.readState());
|
|
10382
|
+
this.cachedMemory.attachOwner(lease);
|
|
10383
|
+
this.cachedOwner = lease;
|
|
10384
|
+
} else {
|
|
10385
|
+
this.cachedMemory.attachOwner(lease);
|
|
10386
|
+
}
|
|
10387
|
+
const tracker = new ChangeTracker();
|
|
10388
|
+
this.cachedMemory.setChangeRecorder(tracker);
|
|
10389
|
+
let result;
|
|
10390
|
+
try {
|
|
10391
|
+
result = operation(this.cachedMemory);
|
|
10392
|
+
} catch (error) {
|
|
10393
|
+
this.cachedMemory.setChangeRecorder(void 0);
|
|
10394
|
+
this.cachedMemory = void 0;
|
|
10395
|
+
throw error;
|
|
10396
|
+
}
|
|
10397
|
+
this.cachedMemory.setChangeRecorder(void 0);
|
|
10398
|
+
try {
|
|
10399
|
+
this.persistChanges(tracker, this.cachedMemory);
|
|
10400
|
+
this.mirrorChanges(tracker);
|
|
10401
|
+
} catch (error) {
|
|
10402
|
+
this.cachedMemory = void 0;
|
|
10403
|
+
throw error;
|
|
9544
10404
|
}
|
|
9545
10405
|
return result;
|
|
9546
10406
|
});
|
|
9547
10407
|
}
|
|
10408
|
+
invoke(lease, operation, persist = true) {
|
|
10409
|
+
if (persist) {
|
|
10410
|
+
return this.write(lease, (memory) => operation(memory, lease));
|
|
10411
|
+
}
|
|
10412
|
+
return this.read(lease, (memory) => operation(memory, lease));
|
|
10413
|
+
}
|
|
9548
10414
|
ensureSchema() {
|
|
9549
10415
|
const catalog = this.catalog();
|
|
9550
10416
|
if (catalog.length > 0 && !this.isCurrentSchema(catalog)) {
|
|
@@ -9561,7 +10427,7 @@ var SqliteStore = class {
|
|
|
9561
10427
|
this.database.run("INSERT INTO runtime_meta (key, value) VALUES (?, ?)", [RETENTION_FLOOR_KEY, "1"]);
|
|
9562
10428
|
const state = new InMemoryStore();
|
|
9563
10429
|
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.
|
|
10430
|
+
this.database.run("INSERT INTO runtime_state (singleton, state_json) VALUES (?, ?)", [STATE_ROW, JSON.stringify(state.exportMetadata())]);
|
|
9565
10431
|
});
|
|
9566
10432
|
return;
|
|
9567
10433
|
}
|
|
@@ -9600,13 +10466,267 @@ var SqliteStore = class {
|
|
|
9600
10466
|
readState() {
|
|
9601
10467
|
const row = this.database.query("SELECT state_json FROM runtime_state WHERE singleton = ?").get(STATE_ROW);
|
|
9602
10468
|
if (!row) throw new RuntimeError("store_unavailable", { operation: "read_state", retryable: false, reason: "runtime_state row is missing" });
|
|
9603
|
-
|
|
10469
|
+
const parsed = JSON.parse(row.state_json);
|
|
10470
|
+
if (parsed.agents && Array.isArray(parsed.agents)) {
|
|
10471
|
+
this.isLegacyState = true;
|
|
10472
|
+
return parsed;
|
|
10473
|
+
}
|
|
10474
|
+
this.isLegacyState = false;
|
|
10475
|
+
return this.loadTableBackedState(parsed);
|
|
10476
|
+
}
|
|
10477
|
+
loadTableBackedState(metadata) {
|
|
10478
|
+
const agentRows = this.database.query(
|
|
10479
|
+
"SELECT id, metadata_json, config_token, config_identity, created_at, activated_at, updated_at FROM agents ORDER BY created_at"
|
|
10480
|
+
).all();
|
|
10481
|
+
const agents = agentRows.map((row) => ({
|
|
10482
|
+
id: row.id,
|
|
10483
|
+
...row.metadata_json ? { metadata: JSON.parse(row.metadata_json) } : {},
|
|
10484
|
+
...row.config_token ? { currentConfigToken: row.config_token } : {},
|
|
10485
|
+
...row.config_identity ? { currentConfigIdentity: row.config_identity } : {},
|
|
10486
|
+
createdAt: row.created_at,
|
|
10487
|
+
...row.activated_at ? { activatedAt: row.activated_at } : {},
|
|
10488
|
+
updatedAt: row.updated_at
|
|
10489
|
+
}));
|
|
10490
|
+
const runRows = this.database.query("SELECT payload_json FROM runs").all();
|
|
10491
|
+
const runs = runRows.map((r) => JSON.parse(r.payload_json));
|
|
10492
|
+
const messageRows = this.database.query("SELECT payload_json FROM messages ORDER BY run_id, sequence_within_run").all();
|
|
10493
|
+
const messages = messageRows.map((m) => JSON.parse(m.payload_json));
|
|
10494
|
+
const toolRows = this.database.query("SELECT payload_json FROM tool_calls").all();
|
|
10495
|
+
const toolCalls = toolRows.map((t) => JSON.parse(t.payload_json));
|
|
10496
|
+
const eventRows = this.database.query("SELECT payload_json FROM run_events ORDER BY sequence").all();
|
|
10497
|
+
const events = eventRows.map((e) => JSON.parse(e.payload_json));
|
|
10498
|
+
const idempotencyRows = this.database.query("SELECT scope, payload_json, result_json FROM idempotency").all();
|
|
10499
|
+
const idempotency = [];
|
|
10500
|
+
const operationReceipts = [];
|
|
10501
|
+
for (const row of idempotencyRows) {
|
|
10502
|
+
const receipt = { payload: row.payload_json, result: JSON.parse(row.result_json) };
|
|
10503
|
+
if (row.scope.startsWith("operation:")) {
|
|
10504
|
+
operationReceipts.push([row.scope.slice("operation:".length), receipt]);
|
|
10505
|
+
} else {
|
|
10506
|
+
idempotency.push([row.scope, receipt]);
|
|
10507
|
+
}
|
|
10508
|
+
}
|
|
10509
|
+
const cpRows = this.database.query("SELECT consumer_id, sequence FROM consumer_checkpoints").all();
|
|
10510
|
+
const consumerCheckpoints = cpRows.map((r) => [r.consumer_id, `${metadata.incarnation}:${r.sequence}`]);
|
|
10511
|
+
const retentionRow = this.database.query("SELECT value FROM runtime_meta WHERE key = ?").get(RETENTION_FLOOR_KEY);
|
|
10512
|
+
const retentionFloor = Math.max(1, Number(retentionRow?.value ?? metadata.retentionFloor ?? "1"));
|
|
10513
|
+
return {
|
|
10514
|
+
incarnation: metadata.incarnation,
|
|
10515
|
+
agents,
|
|
10516
|
+
runs,
|
|
10517
|
+
messages,
|
|
10518
|
+
toolCalls,
|
|
10519
|
+
events,
|
|
10520
|
+
idempotency,
|
|
10521
|
+
operationReceipts,
|
|
10522
|
+
historySeeds: metadata.historySeeds ?? [],
|
|
10523
|
+
consumerCheckpoints,
|
|
10524
|
+
retentionFloor,
|
|
10525
|
+
nextAgentSequence: metadata.nextAgentSequence ?? [],
|
|
10526
|
+
nextReadySequence: metadata.nextReadySequence ?? [],
|
|
10527
|
+
eventSequence: metadata.eventSequence ?? 0,
|
|
10528
|
+
contextCompactions: metadata.contextCompactions ?? []
|
|
10529
|
+
};
|
|
10530
|
+
}
|
|
10531
|
+
ensureTableBackedStorage(memory, tracker, isLegacy) {
|
|
10532
|
+
if (isLegacy) {
|
|
10533
|
+
this.writeFullStateToTables(memory);
|
|
10534
|
+
this.isLegacyState = false;
|
|
10535
|
+
} else {
|
|
10536
|
+
this.persistChanges(tracker, memory);
|
|
10537
|
+
this.mirrorChanges(tracker);
|
|
10538
|
+
}
|
|
10539
|
+
}
|
|
10540
|
+
getStmtUpsertAgent() {
|
|
10541
|
+
return this.stmtUpsertAgent ??= this.database.prepare(
|
|
10542
|
+
`INSERT INTO agents (id, metadata_json, config_token, config_identity, created_at, activated_at, updated_at)
|
|
10543
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
10544
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
10545
|
+
metadata_json = excluded.metadata_json,
|
|
10546
|
+
config_token = excluded.config_token,
|
|
10547
|
+
config_identity = excluded.config_identity,
|
|
10548
|
+
activated_at = excluded.activated_at,
|
|
10549
|
+
updated_at = excluded.updated_at`
|
|
10550
|
+
);
|
|
10551
|
+
}
|
|
10552
|
+
getStmtDeleteAgent() {
|
|
10553
|
+
return this.stmtDeleteAgent ??= this.database.prepare("DELETE FROM agents WHERE id = ?");
|
|
10554
|
+
}
|
|
10555
|
+
getStmtUpsertRun() {
|
|
10556
|
+
return this.stmtUpsertRun ??= this.database.prepare(
|
|
10557
|
+
`INSERT INTO runs (id, agent_id, agent_sequence, state, revision, payload_json, created_at, updated_at)
|
|
10558
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
10559
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
10560
|
+
state = excluded.state,
|
|
10561
|
+
revision = excluded.revision,
|
|
10562
|
+
payload_json = excluded.payload_json,
|
|
10563
|
+
updated_at = excluded.updated_at`
|
|
10564
|
+
);
|
|
10565
|
+
}
|
|
10566
|
+
getStmtDeleteRun() {
|
|
10567
|
+
return this.stmtDeleteRun ??= this.database.prepare("DELETE FROM runs WHERE id = ?");
|
|
10568
|
+
}
|
|
10569
|
+
getStmtInsertMessage() {
|
|
10570
|
+
return this.stmtInsertMessage ??= this.database.prepare(
|
|
10571
|
+
`INSERT INTO messages (id, run_id, sequence_within_run, payload_json, created_at)
|
|
10572
|
+
VALUES (?, ?, ?, ?, ?)
|
|
10573
|
+
ON CONFLICT(id) DO UPDATE SET payload_json = excluded.payload_json`
|
|
10574
|
+
);
|
|
10575
|
+
}
|
|
10576
|
+
getStmtDeleteMessage() {
|
|
10577
|
+
return this.stmtDeleteMessage ??= this.database.prepare("DELETE FROM messages WHERE id = ?");
|
|
9604
10578
|
}
|
|
9605
|
-
|
|
9606
|
-
this.
|
|
10579
|
+
getStmtUpsertToolCall() {
|
|
10580
|
+
return this.stmtUpsertToolCall ??= this.database.prepare(
|
|
10581
|
+
`INSERT INTO tool_calls (id, run_id, execution_id, state, payload_json)
|
|
10582
|
+
VALUES (?, ?, ?, ?, ?)
|
|
10583
|
+
ON CONFLICT(id) DO UPDATE SET state = excluded.state, payload_json = excluded.payload_json`
|
|
10584
|
+
);
|
|
9607
10585
|
}
|
|
9608
|
-
|
|
9609
|
-
this.
|
|
10586
|
+
getStmtDeleteToolCall() {
|
|
10587
|
+
return this.stmtDeleteToolCall ??= this.database.prepare("DELETE FROM tool_calls WHERE id = ?");
|
|
10588
|
+
}
|
|
10589
|
+
getStmtInsertEvent() {
|
|
10590
|
+
return this.stmtInsertEvent ??= this.database.prepare(
|
|
10591
|
+
"INSERT INTO run_events (id, run_id, payload_json, created_at) VALUES (?, ?, ?, ?)"
|
|
10592
|
+
);
|
|
10593
|
+
}
|
|
10594
|
+
getStmtDeleteEvent() {
|
|
10595
|
+
return this.stmtDeleteEvent ??= this.database.prepare("DELETE FROM run_events WHERE id = ?");
|
|
10596
|
+
}
|
|
10597
|
+
getStmtUpsertIdempotency() {
|
|
10598
|
+
return this.stmtUpsertIdempotency ??= this.database.prepare(
|
|
10599
|
+
`INSERT INTO idempotency (scope, payload_json, result_json)
|
|
10600
|
+
VALUES (?, ?, ?)
|
|
10601
|
+
ON CONFLICT(scope) DO UPDATE SET payload_json = excluded.payload_json, result_json = excluded.result_json`
|
|
10602
|
+
);
|
|
10603
|
+
}
|
|
10604
|
+
getStmtDeleteIdempotency() {
|
|
10605
|
+
return this.stmtDeleteIdempotency ??= this.database.prepare("DELETE FROM idempotency WHERE scope = ?");
|
|
10606
|
+
}
|
|
10607
|
+
getStmtUpsertCheckpoint() {
|
|
10608
|
+
return this.stmtUpsertCheckpoint ??= this.database.prepare(
|
|
10609
|
+
`INSERT INTO consumer_checkpoints (consumer_id, sequence, event_id, updated_at)
|
|
10610
|
+
VALUES (?, ?, ?, ?)
|
|
10611
|
+
ON CONFLICT(consumer_id) DO UPDATE SET sequence = excluded.sequence, updated_at = excluded.updated_at`
|
|
10612
|
+
);
|
|
10613
|
+
}
|
|
10614
|
+
getStmtDeleteCheckpoint() {
|
|
10615
|
+
return this.stmtDeleteCheckpoint ??= this.database.prepare("DELETE FROM consumer_checkpoints WHERE consumer_id = ?");
|
|
10616
|
+
}
|
|
10617
|
+
getStmtUpdateMeta() {
|
|
10618
|
+
return this.stmtUpdateMeta ??= this.database.prepare(
|
|
10619
|
+
"INSERT INTO runtime_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
|
|
10620
|
+
);
|
|
10621
|
+
}
|
|
10622
|
+
getStmtUpdateState() {
|
|
10623
|
+
return this.stmtUpdateState ??= this.database.prepare(
|
|
10624
|
+
"UPDATE runtime_state SET state_json = ? WHERE singleton = ?"
|
|
10625
|
+
);
|
|
10626
|
+
}
|
|
10627
|
+
persistChanges(tracker, memory) {
|
|
10628
|
+
for (const agent of tracker.upsertedAgents.values()) {
|
|
10629
|
+
this.getStmtUpsertAgent().run(
|
|
10630
|
+
agent.id,
|
|
10631
|
+
agent.metadata === void 0 ? null : JSON.stringify(agent.metadata),
|
|
10632
|
+
agent.currentConfigToken ?? null,
|
|
10633
|
+
agent.currentConfigIdentity ?? null,
|
|
10634
|
+
agent.createdAt,
|
|
10635
|
+
agent.activatedAt ?? null,
|
|
10636
|
+
agent.updatedAt
|
|
10637
|
+
);
|
|
10638
|
+
}
|
|
10639
|
+
for (const agentId of tracker.deletedAgentIds) {
|
|
10640
|
+
this.getStmtDeleteAgent().run(agentId);
|
|
10641
|
+
}
|
|
10642
|
+
for (const run of tracker.upsertedRuns.values()) {
|
|
10643
|
+
this.getStmtUpsertRun().run(
|
|
10644
|
+
run.id,
|
|
10645
|
+
run.agentId,
|
|
10646
|
+
run.agentSequence,
|
|
10647
|
+
run.state,
|
|
10648
|
+
run.revision,
|
|
10649
|
+
JSON.stringify(run),
|
|
10650
|
+
run.createdAt,
|
|
10651
|
+
run.updatedAt
|
|
10652
|
+
);
|
|
10653
|
+
}
|
|
10654
|
+
for (const runId of tracker.deletedRunIds) {
|
|
10655
|
+
this.getStmtDeleteRun().run(runId);
|
|
10656
|
+
}
|
|
10657
|
+
for (const message of tracker.insertedMessages.values()) {
|
|
10658
|
+
this.getStmtInsertMessage().run(
|
|
10659
|
+
message.id,
|
|
10660
|
+
message.runId,
|
|
10661
|
+
message.sequenceWithinRun,
|
|
10662
|
+
JSON.stringify(message),
|
|
10663
|
+
message.createdAt
|
|
10664
|
+
);
|
|
10665
|
+
}
|
|
10666
|
+
for (const messageId of tracker.deletedMessageIds) {
|
|
10667
|
+
this.getStmtDeleteMessage().run(messageId);
|
|
10668
|
+
}
|
|
10669
|
+
for (const toolCall of tracker.upsertedToolCalls.values()) {
|
|
10670
|
+
this.getStmtUpsertToolCall().run(
|
|
10671
|
+
toolCall.id,
|
|
10672
|
+
toolCall.runId,
|
|
10673
|
+
toolCall.executionId,
|
|
10674
|
+
toolCall.state,
|
|
10675
|
+
JSON.stringify(toolCall)
|
|
10676
|
+
);
|
|
10677
|
+
}
|
|
10678
|
+
for (const toolCallId of tracker.deletedToolCallIds) {
|
|
10679
|
+
this.getStmtDeleteToolCall().run(toolCallId);
|
|
10680
|
+
}
|
|
10681
|
+
for (const event of tracker.appendedEvents) {
|
|
10682
|
+
this.getStmtInsertEvent().run(
|
|
10683
|
+
event.id,
|
|
10684
|
+
event.runId,
|
|
10685
|
+
JSON.stringify(event),
|
|
10686
|
+
event.createdAt
|
|
10687
|
+
);
|
|
10688
|
+
}
|
|
10689
|
+
for (const eventId of tracker.truncatedEventIds) {
|
|
10690
|
+
this.getStmtDeleteEvent().run(eventId);
|
|
10691
|
+
}
|
|
10692
|
+
for (const [scope, receipt] of tracker.upsertedIdempotency) {
|
|
10693
|
+
this.getStmtUpsertIdempotency().run(
|
|
10694
|
+
scope,
|
|
10695
|
+
receipt.payload,
|
|
10696
|
+
JSON.stringify(receipt.result)
|
|
10697
|
+
);
|
|
10698
|
+
}
|
|
10699
|
+
for (const scope of tracker.deletedIdempotencyScopes) {
|
|
10700
|
+
this.getStmtDeleteIdempotency().run(scope);
|
|
10701
|
+
}
|
|
10702
|
+
for (const [key, receipt] of tracker.upsertedOperationReceipts) {
|
|
10703
|
+
this.getStmtUpsertIdempotency().run(
|
|
10704
|
+
`operation:${key}`,
|
|
10705
|
+
receipt.payload,
|
|
10706
|
+
JSON.stringify(receipt.result)
|
|
10707
|
+
);
|
|
10708
|
+
}
|
|
10709
|
+
for (const key of tracker.deletedOperationReceiptKeys) {
|
|
10710
|
+
this.getStmtDeleteIdempotency().run(`operation:${key}`);
|
|
10711
|
+
}
|
|
10712
|
+
for (const [consumerId, cursor] of tracker.upsertedConsumerCheckpoints) {
|
|
10713
|
+
this.getStmtUpsertCheckpoint().run(
|
|
10714
|
+
consumerId,
|
|
10715
|
+
Number(String(cursor).split(":").at(-1)),
|
|
10716
|
+
null,
|
|
10717
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
10718
|
+
);
|
|
10719
|
+
}
|
|
10720
|
+
for (const consumerId of tracker.deletedConsumerCheckpoints) {
|
|
10721
|
+
this.getStmtDeleteCheckpoint().run(consumerId);
|
|
10722
|
+
}
|
|
10723
|
+
if (tracker.retentionFloorChanged !== void 0) {
|
|
10724
|
+
this.getStmtUpdateMeta().run(RETENTION_FLOOR_KEY, String(tracker.retentionFloorChanged));
|
|
10725
|
+
}
|
|
10726
|
+
this.getStmtUpdateState().run(JSON.stringify(memory.exportMetadata()), STATE_ROW);
|
|
10727
|
+
}
|
|
10728
|
+
writeFullStateToTables(memory) {
|
|
10729
|
+
const state = memory.exportState();
|
|
9610
10730
|
this.database.run(
|
|
9611
10731
|
"INSERT INTO runtime_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value",
|
|
9612
10732
|
[RETENTION_FLOOR_KEY, String(Math.max(1, state.retentionFloor ?? 1))]
|
|
@@ -9615,57 +10735,149 @@ var SqliteStore = class {
|
|
|
9615
10735
|
this.database.run(`DELETE FROM ${table}`);
|
|
9616
10736
|
}
|
|
9617
10737
|
for (const agent of state.agents) {
|
|
9618
|
-
this.
|
|
9619
|
-
|
|
9620
|
-
|
|
10738
|
+
this.getStmtUpsertAgent().run(
|
|
10739
|
+
agent.id,
|
|
10740
|
+
agent.metadata === void 0 ? null : JSON.stringify(agent.metadata),
|
|
10741
|
+
agent.currentConfigToken ?? null,
|
|
10742
|
+
agent.currentConfigIdentity ?? null,
|
|
10743
|
+
agent.createdAt,
|
|
10744
|
+
agent.activatedAt ?? null,
|
|
10745
|
+
agent.updatedAt
|
|
9621
10746
|
);
|
|
9622
10747
|
}
|
|
9623
10748
|
for (const run of state.runs) {
|
|
9624
|
-
this.
|
|
9625
|
-
|
|
9626
|
-
|
|
10749
|
+
this.getStmtUpsertRun().run(
|
|
10750
|
+
run.id,
|
|
10751
|
+
run.agentId,
|
|
10752
|
+
run.agentSequence,
|
|
10753
|
+
run.state,
|
|
10754
|
+
run.revision,
|
|
10755
|
+
JSON.stringify(run),
|
|
10756
|
+
run.createdAt,
|
|
10757
|
+
run.updatedAt
|
|
9627
10758
|
);
|
|
9628
10759
|
}
|
|
9629
10760
|
for (const message of state.messages) {
|
|
9630
|
-
this.
|
|
9631
|
-
|
|
9632
|
-
|
|
10761
|
+
this.getStmtInsertMessage().run(
|
|
10762
|
+
message.id,
|
|
10763
|
+
message.runId,
|
|
10764
|
+
message.sequenceWithinRun,
|
|
10765
|
+
JSON.stringify(message),
|
|
10766
|
+
message.createdAt
|
|
9633
10767
|
);
|
|
9634
10768
|
}
|
|
9635
10769
|
for (const toolCall of state.toolCalls) {
|
|
9636
|
-
this.
|
|
9637
|
-
|
|
9638
|
-
|
|
10770
|
+
this.getStmtUpsertToolCall().run(
|
|
10771
|
+
toolCall.id,
|
|
10772
|
+
toolCall.runId,
|
|
10773
|
+
toolCall.executionId,
|
|
10774
|
+
toolCall.state,
|
|
10775
|
+
JSON.stringify(toolCall)
|
|
9639
10776
|
);
|
|
9640
10777
|
}
|
|
9641
10778
|
for (const event of state.events) {
|
|
9642
|
-
this.
|
|
9643
|
-
|
|
9644
|
-
|
|
10779
|
+
this.getStmtInsertEvent().run(
|
|
10780
|
+
event.id,
|
|
10781
|
+
event.runId,
|
|
10782
|
+
JSON.stringify(event),
|
|
10783
|
+
event.createdAt
|
|
9645
10784
|
);
|
|
9646
10785
|
}
|
|
9647
10786
|
for (const [scope, receipt] of state.idempotency) {
|
|
9648
|
-
this.
|
|
9649
|
-
|
|
9650
|
-
|
|
10787
|
+
this.getStmtUpsertIdempotency().run(
|
|
10788
|
+
scope,
|
|
10789
|
+
receipt.payload,
|
|
10790
|
+
JSON.stringify(receipt.result)
|
|
9651
10791
|
);
|
|
9652
10792
|
}
|
|
9653
10793
|
for (const [scope, receipt] of state.operationReceipts) {
|
|
9654
|
-
this.
|
|
9655
|
-
|
|
9656
|
-
|
|
10794
|
+
this.getStmtUpsertIdempotency().run(
|
|
10795
|
+
`operation:${scope}`,
|
|
10796
|
+
receipt.payload,
|
|
10797
|
+
JSON.stringify(receipt.result)
|
|
9657
10798
|
);
|
|
9658
10799
|
}
|
|
9659
10800
|
for (const [consumerId, cursor] of state.consumerCheckpoints ?? []) {
|
|
9660
|
-
this.
|
|
9661
|
-
|
|
9662
|
-
|
|
10801
|
+
this.getStmtUpsertCheckpoint().run(
|
|
10802
|
+
consumerId,
|
|
10803
|
+
Number(String(cursor).split(":").at(-1)),
|
|
10804
|
+
null,
|
|
10805
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
9663
10806
|
);
|
|
9664
10807
|
}
|
|
9665
|
-
this.
|
|
10808
|
+
this.getStmtUpdateState().run(JSON.stringify(memory.exportMetadata()), STATE_ROW);
|
|
10809
|
+
this.mirrorInitialState(state);
|
|
10810
|
+
}
|
|
10811
|
+
mirrorChanges(tracker) {
|
|
10812
|
+
for (const agentId of tracker.deletedAgentIds) {
|
|
10813
|
+
const idStr = String(agentId);
|
|
10814
|
+
rmSync(join6(this.archiveRoot, idStr), { recursive: true, force: true });
|
|
10815
|
+
this.mirroredEventIds.delete(idStr);
|
|
10816
|
+
this.mirroredCompactionIds.delete(idStr);
|
|
10817
|
+
this.mirroredAgents.delete(idStr);
|
|
10818
|
+
}
|
|
10819
|
+
for (const agent of tracker.upsertedAgents.values()) {
|
|
10820
|
+
const idStr = String(agent.id);
|
|
10821
|
+
this.mirroredAgents.add(idStr);
|
|
10822
|
+
const archiveDir = join6(this.archiveRoot, idStr);
|
|
10823
|
+
const toolDir = join6(archiveDir, "tool-results");
|
|
10824
|
+
mkdirSync(toolDir, { recursive: true, mode: 448 });
|
|
10825
|
+
chmodSync(archiveDir, 448);
|
|
10826
|
+
chmodSync(toolDir, 448);
|
|
10827
|
+
}
|
|
10828
|
+
if (tracker.appendedEvents.length > 0) {
|
|
10829
|
+
mkdirSync(this.archiveRoot, { recursive: true, mode: 448 });
|
|
10830
|
+
chmodSync(this.archiveRoot, 448);
|
|
10831
|
+
const eventsByAgent = /* @__PURE__ */ new Map();
|
|
10832
|
+
for (const event of tracker.appendedEvents) {
|
|
10833
|
+
const agentId = String(event.agentId);
|
|
10834
|
+
let list = eventsByAgent.get(agentId);
|
|
10835
|
+
if (!list) {
|
|
10836
|
+
list = [];
|
|
10837
|
+
eventsByAgent.set(agentId, list);
|
|
10838
|
+
}
|
|
10839
|
+
list.push(event);
|
|
10840
|
+
}
|
|
10841
|
+
for (const [agentId, events] of eventsByAgent) {
|
|
10842
|
+
const archiveDir = join6(this.archiveRoot, agentId);
|
|
10843
|
+
const toolDir = join6(archiveDir, "tool-results");
|
|
10844
|
+
mkdirSync(toolDir, { recursive: true, mode: 448 });
|
|
10845
|
+
chmodSync(archiveDir, 448);
|
|
10846
|
+
chmodSync(toolDir, 448);
|
|
10847
|
+
const sessionPath = join6(archiveDir, "session.jsonl");
|
|
10848
|
+
try {
|
|
10849
|
+
chmodSync(sessionPath, 384);
|
|
10850
|
+
} catch {
|
|
10851
|
+
}
|
|
10852
|
+
const known = this.mirroredEventIds.get(agentId) ?? /* @__PURE__ */ new Set();
|
|
10853
|
+
const newEvents = events.filter((e) => !known.has(String(e.id)));
|
|
10854
|
+
if (newEvents.length > 0) {
|
|
10855
|
+
const lines = newEvents.map((e) => JSON.stringify({ schemaVersion: 1, kind: "rowan_event", event: e }) + "\n").join("");
|
|
10856
|
+
appendFileSync(sessionPath, lines, { encoding: "utf8", mode: 384 });
|
|
10857
|
+
chmodSync(sessionPath, 384);
|
|
10858
|
+
for (const e of newEvents) known.add(String(e.id));
|
|
10859
|
+
this.mirroredEventIds.set(agentId, known);
|
|
10860
|
+
}
|
|
10861
|
+
}
|
|
10862
|
+
}
|
|
10863
|
+
if (tracker.upsertedContextCompactions.size > 0) {
|
|
10864
|
+
for (const [agentId, record] of tracker.upsertedContextCompactions) {
|
|
10865
|
+
const idStr = String(agentId);
|
|
10866
|
+
const archiveDir = join6(this.archiveRoot, idStr);
|
|
10867
|
+
const sessionPath = join6(archiveDir, "session.jsonl");
|
|
10868
|
+
const knownCompactions = this.mirroredCompactionIds.get(idStr) ?? /* @__PURE__ */ new Set();
|
|
10869
|
+
if (!knownCompactions.has(record.id)) {
|
|
10870
|
+
const line = JSON.stringify({ schemaVersion: 1, kind: "context_compacted", record }) + "\n";
|
|
10871
|
+
appendFileSync(sessionPath, line, { encoding: "utf8", mode: 384 });
|
|
10872
|
+
chmodSync(sessionPath, 384);
|
|
10873
|
+
knownCompactions.add(record.id);
|
|
10874
|
+
this.mirroredCompactionIds.set(idStr, knownCompactions);
|
|
10875
|
+
}
|
|
10876
|
+
}
|
|
10877
|
+
}
|
|
9666
10878
|
}
|
|
9667
10879
|
/** Append the semantic durable event mirror and remove deleted Agent sidecars. */
|
|
9668
|
-
|
|
10880
|
+
mirrorInitialState(state) {
|
|
9669
10881
|
mkdirSync(this.archiveRoot, { recursive: true, mode: 448 });
|
|
9670
10882
|
chmodSync(this.archiveRoot, 448);
|
|
9671
10883
|
const currentAgents = new Set(state.agents.map((agent) => String(agent.id)));
|
|
@@ -9885,19 +11097,6 @@ function ownerLease(row) {
|
|
|
9885
11097
|
expiresAt: new Date(row.expires_at).toISOString()
|
|
9886
11098
|
};
|
|
9887
11099
|
}
|
|
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
11100
|
function ownershipLost2(lease, row) {
|
|
9902
11101
|
return new RuntimeError("runtime_ownership_lost", {
|
|
9903
11102
|
reason: row.epoch > lease.epoch ? "epoch_advanced" : row.owner_id ? "released" : "released",
|
|
@@ -9924,6 +11123,7 @@ export {
|
|
|
9924
11123
|
DEFAULT_PHASE_ID,
|
|
9925
11124
|
ExtensionLifetimeError,
|
|
9926
11125
|
InMemoryConfigProvider,
|
|
11126
|
+
InMemoryExtensionHost,
|
|
9927
11127
|
InMemoryStore,
|
|
9928
11128
|
ResourceRegistry,
|
|
9929
11129
|
ResourceRegistryError,
|