@axiom-lattice/core 6.2.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +767 -24
- package/dist/index.d.ts +767 -24
- package/dist/index.js +1119 -122
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1084 -115
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -2115,7 +2115,7 @@ var InMemoryModelProviderStore = class {
|
|
|
2115
2115
|
*/
|
|
2116
2116
|
async listProviders(tenantId2) {
|
|
2117
2117
|
return Array.from(this.providers.values()).filter(
|
|
2118
|
-
(
|
|
2118
|
+
(provider2) => provider2.tenantId === tenantId2
|
|
2119
2119
|
);
|
|
2120
2120
|
}
|
|
2121
2121
|
/**
|
|
@@ -2129,7 +2129,7 @@ var InMemoryModelProviderStore = class {
|
|
|
2129
2129
|
*/
|
|
2130
2130
|
async getProviderByName(tenantId2, name) {
|
|
2131
2131
|
const providers = await this.listProviders(tenantId2);
|
|
2132
|
-
return providers.find((
|
|
2132
|
+
return providers.find((provider2) => provider2.name === name) || null;
|
|
2133
2133
|
}
|
|
2134
2134
|
/**
|
|
2135
2135
|
* Create a new provider configuration
|
|
@@ -2313,8 +2313,8 @@ var InMemoryModelProviderStore = class {
|
|
|
2313
2313
|
* Clear providers and models for a specific tenant
|
|
2314
2314
|
*/
|
|
2315
2315
|
clearByTenant(tenantId2) {
|
|
2316
|
-
for (const [key5,
|
|
2317
|
-
if (
|
|
2316
|
+
for (const [key5, provider2] of Array.from(this.providers.entries())) {
|
|
2317
|
+
if (provider2.tenantId === tenantId2) {
|
|
2318
2318
|
this.providers.delete(key5);
|
|
2319
2319
|
}
|
|
2320
2320
|
}
|
|
@@ -3190,6 +3190,123 @@ function entryKey(tenantId2, userId, endpoint) {
|
|
|
3190
3190
|
return JSON.stringify([tenantId2, userId, endpoint]);
|
|
3191
3191
|
}
|
|
3192
3192
|
|
|
3193
|
+
// src/store_lattice/InMemoryLeaseStore.ts
|
|
3194
|
+
var InMemoryLeaseStore = class {
|
|
3195
|
+
/**
|
|
3196
|
+
* @param now Injectable clock in epoch milliseconds (tests use a fake clock).
|
|
3197
|
+
*/
|
|
3198
|
+
constructor(now = Date.now) {
|
|
3199
|
+
this.leases = /* @__PURE__ */ new Map();
|
|
3200
|
+
this.now = now;
|
|
3201
|
+
}
|
|
3202
|
+
/** Atomically acquires a free/expired key (or the caller's own key). */
|
|
3203
|
+
async tryAcquire(key5, holder, ttlMs) {
|
|
3204
|
+
const existing = this.leases.get(key5);
|
|
3205
|
+
if (existing && Date.parse(existing.expiresAt) > this.now()) {
|
|
3206
|
+
if (existing.holder !== holder) return false;
|
|
3207
|
+
this.leases.set(key5, { ...existing, expiresAt: new Date(this.now() + ttlMs).toISOString() });
|
|
3208
|
+
return true;
|
|
3209
|
+
}
|
|
3210
|
+
const acquiredAt = existing && existing.holder === holder ? existing.acquiredAt : new Date(this.now()).toISOString();
|
|
3211
|
+
this.leases.set(key5, {
|
|
3212
|
+
key: key5,
|
|
3213
|
+
holder,
|
|
3214
|
+
acquiredAt,
|
|
3215
|
+
expiresAt: new Date(this.now() + ttlMs).toISOString()
|
|
3216
|
+
});
|
|
3217
|
+
return true;
|
|
3218
|
+
}
|
|
3219
|
+
/** Extends a lease only while `holder` still owns it. */
|
|
3220
|
+
async renew(key5, holder, ttlMs) {
|
|
3221
|
+
const existing = this.leases.get(key5);
|
|
3222
|
+
if (!existing || existing.holder !== holder) return false;
|
|
3223
|
+
this.leases.set(key5, { ...existing, expiresAt: new Date(this.now() + ttlMs).toISOString() });
|
|
3224
|
+
return true;
|
|
3225
|
+
}
|
|
3226
|
+
/** Deletes a lease only when `holder` owns it. */
|
|
3227
|
+
async release(key5, holder) {
|
|
3228
|
+
const existing = this.leases.get(key5);
|
|
3229
|
+
if (!existing || existing.holder !== holder) return false;
|
|
3230
|
+
this.leases.delete(key5);
|
|
3231
|
+
return true;
|
|
3232
|
+
}
|
|
3233
|
+
/** Returns the live lease, pruning an expired one. */
|
|
3234
|
+
async get(key5) {
|
|
3235
|
+
const existing = this.leases.get(key5);
|
|
3236
|
+
if (!existing) return null;
|
|
3237
|
+
if (Date.parse(existing.expiresAt) <= this.now()) {
|
|
3238
|
+
this.leases.delete(key5);
|
|
3239
|
+
return null;
|
|
3240
|
+
}
|
|
3241
|
+
return { ...existing };
|
|
3242
|
+
}
|
|
3243
|
+
};
|
|
3244
|
+
|
|
3245
|
+
// src/store_lattice/InMemoryOutboxStore.ts
|
|
3246
|
+
var InMemoryOutboxStore = class {
|
|
3247
|
+
/**
|
|
3248
|
+
* Creates an in-memory outbox store.
|
|
3249
|
+
*
|
|
3250
|
+
* @param now Optional clock override (defaults to the system clock); it stamps
|
|
3251
|
+
* `createdAt` and is used to evaluate age-based retention.
|
|
3252
|
+
*/
|
|
3253
|
+
constructor(now = () => /* @__PURE__ */ new Date()) {
|
|
3254
|
+
this.events = [];
|
|
3255
|
+
this.counter = 0;
|
|
3256
|
+
this.now = now;
|
|
3257
|
+
}
|
|
3258
|
+
/**
|
|
3259
|
+
* Appends one event, assigning the next monotonic id.
|
|
3260
|
+
* @param input Topic, JSON-safe payload, and authoring replica id.
|
|
3261
|
+
* @returns A defensive copy of the stored event.
|
|
3262
|
+
*/
|
|
3263
|
+
async append(input) {
|
|
3264
|
+
const event = {
|
|
3265
|
+
id: String(++this.counter),
|
|
3266
|
+
topic: input.topic,
|
|
3267
|
+
payload: input.payload,
|
|
3268
|
+
originReplicaId: input.originReplicaId,
|
|
3269
|
+
createdAt: this.now().toISOString()
|
|
3270
|
+
};
|
|
3271
|
+
this.events.push(event);
|
|
3272
|
+
return { ...event };
|
|
3273
|
+
}
|
|
3274
|
+
/**
|
|
3275
|
+
* Lists events strictly newer than `cursor`, ascending, bounded by `limit`.
|
|
3276
|
+
* @param cursor Last-seen id, or `null` to read from the start.
|
|
3277
|
+
* @param limit Maximum number of events to return.
|
|
3278
|
+
* @returns Defensive copies of the matching events.
|
|
3279
|
+
*/
|
|
3280
|
+
async listAfter(cursor, limit) {
|
|
3281
|
+
const floor = cursor === null ? 0 : Number(cursor);
|
|
3282
|
+
return this.events.filter((event) => Number(event.id) > floor).slice(0, limit).map((event) => ({ ...event }));
|
|
3283
|
+
}
|
|
3284
|
+
/**
|
|
3285
|
+
* Returns the newest event id.
|
|
3286
|
+
* @returns The last id, or `null` when the log is empty.
|
|
3287
|
+
*/
|
|
3288
|
+
async latestId() {
|
|
3289
|
+
return this.events.length === 0 ? null : this.events[this.events.length - 1].id;
|
|
3290
|
+
}
|
|
3291
|
+
/**
|
|
3292
|
+
* Deletes events older than `olderThanMs`, evaluated against this store's clock.
|
|
3293
|
+
*
|
|
3294
|
+
* @param olderThanMs Age threshold in milliseconds.
|
|
3295
|
+
* @returns The number of events removed.
|
|
3296
|
+
*/
|
|
3297
|
+
async pruneOlderThan(olderThanMs) {
|
|
3298
|
+
const cutoff = this.now().getTime() - olderThanMs;
|
|
3299
|
+
let removed = 0;
|
|
3300
|
+
for (let i = this.events.length - 1; i >= 0; i -= 1) {
|
|
3301
|
+
if (new Date(this.events[i].createdAt).getTime() < cutoff) {
|
|
3302
|
+
this.events.splice(i, 1);
|
|
3303
|
+
removed += 1;
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3306
|
+
return removed;
|
|
3307
|
+
}
|
|
3308
|
+
};
|
|
3309
|
+
|
|
3193
3310
|
// src/store_lattice/InMemoryUserStore.ts
|
|
3194
3311
|
var InMemoryUserStore = class {
|
|
3195
3312
|
constructor() {
|
|
@@ -3396,7 +3513,8 @@ function isMessageContentValue(value) {
|
|
|
3396
3513
|
|
|
3397
3514
|
// src/store_lattice/InMemoryThreadMessageQueueStore.ts
|
|
3398
3515
|
var InMemoryThreadMessageQueueStore = class {
|
|
3399
|
-
constructor() {
|
|
3516
|
+
constructor(now = Date.now) {
|
|
3517
|
+
this.now = now;
|
|
3400
3518
|
this.messages = /* @__PURE__ */ new Map();
|
|
3401
3519
|
this.messageIdCounter = 0;
|
|
3402
3520
|
this.capacityTail = Promise.resolve();
|
|
@@ -3503,6 +3621,36 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
3503
3621
|
const threadMessages = this.getMessagesForThread(threadId);
|
|
3504
3622
|
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);
|
|
3505
3623
|
}
|
|
3624
|
+
async claimPendingMessages(threadId, scope, options) {
|
|
3625
|
+
const threadMessages = this.getMessagesForThread(threadId);
|
|
3626
|
+
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);
|
|
3627
|
+
const limit = options.limit === void 0 ? void 0 : Math.max(0, Math.floor(options.limit));
|
|
3628
|
+
const selected = limit === void 0 ? candidates : candidates.slice(0, limit);
|
|
3629
|
+
const now = this.now();
|
|
3630
|
+
for (const message of selected) {
|
|
3631
|
+
message.status = "processing";
|
|
3632
|
+
message.lockedBy = options.owner;
|
|
3633
|
+
message.lockedAt = new Date(now);
|
|
3634
|
+
message.leaseExpiresAt = new Date(now + options.ttlMs);
|
|
3635
|
+
}
|
|
3636
|
+
return selected.map(clonePendingMessage);
|
|
3637
|
+
}
|
|
3638
|
+
async reclaimExpiredProcessing(threadId, scope) {
|
|
3639
|
+
const messages = this.messages.get(threadId);
|
|
3640
|
+
if (!messages) return 0;
|
|
3641
|
+
const now = this.now();
|
|
3642
|
+
let count = 0;
|
|
3643
|
+
for (const msg of messages) {
|
|
3644
|
+
if (msg.status === "processing" && this.inScope(msg, scope) && msg.leaseExpiresAt !== void 0 && msg.leaseExpiresAt.getTime() <= now) {
|
|
3645
|
+
msg.status = "pending";
|
|
3646
|
+
msg.lockedBy = void 0;
|
|
3647
|
+
msg.lockedAt = void 0;
|
|
3648
|
+
msg.leaseExpiresAt = void 0;
|
|
3649
|
+
count += 1;
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
return count;
|
|
3653
|
+
}
|
|
3506
3654
|
async getQueueSize(threadId, scope) {
|
|
3507
3655
|
const pending = await this.getPendingMessages(threadId, scope);
|
|
3508
3656
|
return pending.length;
|
|
@@ -3566,6 +3714,9 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
3566
3714
|
for (const msg of messages) {
|
|
3567
3715
|
if (msg.status === "processing" && this.inScope(msg, scope)) {
|
|
3568
3716
|
msg.status = "pending";
|
|
3717
|
+
msg.lockedBy = void 0;
|
|
3718
|
+
msg.lockedAt = void 0;
|
|
3719
|
+
msg.leaseExpiresAt = void 0;
|
|
3569
3720
|
count++;
|
|
3570
3721
|
}
|
|
3571
3722
|
}
|
|
@@ -4824,6 +4975,8 @@ var defaultProjectBotMembershipStore = new InMemoryProjectBotMembershipStore(def
|
|
|
4824
4975
|
var defaultProjectRoomMessageStore = new InMemoryProjectRoomMessageStore(defaultProjectRoomCoordinator);
|
|
4825
4976
|
var defaultProjectRoomReadStateStore = new InMemoryProjectRoomReadStateStore();
|
|
4826
4977
|
var defaultUserPushSubscriptionStore = new InMemoryUserPushSubscriptionStore();
|
|
4978
|
+
var defaultLeaseStore = new InMemoryLeaseStore();
|
|
4979
|
+
var defaultOutboxStore = new InMemoryOutboxStore();
|
|
4827
4980
|
storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
|
|
4828
4981
|
storeLatticeManager.registerLattice(
|
|
4829
4982
|
"default",
|
|
@@ -4845,6 +4998,8 @@ storeLatticeManager.registerLattice("default", "projectBotMembership", defaultPr
|
|
|
4845
4998
|
storeLatticeManager.registerLattice("default", "projectRoomMessage", defaultProjectRoomMessageStore);
|
|
4846
4999
|
storeLatticeManager.registerLattice("default", "projectRoomReadState", defaultProjectRoomReadStateStore);
|
|
4847
5000
|
storeLatticeManager.registerLattice("default", "userPushSubscription", defaultUserPushSubscriptionStore);
|
|
5001
|
+
storeLatticeManager.registerLattice("default", "lease", defaultLeaseStore);
|
|
5002
|
+
storeLatticeManager.registerLattice("default", "outbox", defaultOutboxStore);
|
|
4848
5003
|
var defaultUserStore = new InMemoryUserStore();
|
|
4849
5004
|
var defaultTenantStore = new InMemoryTenantStore();
|
|
4850
5005
|
var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
|
|
@@ -6713,8 +6868,8 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
6713
6868
|
} catch {
|
|
6714
6869
|
}
|
|
6715
6870
|
const tenantConfigs = this.configs.get(tenantId2);
|
|
6716
|
-
const
|
|
6717
|
-
if (
|
|
6871
|
+
const cached2 = tenantConfigs?.get(key5);
|
|
6872
|
+
if (cached2) return cached2;
|
|
6718
6873
|
throw new Error(`Metrics server '${key5}' not found for tenant '${tenantId2}'`);
|
|
6719
6874
|
}
|
|
6720
6875
|
/**
|
|
@@ -8024,8 +8179,8 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
8024
8179
|
getLatticeType() {
|
|
8025
8180
|
return "sandbox_manager";
|
|
8026
8181
|
}
|
|
8027
|
-
registerLattice(key5,
|
|
8028
|
-
this.register(key5,
|
|
8182
|
+
registerLattice(key5, provider2) {
|
|
8183
|
+
this.register(key5, provider2);
|
|
8029
8184
|
}
|
|
8030
8185
|
getSandboxLattice(key5) {
|
|
8031
8186
|
const lattice = this.get(key5);
|
|
@@ -8076,8 +8231,8 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
8076
8231
|
return this.getVolumeBackendForPath(config, "/project");
|
|
8077
8232
|
}
|
|
8078
8233
|
async getVolumeBackendForPath(config, filePath) {
|
|
8079
|
-
const
|
|
8080
|
-
if (!
|
|
8234
|
+
const provider2 = this._requireProvider();
|
|
8235
|
+
if (!provider2.createVolumeFsClient) {
|
|
8081
8236
|
console.log(`[getVolumeBackendForPath] provider has no createVolumeFsClient, returning null`);
|
|
8082
8237
|
return null;
|
|
8083
8238
|
}
|
|
@@ -8088,7 +8243,7 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
8088
8243
|
return null;
|
|
8089
8244
|
}
|
|
8090
8245
|
console.log(`[getVolumeBackendForPath] path=${filePath} volume=${mapping.volumeName} prefix=${mapping.pathPrefix}`);
|
|
8091
|
-
const client =
|
|
8246
|
+
const client = provider2.createVolumeFsClient(mapping.volumeName, mapping.pathPrefix);
|
|
8092
8247
|
return new VolumeFilesystem(stripPrefixClient(client, mapping.pathPrefix), mapping.pathPrefix);
|
|
8093
8248
|
}
|
|
8094
8249
|
_resolveVolumeForPath(config, tenantId2, filePath) {
|
|
@@ -8123,35 +8278,35 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
8123
8278
|
};
|
|
8124
8279
|
}
|
|
8125
8280
|
async createSandbox(name, config) {
|
|
8126
|
-
const
|
|
8127
|
-
return
|
|
8281
|
+
const provider2 = this._requireProvider();
|
|
8282
|
+
return provider2.createSandbox(name, config);
|
|
8128
8283
|
}
|
|
8129
8284
|
async getSandbox(name) {
|
|
8130
|
-
const
|
|
8131
|
-
return
|
|
8285
|
+
const provider2 = this._requireProvider();
|
|
8286
|
+
return provider2.getSandbox(name);
|
|
8132
8287
|
}
|
|
8133
8288
|
async stopSandbox(name) {
|
|
8134
|
-
const
|
|
8135
|
-
return
|
|
8289
|
+
const provider2 = this._requireProvider();
|
|
8290
|
+
return provider2.stopSandbox(name);
|
|
8136
8291
|
}
|
|
8137
8292
|
async deleteSandbox(name) {
|
|
8138
|
-
const
|
|
8139
|
-
return
|
|
8293
|
+
const provider2 = this._requireProvider();
|
|
8294
|
+
return provider2.deleteSandbox(name);
|
|
8140
8295
|
}
|
|
8141
8296
|
async listSandboxes() {
|
|
8142
|
-
const
|
|
8143
|
-
return
|
|
8297
|
+
const provider2 = this._requireProvider();
|
|
8298
|
+
return provider2.listSandboxes();
|
|
8144
8299
|
}
|
|
8145
8300
|
_requireProvider() {
|
|
8146
8301
|
const keys = this.keysByTenant("default");
|
|
8147
8302
|
if (keys.length === 0) {
|
|
8148
8303
|
throw new Error("Sandbox provider not configured.");
|
|
8149
8304
|
}
|
|
8150
|
-
const
|
|
8151
|
-
if (!
|
|
8305
|
+
const provider2 = this.get(keys[0]);
|
|
8306
|
+
if (!provider2) {
|
|
8152
8307
|
throw new Error("Sandbox provider not configured.");
|
|
8153
8308
|
}
|
|
8154
|
-
return
|
|
8309
|
+
return provider2;
|
|
8155
8310
|
}
|
|
8156
8311
|
/**
|
|
8157
8312
|
* Returns the first registered (default) sandbox provider.
|
|
@@ -8181,6 +8336,46 @@ import { tool as tool14 } from "langchain";
|
|
|
8181
8336
|
// src/tool_lattice/shell_exec/index.ts
|
|
8182
8337
|
import z17 from "zod";
|
|
8183
8338
|
import { tool as tool15 } from "langchain";
|
|
8339
|
+
|
|
8340
|
+
// src/sandbox_lattice/sandboxOpenCredential.ts
|
|
8341
|
+
var SANDBOX_OPEN_GATEWAY_URL_ENV = "API_GATEWAY_URL";
|
|
8342
|
+
var SANDBOX_OPEN_TOKEN_ENV = "OPEN_API_TOKEN";
|
|
8343
|
+
var provider;
|
|
8344
|
+
var providerErrorHandler;
|
|
8345
|
+
function registerSandboxOpenCredentialProvider(next, options = {}) {
|
|
8346
|
+
provider = next;
|
|
8347
|
+
providerErrorHandler = options.onError;
|
|
8348
|
+
return () => {
|
|
8349
|
+
if (provider === next) {
|
|
8350
|
+
provider = void 0;
|
|
8351
|
+
providerErrorHandler = void 0;
|
|
8352
|
+
}
|
|
8353
|
+
};
|
|
8354
|
+
}
|
|
8355
|
+
async function getSandboxOpenCredential(context) {
|
|
8356
|
+
if (!provider) return void 0;
|
|
8357
|
+
try {
|
|
8358
|
+
return await provider(context);
|
|
8359
|
+
} catch (error) {
|
|
8360
|
+
try {
|
|
8361
|
+
providerErrorHandler?.(error);
|
|
8362
|
+
} catch {
|
|
8363
|
+
}
|
|
8364
|
+
return void 0;
|
|
8365
|
+
}
|
|
8366
|
+
}
|
|
8367
|
+
function buildSandboxOpenEnv(credential) {
|
|
8368
|
+
return `export ${SANDBOX_OPEN_GATEWAY_URL_ENV}=${shellSingleQuote(credential.gatewayUrl)} && export ${SANDBOX_OPEN_TOKEN_ENV}=${shellSingleQuote(credential.token)}`;
|
|
8369
|
+
}
|
|
8370
|
+
function shellSingleQuote(value) {
|
|
8371
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
8372
|
+
}
|
|
8373
|
+
function clearSandboxOpenCredentialProviderForTests() {
|
|
8374
|
+
provider = void 0;
|
|
8375
|
+
providerErrorHandler = void 0;
|
|
8376
|
+
}
|
|
8377
|
+
|
|
8378
|
+
// src/tool_lattice/shell_exec/index.ts
|
|
8184
8379
|
var SHELL_EXEC_DESCRIPTION = `Execute a shell command in the sandbox environment.
|
|
8185
8380
|
|
|
8186
8381
|
Use this to run CLI tools, install packages, inspect files, or perform any operation that requires a shell.
|
|
@@ -8213,8 +8408,19 @@ var createShellExecTool = ({
|
|
|
8213
8408
|
projectId: runConfig.projectId,
|
|
8214
8409
|
vmIsolation
|
|
8215
8410
|
});
|
|
8411
|
+
const tenantId2 = runConfig.tenantId;
|
|
8412
|
+
const credential = tenantId2 ? await getSandboxOpenCredential({
|
|
8413
|
+
tenantId: tenantId2,
|
|
8414
|
+
workspaceId: runConfig.workspaceId,
|
|
8415
|
+
projectId: runConfig.projectId,
|
|
8416
|
+
sandboxName: sandbox.name,
|
|
8417
|
+
assistantId: runConfig.assistant_id || void 0,
|
|
8418
|
+
threadId: runConfig.thread_id || void 0,
|
|
8419
|
+
depth: runConfig.depth
|
|
8420
|
+
}) : void 0;
|
|
8421
|
+
const command = credential ? `${buildSandboxOpenEnv(credential)} && ${input.command}` : input.command;
|
|
8216
8422
|
const executeResult = await sandbox.shell.execCommand({
|
|
8217
|
-
command
|
|
8423
|
+
command,
|
|
8218
8424
|
exec_dir: input.exec_dir,
|
|
8219
8425
|
timeout: input.timeout ?? 300
|
|
8220
8426
|
});
|
|
@@ -12952,13 +13158,23 @@ var SandboxPluginExecutor = class {
|
|
|
12952
13158
|
validateRelativePath(args.handler, "handler");
|
|
12953
13159
|
const pluginDir = `${PLUGINS_ROOT}/${args.manifest.type}`;
|
|
12954
13160
|
const handlerAbs = `${pluginDir}/${args.handler}`;
|
|
13161
|
+
const tenantId2 = args.runConfig?.tenantId ?? args.context.tenantId;
|
|
12955
13162
|
const sandbox = await this.deps.resolveSandbox({
|
|
12956
|
-
tenantId:
|
|
13163
|
+
tenantId: tenantId2,
|
|
12957
13164
|
assistantId: args.runConfig?.assistantId,
|
|
12958
13165
|
threadId: args.runConfig?.threadId,
|
|
12959
13166
|
workspaceId: args.runConfig?.workspaceId,
|
|
12960
13167
|
projectId: args.runConfig?.projectId
|
|
12961
13168
|
});
|
|
13169
|
+
const openCredential = tenantId2 ? await getSandboxOpenCredential({
|
|
13170
|
+
tenantId: tenantId2,
|
|
13171
|
+
workspaceId: args.runConfig?.workspaceId,
|
|
13172
|
+
projectId: args.runConfig?.projectId,
|
|
13173
|
+
sandboxName: sandbox.name,
|
|
13174
|
+
assistantId: args.runConfig?.assistantId,
|
|
13175
|
+
threadId: args.runConfig?.threadId,
|
|
13176
|
+
depth: args.runConfig?.depth
|
|
13177
|
+
}) : void 0;
|
|
12962
13178
|
const timeoutMs = clamp(args.timeoutMs ?? DEFAULT_TIMEOUT_MS, MIN_TIMEOUT_MS, MAX_TIMEOUT_MS);
|
|
12963
13179
|
const cap = clamp(
|
|
12964
13180
|
args.maxResultBytes ?? DEFAULT_MAX_RESULT_BYTES,
|
|
@@ -12989,6 +13205,12 @@ var SandboxPluginExecutor = class {
|
|
|
12989
13205
|
envParts.push(`PLUGIN_CONNECTION_FILE=${quotePosixShellArg(connectionFile)}`);
|
|
12990
13206
|
}
|
|
12991
13207
|
envParts.push(`PLUGIN_CONTEXT=${quotePosixShellArg(encode(args.context))}`);
|
|
13208
|
+
if (openCredential) {
|
|
13209
|
+
envParts.push(
|
|
13210
|
+
`${SANDBOX_OPEN_GATEWAY_URL_ENV}=${quotePosixShellArg(openCredential.gatewayUrl)}`
|
|
13211
|
+
);
|
|
13212
|
+
envParts.push(`${SANDBOX_OPEN_TOKEN_ENV}=${quotePosixShellArg(openCredential.token)}`);
|
|
13213
|
+
}
|
|
12992
13214
|
const command = `${envParts.join(" ")} node ${quotePosixShellArg(handlerAbs)}`;
|
|
12993
13215
|
const execResult = await sandbox.shell.execCommand({
|
|
12994
13216
|
command,
|
|
@@ -13940,10 +14162,10 @@ var TenantPluginCatalog = class {
|
|
|
13940
14162
|
candidates.push({ type, dirPath: dir.path, raw, manifestJson, files: dirFiles });
|
|
13941
14163
|
}
|
|
13942
14164
|
const hash = createHash3("sha256").update(hashParts.sort().join("\n")).digest("hex").slice(0, 16);
|
|
13943
|
-
const
|
|
13944
|
-
if (
|
|
13945
|
-
this.cache.set(tenantId2, { value:
|
|
13946
|
-
return
|
|
14165
|
+
const cached2 = this.cache.get(tenantId2)?.value;
|
|
14166
|
+
if (cached2 && cached2.hash === hash) {
|
|
14167
|
+
this.cache.set(tenantId2, { value: cached2, checkedAt: this.now() });
|
|
14168
|
+
return cached2;
|
|
13947
14169
|
}
|
|
13948
14170
|
const plugins = [];
|
|
13949
14171
|
const manifests = {};
|
|
@@ -15304,7 +15526,7 @@ var AgentWorkerState = Annotation.Root({
|
|
|
15304
15526
|
default: () => ({})
|
|
15305
15527
|
}),
|
|
15306
15528
|
command2: Annotation({
|
|
15307
|
-
reducer: (
|
|
15529
|
+
reducer: (_x, y) => y,
|
|
15308
15530
|
default: () => void 0
|
|
15309
15531
|
}),
|
|
15310
15532
|
// RunConfig for passing configuration through the graph
|
|
@@ -15321,12 +15543,12 @@ var AgentWorkerState = Annotation.Root({
|
|
|
15321
15543
|
}),
|
|
15322
15544
|
// Execution result
|
|
15323
15545
|
result: Annotation({
|
|
15324
|
-
reducer: (
|
|
15546
|
+
reducer: (_x, y) => y,
|
|
15325
15547
|
default: () => void 0
|
|
15326
15548
|
}),
|
|
15327
15549
|
// Interrupt data
|
|
15328
15550
|
interruptValue: Annotation({
|
|
15329
|
-
reducer: (
|
|
15551
|
+
reducer: (_x, y) => y,
|
|
15330
15552
|
default: () => void 0
|
|
15331
15553
|
}),
|
|
15332
15554
|
// Final state to return
|
|
@@ -17016,6 +17238,71 @@ var CapabilityRuntimeResolver = class {
|
|
|
17016
17238
|
// src/services/TrustedAgentDispatchCapability.ts
|
|
17017
17239
|
var TRUSTED_AGENT_DISPATCH = Symbol("axiom.trustedAgentDispatch");
|
|
17018
17240
|
|
|
17241
|
+
// src/services/threadRunLease.ts
|
|
17242
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
17243
|
+
function threadRunLeaseKey(tenantId2, assistantId, threadId) {
|
|
17244
|
+
return `thread-run:${tenantId2}:${assistantId}:${threadId}`;
|
|
17245
|
+
}
|
|
17246
|
+
async function tryAcquireThreadRun(input) {
|
|
17247
|
+
const key5 = threadRunLeaseKey(input.tenantId, input.assistantId, input.threadId);
|
|
17248
|
+
const holder = `${input.owner}#${randomUUID6()}`;
|
|
17249
|
+
if (!await input.store.tryAcquire(key5, holder, input.ttlMs)) return null;
|
|
17250
|
+
const heartbeatMs = input.heartbeatMs ?? Math.max(1e3, Math.floor(input.ttlMs / 3));
|
|
17251
|
+
let released = false;
|
|
17252
|
+
let lost = false;
|
|
17253
|
+
const heartbeat = setInterval(() => {
|
|
17254
|
+
void input.store.renew(key5, holder, input.ttlMs).then((renewed) => {
|
|
17255
|
+
if (released || renewed || lost) return;
|
|
17256
|
+
lost = true;
|
|
17257
|
+
try {
|
|
17258
|
+
input.onLost?.();
|
|
17259
|
+
} catch {
|
|
17260
|
+
}
|
|
17261
|
+
}).catch(() => void 0);
|
|
17262
|
+
}, heartbeatMs);
|
|
17263
|
+
heartbeat.unref?.();
|
|
17264
|
+
return {
|
|
17265
|
+
get lost() {
|
|
17266
|
+
return lost;
|
|
17267
|
+
},
|
|
17268
|
+
release: async () => {
|
|
17269
|
+
if (released) return;
|
|
17270
|
+
released = true;
|
|
17271
|
+
clearInterval(heartbeat);
|
|
17272
|
+
await input.store.release(key5, holder).catch(() => void 0);
|
|
17273
|
+
}
|
|
17274
|
+
};
|
|
17275
|
+
}
|
|
17276
|
+
async function getThreadRunOwner(input) {
|
|
17277
|
+
let store = input.store;
|
|
17278
|
+
if (!store) {
|
|
17279
|
+
try {
|
|
17280
|
+
store = storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
17281
|
+
} catch {
|
|
17282
|
+
return null;
|
|
17283
|
+
}
|
|
17284
|
+
}
|
|
17285
|
+
try {
|
|
17286
|
+
const record = await store.get(threadRunLeaseKey(input.tenantId, input.assistantId, input.threadId));
|
|
17287
|
+
if (!record) return null;
|
|
17288
|
+
const hash = record.holder.lastIndexOf("#");
|
|
17289
|
+
return hash > 0 ? record.holder.slice(0, hash) : record.holder;
|
|
17290
|
+
} catch {
|
|
17291
|
+
return null;
|
|
17292
|
+
}
|
|
17293
|
+
}
|
|
17294
|
+
|
|
17295
|
+
// src/services/replicaIdentity.ts
|
|
17296
|
+
import os from "os";
|
|
17297
|
+
var cached;
|
|
17298
|
+
function getReplicaId() {
|
|
17299
|
+
cached ?? (cached = process.env.AXIOM_REPLICA_ID?.trim() || `${os.hostname()}:${process.pid}`);
|
|
17300
|
+
return cached;
|
|
17301
|
+
}
|
|
17302
|
+
function resetReplicaIdForTests() {
|
|
17303
|
+
cached = void 0;
|
|
17304
|
+
}
|
|
17305
|
+
|
|
17019
17306
|
// src/services/Agent.ts
|
|
17020
17307
|
var ThreadStatus2 = /* @__PURE__ */ ((ThreadStatus3) => {
|
|
17021
17308
|
ThreadStatus3["IDLE"] = "idle";
|
|
@@ -17333,6 +17620,10 @@ function checkpointCapabilityRevision(state) {
|
|
|
17333
17620
|
var QUEUE_PROCESSOR_RETRY_BASE_MS = 100;
|
|
17334
17621
|
var QUEUE_PROCESSOR_MAX_RETRIES = 3;
|
|
17335
17622
|
var AGENT_RECURSION_LIMIT = 1e3;
|
|
17623
|
+
var THREAD_RUN_LEASE_TTL_MS = 6e4;
|
|
17624
|
+
var THREAD_RUN_LEASE_RETRY_BASE_MS = 150;
|
|
17625
|
+
var THREAD_RUN_LEASE_RETRY_CAP_MS = 1500;
|
|
17626
|
+
var THREAD_RUN_LEASE_MAX_RETRIES = 12;
|
|
17336
17627
|
function hasExactKeys(record, required, optional = []) {
|
|
17337
17628
|
const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
|
|
17338
17629
|
return required.every((key5) => Object.prototype.hasOwnProperty.call(record, key5)) && Reflect.ownKeys(record).every((key5) => typeof key5 === "string" && allowed.has(key5));
|
|
@@ -17362,6 +17653,13 @@ var Agent = class {
|
|
|
17362
17653
|
this.queueProcessorRetryAttempt = 0;
|
|
17363
17654
|
this.queueProcessorGeneration = 0;
|
|
17364
17655
|
this.queueWakeRequested = false;
|
|
17656
|
+
/**
|
|
17657
|
+
* Thread-run ownership lease held while this replica is actively processing
|
|
17658
|
+
* the thread. Acquired non-blockingly in {@link startQueueProcessor}; released
|
|
17659
|
+
* exactly once when the processor definitively stops.
|
|
17660
|
+
*/
|
|
17661
|
+
this.threadRunLease = null;
|
|
17662
|
+
this.threadRunLeaseRetryAttempt = 0;
|
|
17365
17663
|
this.asyncTasks = [];
|
|
17366
17664
|
this.agentExecutor = async ({ input, command, custom_run_config, expected_capability_revision, trusted_run_context }, signal) => {
|
|
17367
17665
|
const { runnable_agent, runConfig } = await this.getLatticeClientAndRuntimeConfig(
|
|
@@ -17478,7 +17776,7 @@ var Agent = class {
|
|
|
17478
17776
|
}
|
|
17479
17777
|
};
|
|
17480
17778
|
this.waitingForQueueEnd = async (signal) => {
|
|
17481
|
-
while (!signal?.aborted) {
|
|
17779
|
+
while (!signal?.aborted && !this.threadRunLease?.lost) {
|
|
17482
17780
|
const pendings = await this.getPendingMessages();
|
|
17483
17781
|
if (pendings.length === 0) {
|
|
17484
17782
|
const state = await this.getCurrentState();
|
|
@@ -18309,6 +18607,29 @@ var Agent = class {
|
|
|
18309
18607
|
}
|
|
18310
18608
|
return this.queueStore;
|
|
18311
18609
|
}
|
|
18610
|
+
/**
|
|
18611
|
+
* Resolves the shared lease store used to serialize thread runs across
|
|
18612
|
+
* Gateway replicas. Returns `undefined` when no lease store is registered so
|
|
18613
|
+
* single-process deployments keep running unconditionally.
|
|
18614
|
+
*/
|
|
18615
|
+
getLeaseStore() {
|
|
18616
|
+
try {
|
|
18617
|
+
return storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
18618
|
+
} catch {
|
|
18619
|
+
return void 0;
|
|
18620
|
+
}
|
|
18621
|
+
}
|
|
18622
|
+
/**
|
|
18623
|
+
* Releases this replica's thread-run ownership lease, if held.
|
|
18624
|
+
*
|
|
18625
|
+
* @remarks Safe to call from any definitive-stop path; a second call is a
|
|
18626
|
+
* no-op. The handle's unique holder makes a stale release harmless.
|
|
18627
|
+
*/
|
|
18628
|
+
async releaseThreadRunLease() {
|
|
18629
|
+
const lease = this.threadRunLease;
|
|
18630
|
+
this.threadRunLease = null;
|
|
18631
|
+
if (lease) await lease.release();
|
|
18632
|
+
}
|
|
18312
18633
|
getDefaultQueueConfig() {
|
|
18313
18634
|
return {
|
|
18314
18635
|
mode: "collect" /* COLLECT */,
|
|
@@ -18334,6 +18655,8 @@ var Agent = class {
|
|
|
18334
18655
|
*/
|
|
18335
18656
|
stopQueueProcessor() {
|
|
18336
18657
|
this.cancelQueueProcessorRetry();
|
|
18658
|
+
this.cancelThreadRunLeaseRetry();
|
|
18659
|
+
void this.releaseThreadRunLease();
|
|
18337
18660
|
this.clearRecoveryBlock();
|
|
18338
18661
|
this.queueProcessorGeneration += 1;
|
|
18339
18662
|
if (this.abortController) {
|
|
@@ -18481,16 +18804,50 @@ var Agent = class {
|
|
|
18481
18804
|
startQueueProcessorIfNeeded() {
|
|
18482
18805
|
return this.startQueueProcessor(true);
|
|
18483
18806
|
}
|
|
18484
|
-
startQueueProcessor(freshWakeup) {
|
|
18807
|
+
async startQueueProcessor(freshWakeup) {
|
|
18485
18808
|
this.queueWakeRequested = true;
|
|
18486
18809
|
if (this.queueProcessorPromise) return this.queueProcessorPromise;
|
|
18487
|
-
if (this.queueProcessorRetryTimer) return
|
|
18810
|
+
if (this.queueProcessorRetryTimer) return;
|
|
18488
18811
|
if (freshWakeup && this.queueProcessorRetryAttempt >= QUEUE_PROCESSOR_MAX_RETRIES) {
|
|
18489
18812
|
this.queueProcessorRetryAttempt = 0;
|
|
18490
18813
|
}
|
|
18814
|
+
if (freshWakeup && this.threadRunLeaseRetryAttempt >= THREAD_RUN_LEASE_MAX_RETRIES) {
|
|
18815
|
+
this.threadRunLeaseRetryAttempt = 0;
|
|
18816
|
+
}
|
|
18491
18817
|
this.queueWakeRequested = false;
|
|
18492
|
-
let processorFailed = false;
|
|
18493
18818
|
const processorGeneration = this.queueProcessorGeneration;
|
|
18819
|
+
if (this.threadRunLease?.lost) await this.releaseThreadRunLease();
|
|
18820
|
+
let acquiredLeaseHere = false;
|
|
18821
|
+
if (this.threadRunLease === null) {
|
|
18822
|
+
const leaseStore = this.getLeaseStore();
|
|
18823
|
+
if (leaseStore) {
|
|
18824
|
+
const lease = await tryAcquireThreadRun({
|
|
18825
|
+
store: leaseStore,
|
|
18826
|
+
tenantId: this.tenant_id,
|
|
18827
|
+
assistantId: this.assistant_id,
|
|
18828
|
+
threadId: this.thread_id,
|
|
18829
|
+
owner: getReplicaId(),
|
|
18830
|
+
ttlMs: THREAD_RUN_LEASE_TTL_MS,
|
|
18831
|
+
onLost: () => {
|
|
18832
|
+
console.warn(`[Agent] Thread-run lease lost for thread ${this.thread_id}; aborting the held run`);
|
|
18833
|
+
this.abortController?.abort();
|
|
18834
|
+
}
|
|
18835
|
+
});
|
|
18836
|
+
if (!lease) {
|
|
18837
|
+
this.scheduleThreadRunLeaseRetry();
|
|
18838
|
+
return;
|
|
18839
|
+
}
|
|
18840
|
+
this.threadRunLease = lease;
|
|
18841
|
+
acquiredLeaseHere = true;
|
|
18842
|
+
this.cancelThreadRunLeaseRetry();
|
|
18843
|
+
}
|
|
18844
|
+
}
|
|
18845
|
+
if (this.queueProcessorPromise) return this.queueProcessorPromise;
|
|
18846
|
+
if (this.queueProcessorGeneration !== processorGeneration) {
|
|
18847
|
+
if (acquiredLeaseHere) await this.releaseThreadRunLease();
|
|
18848
|
+
return;
|
|
18849
|
+
}
|
|
18850
|
+
let processorFailed = false;
|
|
18494
18851
|
const processor = this.runQueueProcessor().catch(async (error) => {
|
|
18495
18852
|
processorFailed = true;
|
|
18496
18853
|
console.error(`Queue processing error for thread ${this.thread_id}:`, error);
|
|
@@ -18508,7 +18865,11 @@ var Agent = class {
|
|
|
18508
18865
|
if (this.queueWakeRequested) void this.startQueueProcessor(false);
|
|
18509
18866
|
return;
|
|
18510
18867
|
}
|
|
18511
|
-
if (failed)
|
|
18868
|
+
if (failed) {
|
|
18869
|
+
this.cancelThreadRunLeaseRetry();
|
|
18870
|
+
await this.releaseThreadRunLease();
|
|
18871
|
+
return;
|
|
18872
|
+
}
|
|
18512
18873
|
this.queueProcessorRetryAttempt = 0;
|
|
18513
18874
|
if (this.queueWakeRequested) {
|
|
18514
18875
|
void this.startQueueProcessor(false);
|
|
@@ -18521,7 +18882,11 @@ var Agent = class {
|
|
|
18521
18882
|
void this.startQueueProcessor(false);
|
|
18522
18883
|
return;
|
|
18523
18884
|
}
|
|
18524
|
-
if (pendingMessages.length === 0)
|
|
18885
|
+
if (pendingMessages.length === 0) {
|
|
18886
|
+
this.cancelThreadRunLeaseRetry();
|
|
18887
|
+
await this.releaseThreadRunLease();
|
|
18888
|
+
return;
|
|
18889
|
+
}
|
|
18525
18890
|
const processingMessages = await this.getQueueStore().getProcessingMessages(
|
|
18526
18891
|
this.thread_id,
|
|
18527
18892
|
this.queueScope()
|
|
@@ -18533,12 +18898,20 @@ var Agent = class {
|
|
|
18533
18898
|
}
|
|
18534
18899
|
if (processingMessages.length > 0) {
|
|
18535
18900
|
const runStatus = await this.getRunStatus();
|
|
18536
|
-
if (runStatus === "busy" /* BUSY */ || runStatus === "interrupted" /* INTERRUPTED */)
|
|
18901
|
+
if (runStatus === "busy" /* BUSY */ || runStatus === "interrupted" /* INTERRUPTED */) {
|
|
18902
|
+
this.cancelThreadRunLeaseRetry();
|
|
18903
|
+
await this.releaseThreadRunLease();
|
|
18904
|
+
return;
|
|
18905
|
+
}
|
|
18537
18906
|
}
|
|
18538
18907
|
void this.startQueueProcessor(false);
|
|
18539
18908
|
} catch (error) {
|
|
18540
18909
|
console.error(`Queue processor finalization failed for thread ${this.thread_id}:`, error);
|
|
18541
18910
|
await this.scheduleQueueProcessorRetry(error, generation);
|
|
18911
|
+
if (!this.queueProcessorPromise) {
|
|
18912
|
+
await this.releaseThreadRunLease();
|
|
18913
|
+
this.cancelThreadRunLeaseRetry();
|
|
18914
|
+
}
|
|
18542
18915
|
}
|
|
18543
18916
|
}
|
|
18544
18917
|
async scheduleQueueProcessorRetry(error, generation) {
|
|
@@ -18576,6 +18949,36 @@ var Agent = class {
|
|
|
18576
18949
|
this.queueProcessorRetryAttempt = 0;
|
|
18577
18950
|
this.queueWakeRequested = false;
|
|
18578
18951
|
}
|
|
18952
|
+
/**
|
|
18953
|
+
* Bounded re-attempt after losing the thread-run lease to a peer. Covers the
|
|
18954
|
+
* narrow window where the peer releases the lease without having observed a
|
|
18955
|
+
* just-enqueued message. Bounded so a genuinely long-held thread does not make
|
|
18956
|
+
* this replica poll forever — the owning replica's loop drains new messages.
|
|
18957
|
+
*/
|
|
18958
|
+
scheduleThreadRunLeaseRetry() {
|
|
18959
|
+
if (this.threadRunLeaseRetryTimer || this.threadRunLeaseRetryAttempt >= THREAD_RUN_LEASE_MAX_RETRIES) return;
|
|
18960
|
+
const delay = Math.min(
|
|
18961
|
+
THREAD_RUN_LEASE_RETRY_BASE_MS * 2 ** this.threadRunLeaseRetryAttempt,
|
|
18962
|
+
THREAD_RUN_LEASE_RETRY_CAP_MS
|
|
18963
|
+
);
|
|
18964
|
+
this.threadRunLeaseRetryAttempt += 1;
|
|
18965
|
+
this.threadRunLeaseRetryTimer = setTimeout(() => {
|
|
18966
|
+
this.threadRunLeaseRetryTimer = void 0;
|
|
18967
|
+
void this.startQueueProcessor(false);
|
|
18968
|
+
}, delay);
|
|
18969
|
+
}
|
|
18970
|
+
/**
|
|
18971
|
+
* Clears any pending thread-run lease retry and resets its backoff budget.
|
|
18972
|
+
*
|
|
18973
|
+
* @remarks Called on lease acquisition and on every definitive processor
|
|
18974
|
+
* stop so the next enqueue starts from the base delay. Never called on
|
|
18975
|
+
* continue/re-arm paths, which must preserve the bounded budget.
|
|
18976
|
+
*/
|
|
18977
|
+
cancelThreadRunLeaseRetry() {
|
|
18978
|
+
if (this.threadRunLeaseRetryTimer) clearTimeout(this.threadRunLeaseRetryTimer);
|
|
18979
|
+
this.threadRunLeaseRetryTimer = void 0;
|
|
18980
|
+
this.threadRunLeaseRetryAttempt = 0;
|
|
18981
|
+
}
|
|
18579
18982
|
async runQueueProcessor() {
|
|
18580
18983
|
const store = this.getQueueStore();
|
|
18581
18984
|
const processingMessages = await store.getProcessingMessages(this.thread_id, this.queueScope());
|
|
@@ -18720,6 +19123,38 @@ var Agent = class {
|
|
|
18720
19123
|
console.error(`[Agent] Failed to initialize agent lattice for ${this.assistant_id} (tenant: ${this.tenant_id}):`, error);
|
|
18721
19124
|
throw error;
|
|
18722
19125
|
}
|
|
19126
|
+
let acquiredLeaseHere = false;
|
|
19127
|
+
if (this.threadRunLease === null) {
|
|
19128
|
+
const leaseStore = this.getLeaseStore();
|
|
19129
|
+
if (leaseStore) {
|
|
19130
|
+
const lease = await tryAcquireThreadRun({
|
|
19131
|
+
store: leaseStore,
|
|
19132
|
+
tenantId: this.tenant_id,
|
|
19133
|
+
assistantId: this.assistant_id,
|
|
19134
|
+
threadId: this.thread_id,
|
|
19135
|
+
owner: getReplicaId(),
|
|
19136
|
+
ttlMs: THREAD_RUN_LEASE_TTL_MS,
|
|
19137
|
+
onLost: () => {
|
|
19138
|
+
console.warn(`[Agent] Thread-run lease lost for thread ${this.thread_id}; aborting the held run`);
|
|
19139
|
+
this.abortController?.abort();
|
|
19140
|
+
}
|
|
19141
|
+
});
|
|
19142
|
+
if (!lease) {
|
|
19143
|
+
return { status: await this.getRunStatus(), settled: false, leaseContended: true };
|
|
19144
|
+
}
|
|
19145
|
+
this.threadRunLease = lease;
|
|
19146
|
+
acquiredLeaseHere = true;
|
|
19147
|
+
this.cancelThreadRunLeaseRetry();
|
|
19148
|
+
}
|
|
19149
|
+
}
|
|
19150
|
+
try {
|
|
19151
|
+
return await this.resumeTaskLocked();
|
|
19152
|
+
} finally {
|
|
19153
|
+
if (acquiredLeaseHere && !this.queueProcessorPromise) await this.releaseThreadRunLease();
|
|
19154
|
+
}
|
|
19155
|
+
}
|
|
19156
|
+
/** Recovery body of {@link resumeTask}, executed while thread ownership is settled. */
|
|
19157
|
+
async resumeTaskLocked() {
|
|
18723
19158
|
const store = this.getQueueStore();
|
|
18724
19159
|
const processingMessages = await store.getProcessingMessages(this.thread_id, this.queueScope());
|
|
18725
19160
|
const preRunState = await this.getCurrentState();
|
|
@@ -18835,6 +19270,8 @@ var Agent = class {
|
|
|
18835
19270
|
*/
|
|
18836
19271
|
async abort() {
|
|
18837
19272
|
this.cancelQueueProcessorRetry();
|
|
19273
|
+
this.cancelThreadRunLeaseRetry();
|
|
19274
|
+
await this.releaseThreadRunLease();
|
|
18838
19275
|
this.clearRecoveryBlock();
|
|
18839
19276
|
this.queueProcessorGeneration += 1;
|
|
18840
19277
|
if (this.abortController) {
|
|
@@ -19494,27 +19931,27 @@ function createCheckAsyncTaskTool() {
|
|
|
19494
19931
|
if (!mainAgent) {
|
|
19495
19932
|
return "Cannot access main agent state.";
|
|
19496
19933
|
}
|
|
19497
|
-
const
|
|
19498
|
-
if (!
|
|
19934
|
+
const cached2 = mainAgent.getAsyncTask(task_id);
|
|
19935
|
+
if (!cached2) {
|
|
19499
19936
|
return `Task ${task_id} not found. Use list_async_tasks to see all tasks.`;
|
|
19500
19937
|
}
|
|
19501
19938
|
try {
|
|
19502
19939
|
if (!agentInstanceManager.hasAgent({
|
|
19503
|
-
assistant_id:
|
|
19940
|
+
assistant_id: cached2.assistantId,
|
|
19504
19941
|
thread_id: task_id,
|
|
19505
19942
|
tenant_id: mainAgent.tenant_id
|
|
19506
19943
|
})) {
|
|
19507
|
-
return `Task ${task_id}: not found (may have been cleaned up). Status was: ${
|
|
19944
|
+
return `Task ${task_id}: not found (may have been cleaned up). Status was: ${cached2.status}`;
|
|
19508
19945
|
}
|
|
19509
19946
|
const subAgent = agentInstanceManager.getAgent({
|
|
19510
|
-
assistant_id:
|
|
19947
|
+
assistant_id: cached2.assistantId,
|
|
19511
19948
|
thread_id: task_id,
|
|
19512
19949
|
tenant_id: mainAgent.tenant_id
|
|
19513
19950
|
});
|
|
19514
19951
|
const status = await subAgent.getRunStatus();
|
|
19515
19952
|
if (status === "busy") {
|
|
19516
19953
|
return `Task ${task_id}: still running.
|
|
19517
|
-
Description: ${
|
|
19954
|
+
Description: ${cached2.description}`;
|
|
19518
19955
|
}
|
|
19519
19956
|
if (status === "idle") {
|
|
19520
19957
|
const state = await subAgent.getCurrentState();
|
|
@@ -19525,21 +19962,21 @@ Description: ${cached.description}`;
|
|
|
19525
19962
|
mainAgent.updateAsyncTaskStatus(task_id, "completed");
|
|
19526
19963
|
const result = lastAI?.content ?? "(completed, no output)";
|
|
19527
19964
|
return `Task ${task_id}: COMPLETED.
|
|
19528
|
-
Description: ${
|
|
19965
|
+
Description: ${cached2.description}
|
|
19529
19966
|
Result:
|
|
19530
19967
|
${result}`;
|
|
19531
19968
|
}
|
|
19532
19969
|
if (status === "error") {
|
|
19533
19970
|
mainAgent.updateAsyncTaskStatus(task_id, "failed");
|
|
19534
19971
|
return `Task ${task_id}: failed.
|
|
19535
|
-
Description: ${
|
|
19972
|
+
Description: ${cached2.description}`;
|
|
19536
19973
|
}
|
|
19537
19974
|
if (status === "interrupted") {
|
|
19538
19975
|
return `Task ${task_id}: interrupted (waiting for input).
|
|
19539
|
-
Description: ${
|
|
19976
|
+
Description: ${cached2.description}`;
|
|
19540
19977
|
}
|
|
19541
19978
|
return `Task ${task_id}: ${status}.
|
|
19542
|
-
Description: ${
|
|
19979
|
+
Description: ${cached2.description}`;
|
|
19543
19980
|
} catch (err) {
|
|
19544
19981
|
return `Task ${task_id}: error checking status: ${err instanceof Error ? err.message : String(err)}`;
|
|
19545
19982
|
}
|
|
@@ -19612,25 +20049,25 @@ function createCancelAsyncTaskTool() {
|
|
|
19612
20049
|
if (!mainAgent) {
|
|
19613
20050
|
return "Cannot access main agent state.";
|
|
19614
20051
|
}
|
|
19615
|
-
const
|
|
19616
|
-
if (!
|
|
20052
|
+
const cached2 = mainAgent.getAsyncTask(task_id);
|
|
20053
|
+
if (!cached2) {
|
|
19617
20054
|
return `Task ${task_id} not found.`;
|
|
19618
20055
|
}
|
|
19619
20056
|
try {
|
|
19620
20057
|
const subAgentExists = agentInstanceManager.hasAgent({
|
|
19621
|
-
assistant_id:
|
|
20058
|
+
assistant_id: cached2.assistantId,
|
|
19622
20059
|
thread_id: task_id,
|
|
19623
20060
|
tenant_id: mainAgent.tenant_id
|
|
19624
20061
|
});
|
|
19625
20062
|
if (subAgentExists) {
|
|
19626
20063
|
const subAgent = agentInstanceManager.getAgent({
|
|
19627
|
-
assistant_id:
|
|
20064
|
+
assistant_id: cached2.assistantId,
|
|
19628
20065
|
thread_id: task_id,
|
|
19629
20066
|
tenant_id: mainAgent.tenant_id
|
|
19630
20067
|
});
|
|
19631
20068
|
await subAgent.abort();
|
|
19632
20069
|
agentInstanceManager.removeAgent({
|
|
19633
|
-
assistant_id:
|
|
20070
|
+
assistant_id: cached2.assistantId,
|
|
19634
20071
|
thread_id: task_id,
|
|
19635
20072
|
tenant_id: mainAgent.tenant_id
|
|
19636
20073
|
});
|
|
@@ -19879,6 +20316,48 @@ var MemoryScheduleStorage = class {
|
|
|
19879
20316
|
});
|
|
19880
20317
|
}
|
|
19881
20318
|
}
|
|
20319
|
+
/**
|
|
20320
|
+
* Atomically claims one due fire by transitioning the task `pending -> running`.
|
|
20321
|
+
*
|
|
20322
|
+
* @param taskId Task to claim.
|
|
20323
|
+
* @returns True when this caller won the claim (task was `pending`); false if
|
|
20324
|
+
* another replica already claimed it or it is not pending.
|
|
20325
|
+
*/
|
|
20326
|
+
async claimScheduledRun(taskId) {
|
|
20327
|
+
const task = this.tasks.get(taskId);
|
|
20328
|
+
if (!task || task.status !== ScheduledTaskStatus.PENDING) {
|
|
20329
|
+
return false;
|
|
20330
|
+
}
|
|
20331
|
+
this.tasks.set(taskId, {
|
|
20332
|
+
...task,
|
|
20333
|
+
status: ScheduledTaskStatus.RUNNING,
|
|
20334
|
+
updatedAt: Date.now()
|
|
20335
|
+
});
|
|
20336
|
+
return true;
|
|
20337
|
+
}
|
|
20338
|
+
/**
|
|
20339
|
+
* Requeues `running` tasks whose `updatedAt` is older than `olderThanMs` back
|
|
20340
|
+
* to `pending` (recovery after a crash that left a claim unsettled).
|
|
20341
|
+
*
|
|
20342
|
+
* @param olderThanMs Age threshold in milliseconds.
|
|
20343
|
+
* @returns The number of tasks requeued.
|
|
20344
|
+
*/
|
|
20345
|
+
async requeueStaleRunning(olderThanMs) {
|
|
20346
|
+
const now = Date.now();
|
|
20347
|
+
const cutoff = now - olderThanMs;
|
|
20348
|
+
let requeued = 0;
|
|
20349
|
+
for (const [taskId, task] of this.tasks.entries()) {
|
|
20350
|
+
if (task.status === ScheduledTaskStatus.RUNNING && task.updatedAt < cutoff) {
|
|
20351
|
+
this.tasks.set(taskId, {
|
|
20352
|
+
...task,
|
|
20353
|
+
status: ScheduledTaskStatus.PENDING,
|
|
20354
|
+
updatedAt: now
|
|
20355
|
+
});
|
|
20356
|
+
requeued++;
|
|
20357
|
+
}
|
|
20358
|
+
}
|
|
20359
|
+
return requeued;
|
|
20360
|
+
}
|
|
19882
20361
|
/**
|
|
19883
20362
|
* Delete task
|
|
19884
20363
|
*/
|
|
@@ -20243,6 +20722,7 @@ function describeCronExpression(expression) {
|
|
|
20243
20722
|
}
|
|
20244
20723
|
|
|
20245
20724
|
// src/schedule_lattice/DefaultScheduleClient.ts
|
|
20725
|
+
var STALE_RUNNING_MS = 30 * 6e4;
|
|
20246
20726
|
var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
20247
20727
|
constructor(storage) {
|
|
20248
20728
|
this.handlers = /* @__PURE__ */ new Map();
|
|
@@ -20483,6 +20963,19 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
20483
20963
|
}
|
|
20484
20964
|
// ===== Recovery =====
|
|
20485
20965
|
async restore() {
|
|
20966
|
+
try {
|
|
20967
|
+
const requeued = await this.storage.requeueStaleRunning(STALE_RUNNING_MS);
|
|
20968
|
+
if (requeued > 0) {
|
|
20969
|
+
console.log(
|
|
20970
|
+
`[Scheduler] Requeued ${requeued} stale running task(s)`
|
|
20971
|
+
);
|
|
20972
|
+
}
|
|
20973
|
+
} catch (error) {
|
|
20974
|
+
console.error(
|
|
20975
|
+
"[Scheduler] Failed to requeue stale running tasks:",
|
|
20976
|
+
error
|
|
20977
|
+
);
|
|
20978
|
+
}
|
|
20486
20979
|
const activeTasks = await this.storage.getActiveTasks();
|
|
20487
20980
|
let restored = 0;
|
|
20488
20981
|
for (const task of activeTasks) {
|
|
@@ -20543,6 +21036,16 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
20543
21036
|
});
|
|
20544
21037
|
}
|
|
20545
21038
|
async executeTask(task) {
|
|
21039
|
+
let claimed = false;
|
|
21040
|
+
try {
|
|
21041
|
+
claimed = await this.storage.claimScheduledRun(task.taskId);
|
|
21042
|
+
} catch (error) {
|
|
21043
|
+
console.error(`[Scheduler] Failed to claim task ${task.taskId}:`, error);
|
|
21044
|
+
return;
|
|
21045
|
+
}
|
|
21046
|
+
if (!claimed) {
|
|
21047
|
+
return;
|
|
21048
|
+
}
|
|
20546
21049
|
const handler = this.handlers.get(task.taskType);
|
|
20547
21050
|
if (!handler) {
|
|
20548
21051
|
console.error(
|
|
@@ -20554,9 +21057,6 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
20554
21057
|
});
|
|
20555
21058
|
return;
|
|
20556
21059
|
}
|
|
20557
|
-
await this.storage.update(task.taskId, {
|
|
20558
|
-
status: ScheduledTaskStatus2.RUNNING
|
|
20559
|
-
});
|
|
20560
21060
|
console.log(`[Scheduler] Executing task: ${task.taskId}`);
|
|
20561
21061
|
try {
|
|
20562
21062
|
const latestTask = await this.storage.get(task.taskId);
|
|
@@ -25270,8 +25770,8 @@ var VectorStoreProviderManager = class _VectorStoreProviderManager extends BaseL
|
|
|
25270
25770
|
* @param key Provider key name
|
|
25271
25771
|
* @param provider VectorStoreProvider implementation
|
|
25272
25772
|
*/
|
|
25273
|
-
registerProvider(key5,
|
|
25274
|
-
const lattice = { key: key5, provider };
|
|
25773
|
+
registerProvider(key5, provider2) {
|
|
25774
|
+
const lattice = { key: key5, provider: provider2 };
|
|
25275
25775
|
this.registerWithTenant("default", key5, lattice);
|
|
25276
25776
|
}
|
|
25277
25777
|
/**
|
|
@@ -25307,7 +25807,7 @@ var VectorStoreProviderManager = class _VectorStoreProviderManager extends BaseL
|
|
|
25307
25807
|
};
|
|
25308
25808
|
var vectorStoreProviderManager = VectorStoreProviderManager.getInstance();
|
|
25309
25809
|
vectorStoreProviderManager.registerProvider("default", new MemoryVectorStoreProvider());
|
|
25310
|
-
var registerVectorStoreProvider = (key5,
|
|
25810
|
+
var registerVectorStoreProvider = (key5, provider2) => vectorStoreProviderManager.registerProvider(key5, provider2);
|
|
25311
25811
|
var getVectorStoreProvider = (key5) => vectorStoreProviderManager.getProvider(key5);
|
|
25312
25812
|
|
|
25313
25813
|
// src/store_lattice/configureStores.ts
|
|
@@ -28009,7 +28509,110 @@ independently before the workflow's integration eval.
|
|
|
28009
28509
|
|
|
28010
28510
|
An unsupported architecture conversion interrupts the flow and requests a new
|
|
28011
28511
|
user decision. Do not route backward to the Charter or to [[agent-build]], and do
|
|
28012
|
-
not create a replacement
|
|
28512
|
+
not create a replacement.`,
|
|
28513
|
+
"ptc": `---
|
|
28514
|
+
name: ptc
|
|
28515
|
+
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.
|
|
28516
|
+
metadata:
|
|
28517
|
+
role: workflow
|
|
28518
|
+
domain: orchestration
|
|
28519
|
+
verified: unverified
|
|
28520
|
+
---
|
|
28521
|
+
|
|
28522
|
+
# Programmatic Tool Calling (PTC)
|
|
28523
|
+
|
|
28524
|
+
PTC means the model writes and runs code that calls platform tools itself, instead
|
|
28525
|
+
of calling tools one at a time. Reach for it when orchestration is multi-step,
|
|
28526
|
+
data-heavy, or needs a loop/branch that would be wasteful as a chain of model tool
|
|
28527
|
+
calls.
|
|
28528
|
+
|
|
28529
|
+
## Where the code runs
|
|
28530
|
+
|
|
28531
|
+
Run the code with \`code_eval\` (backed by \`shell_exec\`). Each execution process is
|
|
28532
|
+
injected with two environment variables:
|
|
28533
|
+
|
|
28534
|
+
- \`API_GATEWAY_URL\` \u2014 the gateway base URL.
|
|
28535
|
+
- \`OPEN_API_TOKEN\` \u2014 a short-lived bearer token **self-bound to this agent**. It is
|
|
28536
|
+
not reusable elsewhere.
|
|
28537
|
+
|
|
28538
|
+
The token already encodes this agent's authority: the platform reflects the agent's
|
|
28539
|
+
own configured middleware into Open grants, plus a small always-on baseline
|
|
28540
|
+
(\`kb\` read-only and \`sandbox:self\`). So the callable set = that baseline \u222A the
|
|
28541
|
+
domains your configured middleware exposes \u2014 and nothing beyond it.
|
|
28542
|
+
|
|
28543
|
+
## Client
|
|
28544
|
+
|
|
28545
|
+
The sandbox must have the zero-dependency \`@axiom-lattice/open-mcp-client\` package.
|
|
28546
|
+
Get it one of two ways:
|
|
28547
|
+
|
|
28548
|
+
- **Preinstalled in the sandbox image** (recommended): \`open-mcp\` is on \`PATH\`; for
|
|
28549
|
+
\`require("@axiom-lattice/open-mcp-client")\` to resolve, install it into the working
|
|
28550
|
+
directory or point \`NODE_PATH\` at the global \`node_modules\`.
|
|
28551
|
+
- **Install it in this run** when the sandbox has network + npm:
|
|
28552
|
+
|
|
28553
|
+
\`\`\`bash
|
|
28554
|
+
npm install @axiom-lattice/open-mcp-client
|
|
28555
|
+
# or use without installing:
|
|
28556
|
+
npx @axiom-lattice/open-mcp-client tools list --json
|
|
28557
|
+
\`\`\`
|
|
28558
|
+
|
|
28559
|
+
\`\`\`js
|
|
28560
|
+
const { OpenMcpClient } = require("@axiom-lattice/open-mcp-client");
|
|
28561
|
+
const client = OpenMcpClient.fromEnv(); // reads API_GATEWAY_URL + OPEN_API_TOKEN
|
|
28562
|
+
\`\`\`
|
|
28563
|
+
|
|
28564
|
+
CLI equivalents (config comes from the same env vars):
|
|
28565
|
+
|
|
28566
|
+
\`\`\`bash
|
|
28567
|
+
open-mcp tools list --json
|
|
28568
|
+
open-mcp tools call kb_search --json '{"query":"refund policy"}'
|
|
28569
|
+
\`\`\`
|
|
28570
|
+
|
|
28571
|
+
## Discover, then call
|
|
28572
|
+
|
|
28573
|
+
1. **Discover first.** Call \`await client.listTools()\`. This returns exactly the
|
|
28574
|
+
tools this agent is authorized to call (the server filters by the token's grants
|
|
28575
|
+
on every request, so it is the source of truth).
|
|
28576
|
+
2. **Only call discovered tools.** Pick a tool from that list and call
|
|
28577
|
+
\`await client.callTool(name, args)\` with args matching the tool's \`inputSchema\`.
|
|
28578
|
+
3. **Print the final result as JSON to stdout** so the calling agent can consume it.
|
|
28579
|
+
Keep intermediate logs minimal.
|
|
28580
|
+
|
|
28581
|
+
An unconfigured domain isn't registered, so calling it returns an \`isError\`
|
|
28582
|
+
tool-not-found result; a registered tool refused by the token's grants surfaces
|
|
28583
|
+
\`GRANT_DENIED\`. Either way the capability is **not configured for this agent**.
|
|
28584
|
+
Do not retry or work around it \u2014 drop that step or tell the user which
|
|
28585
|
+
middleware/domain must be enabled. A denied call is expected behavior, not a
|
|
28586
|
+
transient failure.
|
|
28587
|
+
|
|
28588
|
+
## Tips
|
|
28589
|
+
|
|
28590
|
+
- Fan out with \`Promise.all\` over many items instead of many sequential model turns;
|
|
28591
|
+
that is the main win of PTC.
|
|
28592
|
+
- Inspect \`tool.inputSchema\` before calling to avoid schema-validation errors.
|
|
28593
|
+
- Reduce large results in code and return only the fields the agent needs.
|
|
28594
|
+
- The token is short-lived; for very long jobs re-read the env per \`code_eval\` run
|
|
28595
|
+
rather than caching the token in a file.
|
|
28596
|
+
|
|
28597
|
+
## Worked example
|
|
28598
|
+
|
|
28599
|
+
\`\`\`js
|
|
28600
|
+
const { OpenMcpClient } = require("@axiom-lattice/open-mcp-client");
|
|
28601
|
+
|
|
28602
|
+
async function main() {
|
|
28603
|
+
const client = OpenMcpClient.fromEnv(); // API_GATEWAY_URL + OPEN_API_TOKEN
|
|
28604
|
+
const tools = await client.listTools(); // exactly what this agent may call
|
|
28605
|
+
const pick = tools.find((t) => t.name === "kb_search") ?? tools[0];
|
|
28606
|
+
const out = await client.callTool(pick.name, { query: "refund policy" });
|
|
28607
|
+
console.log(JSON.stringify({ called: pick.name, result: out.json() }));
|
|
28608
|
+
}
|
|
28609
|
+
|
|
28610
|
+
main().catch((err) => { console.error(String(err)); process.exit(1); });
|
|
28611
|
+
\`\`\`
|
|
28612
|
+
|
|
28613
|
+
Run this in \`code_eval\`. The first run proves env + client wiring; then extend it
|
|
28614
|
+
into the real fan-out/aggregation the task needs.
|
|
28615
|
+
`
|
|
28013
28616
|
};
|
|
28014
28617
|
function getBuiltInSkillMeta(name) {
|
|
28015
28618
|
const content = BUILTIN_SKILLS[name];
|
|
@@ -28606,7 +29209,7 @@ ${body}` : `${frontmatter}
|
|
|
28606
29209
|
};
|
|
28607
29210
|
|
|
28608
29211
|
// src/store_lattice/InMemoryMenuStore.ts
|
|
28609
|
-
import { randomUUID as
|
|
29212
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
28610
29213
|
var InMemoryMenuStore = class {
|
|
28611
29214
|
constructor() {
|
|
28612
29215
|
this.items = /* @__PURE__ */ new Map();
|
|
@@ -28627,7 +29230,7 @@ var InMemoryMenuStore = class {
|
|
|
28627
29230
|
async create(input) {
|
|
28628
29231
|
const now = /* @__PURE__ */ new Date();
|
|
28629
29232
|
const item = {
|
|
28630
|
-
id:
|
|
29233
|
+
id: randomUUID7(),
|
|
28631
29234
|
tenantId: input.tenantId,
|
|
28632
29235
|
menuTarget: input.menuTarget,
|
|
28633
29236
|
group: input.group,
|
|
@@ -31139,9 +31742,9 @@ async function getOrCreateCollectionVectorStore(name, embeddingKey, tenantId2, p
|
|
|
31139
31742
|
const pendingInitialization = pendingVectorStoreInitializations.get(storeKey);
|
|
31140
31743
|
if (pendingInitialization) return pendingInitialization;
|
|
31141
31744
|
const initialization = (async () => {
|
|
31142
|
-
const
|
|
31745
|
+
const provider2 = vectorStoreProviderManager.getProvider(providerKey);
|
|
31143
31746
|
const tableName = buildTableName(tenantId2, name);
|
|
31144
|
-
const vectorStore = await
|
|
31747
|
+
const vectorStore = await provider2.create({ tableName, embeddingKey });
|
|
31145
31748
|
vectorStoreLatticeManager.registerLattice(storeKey, vectorStore);
|
|
31146
31749
|
return vectorStore;
|
|
31147
31750
|
})();
|
|
@@ -31159,9 +31762,9 @@ async function getCollectionEntryCount(name, embeddingKey, tenantId2) {
|
|
|
31159
31762
|
return vs.getDocumentCount();
|
|
31160
31763
|
}
|
|
31161
31764
|
try {
|
|
31162
|
-
const
|
|
31163
|
-
if (
|
|
31164
|
-
return
|
|
31765
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
31766
|
+
if (provider2.getEntryCount) {
|
|
31767
|
+
return provider2.getEntryCount(buildTableName(tenantId2, name));
|
|
31165
31768
|
}
|
|
31166
31769
|
} catch {
|
|
31167
31770
|
}
|
|
@@ -31173,9 +31776,9 @@ async function listCollectionEntries(name, embeddingKey, tenantId2) {
|
|
|
31173
31776
|
return vs.getAllDocuments();
|
|
31174
31777
|
}
|
|
31175
31778
|
try {
|
|
31176
|
-
const
|
|
31177
|
-
if (
|
|
31178
|
-
return
|
|
31779
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
31780
|
+
if (provider2.listEntries) {
|
|
31781
|
+
return provider2.listEntries(buildTableName(tenantId2, name));
|
|
31179
31782
|
}
|
|
31180
31783
|
} catch {
|
|
31181
31784
|
}
|
|
@@ -31185,9 +31788,9 @@ async function removeCollectionVectorStore(name, tenantId2) {
|
|
|
31185
31788
|
const storeKey = buildKey(tenantId2, name);
|
|
31186
31789
|
const tableName = buildTableName(tenantId2, name);
|
|
31187
31790
|
try {
|
|
31188
|
-
const
|
|
31189
|
-
if (
|
|
31190
|
-
await
|
|
31791
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
31792
|
+
if (provider2.dropTable) {
|
|
31793
|
+
await provider2.dropTable(tableName);
|
|
31191
31794
|
}
|
|
31192
31795
|
} catch {
|
|
31193
31796
|
}
|
|
@@ -33502,7 +34105,7 @@ var DaytonaProvider = class {
|
|
|
33502
34105
|
|
|
33503
34106
|
// src/sandbox_lattice/providers/LocalSandboxProvider.ts
|
|
33504
34107
|
import * as path6 from "path";
|
|
33505
|
-
import * as
|
|
34108
|
+
import * as os2 from "os";
|
|
33506
34109
|
import * as fs4 from "fs/promises";
|
|
33507
34110
|
|
|
33508
34111
|
// src/sandbox_lattice/LocalSandboxInstance.ts
|
|
@@ -33529,6 +34132,32 @@ function assertRegularDeleteTarget(file, stat4) {
|
|
|
33529
34132
|
function quoteShellArgument(value) {
|
|
33530
34133
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
33531
34134
|
}
|
|
34135
|
+
var PLATFORM_SECRET_ENV_VARS = [
|
|
34136
|
+
"OPEN_TOKEN_SECRET",
|
|
34137
|
+
"AUTH_TOKEN_SECRET",
|
|
34138
|
+
"JWT_SECRET",
|
|
34139
|
+
"WEB_APP_ATTACHMENT_SECRET",
|
|
34140
|
+
"LATTICE_ENCRYPTION_KEY",
|
|
34141
|
+
"DATABASE_URL",
|
|
34142
|
+
"REDIS_PASSWORD",
|
|
34143
|
+
"MICROSANDBOX_API_KEY",
|
|
34144
|
+
"DAYTONA_API_KEY",
|
|
34145
|
+
"E2B_API_KEY",
|
|
34146
|
+
"OPENAI_API_KEY",
|
|
34147
|
+
"AZURE_OPENAI_API_KEY",
|
|
34148
|
+
"ANTHROPIC_API_KEY",
|
|
34149
|
+
"TAVILY_API_KEY",
|
|
34150
|
+
"VAPID_PRIVATE_KEY",
|
|
34151
|
+
"SUPABASE_KEY",
|
|
34152
|
+
"A2A_API_KEYS"
|
|
34153
|
+
];
|
|
34154
|
+
function stripPlatformSecrets(env) {
|
|
34155
|
+
const rest = { ...env };
|
|
34156
|
+
for (const name of PLATFORM_SECRET_ENV_VARS) {
|
|
34157
|
+
delete rest[name];
|
|
34158
|
+
}
|
|
34159
|
+
return rest;
|
|
34160
|
+
}
|
|
33532
34161
|
function validatePackEntryName(name) {
|
|
33533
34162
|
if (!name || name === "." || name === ".." || name.includes("\\") || name.includes("/")) {
|
|
33534
34163
|
throw new Error(`Cannot pack: unsafe entry name '${name}'`);
|
|
@@ -33701,7 +34330,7 @@ var LocalSandboxInstance = class {
|
|
|
33701
34330
|
timeout: timeoutMs,
|
|
33702
34331
|
maxBuffer: 10 * 1024 * 1024,
|
|
33703
34332
|
// 10MB
|
|
33704
|
-
env: { ...process.env, HOME: this.rootDir }
|
|
34333
|
+
env: stripPlatformSecrets({ ...process.env, HOME: this.rootDir })
|
|
33705
34334
|
}
|
|
33706
34335
|
);
|
|
33707
34336
|
const output = stderr ? `${stdout}
|
|
@@ -33966,7 +34595,7 @@ var LocalSandboxProvider = class {
|
|
|
33966
34595
|
this.instances = /* @__PURE__ */ new Map();
|
|
33967
34596
|
this.creating = /* @__PURE__ */ new Map();
|
|
33968
34597
|
this.createResourceAddress = createResourceAddress;
|
|
33969
|
-
this.basePath = config.basePath ?? path6.join(
|
|
34598
|
+
this.basePath = config.basePath ?? path6.join(os2.homedir(), ".axiom-local-sandbox");
|
|
33970
34599
|
}
|
|
33971
34600
|
async createSandbox(name, _config) {
|
|
33972
34601
|
const existing = this.instances.get(name);
|
|
@@ -35342,6 +35971,10 @@ var TaskLifecycleNotifier = class {
|
|
|
35342
35971
|
this.listeners = /* @__PURE__ */ new Set();
|
|
35343
35972
|
this.tails = /* @__PURE__ */ new Map();
|
|
35344
35973
|
}
|
|
35974
|
+
/** Installs (or clears) the durable outbox used to fan notifications to other replicas. */
|
|
35975
|
+
setOutbox(outbox2) {
|
|
35976
|
+
this.outbox = outbox2;
|
|
35977
|
+
}
|
|
35345
35978
|
/**
|
|
35346
35979
|
* Registers an async lifecycle listener.
|
|
35347
35980
|
*
|
|
@@ -35362,6 +35995,25 @@ var TaskLifecycleNotifier = class {
|
|
|
35362
35995
|
* @throws Error when the event is malformed or one or more listeners reject.
|
|
35363
35996
|
*/
|
|
35364
35997
|
async publish(event) {
|
|
35998
|
+
const snapshot = snapshotNotification(event);
|
|
35999
|
+
const key5 = `${snapshot.tenantId}:${snapshot.taskId}`;
|
|
36000
|
+
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
36001
|
+
const delivery = previous.catch(() => void 0).then(() => this.deliver(snapshot));
|
|
36002
|
+
this.tails.set(key5, delivery);
|
|
36003
|
+
if (this.outbox) {
|
|
36004
|
+
try {
|
|
36005
|
+
await this.outbox.append({ topic: "task-lifecycle", payload: snapshot, originReplicaId: getReplicaId() });
|
|
36006
|
+
} catch {
|
|
36007
|
+
}
|
|
36008
|
+
}
|
|
36009
|
+
try {
|
|
36010
|
+
await delivery;
|
|
36011
|
+
} finally {
|
|
36012
|
+
if (this.tails.get(key5) === delivery) this.tails.delete(key5);
|
|
36013
|
+
}
|
|
36014
|
+
}
|
|
36015
|
+
/** Delivers one outbox payload to local listeners without re-appending (poller path). */
|
|
36016
|
+
async deliverFromOutbox(event) {
|
|
35365
36017
|
const snapshot = snapshotNotification(event);
|
|
35366
36018
|
const key5 = `${snapshot.tenantId}:${snapshot.taskId}`;
|
|
35367
36019
|
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
@@ -35426,6 +36078,10 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
35426
36078
|
if (!Number.isSafeInteger(timeout) || timeout <= 0) throw new Error("Invalid admission listener timeout");
|
|
35427
36079
|
this.listenerTimeoutMs = timeout;
|
|
35428
36080
|
}
|
|
36081
|
+
/** Installs (or clears) the durable outbox used to fan notifications to other replicas. */
|
|
36082
|
+
setOutbox(outbox2) {
|
|
36083
|
+
this.outbox = outbox2;
|
|
36084
|
+
}
|
|
35429
36085
|
/**
|
|
35430
36086
|
* Registers a Project task admission listener.
|
|
35431
36087
|
*
|
|
@@ -35445,6 +36101,30 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
35445
36101
|
* @returns A promise settled after every snapshotted listener settles.
|
|
35446
36102
|
*/
|
|
35447
36103
|
async publish(event) {
|
|
36104
|
+
const snapshot = snapshotNotification2(event);
|
|
36105
|
+
const listeners = [...this.listeners];
|
|
36106
|
+
const key5 = `${snapshot.tenantId}\0${snapshot.taskId}`;
|
|
36107
|
+
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
36108
|
+
const delivery = previous.catch(() => void 0).then(() => this.deliver(snapshot, listeners));
|
|
36109
|
+
this.tails.set(key5, delivery);
|
|
36110
|
+
if (this.outbox) {
|
|
36111
|
+
try {
|
|
36112
|
+
await this.outbox.append({
|
|
36113
|
+
topic: "project-task-admission",
|
|
36114
|
+
payload: snapshot,
|
|
36115
|
+
originReplicaId: getReplicaId()
|
|
36116
|
+
});
|
|
36117
|
+
} catch {
|
|
36118
|
+
}
|
|
36119
|
+
}
|
|
36120
|
+
try {
|
|
36121
|
+
await delivery;
|
|
36122
|
+
} finally {
|
|
36123
|
+
if (this.tails.get(key5) === delivery) this.tails.delete(key5);
|
|
36124
|
+
}
|
|
36125
|
+
}
|
|
36126
|
+
/** Delivers one outbox payload to local listeners without re-appending (poller path). */
|
|
36127
|
+
async deliverFromOutbox(event) {
|
|
35448
36128
|
const snapshot = snapshotNotification2(event);
|
|
35449
36129
|
const listeners = [...this.listeners];
|
|
35450
36130
|
const key5 = `${snapshot.tenantId}\0${snapshot.taskId}`;
|
|
@@ -35514,8 +36194,137 @@ function canonicalTimestamp(value) {
|
|
|
35514
36194
|
return Number.isFinite(parsed.getTime()) && parsed.toISOString() === value;
|
|
35515
36195
|
}
|
|
35516
36196
|
|
|
36197
|
+
// src/services/OutboxPoller.ts
|
|
36198
|
+
var OutboxPoller = class {
|
|
36199
|
+
/**
|
|
36200
|
+
* Creates a poller bound to one durable outbox.
|
|
36201
|
+
*
|
|
36202
|
+
* @param deps Store, owner replica id, topic handlers, and optional tuning.
|
|
36203
|
+
*/
|
|
36204
|
+
constructor(deps) {
|
|
36205
|
+
this.deps = deps;
|
|
36206
|
+
this.cursor = null;
|
|
36207
|
+
this.polling = false;
|
|
36208
|
+
}
|
|
36209
|
+
/** Captures the starting cursor and begins polling. */
|
|
36210
|
+
async start() {
|
|
36211
|
+
this.cursor = await this.deps.store.latestId();
|
|
36212
|
+
this.timer = setInterval(() => {
|
|
36213
|
+
void this.pollOnce();
|
|
36214
|
+
}, this.deps.intervalMs ?? 1e3);
|
|
36215
|
+
this.timer.unref?.();
|
|
36216
|
+
}
|
|
36217
|
+
/** Stops polling. */
|
|
36218
|
+
stop() {
|
|
36219
|
+
if (this.timer) clearInterval(this.timer);
|
|
36220
|
+
this.timer = void 0;
|
|
36221
|
+
}
|
|
36222
|
+
/** Runs one drain pass (exported for tests). */
|
|
36223
|
+
async pollOnce() {
|
|
36224
|
+
if (this.polling) return;
|
|
36225
|
+
this.polling = true;
|
|
36226
|
+
try {
|
|
36227
|
+
const batchSize = this.deps.batchSize ?? 100;
|
|
36228
|
+
for (; ; ) {
|
|
36229
|
+
const events = await this.deps.store.listAfter(this.cursor, batchSize);
|
|
36230
|
+
if (events.length === 0) break;
|
|
36231
|
+
for (const event of events) {
|
|
36232
|
+
this.cursor = event.id;
|
|
36233
|
+
if (event.originReplicaId === this.deps.owner) continue;
|
|
36234
|
+
const handler = this.deps.handlers[event.topic];
|
|
36235
|
+
if (!handler) continue;
|
|
36236
|
+
try {
|
|
36237
|
+
await this.deliverWithTimeout(handler, event.payload);
|
|
36238
|
+
} catch {
|
|
36239
|
+
this.deps.log?.warn("Outbox delivery failed", { topic: event.topic, id: event.id });
|
|
36240
|
+
}
|
|
36241
|
+
}
|
|
36242
|
+
if (events.length < batchSize) break;
|
|
36243
|
+
}
|
|
36244
|
+
} catch (error) {
|
|
36245
|
+
this.deps.log?.warn("Outbox poll failed", { error: error instanceof Error ? error.message : String(error) });
|
|
36246
|
+
} finally {
|
|
36247
|
+
this.polling = false;
|
|
36248
|
+
}
|
|
36249
|
+
}
|
|
36250
|
+
/**
|
|
36251
|
+
* Runs one handler bounded by `handlerTimeoutMs` so a hung listener cannot
|
|
36252
|
+
* stall cross-replica delivery for this replica.
|
|
36253
|
+
*/
|
|
36254
|
+
async deliverWithTimeout(handler, payload) {
|
|
36255
|
+
const timeoutMs = this.deps.handlerTimeoutMs ?? 5e3;
|
|
36256
|
+
let timer;
|
|
36257
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
36258
|
+
timer = setTimeout(() => reject(new Error("Outbox handler timed out")), timeoutMs);
|
|
36259
|
+
timer.unref?.();
|
|
36260
|
+
});
|
|
36261
|
+
try {
|
|
36262
|
+
await Promise.race([Promise.resolve().then(() => handler(payload)), timeout]);
|
|
36263
|
+
} finally {
|
|
36264
|
+
if (timer) clearTimeout(timer);
|
|
36265
|
+
}
|
|
36266
|
+
}
|
|
36267
|
+
};
|
|
36268
|
+
|
|
35517
36269
|
// src/services/ProjectMutationMutex.ts
|
|
35518
36270
|
import { snapshotExactRecord as snapshotExactRecord4 } from "@axiom-lattice/protocols";
|
|
36271
|
+
|
|
36272
|
+
// src/services/coordinationLease.ts
|
|
36273
|
+
var configured;
|
|
36274
|
+
function configureCoordinationLeaseStore(store) {
|
|
36275
|
+
configured = store;
|
|
36276
|
+
}
|
|
36277
|
+
function getCoordinationLeaseStore() {
|
|
36278
|
+
return configured;
|
|
36279
|
+
}
|
|
36280
|
+
|
|
36281
|
+
// src/services/withLease.ts
|
|
36282
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
36283
|
+
var LeaseAcquisitionTimeoutError = class extends Error {
|
|
36284
|
+
/**
|
|
36285
|
+
* @param key Lease key that could not be acquired.
|
|
36286
|
+
* @param holder Unique holder that attempted acquisition.
|
|
36287
|
+
* @param timeoutMs How long the caller waited before giving up.
|
|
36288
|
+
*/
|
|
36289
|
+
constructor(key5, holder, timeoutMs) {
|
|
36290
|
+
super(`Could not acquire lease '${key5}' for '${holder}' within ${timeoutMs}ms`);
|
|
36291
|
+
this.key = key5;
|
|
36292
|
+
this.holder = holder;
|
|
36293
|
+
this.timeoutMs = timeoutMs;
|
|
36294
|
+
/** Stable machine-readable code. */
|
|
36295
|
+
this.code = "LEASE_ACQUISITION_TIMEOUT";
|
|
36296
|
+
this.name = "LeaseAcquisitionTimeoutError";
|
|
36297
|
+
}
|
|
36298
|
+
};
|
|
36299
|
+
function sleep(ms) {
|
|
36300
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
36301
|
+
}
|
|
36302
|
+
async function withLease(store, key5, ownerLabel, fn, options = {}) {
|
|
36303
|
+
const ttlMs = options.ttlMs ?? 3e4;
|
|
36304
|
+
const acquireTimeoutMs = options.acquireTimeoutMs ?? 1e4;
|
|
36305
|
+
const retryDelayMs = options.retryDelayMs ?? 50;
|
|
36306
|
+
const heartbeatMs = options.heartbeatMs ?? Math.max(1e3, Math.floor(ttlMs / 3));
|
|
36307
|
+
const holder = `${ownerLabel}#${randomUUID8()}`;
|
|
36308
|
+
const deadline = Date.now() + acquireTimeoutMs;
|
|
36309
|
+
for (; ; ) {
|
|
36310
|
+
if (await store.tryAcquire(key5, holder, ttlMs)) break;
|
|
36311
|
+
if (Date.now() >= deadline) throw new LeaseAcquisitionTimeoutError(key5, holder, acquireTimeoutMs);
|
|
36312
|
+
await sleep(retryDelayMs);
|
|
36313
|
+
}
|
|
36314
|
+
const heartbeat = setInterval(() => {
|
|
36315
|
+
void store.renew(key5, holder, ttlMs).catch(() => void 0);
|
|
36316
|
+
}, heartbeatMs);
|
|
36317
|
+
heartbeat.unref?.();
|
|
36318
|
+
try {
|
|
36319
|
+
return await fn();
|
|
36320
|
+
} finally {
|
|
36321
|
+
clearInterval(heartbeat);
|
|
36322
|
+
await store.release(key5, holder).catch(() => void 0);
|
|
36323
|
+
}
|
|
36324
|
+
}
|
|
36325
|
+
|
|
36326
|
+
// src/services/ProjectMutationMutex.ts
|
|
36327
|
+
var MUTATION_LEASE_OPTIONS = { ttlMs: 6e4, acquireTimeoutMs: 9e4, retryDelayMs: 100 };
|
|
35519
36328
|
function projectKey(scope) {
|
|
35520
36329
|
const row = snapshotExactRecord4(scope, ["tenantId", "projectId"]);
|
|
35521
36330
|
if (!row || typeof row.tenantId !== "string" || !row.tenantId || row.tenantId.includes("\0") || typeof row.projectId !== "string" || !row.projectId || row.projectId.includes("\0")) {
|
|
@@ -35531,9 +36340,12 @@ var ProjectMutationMutex = class {
|
|
|
35531
36340
|
/** Runs one mutation after all earlier mutations for the same Tenant and Project. */
|
|
35532
36341
|
async runExclusive(scope, operation, signal) {
|
|
35533
36342
|
const key5 = projectKey(scope);
|
|
36343
|
+
const leaseKey = `project-mutation:${encodeURIComponent(scope.tenantId)}:${encodeURIComponent(scope.projectId)}`;
|
|
35534
36344
|
await this.acquire(key5, signal);
|
|
35535
36345
|
try {
|
|
35536
|
-
|
|
36346
|
+
const store = getCoordinationLeaseStore();
|
|
36347
|
+
if (!store) return await operation();
|
|
36348
|
+
return await withLease(store, leaseKey, getReplicaId(), operation, MUTATION_LEASE_OPTIONS);
|
|
35537
36349
|
} finally {
|
|
35538
36350
|
this.release(key5);
|
|
35539
36351
|
}
|
|
@@ -35591,7 +36403,7 @@ function createTrustedAgentMessageDispatcher(resolve4) {
|
|
|
35591
36403
|
}
|
|
35592
36404
|
|
|
35593
36405
|
// src/services/RoomAgentMessageService.ts
|
|
35594
|
-
import { randomUUID as
|
|
36406
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
35595
36407
|
import { snapshotExactArray, snapshotExactRecord as snapshotExactRecord5 } from "@axiom-lattice/protocols";
|
|
35596
36408
|
var INPUT_KEYS = [
|
|
35597
36409
|
"tenantId",
|
|
@@ -35679,7 +36491,7 @@ var RoomAgentMessageService = class {
|
|
|
35679
36491
|
throw new Error("Invalid project room membership");
|
|
35680
36492
|
}
|
|
35681
36493
|
const candidate = {
|
|
35682
|
-
id: (this.deps.idFactory ??
|
|
36494
|
+
id: (this.deps.idFactory ?? randomUUID9)(),
|
|
35683
36495
|
tenantId: input.tenantId,
|
|
35684
36496
|
workspaceId: input.workspaceId,
|
|
35685
36497
|
projectId: input.projectId,
|
|
@@ -36040,9 +36852,9 @@ var BELIEF_OWNER_WRITE_ATTEMPTS = 3;
|
|
|
36040
36852
|
function isWellFormedImpact(impact) {
|
|
36041
36853
|
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);
|
|
36042
36854
|
}
|
|
36043
|
-
async function applyBeliefImpacts(taskStore,
|
|
36044
|
-
if (impacts.length === 0) return { description:
|
|
36045
|
-
let current =
|
|
36855
|
+
async function applyBeliefImpacts(taskStore, owner2, impacts) {
|
|
36856
|
+
if (impacts.length === 0) return { description: owner2.description ?? "" };
|
|
36857
|
+
let current = owner2;
|
|
36046
36858
|
for (let attempt = 0; attempt < BELIEF_OWNER_WRITE_ATTEMPTS; attempt += 1) {
|
|
36047
36859
|
const parsed = parseTaskBeliefState(current.description ?? "");
|
|
36048
36860
|
const existingTable = parsed.success;
|
|
@@ -36171,14 +36983,14 @@ function sameBeliefOwner(left, right) {
|
|
|
36171
36983
|
function sameBeliefOwnerIdentity(left, right) {
|
|
36172
36984
|
return canonicalJson({ ...left, beliefState: void 0 }) === canonicalJson({ ...right, beliefState: void 0 });
|
|
36173
36985
|
}
|
|
36174
|
-
function canonicalBeliefOwner(
|
|
36986
|
+
function canonicalBeliefOwner(owner2) {
|
|
36175
36987
|
const beliefState = {
|
|
36176
|
-
entries:
|
|
36988
|
+
entries: owner2.beliefState.entries.map((entry) => ({
|
|
36177
36989
|
...entry,
|
|
36178
36990
|
basis: entry.basis.trim().replace(/\s+/g, " ")
|
|
36179
36991
|
})).sort((left, right) => left.key < right.key ? -1 : left.key > right.key ? 1 : 0)
|
|
36180
36992
|
};
|
|
36181
|
-
return { ...
|
|
36993
|
+
return { ...owner2, beliefState };
|
|
36182
36994
|
}
|
|
36183
36995
|
function eventKeyFor(taskId, result, impacts, beliefOwner) {
|
|
36184
36996
|
const base = `belief-impact:${taskId}:${buildBeliefCompletionEventKey(taskId, result, impacts)}`;
|
|
@@ -37545,8 +38357,8 @@ var TaskLifecycleService = class {
|
|
|
37545
38357
|
return { task: existing, parent: parentResult, eventKey, evidence, result, impacts };
|
|
37546
38358
|
}
|
|
37547
38359
|
beliefOwnerSnapshot(task, parent) {
|
|
37548
|
-
const
|
|
37549
|
-
const parsed = parseTaskBeliefState(
|
|
38360
|
+
const owner2 = parent?.ownerType === "agent" ? parent : task;
|
|
38361
|
+
const parsed = parseTaskBeliefState(owner2.description ?? "");
|
|
37550
38362
|
const beliefState = parsed.success ? parsed.state : { entries: [] };
|
|
37551
38363
|
if (parent?.ownerType === "agent") {
|
|
37552
38364
|
return {
|
|
@@ -38266,7 +39078,7 @@ function createTaskLifecycleService(deps) {
|
|
|
38266
39078
|
}
|
|
38267
39079
|
|
|
38268
39080
|
// src/services/TaskExecutionService.ts
|
|
38269
|
-
import { randomUUID as
|
|
39081
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
38270
39082
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
|
|
38271
39083
|
import { isExecutionResultEventKey as isExecutionResultEventKey2 } from "@axiom-lattice/protocols";
|
|
38272
39084
|
|
|
@@ -38525,12 +39337,20 @@ var TaskRunRegistry = class {
|
|
|
38525
39337
|
}
|
|
38526
39338
|
};
|
|
38527
39339
|
var taskRunRegistry = new TaskRunRegistry();
|
|
39340
|
+
async function safelyLive(probe, task) {
|
|
39341
|
+
try {
|
|
39342
|
+
return await probe(task);
|
|
39343
|
+
} catch {
|
|
39344
|
+
return true;
|
|
39345
|
+
}
|
|
39346
|
+
}
|
|
38528
39347
|
async function reconcileStaleTaskRuns(input) {
|
|
38529
39348
|
const registry4 = input.registry ?? taskRunRegistry;
|
|
38530
39349
|
const converged = [];
|
|
38531
39350
|
const convergedTasks = [];
|
|
38532
39351
|
for (const task of input.tasks) {
|
|
38533
39352
|
if (task.status !== "in_progress" || registry4.isLive(task.id)) continue;
|
|
39353
|
+
if (input.isTaskLive && await safelyLive(input.isTaskLive, task)) continue;
|
|
38534
39354
|
const result = await input.lifecycle.failTask({
|
|
38535
39355
|
tenantId: task.tenantId,
|
|
38536
39356
|
taskId: task.id,
|
|
@@ -38551,7 +39371,8 @@ async function reconcileTenantTaskRuns(input) {
|
|
|
38551
39371
|
tasks: candidates,
|
|
38552
39372
|
actor: input.actor,
|
|
38553
39373
|
lifecycle: input.lifecycle,
|
|
38554
|
-
...input.registry ? { registry: input.registry } : {}
|
|
39374
|
+
...input.registry ? { registry: input.registry } : {},
|
|
39375
|
+
...input.isTaskLive ? { isTaskLive: input.isTaskLive } : {}
|
|
38555
39376
|
});
|
|
38556
39377
|
}
|
|
38557
39378
|
async function reconcileAllTenantTaskRuns(input) {
|
|
@@ -38567,7 +39388,8 @@ async function reconcileAllTenantTaskRuns(input) {
|
|
|
38567
39388
|
taskStore: input.taskStore,
|
|
38568
39389
|
lifecycle: input.lifecycle,
|
|
38569
39390
|
...input.registry ? { registry: input.registry } : {},
|
|
38570
|
-
...input.include ? { include: input.include } : {}
|
|
39391
|
+
...input.include ? { include: input.include } : {},
|
|
39392
|
+
...input.isTaskLive ? { isTaskLive: input.isTaskLive } : {}
|
|
38571
39393
|
});
|
|
38572
39394
|
} catch {
|
|
38573
39395
|
continue;
|
|
@@ -38578,6 +39400,42 @@ async function reconcileAllTenantTaskRuns(input) {
|
|
|
38578
39400
|
return { converged, convergedTasks };
|
|
38579
39401
|
}
|
|
38580
39402
|
|
|
39403
|
+
// src/services/taskRunLease.ts
|
|
39404
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
39405
|
+
function taskRunLeaseKey(taskId) {
|
|
39406
|
+
return `task-run:${taskId}`;
|
|
39407
|
+
}
|
|
39408
|
+
async function tryAcquireTaskRun(input) {
|
|
39409
|
+
const key5 = taskRunLeaseKey(input.taskId);
|
|
39410
|
+
const holder = `${input.owner}#${randomUUID10()}`;
|
|
39411
|
+
if (!await input.store.tryAcquire(key5, holder, input.ttlMs)) return null;
|
|
39412
|
+
const heartbeatMs = input.heartbeatMs ?? Math.max(1e3, Math.floor(input.ttlMs / 3));
|
|
39413
|
+
let released = false;
|
|
39414
|
+
let lost = false;
|
|
39415
|
+
const heartbeat = setInterval(() => {
|
|
39416
|
+
void input.store.renew(key5, holder, input.ttlMs).then((renewed) => {
|
|
39417
|
+
if (released || renewed || lost) return;
|
|
39418
|
+
lost = true;
|
|
39419
|
+
try {
|
|
39420
|
+
input.onLost?.();
|
|
39421
|
+
} catch {
|
|
39422
|
+
}
|
|
39423
|
+
}).catch(() => void 0);
|
|
39424
|
+
}, heartbeatMs);
|
|
39425
|
+
heartbeat.unref?.();
|
|
39426
|
+
return {
|
|
39427
|
+
get lost() {
|
|
39428
|
+
return lost;
|
|
39429
|
+
},
|
|
39430
|
+
release: async () => {
|
|
39431
|
+
if (released) return;
|
|
39432
|
+
released = true;
|
|
39433
|
+
clearInterval(heartbeat);
|
|
39434
|
+
await input.store.release(key5, holder).catch(() => void 0);
|
|
39435
|
+
}
|
|
39436
|
+
};
|
|
39437
|
+
}
|
|
39438
|
+
|
|
38581
39439
|
// src/services/ExecutionAuthorityRegistry.ts
|
|
38582
39440
|
var ManagedTaskStartError = class extends Error {
|
|
38583
39441
|
/**
|
|
@@ -38848,6 +39706,14 @@ async function prepareTaskDispatch(deps, input) {
|
|
|
38848
39706
|
|
|
38849
39707
|
// src/services/TaskExecutionService.ts
|
|
38850
39708
|
import { GraphInterrupt as GraphInterrupt2 } from "@langchain/langgraph";
|
|
39709
|
+
var TASK_RUN_LEASE_TTL_MS = 12e4;
|
|
39710
|
+
function getLeaseStore() {
|
|
39711
|
+
try {
|
|
39712
|
+
return storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
39713
|
+
} catch {
|
|
39714
|
+
return void 0;
|
|
39715
|
+
}
|
|
39716
|
+
}
|
|
38851
39717
|
function persistedExecutionObservation(item, attempted) {
|
|
38852
39718
|
const detail = item.detail;
|
|
38853
39719
|
const persistedObservation = toJsonSafeValue(detail?.observation);
|
|
@@ -38908,11 +39774,11 @@ function createTaskExecutionService(deps) {
|
|
|
38908
39774
|
let threadId;
|
|
38909
39775
|
let runId;
|
|
38910
39776
|
try {
|
|
38911
|
-
threadId = storedThreadId ?? (deps.createThreadId ??
|
|
39777
|
+
threadId = storedThreadId ?? (deps.createThreadId ?? randomUUID11)();
|
|
38912
39778
|
if (task.status === "interrupted" && reuseCurrentRun) {
|
|
38913
39779
|
runId = storedRunId;
|
|
38914
39780
|
} else if (task.status === "interrupted" || task.status === "failed") {
|
|
38915
|
-
runId = (deps.createRunId ??
|
|
39781
|
+
runId = (deps.createRunId ?? randomUUID11)();
|
|
38916
39782
|
}
|
|
38917
39783
|
} catch (error) {
|
|
38918
39784
|
return {
|
|
@@ -38975,7 +39841,21 @@ function createTaskExecutionService(deps) {
|
|
|
38975
39841
|
warnings.push(...begun.warnings);
|
|
38976
39842
|
}
|
|
38977
39843
|
taskRunRegistry.register(task.id);
|
|
39844
|
+
let taskRunLease = null;
|
|
38978
39845
|
try {
|
|
39846
|
+
const leaseStore = getLeaseStore();
|
|
39847
|
+
if (leaseStore) {
|
|
39848
|
+
try {
|
|
39849
|
+
taskRunLease = await tryAcquireTaskRun({
|
|
39850
|
+
store: leaseStore,
|
|
39851
|
+
taskId: task.id,
|
|
39852
|
+
owner: getReplicaId(),
|
|
39853
|
+
ttlMs: TASK_RUN_LEASE_TTL_MS
|
|
39854
|
+
});
|
|
39855
|
+
} catch {
|
|
39856
|
+
taskRunLease = null;
|
|
39857
|
+
}
|
|
39858
|
+
}
|
|
38979
39859
|
const invocation = {
|
|
38980
39860
|
tenantId: tenantId2,
|
|
38981
39861
|
workspaceId: task.workspaceId,
|
|
@@ -39143,6 +40023,7 @@ function createTaskExecutionService(deps) {
|
|
|
39143
40023
|
}
|
|
39144
40024
|
} finally {
|
|
39145
40025
|
taskRunRegistry.unregister(task.id);
|
|
40026
|
+
if (taskRunLease) await taskRunLease.release();
|
|
39146
40027
|
}
|
|
39147
40028
|
};
|
|
39148
40029
|
return {
|
|
@@ -39155,6 +40036,43 @@ function createTaskExecutionService(deps) {
|
|
|
39155
40036
|
};
|
|
39156
40037
|
}
|
|
39157
40038
|
|
|
40039
|
+
// src/services/leadership.ts
|
|
40040
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
40041
|
+
async function runAsLeader(store, name, fn, options = {}) {
|
|
40042
|
+
const key5 = `leader:${name}`;
|
|
40043
|
+
const owner2 = options.owner ?? getReplicaId();
|
|
40044
|
+
const holder = `${owner2}#${randomUUID12()}`;
|
|
40045
|
+
const ttlMs = options.ttlMs ?? 6e4;
|
|
40046
|
+
if (!await store.tryAcquire(key5, holder, ttlMs)) return { ran: false };
|
|
40047
|
+
const heartbeat = setInterval(() => {
|
|
40048
|
+
void store.renew(key5, holder, ttlMs).catch(() => void 0);
|
|
40049
|
+
}, Math.max(1e3, Math.floor(ttlMs / 3)));
|
|
40050
|
+
heartbeat.unref?.();
|
|
40051
|
+
try {
|
|
40052
|
+
const result = await fn();
|
|
40053
|
+
return { ran: true, result };
|
|
40054
|
+
} finally {
|
|
40055
|
+
clearInterval(heartbeat);
|
|
40056
|
+
if (!options.hold) await store.release(key5, holder).catch(() => void 0);
|
|
40057
|
+
}
|
|
40058
|
+
}
|
|
40059
|
+
|
|
40060
|
+
// src/services/pluginCatalogSync.ts
|
|
40061
|
+
var PLUGIN_CATALOG_CHANGED_TOPIC = "plugin-catalog-changed";
|
|
40062
|
+
var outbox;
|
|
40063
|
+
var owner = "unknown";
|
|
40064
|
+
function configurePluginCatalogSync(next) {
|
|
40065
|
+
outbox = next?.outbox;
|
|
40066
|
+
owner = next?.owner ?? "unknown";
|
|
40067
|
+
}
|
|
40068
|
+
async function publishPluginCatalogChanged(tenantId2) {
|
|
40069
|
+
if (!outbox || !tenantId2) return;
|
|
40070
|
+
try {
|
|
40071
|
+
await outbox.append({ topic: PLUGIN_CATALOG_CHANGED_TOPIC, payload: { tenantId: tenantId2 }, originReplicaId: owner });
|
|
40072
|
+
} catch {
|
|
40073
|
+
}
|
|
40074
|
+
}
|
|
40075
|
+
|
|
39158
40076
|
// src/index.ts
|
|
39159
40077
|
import * as Protocols from "@axiom-lattice/protocols";
|
|
39160
40078
|
|
|
@@ -39297,9 +40215,9 @@ var createLoadSkillsTool = ({ skills, readAll, pluginSkills, pluginSkillOwners }
|
|
|
39297
40215
|
if (!skillName) continue;
|
|
39298
40216
|
if (await isPluginSkillManagedInSandbox(sandbox, skillName)) {
|
|
39299
40217
|
const enabledDefinition = pluginSkills?.[skillName];
|
|
39300
|
-
const
|
|
39301
|
-
const registered =
|
|
39302
|
-
if (!registered || registered.definition !== enabledDefinition || !
|
|
40218
|
+
const owner2 = pluginSkillOwners?.[skillName];
|
|
40219
|
+
const registered = owner2 && enabledDefinition ? PluginRegistry.getSkillForPlugin(owner2, skillName) : void 0;
|
|
40220
|
+
if (!registered || registered.definition !== enabledDefinition || !owner2 || !await isPluginSkillAuthorizedInSandbox(sandbox, skillName, owner2) || await getPluginSkillManifestVersion(sandbox, skillName) !== enabledDefinition.version) {
|
|
39303
40221
|
continue;
|
|
39304
40222
|
}
|
|
39305
40223
|
}
|
|
@@ -39325,8 +40243,8 @@ var createLoadSkillsTool = ({ skills, readAll, pluginSkills, pluginSkillOwners }
|
|
|
39325
40243
|
const seenNames = new Set(filteredSkills.map((skill) => skill.name));
|
|
39326
40244
|
try {
|
|
39327
40245
|
for (const [name, definition] of Object.entries(pluginSkills ?? {})) {
|
|
39328
|
-
const
|
|
39329
|
-
const registered =
|
|
40246
|
+
const owner2 = pluginSkillOwners?.[name];
|
|
40247
|
+
const registered = owner2 ? PluginRegistry.getSkillForPlugin(owner2, name) : void 0;
|
|
39330
40248
|
if (!registered || registered.definition !== definition) continue;
|
|
39331
40249
|
const { meta } = parseSkillFrontmatter(definition.content);
|
|
39332
40250
|
if (!meta.name || !meta.description || seenNames.has(meta.name)) continue;
|
|
@@ -39363,24 +40281,24 @@ import z54 from "zod";
|
|
|
39363
40281
|
import { tool as tool48 } from "langchain";
|
|
39364
40282
|
|
|
39365
40283
|
// src/sandbox_plugin/pluginSkillResolution.ts
|
|
39366
|
-
async function resolveTenantPluginSkill(tenantId2,
|
|
40284
|
+
async function resolveTenantPluginSkill(tenantId2, owner2, skillName) {
|
|
39367
40285
|
try {
|
|
39368
40286
|
const { plugins } = await getSandboxPluginCatalog().ensureLoaded(tenantId2);
|
|
39369
|
-
const plugin = plugins.find((candidate) => candidate.meta.type ===
|
|
40287
|
+
const plugin = plugins.find((candidate) => candidate.meta.type === owner2);
|
|
39370
40288
|
return plugin?.skills?.[skillName];
|
|
39371
40289
|
} catch {
|
|
39372
40290
|
return void 0;
|
|
39373
40291
|
}
|
|
39374
40292
|
}
|
|
39375
|
-
async function resolveEnabledPluginSkill(
|
|
39376
|
-
if (!
|
|
39377
|
-
const registered = PluginRegistry.getSkillForPlugin(
|
|
39378
|
-
if (registered && registered.pluginType ===
|
|
39379
|
-
return { pluginType:
|
|
40293
|
+
async function resolveEnabledPluginSkill(owner2, skillName, enabledDefinition, tenantId2) {
|
|
40294
|
+
if (!owner2 || !enabledDefinition) return void 0;
|
|
40295
|
+
const registered = PluginRegistry.getSkillForPlugin(owner2, skillName);
|
|
40296
|
+
if (registered && registered.pluginType === owner2 && registered.definition === enabledDefinition) {
|
|
40297
|
+
return { pluginType: owner2, definition: enabledDefinition };
|
|
39380
40298
|
}
|
|
39381
40299
|
if (!tenantId2) return void 0;
|
|
39382
|
-
const tenantDefinition = await resolveTenantPluginSkill(tenantId2,
|
|
39383
|
-
return tenantDefinition ? { pluginType:
|
|
40300
|
+
const tenantDefinition = await resolveTenantPluginSkill(tenantId2, owner2, skillName);
|
|
40301
|
+
return tenantDefinition ? { pluginType: owner2, definition: tenantDefinition } : void 0;
|
|
39384
40302
|
}
|
|
39385
40303
|
|
|
39386
40304
|
// src/tool_lattice/skill/load_skill_content.ts
|
|
@@ -39442,10 +40360,10 @@ var createLoadSkillContentTool = (pluginSkills, pluginSkillOwnersOrStaticSelecti
|
|
|
39442
40360
|
return result2;
|
|
39443
40361
|
}
|
|
39444
40362
|
const enabledDefinition = pluginSkills?.[input.skill_name];
|
|
39445
|
-
const
|
|
40363
|
+
const owner2 = pluginSkillOwners?.[input.skill_name];
|
|
39446
40364
|
const runConfig = _exe_config?.configurable?.runConfig || {};
|
|
39447
40365
|
const pluginSkill = await resolveEnabledPluginSkill(
|
|
39448
|
-
|
|
40366
|
+
owner2,
|
|
39449
40367
|
input.skill_name,
|
|
39450
40368
|
enabledDefinition,
|
|
39451
40369
|
runConfig.tenantId
|
|
@@ -39552,9 +40470,9 @@ var createLoadSkillResourceTool = (pluginSkills, pluginSkillOwners) => {
|
|
|
39552
40470
|
validateRelativePath(input.resource_path, "resource");
|
|
39553
40471
|
const sandbox = await getSandboxFromExeConfig3(_exe_config);
|
|
39554
40472
|
const definition = pluginSkills?.[input.skill_name];
|
|
39555
|
-
const
|
|
40473
|
+
const owner2 = pluginSkillOwners?.[input.skill_name];
|
|
39556
40474
|
const tenantId2 = _exe_config?.configurable?.runConfig?.tenantId;
|
|
39557
|
-
const resolved = await resolveEnabledPluginSkill(
|
|
40475
|
+
const resolved = await resolveEnabledPluginSkill(owner2, input.skill_name, definition, tenantId2);
|
|
39558
40476
|
if (definition) {
|
|
39559
40477
|
if (!resolved || !resolved.definition.resources?.[input.resource_path]) {
|
|
39560
40478
|
return `Resource "${input.resource_path}" not found for skill "${input.skill_name}".`;
|
|
@@ -41786,9 +42704,9 @@ async function renderAvailableExecutors(rc, tenantId2) {
|
|
|
41786
42704
|
const governed = authority.kind === "projectRoom" || authority.kind === "projectTask";
|
|
41787
42705
|
const projectId = governed ? (authority.trusted.projectTask ?? authority.trusted.projectRoom)?.projectId : void 0;
|
|
41788
42706
|
const cacheKey = `${tenantId2}:${governed ? `project:${projectId ?? ""}` : "ordinary"}`;
|
|
41789
|
-
const
|
|
42707
|
+
const cached2 = executorCache.get(cacheKey);
|
|
41790
42708
|
const now = Date.now();
|
|
41791
|
-
if (
|
|
42709
|
+
if (cached2 && now - cached2.at < EXECUTOR_CACHE_TTL_MS) return cached2.text;
|
|
41792
42710
|
const lines = [];
|
|
41793
42711
|
try {
|
|
41794
42712
|
if (governed && projectId) {
|
|
@@ -46074,6 +46992,7 @@ var sandboxPluginsPlugin = {
|
|
|
46074
46992
|
}
|
|
46075
46993
|
case "reload": {
|
|
46076
46994
|
const loaded = await catalog2.reload(tenantId2);
|
|
46995
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
46077
46996
|
return JSON.stringify({ reloaded: true, plugins: loaded.plugins.length, diagnostics: loaded.diagnostics });
|
|
46078
46997
|
}
|
|
46079
46998
|
case "create":
|
|
@@ -46093,12 +47012,14 @@ var sandboxPluginsPlugin = {
|
|
|
46093
47012
|
if (!check.manifest) return JSON.stringify({ written: false, diagnostics: check.diagnostics });
|
|
46094
47013
|
await catalog2.writePlugin(tenantId2, input.type, input.manifest, handlers);
|
|
46095
47014
|
const loaded = await catalog2.reload(tenantId2);
|
|
47015
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
46096
47016
|
return JSON.stringify({ written: true, diagnostics: loaded.diagnostics, hash: loaded.hash });
|
|
46097
47017
|
}
|
|
46098
47018
|
case "delete": {
|
|
46099
47019
|
if (!input.type) return "type is required";
|
|
46100
47020
|
await catalog2.deletePlugin(tenantId2, input.type);
|
|
46101
47021
|
await catalog2.reload(tenantId2);
|
|
47022
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
46102
47023
|
return JSON.stringify({ deleted: true });
|
|
46103
47024
|
}
|
|
46104
47025
|
case "validate": {
|
|
@@ -46210,6 +47131,26 @@ function registerBuiltinPlugins() {
|
|
|
46210
47131
|
}
|
|
46211
47132
|
}
|
|
46212
47133
|
|
|
47134
|
+
// src/sandbox_plugin/provisionOpenClient.ts
|
|
47135
|
+
import { readFileSync } from "fs";
|
|
47136
|
+
var SDK_ROOT = "/root/.agents/sdk";
|
|
47137
|
+
var CLIENT_DIR = `${SDK_ROOT}/open-mcp-client`;
|
|
47138
|
+
var MANIFEST_PATH2 = `${SDK_ROOT}/.open-client-manifest.json`;
|
|
47139
|
+
async function provisionSandboxOpenClient(sandbox, bundle) {
|
|
47140
|
+
await sandbox.file.createDirectory(SDK_ROOT);
|
|
47141
|
+
await sandbox.file.createDirectory(CLIENT_DIR);
|
|
47142
|
+
await sandbox.file.writeFile(`${CLIENT_DIR}/index.js`, bundle.indexJs);
|
|
47143
|
+
await sandbox.file.writeFile(`${CLIENT_DIR}/cli.js`, bundle.cliJs);
|
|
47144
|
+
await sandbox.file.writeFile(MANIFEST_PATH2, JSON.stringify({ version: bundle.version }));
|
|
47145
|
+
}
|
|
47146
|
+
function buildBundleFromDist(distDir, version) {
|
|
47147
|
+
return {
|
|
47148
|
+
indexJs: readFileSync(`${distDir}/index.js`, "utf8"),
|
|
47149
|
+
cliJs: readFileSync(`${distDir}/cli.js`, "utf8"),
|
|
47150
|
+
version
|
|
47151
|
+
};
|
|
47152
|
+
}
|
|
47153
|
+
|
|
46213
47154
|
// src/personal_assistant/PersonalAssistantConfig.ts
|
|
46214
47155
|
function deepClone(obj) {
|
|
46215
47156
|
return JSON.parse(JSON.stringify(obj));
|
|
@@ -46671,10 +47612,12 @@ export {
|
|
|
46671
47612
|
InMemoryChunkBuffer,
|
|
46672
47613
|
InMemoryCollectionStore,
|
|
46673
47614
|
InMemoryDatabaseConfigStore,
|
|
47615
|
+
InMemoryLeaseStore,
|
|
46674
47616
|
InMemoryMailboxStore,
|
|
46675
47617
|
InMemoryMenuStore,
|
|
46676
47618
|
InMemoryModelProviderStore,
|
|
46677
47619
|
InMemoryOpenAuditStore,
|
|
47620
|
+
InMemoryOutboxStore,
|
|
46678
47621
|
InMemoryProjectBotMembershipStore,
|
|
46679
47622
|
InMemoryProjectMembershipStore,
|
|
46680
47623
|
InMemoryProjectRoomCoordinator,
|
|
@@ -46694,6 +47637,7 @@ export {
|
|
|
46694
47637
|
LatticeEval,
|
|
46695
47638
|
LatticeEvalProject,
|
|
46696
47639
|
LatticeEvalSuite,
|
|
47640
|
+
LeaseAcquisitionTimeoutError,
|
|
46697
47641
|
LocalSandboxInstance,
|
|
46698
47642
|
LocalSandboxProvider,
|
|
46699
47643
|
LoggerLatticeManager,
|
|
@@ -46716,7 +47660,10 @@ export {
|
|
|
46716
47660
|
MicrosandboxServiceClient,
|
|
46717
47661
|
ModelLatticeManager,
|
|
46718
47662
|
MysqlDatabase,
|
|
47663
|
+
OutboxPoller,
|
|
46719
47664
|
PACK_DIRECTORY_TIMEOUT_SECONDS,
|
|
47665
|
+
PLATFORM_SECRET_ENV_VARS,
|
|
47666
|
+
PLUGIN_CATALOG_CHANGED_TOPIC,
|
|
46720
47667
|
PersonalAssistantConfig,
|
|
46721
47668
|
PinoLoggerClient,
|
|
46722
47669
|
PluginRegistry,
|
|
@@ -46737,6 +47684,8 @@ export {
|
|
|
46737
47684
|
RepeatedToolCallError,
|
|
46738
47685
|
RoomAgentMessageService,
|
|
46739
47686
|
SAFE_PATH_COMPONENT,
|
|
47687
|
+
SANDBOX_OPEN_GATEWAY_URL_ENV,
|
|
47688
|
+
SANDBOX_OPEN_TOKEN_ENV,
|
|
46740
47689
|
STTModelLattice,
|
|
46741
47690
|
STTModelLatticeManager,
|
|
46742
47691
|
SandboxFilesystem,
|
|
@@ -46777,11 +47726,13 @@ export {
|
|
|
46777
47726
|
appendReconciliationWarning,
|
|
46778
47727
|
appendUiFence,
|
|
46779
47728
|
assertSafeUpstreamUrl,
|
|
47729
|
+
buildBundleFromDist,
|
|
46780
47730
|
buildGrepResultsDict,
|
|
46781
47731
|
buildInput,
|
|
46782
47732
|
buildNamedVolumeName,
|
|
46783
47733
|
buildRemotePackDirectoryCommand,
|
|
46784
47734
|
buildSandboxMetadataEnv,
|
|
47735
|
+
buildSandboxOpenEnv,
|
|
46785
47736
|
buildSkillFile,
|
|
46786
47737
|
buildStateAnnotation,
|
|
46787
47738
|
buildTableName,
|
|
@@ -46790,11 +47741,14 @@ export {
|
|
|
46790
47741
|
checkEmptyContent,
|
|
46791
47742
|
clearEncryptionKeyCache,
|
|
46792
47743
|
clearEvalRunService,
|
|
47744
|
+
clearSandboxOpenCredentialProviderForTests,
|
|
46793
47745
|
collectionLatticeManager,
|
|
46794
47746
|
compileInternal,
|
|
46795
47747
|
compileSandboxPlugin,
|
|
46796
47748
|
compileWorkflow,
|
|
46797
47749
|
computeSandboxName,
|
|
47750
|
+
configureCoordinationLeaseStore,
|
|
47751
|
+
configurePluginCatalogSync,
|
|
46798
47752
|
configureStores,
|
|
46799
47753
|
connectAllChannels,
|
|
46800
47754
|
convertToConnection,
|
|
@@ -46826,6 +47780,7 @@ export {
|
|
|
46826
47780
|
createSandboxResolver,
|
|
46827
47781
|
createSchedulerMiddleware,
|
|
46828
47782
|
createSharePayload,
|
|
47783
|
+
createShellExecTool,
|
|
46829
47784
|
createTaskExecutionService,
|
|
46830
47785
|
createTaskLifecycleService,
|
|
46831
47786
|
createTaskMiddleware,
|
|
@@ -46872,6 +47827,7 @@ export {
|
|
|
46872
47827
|
getCheckpointSaver,
|
|
46873
47828
|
getChunkBuffer,
|
|
46874
47829
|
getCollectionEntryCount,
|
|
47830
|
+
getCoordinationLeaseStore,
|
|
46875
47831
|
getEmbeddingsClient,
|
|
46876
47832
|
getEmbeddingsLattice,
|
|
46877
47833
|
getEncryptionKey,
|
|
@@ -46883,15 +47839,18 @@ export {
|
|
|
46883
47839
|
getOrCreateCollectionVectorStore,
|
|
46884
47840
|
getPluginSkillManifestVersion,
|
|
46885
47841
|
getQueueLattice,
|
|
47842
|
+
getReplicaId,
|
|
46886
47843
|
getRuntimeCapabilityConfig,
|
|
46887
47844
|
getRuntimeSkillSelection,
|
|
46888
47845
|
getSTTClient,
|
|
46889
47846
|
getSTTClientWithTenant,
|
|
46890
47847
|
getSTTModelLattice,
|
|
46891
47848
|
getSandBoxManager,
|
|
47849
|
+
getSandboxOpenCredential,
|
|
46892
47850
|
getSandboxPluginCatalog,
|
|
46893
47851
|
getScheduleLattice,
|
|
46894
47852
|
getStoreLattice,
|
|
47853
|
+
getThreadRunOwner,
|
|
46895
47854
|
getToolClient,
|
|
46896
47855
|
getToolClientWithTenant,
|
|
46897
47856
|
getToolDefinition,
|
|
@@ -46945,6 +47904,8 @@ export {
|
|
|
46945
47904
|
projectMutationMutex,
|
|
46946
47905
|
projectRoomPlugin,
|
|
46947
47906
|
projectTaskAdmissionNotifier,
|
|
47907
|
+
provisionSandboxOpenClient,
|
|
47908
|
+
publishPluginCatalogChanged,
|
|
46948
47909
|
queueLatticeManager,
|
|
46949
47910
|
readLoopBreakerConfig,
|
|
46950
47911
|
reconcileAllTenantTaskRuns,
|
|
@@ -46963,6 +47924,7 @@ export {
|
|
|
46963
47924
|
registerModelLatticeForTenant,
|
|
46964
47925
|
registerQueueLattice,
|
|
46965
47926
|
registerSTTModelLattice,
|
|
47927
|
+
registerSandboxOpenCredentialProvider,
|
|
46966
47928
|
registerSandboxProviderType,
|
|
46967
47929
|
registerScheduleLattice,
|
|
46968
47930
|
registerStoreLattice,
|
|
@@ -46973,6 +47935,7 @@ export {
|
|
|
46973
47935
|
registerWorkflowRun,
|
|
46974
47936
|
removeCollectionVectorStore,
|
|
46975
47937
|
renderTemplate,
|
|
47938
|
+
resetReplicaIdForTests,
|
|
46976
47939
|
resolveEnabledPluginSkill,
|
|
46977
47940
|
resolveJudgeModelKey,
|
|
46978
47941
|
resolvePath,
|
|
@@ -46980,6 +47943,7 @@ export {
|
|
|
46980
47943
|
resolveSandboxPluginConnections,
|
|
46981
47944
|
resolveTenantPluginSkill,
|
|
46982
47945
|
roomCoordinatorConfig,
|
|
47946
|
+
runAsLeader,
|
|
46983
47947
|
runRemotePackDirectory,
|
|
46984
47948
|
safeTaskResponseId,
|
|
46985
47949
|
sandboxLatticeManager,
|
|
@@ -46998,11 +47962,15 @@ export {
|
|
|
46998
47962
|
storeLatticeManager,
|
|
46999
47963
|
sttModelLatticeManager,
|
|
47000
47964
|
taskLifecycleNotifier,
|
|
47965
|
+
taskRunLeaseKey,
|
|
47001
47966
|
taskRunRegistry,
|
|
47967
|
+
threadRunLeaseKey,
|
|
47002
47968
|
toJsonSchema,
|
|
47003
47969
|
toSafeStateExpr,
|
|
47004
47970
|
toolLatticeManager,
|
|
47005
47971
|
truncateIfTooLong,
|
|
47972
|
+
tryAcquireTaskRun,
|
|
47973
|
+
tryAcquireThreadRun,
|
|
47006
47974
|
unregisterTeammateAgent,
|
|
47007
47975
|
unregisterWorkflowRun,
|
|
47008
47976
|
updateFileData,
|
|
@@ -47018,6 +47986,7 @@ export {
|
|
|
47018
47986
|
validateToolInput,
|
|
47019
47987
|
vectorStoreLatticeManager,
|
|
47020
47988
|
vectorStoreProviderManager,
|
|
47989
|
+
withLease,
|
|
47021
47990
|
withTimeout,
|
|
47022
47991
|
wrapMcpToolWithUi
|
|
47023
47992
|
};
|