@axiom-lattice/core 6.2.0 → 6.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +781 -24
- package/dist/index.d.ts +781 -24
- package/dist/index.js +1154 -122
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1119 -115
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.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();
|
|
@@ -18254,12 +18552,47 @@ var Agent = class {
|
|
|
18254
18552
|
id: interruptData.id,
|
|
18255
18553
|
data: { content: interruptData.value }
|
|
18256
18554
|
};
|
|
18555
|
+
await this.awaitDurableInterrupt(interruptData.id, signal);
|
|
18257
18556
|
}
|
|
18258
18557
|
if (data) {
|
|
18259
18558
|
this.addChunk(data);
|
|
18260
18559
|
}
|
|
18261
18560
|
}
|
|
18262
18561
|
}
|
|
18562
|
+
/**
|
|
18563
|
+
* Waits until the thread's durable checkpoint reports the given interrupt id.
|
|
18564
|
+
*
|
|
18565
|
+
* Reads {@link getCurrentState} (the checkpoint, i.e. the single source of
|
|
18566
|
+
* truth), never an in-memory status, so a `true` result guarantees a resume
|
|
18567
|
+
* against this thread will find the interrupt. Bounded so a broken
|
|
18568
|
+
* checkpointer cannot strand the stream; on timeout the interrupt is emitted
|
|
18569
|
+
* anyway and a warning is logged.
|
|
18570
|
+
*
|
|
18571
|
+
* @param interruptId - Interrupt id from the streamed `__interrupt__` update.
|
|
18572
|
+
* @param signal - Run abort signal; polling stops when aborted.
|
|
18573
|
+
* @param timeoutMs - Maximum time to wait for durable confirmation.
|
|
18574
|
+
*/
|
|
18575
|
+
async awaitDurableInterrupt(interruptId, signal, timeoutMs = 5e3) {
|
|
18576
|
+
if (!interruptId) return;
|
|
18577
|
+
const deadline = Date.now() + timeoutMs;
|
|
18578
|
+
while (!signal?.aborted) {
|
|
18579
|
+
try {
|
|
18580
|
+
const state = await this.getCurrentState();
|
|
18581
|
+
const durable = (state?.tasks ?? []).some(
|
|
18582
|
+
(task) => (task.interrupts ?? []).some((interrupt5) => interrupt5.id === interruptId)
|
|
18583
|
+
);
|
|
18584
|
+
if (durable) return;
|
|
18585
|
+
} catch {
|
|
18586
|
+
}
|
|
18587
|
+
if (Date.now() >= deadline) {
|
|
18588
|
+
console.warn(
|
|
18589
|
+
`[Agent] interrupt ${interruptId} not durable within ${timeoutMs}ms on thread ${this.thread_id}; emitting without durable confirmation`
|
|
18590
|
+
);
|
|
18591
|
+
return;
|
|
18592
|
+
}
|
|
18593
|
+
await new Promise((resolve4) => setTimeout(resolve4, 20));
|
|
18594
|
+
}
|
|
18595
|
+
}
|
|
18263
18596
|
/**
|
|
18264
18597
|
* Resume LangGraph execution from the last checkpoint.
|
|
18265
18598
|
*
|
|
@@ -18309,6 +18642,29 @@ var Agent = class {
|
|
|
18309
18642
|
}
|
|
18310
18643
|
return this.queueStore;
|
|
18311
18644
|
}
|
|
18645
|
+
/**
|
|
18646
|
+
* Resolves the shared lease store used to serialize thread runs across
|
|
18647
|
+
* Gateway replicas. Returns `undefined` when no lease store is registered so
|
|
18648
|
+
* single-process deployments keep running unconditionally.
|
|
18649
|
+
*/
|
|
18650
|
+
getLeaseStore() {
|
|
18651
|
+
try {
|
|
18652
|
+
return storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
18653
|
+
} catch {
|
|
18654
|
+
return void 0;
|
|
18655
|
+
}
|
|
18656
|
+
}
|
|
18657
|
+
/**
|
|
18658
|
+
* Releases this replica's thread-run ownership lease, if held.
|
|
18659
|
+
*
|
|
18660
|
+
* @remarks Safe to call from any definitive-stop path; a second call is a
|
|
18661
|
+
* no-op. The handle's unique holder makes a stale release harmless.
|
|
18662
|
+
*/
|
|
18663
|
+
async releaseThreadRunLease() {
|
|
18664
|
+
const lease = this.threadRunLease;
|
|
18665
|
+
this.threadRunLease = null;
|
|
18666
|
+
if (lease) await lease.release();
|
|
18667
|
+
}
|
|
18312
18668
|
getDefaultQueueConfig() {
|
|
18313
18669
|
return {
|
|
18314
18670
|
mode: "collect" /* COLLECT */,
|
|
@@ -18334,6 +18690,8 @@ var Agent = class {
|
|
|
18334
18690
|
*/
|
|
18335
18691
|
stopQueueProcessor() {
|
|
18336
18692
|
this.cancelQueueProcessorRetry();
|
|
18693
|
+
this.cancelThreadRunLeaseRetry();
|
|
18694
|
+
void this.releaseThreadRunLease();
|
|
18337
18695
|
this.clearRecoveryBlock();
|
|
18338
18696
|
this.queueProcessorGeneration += 1;
|
|
18339
18697
|
if (this.abortController) {
|
|
@@ -18481,16 +18839,50 @@ var Agent = class {
|
|
|
18481
18839
|
startQueueProcessorIfNeeded() {
|
|
18482
18840
|
return this.startQueueProcessor(true);
|
|
18483
18841
|
}
|
|
18484
|
-
startQueueProcessor(freshWakeup) {
|
|
18842
|
+
async startQueueProcessor(freshWakeup) {
|
|
18485
18843
|
this.queueWakeRequested = true;
|
|
18486
18844
|
if (this.queueProcessorPromise) return this.queueProcessorPromise;
|
|
18487
|
-
if (this.queueProcessorRetryTimer) return
|
|
18845
|
+
if (this.queueProcessorRetryTimer) return;
|
|
18488
18846
|
if (freshWakeup && this.queueProcessorRetryAttempt >= QUEUE_PROCESSOR_MAX_RETRIES) {
|
|
18489
18847
|
this.queueProcessorRetryAttempt = 0;
|
|
18490
18848
|
}
|
|
18849
|
+
if (freshWakeup && this.threadRunLeaseRetryAttempt >= THREAD_RUN_LEASE_MAX_RETRIES) {
|
|
18850
|
+
this.threadRunLeaseRetryAttempt = 0;
|
|
18851
|
+
}
|
|
18491
18852
|
this.queueWakeRequested = false;
|
|
18492
|
-
let processorFailed = false;
|
|
18493
18853
|
const processorGeneration = this.queueProcessorGeneration;
|
|
18854
|
+
if (this.threadRunLease?.lost) await this.releaseThreadRunLease();
|
|
18855
|
+
let acquiredLeaseHere = false;
|
|
18856
|
+
if (this.threadRunLease === null) {
|
|
18857
|
+
const leaseStore = this.getLeaseStore();
|
|
18858
|
+
if (leaseStore) {
|
|
18859
|
+
const lease = await tryAcquireThreadRun({
|
|
18860
|
+
store: leaseStore,
|
|
18861
|
+
tenantId: this.tenant_id,
|
|
18862
|
+
assistantId: this.assistant_id,
|
|
18863
|
+
threadId: this.thread_id,
|
|
18864
|
+
owner: getReplicaId(),
|
|
18865
|
+
ttlMs: THREAD_RUN_LEASE_TTL_MS,
|
|
18866
|
+
onLost: () => {
|
|
18867
|
+
console.warn(`[Agent] Thread-run lease lost for thread ${this.thread_id}; aborting the held run`);
|
|
18868
|
+
this.abortController?.abort();
|
|
18869
|
+
}
|
|
18870
|
+
});
|
|
18871
|
+
if (!lease) {
|
|
18872
|
+
this.scheduleThreadRunLeaseRetry();
|
|
18873
|
+
return;
|
|
18874
|
+
}
|
|
18875
|
+
this.threadRunLease = lease;
|
|
18876
|
+
acquiredLeaseHere = true;
|
|
18877
|
+
this.cancelThreadRunLeaseRetry();
|
|
18878
|
+
}
|
|
18879
|
+
}
|
|
18880
|
+
if (this.queueProcessorPromise) return this.queueProcessorPromise;
|
|
18881
|
+
if (this.queueProcessorGeneration !== processorGeneration) {
|
|
18882
|
+
if (acquiredLeaseHere) await this.releaseThreadRunLease();
|
|
18883
|
+
return;
|
|
18884
|
+
}
|
|
18885
|
+
let processorFailed = false;
|
|
18494
18886
|
const processor = this.runQueueProcessor().catch(async (error) => {
|
|
18495
18887
|
processorFailed = true;
|
|
18496
18888
|
console.error(`Queue processing error for thread ${this.thread_id}:`, error);
|
|
@@ -18508,7 +18900,11 @@ var Agent = class {
|
|
|
18508
18900
|
if (this.queueWakeRequested) void this.startQueueProcessor(false);
|
|
18509
18901
|
return;
|
|
18510
18902
|
}
|
|
18511
|
-
if (failed)
|
|
18903
|
+
if (failed) {
|
|
18904
|
+
this.cancelThreadRunLeaseRetry();
|
|
18905
|
+
await this.releaseThreadRunLease();
|
|
18906
|
+
return;
|
|
18907
|
+
}
|
|
18512
18908
|
this.queueProcessorRetryAttempt = 0;
|
|
18513
18909
|
if (this.queueWakeRequested) {
|
|
18514
18910
|
void this.startQueueProcessor(false);
|
|
@@ -18521,7 +18917,11 @@ var Agent = class {
|
|
|
18521
18917
|
void this.startQueueProcessor(false);
|
|
18522
18918
|
return;
|
|
18523
18919
|
}
|
|
18524
|
-
if (pendingMessages.length === 0)
|
|
18920
|
+
if (pendingMessages.length === 0) {
|
|
18921
|
+
this.cancelThreadRunLeaseRetry();
|
|
18922
|
+
await this.releaseThreadRunLease();
|
|
18923
|
+
return;
|
|
18924
|
+
}
|
|
18525
18925
|
const processingMessages = await this.getQueueStore().getProcessingMessages(
|
|
18526
18926
|
this.thread_id,
|
|
18527
18927
|
this.queueScope()
|
|
@@ -18533,12 +18933,20 @@ var Agent = class {
|
|
|
18533
18933
|
}
|
|
18534
18934
|
if (processingMessages.length > 0) {
|
|
18535
18935
|
const runStatus = await this.getRunStatus();
|
|
18536
|
-
if (runStatus === "busy" /* BUSY */ || runStatus === "interrupted" /* INTERRUPTED */)
|
|
18936
|
+
if (runStatus === "busy" /* BUSY */ || runStatus === "interrupted" /* INTERRUPTED */) {
|
|
18937
|
+
this.cancelThreadRunLeaseRetry();
|
|
18938
|
+
await this.releaseThreadRunLease();
|
|
18939
|
+
return;
|
|
18940
|
+
}
|
|
18537
18941
|
}
|
|
18538
18942
|
void this.startQueueProcessor(false);
|
|
18539
18943
|
} catch (error) {
|
|
18540
18944
|
console.error(`Queue processor finalization failed for thread ${this.thread_id}:`, error);
|
|
18541
18945
|
await this.scheduleQueueProcessorRetry(error, generation);
|
|
18946
|
+
if (!this.queueProcessorPromise) {
|
|
18947
|
+
await this.releaseThreadRunLease();
|
|
18948
|
+
this.cancelThreadRunLeaseRetry();
|
|
18949
|
+
}
|
|
18542
18950
|
}
|
|
18543
18951
|
}
|
|
18544
18952
|
async scheduleQueueProcessorRetry(error, generation) {
|
|
@@ -18576,6 +18984,36 @@ var Agent = class {
|
|
|
18576
18984
|
this.queueProcessorRetryAttempt = 0;
|
|
18577
18985
|
this.queueWakeRequested = false;
|
|
18578
18986
|
}
|
|
18987
|
+
/**
|
|
18988
|
+
* Bounded re-attempt after losing the thread-run lease to a peer. Covers the
|
|
18989
|
+
* narrow window where the peer releases the lease without having observed a
|
|
18990
|
+
* just-enqueued message. Bounded so a genuinely long-held thread does not make
|
|
18991
|
+
* this replica poll forever — the owning replica's loop drains new messages.
|
|
18992
|
+
*/
|
|
18993
|
+
scheduleThreadRunLeaseRetry() {
|
|
18994
|
+
if (this.threadRunLeaseRetryTimer || this.threadRunLeaseRetryAttempt >= THREAD_RUN_LEASE_MAX_RETRIES) return;
|
|
18995
|
+
const delay = Math.min(
|
|
18996
|
+
THREAD_RUN_LEASE_RETRY_BASE_MS * 2 ** this.threadRunLeaseRetryAttempt,
|
|
18997
|
+
THREAD_RUN_LEASE_RETRY_CAP_MS
|
|
18998
|
+
);
|
|
18999
|
+
this.threadRunLeaseRetryAttempt += 1;
|
|
19000
|
+
this.threadRunLeaseRetryTimer = setTimeout(() => {
|
|
19001
|
+
this.threadRunLeaseRetryTimer = void 0;
|
|
19002
|
+
void this.startQueueProcessor(false);
|
|
19003
|
+
}, delay);
|
|
19004
|
+
}
|
|
19005
|
+
/**
|
|
19006
|
+
* Clears any pending thread-run lease retry and resets its backoff budget.
|
|
19007
|
+
*
|
|
19008
|
+
* @remarks Called on lease acquisition and on every definitive processor
|
|
19009
|
+
* stop so the next enqueue starts from the base delay. Never called on
|
|
19010
|
+
* continue/re-arm paths, which must preserve the bounded budget.
|
|
19011
|
+
*/
|
|
19012
|
+
cancelThreadRunLeaseRetry() {
|
|
19013
|
+
if (this.threadRunLeaseRetryTimer) clearTimeout(this.threadRunLeaseRetryTimer);
|
|
19014
|
+
this.threadRunLeaseRetryTimer = void 0;
|
|
19015
|
+
this.threadRunLeaseRetryAttempt = 0;
|
|
19016
|
+
}
|
|
18579
19017
|
async runQueueProcessor() {
|
|
18580
19018
|
const store = this.getQueueStore();
|
|
18581
19019
|
const processingMessages = await store.getProcessingMessages(this.thread_id, this.queueScope());
|
|
@@ -18720,6 +19158,38 @@ var Agent = class {
|
|
|
18720
19158
|
console.error(`[Agent] Failed to initialize agent lattice for ${this.assistant_id} (tenant: ${this.tenant_id}):`, error);
|
|
18721
19159
|
throw error;
|
|
18722
19160
|
}
|
|
19161
|
+
let acquiredLeaseHere = false;
|
|
19162
|
+
if (this.threadRunLease === null) {
|
|
19163
|
+
const leaseStore = this.getLeaseStore();
|
|
19164
|
+
if (leaseStore) {
|
|
19165
|
+
const lease = await tryAcquireThreadRun({
|
|
19166
|
+
store: leaseStore,
|
|
19167
|
+
tenantId: this.tenant_id,
|
|
19168
|
+
assistantId: this.assistant_id,
|
|
19169
|
+
threadId: this.thread_id,
|
|
19170
|
+
owner: getReplicaId(),
|
|
19171
|
+
ttlMs: THREAD_RUN_LEASE_TTL_MS,
|
|
19172
|
+
onLost: () => {
|
|
19173
|
+
console.warn(`[Agent] Thread-run lease lost for thread ${this.thread_id}; aborting the held run`);
|
|
19174
|
+
this.abortController?.abort();
|
|
19175
|
+
}
|
|
19176
|
+
});
|
|
19177
|
+
if (!lease) {
|
|
19178
|
+
return { status: await this.getRunStatus(), settled: false, leaseContended: true };
|
|
19179
|
+
}
|
|
19180
|
+
this.threadRunLease = lease;
|
|
19181
|
+
acquiredLeaseHere = true;
|
|
19182
|
+
this.cancelThreadRunLeaseRetry();
|
|
19183
|
+
}
|
|
19184
|
+
}
|
|
19185
|
+
try {
|
|
19186
|
+
return await this.resumeTaskLocked();
|
|
19187
|
+
} finally {
|
|
19188
|
+
if (acquiredLeaseHere && !this.queueProcessorPromise) await this.releaseThreadRunLease();
|
|
19189
|
+
}
|
|
19190
|
+
}
|
|
19191
|
+
/** Recovery body of {@link resumeTask}, executed while thread ownership is settled. */
|
|
19192
|
+
async resumeTaskLocked() {
|
|
18723
19193
|
const store = this.getQueueStore();
|
|
18724
19194
|
const processingMessages = await store.getProcessingMessages(this.thread_id, this.queueScope());
|
|
18725
19195
|
const preRunState = await this.getCurrentState();
|
|
@@ -18835,6 +19305,8 @@ var Agent = class {
|
|
|
18835
19305
|
*/
|
|
18836
19306
|
async abort() {
|
|
18837
19307
|
this.cancelQueueProcessorRetry();
|
|
19308
|
+
this.cancelThreadRunLeaseRetry();
|
|
19309
|
+
await this.releaseThreadRunLease();
|
|
18838
19310
|
this.clearRecoveryBlock();
|
|
18839
19311
|
this.queueProcessorGeneration += 1;
|
|
18840
19312
|
if (this.abortController) {
|
|
@@ -19494,27 +19966,27 @@ function createCheckAsyncTaskTool() {
|
|
|
19494
19966
|
if (!mainAgent) {
|
|
19495
19967
|
return "Cannot access main agent state.";
|
|
19496
19968
|
}
|
|
19497
|
-
const
|
|
19498
|
-
if (!
|
|
19969
|
+
const cached2 = mainAgent.getAsyncTask(task_id);
|
|
19970
|
+
if (!cached2) {
|
|
19499
19971
|
return `Task ${task_id} not found. Use list_async_tasks to see all tasks.`;
|
|
19500
19972
|
}
|
|
19501
19973
|
try {
|
|
19502
19974
|
if (!agentInstanceManager.hasAgent({
|
|
19503
|
-
assistant_id:
|
|
19975
|
+
assistant_id: cached2.assistantId,
|
|
19504
19976
|
thread_id: task_id,
|
|
19505
19977
|
tenant_id: mainAgent.tenant_id
|
|
19506
19978
|
})) {
|
|
19507
|
-
return `Task ${task_id}: not found (may have been cleaned up). Status was: ${
|
|
19979
|
+
return `Task ${task_id}: not found (may have been cleaned up). Status was: ${cached2.status}`;
|
|
19508
19980
|
}
|
|
19509
19981
|
const subAgent = agentInstanceManager.getAgent({
|
|
19510
|
-
assistant_id:
|
|
19982
|
+
assistant_id: cached2.assistantId,
|
|
19511
19983
|
thread_id: task_id,
|
|
19512
19984
|
tenant_id: mainAgent.tenant_id
|
|
19513
19985
|
});
|
|
19514
19986
|
const status = await subAgent.getRunStatus();
|
|
19515
19987
|
if (status === "busy") {
|
|
19516
19988
|
return `Task ${task_id}: still running.
|
|
19517
|
-
Description: ${
|
|
19989
|
+
Description: ${cached2.description}`;
|
|
19518
19990
|
}
|
|
19519
19991
|
if (status === "idle") {
|
|
19520
19992
|
const state = await subAgent.getCurrentState();
|
|
@@ -19525,21 +19997,21 @@ Description: ${cached.description}`;
|
|
|
19525
19997
|
mainAgent.updateAsyncTaskStatus(task_id, "completed");
|
|
19526
19998
|
const result = lastAI?.content ?? "(completed, no output)";
|
|
19527
19999
|
return `Task ${task_id}: COMPLETED.
|
|
19528
|
-
Description: ${
|
|
20000
|
+
Description: ${cached2.description}
|
|
19529
20001
|
Result:
|
|
19530
20002
|
${result}`;
|
|
19531
20003
|
}
|
|
19532
20004
|
if (status === "error") {
|
|
19533
20005
|
mainAgent.updateAsyncTaskStatus(task_id, "failed");
|
|
19534
20006
|
return `Task ${task_id}: failed.
|
|
19535
|
-
Description: ${
|
|
20007
|
+
Description: ${cached2.description}`;
|
|
19536
20008
|
}
|
|
19537
20009
|
if (status === "interrupted") {
|
|
19538
20010
|
return `Task ${task_id}: interrupted (waiting for input).
|
|
19539
|
-
Description: ${
|
|
20011
|
+
Description: ${cached2.description}`;
|
|
19540
20012
|
}
|
|
19541
20013
|
return `Task ${task_id}: ${status}.
|
|
19542
|
-
Description: ${
|
|
20014
|
+
Description: ${cached2.description}`;
|
|
19543
20015
|
} catch (err) {
|
|
19544
20016
|
return `Task ${task_id}: error checking status: ${err instanceof Error ? err.message : String(err)}`;
|
|
19545
20017
|
}
|
|
@@ -19612,25 +20084,25 @@ function createCancelAsyncTaskTool() {
|
|
|
19612
20084
|
if (!mainAgent) {
|
|
19613
20085
|
return "Cannot access main agent state.";
|
|
19614
20086
|
}
|
|
19615
|
-
const
|
|
19616
|
-
if (!
|
|
20087
|
+
const cached2 = mainAgent.getAsyncTask(task_id);
|
|
20088
|
+
if (!cached2) {
|
|
19617
20089
|
return `Task ${task_id} not found.`;
|
|
19618
20090
|
}
|
|
19619
20091
|
try {
|
|
19620
20092
|
const subAgentExists = agentInstanceManager.hasAgent({
|
|
19621
|
-
assistant_id:
|
|
20093
|
+
assistant_id: cached2.assistantId,
|
|
19622
20094
|
thread_id: task_id,
|
|
19623
20095
|
tenant_id: mainAgent.tenant_id
|
|
19624
20096
|
});
|
|
19625
20097
|
if (subAgentExists) {
|
|
19626
20098
|
const subAgent = agentInstanceManager.getAgent({
|
|
19627
|
-
assistant_id:
|
|
20099
|
+
assistant_id: cached2.assistantId,
|
|
19628
20100
|
thread_id: task_id,
|
|
19629
20101
|
tenant_id: mainAgent.tenant_id
|
|
19630
20102
|
});
|
|
19631
20103
|
await subAgent.abort();
|
|
19632
20104
|
agentInstanceManager.removeAgent({
|
|
19633
|
-
assistant_id:
|
|
20105
|
+
assistant_id: cached2.assistantId,
|
|
19634
20106
|
thread_id: task_id,
|
|
19635
20107
|
tenant_id: mainAgent.tenant_id
|
|
19636
20108
|
});
|
|
@@ -19879,6 +20351,48 @@ var MemoryScheduleStorage = class {
|
|
|
19879
20351
|
});
|
|
19880
20352
|
}
|
|
19881
20353
|
}
|
|
20354
|
+
/**
|
|
20355
|
+
* Atomically claims one due fire by transitioning the task `pending -> running`.
|
|
20356
|
+
*
|
|
20357
|
+
* @param taskId Task to claim.
|
|
20358
|
+
* @returns True when this caller won the claim (task was `pending`); false if
|
|
20359
|
+
* another replica already claimed it or it is not pending.
|
|
20360
|
+
*/
|
|
20361
|
+
async claimScheduledRun(taskId) {
|
|
20362
|
+
const task = this.tasks.get(taskId);
|
|
20363
|
+
if (!task || task.status !== ScheduledTaskStatus.PENDING) {
|
|
20364
|
+
return false;
|
|
20365
|
+
}
|
|
20366
|
+
this.tasks.set(taskId, {
|
|
20367
|
+
...task,
|
|
20368
|
+
status: ScheduledTaskStatus.RUNNING,
|
|
20369
|
+
updatedAt: Date.now()
|
|
20370
|
+
});
|
|
20371
|
+
return true;
|
|
20372
|
+
}
|
|
20373
|
+
/**
|
|
20374
|
+
* Requeues `running` tasks whose `updatedAt` is older than `olderThanMs` back
|
|
20375
|
+
* to `pending` (recovery after a crash that left a claim unsettled).
|
|
20376
|
+
*
|
|
20377
|
+
* @param olderThanMs Age threshold in milliseconds.
|
|
20378
|
+
* @returns The number of tasks requeued.
|
|
20379
|
+
*/
|
|
20380
|
+
async requeueStaleRunning(olderThanMs) {
|
|
20381
|
+
const now = Date.now();
|
|
20382
|
+
const cutoff = now - olderThanMs;
|
|
20383
|
+
let requeued = 0;
|
|
20384
|
+
for (const [taskId, task] of this.tasks.entries()) {
|
|
20385
|
+
if (task.status === ScheduledTaskStatus.RUNNING && task.updatedAt < cutoff) {
|
|
20386
|
+
this.tasks.set(taskId, {
|
|
20387
|
+
...task,
|
|
20388
|
+
status: ScheduledTaskStatus.PENDING,
|
|
20389
|
+
updatedAt: now
|
|
20390
|
+
});
|
|
20391
|
+
requeued++;
|
|
20392
|
+
}
|
|
20393
|
+
}
|
|
20394
|
+
return requeued;
|
|
20395
|
+
}
|
|
19882
20396
|
/**
|
|
19883
20397
|
* Delete task
|
|
19884
20398
|
*/
|
|
@@ -20243,6 +20757,7 @@ function describeCronExpression(expression) {
|
|
|
20243
20757
|
}
|
|
20244
20758
|
|
|
20245
20759
|
// src/schedule_lattice/DefaultScheduleClient.ts
|
|
20760
|
+
var STALE_RUNNING_MS = 30 * 6e4;
|
|
20246
20761
|
var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
20247
20762
|
constructor(storage) {
|
|
20248
20763
|
this.handlers = /* @__PURE__ */ new Map();
|
|
@@ -20483,6 +20998,19 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
20483
20998
|
}
|
|
20484
20999
|
// ===== Recovery =====
|
|
20485
21000
|
async restore() {
|
|
21001
|
+
try {
|
|
21002
|
+
const requeued = await this.storage.requeueStaleRunning(STALE_RUNNING_MS);
|
|
21003
|
+
if (requeued > 0) {
|
|
21004
|
+
console.log(
|
|
21005
|
+
`[Scheduler] Requeued ${requeued} stale running task(s)`
|
|
21006
|
+
);
|
|
21007
|
+
}
|
|
21008
|
+
} catch (error) {
|
|
21009
|
+
console.error(
|
|
21010
|
+
"[Scheduler] Failed to requeue stale running tasks:",
|
|
21011
|
+
error
|
|
21012
|
+
);
|
|
21013
|
+
}
|
|
20486
21014
|
const activeTasks = await this.storage.getActiveTasks();
|
|
20487
21015
|
let restored = 0;
|
|
20488
21016
|
for (const task of activeTasks) {
|
|
@@ -20543,6 +21071,16 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
20543
21071
|
});
|
|
20544
21072
|
}
|
|
20545
21073
|
async executeTask(task) {
|
|
21074
|
+
let claimed = false;
|
|
21075
|
+
try {
|
|
21076
|
+
claimed = await this.storage.claimScheduledRun(task.taskId);
|
|
21077
|
+
} catch (error) {
|
|
21078
|
+
console.error(`[Scheduler] Failed to claim task ${task.taskId}:`, error);
|
|
21079
|
+
return;
|
|
21080
|
+
}
|
|
21081
|
+
if (!claimed) {
|
|
21082
|
+
return;
|
|
21083
|
+
}
|
|
20546
21084
|
const handler = this.handlers.get(task.taskType);
|
|
20547
21085
|
if (!handler) {
|
|
20548
21086
|
console.error(
|
|
@@ -20554,9 +21092,6 @@ var _DefaultScheduleClient = class _DefaultScheduleClient {
|
|
|
20554
21092
|
});
|
|
20555
21093
|
return;
|
|
20556
21094
|
}
|
|
20557
|
-
await this.storage.update(task.taskId, {
|
|
20558
|
-
status: ScheduledTaskStatus2.RUNNING
|
|
20559
|
-
});
|
|
20560
21095
|
console.log(`[Scheduler] Executing task: ${task.taskId}`);
|
|
20561
21096
|
try {
|
|
20562
21097
|
const latestTask = await this.storage.get(task.taskId);
|
|
@@ -25270,8 +25805,8 @@ var VectorStoreProviderManager = class _VectorStoreProviderManager extends BaseL
|
|
|
25270
25805
|
* @param key Provider key name
|
|
25271
25806
|
* @param provider VectorStoreProvider implementation
|
|
25272
25807
|
*/
|
|
25273
|
-
registerProvider(key5,
|
|
25274
|
-
const lattice = { key: key5, provider };
|
|
25808
|
+
registerProvider(key5, provider2) {
|
|
25809
|
+
const lattice = { key: key5, provider: provider2 };
|
|
25275
25810
|
this.registerWithTenant("default", key5, lattice);
|
|
25276
25811
|
}
|
|
25277
25812
|
/**
|
|
@@ -25307,7 +25842,7 @@ var VectorStoreProviderManager = class _VectorStoreProviderManager extends BaseL
|
|
|
25307
25842
|
};
|
|
25308
25843
|
var vectorStoreProviderManager = VectorStoreProviderManager.getInstance();
|
|
25309
25844
|
vectorStoreProviderManager.registerProvider("default", new MemoryVectorStoreProvider());
|
|
25310
|
-
var registerVectorStoreProvider = (key5,
|
|
25845
|
+
var registerVectorStoreProvider = (key5, provider2) => vectorStoreProviderManager.registerProvider(key5, provider2);
|
|
25311
25846
|
var getVectorStoreProvider = (key5) => vectorStoreProviderManager.getProvider(key5);
|
|
25312
25847
|
|
|
25313
25848
|
// src/store_lattice/configureStores.ts
|
|
@@ -28009,7 +28544,110 @@ independently before the workflow's integration eval.
|
|
|
28009
28544
|
|
|
28010
28545
|
An unsupported architecture conversion interrupts the flow and requests a new
|
|
28011
28546
|
user decision. Do not route backward to the Charter or to [[agent-build]], and do
|
|
28012
|
-
not create a replacement
|
|
28547
|
+
not create a replacement.`,
|
|
28548
|
+
"ptc": `---
|
|
28549
|
+
name: ptc
|
|
28550
|
+
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.
|
|
28551
|
+
metadata:
|
|
28552
|
+
role: workflow
|
|
28553
|
+
domain: orchestration
|
|
28554
|
+
verified: unverified
|
|
28555
|
+
---
|
|
28556
|
+
|
|
28557
|
+
# Programmatic Tool Calling (PTC)
|
|
28558
|
+
|
|
28559
|
+
PTC means the model writes and runs code that calls platform tools itself, instead
|
|
28560
|
+
of calling tools one at a time. Reach for it when orchestration is multi-step,
|
|
28561
|
+
data-heavy, or needs a loop/branch that would be wasteful as a chain of model tool
|
|
28562
|
+
calls.
|
|
28563
|
+
|
|
28564
|
+
## Where the code runs
|
|
28565
|
+
|
|
28566
|
+
Run the code with \`code_eval\` (backed by \`shell_exec\`). Each execution process is
|
|
28567
|
+
injected with two environment variables:
|
|
28568
|
+
|
|
28569
|
+
- \`API_GATEWAY_URL\` \u2014 the gateway base URL.
|
|
28570
|
+
- \`OPEN_API_TOKEN\` \u2014 a short-lived bearer token **self-bound to this agent**. It is
|
|
28571
|
+
not reusable elsewhere.
|
|
28572
|
+
|
|
28573
|
+
The token already encodes this agent's authority: the platform reflects the agent's
|
|
28574
|
+
own configured middleware into Open grants, plus a small always-on baseline
|
|
28575
|
+
(\`kb\` read-only and \`sandbox:self\`). So the callable set = that baseline \u222A the
|
|
28576
|
+
domains your configured middleware exposes \u2014 and nothing beyond it.
|
|
28577
|
+
|
|
28578
|
+
## Client
|
|
28579
|
+
|
|
28580
|
+
The sandbox must have the zero-dependency \`@axiom-lattice/open-mcp-client\` package.
|
|
28581
|
+
Get it one of two ways:
|
|
28582
|
+
|
|
28583
|
+
- **Preinstalled in the sandbox image** (recommended): \`open-mcp\` is on \`PATH\`; for
|
|
28584
|
+
\`require("@axiom-lattice/open-mcp-client")\` to resolve, install it into the working
|
|
28585
|
+
directory or point \`NODE_PATH\` at the global \`node_modules\`.
|
|
28586
|
+
- **Install it in this run** when the sandbox has network + npm:
|
|
28587
|
+
|
|
28588
|
+
\`\`\`bash
|
|
28589
|
+
npm install @axiom-lattice/open-mcp-client
|
|
28590
|
+
# or use without installing:
|
|
28591
|
+
npx @axiom-lattice/open-mcp-client tools list --json
|
|
28592
|
+
\`\`\`
|
|
28593
|
+
|
|
28594
|
+
\`\`\`js
|
|
28595
|
+
const { OpenMcpClient } = require("@axiom-lattice/open-mcp-client");
|
|
28596
|
+
const client = OpenMcpClient.fromEnv(); // reads API_GATEWAY_URL + OPEN_API_TOKEN
|
|
28597
|
+
\`\`\`
|
|
28598
|
+
|
|
28599
|
+
CLI equivalents (config comes from the same env vars):
|
|
28600
|
+
|
|
28601
|
+
\`\`\`bash
|
|
28602
|
+
open-mcp tools list --json
|
|
28603
|
+
open-mcp tools call kb_search --json '{"query":"refund policy"}'
|
|
28604
|
+
\`\`\`
|
|
28605
|
+
|
|
28606
|
+
## Discover, then call
|
|
28607
|
+
|
|
28608
|
+
1. **Discover first.** Call \`await client.listTools()\`. This returns exactly the
|
|
28609
|
+
tools this agent is authorized to call (the server filters by the token's grants
|
|
28610
|
+
on every request, so it is the source of truth).
|
|
28611
|
+
2. **Only call discovered tools.** Pick a tool from that list and call
|
|
28612
|
+
\`await client.callTool(name, args)\` with args matching the tool's \`inputSchema\`.
|
|
28613
|
+
3. **Print the final result as JSON to stdout** so the calling agent can consume it.
|
|
28614
|
+
Keep intermediate logs minimal.
|
|
28615
|
+
|
|
28616
|
+
An unconfigured domain isn't registered, so calling it returns an \`isError\`
|
|
28617
|
+
tool-not-found result; a registered tool refused by the token's grants surfaces
|
|
28618
|
+
\`GRANT_DENIED\`. Either way the capability is **not configured for this agent**.
|
|
28619
|
+
Do not retry or work around it \u2014 drop that step or tell the user which
|
|
28620
|
+
middleware/domain must be enabled. A denied call is expected behavior, not a
|
|
28621
|
+
transient failure.
|
|
28622
|
+
|
|
28623
|
+
## Tips
|
|
28624
|
+
|
|
28625
|
+
- Fan out with \`Promise.all\` over many items instead of many sequential model turns;
|
|
28626
|
+
that is the main win of PTC.
|
|
28627
|
+
- Inspect \`tool.inputSchema\` before calling to avoid schema-validation errors.
|
|
28628
|
+
- Reduce large results in code and return only the fields the agent needs.
|
|
28629
|
+
- The token is short-lived; for very long jobs re-read the env per \`code_eval\` run
|
|
28630
|
+
rather than caching the token in a file.
|
|
28631
|
+
|
|
28632
|
+
## Worked example
|
|
28633
|
+
|
|
28634
|
+
\`\`\`js
|
|
28635
|
+
const { OpenMcpClient } = require("@axiom-lattice/open-mcp-client");
|
|
28636
|
+
|
|
28637
|
+
async function main() {
|
|
28638
|
+
const client = OpenMcpClient.fromEnv(); // API_GATEWAY_URL + OPEN_API_TOKEN
|
|
28639
|
+
const tools = await client.listTools(); // exactly what this agent may call
|
|
28640
|
+
const pick = tools.find((t) => t.name === "kb_search") ?? tools[0];
|
|
28641
|
+
const out = await client.callTool(pick.name, { query: "refund policy" });
|
|
28642
|
+
console.log(JSON.stringify({ called: pick.name, result: out.json() }));
|
|
28643
|
+
}
|
|
28644
|
+
|
|
28645
|
+
main().catch((err) => { console.error(String(err)); process.exit(1); });
|
|
28646
|
+
\`\`\`
|
|
28647
|
+
|
|
28648
|
+
Run this in \`code_eval\`. The first run proves env + client wiring; then extend it
|
|
28649
|
+
into the real fan-out/aggregation the task needs.
|
|
28650
|
+
`
|
|
28013
28651
|
};
|
|
28014
28652
|
function getBuiltInSkillMeta(name) {
|
|
28015
28653
|
const content = BUILTIN_SKILLS[name];
|
|
@@ -28606,7 +29244,7 @@ ${body}` : `${frontmatter}
|
|
|
28606
29244
|
};
|
|
28607
29245
|
|
|
28608
29246
|
// src/store_lattice/InMemoryMenuStore.ts
|
|
28609
|
-
import { randomUUID as
|
|
29247
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
28610
29248
|
var InMemoryMenuStore = class {
|
|
28611
29249
|
constructor() {
|
|
28612
29250
|
this.items = /* @__PURE__ */ new Map();
|
|
@@ -28627,7 +29265,7 @@ var InMemoryMenuStore = class {
|
|
|
28627
29265
|
async create(input) {
|
|
28628
29266
|
const now = /* @__PURE__ */ new Date();
|
|
28629
29267
|
const item = {
|
|
28630
|
-
id:
|
|
29268
|
+
id: randomUUID7(),
|
|
28631
29269
|
tenantId: input.tenantId,
|
|
28632
29270
|
menuTarget: input.menuTarget,
|
|
28633
29271
|
group: input.group,
|
|
@@ -31139,9 +31777,9 @@ async function getOrCreateCollectionVectorStore(name, embeddingKey, tenantId2, p
|
|
|
31139
31777
|
const pendingInitialization = pendingVectorStoreInitializations.get(storeKey);
|
|
31140
31778
|
if (pendingInitialization) return pendingInitialization;
|
|
31141
31779
|
const initialization = (async () => {
|
|
31142
|
-
const
|
|
31780
|
+
const provider2 = vectorStoreProviderManager.getProvider(providerKey);
|
|
31143
31781
|
const tableName = buildTableName(tenantId2, name);
|
|
31144
|
-
const vectorStore = await
|
|
31782
|
+
const vectorStore = await provider2.create({ tableName, embeddingKey });
|
|
31145
31783
|
vectorStoreLatticeManager.registerLattice(storeKey, vectorStore);
|
|
31146
31784
|
return vectorStore;
|
|
31147
31785
|
})();
|
|
@@ -31159,9 +31797,9 @@ async function getCollectionEntryCount(name, embeddingKey, tenantId2) {
|
|
|
31159
31797
|
return vs.getDocumentCount();
|
|
31160
31798
|
}
|
|
31161
31799
|
try {
|
|
31162
|
-
const
|
|
31163
|
-
if (
|
|
31164
|
-
return
|
|
31800
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
31801
|
+
if (provider2.getEntryCount) {
|
|
31802
|
+
return provider2.getEntryCount(buildTableName(tenantId2, name));
|
|
31165
31803
|
}
|
|
31166
31804
|
} catch {
|
|
31167
31805
|
}
|
|
@@ -31173,9 +31811,9 @@ async function listCollectionEntries(name, embeddingKey, tenantId2) {
|
|
|
31173
31811
|
return vs.getAllDocuments();
|
|
31174
31812
|
}
|
|
31175
31813
|
try {
|
|
31176
|
-
const
|
|
31177
|
-
if (
|
|
31178
|
-
return
|
|
31814
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
31815
|
+
if (provider2.listEntries) {
|
|
31816
|
+
return provider2.listEntries(buildTableName(tenantId2, name));
|
|
31179
31817
|
}
|
|
31180
31818
|
} catch {
|
|
31181
31819
|
}
|
|
@@ -31185,9 +31823,9 @@ async function removeCollectionVectorStore(name, tenantId2) {
|
|
|
31185
31823
|
const storeKey = buildKey(tenantId2, name);
|
|
31186
31824
|
const tableName = buildTableName(tenantId2, name);
|
|
31187
31825
|
try {
|
|
31188
|
-
const
|
|
31189
|
-
if (
|
|
31190
|
-
await
|
|
31826
|
+
const provider2 = vectorStoreProviderManager.getProvider("default");
|
|
31827
|
+
if (provider2.dropTable) {
|
|
31828
|
+
await provider2.dropTable(tableName);
|
|
31191
31829
|
}
|
|
31192
31830
|
} catch {
|
|
31193
31831
|
}
|
|
@@ -33502,7 +34140,7 @@ var DaytonaProvider = class {
|
|
|
33502
34140
|
|
|
33503
34141
|
// src/sandbox_lattice/providers/LocalSandboxProvider.ts
|
|
33504
34142
|
import * as path6 from "path";
|
|
33505
|
-
import * as
|
|
34143
|
+
import * as os2 from "os";
|
|
33506
34144
|
import * as fs4 from "fs/promises";
|
|
33507
34145
|
|
|
33508
34146
|
// src/sandbox_lattice/LocalSandboxInstance.ts
|
|
@@ -33529,6 +34167,32 @@ function assertRegularDeleteTarget(file, stat4) {
|
|
|
33529
34167
|
function quoteShellArgument(value) {
|
|
33530
34168
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
33531
34169
|
}
|
|
34170
|
+
var PLATFORM_SECRET_ENV_VARS = [
|
|
34171
|
+
"OPEN_TOKEN_SECRET",
|
|
34172
|
+
"AUTH_TOKEN_SECRET",
|
|
34173
|
+
"JWT_SECRET",
|
|
34174
|
+
"WEB_APP_ATTACHMENT_SECRET",
|
|
34175
|
+
"LATTICE_ENCRYPTION_KEY",
|
|
34176
|
+
"DATABASE_URL",
|
|
34177
|
+
"REDIS_PASSWORD",
|
|
34178
|
+
"MICROSANDBOX_API_KEY",
|
|
34179
|
+
"DAYTONA_API_KEY",
|
|
34180
|
+
"E2B_API_KEY",
|
|
34181
|
+
"OPENAI_API_KEY",
|
|
34182
|
+
"AZURE_OPENAI_API_KEY",
|
|
34183
|
+
"ANTHROPIC_API_KEY",
|
|
34184
|
+
"TAVILY_API_KEY",
|
|
34185
|
+
"VAPID_PRIVATE_KEY",
|
|
34186
|
+
"SUPABASE_KEY",
|
|
34187
|
+
"A2A_API_KEYS"
|
|
34188
|
+
];
|
|
34189
|
+
function stripPlatformSecrets(env) {
|
|
34190
|
+
const rest = { ...env };
|
|
34191
|
+
for (const name of PLATFORM_SECRET_ENV_VARS) {
|
|
34192
|
+
delete rest[name];
|
|
34193
|
+
}
|
|
34194
|
+
return rest;
|
|
34195
|
+
}
|
|
33532
34196
|
function validatePackEntryName(name) {
|
|
33533
34197
|
if (!name || name === "." || name === ".." || name.includes("\\") || name.includes("/")) {
|
|
33534
34198
|
throw new Error(`Cannot pack: unsafe entry name '${name}'`);
|
|
@@ -33701,7 +34365,7 @@ var LocalSandboxInstance = class {
|
|
|
33701
34365
|
timeout: timeoutMs,
|
|
33702
34366
|
maxBuffer: 10 * 1024 * 1024,
|
|
33703
34367
|
// 10MB
|
|
33704
|
-
env: { ...process.env, HOME: this.rootDir }
|
|
34368
|
+
env: stripPlatformSecrets({ ...process.env, HOME: this.rootDir })
|
|
33705
34369
|
}
|
|
33706
34370
|
);
|
|
33707
34371
|
const output = stderr ? `${stdout}
|
|
@@ -33966,7 +34630,7 @@ var LocalSandboxProvider = class {
|
|
|
33966
34630
|
this.instances = /* @__PURE__ */ new Map();
|
|
33967
34631
|
this.creating = /* @__PURE__ */ new Map();
|
|
33968
34632
|
this.createResourceAddress = createResourceAddress;
|
|
33969
|
-
this.basePath = config.basePath ?? path6.join(
|
|
34633
|
+
this.basePath = config.basePath ?? path6.join(os2.homedir(), ".axiom-local-sandbox");
|
|
33970
34634
|
}
|
|
33971
34635
|
async createSandbox(name, _config) {
|
|
33972
34636
|
const existing = this.instances.get(name);
|
|
@@ -35342,6 +36006,10 @@ var TaskLifecycleNotifier = class {
|
|
|
35342
36006
|
this.listeners = /* @__PURE__ */ new Set();
|
|
35343
36007
|
this.tails = /* @__PURE__ */ new Map();
|
|
35344
36008
|
}
|
|
36009
|
+
/** Installs (or clears) the durable outbox used to fan notifications to other replicas. */
|
|
36010
|
+
setOutbox(outbox2) {
|
|
36011
|
+
this.outbox = outbox2;
|
|
36012
|
+
}
|
|
35345
36013
|
/**
|
|
35346
36014
|
* Registers an async lifecycle listener.
|
|
35347
36015
|
*
|
|
@@ -35362,6 +36030,25 @@ var TaskLifecycleNotifier = class {
|
|
|
35362
36030
|
* @throws Error when the event is malformed or one or more listeners reject.
|
|
35363
36031
|
*/
|
|
35364
36032
|
async publish(event) {
|
|
36033
|
+
const snapshot = snapshotNotification(event);
|
|
36034
|
+
const key5 = `${snapshot.tenantId}:${snapshot.taskId}`;
|
|
36035
|
+
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
36036
|
+
const delivery = previous.catch(() => void 0).then(() => this.deliver(snapshot));
|
|
36037
|
+
this.tails.set(key5, delivery);
|
|
36038
|
+
if (this.outbox) {
|
|
36039
|
+
try {
|
|
36040
|
+
await this.outbox.append({ topic: "task-lifecycle", payload: snapshot, originReplicaId: getReplicaId() });
|
|
36041
|
+
} catch {
|
|
36042
|
+
}
|
|
36043
|
+
}
|
|
36044
|
+
try {
|
|
36045
|
+
await delivery;
|
|
36046
|
+
} finally {
|
|
36047
|
+
if (this.tails.get(key5) === delivery) this.tails.delete(key5);
|
|
36048
|
+
}
|
|
36049
|
+
}
|
|
36050
|
+
/** Delivers one outbox payload to local listeners without re-appending (poller path). */
|
|
36051
|
+
async deliverFromOutbox(event) {
|
|
35365
36052
|
const snapshot = snapshotNotification(event);
|
|
35366
36053
|
const key5 = `${snapshot.tenantId}:${snapshot.taskId}`;
|
|
35367
36054
|
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
@@ -35426,6 +36113,10 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
35426
36113
|
if (!Number.isSafeInteger(timeout) || timeout <= 0) throw new Error("Invalid admission listener timeout");
|
|
35427
36114
|
this.listenerTimeoutMs = timeout;
|
|
35428
36115
|
}
|
|
36116
|
+
/** Installs (or clears) the durable outbox used to fan notifications to other replicas. */
|
|
36117
|
+
setOutbox(outbox2) {
|
|
36118
|
+
this.outbox = outbox2;
|
|
36119
|
+
}
|
|
35429
36120
|
/**
|
|
35430
36121
|
* Registers a Project task admission listener.
|
|
35431
36122
|
*
|
|
@@ -35445,6 +36136,30 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
35445
36136
|
* @returns A promise settled after every snapshotted listener settles.
|
|
35446
36137
|
*/
|
|
35447
36138
|
async publish(event) {
|
|
36139
|
+
const snapshot = snapshotNotification2(event);
|
|
36140
|
+
const listeners = [...this.listeners];
|
|
36141
|
+
const key5 = `${snapshot.tenantId}\0${snapshot.taskId}`;
|
|
36142
|
+
const previous = this.tails.get(key5) ?? Promise.resolve();
|
|
36143
|
+
const delivery = previous.catch(() => void 0).then(() => this.deliver(snapshot, listeners));
|
|
36144
|
+
this.tails.set(key5, delivery);
|
|
36145
|
+
if (this.outbox) {
|
|
36146
|
+
try {
|
|
36147
|
+
await this.outbox.append({
|
|
36148
|
+
topic: "project-task-admission",
|
|
36149
|
+
payload: snapshot,
|
|
36150
|
+
originReplicaId: getReplicaId()
|
|
36151
|
+
});
|
|
36152
|
+
} catch {
|
|
36153
|
+
}
|
|
36154
|
+
}
|
|
36155
|
+
try {
|
|
36156
|
+
await delivery;
|
|
36157
|
+
} finally {
|
|
36158
|
+
if (this.tails.get(key5) === delivery) this.tails.delete(key5);
|
|
36159
|
+
}
|
|
36160
|
+
}
|
|
36161
|
+
/** Delivers one outbox payload to local listeners without re-appending (poller path). */
|
|
36162
|
+
async deliverFromOutbox(event) {
|
|
35448
36163
|
const snapshot = snapshotNotification2(event);
|
|
35449
36164
|
const listeners = [...this.listeners];
|
|
35450
36165
|
const key5 = `${snapshot.tenantId}\0${snapshot.taskId}`;
|
|
@@ -35514,8 +36229,137 @@ function canonicalTimestamp(value) {
|
|
|
35514
36229
|
return Number.isFinite(parsed.getTime()) && parsed.toISOString() === value;
|
|
35515
36230
|
}
|
|
35516
36231
|
|
|
36232
|
+
// src/services/OutboxPoller.ts
|
|
36233
|
+
var OutboxPoller = class {
|
|
36234
|
+
/**
|
|
36235
|
+
* Creates a poller bound to one durable outbox.
|
|
36236
|
+
*
|
|
36237
|
+
* @param deps Store, owner replica id, topic handlers, and optional tuning.
|
|
36238
|
+
*/
|
|
36239
|
+
constructor(deps) {
|
|
36240
|
+
this.deps = deps;
|
|
36241
|
+
this.cursor = null;
|
|
36242
|
+
this.polling = false;
|
|
36243
|
+
}
|
|
36244
|
+
/** Captures the starting cursor and begins polling. */
|
|
36245
|
+
async start() {
|
|
36246
|
+
this.cursor = await this.deps.store.latestId();
|
|
36247
|
+
this.timer = setInterval(() => {
|
|
36248
|
+
void this.pollOnce();
|
|
36249
|
+
}, this.deps.intervalMs ?? 1e3);
|
|
36250
|
+
this.timer.unref?.();
|
|
36251
|
+
}
|
|
36252
|
+
/** Stops polling. */
|
|
36253
|
+
stop() {
|
|
36254
|
+
if (this.timer) clearInterval(this.timer);
|
|
36255
|
+
this.timer = void 0;
|
|
36256
|
+
}
|
|
36257
|
+
/** Runs one drain pass (exported for tests). */
|
|
36258
|
+
async pollOnce() {
|
|
36259
|
+
if (this.polling) return;
|
|
36260
|
+
this.polling = true;
|
|
36261
|
+
try {
|
|
36262
|
+
const batchSize = this.deps.batchSize ?? 100;
|
|
36263
|
+
for (; ; ) {
|
|
36264
|
+
const events = await this.deps.store.listAfter(this.cursor, batchSize);
|
|
36265
|
+
if (events.length === 0) break;
|
|
36266
|
+
for (const event of events) {
|
|
36267
|
+
this.cursor = event.id;
|
|
36268
|
+
if (event.originReplicaId === this.deps.owner) continue;
|
|
36269
|
+
const handler = this.deps.handlers[event.topic];
|
|
36270
|
+
if (!handler) continue;
|
|
36271
|
+
try {
|
|
36272
|
+
await this.deliverWithTimeout(handler, event.payload);
|
|
36273
|
+
} catch {
|
|
36274
|
+
this.deps.log?.warn("Outbox delivery failed", { topic: event.topic, id: event.id });
|
|
36275
|
+
}
|
|
36276
|
+
}
|
|
36277
|
+
if (events.length < batchSize) break;
|
|
36278
|
+
}
|
|
36279
|
+
} catch (error) {
|
|
36280
|
+
this.deps.log?.warn("Outbox poll failed", { error: error instanceof Error ? error.message : String(error) });
|
|
36281
|
+
} finally {
|
|
36282
|
+
this.polling = false;
|
|
36283
|
+
}
|
|
36284
|
+
}
|
|
36285
|
+
/**
|
|
36286
|
+
* Runs one handler bounded by `handlerTimeoutMs` so a hung listener cannot
|
|
36287
|
+
* stall cross-replica delivery for this replica.
|
|
36288
|
+
*/
|
|
36289
|
+
async deliverWithTimeout(handler, payload) {
|
|
36290
|
+
const timeoutMs = this.deps.handlerTimeoutMs ?? 5e3;
|
|
36291
|
+
let timer;
|
|
36292
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
36293
|
+
timer = setTimeout(() => reject(new Error("Outbox handler timed out")), timeoutMs);
|
|
36294
|
+
timer.unref?.();
|
|
36295
|
+
});
|
|
36296
|
+
try {
|
|
36297
|
+
await Promise.race([Promise.resolve().then(() => handler(payload)), timeout]);
|
|
36298
|
+
} finally {
|
|
36299
|
+
if (timer) clearTimeout(timer);
|
|
36300
|
+
}
|
|
36301
|
+
}
|
|
36302
|
+
};
|
|
36303
|
+
|
|
35517
36304
|
// src/services/ProjectMutationMutex.ts
|
|
35518
36305
|
import { snapshotExactRecord as snapshotExactRecord4 } from "@axiom-lattice/protocols";
|
|
36306
|
+
|
|
36307
|
+
// src/services/coordinationLease.ts
|
|
36308
|
+
var configured;
|
|
36309
|
+
function configureCoordinationLeaseStore(store) {
|
|
36310
|
+
configured = store;
|
|
36311
|
+
}
|
|
36312
|
+
function getCoordinationLeaseStore() {
|
|
36313
|
+
return configured;
|
|
36314
|
+
}
|
|
36315
|
+
|
|
36316
|
+
// src/services/withLease.ts
|
|
36317
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
36318
|
+
var LeaseAcquisitionTimeoutError = class extends Error {
|
|
36319
|
+
/**
|
|
36320
|
+
* @param key Lease key that could not be acquired.
|
|
36321
|
+
* @param holder Unique holder that attempted acquisition.
|
|
36322
|
+
* @param timeoutMs How long the caller waited before giving up.
|
|
36323
|
+
*/
|
|
36324
|
+
constructor(key5, holder, timeoutMs) {
|
|
36325
|
+
super(`Could not acquire lease '${key5}' for '${holder}' within ${timeoutMs}ms`);
|
|
36326
|
+
this.key = key5;
|
|
36327
|
+
this.holder = holder;
|
|
36328
|
+
this.timeoutMs = timeoutMs;
|
|
36329
|
+
/** Stable machine-readable code. */
|
|
36330
|
+
this.code = "LEASE_ACQUISITION_TIMEOUT";
|
|
36331
|
+
this.name = "LeaseAcquisitionTimeoutError";
|
|
36332
|
+
}
|
|
36333
|
+
};
|
|
36334
|
+
function sleep(ms) {
|
|
36335
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
36336
|
+
}
|
|
36337
|
+
async function withLease(store, key5, ownerLabel, fn, options = {}) {
|
|
36338
|
+
const ttlMs = options.ttlMs ?? 3e4;
|
|
36339
|
+
const acquireTimeoutMs = options.acquireTimeoutMs ?? 1e4;
|
|
36340
|
+
const retryDelayMs = options.retryDelayMs ?? 50;
|
|
36341
|
+
const heartbeatMs = options.heartbeatMs ?? Math.max(1e3, Math.floor(ttlMs / 3));
|
|
36342
|
+
const holder = `${ownerLabel}#${randomUUID8()}`;
|
|
36343
|
+
const deadline = Date.now() + acquireTimeoutMs;
|
|
36344
|
+
for (; ; ) {
|
|
36345
|
+
if (await store.tryAcquire(key5, holder, ttlMs)) break;
|
|
36346
|
+
if (Date.now() >= deadline) throw new LeaseAcquisitionTimeoutError(key5, holder, acquireTimeoutMs);
|
|
36347
|
+
await sleep(retryDelayMs);
|
|
36348
|
+
}
|
|
36349
|
+
const heartbeat = setInterval(() => {
|
|
36350
|
+
void store.renew(key5, holder, ttlMs).catch(() => void 0);
|
|
36351
|
+
}, heartbeatMs);
|
|
36352
|
+
heartbeat.unref?.();
|
|
36353
|
+
try {
|
|
36354
|
+
return await fn();
|
|
36355
|
+
} finally {
|
|
36356
|
+
clearInterval(heartbeat);
|
|
36357
|
+
await store.release(key5, holder).catch(() => void 0);
|
|
36358
|
+
}
|
|
36359
|
+
}
|
|
36360
|
+
|
|
36361
|
+
// src/services/ProjectMutationMutex.ts
|
|
36362
|
+
var MUTATION_LEASE_OPTIONS = { ttlMs: 6e4, acquireTimeoutMs: 9e4, retryDelayMs: 100 };
|
|
35519
36363
|
function projectKey(scope) {
|
|
35520
36364
|
const row = snapshotExactRecord4(scope, ["tenantId", "projectId"]);
|
|
35521
36365
|
if (!row || typeof row.tenantId !== "string" || !row.tenantId || row.tenantId.includes("\0") || typeof row.projectId !== "string" || !row.projectId || row.projectId.includes("\0")) {
|
|
@@ -35531,9 +36375,12 @@ var ProjectMutationMutex = class {
|
|
|
35531
36375
|
/** Runs one mutation after all earlier mutations for the same Tenant and Project. */
|
|
35532
36376
|
async runExclusive(scope, operation, signal) {
|
|
35533
36377
|
const key5 = projectKey(scope);
|
|
36378
|
+
const leaseKey = `project-mutation:${encodeURIComponent(scope.tenantId)}:${encodeURIComponent(scope.projectId)}`;
|
|
35534
36379
|
await this.acquire(key5, signal);
|
|
35535
36380
|
try {
|
|
35536
|
-
|
|
36381
|
+
const store = getCoordinationLeaseStore();
|
|
36382
|
+
if (!store) return await operation();
|
|
36383
|
+
return await withLease(store, leaseKey, getReplicaId(), operation, MUTATION_LEASE_OPTIONS);
|
|
35537
36384
|
} finally {
|
|
35538
36385
|
this.release(key5);
|
|
35539
36386
|
}
|
|
@@ -35591,7 +36438,7 @@ function createTrustedAgentMessageDispatcher(resolve4) {
|
|
|
35591
36438
|
}
|
|
35592
36439
|
|
|
35593
36440
|
// src/services/RoomAgentMessageService.ts
|
|
35594
|
-
import { randomUUID as
|
|
36441
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
35595
36442
|
import { snapshotExactArray, snapshotExactRecord as snapshotExactRecord5 } from "@axiom-lattice/protocols";
|
|
35596
36443
|
var INPUT_KEYS = [
|
|
35597
36444
|
"tenantId",
|
|
@@ -35679,7 +36526,7 @@ var RoomAgentMessageService = class {
|
|
|
35679
36526
|
throw new Error("Invalid project room membership");
|
|
35680
36527
|
}
|
|
35681
36528
|
const candidate = {
|
|
35682
|
-
id: (this.deps.idFactory ??
|
|
36529
|
+
id: (this.deps.idFactory ?? randomUUID9)(),
|
|
35683
36530
|
tenantId: input.tenantId,
|
|
35684
36531
|
workspaceId: input.workspaceId,
|
|
35685
36532
|
projectId: input.projectId,
|
|
@@ -36040,9 +36887,9 @@ var BELIEF_OWNER_WRITE_ATTEMPTS = 3;
|
|
|
36040
36887
|
function isWellFormedImpact(impact) {
|
|
36041
36888
|
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
36889
|
}
|
|
36043
|
-
async function applyBeliefImpacts(taskStore,
|
|
36044
|
-
if (impacts.length === 0) return { description:
|
|
36045
|
-
let current =
|
|
36890
|
+
async function applyBeliefImpacts(taskStore, owner2, impacts) {
|
|
36891
|
+
if (impacts.length === 0) return { description: owner2.description ?? "" };
|
|
36892
|
+
let current = owner2;
|
|
36046
36893
|
for (let attempt = 0; attempt < BELIEF_OWNER_WRITE_ATTEMPTS; attempt += 1) {
|
|
36047
36894
|
const parsed = parseTaskBeliefState(current.description ?? "");
|
|
36048
36895
|
const existingTable = parsed.success;
|
|
@@ -36171,14 +37018,14 @@ function sameBeliefOwner(left, right) {
|
|
|
36171
37018
|
function sameBeliefOwnerIdentity(left, right) {
|
|
36172
37019
|
return canonicalJson({ ...left, beliefState: void 0 }) === canonicalJson({ ...right, beliefState: void 0 });
|
|
36173
37020
|
}
|
|
36174
|
-
function canonicalBeliefOwner(
|
|
37021
|
+
function canonicalBeliefOwner(owner2) {
|
|
36175
37022
|
const beliefState = {
|
|
36176
|
-
entries:
|
|
37023
|
+
entries: owner2.beliefState.entries.map((entry) => ({
|
|
36177
37024
|
...entry,
|
|
36178
37025
|
basis: entry.basis.trim().replace(/\s+/g, " ")
|
|
36179
37026
|
})).sort((left, right) => left.key < right.key ? -1 : left.key > right.key ? 1 : 0)
|
|
36180
37027
|
};
|
|
36181
|
-
return { ...
|
|
37028
|
+
return { ...owner2, beliefState };
|
|
36182
37029
|
}
|
|
36183
37030
|
function eventKeyFor(taskId, result, impacts, beliefOwner) {
|
|
36184
37031
|
const base = `belief-impact:${taskId}:${buildBeliefCompletionEventKey(taskId, result, impacts)}`;
|
|
@@ -37545,8 +38392,8 @@ var TaskLifecycleService = class {
|
|
|
37545
38392
|
return { task: existing, parent: parentResult, eventKey, evidence, result, impacts };
|
|
37546
38393
|
}
|
|
37547
38394
|
beliefOwnerSnapshot(task, parent) {
|
|
37548
|
-
const
|
|
37549
|
-
const parsed = parseTaskBeliefState(
|
|
38395
|
+
const owner2 = parent?.ownerType === "agent" ? parent : task;
|
|
38396
|
+
const parsed = parseTaskBeliefState(owner2.description ?? "");
|
|
37550
38397
|
const beliefState = parsed.success ? parsed.state : { entries: [] };
|
|
37551
38398
|
if (parent?.ownerType === "agent") {
|
|
37552
38399
|
return {
|
|
@@ -38266,7 +39113,7 @@ function createTaskLifecycleService(deps) {
|
|
|
38266
39113
|
}
|
|
38267
39114
|
|
|
38268
39115
|
// src/services/TaskExecutionService.ts
|
|
38269
|
-
import { randomUUID as
|
|
39116
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
38270
39117
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
|
|
38271
39118
|
import { isExecutionResultEventKey as isExecutionResultEventKey2 } from "@axiom-lattice/protocols";
|
|
38272
39119
|
|
|
@@ -38525,12 +39372,20 @@ var TaskRunRegistry = class {
|
|
|
38525
39372
|
}
|
|
38526
39373
|
};
|
|
38527
39374
|
var taskRunRegistry = new TaskRunRegistry();
|
|
39375
|
+
async function safelyLive(probe, task) {
|
|
39376
|
+
try {
|
|
39377
|
+
return await probe(task);
|
|
39378
|
+
} catch {
|
|
39379
|
+
return true;
|
|
39380
|
+
}
|
|
39381
|
+
}
|
|
38528
39382
|
async function reconcileStaleTaskRuns(input) {
|
|
38529
39383
|
const registry4 = input.registry ?? taskRunRegistry;
|
|
38530
39384
|
const converged = [];
|
|
38531
39385
|
const convergedTasks = [];
|
|
38532
39386
|
for (const task of input.tasks) {
|
|
38533
39387
|
if (task.status !== "in_progress" || registry4.isLive(task.id)) continue;
|
|
39388
|
+
if (input.isTaskLive && await safelyLive(input.isTaskLive, task)) continue;
|
|
38534
39389
|
const result = await input.lifecycle.failTask({
|
|
38535
39390
|
tenantId: task.tenantId,
|
|
38536
39391
|
taskId: task.id,
|
|
@@ -38551,7 +39406,8 @@ async function reconcileTenantTaskRuns(input) {
|
|
|
38551
39406
|
tasks: candidates,
|
|
38552
39407
|
actor: input.actor,
|
|
38553
39408
|
lifecycle: input.lifecycle,
|
|
38554
|
-
...input.registry ? { registry: input.registry } : {}
|
|
39409
|
+
...input.registry ? { registry: input.registry } : {},
|
|
39410
|
+
...input.isTaskLive ? { isTaskLive: input.isTaskLive } : {}
|
|
38555
39411
|
});
|
|
38556
39412
|
}
|
|
38557
39413
|
async function reconcileAllTenantTaskRuns(input) {
|
|
@@ -38567,7 +39423,8 @@ async function reconcileAllTenantTaskRuns(input) {
|
|
|
38567
39423
|
taskStore: input.taskStore,
|
|
38568
39424
|
lifecycle: input.lifecycle,
|
|
38569
39425
|
...input.registry ? { registry: input.registry } : {},
|
|
38570
|
-
...input.include ? { include: input.include } : {}
|
|
39426
|
+
...input.include ? { include: input.include } : {},
|
|
39427
|
+
...input.isTaskLive ? { isTaskLive: input.isTaskLive } : {}
|
|
38571
39428
|
});
|
|
38572
39429
|
} catch {
|
|
38573
39430
|
continue;
|
|
@@ -38578,6 +39435,42 @@ async function reconcileAllTenantTaskRuns(input) {
|
|
|
38578
39435
|
return { converged, convergedTasks };
|
|
38579
39436
|
}
|
|
38580
39437
|
|
|
39438
|
+
// src/services/taskRunLease.ts
|
|
39439
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
39440
|
+
function taskRunLeaseKey(taskId) {
|
|
39441
|
+
return `task-run:${taskId}`;
|
|
39442
|
+
}
|
|
39443
|
+
async function tryAcquireTaskRun(input) {
|
|
39444
|
+
const key5 = taskRunLeaseKey(input.taskId);
|
|
39445
|
+
const holder = `${input.owner}#${randomUUID10()}`;
|
|
39446
|
+
if (!await input.store.tryAcquire(key5, holder, input.ttlMs)) return null;
|
|
39447
|
+
const heartbeatMs = input.heartbeatMs ?? Math.max(1e3, Math.floor(input.ttlMs / 3));
|
|
39448
|
+
let released = false;
|
|
39449
|
+
let lost = false;
|
|
39450
|
+
const heartbeat = setInterval(() => {
|
|
39451
|
+
void input.store.renew(key5, holder, input.ttlMs).then((renewed) => {
|
|
39452
|
+
if (released || renewed || lost) return;
|
|
39453
|
+
lost = true;
|
|
39454
|
+
try {
|
|
39455
|
+
input.onLost?.();
|
|
39456
|
+
} catch {
|
|
39457
|
+
}
|
|
39458
|
+
}).catch(() => void 0);
|
|
39459
|
+
}, heartbeatMs);
|
|
39460
|
+
heartbeat.unref?.();
|
|
39461
|
+
return {
|
|
39462
|
+
get lost() {
|
|
39463
|
+
return lost;
|
|
39464
|
+
},
|
|
39465
|
+
release: async () => {
|
|
39466
|
+
if (released) return;
|
|
39467
|
+
released = true;
|
|
39468
|
+
clearInterval(heartbeat);
|
|
39469
|
+
await input.store.release(key5, holder).catch(() => void 0);
|
|
39470
|
+
}
|
|
39471
|
+
};
|
|
39472
|
+
}
|
|
39473
|
+
|
|
38581
39474
|
// src/services/ExecutionAuthorityRegistry.ts
|
|
38582
39475
|
var ManagedTaskStartError = class extends Error {
|
|
38583
39476
|
/**
|
|
@@ -38848,6 +39741,14 @@ async function prepareTaskDispatch(deps, input) {
|
|
|
38848
39741
|
|
|
38849
39742
|
// src/services/TaskExecutionService.ts
|
|
38850
39743
|
import { GraphInterrupt as GraphInterrupt2 } from "@langchain/langgraph";
|
|
39744
|
+
var TASK_RUN_LEASE_TTL_MS = 12e4;
|
|
39745
|
+
function getLeaseStore() {
|
|
39746
|
+
try {
|
|
39747
|
+
return storeLatticeManager.getStoreLattice("default", "lease").store;
|
|
39748
|
+
} catch {
|
|
39749
|
+
return void 0;
|
|
39750
|
+
}
|
|
39751
|
+
}
|
|
38851
39752
|
function persistedExecutionObservation(item, attempted) {
|
|
38852
39753
|
const detail = item.detail;
|
|
38853
39754
|
const persistedObservation = toJsonSafeValue(detail?.observation);
|
|
@@ -38908,11 +39809,11 @@ function createTaskExecutionService(deps) {
|
|
|
38908
39809
|
let threadId;
|
|
38909
39810
|
let runId;
|
|
38910
39811
|
try {
|
|
38911
|
-
threadId = storedThreadId ?? (deps.createThreadId ??
|
|
39812
|
+
threadId = storedThreadId ?? (deps.createThreadId ?? randomUUID11)();
|
|
38912
39813
|
if (task.status === "interrupted" && reuseCurrentRun) {
|
|
38913
39814
|
runId = storedRunId;
|
|
38914
39815
|
} else if (task.status === "interrupted" || task.status === "failed") {
|
|
38915
|
-
runId = (deps.createRunId ??
|
|
39816
|
+
runId = (deps.createRunId ?? randomUUID11)();
|
|
38916
39817
|
}
|
|
38917
39818
|
} catch (error) {
|
|
38918
39819
|
return {
|
|
@@ -38975,7 +39876,21 @@ function createTaskExecutionService(deps) {
|
|
|
38975
39876
|
warnings.push(...begun.warnings);
|
|
38976
39877
|
}
|
|
38977
39878
|
taskRunRegistry.register(task.id);
|
|
39879
|
+
let taskRunLease = null;
|
|
38978
39880
|
try {
|
|
39881
|
+
const leaseStore = getLeaseStore();
|
|
39882
|
+
if (leaseStore) {
|
|
39883
|
+
try {
|
|
39884
|
+
taskRunLease = await tryAcquireTaskRun({
|
|
39885
|
+
store: leaseStore,
|
|
39886
|
+
taskId: task.id,
|
|
39887
|
+
owner: getReplicaId(),
|
|
39888
|
+
ttlMs: TASK_RUN_LEASE_TTL_MS
|
|
39889
|
+
});
|
|
39890
|
+
} catch {
|
|
39891
|
+
taskRunLease = null;
|
|
39892
|
+
}
|
|
39893
|
+
}
|
|
38979
39894
|
const invocation = {
|
|
38980
39895
|
tenantId: tenantId2,
|
|
38981
39896
|
workspaceId: task.workspaceId,
|
|
@@ -39143,6 +40058,7 @@ function createTaskExecutionService(deps) {
|
|
|
39143
40058
|
}
|
|
39144
40059
|
} finally {
|
|
39145
40060
|
taskRunRegistry.unregister(task.id);
|
|
40061
|
+
if (taskRunLease) await taskRunLease.release();
|
|
39146
40062
|
}
|
|
39147
40063
|
};
|
|
39148
40064
|
return {
|
|
@@ -39155,6 +40071,43 @@ function createTaskExecutionService(deps) {
|
|
|
39155
40071
|
};
|
|
39156
40072
|
}
|
|
39157
40073
|
|
|
40074
|
+
// src/services/leadership.ts
|
|
40075
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
40076
|
+
async function runAsLeader(store, name, fn, options = {}) {
|
|
40077
|
+
const key5 = `leader:${name}`;
|
|
40078
|
+
const owner2 = options.owner ?? getReplicaId();
|
|
40079
|
+
const holder = `${owner2}#${randomUUID12()}`;
|
|
40080
|
+
const ttlMs = options.ttlMs ?? 6e4;
|
|
40081
|
+
if (!await store.tryAcquire(key5, holder, ttlMs)) return { ran: false };
|
|
40082
|
+
const heartbeat = setInterval(() => {
|
|
40083
|
+
void store.renew(key5, holder, ttlMs).catch(() => void 0);
|
|
40084
|
+
}, Math.max(1e3, Math.floor(ttlMs / 3)));
|
|
40085
|
+
heartbeat.unref?.();
|
|
40086
|
+
try {
|
|
40087
|
+
const result = await fn();
|
|
40088
|
+
return { ran: true, result };
|
|
40089
|
+
} finally {
|
|
40090
|
+
clearInterval(heartbeat);
|
|
40091
|
+
if (!options.hold) await store.release(key5, holder).catch(() => void 0);
|
|
40092
|
+
}
|
|
40093
|
+
}
|
|
40094
|
+
|
|
40095
|
+
// src/services/pluginCatalogSync.ts
|
|
40096
|
+
var PLUGIN_CATALOG_CHANGED_TOPIC = "plugin-catalog-changed";
|
|
40097
|
+
var outbox;
|
|
40098
|
+
var owner = "unknown";
|
|
40099
|
+
function configurePluginCatalogSync(next) {
|
|
40100
|
+
outbox = next?.outbox;
|
|
40101
|
+
owner = next?.owner ?? "unknown";
|
|
40102
|
+
}
|
|
40103
|
+
async function publishPluginCatalogChanged(tenantId2) {
|
|
40104
|
+
if (!outbox || !tenantId2) return;
|
|
40105
|
+
try {
|
|
40106
|
+
await outbox.append({ topic: PLUGIN_CATALOG_CHANGED_TOPIC, payload: { tenantId: tenantId2 }, originReplicaId: owner });
|
|
40107
|
+
} catch {
|
|
40108
|
+
}
|
|
40109
|
+
}
|
|
40110
|
+
|
|
39158
40111
|
// src/index.ts
|
|
39159
40112
|
import * as Protocols from "@axiom-lattice/protocols";
|
|
39160
40113
|
|
|
@@ -39297,9 +40250,9 @@ var createLoadSkillsTool = ({ skills, readAll, pluginSkills, pluginSkillOwners }
|
|
|
39297
40250
|
if (!skillName) continue;
|
|
39298
40251
|
if (await isPluginSkillManagedInSandbox(sandbox, skillName)) {
|
|
39299
40252
|
const enabledDefinition = pluginSkills?.[skillName];
|
|
39300
|
-
const
|
|
39301
|
-
const registered =
|
|
39302
|
-
if (!registered || registered.definition !== enabledDefinition || !
|
|
40253
|
+
const owner2 = pluginSkillOwners?.[skillName];
|
|
40254
|
+
const registered = owner2 && enabledDefinition ? PluginRegistry.getSkillForPlugin(owner2, skillName) : void 0;
|
|
40255
|
+
if (!registered || registered.definition !== enabledDefinition || !owner2 || !await isPluginSkillAuthorizedInSandbox(sandbox, skillName, owner2) || await getPluginSkillManifestVersion(sandbox, skillName) !== enabledDefinition.version) {
|
|
39303
40256
|
continue;
|
|
39304
40257
|
}
|
|
39305
40258
|
}
|
|
@@ -39325,8 +40278,8 @@ var createLoadSkillsTool = ({ skills, readAll, pluginSkills, pluginSkillOwners }
|
|
|
39325
40278
|
const seenNames = new Set(filteredSkills.map((skill) => skill.name));
|
|
39326
40279
|
try {
|
|
39327
40280
|
for (const [name, definition] of Object.entries(pluginSkills ?? {})) {
|
|
39328
|
-
const
|
|
39329
|
-
const registered =
|
|
40281
|
+
const owner2 = pluginSkillOwners?.[name];
|
|
40282
|
+
const registered = owner2 ? PluginRegistry.getSkillForPlugin(owner2, name) : void 0;
|
|
39330
40283
|
if (!registered || registered.definition !== definition) continue;
|
|
39331
40284
|
const { meta } = parseSkillFrontmatter(definition.content);
|
|
39332
40285
|
if (!meta.name || !meta.description || seenNames.has(meta.name)) continue;
|
|
@@ -39363,24 +40316,24 @@ import z54 from "zod";
|
|
|
39363
40316
|
import { tool as tool48 } from "langchain";
|
|
39364
40317
|
|
|
39365
40318
|
// src/sandbox_plugin/pluginSkillResolution.ts
|
|
39366
|
-
async function resolveTenantPluginSkill(tenantId2,
|
|
40319
|
+
async function resolveTenantPluginSkill(tenantId2, owner2, skillName) {
|
|
39367
40320
|
try {
|
|
39368
40321
|
const { plugins } = await getSandboxPluginCatalog().ensureLoaded(tenantId2);
|
|
39369
|
-
const plugin = plugins.find((candidate) => candidate.meta.type ===
|
|
40322
|
+
const plugin = plugins.find((candidate) => candidate.meta.type === owner2);
|
|
39370
40323
|
return plugin?.skills?.[skillName];
|
|
39371
40324
|
} catch {
|
|
39372
40325
|
return void 0;
|
|
39373
40326
|
}
|
|
39374
40327
|
}
|
|
39375
|
-
async function resolveEnabledPluginSkill(
|
|
39376
|
-
if (!
|
|
39377
|
-
const registered = PluginRegistry.getSkillForPlugin(
|
|
39378
|
-
if (registered && registered.pluginType ===
|
|
39379
|
-
return { pluginType:
|
|
40328
|
+
async function resolveEnabledPluginSkill(owner2, skillName, enabledDefinition, tenantId2) {
|
|
40329
|
+
if (!owner2 || !enabledDefinition) return void 0;
|
|
40330
|
+
const registered = PluginRegistry.getSkillForPlugin(owner2, skillName);
|
|
40331
|
+
if (registered && registered.pluginType === owner2 && registered.definition === enabledDefinition) {
|
|
40332
|
+
return { pluginType: owner2, definition: enabledDefinition };
|
|
39380
40333
|
}
|
|
39381
40334
|
if (!tenantId2) return void 0;
|
|
39382
|
-
const tenantDefinition = await resolveTenantPluginSkill(tenantId2,
|
|
39383
|
-
return tenantDefinition ? { pluginType:
|
|
40335
|
+
const tenantDefinition = await resolveTenantPluginSkill(tenantId2, owner2, skillName);
|
|
40336
|
+
return tenantDefinition ? { pluginType: owner2, definition: tenantDefinition } : void 0;
|
|
39384
40337
|
}
|
|
39385
40338
|
|
|
39386
40339
|
// src/tool_lattice/skill/load_skill_content.ts
|
|
@@ -39442,10 +40395,10 @@ var createLoadSkillContentTool = (pluginSkills, pluginSkillOwnersOrStaticSelecti
|
|
|
39442
40395
|
return result2;
|
|
39443
40396
|
}
|
|
39444
40397
|
const enabledDefinition = pluginSkills?.[input.skill_name];
|
|
39445
|
-
const
|
|
40398
|
+
const owner2 = pluginSkillOwners?.[input.skill_name];
|
|
39446
40399
|
const runConfig = _exe_config?.configurable?.runConfig || {};
|
|
39447
40400
|
const pluginSkill = await resolveEnabledPluginSkill(
|
|
39448
|
-
|
|
40401
|
+
owner2,
|
|
39449
40402
|
input.skill_name,
|
|
39450
40403
|
enabledDefinition,
|
|
39451
40404
|
runConfig.tenantId
|
|
@@ -39552,9 +40505,9 @@ var createLoadSkillResourceTool = (pluginSkills, pluginSkillOwners) => {
|
|
|
39552
40505
|
validateRelativePath(input.resource_path, "resource");
|
|
39553
40506
|
const sandbox = await getSandboxFromExeConfig3(_exe_config);
|
|
39554
40507
|
const definition = pluginSkills?.[input.skill_name];
|
|
39555
|
-
const
|
|
40508
|
+
const owner2 = pluginSkillOwners?.[input.skill_name];
|
|
39556
40509
|
const tenantId2 = _exe_config?.configurable?.runConfig?.tenantId;
|
|
39557
|
-
const resolved = await resolveEnabledPluginSkill(
|
|
40510
|
+
const resolved = await resolveEnabledPluginSkill(owner2, input.skill_name, definition, tenantId2);
|
|
39558
40511
|
if (definition) {
|
|
39559
40512
|
if (!resolved || !resolved.definition.resources?.[input.resource_path]) {
|
|
39560
40513
|
return `Resource "${input.resource_path}" not found for skill "${input.skill_name}".`;
|
|
@@ -41786,9 +42739,9 @@ async function renderAvailableExecutors(rc, tenantId2) {
|
|
|
41786
42739
|
const governed = authority.kind === "projectRoom" || authority.kind === "projectTask";
|
|
41787
42740
|
const projectId = governed ? (authority.trusted.projectTask ?? authority.trusted.projectRoom)?.projectId : void 0;
|
|
41788
42741
|
const cacheKey = `${tenantId2}:${governed ? `project:${projectId ?? ""}` : "ordinary"}`;
|
|
41789
|
-
const
|
|
42742
|
+
const cached2 = executorCache.get(cacheKey);
|
|
41790
42743
|
const now = Date.now();
|
|
41791
|
-
if (
|
|
42744
|
+
if (cached2 && now - cached2.at < EXECUTOR_CACHE_TTL_MS) return cached2.text;
|
|
41792
42745
|
const lines = [];
|
|
41793
42746
|
try {
|
|
41794
42747
|
if (governed && projectId) {
|
|
@@ -46074,6 +47027,7 @@ var sandboxPluginsPlugin = {
|
|
|
46074
47027
|
}
|
|
46075
47028
|
case "reload": {
|
|
46076
47029
|
const loaded = await catalog2.reload(tenantId2);
|
|
47030
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
46077
47031
|
return JSON.stringify({ reloaded: true, plugins: loaded.plugins.length, diagnostics: loaded.diagnostics });
|
|
46078
47032
|
}
|
|
46079
47033
|
case "create":
|
|
@@ -46093,12 +47047,14 @@ var sandboxPluginsPlugin = {
|
|
|
46093
47047
|
if (!check.manifest) return JSON.stringify({ written: false, diagnostics: check.diagnostics });
|
|
46094
47048
|
await catalog2.writePlugin(tenantId2, input.type, input.manifest, handlers);
|
|
46095
47049
|
const loaded = await catalog2.reload(tenantId2);
|
|
47050
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
46096
47051
|
return JSON.stringify({ written: true, diagnostics: loaded.diagnostics, hash: loaded.hash });
|
|
46097
47052
|
}
|
|
46098
47053
|
case "delete": {
|
|
46099
47054
|
if (!input.type) return "type is required";
|
|
46100
47055
|
await catalog2.deletePlugin(tenantId2, input.type);
|
|
46101
47056
|
await catalog2.reload(tenantId2);
|
|
47057
|
+
void publishPluginCatalogChanged(tenantId2);
|
|
46102
47058
|
return JSON.stringify({ deleted: true });
|
|
46103
47059
|
}
|
|
46104
47060
|
case "validate": {
|
|
@@ -46210,6 +47166,26 @@ function registerBuiltinPlugins() {
|
|
|
46210
47166
|
}
|
|
46211
47167
|
}
|
|
46212
47168
|
|
|
47169
|
+
// src/sandbox_plugin/provisionOpenClient.ts
|
|
47170
|
+
import { readFileSync } from "fs";
|
|
47171
|
+
var SDK_ROOT = "/root/.agents/sdk";
|
|
47172
|
+
var CLIENT_DIR = `${SDK_ROOT}/open-mcp-client`;
|
|
47173
|
+
var MANIFEST_PATH2 = `${SDK_ROOT}/.open-client-manifest.json`;
|
|
47174
|
+
async function provisionSandboxOpenClient(sandbox, bundle) {
|
|
47175
|
+
await sandbox.file.createDirectory(SDK_ROOT);
|
|
47176
|
+
await sandbox.file.createDirectory(CLIENT_DIR);
|
|
47177
|
+
await sandbox.file.writeFile(`${CLIENT_DIR}/index.js`, bundle.indexJs);
|
|
47178
|
+
await sandbox.file.writeFile(`${CLIENT_DIR}/cli.js`, bundle.cliJs);
|
|
47179
|
+
await sandbox.file.writeFile(MANIFEST_PATH2, JSON.stringify({ version: bundle.version }));
|
|
47180
|
+
}
|
|
47181
|
+
function buildBundleFromDist(distDir, version) {
|
|
47182
|
+
return {
|
|
47183
|
+
indexJs: readFileSync(`${distDir}/index.js`, "utf8"),
|
|
47184
|
+
cliJs: readFileSync(`${distDir}/cli.js`, "utf8"),
|
|
47185
|
+
version
|
|
47186
|
+
};
|
|
47187
|
+
}
|
|
47188
|
+
|
|
46213
47189
|
// src/personal_assistant/PersonalAssistantConfig.ts
|
|
46214
47190
|
function deepClone(obj) {
|
|
46215
47191
|
return JSON.parse(JSON.stringify(obj));
|
|
@@ -46671,10 +47647,12 @@ export {
|
|
|
46671
47647
|
InMemoryChunkBuffer,
|
|
46672
47648
|
InMemoryCollectionStore,
|
|
46673
47649
|
InMemoryDatabaseConfigStore,
|
|
47650
|
+
InMemoryLeaseStore,
|
|
46674
47651
|
InMemoryMailboxStore,
|
|
46675
47652
|
InMemoryMenuStore,
|
|
46676
47653
|
InMemoryModelProviderStore,
|
|
46677
47654
|
InMemoryOpenAuditStore,
|
|
47655
|
+
InMemoryOutboxStore,
|
|
46678
47656
|
InMemoryProjectBotMembershipStore,
|
|
46679
47657
|
InMemoryProjectMembershipStore,
|
|
46680
47658
|
InMemoryProjectRoomCoordinator,
|
|
@@ -46694,6 +47672,7 @@ export {
|
|
|
46694
47672
|
LatticeEval,
|
|
46695
47673
|
LatticeEvalProject,
|
|
46696
47674
|
LatticeEvalSuite,
|
|
47675
|
+
LeaseAcquisitionTimeoutError,
|
|
46697
47676
|
LocalSandboxInstance,
|
|
46698
47677
|
LocalSandboxProvider,
|
|
46699
47678
|
LoggerLatticeManager,
|
|
@@ -46716,7 +47695,10 @@ export {
|
|
|
46716
47695
|
MicrosandboxServiceClient,
|
|
46717
47696
|
ModelLatticeManager,
|
|
46718
47697
|
MysqlDatabase,
|
|
47698
|
+
OutboxPoller,
|
|
46719
47699
|
PACK_DIRECTORY_TIMEOUT_SECONDS,
|
|
47700
|
+
PLATFORM_SECRET_ENV_VARS,
|
|
47701
|
+
PLUGIN_CATALOG_CHANGED_TOPIC,
|
|
46720
47702
|
PersonalAssistantConfig,
|
|
46721
47703
|
PinoLoggerClient,
|
|
46722
47704
|
PluginRegistry,
|
|
@@ -46737,6 +47719,8 @@ export {
|
|
|
46737
47719
|
RepeatedToolCallError,
|
|
46738
47720
|
RoomAgentMessageService,
|
|
46739
47721
|
SAFE_PATH_COMPONENT,
|
|
47722
|
+
SANDBOX_OPEN_GATEWAY_URL_ENV,
|
|
47723
|
+
SANDBOX_OPEN_TOKEN_ENV,
|
|
46740
47724
|
STTModelLattice,
|
|
46741
47725
|
STTModelLatticeManager,
|
|
46742
47726
|
SandboxFilesystem,
|
|
@@ -46777,11 +47761,13 @@ export {
|
|
|
46777
47761
|
appendReconciliationWarning,
|
|
46778
47762
|
appendUiFence,
|
|
46779
47763
|
assertSafeUpstreamUrl,
|
|
47764
|
+
buildBundleFromDist,
|
|
46780
47765
|
buildGrepResultsDict,
|
|
46781
47766
|
buildInput,
|
|
46782
47767
|
buildNamedVolumeName,
|
|
46783
47768
|
buildRemotePackDirectoryCommand,
|
|
46784
47769
|
buildSandboxMetadataEnv,
|
|
47770
|
+
buildSandboxOpenEnv,
|
|
46785
47771
|
buildSkillFile,
|
|
46786
47772
|
buildStateAnnotation,
|
|
46787
47773
|
buildTableName,
|
|
@@ -46790,11 +47776,14 @@ export {
|
|
|
46790
47776
|
checkEmptyContent,
|
|
46791
47777
|
clearEncryptionKeyCache,
|
|
46792
47778
|
clearEvalRunService,
|
|
47779
|
+
clearSandboxOpenCredentialProviderForTests,
|
|
46793
47780
|
collectionLatticeManager,
|
|
46794
47781
|
compileInternal,
|
|
46795
47782
|
compileSandboxPlugin,
|
|
46796
47783
|
compileWorkflow,
|
|
46797
47784
|
computeSandboxName,
|
|
47785
|
+
configureCoordinationLeaseStore,
|
|
47786
|
+
configurePluginCatalogSync,
|
|
46798
47787
|
configureStores,
|
|
46799
47788
|
connectAllChannels,
|
|
46800
47789
|
convertToConnection,
|
|
@@ -46826,6 +47815,7 @@ export {
|
|
|
46826
47815
|
createSandboxResolver,
|
|
46827
47816
|
createSchedulerMiddleware,
|
|
46828
47817
|
createSharePayload,
|
|
47818
|
+
createShellExecTool,
|
|
46829
47819
|
createTaskExecutionService,
|
|
46830
47820
|
createTaskLifecycleService,
|
|
46831
47821
|
createTaskMiddleware,
|
|
@@ -46872,6 +47862,7 @@ export {
|
|
|
46872
47862
|
getCheckpointSaver,
|
|
46873
47863
|
getChunkBuffer,
|
|
46874
47864
|
getCollectionEntryCount,
|
|
47865
|
+
getCoordinationLeaseStore,
|
|
46875
47866
|
getEmbeddingsClient,
|
|
46876
47867
|
getEmbeddingsLattice,
|
|
46877
47868
|
getEncryptionKey,
|
|
@@ -46883,15 +47874,18 @@ export {
|
|
|
46883
47874
|
getOrCreateCollectionVectorStore,
|
|
46884
47875
|
getPluginSkillManifestVersion,
|
|
46885
47876
|
getQueueLattice,
|
|
47877
|
+
getReplicaId,
|
|
46886
47878
|
getRuntimeCapabilityConfig,
|
|
46887
47879
|
getRuntimeSkillSelection,
|
|
46888
47880
|
getSTTClient,
|
|
46889
47881
|
getSTTClientWithTenant,
|
|
46890
47882
|
getSTTModelLattice,
|
|
46891
47883
|
getSandBoxManager,
|
|
47884
|
+
getSandboxOpenCredential,
|
|
46892
47885
|
getSandboxPluginCatalog,
|
|
46893
47886
|
getScheduleLattice,
|
|
46894
47887
|
getStoreLattice,
|
|
47888
|
+
getThreadRunOwner,
|
|
46895
47889
|
getToolClient,
|
|
46896
47890
|
getToolClientWithTenant,
|
|
46897
47891
|
getToolDefinition,
|
|
@@ -46945,6 +47939,8 @@ export {
|
|
|
46945
47939
|
projectMutationMutex,
|
|
46946
47940
|
projectRoomPlugin,
|
|
46947
47941
|
projectTaskAdmissionNotifier,
|
|
47942
|
+
provisionSandboxOpenClient,
|
|
47943
|
+
publishPluginCatalogChanged,
|
|
46948
47944
|
queueLatticeManager,
|
|
46949
47945
|
readLoopBreakerConfig,
|
|
46950
47946
|
reconcileAllTenantTaskRuns,
|
|
@@ -46963,6 +47959,7 @@ export {
|
|
|
46963
47959
|
registerModelLatticeForTenant,
|
|
46964
47960
|
registerQueueLattice,
|
|
46965
47961
|
registerSTTModelLattice,
|
|
47962
|
+
registerSandboxOpenCredentialProvider,
|
|
46966
47963
|
registerSandboxProviderType,
|
|
46967
47964
|
registerScheduleLattice,
|
|
46968
47965
|
registerStoreLattice,
|
|
@@ -46973,6 +47970,7 @@ export {
|
|
|
46973
47970
|
registerWorkflowRun,
|
|
46974
47971
|
removeCollectionVectorStore,
|
|
46975
47972
|
renderTemplate,
|
|
47973
|
+
resetReplicaIdForTests,
|
|
46976
47974
|
resolveEnabledPluginSkill,
|
|
46977
47975
|
resolveJudgeModelKey,
|
|
46978
47976
|
resolvePath,
|
|
@@ -46980,6 +47978,7 @@ export {
|
|
|
46980
47978
|
resolveSandboxPluginConnections,
|
|
46981
47979
|
resolveTenantPluginSkill,
|
|
46982
47980
|
roomCoordinatorConfig,
|
|
47981
|
+
runAsLeader,
|
|
46983
47982
|
runRemotePackDirectory,
|
|
46984
47983
|
safeTaskResponseId,
|
|
46985
47984
|
sandboxLatticeManager,
|
|
@@ -46998,11 +47997,15 @@ export {
|
|
|
46998
47997
|
storeLatticeManager,
|
|
46999
47998
|
sttModelLatticeManager,
|
|
47000
47999
|
taskLifecycleNotifier,
|
|
48000
|
+
taskRunLeaseKey,
|
|
47001
48001
|
taskRunRegistry,
|
|
48002
|
+
threadRunLeaseKey,
|
|
47002
48003
|
toJsonSchema,
|
|
47003
48004
|
toSafeStateExpr,
|
|
47004
48005
|
toolLatticeManager,
|
|
47005
48006
|
truncateIfTooLong,
|
|
48007
|
+
tryAcquireTaskRun,
|
|
48008
|
+
tryAcquireThreadRun,
|
|
47006
48009
|
unregisterTeammateAgent,
|
|
47007
48010
|
unregisterWorkflowRun,
|
|
47008
48011
|
updateFileData,
|
|
@@ -47018,6 +48021,7 @@ export {
|
|
|
47018
48021
|
validateToolInput,
|
|
47019
48022
|
vectorStoreLatticeManager,
|
|
47020
48023
|
vectorStoreProviderManager,
|
|
48024
|
+
withLease,
|
|
47021
48025
|
withTimeout,
|
|
47022
48026
|
wrapMcpToolWithUi
|
|
47023
48027
|
};
|