@axiom-lattice/core 6.2.0 → 6.3.1
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.mts +781 -24
- package/dist/index.d.ts +781 -24
- package/dist/index.js +1154 -122
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1119 -115
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1660,10 +1660,12 @@ __export(index_exports, {
|
|
|
1660
1660
|
InMemoryChunkBuffer: () => InMemoryChunkBuffer,
|
|
1661
1661
|
InMemoryCollectionStore: () => InMemoryCollectionStore,
|
|
1662
1662
|
InMemoryDatabaseConfigStore: () => InMemoryDatabaseConfigStore,
|
|
1663
|
+
InMemoryLeaseStore: () => InMemoryLeaseStore,
|
|
1663
1664
|
InMemoryMailboxStore: () => InMemoryMailboxStore,
|
|
1664
1665
|
InMemoryMenuStore: () => InMemoryMenuStore,
|
|
1665
1666
|
InMemoryModelProviderStore: () => InMemoryModelProviderStore,
|
|
1666
1667
|
InMemoryOpenAuditStore: () => InMemoryOpenAuditStore,
|
|
1668
|
+
InMemoryOutboxStore: () => InMemoryOutboxStore,
|
|
1667
1669
|
InMemoryProjectBotMembershipStore: () => InMemoryProjectBotMembershipStore,
|
|
1668
1670
|
InMemoryProjectMembershipStore: () => InMemoryProjectMembershipStore,
|
|
1669
1671
|
InMemoryProjectRoomCoordinator: () => InMemoryProjectRoomCoordinator,
|
|
@@ -1683,6 +1685,7 @@ __export(index_exports, {
|
|
|
1683
1685
|
LatticeEval: () => LatticeEval,
|
|
1684
1686
|
LatticeEvalProject: () => LatticeEvalProject,
|
|
1685
1687
|
LatticeEvalSuite: () => LatticeEvalSuite,
|
|
1688
|
+
LeaseAcquisitionTimeoutError: () => LeaseAcquisitionTimeoutError,
|
|
1686
1689
|
LocalSandboxInstance: () => LocalSandboxInstance,
|
|
1687
1690
|
LocalSandboxProvider: () => LocalSandboxProvider,
|
|
1688
1691
|
LoggerLatticeManager: () => LoggerLatticeManager,
|
|
@@ -1705,7 +1708,10 @@ __export(index_exports, {
|
|
|
1705
1708
|
MicrosandboxServiceClient: () => MicrosandboxServiceClient,
|
|
1706
1709
|
ModelLatticeManager: () => ModelLatticeManager,
|
|
1707
1710
|
MysqlDatabase: () => MysqlDatabase,
|
|
1711
|
+
OutboxPoller: () => OutboxPoller,
|
|
1708
1712
|
PACK_DIRECTORY_TIMEOUT_SECONDS: () => PACK_DIRECTORY_TIMEOUT_SECONDS,
|
|
1713
|
+
PLATFORM_SECRET_ENV_VARS: () => PLATFORM_SECRET_ENV_VARS,
|
|
1714
|
+
PLUGIN_CATALOG_CHANGED_TOPIC: () => PLUGIN_CATALOG_CHANGED_TOPIC,
|
|
1709
1715
|
PersonalAssistantConfig: () => PersonalAssistantConfig,
|
|
1710
1716
|
PinoLoggerClient: () => PinoLoggerClient,
|
|
1711
1717
|
PluginRegistry: () => PluginRegistry,
|
|
@@ -1726,6 +1732,8 @@ __export(index_exports, {
|
|
|
1726
1732
|
RepeatedToolCallError: () => RepeatedToolCallError,
|
|
1727
1733
|
RoomAgentMessageService: () => RoomAgentMessageService,
|
|
1728
1734
|
SAFE_PATH_COMPONENT: () => SAFE_PATH_COMPONENT,
|
|
1735
|
+
SANDBOX_OPEN_GATEWAY_URL_ENV: () => SANDBOX_OPEN_GATEWAY_URL_ENV,
|
|
1736
|
+
SANDBOX_OPEN_TOKEN_ENV: () => SANDBOX_OPEN_TOKEN_ENV,
|
|
1729
1737
|
STTModelLattice: () => STTModelLattice,
|
|
1730
1738
|
STTModelLatticeManager: () => STTModelLatticeManager,
|
|
1731
1739
|
SandboxFilesystem: () => SandboxFilesystem,
|
|
@@ -1766,11 +1774,13 @@ __export(index_exports, {
|
|
|
1766
1774
|
appendReconciliationWarning: () => appendReconciliationWarning,
|
|
1767
1775
|
appendUiFence: () => appendUiFence,
|
|
1768
1776
|
assertSafeUpstreamUrl: () => assertSafeUpstreamUrl,
|
|
1777
|
+
buildBundleFromDist: () => buildBundleFromDist,
|
|
1769
1778
|
buildGrepResultsDict: () => buildGrepResultsDict,
|
|
1770
1779
|
buildInput: () => buildInput,
|
|
1771
1780
|
buildNamedVolumeName: () => buildNamedVolumeName,
|
|
1772
1781
|
buildRemotePackDirectoryCommand: () => buildRemotePackDirectoryCommand,
|
|
1773
1782
|
buildSandboxMetadataEnv: () => buildSandboxMetadataEnv,
|
|
1783
|
+
buildSandboxOpenEnv: () => buildSandboxOpenEnv,
|
|
1774
1784
|
buildSkillFile: () => buildSkillFile,
|
|
1775
1785
|
buildStateAnnotation: () => buildStateAnnotation,
|
|
1776
1786
|
buildTableName: () => buildTableName,
|
|
@@ -1779,11 +1789,14 @@ __export(index_exports, {
|
|
|
1779
1789
|
checkEmptyContent: () => checkEmptyContent,
|
|
1780
1790
|
clearEncryptionKeyCache: () => clearEncryptionKeyCache,
|
|
1781
1791
|
clearEvalRunService: () => clearEvalRunService,
|
|
1792
|
+
clearSandboxOpenCredentialProviderForTests: () => clearSandboxOpenCredentialProviderForTests,
|
|
1782
1793
|
collectionLatticeManager: () => collectionLatticeManager,
|
|
1783
1794
|
compileInternal: () => compileInternal,
|
|
1784
1795
|
compileSandboxPlugin: () => compileSandboxPlugin,
|
|
1785
1796
|
compileWorkflow: () => compileWorkflow,
|
|
1786
1797
|
computeSandboxName: () => computeSandboxName,
|
|
1798
|
+
configureCoordinationLeaseStore: () => configureCoordinationLeaseStore,
|
|
1799
|
+
configurePluginCatalogSync: () => configurePluginCatalogSync,
|
|
1787
1800
|
configureStores: () => configureStores,
|
|
1788
1801
|
connectAllChannels: () => connectAllChannels,
|
|
1789
1802
|
convertToConnection: () => convertToConnection,
|
|
@@ -1815,6 +1828,7 @@ __export(index_exports, {
|
|
|
1815
1828
|
createSandboxResolver: () => createSandboxResolver,
|
|
1816
1829
|
createSchedulerMiddleware: () => createSchedulerMiddleware,
|
|
1817
1830
|
createSharePayload: () => createSharePayload,
|
|
1831
|
+
createShellExecTool: () => createShellExecTool,
|
|
1818
1832
|
createTaskExecutionService: () => createTaskExecutionService,
|
|
1819
1833
|
createTaskLifecycleService: () => createTaskLifecycleService,
|
|
1820
1834
|
createTaskMiddleware: () => createTaskMiddleware,
|
|
@@ -1861,6 +1875,7 @@ __export(index_exports, {
|
|
|
1861
1875
|
getCheckpointSaver: () => getCheckpointSaver,
|
|
1862
1876
|
getChunkBuffer: () => getChunkBuffer,
|
|
1863
1877
|
getCollectionEntryCount: () => getCollectionEntryCount,
|
|
1878
|
+
getCoordinationLeaseStore: () => getCoordinationLeaseStore,
|
|
1864
1879
|
getEmbeddingsClient: () => getEmbeddingsClient,
|
|
1865
1880
|
getEmbeddingsLattice: () => getEmbeddingsLattice,
|
|
1866
1881
|
getEncryptionKey: () => getEncryptionKey,
|
|
@@ -1872,15 +1887,18 @@ __export(index_exports, {
|
|
|
1872
1887
|
getOrCreateCollectionVectorStore: () => getOrCreateCollectionVectorStore,
|
|
1873
1888
|
getPluginSkillManifestVersion: () => getPluginSkillManifestVersion,
|
|
1874
1889
|
getQueueLattice: () => getQueueLattice,
|
|
1890
|
+
getReplicaId: () => getReplicaId,
|
|
1875
1891
|
getRuntimeCapabilityConfig: () => getRuntimeCapabilityConfig,
|
|
1876
1892
|
getRuntimeSkillSelection: () => getRuntimeSkillSelection,
|
|
1877
1893
|
getSTTClient: () => getSTTClient,
|
|
1878
1894
|
getSTTClientWithTenant: () => getSTTClientWithTenant,
|
|
1879
1895
|
getSTTModelLattice: () => getSTTModelLattice,
|
|
1880
1896
|
getSandBoxManager: () => getSandBoxManager,
|
|
1897
|
+
getSandboxOpenCredential: () => getSandboxOpenCredential,
|
|
1881
1898
|
getSandboxPluginCatalog: () => getSandboxPluginCatalog,
|
|
1882
1899
|
getScheduleLattice: () => getScheduleLattice,
|
|
1883
1900
|
getStoreLattice: () => getStoreLattice,
|
|
1901
|
+
getThreadRunOwner: () => getThreadRunOwner,
|
|
1884
1902
|
getToolClient: () => getToolClient,
|
|
1885
1903
|
getToolClientWithTenant: () => getToolClientWithTenant,
|
|
1886
1904
|
getToolDefinition: () => getToolDefinition,
|
|
@@ -1934,6 +1952,8 @@ __export(index_exports, {
|
|
|
1934
1952
|
projectMutationMutex: () => projectMutationMutex,
|
|
1935
1953
|
projectRoomPlugin: () => projectRoomPlugin,
|
|
1936
1954
|
projectTaskAdmissionNotifier: () => projectTaskAdmissionNotifier,
|
|
1955
|
+
provisionSandboxOpenClient: () => provisionSandboxOpenClient,
|
|
1956
|
+
publishPluginCatalogChanged: () => publishPluginCatalogChanged,
|
|
1937
1957
|
queueLatticeManager: () => queueLatticeManager,
|
|
1938
1958
|
readLoopBreakerConfig: () => readLoopBreakerConfig,
|
|
1939
1959
|
reconcileAllTenantTaskRuns: () => reconcileAllTenantTaskRuns,
|
|
@@ -1952,6 +1972,7 @@ __export(index_exports, {
|
|
|
1952
1972
|
registerModelLatticeForTenant: () => registerModelLatticeForTenant,
|
|
1953
1973
|
registerQueueLattice: () => registerQueueLattice,
|
|
1954
1974
|
registerSTTModelLattice: () => registerSTTModelLattice,
|
|
1975
|
+
registerSandboxOpenCredentialProvider: () => registerSandboxOpenCredentialProvider,
|
|
1955
1976
|
registerSandboxProviderType: () => registerSandboxProviderType,
|
|
1956
1977
|
registerScheduleLattice: () => registerScheduleLattice,
|
|
1957
1978
|
registerStoreLattice: () => registerStoreLattice,
|
|
@@ -1962,6 +1983,7 @@ __export(index_exports, {
|
|
|
1962
1983
|
registerWorkflowRun: () => registerWorkflowRun,
|
|
1963
1984
|
removeCollectionVectorStore: () => removeCollectionVectorStore,
|
|
1964
1985
|
renderTemplate: () => renderTemplate,
|
|
1986
|
+
resetReplicaIdForTests: () => resetReplicaIdForTests,
|
|
1965
1987
|
resolveEnabledPluginSkill: () => resolveEnabledPluginSkill,
|
|
1966
1988
|
resolveJudgeModelKey: () => resolveJudgeModelKey,
|
|
1967
1989
|
resolvePath: () => resolvePath,
|
|
@@ -1969,6 +1991,7 @@ __export(index_exports, {
|
|
|
1969
1991
|
resolveSandboxPluginConnections: () => resolveSandboxPluginConnections,
|
|
1970
1992
|
resolveTenantPluginSkill: () => resolveTenantPluginSkill,
|
|
1971
1993
|
roomCoordinatorConfig: () => roomCoordinatorConfig,
|
|
1994
|
+
runAsLeader: () => runAsLeader,
|
|
1972
1995
|
runRemotePackDirectory: () => runRemotePackDirectory,
|
|
1973
1996
|
safeTaskResponseId: () => safeTaskResponseId,
|
|
1974
1997
|
sandboxLatticeManager: () => sandboxLatticeManager,
|
|
@@ -1987,11 +2010,15 @@ __export(index_exports, {
|
|
|
1987
2010
|
storeLatticeManager: () => storeLatticeManager,
|
|
1988
2011
|
sttModelLatticeManager: () => sttModelLatticeManager,
|
|
1989
2012
|
taskLifecycleNotifier: () => taskLifecycleNotifier,
|
|
2013
|
+
taskRunLeaseKey: () => taskRunLeaseKey,
|
|
1990
2014
|
taskRunRegistry: () => taskRunRegistry,
|
|
2015
|
+
threadRunLeaseKey: () => threadRunLeaseKey,
|
|
1991
2016
|
toJsonSchema: () => toJsonSchema,
|
|
1992
2017
|
toSafeStateExpr: () => toSafeStateExpr,
|
|
1993
2018
|
toolLatticeManager: () => toolLatticeManager,
|
|
1994
2019
|
truncateIfTooLong: () => truncateIfTooLong,
|
|
2020
|
+
tryAcquireTaskRun: () => tryAcquireTaskRun,
|
|
2021
|
+
tryAcquireThreadRun: () => tryAcquireThreadRun,
|
|
1995
2022
|
unregisterTeammateAgent: () => unregisterTeammateAgent,
|
|
1996
2023
|
unregisterWorkflowRun: () => unregisterWorkflowRun,
|
|
1997
2024
|
updateFileData: () => updateFileData,
|
|
@@ -2007,6 +2034,7 @@ __export(index_exports, {
|
|
|
2007
2034
|
validateToolInput: () => validateToolInput,
|
|
2008
2035
|
vectorStoreLatticeManager: () => vectorStoreLatticeManager,
|
|
2009
2036
|
vectorStoreProviderManager: () => vectorStoreProviderManager,
|
|
2037
|
+
withLease: () => withLease,
|
|
2010
2038
|
withTimeout: () => withTimeout2,
|
|
2011
2039
|
wrapMcpToolWithUi: () => wrapMcpToolWithUi
|
|
2012
2040
|
});
|
|
@@ -4100,7 +4128,7 @@ var InMemoryModelProviderStore = class {
|
|
|
4100
4128
|
*/
|
|
4101
4129
|
async listProviders(tenantId2) {
|
|
4102
4130
|
return Array.from(this.providers.values()).filter(
|
|
4103
|
-
(
|
|
4131
|
+
(provider2) => provider2.tenantId === tenantId2
|
|
4104
4132
|
);
|
|
4105
4133
|
}
|
|
4106
4134
|
/**
|
|
@@ -4114,7 +4142,7 @@ var InMemoryModelProviderStore = class {
|
|
|
4114
4142
|
*/
|
|
4115
4143
|
async getProviderByName(tenantId2, name) {
|
|
4116
4144
|
const providers = await this.listProviders(tenantId2);
|
|
4117
|
-
return providers.find((
|
|
4145
|
+
return providers.find((provider2) => provider2.name === name) || null;
|
|
4118
4146
|
}
|
|
4119
4147
|
/**
|
|
4120
4148
|
* Create a new provider configuration
|
|
@@ -4298,8 +4326,8 @@ var InMemoryModelProviderStore = class {
|
|
|
4298
4326
|
* Clear providers and models for a specific tenant
|
|
4299
4327
|
*/
|
|
4300
4328
|
clearByTenant(tenantId2) {
|
|
4301
|
-
for (const [key5,
|
|
4302
|
-
if (
|
|
4329
|
+
for (const [key5, provider2] of Array.from(this.providers.entries())) {
|
|
4330
|
+
if (provider2.tenantId === tenantId2) {
|
|
4303
4331
|
this.providers.delete(key5);
|
|
4304
4332
|
}
|
|
4305
4333
|
}
|
|
@@ -5175,6 +5203,123 @@ function entryKey(tenantId2, userId, endpoint) {
|
|
|
5175
5203
|
return JSON.stringify([tenantId2, userId, endpoint]);
|
|
5176
5204
|
}
|
|
5177
5205
|
|
|
5206
|
+
// src/store_lattice/InMemoryLeaseStore.ts
|
|
5207
|
+
var InMemoryLeaseStore = class {
|
|
5208
|
+
/**
|
|
5209
|
+
* @param now Injectable clock in epoch milliseconds (tests use a fake clock).
|
|
5210
|
+
*/
|
|
5211
|
+
constructor(now = Date.now) {
|
|
5212
|
+
this.leases = /* @__PURE__ */ new Map();
|
|
5213
|
+
this.now = now;
|
|
5214
|
+
}
|
|
5215
|
+
/** Atomically acquires a free/expired key (or the caller's own key). */
|
|
5216
|
+
async tryAcquire(key5, holder, ttlMs) {
|
|
5217
|
+
const existing = this.leases.get(key5);
|
|
5218
|
+
if (existing && Date.parse(existing.expiresAt) > this.now()) {
|
|
5219
|
+
if (existing.holder !== holder) return false;
|
|
5220
|
+
this.leases.set(key5, { ...existing, expiresAt: new Date(this.now() + ttlMs).toISOString() });
|
|
5221
|
+
return true;
|
|
5222
|
+
}
|
|
5223
|
+
const acquiredAt = existing && existing.holder === holder ? existing.acquiredAt : new Date(this.now()).toISOString();
|
|
5224
|
+
this.leases.set(key5, {
|
|
5225
|
+
key: key5,
|
|
5226
|
+
holder,
|
|
5227
|
+
acquiredAt,
|
|
5228
|
+
expiresAt: new Date(this.now() + ttlMs).toISOString()
|
|
5229
|
+
});
|
|
5230
|
+
return true;
|
|
5231
|
+
}
|
|
5232
|
+
/** Extends a lease only while `holder` still owns it. */
|
|
5233
|
+
async renew(key5, holder, ttlMs) {
|
|
5234
|
+
const existing = this.leases.get(key5);
|
|
5235
|
+
if (!existing || existing.holder !== holder) return false;
|
|
5236
|
+
this.leases.set(key5, { ...existing, expiresAt: new Date(this.now() + ttlMs).toISOString() });
|
|
5237
|
+
return true;
|
|
5238
|
+
}
|
|
5239
|
+
/** Deletes a lease only when `holder` owns it. */
|
|
5240
|
+
async release(key5, holder) {
|
|
5241
|
+
const existing = this.leases.get(key5);
|
|
5242
|
+
if (!existing || existing.holder !== holder) return false;
|
|
5243
|
+
this.leases.delete(key5);
|
|
5244
|
+
return true;
|
|
5245
|
+
}
|
|
5246
|
+
/** Returns the live lease, pruning an expired one. */
|
|
5247
|
+
async get(key5) {
|
|
5248
|
+
const existing = this.leases.get(key5);
|
|
5249
|
+
if (!existing) return null;
|
|
5250
|
+
if (Date.parse(existing.expiresAt) <= this.now()) {
|
|
5251
|
+
this.leases.delete(key5);
|
|
5252
|
+
return null;
|
|
5253
|
+
}
|
|
5254
|
+
return { ...existing };
|
|
5255
|
+
}
|
|
5256
|
+
};
|
|
5257
|
+
|
|
5258
|
+
// src/store_lattice/InMemoryOutboxStore.ts
|
|
5259
|
+
var InMemoryOutboxStore = class {
|
|
5260
|
+
/**
|
|
5261
|
+
* Creates an in-memory outbox store.
|
|
5262
|
+
*
|
|
5263
|
+
* @param now Optional clock override (defaults to the system clock); it stamps
|
|
5264
|
+
* `createdAt` and is used to evaluate age-based retention.
|
|
5265
|
+
*/
|
|
5266
|
+
constructor(now = () => /* @__PURE__ */ new Date()) {
|
|
5267
|
+
this.events = [];
|
|
5268
|
+
this.counter = 0;
|
|
5269
|
+
this.now = now;
|
|
5270
|
+
}
|
|
5271
|
+
/**
|
|
5272
|
+
* Appends one event, assigning the next monotonic id.
|
|
5273
|
+
* @param input Topic, JSON-safe payload, and authoring replica id.
|
|
5274
|
+
* @returns A defensive copy of the stored event.
|
|
5275
|
+
*/
|
|
5276
|
+
async append(input) {
|
|
5277
|
+
const event = {
|
|
5278
|
+
id: String(++this.counter),
|
|
5279
|
+
topic: input.topic,
|
|
5280
|
+
payload: input.payload,
|
|
5281
|
+
originReplicaId: input.originReplicaId,
|
|
5282
|
+
createdAt: this.now().toISOString()
|
|
5283
|
+
};
|
|
5284
|
+
this.events.push(event);
|
|
5285
|
+
return { ...event };
|
|
5286
|
+
}
|
|
5287
|
+
/**
|
|
5288
|
+
* Lists events strictly newer than `cursor`, ascending, bounded by `limit`.
|
|
5289
|
+
* @param cursor Last-seen id, or `null` to read from the start.
|
|
5290
|
+
* @param limit Maximum number of events to return.
|
|
5291
|
+
* @returns Defensive copies of the matching events.
|
|
5292
|
+
*/
|
|
5293
|
+
async listAfter(cursor, limit) {
|
|
5294
|
+
const floor = cursor === null ? 0 : Number(cursor);
|
|
5295
|
+
return this.events.filter((event) => Number(event.id) > floor).slice(0, limit).map((event) => ({ ...event }));
|
|
5296
|
+
}
|
|
5297
|
+
/**
|
|
5298
|
+
* Returns the newest event id.
|
|
5299
|
+
* @returns The last id, or `null` when the log is empty.
|
|
5300
|
+
*/
|
|
5301
|
+
async latestId() {
|
|
5302
|
+
return this.events.length === 0 ? null : this.events[this.events.length - 1].id;
|
|
5303
|
+
}
|
|
5304
|
+
/**
|
|
5305
|
+
* Deletes events older than `olderThanMs`, evaluated against this store's clock.
|
|
5306
|
+
*
|
|
5307
|
+
* @param olderThanMs Age threshold in milliseconds.
|
|
5308
|
+
* @returns The number of events removed.
|
|
5309
|
+
*/
|
|
5310
|
+
async pruneOlderThan(olderThanMs) {
|
|
5311
|
+
const cutoff = this.now().getTime() - olderThanMs;
|
|
5312
|
+
let removed = 0;
|
|
5313
|
+
for (let i = this.events.length - 1; i >= 0; i -= 1) {
|
|
5314
|
+
if (new Date(this.events[i].createdAt).getTime() < cutoff) {
|
|
5315
|
+
this.events.splice(i, 1);
|
|
5316
|
+
removed += 1;
|
|
5317
|
+
}
|
|
5318
|
+
}
|
|
5319
|
+
return removed;
|
|
5320
|
+
}
|
|
5321
|
+
};
|
|
5322
|
+
|
|
5178
5323
|
// src/store_lattice/InMemoryUserStore.ts
|
|
5179
5324
|
var InMemoryUserStore = class {
|
|
5180
5325
|
constructor() {
|
|
@@ -5378,7 +5523,8 @@ function isMessageContentValue(value) {
|
|
|
5378
5523
|
|
|
5379
5524
|
// src/store_lattice/InMemoryThreadMessageQueueStore.ts
|
|
5380
5525
|
var InMemoryThreadMessageQueueStore = class {
|
|
5381
|
-
constructor() {
|
|
5526
|
+
constructor(now = Date.now) {
|
|
5527
|
+
this.now = now;
|
|
5382
5528
|
this.messages = /* @__PURE__ */ new Map();
|
|
5383
5529
|
this.messageIdCounter = 0;
|
|
5384
5530
|
this.capacityTail = Promise.resolve();
|
|
@@ -5485,6 +5631,36 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
5485
5631
|
const threadMessages = this.getMessagesForThread(threadId);
|
|
5486
5632
|
return threadMessages.filter((msg) => msg.status === "processing" && this.inScope(msg, scope)).sort((a, b) => (b.priority || 0) - (a.priority || 0) || a.sequence - b.sequence).map(clonePendingMessage);
|
|
5487
5633
|
}
|
|
5634
|
+
async claimPendingMessages(threadId, scope, options) {
|
|
5635
|
+
const threadMessages = this.getMessagesForThread(threadId);
|
|
5636
|
+
const candidates = threadMessages.filter((msg) => (msg.status === "pending" || !msg.status) && this.inScope(msg, scope)).sort((a, b) => (b.priority || 0) - (a.priority || 0) || a.sequence - b.sequence);
|
|
5637
|
+
const limit = options.limit === void 0 ? void 0 : Math.max(0, Math.floor(options.limit));
|
|
5638
|
+
const selected = limit === void 0 ? candidates : candidates.slice(0, limit);
|
|
5639
|
+
const now = this.now();
|
|
5640
|
+
for (const message of selected) {
|
|
5641
|
+
message.status = "processing";
|
|
5642
|
+
message.lockedBy = options.owner;
|
|
5643
|
+
message.lockedAt = new Date(now);
|
|
5644
|
+
message.leaseExpiresAt = new Date(now + options.ttlMs);
|
|
5645
|
+
}
|
|
5646
|
+
return selected.map(clonePendingMessage);
|
|
5647
|
+
}
|
|
5648
|
+
async reclaimExpiredProcessing(threadId, scope) {
|
|
5649
|
+
const messages = this.messages.get(threadId);
|
|
5650
|
+
if (!messages) return 0;
|
|
5651
|
+
const now = this.now();
|
|
5652
|
+
let count = 0;
|
|
5653
|
+
for (const msg of messages) {
|
|
5654
|
+
if (msg.status === "processing" && this.inScope(msg, scope) && msg.leaseExpiresAt !== void 0 && msg.leaseExpiresAt.getTime() <= now) {
|
|
5655
|
+
msg.status = "pending";
|
|
5656
|
+
msg.lockedBy = void 0;
|
|
5657
|
+
msg.lockedAt = void 0;
|
|
5658
|
+
msg.leaseExpiresAt = void 0;
|
|
5659
|
+
count += 1;
|
|
5660
|
+
}
|
|
5661
|
+
}
|
|
5662
|
+
return count;
|
|
5663
|
+
}
|
|
5488
5664
|
async getQueueSize(threadId, scope) {
|
|
5489
5665
|
const pending = await this.getPendingMessages(threadId, scope);
|
|
5490
5666
|
return pending.length;
|
|
@@ -5548,6 +5724,9 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
5548
5724
|
for (const msg of messages) {
|
|
5549
5725
|
if (msg.status === "processing" && this.inScope(msg, scope)) {
|
|
5550
5726
|
msg.status = "pending";
|
|
5727
|
+
msg.lockedBy = void 0;
|
|
5728
|
+
msg.lockedAt = void 0;
|
|
5729
|
+
msg.leaseExpiresAt = void 0;
|
|
5551
5730
|
count++;
|
|
5552
5731
|
}
|
|
5553
5732
|
}
|
|
@@ -6801,6 +6980,8 @@ var defaultProjectBotMembershipStore = new InMemoryProjectBotMembershipStore(def
|
|
|
6801
6980
|
var defaultProjectRoomMessageStore = new InMemoryProjectRoomMessageStore(defaultProjectRoomCoordinator);
|
|
6802
6981
|
var defaultProjectRoomReadStateStore = new InMemoryProjectRoomReadStateStore();
|
|
6803
6982
|
var defaultUserPushSubscriptionStore = new InMemoryUserPushSubscriptionStore();
|
|
6983
|
+
var defaultLeaseStore = new InMemoryLeaseStore();
|
|
6984
|
+
var defaultOutboxStore = new InMemoryOutboxStore();
|
|
6804
6985
|
storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
|
|
6805
6986
|
storeLatticeManager.registerLattice(
|
|
6806
6987
|
"default",
|
|
@@ -6822,6 +7003,8 @@ storeLatticeManager.registerLattice("default", "projectBotMembership", defaultPr
|
|
|
6822
7003
|
storeLatticeManager.registerLattice("default", "projectRoomMessage", defaultProjectRoomMessageStore);
|
|
6823
7004
|
storeLatticeManager.registerLattice("default", "projectRoomReadState", defaultProjectRoomReadStateStore);
|
|
6824
7005
|
storeLatticeManager.registerLattice("default", "userPushSubscription", defaultUserPushSubscriptionStore);
|
|
7006
|
+
storeLatticeManager.registerLattice("default", "lease", defaultLeaseStore);
|
|
7007
|
+
storeLatticeManager.registerLattice("default", "outbox", defaultOutboxStore);
|
|
6825
7008
|
var defaultUserStore = new InMemoryUserStore();
|
|
6826
7009
|
var defaultTenantStore = new InMemoryTenantStore();
|
|
6827
7010
|
var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
|
|
@@ -8690,8 +8873,8 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
8690
8873
|
} catch {
|
|
8691
8874
|
}
|
|
8692
8875
|
const tenantConfigs = this.configs.get(tenantId2);
|
|
8693
|
-
const
|
|
8694
|
-
if (
|
|
8876
|
+
const cached2 = tenantConfigs?.get(key5);
|
|
8877
|
+
if (cached2) return cached2;
|
|
8695
8878
|
throw new Error(`Metrics server '${key5}' not found for tenant '${tenantId2}'`);
|
|
8696
8879
|
}
|
|
8697
8880
|
/**
|
|
@@ -10004,8 +10187,8 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
10004
10187
|
getLatticeType() {
|
|
10005
10188
|
return "sandbox_manager";
|
|
10006
10189
|
}
|
|
10007
|
-
registerLattice(key5,
|
|
10008
|
-
this.register(key5,
|
|
10190
|
+
registerLattice(key5, provider2) {
|
|
10191
|
+
this.register(key5, provider2);
|
|
10009
10192
|
}
|
|
10010
10193
|
getSandboxLattice(key5) {
|
|
10011
10194
|
const lattice = this.get(key5);
|
|
@@ -10056,8 +10239,8 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
10056
10239
|
return this.getVolumeBackendForPath(config, "/project");
|
|
10057
10240
|
}
|
|
10058
10241
|
async getVolumeBackendForPath(config, filePath) {
|
|
10059
|
-
const
|
|
10060
|
-
if (!
|
|
10242
|
+
const provider2 = this._requireProvider();
|
|
10243
|
+
if (!provider2.createVolumeFsClient) {
|
|
10061
10244
|
console.log(`[getVolumeBackendForPath] provider has no createVolumeFsClient, returning null`);
|
|
10062
10245
|
return null;
|
|
10063
10246
|
}
|
|
@@ -10068,7 +10251,7 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
10068
10251
|
return null;
|
|
10069
10252
|
}
|
|
10070
10253
|
console.log(`[getVolumeBackendForPath] path=${filePath} volume=${mapping.volumeName} prefix=${mapping.pathPrefix}`);
|
|
10071
|
-
const client =
|
|
10254
|
+
const client = provider2.createVolumeFsClient(mapping.volumeName, mapping.pathPrefix);
|
|
10072
10255
|
return new VolumeFilesystem(stripPrefixClient(client, mapping.pathPrefix), mapping.pathPrefix);
|
|
10073
10256
|
}
|
|
10074
10257
|
_resolveVolumeForPath(config, tenantId2, filePath) {
|
|
@@ -10103,35 +10286,35 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
10103
10286
|
};
|
|
10104
10287
|
}
|
|
10105
10288
|
async createSandbox(name, config) {
|
|
10106
|
-
const
|
|
10107
|
-
return
|
|
10289
|
+
const provider2 = this._requireProvider();
|
|
10290
|
+
return provider2.createSandbox(name, config);
|
|
10108
10291
|
}
|
|
10109
10292
|
async getSandbox(name) {
|
|
10110
|
-
const
|
|
10111
|
-
return
|
|
10293
|
+
const provider2 = this._requireProvider();
|
|
10294
|
+
return provider2.getSandbox(name);
|
|
10112
10295
|
}
|
|
10113
10296
|
async stopSandbox(name) {
|
|
10114
|
-
const
|
|
10115
|
-
return
|
|
10297
|
+
const provider2 = this._requireProvider();
|
|
10298
|
+
return provider2.stopSandbox(name);
|
|
10116
10299
|
}
|
|
10117
10300
|
async deleteSandbox(name) {
|
|
10118
|
-
const
|
|
10119
|
-
return
|
|
10301
|
+
const provider2 = this._requireProvider();
|
|
10302
|
+
return provider2.deleteSandbox(name);
|
|
10120
10303
|
}
|
|
10121
10304
|
async listSandboxes() {
|
|
10122
|
-
const
|
|
10123
|
-
return
|
|
10305
|
+
const provider2 = this._requireProvider();
|
|
10306
|
+
return provider2.listSandboxes();
|
|
10124
10307
|
}
|
|
10125
10308
|
_requireProvider() {
|
|
10126
10309
|
const keys = this.keysByTenant("default");
|
|
10127
10310
|
if (keys.length === 0) {
|
|
10128
10311
|
throw new Error("Sandbox provider not configured.");
|
|
10129
10312
|
}
|
|
10130
|
-
const
|
|
10131
|
-
if (!
|
|
10313
|
+
const provider2 = this.get(keys[0]);
|
|
10314
|
+
if (!provider2) {
|
|
10132
10315
|
throw new Error("Sandbox provider not configured.");
|
|
10133
10316
|
}
|
|
10134
|
-
return
|
|
10317
|
+
return provider2;
|
|
10135
10318
|
}
|
|
10136
10319
|
/**
|
|
10137
10320
|
* Returns the first registered (default) sandbox provider.
|
|
@@ -10161,6 +10344,46 @@ var import_langchain13 = require("langchain");
|
|
|
10161
10344
|
// src/tool_lattice/shell_exec/index.ts
|
|
10162
10345
|
var import_zod17 = __toESM(require("zod"));
|
|
10163
10346
|
var import_langchain14 = require("langchain");
|
|
10347
|
+
|
|
10348
|
+
// src/sandbox_lattice/sandboxOpenCredential.ts
|
|
10349
|
+
var SANDBOX_OPEN_GATEWAY_URL_ENV = "API_GATEWAY_URL";
|
|
10350
|
+
var SANDBOX_OPEN_TOKEN_ENV = "OPEN_API_TOKEN";
|
|
10351
|
+
var provider;
|
|
10352
|
+
var providerErrorHandler;
|
|
10353
|
+
function registerSandboxOpenCredentialProvider(next, options = {}) {
|
|
10354
|
+
provider = next;
|
|
10355
|
+
providerErrorHandler = options.onError;
|
|
10356
|
+
return () => {
|
|
10357
|
+
if (provider === next) {
|
|
10358
|
+
provider = void 0;
|
|
10359
|
+
providerErrorHandler = void 0;
|
|
10360
|
+
}
|
|
10361
|
+
};
|
|
10362
|
+
}
|
|
10363
|
+
async function getSandboxOpenCredential(context) {
|
|
10364
|
+
if (!provider) return void 0;
|
|
10365
|
+
try {
|
|
10366
|
+
return await provider(context);
|
|
10367
|
+
} catch (error) {
|
|
10368
|
+
try {
|
|
10369
|
+
providerErrorHandler?.(error);
|
|
10370
|
+
} catch {
|
|
10371
|
+
}
|
|
10372
|
+
return void 0;
|
|
10373
|
+
}
|
|
10374
|
+
}
|
|
10375
|
+
function buildSandboxOpenEnv(credential) {
|
|
10376
|
+
return `export ${SANDBOX_OPEN_GATEWAY_URL_ENV}=${shellSingleQuote(credential.gatewayUrl)} && export ${SANDBOX_OPEN_TOKEN_ENV}=${shellSingleQuote(credential.token)}`;
|
|
10377
|
+
}
|
|
10378
|
+
function shellSingleQuote(value) {
|
|
10379
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
10380
|
+
}
|
|
10381
|
+
function clearSandboxOpenCredentialProviderForTests() {
|
|
10382
|
+
provider = void 0;
|
|
10383
|
+
providerErrorHandler = void 0;
|
|
10384
|
+
}
|
|
10385
|
+
|
|
10386
|
+
// src/tool_lattice/shell_exec/index.ts
|
|
10164
10387
|
var SHELL_EXEC_DESCRIPTION = `Execute a shell command in the sandbox environment.
|
|
10165
10388
|
|
|
10166
10389
|
Use this to run CLI tools, install packages, inspect files, or perform any operation that requires a shell.
|
|
@@ -10193,8 +10416,19 @@ var createShellExecTool = ({
|
|
|
10193
10416
|
projectId: runConfig.projectId,
|
|
10194
10417
|
vmIsolation
|
|
10195
10418
|
});
|
|
10419
|
+
const tenantId2 = runConfig.tenantId;
|
|
10420
|
+
const credential = tenantId2 ? await getSandboxOpenCredential({
|
|
10421
|
+
tenantId: tenantId2,
|
|
10422
|
+
workspaceId: runConfig.workspaceId,
|
|
10423
|
+
projectId: runConfig.projectId,
|
|
10424
|
+
sandboxName: sandbox.name,
|
|
10425
|
+
assistantId: runConfig.assistant_id || void 0,
|
|
10426
|
+
threadId: runConfig.thread_id || void 0,
|
|
10427
|
+
depth: runConfig.depth
|
|
10428
|
+
}) : void 0;
|
|
10429
|
+
const command = credential ? `${buildSandboxOpenEnv(credential)} && ${input.command}` : input.command;
|
|
10196
10430
|
const executeResult = await sandbox.shell.execCommand({
|
|
10197
|
-
command
|
|
10431
|
+
command,
|
|
10198
10432
|
exec_dir: input.exec_dir,
|
|
10199
10433
|
timeout: input.timeout ?? 300
|
|
10200
10434
|
});
|
|
@@ -14926,13 +15160,23 @@ var SandboxPluginExecutor = class {
|
|
|
14926
15160
|
validateRelativePath(args.handler, "handler");
|
|
14927
15161
|
const pluginDir = `${PLUGINS_ROOT}/${args.manifest.type}`;
|
|
14928
15162
|
const handlerAbs = `${pluginDir}/${args.handler}`;
|
|
15163
|
+
const tenantId2 = args.runConfig?.tenantId ?? args.context.tenantId;
|
|
14929
15164
|
const sandbox = await this.deps.resolveSandbox({
|
|
14930
|
-
tenantId:
|
|
15165
|
+
tenantId: tenantId2,
|
|
14931
15166
|
assistantId: args.runConfig?.assistantId,
|
|
14932
15167
|
threadId: args.runConfig?.threadId,
|
|
14933
15168
|
workspaceId: args.runConfig?.workspaceId,
|
|
14934
15169
|
projectId: args.runConfig?.projectId
|
|
14935
15170
|
});
|
|
15171
|
+
const openCredential = tenantId2 ? await getSandboxOpenCredential({
|
|
15172
|
+
tenantId: tenantId2,
|
|
15173
|
+
workspaceId: args.runConfig?.workspaceId,
|
|
15174
|
+
projectId: args.runConfig?.projectId,
|
|
15175
|
+
sandboxName: sandbox.name,
|
|
15176
|
+
assistantId: args.runConfig?.assistantId,
|
|
15177
|
+
threadId: args.runConfig?.threadId,
|
|
15178
|
+
depth: args.runConfig?.depth
|
|
15179
|
+
}) : void 0;
|
|
14936
15180
|
const timeoutMs = clamp(args.timeoutMs ?? DEFAULT_TIMEOUT_MS, MIN_TIMEOUT_MS, MAX_TIMEOUT_MS);
|
|
14937
15181
|
const cap = clamp(
|
|
14938
15182
|
args.maxResultBytes ?? DEFAULT_MAX_RESULT_BYTES,
|
|
@@ -14963,6 +15207,12 @@ var SandboxPluginExecutor = class {
|
|
|
14963
15207
|
envParts.push(`PLUGIN_CONNECTION_FILE=${quotePosixShellArg(connectionFile)}`);
|
|
14964
15208
|
}
|
|
14965
15209
|
envParts.push(`PLUGIN_CONTEXT=${quotePosixShellArg(encode(args.context))}`);
|
|
15210
|
+
if (openCredential) {
|
|
15211
|
+
envParts.push(
|
|
15212
|
+
`${SANDBOX_OPEN_GATEWAY_URL_ENV}=${quotePosixShellArg(openCredential.gatewayUrl)}`
|
|
15213
|
+
);
|
|
15214
|
+
envParts.push(`${SANDBOX_OPEN_TOKEN_ENV}=${quotePosixShellArg(openCredential.token)}`);
|
|
15215
|
+
}
|
|
14966
15216
|
const command = `${envParts.join(" ")} node ${quotePosixShellArg(handlerAbs)}`;
|
|
14967
15217
|
const execResult = await sandbox.shell.execCommand({
|
|
14968
15218
|
command,
|
|
@@ -15914,10 +16164,10 @@ var TenantPluginCatalog = class {
|
|
|
15914
16164
|
candidates.push({ type, dirPath: dir.path, raw, manifestJson, files: dirFiles });
|
|
15915
16165
|
}
|
|
15916
16166
|
const hash = (0, import_node_crypto3.createHash)("sha256").update(hashParts.sort().join("\n")).digest("hex").slice(0, 16);
|
|
15917
|
-
const
|
|
15918
|
-
if (
|
|
15919
|
-
this.cache.set(tenantId2, { value:
|
|
15920
|
-
return
|
|
16167
|
+
const cached2 = this.cache.get(tenantId2)?.value;
|
|
16168
|
+
if (cached2 && cached2.hash === hash) {
|
|
16169
|
+
this.cache.set(tenantId2, { value: cached2, checkedAt: this.now() });
|
|
16170
|
+
return cached2;
|
|
15921
16171
|
}
|
|
15922
16172
|
const plugins = [];
|
|
15923
16173
|
const manifests = {};
|
|
@@ -17262,7 +17512,7 @@ var AgentWorkerState = import_langgraph5.Annotation.Root({
|
|
|
17262
17512
|
default: () => ({})
|
|
17263
17513
|
}),
|
|
17264
17514
|
command2: (0, import_langgraph5.Annotation)({
|
|
17265
|
-
reducer: (
|
|
17515
|
+
reducer: (_x, y) => y,
|
|
17266
17516
|
default: () => void 0
|
|
17267
17517
|
}),
|
|
17268
17518
|
// RunConfig for passing configuration through the graph
|
|
@@ -17279,12 +17529,12 @@ var AgentWorkerState = import_langgraph5.Annotation.Root({
|
|
|
17279
17529
|
}),
|
|
17280
17530
|
// Execution result
|
|
17281
17531
|
result: (0, import_langgraph5.Annotation)({
|
|
17282
|
-
reducer: (
|
|
17532
|
+
reducer: (_x, y) => y,
|
|
17283
17533
|
default: () => void 0
|
|
17284
17534
|
}),
|
|
17285
17535
|
// Interrupt data
|
|
17286
17536
|
interruptValue: (0, import_langgraph5.Annotation)({
|
|
17287
|
-
reducer: (
|
|
17537
|
+
reducer: (_x, y) => y,
|
|
17288
17538
|
default: () => void 0
|
|
17289
17539
|
}),
|
|
17290
17540
|
// Final state to return
|
|
@@ -18974,6 +19224,71 @@ var CapabilityRuntimeResolver = class {
|
|
|
18974
19224
|
// src/services/TrustedAgentDispatchCapability.ts
|
|
18975
19225
|
var TRUSTED_AGENT_DISPATCH = Symbol("axiom.trustedAgentDispatch");
|
|
18976
19226
|
|
|
19227
|
+
// src/services/threadRunLease.ts
|
|
19228
|
+
var import_node_crypto5 = require("crypto");
|
|
19229
|
+
function threadRunLeaseKey(tenantId2, assistantId, threadId) {
|
|
19230
|
+
return `thread-run:${tenantId2}:${assistantId}:${threadId}`;
|
|
19231
|
+
}
|
|
19232
|
+
async function tryAcquireThreadRun(input) {
|
|
19233
|
+
const key5 = threadRunLeaseKey(input.tenantId, input.assistantId, input.threadId);
|
|
19234
|
+
const holder = `${input.owner}#${(0, import_node_crypto5.randomUUID)()}`;
|
|
19235
|
+
if (!await input.store.tryAcquire(key5, holder, input.ttlMs)) return null;
|
|
19236
|
+
const heartbeatMs = input.heartbeatMs ?? Math.max(1e3, Math.floor(input.ttlMs / 3));
|
|
19237
|
+
let released = false;
|
|
19238
|
+
let lost = false;
|
|
19239
|
+
const heartbeat = setInterval(() => {
|
|
19240
|
+
void input.store.renew(key5, holder, input.ttlMs).then((renewed) => {
|
|
19241
|
+
if (released || renewed || lost) return;
|
|
19242
|
+
lost = true;
|
|
19243
|
+
try {
|
|
19244
|
+
input.onLost?.();
|
|
19245
|
+
} catch {
|
|
19246
|
+
}
|
|
19247
|
+
}).catch(() => void 0);
|
|
19248
|
+
}, heartbeatMs);
|
|
19249
|
+
heartbeat.unref?.();
|
|
19250
|
+
return {
|
|
19251
|
+
get lost() {
|
|
19252
|
+
return lost;
|
|
19253
|
+
},
|
|
19254
|
+
release: async () => {
|
|
19255
|
+
if (released) return;
|
|
19256
|
+
released = true;
|
|
19257
|
+
clearInterval(heartbeat);
|
|
19258
|
+
await input.store.release(key5, holder).catch(() => void 0);
|
|
19259
|
+
}
|
|
19260
|
+
};
|
|
19261
|
+
}
|
|
19262
|
+
async function getThreadRunOwner(input) {
|
|
19263
|
+
let store = input.store;
|
|
19264
|
+
if (!store) {
|
|
19265
|
+
try {
|
|
19266
|
+
store = storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
19267
|
+
} catch {
|
|
19268
|
+
return null;
|
|
19269
|
+
}
|
|
19270
|
+
}
|
|
19271
|
+
try {
|
|
19272
|
+
const record = await store.get(threadRunLeaseKey(input.tenantId, input.assistantId, input.threadId));
|
|
19273
|
+
if (!record) return null;
|
|
19274
|
+
const hash = record.holder.lastIndexOf("#");
|
|
19275
|
+
return hash > 0 ? record.holder.slice(0, hash) : record.holder;
|
|
19276
|
+
} catch {
|
|
19277
|
+
return null;
|
|
19278
|
+
}
|
|
19279
|
+
}
|
|
19280
|
+
|
|
19281
|
+
// src/services/replicaIdentity.ts
|
|
19282
|
+
var import_node_os = __toESM(require("os"));
|
|
19283
|
+
var cached;
|
|
19284
|
+
function getReplicaId() {
|
|
19285
|
+
cached ?? (cached = process.env.AXIOM_REPLICA_ID?.trim() || `${import_node_os.default.hostname()}:${process.pid}`);
|
|
19286
|
+
return cached;
|
|
19287
|
+
}
|
|
19288
|
+
function resetReplicaIdForTests() {
|
|
19289
|
+
cached = void 0;
|
|
19290
|
+
}
|
|
19291
|
+
|
|
18977
19292
|
// src/services/Agent.ts
|
|
18978
19293
|
var ThreadStatus2 = /* @__PURE__ */ ((ThreadStatus3) => {
|
|
18979
19294
|
ThreadStatus3["IDLE"] = "idle";
|
|
@@ -19291,6 +19606,10 @@ function checkpointCapabilityRevision(state) {
|
|
|
19291
19606
|
var QUEUE_PROCESSOR_RETRY_BASE_MS = 100;
|
|
19292
19607
|
var QUEUE_PROCESSOR_MAX_RETRIES = 3;
|
|
19293
19608
|
var AGENT_RECURSION_LIMIT = 1e3;
|
|
19609
|
+
var THREAD_RUN_LEASE_TTL_MS = 6e4;
|
|
19610
|
+
var THREAD_RUN_LEASE_RETRY_BASE_MS = 150;
|
|
19611
|
+
var THREAD_RUN_LEASE_RETRY_CAP_MS = 1500;
|
|
19612
|
+
var THREAD_RUN_LEASE_MAX_RETRIES = 12;
|
|
19294
19613
|
function hasExactKeys(record, required, optional = []) {
|
|
19295
19614
|
const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
|
|
19296
19615
|
return required.every((key5) => Object.prototype.hasOwnProperty.call(record, key5)) && Reflect.ownKeys(record).every((key5) => typeof key5 === "string" && allowed.has(key5));
|
|
@@ -19320,6 +19639,13 @@ var Agent = class {
|
|
|
19320
19639
|
this.queueProcessorRetryAttempt = 0;
|
|
19321
19640
|
this.queueProcessorGeneration = 0;
|
|
19322
19641
|
this.queueWakeRequested = false;
|
|
19642
|
+
/**
|
|
19643
|
+
* Thread-run ownership lease held while this replica is actively processing
|
|
19644
|
+
* the thread. Acquired non-blockingly in {@link startQueueProcessor}; released
|
|
19645
|
+
* exactly once when the processor definitively stops.
|
|
19646
|
+
*/
|
|
19647
|
+
this.threadRunLease = null;
|
|
19648
|
+
this.threadRunLeaseRetryAttempt = 0;
|
|
19323
19649
|
this.asyncTasks = [];
|
|
19324
19650
|
this.agentExecutor = async ({ input, command, custom_run_config, expected_capability_revision, trusted_run_context }, signal) => {
|
|
19325
19651
|
const { runnable_agent, runConfig } = await this.getLatticeClientAndRuntimeConfig(
|
|
@@ -19436,7 +19762,7 @@ var Agent = class {
|
|
|
19436
19762
|
}
|
|
19437
19763
|
};
|
|
19438
19764
|
this.waitingForQueueEnd = async (signal) => {
|
|
19439
|
-
while (!signal?.aborted) {
|
|
19765
|
+
while (!signal?.aborted && !this.threadRunLease?.lost) {
|
|
19440
19766
|
const pendings = await this.getPendingMessages();
|
|
19441
19767
|
if (pendings.length === 0) {
|
|
19442
19768
|
const state = await this.getCurrentState();
|
|
@@ -20212,12 +20538,47 @@ var Agent = class {
|
|
|
20212
20538
|
id: interruptData.id,
|
|
20213
20539
|
data: { content: interruptData.value }
|
|
20214
20540
|
};
|
|
20541
|
+
await this.awaitDurableInterrupt(interruptData.id, signal);
|
|
20215
20542
|
}
|
|
20216
20543
|
if (data) {
|
|
20217
20544
|
this.addChunk(data);
|
|
20218
20545
|
}
|
|
20219
20546
|
}
|
|
20220
20547
|
}
|
|
20548
|
+
/**
|
|
20549
|
+
* Waits until the thread's durable checkpoint reports the given interrupt id.
|
|
20550
|
+
*
|
|
20551
|
+
* Reads {@link getCurrentState} (the checkpoint, i.e. the single source of
|
|
20552
|
+
* truth), never an in-memory status, so a `true` result guarantees a resume
|
|
20553
|
+
* against this thread will find the interrupt. Bounded so a broken
|
|
20554
|
+
* checkpointer cannot strand the stream; on timeout the interrupt is emitted
|
|
20555
|
+
* anyway and a warning is logged.
|
|
20556
|
+
*
|
|
20557
|
+
* @param interruptId - Interrupt id from the streamed `__interrupt__` update.
|
|
20558
|
+
* @param signal - Run abort signal; polling stops when aborted.
|
|
20559
|
+
* @param timeoutMs - Maximum time to wait for durable confirmation.
|
|
20560
|
+
*/
|
|
20561
|
+
async awaitDurableInterrupt(interruptId, signal, timeoutMs = 5e3) {
|
|
20562
|
+
if (!interruptId) return;
|
|
20563
|
+
const deadline = Date.now() + timeoutMs;
|
|
20564
|
+
while (!signal?.aborted) {
|
|
20565
|
+
try {
|
|
20566
|
+
const state = await this.getCurrentState();
|
|
20567
|
+
const durable = (state?.tasks ?? []).some(
|
|
20568
|
+
(task) => (task.interrupts ?? []).some((interrupt5) => interrupt5.id === interruptId)
|
|
20569
|
+
);
|
|
20570
|
+
if (durable) return;
|
|
20571
|
+
} catch {
|
|
20572
|
+
}
|
|
20573
|
+
if (Date.now() >= deadline) {
|
|
20574
|
+
console.warn(
|
|
20575
|
+
`[Agent] interrupt ${interruptId} not durable within ${timeoutMs}ms on thread ${this.thread_id}; emitting without durable confirmation`
|
|
20576
|
+
);
|
|
20577
|
+
return;
|
|
20578
|
+
}
|
|
20579
|
+
await new Promise((resolve4) => setTimeout(resolve4, 20));
|
|
20580
|
+
}
|
|
20581
|
+
}
|
|
20221
20582
|
/**
|
|
20222
20583
|
* Resume LangGraph execution from the last checkpoint.
|
|
20223
20584
|
*
|
|
@@ -20267,6 +20628,29 @@ var Agent = class {
|
|
|
20267
20628
|
}
|
|
20268
20629
|
return this.queueStore;
|
|
20269
20630
|
}
|
|
20631
|
+
/**
|
|
20632
|
+
* Resolves the shared lease store used to serialize thread runs across
|
|
20633
|
+
* Gateway replicas. Returns `undefined` when no lease store is registered so
|
|
20634
|
+
* single-process deployments keep running unconditionally.
|
|
20635
|
+
*/
|
|
20636
|
+
getLeaseStore() {
|
|
20637
|
+
try {
|
|
20638
|
+
return storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
20639
|
+
} catch {
|
|
20640
|
+
return void 0;
|
|
20641
|
+
}
|
|
20642
|
+
}
|
|
20643
|
+
/**
|
|
20644
|
+
* Releases this replica's thread-run ownership lease, if held.
|
|
20645
|
+
*
|
|
20646
|
+
* @remarks Safe to call from any definitive-stop path; a second call is a
|
|
20647
|
+
* no-op. The handle's unique holder makes a stale release harmless.
|
|
20648
|
+
*/
|
|
20649
|
+
async releaseThreadRunLease() {
|
|
20650
|
+
const lease = this.threadRunLease;
|
|
20651
|
+
this.threadRunLease = null;
|
|
20652
|
+
if (lease) await lease.release();
|
|
20653
|
+
}
|
|
20270
20654
|
getDefaultQueueConfig() {
|
|
20271
20655
|
return {
|
|
20272
20656
|
mode: "collect" /* COLLECT */,
|
|
@@ -20292,6 +20676,8 @@ var Agent = class {
|
|
|
20292
20676
|
*/
|
|
20293
20677
|
stopQueueProcessor() {
|
|
20294
20678
|
this.cancelQueueProcessorRetry();
|
|
20679
|
+
this.cancelThreadRunLeaseRetry();
|
|
20680
|
+
void this.releaseThreadRunLease();
|
|
20295
20681
|
this.clearRecoveryBlock();
|
|
20296
20682
|
this.queueProcessorGeneration += 1;
|
|
20297
20683
|
if (this.abortController) {
|
|
@@ -20439,16 +20825,50 @@ var Agent = class {
|
|
|
20439
20825
|
startQueueProcessorIfNeeded() {
|
|
20440
20826
|
return this.startQueueProcessor(true);
|
|
20441
20827
|
}
|
|
20442
|
-
startQueueProcessor(freshWakeup) {
|
|
20828
|
+
async startQueueProcessor(freshWakeup) {
|
|
20443
20829
|
this.queueWakeRequested = true;
|
|
20444
20830
|
if (this.queueProcessorPromise) return this.queueProcessorPromise;
|
|
20445
|
-
if (this.queueProcessorRetryTimer) return
|
|
20831
|
+
if (this.queueProcessorRetryTimer) return;
|
|
20446
20832
|
if (freshWakeup && this.queueProcessorRetryAttempt >= QUEUE_PROCESSOR_MAX_RETRIES) {
|
|
20447
20833
|
this.queueProcessorRetryAttempt = 0;
|
|
20448
20834
|
}
|
|
20835
|
+
if (freshWakeup && this.threadRunLeaseRetryAttempt >= THREAD_RUN_LEASE_MAX_RETRIES) {
|
|
20836
|
+
this.threadRunLeaseRetryAttempt = 0;
|
|
20837
|
+
}
|
|
20449
20838
|
this.queueWakeRequested = false;
|
|
20450
|
-
let processorFailed = false;
|
|
20451
20839
|
const processorGeneration = this.queueProcessorGeneration;
|
|
20840
|
+
if (this.threadRunLease?.lost) await this.releaseThreadRunLease();
|
|
20841
|
+
let acquiredLeaseHere = false;
|
|
20842
|
+
if (this.threadRunLease === null) {
|
|
20843
|
+
const leaseStore = this.getLeaseStore();
|
|
20844
|
+
if (leaseStore) {
|
|
20845
|
+
const lease = await tryAcquireThreadRun({
|
|
20846
|
+
store: leaseStore,
|
|
20847
|
+
tenantId: this.tenant_id,
|
|
20848
|
+
assistantId: this.assistant_id,
|
|
20849
|
+
threadId: this.thread_id,
|
|
20850
|
+
owner: getReplicaId(),
|
|
20851
|
+
ttlMs: THREAD_RUN_LEASE_TTL_MS,
|
|
20852
|
+
onLost: () => {
|
|
20853
|
+
console.warn(`[Agent] Thread-run lease lost for thread ${this.thread_id}; aborting the held run`);
|
|
20854
|
+
this.abortController?.abort();
|
|
20855
|
+
}
|
|
20856
|
+
});
|
|
20857
|
+
if (!lease) {
|
|
20858
|
+
this.scheduleThreadRunLeaseRetry();
|
|
20859
|
+
return;
|
|
20860
|
+
}
|
|
20861
|
+
this.threadRunLease = lease;
|
|
20862
|
+
acquiredLeaseHere = true;
|
|
20863
|
+
this.cancelThreadRunLeaseRetry();
|
|
20864
|
+
}
|
|
20865
|
+
}
|
|
20866
|
+
if (this.queueProcessorPromise) return this.queueProcessorPromise;
|
|
20867
|
+
if (this.queueProcessorGeneration !== processorGeneration) {
|
|
20868
|
+
if (acquiredLeaseHere) await this.releaseThreadRunLease();
|
|
20869
|
+
return;
|
|
20870
|
+
}
|
|
20871
|
+
let processorFailed = false;
|
|
20452
20872
|
const processor = this.runQueueProcessor().catch(async (error) => {
|
|
20453
20873
|
processorFailed = true;
|
|
20454
20874
|
console.error(`Queue processing error for thread ${this.thread_id}:`, error);
|
|
@@ -20466,7 +20886,11 @@ var Agent = class {
|
|
|
20466
20886
|
if (this.queueWakeRequested) void this.startQueueProcessor(false);
|
|
20467
20887
|
return;
|
|
20468
20888
|
}
|
|
20469
|
-
if (failed)
|
|
20889
|
+
if (failed) {
|
|
20890
|
+
this.cancelThreadRunLeaseRetry();
|
|
20891
|
+
await this.releaseThreadRunLease();
|
|
20892
|
+
return;
|
|
20893
|
+
}
|
|
20470
20894
|
this.queueProcessorRetryAttempt = 0;
|
|
20471
20895
|
if (this.queueWakeRequested) {
|
|
20472
20896
|
void this.startQueueProcessor(false);
|
|
@@ -20479,7 +20903,11 @@ var Agent = class {
|
|
|
20479
20903
|
void this.startQueueProcessor(false);
|
|
20480
20904
|
return;
|
|
20481
20905
|
}
|
|
20482
|
-
if (pendingMessages.length === 0)
|
|
20906
|
+
if (pendingMessages.length === 0) {
|
|
20907
|
+
this.cancelThreadRunLeaseRetry();
|
|
20908
|
+
await this.releaseThreadRunLease();
|
|
20909
|
+
return;
|
|
20910
|
+
}
|
|
20483
20911
|
const processingMessages = await this.getQueueStore().getProcessingMessages(
|
|
20484
20912
|
this.thread_id,
|
|
20485
20913
|
this.queueScope()
|
|
@@ -20491,12 +20919,20 @@ var Agent = class {
|
|
|
20491
20919
|
}
|
|
20492
20920
|
if (processingMessages.length > 0) {
|
|
20493
20921
|
const runStatus = await this.getRunStatus();
|
|
20494
|
-
if (runStatus === "busy" /* BUSY */ || runStatus === "interrupted" /* INTERRUPTED */)
|
|
20922
|
+
if (runStatus === "busy" /* BUSY */ || runStatus === "interrupted" /* INTERRUPTED */) {
|
|
20923
|
+
this.cancelThreadRunLeaseRetry();
|
|
20924
|
+
await this.releaseThreadRunLease();
|
|
20925
|
+
return;
|
|
20926
|
+
}
|
|
20495
20927
|
}
|
|
20496
20928
|
void this.startQueueProcessor(false);
|
|
20497
20929
|
} catch (error) {
|
|
20498
20930
|
console.error(`Queue processor finalization failed for thread ${this.thread_id}:`, error);
|
|
20499
20931
|
await this.scheduleQueueProcessorRetry(error, generation);
|
|
20932
|
+
if (!this.queueProcessorPromise) {
|
|
20933
|
+
await this.releaseThreadRunLease();
|
|
20934
|
+
this.cancelThreadRunLeaseRetry();
|
|
20935
|
+
}
|
|
20500
20936
|
}
|
|
20501
20937
|
}
|
|
20502
20938
|
async scheduleQueueProcessorRetry(error, generation) {
|
|
@@ -20534,6 +20970,36 @@ var Agent = class {
|
|
|
20534
20970
|
this.queueProcessorRetryAttempt = 0;
|
|
20535
20971
|
this.queueWakeRequested = false;
|
|
20536
20972
|
}
|
|
20973
|
+
/**
|
|
20974
|
+
* Bounded re-attempt after losing the thread-run lease to a peer. Covers the
|
|
20975
|
+
* narrow window where the peer releases the lease without having observed a
|
|
20976
|
+
* just-enqueued message. Bounded so a genuinely long-held thread does not make
|
|
20977
|
+
* this replica poll forever — the owning replica's loop drains new messages.
|
|
20978
|
+
*/
|
|
20979
|
+
scheduleThreadRunLeaseRetry() {
|
|
20980
|
+
if (this.threadRunLeaseRetryTimer || this.threadRunLeaseRetryAttempt >= THREAD_RUN_LEASE_MAX_RETRIES) return;
|
|
20981
|
+
const delay = Math.min(
|
|
20982
|
+
THREAD_RUN_LEASE_RETRY_BASE_MS * 2 ** this.threadRunLeaseRetryAttempt,
|
|
20983
|
+
THREAD_RUN_LEASE_RETRY_CAP_MS
|
|
20984
|
+
);
|
|
20985
|
+
this.threadRunLeaseRetryAttempt += 1;
|
|
20986
|
+
this.threadRunLeaseRetryTimer = setTimeout(() => {
|
|
20987
|
+
this.threadRunLeaseRetryTimer = void 0;
|
|
20988
|
+
void this.startQueueProcessor(false);
|
|
20989
|
+
}, delay);
|
|
20990
|
+
}
|
|
20991
|
+
/**
|
|
20992
|
+
* Clears any pending thread-run lease retry and resets its backoff budget.
|
|
20993
|
+
*
|
|
20994
|
+
* @remarks Called on lease acquisition and on every definitive processor
|
|
20995
|
+
* stop so the next enqueue starts from the base delay. Never called on
|
|
20996
|
+
* continue/re-arm paths, which must preserve the bounded budget.
|
|
20997
|
+
*/
|
|
20998
|
+
cancelThreadRunLeaseRetry() {
|
|
20999
|
+
if (this.threadRunLeaseRetryTimer) clearTimeout(this.threadRunLeaseRetryTimer);
|
|
21000
|
+
this.threadRunLeaseRetryTimer = void 0;
|
|
21001
|
+
this.threadRunLeaseRetryAttempt = 0;
|
|
21002
|
+
}
|
|
20537
21003
|
async runQueueProcessor() {
|
|
20538
21004
|
const store = this.getQueueStore();
|
|
20539
21005
|
const processingMessages = await store.getProcessingMessages(this.thread_id, this.queueScope());
|
|
@@ -20678,6 +21144,38 @@ var Agent = class {
|
|
|
20678
21144
|
console.error(`[Agent] Failed to initialize agent lattice for ${this.assistant_id} (tenant: ${this.tenant_id}):`, error);
|
|
20679
21145
|
throw error;
|
|
20680
21146
|
}
|
|
21147
|
+
let acquiredLeaseHere = false;
|
|
21148
|
+
if (this.threadRunLease === null) {
|
|
21149
|
+
const leaseStore = this.getLeaseStore();
|
|
21150
|
+
if (leaseStore) {
|
|
21151
|
+
const lease = await tryAcquireThreadRun({
|
|
21152
|
+
store: leaseStore,
|
|
21153
|
+
tenantId: this.tenant_id,
|
|
21154
|
+
assistantId: this.assistant_id,
|
|
21155
|
+
threadId: this.thread_id,
|
|
21156
|
+
owner: getReplicaId(),
|
|
21157
|
+
ttlMs: THREAD_RUN_LEASE_TTL_MS,
|
|
21158
|
+
onLost: () => {
|
|
21159
|
+
console.warn(`[Agent] Thread-run lease lost for thread ${this.thread_id}; aborting the held run`);
|
|
21160
|
+
this.abortController?.abort();
|
|
21161
|
+
}
|
|
21162
|
+
});
|
|
21163
|
+
if (!lease) {
|
|
21164
|
+
return { status: await this.getRunStatus(), settled: false, leaseContended: true };
|
|
21165
|
+
}
|
|
21166
|
+
this.threadRunLease = lease;
|
|
21167
|
+
acquiredLeaseHere = true;
|
|
21168
|
+
this.cancelThreadRunLeaseRetry();
|
|
21169
|
+
}
|
|
21170
|
+
}
|
|
21171
|
+
try {
|
|
21172
|
+
return await this.resumeTaskLocked();
|
|
21173
|
+
} finally {
|
|
21174
|
+
if (acquiredLeaseHere && !this.queueProcessorPromise) await this.releaseThreadRunLease();
|
|
21175
|
+
}
|
|
21176
|
+
}
|
|
21177
|
+
/** Recovery body of {@link resumeTask}, executed while thread ownership is settled. */
|
|
21178
|
+
async resumeTaskLocked() {
|
|
20681
21179
|
const store = this.getQueueStore();
|
|
20682
21180
|
const processingMessages = await store.getProcessingMessages(this.thread_id, this.queueScope());
|
|
20683
21181
|
const preRunState = await this.getCurrentState();
|
|
@@ -20793,6 +21291,8 @@ var Agent = class {
|
|
|
20793
21291
|
*/
|
|
20794
21292
|
async abort() {
|
|
20795
21293
|
this.cancelQueueProcessorRetry();
|
|
21294
|
+
this.cancelThreadRunLeaseRetry();
|
|
21295
|
+
await this.releaseThreadRunLease();
|
|
20796
21296
|
this.clearRecoveryBlock();
|
|
20797
21297
|
this.queueProcessorGeneration += 1;
|
|
20798
21298
|
if (this.abortController) {
|
|
@@ -21452,27 +21952,27 @@ function createCheckAsyncTaskTool() {
|
|
|
21452
21952
|
if (!mainAgent) {
|
|
21453
21953
|
return "Cannot access main agent state.";
|
|
21454
21954
|
}
|
|
21455
|
-
const
|
|
21456
|
-
if (!
|
|
21955
|
+
const cached2 = mainAgent.getAsyncTask(task_id);
|
|
21956
|
+
if (!cached2) {
|
|
21457
21957
|
return `Task ${task_id} not found. Use list_async_tasks to see all tasks.`;
|
|
21458
21958
|
}
|
|
21459
21959
|
try {
|
|
21460
21960
|
if (!agentInstanceManager.hasAgent({
|
|
21461
|
-
assistant_id:
|
|
21961
|
+
assistant_id: cached2.assistantId,
|
|
21462
21962
|
thread_id: task_id,
|
|
21463
21963
|
tenant_id: mainAgent.tenant_id
|
|
21464
21964
|
})) {
|
|
21465
|
-
return `Task ${task_id}: not found (may have been cleaned up). Status was: ${
|
|
21965
|
+
return `Task ${task_id}: not found (may have been cleaned up). Status was: ${cached2.status}`;
|
|
21466
21966
|
}
|
|
21467
21967
|
const subAgent = agentInstanceManager.getAgent({
|
|
21468
|
-
assistant_id:
|
|
21968
|
+
assistant_id: cached2.assistantId,
|
|
21469
21969
|
thread_id: task_id,
|
|
21470
21970
|
tenant_id: mainAgent.tenant_id
|
|
21471
21971
|
});
|
|
21472
21972
|
const status = await subAgent.getRunStatus();
|
|
21473
21973
|
if (status === "busy") {
|
|
21474
21974
|
return `Task ${task_id}: still running.
|
|
21475
|
-
Description: ${
|
|
21975
|
+
Description: ${cached2.description}`;
|
|
21476
21976
|
}
|
|
21477
21977
|
if (status === "idle") {
|
|
21478
21978
|
const state = await subAgent.getCurrentState();
|
|
@@ -21483,21 +21983,21 @@ Description: ${cached.description}`;
|
|
|
21483
21983
|
mainAgent.updateAsyncTaskStatus(task_id, "completed");
|
|
21484
21984
|
const result = lastAI?.content ?? "(completed, no output)";
|
|
21485
21985
|
return `Task ${task_id}: COMPLETED.
|
|
21486
|
-
Description: ${
|
|
21986
|
+
Description: ${cached2.description}
|
|
21487
21987
|
Result:
|
|
21488
21988
|
${result}`;
|
|
21489
21989
|
}
|
|
21490
21990
|
if (status === "error") {
|
|
21491
21991
|
mainAgent.updateAsyncTaskStatus(task_id, "failed");
|
|
21492
21992
|
return `Task ${task_id}: failed.
|
|
21493
|
-
Description: ${
|
|
21993
|
+
Description: ${cached2.description}`;
|
|
21494
21994
|
}
|
|
21495
21995
|
if (status === "interrupted") {
|
|
21496
21996
|
return `Task ${task_id}: interrupted (waiting for input).
|
|
21497
|
-
Description: ${
|
|
21997
|
+
Description: ${cached2.description}`;
|
|
21498
21998
|
}
|
|
21499
21999
|
return `Task ${task_id}: ${status}.
|
|
21500
|
-
Description: ${
|
|
22000
|
+
Description: ${cached2.description}`;
|
|
21501
22001
|
} catch (err) {
|
|
21502
22002
|
return `Task ${task_id}: error checking status: ${err instanceof Error ? err.message : String(err)}`;
|
|
21503
22003
|
}
|
|
@@ -21570,25 +22070,25 @@ function createCancelAsyncTaskTool() {
|
|
|
21570
22070
|
if (!mainAgent) {
|
|
21571
22071
|
return "Cannot access main agent state.";
|
|
21572
22072
|
}
|
|
21573
|
-
const
|
|
21574
|
-
if (!
|
|
22073
|
+
const cached2 = mainAgent.getAsyncTask(task_id);
|
|
22074
|
+
if (!cached2) {
|
|
21575
22075
|
return `Task ${task_id} not found.`;
|
|
21576
22076
|
}
|
|
21577
22077
|
try {
|
|
21578
22078
|
const subAgentExists = agentInstanceManager.hasAgent({
|
|
21579
|
-
assistant_id:
|
|
22079
|
+
assistant_id: cached2.assistantId,
|
|
21580
22080
|
thread_id: task_id,
|
|
21581
22081
|
tenant_id: mainAgent.tenant_id
|
|
21582
22082
|
});
|
|
21583
22083
|
if (subAgentExists) {
|
|
21584
22084
|
const subAgent = agentInstanceManager.getAgent({
|
|
21585
|
-
assistant_id:
|
|
22085
|
+
assistant_id: cached2.assistantId,
|
|
21586
22086
|
thread_id: task_id,
|
|
21587
22087
|
tenant_id: mainAgent.tenant_id
|
|
21588
22088
|
});
|
|
21589
22089
|
await subAgent.abort();
|
|
21590
22090
|
agentInstanceManager.removeAgent({
|
|
21591
|
-
assistant_id:
|
|
22091
|
+
assistant_id: cached2.assistantId,
|
|
21592
22092
|
thread_id: task_id,
|
|
21593
22093
|
tenant_id: mainAgent.tenant_id
|
|
21594
22094
|
});
|
|
@@ -21831,6 +22331,48 @@ var MemoryScheduleStorage = class {
|
|
|
21831
22331
|
});
|
|
21832
22332
|
}
|
|
21833
22333
|
}
|
|
22334
|
+
/**
|
|
22335
|
+
* Atomically claims one due fire by transitioning the task `pending -> running`.
|
|
22336
|
+
*
|
|
22337
|
+
* @param taskId Task to claim.
|
|
22338
|
+
* @returns True when this caller won the claim (task was `pending`); false if
|
|
22339
|
+
* another replica already claimed it or it is not pending.
|
|
22340
|
+
*/
|
|
22341
|
+
async claimScheduledRun(taskId) {
|
|
22342
|
+
const task = this.tasks.get(taskId);
|
|
22343
|
+
if (!task || task.status !== import_protocols11.ScheduledTaskStatus.PENDING) {
|
|
22344
|
+
return false;
|
|
22345
|
+
}
|
|
22346
|
+
this.tasks.set(taskId, {
|
|
22347
|
+
...task,
|
|
22348
|
+
status: import_protocols11.ScheduledTaskStatus.RUNNING,
|
|
22349
|
+
updatedAt: Date.now()
|
|
22350
|
+
});
|
|
22351
|
+
return true;
|
|
22352
|
+
}
|
|
22353
|
+
/**
|
|
22354
|
+
* Requeues `running` tasks whose `updatedAt` is older than `olderThanMs` back
|
|
22355
|
+
* to `pending` (recovery after a crash that left a claim unsettled).
|
|
22356
|
+
*
|
|
22357
|
+
* @param olderThanMs Age threshold in milliseconds.
|
|
22358
|
+
* @returns The number of tasks requeued.
|
|
22359
|
+
*/
|
|
22360
|
+
async requeueStaleRunning(olderThanMs) {
|
|
22361
|
+
const now = Date.now();
|
|
22362
|
+
const cutoff = now - olderThanMs;
|
|
22363
|
+
let requeued = 0;
|
|
22364
|
+
for (const [taskId, task] of this.tasks.entries()) {
|
|
22365
|
+
if (task.status === import_protocols11.ScheduledTaskStatus.RUNNING && task.updatedAt < cutoff) {
|
|
22366
|
+
this.tasks.set(taskId, {
|
|
22367
|
+
...task,
|
|
22368
|
+
status: import_protocols11.ScheduledTaskStatus.PENDING,
|
|
22369
|
+
updatedAt: now
|
|
22370
|
+
});
|
|
22371
|
+
requeued++;
|
|
22372
|
+
}
|
|
22373
|
+
}
|
|
22374
|
+
return requeued;
|
|
22375
|
+
}
|
|
21834
22376
|
/**
|
|
21835
22377
|
* Delete task
|
|
21836
22378
|
*/
|
|
@@ -22195,6 +22737,7 @@ function describeCronExpression(expression) {
|
|
|
22195
22737
|
}
|
|
22196
22738
|
|
|
22197
22739
|
// src/schedule_lattice/DefaultScheduleClient.ts
|
|
22740
|
+
var STALE_RUNNING_MS = 30 * 6e4;
|
|
22198
22741
|
var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
22199
22742
|
constructor(storage) {
|
|
22200
22743
|
this.handlers = /* @__PURE__ */ new Map();
|
|
@@ -22435,6 +22978,19 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
22435
22978
|
}
|
|
22436
22979
|
// ===== Recovery =====
|
|
22437
22980
|
async restore() {
|
|
22981
|
+
try {
|
|
22982
|
+
const requeued = await this.storage.requeueStaleRunning(STALE_RUNNING_MS);
|
|
22983
|
+
if (requeued > 0) {
|
|
22984
|
+
console.log(
|
|
22985
|
+
`[Scheduler] Requeued ${requeued} stale running task(s)`
|
|
22986
|
+
);
|
|
22987
|
+
}
|
|
22988
|
+
} catch (error) {
|
|
22989
|
+
console.error(
|
|
22990
|
+
"[Scheduler] Failed to requeue stale running tasks:",
|
|
22991
|
+
error
|
|
22992
|
+
);
|
|
22993
|
+
}
|
|
22438
22994
|
const activeTasks = await this.storage.getActiveTasks();
|
|
22439
22995
|
let restored = 0;
|
|
22440
22996
|
for (const task of activeTasks) {
|
|
@@ -22495,6 +23051,16 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
22495
23051
|
});
|
|
22496
23052
|
}
|
|
22497
23053
|
async executeTask(task) {
|
|
23054
|
+
let claimed = false;
|
|
23055
|
+
try {
|
|
23056
|
+
claimed = await this.storage.claimScheduledRun(task.taskId);
|
|
23057
|
+
} catch (error) {
|
|
23058
|
+
console.error(`[Scheduler] Failed to claim task ${task.taskId}:`, error);
|
|
23059
|
+
return;
|
|
23060
|
+
}
|
|
23061
|
+
if (!claimed) {
|
|
23062
|
+
return;
|
|
23063
|
+
}
|
|
22498
23064
|
const handler = this.handlers.get(task.taskType);
|
|
22499
23065
|
if (!handler) {
|
|
22500
23066
|
console.error(
|
|
@@ -22506,9 +23072,6 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
22506
23072
|
});
|
|
22507
23073
|
return;
|
|
22508
23074
|
}
|
|
22509
|
-
await this.storage.update(task.taskId, {
|
|
22510
|
-
status: import_protocols12.ScheduledTaskStatus.RUNNING
|
|
22511
|
-
});
|
|
22512
23075
|
console.log(`[Scheduler] Executing task: ${task.taskId}`);
|
|
22513
23076
|
try {
|
|
22514
23077
|
const latestTask = await this.storage.get(task.taskId);
|
|
@@ -27232,8 +27795,8 @@ var VectorStoreProviderManager = class _VectorStoreProviderManager extends BaseL
|
|
|
27232
27795
|
* @param key Provider key name
|
|
27233
27796
|
* @param provider VectorStoreProvider implementation
|
|
27234
27797
|
*/
|
|
27235
|
-
registerProvider(key5,
|
|
27236
|
-
const lattice = { key: key5, provider };
|
|
27798
|
+
registerProvider(key5, provider2) {
|
|
27799
|
+
const lattice = { key: key5, provider: provider2 };
|
|
27237
27800
|
this.registerWithTenant("default", key5, lattice);
|
|
27238
27801
|
}
|
|
27239
27802
|
/**
|
|
@@ -27269,7 +27832,7 @@ var VectorStoreProviderManager = class _VectorStoreProviderManager extends BaseL
|
|
|
27269
27832
|
};
|
|
27270
27833
|
var vectorStoreProviderManager = VectorStoreProviderManager.getInstance();
|
|
27271
27834
|
vectorStoreProviderManager.registerProvider("default", new MemoryVectorStoreProvider());
|
|
27272
|
-
var registerVectorStoreProvider = (key5,
|
|
27835
|
+
var registerVectorStoreProvider = (key5, provider2) => vectorStoreProviderManager.registerProvider(key5, provider2);
|
|
27273
27836
|
var getVectorStoreProvider = (key5) => vectorStoreProviderManager.getProvider(key5);
|
|
27274
27837
|
|
|
27275
27838
|
// src/store_lattice/configureStores.ts
|
|
@@ -29971,7 +30534,110 @@ independently before the workflow's integration eval.
|
|
|
29971
30534
|
|
|
29972
30535
|
An unsupported architecture conversion interrupts the flow and requests a new
|
|
29973
30536
|
user decision. Do not route backward to the Charter or to [[agent-build]], and do
|
|
29974
|
-
not create a replacement
|
|
30537
|
+
not create a replacement.`,
|
|
30538
|
+
"ptc": `---
|
|
30539
|
+
name: ptc
|
|
30540
|
+
description: Programmatic Tool Calling (PTC) \u2014 write sandbox code that discovers and calls platform Open capabilities (MCP tools) through the gateway. Use when orchestration is multi-step, data-heavy, or needs loops/branches across platform tools instead of one-at-a-time model tool calls.
|
|
30541
|
+
metadata:
|
|
30542
|
+
role: workflow
|
|
30543
|
+
domain: orchestration
|
|
30544
|
+
verified: unverified
|
|
30545
|
+
---
|
|
30546
|
+
|
|
30547
|
+
# Programmatic Tool Calling (PTC)
|
|
30548
|
+
|
|
30549
|
+
PTC means the model writes and runs code that calls platform tools itself, instead
|
|
30550
|
+
of calling tools one at a time. Reach for it when orchestration is multi-step,
|
|
30551
|
+
data-heavy, or needs a loop/branch that would be wasteful as a chain of model tool
|
|
30552
|
+
calls.
|
|
30553
|
+
|
|
30554
|
+
## Where the code runs
|
|
30555
|
+
|
|
30556
|
+
Run the code with \`code_eval\` (backed by \`shell_exec\`). Each execution process is
|
|
30557
|
+
injected with two environment variables:
|
|
30558
|
+
|
|
30559
|
+
- \`API_GATEWAY_URL\` \u2014 the gateway base URL.
|
|
30560
|
+
- \`OPEN_API_TOKEN\` \u2014 a short-lived bearer token **self-bound to this agent**. It is
|
|
30561
|
+
not reusable elsewhere.
|
|
30562
|
+
|
|
30563
|
+
The token already encodes this agent's authority: the platform reflects the agent's
|
|
30564
|
+
own configured middleware into Open grants, plus a small always-on baseline
|
|
30565
|
+
(\`kb\` read-only and \`sandbox:self\`). So the callable set = that baseline \u222A the
|
|
30566
|
+
domains your configured middleware exposes \u2014 and nothing beyond it.
|
|
30567
|
+
|
|
30568
|
+
## Client
|
|
30569
|
+
|
|
30570
|
+
The sandbox must have the zero-dependency \`@axiom-lattice/open-mcp-client\` package.
|
|
30571
|
+
Get it one of two ways:
|
|
30572
|
+
|
|
30573
|
+
- **Preinstalled in the sandbox image** (recommended): \`open-mcp\` is on \`PATH\`; for
|
|
30574
|
+
\`require("@axiom-lattice/open-mcp-client")\` to resolve, install it into the working
|
|
30575
|
+
directory or point \`NODE_PATH\` at the global \`node_modules\`.
|
|
30576
|
+
- **Install it in this run** when the sandbox has network + npm:
|
|
30577
|
+
|
|
30578
|
+
\`\`\`bash
|
|
30579
|
+
npm install @axiom-lattice/open-mcp-client
|
|
30580
|
+
# or use without installing:
|
|
30581
|
+
npx @axiom-lattice/open-mcp-client tools list --json
|
|
30582
|
+
\`\`\`
|
|
30583
|
+
|
|
30584
|
+
\`\`\`js
|
|
30585
|
+
const { OpenMcpClient } = require("@axiom-lattice/open-mcp-client");
|
|
30586
|
+
const client = OpenMcpClient.fromEnv(); // reads API_GATEWAY_URL + OPEN_API_TOKEN
|
|
30587
|
+
\`\`\`
|
|
30588
|
+
|
|
30589
|
+
CLI equivalents (config comes from the same env vars):
|
|
30590
|
+
|
|
30591
|
+
\`\`\`bash
|
|
30592
|
+
open-mcp tools list --json
|
|
30593
|
+
open-mcp tools call kb_search --json '{"query":"refund policy"}'
|
|
30594
|
+
\`\`\`
|
|
30595
|
+
|
|
30596
|
+
## Discover, then call
|
|
30597
|
+
|
|
30598
|
+
1. **Discover first.** Call \`await client.listTools()\`. This returns exactly the
|
|
30599
|
+
tools this agent is authorized to call (the server filters by the token's grants
|
|
30600
|
+
on every request, so it is the source of truth).
|
|
30601
|
+
2. **Only call discovered tools.** Pick a tool from that list and call
|
|
30602
|
+
\`await client.callTool(name, args)\` with args matching the tool's \`inputSchema\`.
|
|
30603
|
+
3. **Print the final result as JSON to stdout** so the calling agent can consume it.
|
|
30604
|
+
Keep intermediate logs minimal.
|
|
30605
|
+
|
|
30606
|
+
An unconfigured domain isn't registered, so calling it returns an \`isError\`
|
|
30607
|
+
tool-not-found result; a registered tool refused by the token's grants surfaces
|
|
30608
|
+
\`GRANT_DENIED\`. Either way the capability is **not configured for this agent**.
|
|
30609
|
+
Do not retry or work around it \u2014 drop that step or tell the user which
|
|
30610
|
+
middleware/domain must be enabled. A denied call is expected behavior, not a
|
|
30611
|
+
transient failure.
|
|
30612
|
+
|
|
30613
|
+
## Tips
|
|
30614
|
+
|
|
30615
|
+
- Fan out with \`Promise.all\` over many items instead of many sequential model turns;
|
|
30616
|
+
that is the main win of PTC.
|
|
30617
|
+
- Inspect \`tool.inputSchema\` before calling to avoid schema-validation errors.
|
|
30618
|
+
- Reduce large results in code and return only the fields the agent needs.
|
|
30619
|
+
- The token is short-lived; for very long jobs re-read the env per \`code_eval\` run
|
|
30620
|
+
rather than caching the token in a file.
|
|
30621
|
+
|
|
30622
|
+
## Worked example
|
|
30623
|
+
|
|
30624
|
+
\`\`\`js
|
|
30625
|
+
const { OpenMcpClient } = require("@axiom-lattice/open-mcp-client");
|
|
30626
|
+
|
|
30627
|
+
async function main() {
|
|
30628
|
+
const client = OpenMcpClient.fromEnv(); // API_GATEWAY_URL + OPEN_API_TOKEN
|
|
30629
|
+
const tools = await client.listTools(); // exactly what this agent may call
|
|
30630
|
+
const pick = tools.find((t) => t.name === "kb_search") ?? tools[0];
|
|
30631
|
+
const out = await client.callTool(pick.name, { query: "refund policy" });
|
|
30632
|
+
console.log(JSON.stringify({ called: pick.name, result: out.json() }));
|
|
30633
|
+
}
|
|
30634
|
+
|
|
30635
|
+
main().catch((err) => { console.error(String(err)); process.exit(1); });
|
|
30636
|
+
\`\`\`
|
|
30637
|
+
|
|
30638
|
+
Run this in \`code_eval\`. The first run proves env + client wiring; then extend it
|
|
30639
|
+
into the real fan-out/aggregation the task needs.
|
|
30640
|
+
`
|
|
29975
30641
|
};
|
|
29976
30642
|
function getBuiltInSkillMeta(name) {
|
|
29977
30643
|
const content = BUILTIN_SKILLS[name];
|
|
@@ -33105,9 +33771,9 @@ async function getOrCreateCollectionVectorStore(name, embeddingKey, tenantId2, p
|
|
|
33105
33771
|
const pendingInitialization = pendingVectorStoreInitializations.get(storeKey);
|
|
33106
33772
|
if (pendingInitialization) return pendingInitialization;
|
|
33107
33773
|
const initialization = (async () => {
|
|
33108
|
-
const
|
|
33774
|
+
const provider2 = vectorStoreProviderManager.getProvider(providerKey);
|
|
33109
33775
|
const tableName = buildTableName(tenantId2, name);
|
|
33110
|
-
const vectorStore = await
|
|
33776
|
+
const vectorStore = await provider2.create({ tableName, embeddingKey });
|
|
33111
33777
|
vectorStoreLatticeManager.registerLattice(storeKey, vectorStore);
|
|
33112
33778
|
return vectorStore;
|
|
33113
33779
|
})();
|
|
@@ -33125,9 +33791,9 @@ async function getCollectionEntryCount(name, embeddingKey, tenantId2) {
|
|
|
33125
33791
|
return vs.getDocumentCount();
|
|
33126
33792
|
}
|
|
33127
33793
|
try {
|
|
33128
|
-
const
|
|
33129
|
-
if (
|
|
33130
|
-
return
|
|
33794
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
33795
|
+
if (provider2.getEntryCount) {
|
|
33796
|
+
return provider2.getEntryCount(buildTableName(tenantId2, name));
|
|
33131
33797
|
}
|
|
33132
33798
|
} catch {
|
|
33133
33799
|
}
|
|
@@ -33139,9 +33805,9 @@ async function listCollectionEntries(name, embeddingKey, tenantId2) {
|
|
|
33139
33805
|
return vs.getAllDocuments();
|
|
33140
33806
|
}
|
|
33141
33807
|
try {
|
|
33142
|
-
const
|
|
33143
|
-
if (
|
|
33144
|
-
return
|
|
33808
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
33809
|
+
if (provider2.listEntries) {
|
|
33810
|
+
return provider2.listEntries(buildTableName(tenantId2, name));
|
|
33145
33811
|
}
|
|
33146
33812
|
} catch {
|
|
33147
33813
|
}
|
|
@@ -33151,9 +33817,9 @@ async function removeCollectionVectorStore(name, tenantId2) {
|
|
|
33151
33817
|
const storeKey = buildKey(tenantId2, name);
|
|
33152
33818
|
const tableName = buildTableName(tenantId2, name);
|
|
33153
33819
|
try {
|
|
33154
|
-
const
|
|
33155
|
-
if (
|
|
33156
|
-
await
|
|
33820
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
33821
|
+
if (provider2.dropTable) {
|
|
33822
|
+
await provider2.dropTable(tableName);
|
|
33157
33823
|
}
|
|
33158
33824
|
} catch {
|
|
33159
33825
|
}
|
|
@@ -33885,7 +34551,7 @@ function parseRecursiveGrepOutput(output) {
|
|
|
33885
34551
|
}
|
|
33886
34552
|
|
|
33887
34553
|
// src/sandbox_lattice/packDirectory.ts
|
|
33888
|
-
var
|
|
34554
|
+
var import_node_crypto6 = require("crypto");
|
|
33889
34555
|
var posix2 = __toESM(require("path/posix"));
|
|
33890
34556
|
var MAX_PACK_ENTRIES = 1e4;
|
|
33891
34557
|
var MAX_PACK_FILE_BYTES = 100 * 1024 * 1024;
|
|
@@ -33911,7 +34577,7 @@ function buildRemotePackDirectoryCommand(parentDir, sourceName, archiveName) {
|
|
|
33911
34577
|
const parent = quotePosixShellArg(parentDir);
|
|
33912
34578
|
const name = quotePosixShellArg(sourceName);
|
|
33913
34579
|
const lock = quotePosixShellArg(`.${archiveName}.lock`);
|
|
33914
|
-
const tempDir = quotePosixShellArg(`.${archiveName}.tmp-${(0,
|
|
34580
|
+
const tempDir = quotePosixShellArg(`.${archiveName}.tmp-${(0, import_node_crypto6.randomBytes)(16).toString("hex")}`);
|
|
33915
34581
|
const archivePath = joinPhysicalPath(parentDir, archiveName);
|
|
33916
34582
|
const archive = quotePosixShellArg(archivePath);
|
|
33917
34583
|
return [
|
|
@@ -35469,12 +36135,12 @@ var DaytonaProvider = class {
|
|
|
35469
36135
|
|
|
35470
36136
|
// src/sandbox_lattice/providers/LocalSandboxProvider.ts
|
|
35471
36137
|
var path6 = __toESM(require("path"));
|
|
35472
|
-
var
|
|
36138
|
+
var os2 = __toESM(require("os"));
|
|
35473
36139
|
var fs4 = __toESM(require("fs/promises"));
|
|
35474
36140
|
|
|
35475
36141
|
// src/sandbox_lattice/LocalSandboxInstance.ts
|
|
35476
36142
|
var import_node_child_process = require("child_process");
|
|
35477
|
-
var
|
|
36143
|
+
var import_node_crypto7 = require("crypto");
|
|
35478
36144
|
var fs3 = __toESM(require("fs/promises"));
|
|
35479
36145
|
var path5 = __toESM(require("path"));
|
|
35480
36146
|
var posix5 = __toESM(require("path/posix"));
|
|
@@ -35496,6 +36162,32 @@ function assertRegularDeleteTarget(file, stat4) {
|
|
|
35496
36162
|
function quoteShellArgument(value) {
|
|
35497
36163
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
35498
36164
|
}
|
|
36165
|
+
var PLATFORM_SECRET_ENV_VARS = [
|
|
36166
|
+
"OPEN_TOKEN_SECRET",
|
|
36167
|
+
"AUTH_TOKEN_SECRET",
|
|
36168
|
+
"JWT_SECRET",
|
|
36169
|
+
"WEB_APP_ATTACHMENT_SECRET",
|
|
36170
|
+
"LATTICE_ENCRYPTION_KEY",
|
|
36171
|
+
"DATABASE_URL",
|
|
36172
|
+
"REDIS_PASSWORD",
|
|
36173
|
+
"MICROSANDBOX_API_KEY",
|
|
36174
|
+
"DAYTONA_API_KEY",
|
|
36175
|
+
"E2B_API_KEY",
|
|
36176
|
+
"OPENAI_API_KEY",
|
|
36177
|
+
"AZURE_OPENAI_API_KEY",
|
|
36178
|
+
"ANTHROPIC_API_KEY",
|
|
36179
|
+
"TAVILY_API_KEY",
|
|
36180
|
+
"VAPID_PRIVATE_KEY",
|
|
36181
|
+
"SUPABASE_KEY",
|
|
36182
|
+
"A2A_API_KEYS"
|
|
36183
|
+
];
|
|
36184
|
+
function stripPlatformSecrets(env) {
|
|
36185
|
+
const rest = { ...env };
|
|
36186
|
+
for (const name of PLATFORM_SECRET_ENV_VARS) {
|
|
36187
|
+
delete rest[name];
|
|
36188
|
+
}
|
|
36189
|
+
return rest;
|
|
36190
|
+
}
|
|
35499
36191
|
function validatePackEntryName(name) {
|
|
35500
36192
|
if (!name || name === "." || name === ".." || name.includes("\\") || name.includes("/")) {
|
|
35501
36193
|
throw new Error(`Cannot pack: unsafe entry name '${name}'`);
|
|
@@ -35668,7 +36360,7 @@ var LocalSandboxInstance = class {
|
|
|
35668
36360
|
timeout: timeoutMs,
|
|
35669
36361
|
maxBuffer: 10 * 1024 * 1024,
|
|
35670
36362
|
// 10MB
|
|
35671
|
-
env: { ...process.env, HOME: this.rootDir }
|
|
36363
|
+
env: stripPlatformSecrets({ ...process.env, HOME: this.rootDir })
|
|
35672
36364
|
}
|
|
35673
36365
|
);
|
|
35674
36366
|
const output = stderr ? `${stdout}
|
|
@@ -35794,7 +36486,7 @@ ${errOut}`.trim() : out.trim();
|
|
|
35794
36486
|
};
|
|
35795
36487
|
await preflight(sourceHost);
|
|
35796
36488
|
const lockName = `.${filename}.lock`;
|
|
35797
|
-
const tempDirectoryName = `.${filename}.tmp-${(0,
|
|
36489
|
+
const tempDirectoryName = `.${filename}.tmp-${(0, import_node_crypto7.randomBytes)(16).toString("hex")}`;
|
|
35798
36490
|
const sourceOperand = `./${rootName}`;
|
|
35799
36491
|
tempDirectoryHost = path5.join(realArchiveDirectory, tempDirectoryName);
|
|
35800
36492
|
tempHost = path5.join(tempDirectoryHost, "archive.zip");
|
|
@@ -35933,7 +36625,7 @@ var LocalSandboxProvider = class {
|
|
|
35933
36625
|
this.instances = /* @__PURE__ */ new Map();
|
|
35934
36626
|
this.creating = /* @__PURE__ */ new Map();
|
|
35935
36627
|
this.createResourceAddress = createResourceAddress;
|
|
35936
|
-
this.basePath = config.basePath ?? path6.join(
|
|
36628
|
+
this.basePath = config.basePath ?? path6.join(os2.homedir(), ".axiom-local-sandbox");
|
|
35937
36629
|
}
|
|
35938
36630
|
async createSandbox(name, _config) {
|
|
35939
36631
|
const existing = this.instances.get(name);
|
|
@@ -37309,6 +38001,10 @@ var TaskLifecycleNotifier = class {
|
|
|
37309
38001
|
this.listeners = /* @__PURE__ */ new Set();
|
|
37310
38002
|
this.tails = /* @__PURE__ */ new Map();
|
|
37311
38003
|
}
|
|
38004
|
+
/** Installs (or clears) the durable outbox used to fan notifications to other replicas. */
|
|
38005
|
+
setOutbox(outbox2) {
|
|
38006
|
+
this.outbox = outbox2;
|
|
38007
|
+
}
|
|
37312
38008
|
/**
|
|
37313
38009
|
* Registers an async lifecycle listener.
|
|
37314
38010
|
*
|
|
@@ -37329,6 +38025,25 @@ var TaskLifecycleNotifier = class {
|
|
|
37329
38025
|
* @throws Error when the event is malformed or one or more listeners reject.
|
|
37330
38026
|
*/
|
|
37331
38027
|
async publish(event) {
|
|
38028
|
+
const snapshot = snapshotNotification(event);
|
|
38029
|
+
const key5 = `${snapshot.tenantId}:${snapshot.taskId}`;
|
|
38030
|
+
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
38031
|
+
const delivery = previous.catch(() => void 0).then(() => this.deliver(snapshot));
|
|
38032
|
+
this.tails.set(key5, delivery);
|
|
38033
|
+
if (this.outbox) {
|
|
38034
|
+
try {
|
|
38035
|
+
await this.outbox.append({ topic: "task-lifecycle", payload: snapshot, originReplicaId: getReplicaId() });
|
|
38036
|
+
} catch {
|
|
38037
|
+
}
|
|
38038
|
+
}
|
|
38039
|
+
try {
|
|
38040
|
+
await delivery;
|
|
38041
|
+
} finally {
|
|
38042
|
+
if (this.tails.get(key5) === delivery) this.tails.delete(key5);
|
|
38043
|
+
}
|
|
38044
|
+
}
|
|
38045
|
+
/** Delivers one outbox payload to local listeners without re-appending (poller path). */
|
|
38046
|
+
async deliverFromOutbox(event) {
|
|
37332
38047
|
const snapshot = snapshotNotification(event);
|
|
37333
38048
|
const key5 = `${snapshot.tenantId}:${snapshot.taskId}`;
|
|
37334
38049
|
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
@@ -37393,6 +38108,10 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
37393
38108
|
if (!Number.isSafeInteger(timeout) || timeout <= 0) throw new Error("Invalid admission listener timeout");
|
|
37394
38109
|
this.listenerTimeoutMs = timeout;
|
|
37395
38110
|
}
|
|
38111
|
+
/** Installs (or clears) the durable outbox used to fan notifications to other replicas. */
|
|
38112
|
+
setOutbox(outbox2) {
|
|
38113
|
+
this.outbox = outbox2;
|
|
38114
|
+
}
|
|
37396
38115
|
/**
|
|
37397
38116
|
* Registers a Project task admission listener.
|
|
37398
38117
|
*
|
|
@@ -37412,6 +38131,30 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
37412
38131
|
* @returns A promise settled after every snapshotted listener settles.
|
|
37413
38132
|
*/
|
|
37414
38133
|
async publish(event) {
|
|
38134
|
+
const snapshot = snapshotNotification2(event);
|
|
38135
|
+
const listeners = [...this.listeners];
|
|
38136
|
+
const key5 = `${snapshot.tenantId}\0${snapshot.taskId}`;
|
|
38137
|
+
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
38138
|
+
const delivery = previous.catch(() => void 0).then(() => this.deliver(snapshot, listeners));
|
|
38139
|
+
this.tails.set(key5, delivery);
|
|
38140
|
+
if (this.outbox) {
|
|
38141
|
+
try {
|
|
38142
|
+
await this.outbox.append({
|
|
38143
|
+
topic: "project-task-admission",
|
|
38144
|
+
payload: snapshot,
|
|
38145
|
+
originReplicaId: getReplicaId()
|
|
38146
|
+
});
|
|
38147
|
+
} catch {
|
|
38148
|
+
}
|
|
38149
|
+
}
|
|
38150
|
+
try {
|
|
38151
|
+
await delivery;
|
|
38152
|
+
} finally {
|
|
38153
|
+
if (this.tails.get(key5) === delivery) this.tails.delete(key5);
|
|
38154
|
+
}
|
|
38155
|
+
}
|
|
38156
|
+
/** Delivers one outbox payload to local listeners without re-appending (poller path). */
|
|
38157
|
+
async deliverFromOutbox(event) {
|
|
37415
38158
|
const snapshot = snapshotNotification2(event);
|
|
37416
38159
|
const listeners = [...this.listeners];
|
|
37417
38160
|
const key5 = `${snapshot.tenantId}\0${snapshot.taskId}`;
|
|
@@ -37481,8 +38224,137 @@ function canonicalTimestamp(value) {
|
|
|
37481
38224
|
return Number.isFinite(parsed.getTime()) && parsed.toISOString() === value;
|
|
37482
38225
|
}
|
|
37483
38226
|
|
|
38227
|
+
// src/services/OutboxPoller.ts
|
|
38228
|
+
var OutboxPoller = class {
|
|
38229
|
+
/**
|
|
38230
|
+
* Creates a poller bound to one durable outbox.
|
|
38231
|
+
*
|
|
38232
|
+
* @param deps Store, owner replica id, topic handlers, and optional tuning.
|
|
38233
|
+
*/
|
|
38234
|
+
constructor(deps) {
|
|
38235
|
+
this.deps = deps;
|
|
38236
|
+
this.cursor = null;
|
|
38237
|
+
this.polling = false;
|
|
38238
|
+
}
|
|
38239
|
+
/** Captures the starting cursor and begins polling. */
|
|
38240
|
+
async start() {
|
|
38241
|
+
this.cursor = await this.deps.store.latestId();
|
|
38242
|
+
this.timer = setInterval(() => {
|
|
38243
|
+
void this.pollOnce();
|
|
38244
|
+
}, this.deps.intervalMs ?? 1e3);
|
|
38245
|
+
this.timer.unref?.();
|
|
38246
|
+
}
|
|
38247
|
+
/** Stops polling. */
|
|
38248
|
+
stop() {
|
|
38249
|
+
if (this.timer) clearInterval(this.timer);
|
|
38250
|
+
this.timer = void 0;
|
|
38251
|
+
}
|
|
38252
|
+
/** Runs one drain pass (exported for tests). */
|
|
38253
|
+
async pollOnce() {
|
|
38254
|
+
if (this.polling) return;
|
|
38255
|
+
this.polling = true;
|
|
38256
|
+
try {
|
|
38257
|
+
const batchSize = this.deps.batchSize ?? 100;
|
|
38258
|
+
for (; ; ) {
|
|
38259
|
+
const events = await this.deps.store.listAfter(this.cursor, batchSize);
|
|
38260
|
+
if (events.length === 0) break;
|
|
38261
|
+
for (const event of events) {
|
|
38262
|
+
this.cursor = event.id;
|
|
38263
|
+
if (event.originReplicaId === this.deps.owner) continue;
|
|
38264
|
+
const handler = this.deps.handlers[event.topic];
|
|
38265
|
+
if (!handler) continue;
|
|
38266
|
+
try {
|
|
38267
|
+
await this.deliverWithTimeout(handler, event.payload);
|
|
38268
|
+
} catch {
|
|
38269
|
+
this.deps.log?.warn("Outbox delivery failed", { topic: event.topic, id: event.id });
|
|
38270
|
+
}
|
|
38271
|
+
}
|
|
38272
|
+
if (events.length < batchSize) break;
|
|
38273
|
+
}
|
|
38274
|
+
} catch (error) {
|
|
38275
|
+
this.deps.log?.warn("Outbox poll failed", { error: error instanceof Error ? error.message : String(error) });
|
|
38276
|
+
} finally {
|
|
38277
|
+
this.polling = false;
|
|
38278
|
+
}
|
|
38279
|
+
}
|
|
38280
|
+
/**
|
|
38281
|
+
* Runs one handler bounded by `handlerTimeoutMs` so a hung listener cannot
|
|
38282
|
+
* stall cross-replica delivery for this replica.
|
|
38283
|
+
*/
|
|
38284
|
+
async deliverWithTimeout(handler, payload) {
|
|
38285
|
+
const timeoutMs = this.deps.handlerTimeoutMs ?? 5e3;
|
|
38286
|
+
let timer;
|
|
38287
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
38288
|
+
timer = setTimeout(() => reject(new Error("Outbox handler timed out")), timeoutMs);
|
|
38289
|
+
timer.unref?.();
|
|
38290
|
+
});
|
|
38291
|
+
try {
|
|
38292
|
+
await Promise.race([Promise.resolve().then(() => handler(payload)), timeout]);
|
|
38293
|
+
} finally {
|
|
38294
|
+
if (timer) clearTimeout(timer);
|
|
38295
|
+
}
|
|
38296
|
+
}
|
|
38297
|
+
};
|
|
38298
|
+
|
|
37484
38299
|
// src/services/ProjectMutationMutex.ts
|
|
37485
38300
|
var import_protocols28 = require("@axiom-lattice/protocols");
|
|
38301
|
+
|
|
38302
|
+
// src/services/coordinationLease.ts
|
|
38303
|
+
var configured;
|
|
38304
|
+
function configureCoordinationLeaseStore(store) {
|
|
38305
|
+
configured = store;
|
|
38306
|
+
}
|
|
38307
|
+
function getCoordinationLeaseStore() {
|
|
38308
|
+
return configured;
|
|
38309
|
+
}
|
|
38310
|
+
|
|
38311
|
+
// src/services/withLease.ts
|
|
38312
|
+
var import_node_crypto8 = require("crypto");
|
|
38313
|
+
var LeaseAcquisitionTimeoutError = class extends Error {
|
|
38314
|
+
/**
|
|
38315
|
+
* @param key Lease key that could not be acquired.
|
|
38316
|
+
* @param holder Unique holder that attempted acquisition.
|
|
38317
|
+
* @param timeoutMs How long the caller waited before giving up.
|
|
38318
|
+
*/
|
|
38319
|
+
constructor(key5, holder, timeoutMs) {
|
|
38320
|
+
super(`Could not acquire lease '${key5}' for '${holder}' within ${timeoutMs}ms`);
|
|
38321
|
+
this.key = key5;
|
|
38322
|
+
this.holder = holder;
|
|
38323
|
+
this.timeoutMs = timeoutMs;
|
|
38324
|
+
/** Stable machine-readable code. */
|
|
38325
|
+
this.code = "LEASE_ACQUISITION_TIMEOUT";
|
|
38326
|
+
this.name = "LeaseAcquisitionTimeoutError";
|
|
38327
|
+
}
|
|
38328
|
+
};
|
|
38329
|
+
function sleep(ms) {
|
|
38330
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
38331
|
+
}
|
|
38332
|
+
async function withLease(store, key5, ownerLabel, fn, options = {}) {
|
|
38333
|
+
const ttlMs = options.ttlMs ?? 3e4;
|
|
38334
|
+
const acquireTimeoutMs = options.acquireTimeoutMs ?? 1e4;
|
|
38335
|
+
const retryDelayMs = options.retryDelayMs ?? 50;
|
|
38336
|
+
const heartbeatMs = options.heartbeatMs ?? Math.max(1e3, Math.floor(ttlMs / 3));
|
|
38337
|
+
const holder = `${ownerLabel}#${(0, import_node_crypto8.randomUUID)()}`;
|
|
38338
|
+
const deadline = Date.now() + acquireTimeoutMs;
|
|
38339
|
+
for (; ; ) {
|
|
38340
|
+
if (await store.tryAcquire(key5, holder, ttlMs)) break;
|
|
38341
|
+
if (Date.now() >= deadline) throw new LeaseAcquisitionTimeoutError(key5, holder, acquireTimeoutMs);
|
|
38342
|
+
await sleep(retryDelayMs);
|
|
38343
|
+
}
|
|
38344
|
+
const heartbeat = setInterval(() => {
|
|
38345
|
+
void store.renew(key5, holder, ttlMs).catch(() => void 0);
|
|
38346
|
+
}, heartbeatMs);
|
|
38347
|
+
heartbeat.unref?.();
|
|
38348
|
+
try {
|
|
38349
|
+
return await fn();
|
|
38350
|
+
} finally {
|
|
38351
|
+
clearInterval(heartbeat);
|
|
38352
|
+
await store.release(key5, holder).catch(() => void 0);
|
|
38353
|
+
}
|
|
38354
|
+
}
|
|
38355
|
+
|
|
38356
|
+
// src/services/ProjectMutationMutex.ts
|
|
38357
|
+
var MUTATION_LEASE_OPTIONS = { ttlMs: 6e4, acquireTimeoutMs: 9e4, retryDelayMs: 100 };
|
|
37486
38358
|
function projectKey(scope) {
|
|
37487
38359
|
const row = (0, import_protocols28.snapshotExactRecord)(scope, ["tenantId", "projectId"]);
|
|
37488
38360
|
if (!row || typeof row.tenantId !== "string" || !row.tenantId || row.tenantId.includes("\0") || typeof row.projectId !== "string" || !row.projectId || row.projectId.includes("\0")) {
|
|
@@ -37498,9 +38370,12 @@ var ProjectMutationMutex = class {
|
|
|
37498
38370
|
/** Runs one mutation after all earlier mutations for the same Tenant and Project. */
|
|
37499
38371
|
async runExclusive(scope, operation, signal) {
|
|
37500
38372
|
const key5 = projectKey(scope);
|
|
38373
|
+
const leaseKey = `project-mutation:${encodeURIComponent(scope.tenantId)}:${encodeURIComponent(scope.projectId)}`;
|
|
37501
38374
|
await this.acquire(key5, signal);
|
|
37502
38375
|
try {
|
|
37503
|
-
|
|
38376
|
+
const store = getCoordinationLeaseStore();
|
|
38377
|
+
if (!store) return await operation();
|
|
38378
|
+
return await withLease(store, leaseKey, getReplicaId(), operation, MUTATION_LEASE_OPTIONS);
|
|
37504
38379
|
} finally {
|
|
37505
38380
|
this.release(key5);
|
|
37506
38381
|
}
|
|
@@ -37937,11 +38812,11 @@ function snapshotDate(value) {
|
|
|
37937
38812
|
}
|
|
37938
38813
|
|
|
37939
38814
|
// src/services/TaskLifecycleService.ts
|
|
37940
|
-
var
|
|
38815
|
+
var import_node_crypto10 = require("crypto");
|
|
37941
38816
|
var import_protocols31 = require("@axiom-lattice/protocols");
|
|
37942
38817
|
|
|
37943
38818
|
// src/middlewares/taskBelief.ts
|
|
37944
|
-
var
|
|
38819
|
+
var import_node_crypto9 = require("crypto");
|
|
37945
38820
|
function buildBeliefCompletionEventKey(taskId, result, impacts) {
|
|
37946
38821
|
const canonical = JSON.stringify({
|
|
37947
38822
|
beliefImpact: impacts.map((impact) => ({
|
|
@@ -37952,7 +38827,7 @@ function buildBeliefCompletionEventKey(taskId, result, impacts) {
|
|
|
37952
38827
|
})),
|
|
37953
38828
|
result: result.trim()
|
|
37954
38829
|
});
|
|
37955
|
-
return (0,
|
|
38830
|
+
return (0, import_node_crypto9.createHash)("sha256").update(canonical).digest("hex");
|
|
37956
38831
|
}
|
|
37957
38832
|
function buildCompletionEvidenceDetail(result, impacts, eventKey) {
|
|
37958
38833
|
return { result, beliefImpact: impacts, eventKey };
|
|
@@ -38007,9 +38882,9 @@ var BELIEF_OWNER_WRITE_ATTEMPTS = 3;
|
|
|
38007
38882
|
function isWellFormedImpact(impact) {
|
|
38008
38883
|
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(impact.key) && Number.isInteger(impact.after) && impact.after >= 0 && impact.after <= 100 && impact.basis.trim().length > 0 && impact.basis.length <= 1e3 && !/[\r\n]/.test(impact.basis);
|
|
38009
38884
|
}
|
|
38010
|
-
async function applyBeliefImpacts(taskStore,
|
|
38011
|
-
if (impacts.length === 0) return { description:
|
|
38012
|
-
let current =
|
|
38885
|
+
async function applyBeliefImpacts(taskStore, owner2, impacts) {
|
|
38886
|
+
if (impacts.length === 0) return { description: owner2.description ?? "" };
|
|
38887
|
+
let current = owner2;
|
|
38013
38888
|
for (let attempt = 0; attempt < BELIEF_OWNER_WRITE_ATTEMPTS; attempt += 1) {
|
|
38014
38889
|
const parsed = (0, import_protocols31.parseTaskBeliefState)(current.description ?? "");
|
|
38015
38890
|
const existingTable = parsed.success;
|
|
@@ -38138,14 +39013,14 @@ function sameBeliefOwner(left, right) {
|
|
|
38138
39013
|
function sameBeliefOwnerIdentity(left, right) {
|
|
38139
39014
|
return canonicalJson({ ...left, beliefState: void 0 }) === canonicalJson({ ...right, beliefState: void 0 });
|
|
38140
39015
|
}
|
|
38141
|
-
function canonicalBeliefOwner(
|
|
39016
|
+
function canonicalBeliefOwner(owner2) {
|
|
38142
39017
|
const beliefState = {
|
|
38143
|
-
entries:
|
|
39018
|
+
entries: owner2.beliefState.entries.map((entry) => ({
|
|
38144
39019
|
...entry,
|
|
38145
39020
|
basis: entry.basis.trim().replace(/\s+/g, " ")
|
|
38146
39021
|
})).sort((left, right) => left.key < right.key ? -1 : left.key > right.key ? 1 : 0)
|
|
38147
39022
|
};
|
|
38148
|
-
return { ...
|
|
39023
|
+
return { ...owner2, beliefState };
|
|
38149
39024
|
}
|
|
38150
39025
|
function eventKeyFor(taskId, result, impacts, beliefOwner) {
|
|
38151
39026
|
const base = `belief-impact:${taskId}:${buildBeliefCompletionEventKey(taskId, result, impacts)}`;
|
|
@@ -38155,7 +39030,7 @@ function canonicalJson(value) {
|
|
|
38155
39030
|
return JSON.stringify(value);
|
|
38156
39031
|
}
|
|
38157
39032
|
function sha256(value) {
|
|
38158
|
-
return (0,
|
|
39033
|
+
return (0, import_node_crypto10.createHash)("sha256").update(canonicalJson(value)).digest("hex");
|
|
38159
39034
|
}
|
|
38160
39035
|
function sameEvidenceDetail(detail, taskId, result, impacts, eventKey, beliefOwner) {
|
|
38161
39036
|
const storedOwner = detail.beliefOwner;
|
|
@@ -39512,8 +40387,8 @@ var TaskLifecycleService = class {
|
|
|
39512
40387
|
return { task: existing, parent: parentResult, eventKey, evidence, result, impacts };
|
|
39513
40388
|
}
|
|
39514
40389
|
beliefOwnerSnapshot(task, parent) {
|
|
39515
|
-
const
|
|
39516
|
-
const parsed = (0, import_protocols31.parseTaskBeliefState)(
|
|
40390
|
+
const owner2 = parent?.ownerType === "agent" ? parent : task;
|
|
40391
|
+
const parsed = (0, import_protocols31.parseTaskBeliefState)(owner2.description ?? "");
|
|
39517
40392
|
const beliefState = parsed.success ? parsed.state : { entries: [] };
|
|
39518
40393
|
if (parent?.ownerType === "agent") {
|
|
39519
40394
|
return {
|
|
@@ -40233,7 +41108,7 @@ function createTaskLifecycleService(deps) {
|
|
|
40233
41108
|
}
|
|
40234
41109
|
|
|
40235
41110
|
// src/services/TaskExecutionService.ts
|
|
40236
|
-
var
|
|
41111
|
+
var import_node_crypto12 = require("crypto");
|
|
40237
41112
|
var import_node_util3 = require("util");
|
|
40238
41113
|
var import_protocols32 = require("@axiom-lattice/protocols");
|
|
40239
41114
|
|
|
@@ -40492,12 +41367,20 @@ var TaskRunRegistry = class {
|
|
|
40492
41367
|
}
|
|
40493
41368
|
};
|
|
40494
41369
|
var taskRunRegistry = new TaskRunRegistry();
|
|
41370
|
+
async function safelyLive(probe, task) {
|
|
41371
|
+
try {
|
|
41372
|
+
return await probe(task);
|
|
41373
|
+
} catch {
|
|
41374
|
+
return true;
|
|
41375
|
+
}
|
|
41376
|
+
}
|
|
40495
41377
|
async function reconcileStaleTaskRuns(input) {
|
|
40496
41378
|
const registry4 = input.registry ?? taskRunRegistry;
|
|
40497
41379
|
const converged = [];
|
|
40498
41380
|
const convergedTasks = [];
|
|
40499
41381
|
for (const task of input.tasks) {
|
|
40500
41382
|
if (task.status !== "in_progress" || registry4.isLive(task.id)) continue;
|
|
41383
|
+
if (input.isTaskLive && await safelyLive(input.isTaskLive, task)) continue;
|
|
40501
41384
|
const result = await input.lifecycle.failTask({
|
|
40502
41385
|
tenantId: task.tenantId,
|
|
40503
41386
|
taskId: task.id,
|
|
@@ -40518,7 +41401,8 @@ async function reconcileTenantTaskRuns(input) {
|
|
|
40518
41401
|
tasks: candidates,
|
|
40519
41402
|
actor: input.actor,
|
|
40520
41403
|
lifecycle: input.lifecycle,
|
|
40521
|
-
...input.registry ? { registry: input.registry } : {}
|
|
41404
|
+
...input.registry ? { registry: input.registry } : {},
|
|
41405
|
+
...input.isTaskLive ? { isTaskLive: input.isTaskLive } : {}
|
|
40522
41406
|
});
|
|
40523
41407
|
}
|
|
40524
41408
|
async function reconcileAllTenantTaskRuns(input) {
|
|
@@ -40534,7 +41418,8 @@ async function reconcileAllTenantTaskRuns(input) {
|
|
|
40534
41418
|
taskStore: input.taskStore,
|
|
40535
41419
|
lifecycle: input.lifecycle,
|
|
40536
41420
|
...input.registry ? { registry: input.registry } : {},
|
|
40537
|
-
...input.include ? { include: input.include } : {}
|
|
41421
|
+
...input.include ? { include: input.include } : {},
|
|
41422
|
+
...input.isTaskLive ? { isTaskLive: input.isTaskLive } : {}
|
|
40538
41423
|
});
|
|
40539
41424
|
} catch {
|
|
40540
41425
|
continue;
|
|
@@ -40545,6 +41430,42 @@ async function reconcileAllTenantTaskRuns(input) {
|
|
|
40545
41430
|
return { converged, convergedTasks };
|
|
40546
41431
|
}
|
|
40547
41432
|
|
|
41433
|
+
// src/services/taskRunLease.ts
|
|
41434
|
+
var import_node_crypto11 = require("crypto");
|
|
41435
|
+
function taskRunLeaseKey(taskId) {
|
|
41436
|
+
return `task-run:${taskId}`;
|
|
41437
|
+
}
|
|
41438
|
+
async function tryAcquireTaskRun(input) {
|
|
41439
|
+
const key5 = taskRunLeaseKey(input.taskId);
|
|
41440
|
+
const holder = `${input.owner}#${(0, import_node_crypto11.randomUUID)()}`;
|
|
41441
|
+
if (!await input.store.tryAcquire(key5, holder, input.ttlMs)) return null;
|
|
41442
|
+
const heartbeatMs = input.heartbeatMs ?? Math.max(1e3, Math.floor(input.ttlMs / 3));
|
|
41443
|
+
let released = false;
|
|
41444
|
+
let lost = false;
|
|
41445
|
+
const heartbeat = setInterval(() => {
|
|
41446
|
+
void input.store.renew(key5, holder, input.ttlMs).then((renewed) => {
|
|
41447
|
+
if (released || renewed || lost) return;
|
|
41448
|
+
lost = true;
|
|
41449
|
+
try {
|
|
41450
|
+
input.onLost?.();
|
|
41451
|
+
} catch {
|
|
41452
|
+
}
|
|
41453
|
+
}).catch(() => void 0);
|
|
41454
|
+
}, heartbeatMs);
|
|
41455
|
+
heartbeat.unref?.();
|
|
41456
|
+
return {
|
|
41457
|
+
get lost() {
|
|
41458
|
+
return lost;
|
|
41459
|
+
},
|
|
41460
|
+
release: async () => {
|
|
41461
|
+
if (released) return;
|
|
41462
|
+
released = true;
|
|
41463
|
+
clearInterval(heartbeat);
|
|
41464
|
+
await input.store.release(key5, holder).catch(() => void 0);
|
|
41465
|
+
}
|
|
41466
|
+
};
|
|
41467
|
+
}
|
|
41468
|
+
|
|
40548
41469
|
// src/services/ExecutionAuthorityRegistry.ts
|
|
40549
41470
|
var ManagedTaskStartError = class extends Error {
|
|
40550
41471
|
/**
|
|
@@ -40815,6 +41736,14 @@ async function prepareTaskDispatch(deps, input) {
|
|
|
40815
41736
|
|
|
40816
41737
|
// src/services/TaskExecutionService.ts
|
|
40817
41738
|
var import_langgraph14 = require("@langchain/langgraph");
|
|
41739
|
+
var TASK_RUN_LEASE_TTL_MS = 12e4;
|
|
41740
|
+
function getLeaseStore() {
|
|
41741
|
+
try {
|
|
41742
|
+
return storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
41743
|
+
} catch {
|
|
41744
|
+
return void 0;
|
|
41745
|
+
}
|
|
41746
|
+
}
|
|
40818
41747
|
function persistedExecutionObservation(item, attempted) {
|
|
40819
41748
|
const detail = item.detail;
|
|
40820
41749
|
const persistedObservation = toJsonSafeValue(detail?.observation);
|
|
@@ -40875,11 +41804,11 @@ function createTaskExecutionService(deps) {
|
|
|
40875
41804
|
let threadId;
|
|
40876
41805
|
let runId;
|
|
40877
41806
|
try {
|
|
40878
|
-
threadId = storedThreadId ?? (deps.createThreadId ??
|
|
41807
|
+
threadId = storedThreadId ?? (deps.createThreadId ?? import_node_crypto12.randomUUID)();
|
|
40879
41808
|
if (task.status === "interrupted" && reuseCurrentRun) {
|
|
40880
41809
|
runId = storedRunId;
|
|
40881
41810
|
} else if (task.status === "interrupted" || task.status === "failed") {
|
|
40882
|
-
runId = (deps.createRunId ??
|
|
41811
|
+
runId = (deps.createRunId ?? import_node_crypto12.randomUUID)();
|
|
40883
41812
|
}
|
|
40884
41813
|
} catch (error) {
|
|
40885
41814
|
return {
|
|
@@ -40942,7 +41871,21 @@ function createTaskExecutionService(deps) {
|
|
|
40942
41871
|
warnings.push(...begun.warnings);
|
|
40943
41872
|
}
|
|
40944
41873
|
taskRunRegistry.register(task.id);
|
|
41874
|
+
let taskRunLease = null;
|
|
40945
41875
|
try {
|
|
41876
|
+
const leaseStore = getLeaseStore();
|
|
41877
|
+
if (leaseStore) {
|
|
41878
|
+
try {
|
|
41879
|
+
taskRunLease = await tryAcquireTaskRun({
|
|
41880
|
+
store: leaseStore,
|
|
41881
|
+
taskId: task.id,
|
|
41882
|
+
owner: getReplicaId(),
|
|
41883
|
+
ttlMs: TASK_RUN_LEASE_TTL_MS
|
|
41884
|
+
});
|
|
41885
|
+
} catch {
|
|
41886
|
+
taskRunLease = null;
|
|
41887
|
+
}
|
|
41888
|
+
}
|
|
40946
41889
|
const invocation = {
|
|
40947
41890
|
tenantId: tenantId2,
|
|
40948
41891
|
workspaceId: task.workspaceId,
|
|
@@ -41110,6 +42053,7 @@ function createTaskExecutionService(deps) {
|
|
|
41110
42053
|
}
|
|
41111
42054
|
} finally {
|
|
41112
42055
|
taskRunRegistry.unregister(task.id);
|
|
42056
|
+
if (taskRunLease) await taskRunLease.release();
|
|
41113
42057
|
}
|
|
41114
42058
|
};
|
|
41115
42059
|
return {
|
|
@@ -41122,6 +42066,43 @@ function createTaskExecutionService(deps) {
|
|
|
41122
42066
|
};
|
|
41123
42067
|
}
|
|
41124
42068
|
|
|
42069
|
+
// src/services/leadership.ts
|
|
42070
|
+
var import_node_crypto13 = require("crypto");
|
|
42071
|
+
async function runAsLeader(store, name, fn, options = {}) {
|
|
42072
|
+
const key5 = `leader:${name}`;
|
|
42073
|
+
const owner2 = options.owner ?? getReplicaId();
|
|
42074
|
+
const holder = `${owner2}#${(0, import_node_crypto13.randomUUID)()}`;
|
|
42075
|
+
const ttlMs = options.ttlMs ?? 6e4;
|
|
42076
|
+
if (!await store.tryAcquire(key5, holder, ttlMs)) return { ran: false };
|
|
42077
|
+
const heartbeat = setInterval(() => {
|
|
42078
|
+
void store.renew(key5, holder, ttlMs).catch(() => void 0);
|
|
42079
|
+
}, Math.max(1e3, Math.floor(ttlMs / 3)));
|
|
42080
|
+
heartbeat.unref?.();
|
|
42081
|
+
try {
|
|
42082
|
+
const result = await fn();
|
|
42083
|
+
return { ran: true, result };
|
|
42084
|
+
} finally {
|
|
42085
|
+
clearInterval(heartbeat);
|
|
42086
|
+
if (!options.hold) await store.release(key5, holder).catch(() => void 0);
|
|
42087
|
+
}
|
|
42088
|
+
}
|
|
42089
|
+
|
|
42090
|
+
// src/services/pluginCatalogSync.ts
|
|
42091
|
+
var PLUGIN_CATALOG_CHANGED_TOPIC = "plugin-catalog-changed";
|
|
42092
|
+
var outbox;
|
|
42093
|
+
var owner = "unknown";
|
|
42094
|
+
function configurePluginCatalogSync(next) {
|
|
42095
|
+
outbox = next?.outbox;
|
|
42096
|
+
owner = next?.owner ?? "unknown";
|
|
42097
|
+
}
|
|
42098
|
+
async function publishPluginCatalogChanged(tenantId2) {
|
|
42099
|
+
if (!outbox || !tenantId2) return;
|
|
42100
|
+
try {
|
|
42101
|
+
await outbox.append({ topic: PLUGIN_CATALOG_CHANGED_TOPIC, payload: { tenantId: tenantId2 }, originReplicaId: owner });
|
|
42102
|
+
} catch {
|
|
42103
|
+
}
|
|
42104
|
+
}
|
|
42105
|
+
|
|
41125
42106
|
// src/index.ts
|
|
41126
42107
|
var Protocols = __toESM(require("@axiom-lattice/protocols"));
|
|
41127
42108
|
|
|
@@ -41264,9 +42245,9 @@ var createLoadSkillsTool = ({ skills, readAll, pluginSkills, pluginSkillOwners }
|
|
|
41264
42245
|
if (!skillName) continue;
|
|
41265
42246
|
if (await isPluginSkillManagedInSandbox(sandbox, skillName)) {
|
|
41266
42247
|
const enabledDefinition = pluginSkills?.[skillName];
|
|
41267
|
-
const
|
|
41268
|
-
const registered =
|
|
41269
|
-
if (!registered || registered.definition !== enabledDefinition || !
|
|
42248
|
+
const owner2 = pluginSkillOwners?.[skillName];
|
|
42249
|
+
const registered = owner2 && enabledDefinition ? PluginRegistry.getSkillForPlugin(owner2, skillName) : void 0;
|
|
42250
|
+
if (!registered || registered.definition !== enabledDefinition || !owner2 || !await isPluginSkillAuthorizedInSandbox(sandbox, skillName, owner2) || await getPluginSkillManifestVersion(sandbox, skillName) !== enabledDefinition.version) {
|
|
41270
42251
|
continue;
|
|
41271
42252
|
}
|
|
41272
42253
|
}
|
|
@@ -41292,8 +42273,8 @@ var createLoadSkillsTool = ({ skills, readAll, pluginSkills, pluginSkillOwners }
|
|
|
41292
42273
|
const seenNames = new Set(filteredSkills.map((skill) => skill.name));
|
|
41293
42274
|
try {
|
|
41294
42275
|
for (const [name, definition] of Object.entries(pluginSkills ?? {})) {
|
|
41295
|
-
const
|
|
41296
|
-
const registered =
|
|
42276
|
+
const owner2 = pluginSkillOwners?.[name];
|
|
42277
|
+
const registered = owner2 ? PluginRegistry.getSkillForPlugin(owner2, name) : void 0;
|
|
41297
42278
|
if (!registered || registered.definition !== definition) continue;
|
|
41298
42279
|
const { meta } = parseSkillFrontmatter(definition.content);
|
|
41299
42280
|
if (!meta.name || !meta.description || seenNames.has(meta.name)) continue;
|
|
@@ -41330,24 +42311,24 @@ var import_zod52 = __toESM(require("zod"));
|
|
|
41330
42311
|
var import_langchain63 = require("langchain");
|
|
41331
42312
|
|
|
41332
42313
|
// src/sandbox_plugin/pluginSkillResolution.ts
|
|
41333
|
-
async function resolveTenantPluginSkill(tenantId2,
|
|
42314
|
+
async function resolveTenantPluginSkill(tenantId2, owner2, skillName) {
|
|
41334
42315
|
try {
|
|
41335
42316
|
const { plugins } = await getSandboxPluginCatalog().ensureLoaded(tenantId2);
|
|
41336
|
-
const plugin = plugins.find((candidate) => candidate.meta.type ===
|
|
42317
|
+
const plugin = plugins.find((candidate) => candidate.meta.type === owner2);
|
|
41337
42318
|
return plugin?.skills?.[skillName];
|
|
41338
42319
|
} catch {
|
|
41339
42320
|
return void 0;
|
|
41340
42321
|
}
|
|
41341
42322
|
}
|
|
41342
|
-
async function resolveEnabledPluginSkill(
|
|
41343
|
-
if (!
|
|
41344
|
-
const registered = PluginRegistry.getSkillForPlugin(
|
|
41345
|
-
if (registered && registered.pluginType ===
|
|
41346
|
-
return { pluginType:
|
|
42323
|
+
async function resolveEnabledPluginSkill(owner2, skillName, enabledDefinition, tenantId2) {
|
|
42324
|
+
if (!owner2 || !enabledDefinition) return void 0;
|
|
42325
|
+
const registered = PluginRegistry.getSkillForPlugin(owner2, skillName);
|
|
42326
|
+
if (registered && registered.pluginType === owner2 && registered.definition === enabledDefinition) {
|
|
42327
|
+
return { pluginType: owner2, definition: enabledDefinition };
|
|
41347
42328
|
}
|
|
41348
42329
|
if (!tenantId2) return void 0;
|
|
41349
|
-
const tenantDefinition = await resolveTenantPluginSkill(tenantId2,
|
|
41350
|
-
return tenantDefinition ? { pluginType:
|
|
42330
|
+
const tenantDefinition = await resolveTenantPluginSkill(tenantId2, owner2, skillName);
|
|
42331
|
+
return tenantDefinition ? { pluginType: owner2, definition: tenantDefinition } : void 0;
|
|
41351
42332
|
}
|
|
41352
42333
|
|
|
41353
42334
|
// src/tool_lattice/skill/load_skill_content.ts
|
|
@@ -41409,10 +42390,10 @@ var createLoadSkillContentTool = (pluginSkills, pluginSkillOwnersOrStaticSelecti
|
|
|
41409
42390
|
return result2;
|
|
41410
42391
|
}
|
|
41411
42392
|
const enabledDefinition = pluginSkills?.[input.skill_name];
|
|
41412
|
-
const
|
|
42393
|
+
const owner2 = pluginSkillOwners?.[input.skill_name];
|
|
41413
42394
|
const runConfig = _exe_config?.configurable?.runConfig || {};
|
|
41414
42395
|
const pluginSkill = await resolveEnabledPluginSkill(
|
|
41415
|
-
|
|
42396
|
+
owner2,
|
|
41416
42397
|
input.skill_name,
|
|
41417
42398
|
enabledDefinition,
|
|
41418
42399
|
runConfig.tenantId
|
|
@@ -41519,9 +42500,9 @@ var createLoadSkillResourceTool = (pluginSkills, pluginSkillOwners) => {
|
|
|
41519
42500
|
validateRelativePath(input.resource_path, "resource");
|
|
41520
42501
|
const sandbox = await getSandboxFromExeConfig3(_exe_config);
|
|
41521
42502
|
const definition = pluginSkills?.[input.skill_name];
|
|
41522
|
-
const
|
|
42503
|
+
const owner2 = pluginSkillOwners?.[input.skill_name];
|
|
41523
42504
|
const tenantId2 = _exe_config?.configurable?.runConfig?.tenantId;
|
|
41524
|
-
const resolved = await resolveEnabledPluginSkill(
|
|
42505
|
+
const resolved = await resolveEnabledPluginSkill(owner2, input.skill_name, definition, tenantId2);
|
|
41525
42506
|
if (definition) {
|
|
41526
42507
|
if (!resolved || !resolved.definition.resources?.[input.resource_path]) {
|
|
41527
42508
|
return `Resource "${input.resource_path}" not found for skill "${input.skill_name}".`;
|
|
@@ -43748,9 +44729,9 @@ async function renderAvailableExecutors(rc, tenantId2) {
|
|
|
43748
44729
|
const governed = authority.kind === "projectRoom" || authority.kind === "projectTask";
|
|
43749
44730
|
const projectId = governed ? (authority.trusted.projectTask ?? authority.trusted.projectRoom)?.projectId : void 0;
|
|
43750
44731
|
const cacheKey = `${tenantId2}:${governed ? `project:${projectId ?? ""}` : "ordinary"}`;
|
|
43751
|
-
const
|
|
44732
|
+
const cached2 = executorCache.get(cacheKey);
|
|
43752
44733
|
const now = Date.now();
|
|
43753
|
-
if (
|
|
44734
|
+
if (cached2 && now - cached2.at < EXECUTOR_CACHE_TTL_MS) return cached2.text;
|
|
43754
44735
|
const lines = [];
|
|
43755
44736
|
try {
|
|
43756
44737
|
if (governed && projectId) {
|
|
@@ -48031,6 +49012,7 @@ var sandboxPluginsPlugin = {
|
|
|
48031
49012
|
}
|
|
48032
49013
|
case "reload": {
|
|
48033
49014
|
const loaded = await catalog2.reload(tenantId2);
|
|
49015
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
48034
49016
|
return JSON.stringify({ reloaded: true, plugins: loaded.plugins.length, diagnostics: loaded.diagnostics });
|
|
48035
49017
|
}
|
|
48036
49018
|
case "create":
|
|
@@ -48050,12 +49032,14 @@ var sandboxPluginsPlugin = {
|
|
|
48050
49032
|
if (!check.manifest) return JSON.stringify({ written: false, diagnostics: check.diagnostics });
|
|
48051
49033
|
await catalog2.writePlugin(tenantId2, input.type, input.manifest, handlers);
|
|
48052
49034
|
const loaded = await catalog2.reload(tenantId2);
|
|
49035
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
48053
49036
|
return JSON.stringify({ written: true, diagnostics: loaded.diagnostics, hash: loaded.hash });
|
|
48054
49037
|
}
|
|
48055
49038
|
case "delete": {
|
|
48056
49039
|
if (!input.type) return "type is required";
|
|
48057
49040
|
await catalog2.deletePlugin(tenantId2, input.type);
|
|
48058
49041
|
await catalog2.reload(tenantId2);
|
|
49042
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
48059
49043
|
return JSON.stringify({ deleted: true });
|
|
48060
49044
|
}
|
|
48061
49045
|
case "validate": {
|
|
@@ -48167,6 +49151,26 @@ function registerBuiltinPlugins() {
|
|
|
48167
49151
|
}
|
|
48168
49152
|
}
|
|
48169
49153
|
|
|
49154
|
+
// src/sandbox_plugin/provisionOpenClient.ts
|
|
49155
|
+
var import_node_fs = require("fs");
|
|
49156
|
+
var SDK_ROOT = "/root/.agents/sdk";
|
|
49157
|
+
var CLIENT_DIR = `${SDK_ROOT}/open-mcp-client`;
|
|
49158
|
+
var MANIFEST_PATH2 = `${SDK_ROOT}/.open-client-manifest.json`;
|
|
49159
|
+
async function provisionSandboxOpenClient(sandbox, bundle) {
|
|
49160
|
+
await sandbox.file.createDirectory(SDK_ROOT);
|
|
49161
|
+
await sandbox.file.createDirectory(CLIENT_DIR);
|
|
49162
|
+
await sandbox.file.writeFile(`${CLIENT_DIR}/index.js`, bundle.indexJs);
|
|
49163
|
+
await sandbox.file.writeFile(`${CLIENT_DIR}/cli.js`, bundle.cliJs);
|
|
49164
|
+
await sandbox.file.writeFile(MANIFEST_PATH2, JSON.stringify({ version: bundle.version }));
|
|
49165
|
+
}
|
|
49166
|
+
function buildBundleFromDist(distDir, version) {
|
|
49167
|
+
return {
|
|
49168
|
+
indexJs: (0, import_node_fs.readFileSync)(`${distDir}/index.js`, "utf8"),
|
|
49169
|
+
cliJs: (0, import_node_fs.readFileSync)(`${distDir}/cli.js`, "utf8"),
|
|
49170
|
+
version
|
|
49171
|
+
};
|
|
49172
|
+
}
|
|
49173
|
+
|
|
48170
49174
|
// src/workflow/index.ts
|
|
48171
49175
|
init_compile();
|
|
48172
49176
|
init_parse_yaml();
|
|
@@ -48558,16 +49562,16 @@ var IdRemapper = class {
|
|
|
48558
49562
|
};
|
|
48559
49563
|
|
|
48560
49564
|
// src/util/directRoomId.ts
|
|
48561
|
-
var
|
|
49565
|
+
var import_node_crypto14 = require("crypto");
|
|
48562
49566
|
function generateDirectHumanProjectId(tenantId2, workspaceId, userId1, userId2) {
|
|
48563
49567
|
const sortedUserIds = [userId1, userId2].sort();
|
|
48564
49568
|
const parts = [tenantId2, workspaceId, ...sortedUserIds];
|
|
48565
|
-
const hash = (0,
|
|
49569
|
+
const hash = (0, import_node_crypto14.createHash)("sha256").update(parts.join(":")).digest("hex");
|
|
48566
49570
|
return `direct_human_${hash}`;
|
|
48567
49571
|
}
|
|
48568
49572
|
function generateDirectBotProjectId(tenantId2, workspaceId, userId, assistantId) {
|
|
48569
49573
|
const parts = [tenantId2, workspaceId, userId, assistantId];
|
|
48570
|
-
const hash = (0,
|
|
49574
|
+
const hash = (0, import_node_crypto14.createHash)("sha256").update(parts.join(":")).digest("hex");
|
|
48571
49575
|
return `direct_bot_${hash}`;
|
|
48572
49576
|
}
|
|
48573
49577
|
function parseDirectRoomType(projectId) {
|
|
@@ -48636,10 +49640,12 @@ registerBuiltinPlugins();
|
|
|
48636
49640
|
InMemoryChunkBuffer,
|
|
48637
49641
|
InMemoryCollectionStore,
|
|
48638
49642
|
InMemoryDatabaseConfigStore,
|
|
49643
|
+
InMemoryLeaseStore,
|
|
48639
49644
|
InMemoryMailboxStore,
|
|
48640
49645
|
InMemoryMenuStore,
|
|
48641
49646
|
InMemoryModelProviderStore,
|
|
48642
49647
|
InMemoryOpenAuditStore,
|
|
49648
|
+
InMemoryOutboxStore,
|
|
48643
49649
|
InMemoryProjectBotMembershipStore,
|
|
48644
49650
|
InMemoryProjectMembershipStore,
|
|
48645
49651
|
InMemoryProjectRoomCoordinator,
|
|
@@ -48659,6 +49665,7 @@ registerBuiltinPlugins();
|
|
|
48659
49665
|
LatticeEval,
|
|
48660
49666
|
LatticeEvalProject,
|
|
48661
49667
|
LatticeEvalSuite,
|
|
49668
|
+
LeaseAcquisitionTimeoutError,
|
|
48662
49669
|
LocalSandboxInstance,
|
|
48663
49670
|
LocalSandboxProvider,
|
|
48664
49671
|
LoggerLatticeManager,
|
|
@@ -48681,7 +49688,10 @@ registerBuiltinPlugins();
|
|
|
48681
49688
|
MicrosandboxServiceClient,
|
|
48682
49689
|
ModelLatticeManager,
|
|
48683
49690
|
MysqlDatabase,
|
|
49691
|
+
OutboxPoller,
|
|
48684
49692
|
PACK_DIRECTORY_TIMEOUT_SECONDS,
|
|
49693
|
+
PLATFORM_SECRET_ENV_VARS,
|
|
49694
|
+
PLUGIN_CATALOG_CHANGED_TOPIC,
|
|
48685
49695
|
PersonalAssistantConfig,
|
|
48686
49696
|
PinoLoggerClient,
|
|
48687
49697
|
PluginRegistry,
|
|
@@ -48702,6 +49712,8 @@ registerBuiltinPlugins();
|
|
|
48702
49712
|
RepeatedToolCallError,
|
|
48703
49713
|
RoomAgentMessageService,
|
|
48704
49714
|
SAFE_PATH_COMPONENT,
|
|
49715
|
+
SANDBOX_OPEN_GATEWAY_URL_ENV,
|
|
49716
|
+
SANDBOX_OPEN_TOKEN_ENV,
|
|
48705
49717
|
STTModelLattice,
|
|
48706
49718
|
STTModelLatticeManager,
|
|
48707
49719
|
SandboxFilesystem,
|
|
@@ -48742,11 +49754,13 @@ registerBuiltinPlugins();
|
|
|
48742
49754
|
appendReconciliationWarning,
|
|
48743
49755
|
appendUiFence,
|
|
48744
49756
|
assertSafeUpstreamUrl,
|
|
49757
|
+
buildBundleFromDist,
|
|
48745
49758
|
buildGrepResultsDict,
|
|
48746
49759
|
buildInput,
|
|
48747
49760
|
buildNamedVolumeName,
|
|
48748
49761
|
buildRemotePackDirectoryCommand,
|
|
48749
49762
|
buildSandboxMetadataEnv,
|
|
49763
|
+
buildSandboxOpenEnv,
|
|
48750
49764
|
buildSkillFile,
|
|
48751
49765
|
buildStateAnnotation,
|
|
48752
49766
|
buildTableName,
|
|
@@ -48755,11 +49769,14 @@ registerBuiltinPlugins();
|
|
|
48755
49769
|
checkEmptyContent,
|
|
48756
49770
|
clearEncryptionKeyCache,
|
|
48757
49771
|
clearEvalRunService,
|
|
49772
|
+
clearSandboxOpenCredentialProviderForTests,
|
|
48758
49773
|
collectionLatticeManager,
|
|
48759
49774
|
compileInternal,
|
|
48760
49775
|
compileSandboxPlugin,
|
|
48761
49776
|
compileWorkflow,
|
|
48762
49777
|
computeSandboxName,
|
|
49778
|
+
configureCoordinationLeaseStore,
|
|
49779
|
+
configurePluginCatalogSync,
|
|
48763
49780
|
configureStores,
|
|
48764
49781
|
connectAllChannels,
|
|
48765
49782
|
convertToConnection,
|
|
@@ -48791,6 +49808,7 @@ registerBuiltinPlugins();
|
|
|
48791
49808
|
createSandboxResolver,
|
|
48792
49809
|
createSchedulerMiddleware,
|
|
48793
49810
|
createSharePayload,
|
|
49811
|
+
createShellExecTool,
|
|
48794
49812
|
createTaskExecutionService,
|
|
48795
49813
|
createTaskLifecycleService,
|
|
48796
49814
|
createTaskMiddleware,
|
|
@@ -48837,6 +49855,7 @@ registerBuiltinPlugins();
|
|
|
48837
49855
|
getCheckpointSaver,
|
|
48838
49856
|
getChunkBuffer,
|
|
48839
49857
|
getCollectionEntryCount,
|
|
49858
|
+
getCoordinationLeaseStore,
|
|
48840
49859
|
getEmbeddingsClient,
|
|
48841
49860
|
getEmbeddingsLattice,
|
|
48842
49861
|
getEncryptionKey,
|
|
@@ -48848,15 +49867,18 @@ registerBuiltinPlugins();
|
|
|
48848
49867
|
getOrCreateCollectionVectorStore,
|
|
48849
49868
|
getPluginSkillManifestVersion,
|
|
48850
49869
|
getQueueLattice,
|
|
49870
|
+
getReplicaId,
|
|
48851
49871
|
getRuntimeCapabilityConfig,
|
|
48852
49872
|
getRuntimeSkillSelection,
|
|
48853
49873
|
getSTTClient,
|
|
48854
49874
|
getSTTClientWithTenant,
|
|
48855
49875
|
getSTTModelLattice,
|
|
48856
49876
|
getSandBoxManager,
|
|
49877
|
+
getSandboxOpenCredential,
|
|
48857
49878
|
getSandboxPluginCatalog,
|
|
48858
49879
|
getScheduleLattice,
|
|
48859
49880
|
getStoreLattice,
|
|
49881
|
+
getThreadRunOwner,
|
|
48860
49882
|
getToolClient,
|
|
48861
49883
|
getToolClientWithTenant,
|
|
48862
49884
|
getToolDefinition,
|
|
@@ -48910,6 +49932,8 @@ registerBuiltinPlugins();
|
|
|
48910
49932
|
projectMutationMutex,
|
|
48911
49933
|
projectRoomPlugin,
|
|
48912
49934
|
projectTaskAdmissionNotifier,
|
|
49935
|
+
provisionSandboxOpenClient,
|
|
49936
|
+
publishPluginCatalogChanged,
|
|
48913
49937
|
queueLatticeManager,
|
|
48914
49938
|
readLoopBreakerConfig,
|
|
48915
49939
|
reconcileAllTenantTaskRuns,
|
|
@@ -48928,6 +49952,7 @@ registerBuiltinPlugins();
|
|
|
48928
49952
|
registerModelLatticeForTenant,
|
|
48929
49953
|
registerQueueLattice,
|
|
48930
49954
|
registerSTTModelLattice,
|
|
49955
|
+
registerSandboxOpenCredentialProvider,
|
|
48931
49956
|
registerSandboxProviderType,
|
|
48932
49957
|
registerScheduleLattice,
|
|
48933
49958
|
registerStoreLattice,
|
|
@@ -48938,6 +49963,7 @@ registerBuiltinPlugins();
|
|
|
48938
49963
|
registerWorkflowRun,
|
|
48939
49964
|
removeCollectionVectorStore,
|
|
48940
49965
|
renderTemplate,
|
|
49966
|
+
resetReplicaIdForTests,
|
|
48941
49967
|
resolveEnabledPluginSkill,
|
|
48942
49968
|
resolveJudgeModelKey,
|
|
48943
49969
|
resolvePath,
|
|
@@ -48945,6 +49971,7 @@ registerBuiltinPlugins();
|
|
|
48945
49971
|
resolveSandboxPluginConnections,
|
|
48946
49972
|
resolveTenantPluginSkill,
|
|
48947
49973
|
roomCoordinatorConfig,
|
|
49974
|
+
runAsLeader,
|
|
48948
49975
|
runRemotePackDirectory,
|
|
48949
49976
|
safeTaskResponseId,
|
|
48950
49977
|
sandboxLatticeManager,
|
|
@@ -48963,11 +49990,15 @@ registerBuiltinPlugins();
|
|
|
48963
49990
|
storeLatticeManager,
|
|
48964
49991
|
sttModelLatticeManager,
|
|
48965
49992
|
taskLifecycleNotifier,
|
|
49993
|
+
taskRunLeaseKey,
|
|
48966
49994
|
taskRunRegistry,
|
|
49995
|
+
threadRunLeaseKey,
|
|
48967
49996
|
toJsonSchema,
|
|
48968
49997
|
toSafeStateExpr,
|
|
48969
49998
|
toolLatticeManager,
|
|
48970
49999
|
truncateIfTooLong,
|
|
50000
|
+
tryAcquireTaskRun,
|
|
50001
|
+
tryAcquireThreadRun,
|
|
48971
50002
|
unregisterTeammateAgent,
|
|
48972
50003
|
unregisterWorkflowRun,
|
|
48973
50004
|
updateFileData,
|
|
@@ -48983,6 +50014,7 @@ registerBuiltinPlugins();
|
|
|
48983
50014
|
validateToolInput,
|
|
48984
50015
|
vectorStoreLatticeManager,
|
|
48985
50016
|
vectorStoreProviderManager,
|
|
50017
|
+
withLease,
|
|
48986
50018
|
withTimeout,
|
|
48987
50019
|
wrapMcpToolWithUi
|
|
48988
50020
|
});
|