@forgeax/engine-tool-runtime 0.1.29 → 0.1.30
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/api.d.ts +72 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +849 -472
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.ts +35 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -233,494 +233,186 @@ function validateArtifactRefs(value) {
|
|
|
233
233
|
);
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
// src/
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
236
|
+
// src/lease.ts
|
|
237
|
+
function createLexicalLease(runId) {
|
|
238
|
+
const cleanups = [];
|
|
239
|
+
let state = "active";
|
|
240
|
+
let terminalId;
|
|
241
|
+
let termination;
|
|
242
|
+
const terminate = (reason) => {
|
|
243
|
+
if (termination !== void 0) return termination;
|
|
244
|
+
terminalId = `${runId}:terminal:${crypto.randomUUID()}`;
|
|
245
|
+
state = "terminating";
|
|
246
|
+
termination = (async () => {
|
|
247
|
+
const failures = [];
|
|
248
|
+
for (let index = cleanups.length - 1; index >= 0; index -= 1) {
|
|
249
|
+
const entry = cleanups[index];
|
|
250
|
+
if (entry === void 0) continue;
|
|
251
|
+
try {
|
|
252
|
+
await entry.cleanup();
|
|
253
|
+
} catch (cause) {
|
|
254
|
+
failures.push({
|
|
255
|
+
owner: entry.owner,
|
|
256
|
+
message: cause instanceof Error ? cause.message : String(cause)
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
state = "terminated";
|
|
261
|
+
return { terminalId, reason, failures };
|
|
262
|
+
})();
|
|
263
|
+
return termination;
|
|
248
264
|
};
|
|
249
|
-
}
|
|
250
|
-
function admissionFailure(admission, expected) {
|
|
251
|
-
if (admission === void 0) return "no workload-scoped admission report was supplied";
|
|
252
|
-
if (admission.schema !== "forgeax.tool-service-admission-ref.v1" || !/^sha256:[0-9a-f]{64}$/.test(admission.reportDigest)) {
|
|
253
|
-
return "admission report identity is invalid";
|
|
254
|
-
}
|
|
255
|
-
for (const key of [
|
|
256
|
-
"toolId",
|
|
257
|
-
"descriptorDigest",
|
|
258
|
-
"recipeDigest",
|
|
259
|
-
"workloadClass",
|
|
260
|
-
"codeDigest",
|
|
261
|
-
"browserVersion",
|
|
262
|
-
"backend"
|
|
263
|
-
]) {
|
|
264
|
-
if (admission[key] !== expected[key]) return `admission ${key} does not match this run`;
|
|
265
|
-
}
|
|
266
|
-
if (admission.frameCount < 300) return "admission workload ran fewer than 300 frames";
|
|
267
|
-
if (Object.values(admission.samples).some((count) => count < 30)) {
|
|
268
|
-
return "admission sample set is incomplete";
|
|
269
|
-
}
|
|
270
|
-
if (!admission.correctness.terminalEquivalent || !admission.correctness.artifactIntegrity || !admission.correctness.freshReplay || !admission.correctness.hiddenParity || admission.correctness.drawCalls <= 0 || admission.correctness.nonBlackPixels <= 0) {
|
|
271
|
-
return "admission correctness gate failed";
|
|
272
|
-
}
|
|
273
|
-
const performance2 = admission.performance;
|
|
274
|
-
if (Object.values(performance2).some((value) => !Number.isFinite(value) || value <= 0) || performance2.serviceMedianMs > performance2.privateMedianMs * 0.8 || performance2.serviceP95Ms > performance2.privateP95Ms * 0.9 || performance2.serviceMaxMs > performance2.privateMaxMs * 1.1 || performance2.serviceRssBytes > performance2.privateRssBytes * 1.25) {
|
|
275
|
-
return "admission performance threshold failed";
|
|
276
|
-
}
|
|
277
|
-
if (!admission.cleanupPassed) return "admission cleanup gate failed";
|
|
278
|
-
if (!admission.evictionPassed) return "admission eviction gate failed";
|
|
279
|
-
return void 0;
|
|
280
|
-
}
|
|
281
|
-
function createServiceCapability(admission, expected) {
|
|
282
|
-
const reason = admissionFailure(admission, expected);
|
|
283
|
-
if (reason === void 0 && admission !== void 0) {
|
|
284
|
-
return { available: true, reportDigest: admission.reportDigest };
|
|
285
|
-
}
|
|
286
265
|
return {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
266
|
+
get state() {
|
|
267
|
+
return state;
|
|
268
|
+
},
|
|
269
|
+
register(owner, cleanup) {
|
|
270
|
+
if (state !== "active") return false;
|
|
271
|
+
cleanups.push({ owner, cleanup });
|
|
272
|
+
return true;
|
|
273
|
+
},
|
|
274
|
+
terminate
|
|
292
275
|
};
|
|
293
276
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
277
|
+
|
|
278
|
+
// src/timing.ts
|
|
279
|
+
var PHASES = [
|
|
280
|
+
"lookup",
|
|
281
|
+
"lease",
|
|
282
|
+
"transport",
|
|
283
|
+
"execute",
|
|
284
|
+
"capture",
|
|
285
|
+
"finalize",
|
|
286
|
+
"analyze"
|
|
287
|
+
];
|
|
288
|
+
function createExclusiveTiming(now = () => performance.now()) {
|
|
289
|
+
const phases = Object.fromEntries(
|
|
290
|
+
PHASES.map((phase) => [phase, { status: "not-applicable" }])
|
|
302
291
|
);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
292
|
+
const closed = /* @__PURE__ */ new Set();
|
|
293
|
+
let active;
|
|
294
|
+
let startedAtMs;
|
|
295
|
+
let endedAtMs;
|
|
306
296
|
return {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
297
|
+
begin(phase) {
|
|
298
|
+
if (active !== void 0) throw new TypeError(`phase '${active.phase}' is still open`);
|
|
299
|
+
if (closed.has(phase)) throw new TypeError(`phase '${phase}' was already closed`);
|
|
300
|
+
const at = now();
|
|
301
|
+
startedAtMs ??= at;
|
|
302
|
+
active = { phase, startedAtMs: at };
|
|
303
|
+
},
|
|
304
|
+
end(phase) {
|
|
305
|
+
if (active?.phase !== phase) throw new TypeError(`phase '${phase}' is not the active phase`);
|
|
306
|
+
const at = now();
|
|
307
|
+
phases[phase] = { status: "observed", durationMs: Math.max(0, at - active.startedAtMs) };
|
|
308
|
+
closed.add(phase);
|
|
309
|
+
active = void 0;
|
|
310
|
+
endedAtMs = at;
|
|
311
|
+
},
|
|
312
|
+
record(phase, durationMs) {
|
|
313
|
+
if (!Number.isFinite(durationMs) || durationMs < 0)
|
|
314
|
+
throw new TypeError("phase duration must be finite and non-negative");
|
|
315
|
+
if (closed.has(phase)) throw new TypeError(`phase '${phase}' was already closed`);
|
|
316
|
+
const at = now();
|
|
317
|
+
startedAtMs ??= at - durationMs;
|
|
318
|
+
phases[phase] = { status: "observed", durationMs };
|
|
319
|
+
closed.add(phase);
|
|
320
|
+
endedAtMs = at;
|
|
321
|
+
},
|
|
322
|
+
finish() {
|
|
323
|
+
if (active !== void 0) throw new TypeError(`phase '${active.phase}' is still open`);
|
|
324
|
+
const start = startedAtMs ?? now();
|
|
325
|
+
const end = endedAtMs ?? start;
|
|
326
|
+
return {
|
|
327
|
+
startedAtMs: start,
|
|
328
|
+
endedAtMs: end,
|
|
329
|
+
totalMs: Math.max(0, end - start),
|
|
330
|
+
phases: { ...phases }
|
|
331
|
+
};
|
|
332
|
+
}
|
|
311
333
|
};
|
|
312
334
|
}
|
|
313
|
-
function
|
|
314
|
-
|
|
315
|
-
structuredClone(value);
|
|
316
|
-
return { ok: true };
|
|
317
|
-
} catch (cause) {
|
|
318
|
-
return {
|
|
319
|
-
ok: false,
|
|
320
|
-
error: bootstrapNotCloneSafeError({
|
|
321
|
-
message: cause instanceof Error ? cause.message : String(cause)
|
|
322
|
-
})
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// src/carrier.ts
|
|
328
|
-
function token() {
|
|
329
|
-
return crypto.randomUUID().replaceAll("-", "");
|
|
330
|
-
}
|
|
331
|
-
function carrierError(code, expected, hint, detail) {
|
|
332
|
-
return { code, expected, hint, detail };
|
|
335
|
+
function startToolTiming() {
|
|
336
|
+
return performance.now();
|
|
333
337
|
}
|
|
334
|
-
function
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
338
|
+
function finishToolTiming(startedAtMs, operationTiming) {
|
|
339
|
+
const endedAtMs = performance.now();
|
|
340
|
+
const result = operationTiming?.finish();
|
|
341
|
+
const durationMs = Math.max(0, endedAtMs - startedAtMs);
|
|
342
|
+
const attributedMs = result === void 0 ? 0 : Object.values(result.phases).reduce(
|
|
343
|
+
(sum, observation) => observation.status === "observed" ? sum + observation.durationMs : sum,
|
|
344
|
+
0
|
|
345
|
+
);
|
|
346
|
+
return {
|
|
347
|
+
startedAtMs,
|
|
348
|
+
endedAtMs,
|
|
349
|
+
durationMs,
|
|
350
|
+
...result === void 0 ? {} : { phases: result.phases, unattributedMs: Math.max(0, durationMs - attributedMs) }
|
|
351
|
+
};
|
|
346
352
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
353
|
+
|
|
354
|
+
// src/runtime.ts
|
|
355
|
+
function defineTool(descriptor, execute) {
|
|
356
|
+
if (!/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/.test(descriptor.id)) {
|
|
357
|
+
throw new TypeError(`Tool id must use a stable lower-case path: ${descriptor.id}`);
|
|
350
358
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
throw new TypeError("carrier endpoint must be loopback HTTP");
|
|
359
|
+
if (descriptor.title.trim().length === 0 || descriptor.summary.trim().length === 0) {
|
|
360
|
+
throw new TypeError("Tool title and summary must not be empty");
|
|
354
361
|
}
|
|
355
|
-
if (!
|
|
356
|
-
|
|
362
|
+
if (!Array.isArray(descriptor.evidence)) throw new TypeError("Tool evidence must be an array");
|
|
363
|
+
if (descriptor.preview !== void 0 && descriptor.preview.realm !== descriptor.realm) {
|
|
364
|
+
throw new TypeError(
|
|
365
|
+
`Tool ${descriptor.id} preview contract declares ${descriptor.preview.realm} but descriptor declares ${descriptor.realm}`
|
|
366
|
+
);
|
|
357
367
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
schemaVersion: "1.0.0",
|
|
364
|
-
projectId: options.projectId,
|
|
365
|
-
consumerId: options.consumerId,
|
|
366
|
-
offerId: `offer:${token()}`,
|
|
367
|
-
endpoint: options.endpoint,
|
|
368
|
-
bearerToken: token(),
|
|
369
|
-
livenessToken: token(),
|
|
370
|
-
expiresAt: options.now + options.ttlMs,
|
|
371
|
-
...options.descriptorDigest === void 0 ? {} : { descriptorDigest: options.descriptorDigest },
|
|
372
|
-
...options.recipeDigest === void 0 ? {} : { recipeDigest: options.recipeDigest },
|
|
373
|
-
state: "offered"
|
|
368
|
+
const argsSchema = descriptor.argsSchema;
|
|
369
|
+
const resultSchema = descriptor.resultSchema;
|
|
370
|
+
return {
|
|
371
|
+
descriptor: { ...descriptor, argsSchema, resultSchema, evidence: [...descriptor.evidence] },
|
|
372
|
+
execute
|
|
374
373
|
};
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
"carrier-token-invalid",
|
|
385
|
-
"a complete lease request",
|
|
386
|
-
"Provide consumer identity, bearer token, and current time.",
|
|
387
|
-
{}
|
|
388
|
-
)
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
if (state.state === "started") {
|
|
392
|
-
return {
|
|
393
|
-
ok: false,
|
|
394
|
-
error: carrierError(
|
|
395
|
-
"carrier-started",
|
|
396
|
-
"a started carrier not to be retried",
|
|
397
|
-
"Report one terminal failure and clean up the existing started lease.",
|
|
398
|
-
{}
|
|
399
|
-
)
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
if (state.state === "exited") {
|
|
403
|
-
return {
|
|
404
|
-
ok: false,
|
|
405
|
-
error: carrierError(
|
|
406
|
-
"carrier-exited",
|
|
407
|
-
"an exited carrier not to be retried",
|
|
408
|
-
"Re-run the operation from a serialized snapshot instead of migrating live state.",
|
|
409
|
-
{}
|
|
410
|
-
)
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
if (request.consumerId !== offer.consumerId) {
|
|
414
|
-
return {
|
|
415
|
-
ok: false,
|
|
416
|
-
error: carrierError(
|
|
417
|
-
"carrier-consumer-mismatch",
|
|
418
|
-
"the offer consumer identity to match",
|
|
419
|
-
"Use the consumer identity that was authenticated for this project offer.",
|
|
420
|
-
{ expected: offer.consumerId, actual: request.consumerId }
|
|
421
|
-
)
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
if (request.bearerToken !== offer.bearerToken) {
|
|
425
|
-
return {
|
|
426
|
-
ok: false,
|
|
427
|
-
error: carrierError(
|
|
428
|
-
"carrier-token-invalid",
|
|
429
|
-
"the bearer token to match the ephemeral offer",
|
|
430
|
-
"Request a fresh visible offer; never persist or guess bearer tokens.",
|
|
431
|
-
{}
|
|
432
|
-
)
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
if (offer.descriptorDigest !== void 0 && request.descriptorDigest !== offer.descriptorDigest) {
|
|
436
|
-
return {
|
|
437
|
-
ok: false,
|
|
438
|
-
error: carrierError(
|
|
439
|
-
"carrier-descriptor-mismatch",
|
|
440
|
-
"the descriptor digest to match the authenticated offer",
|
|
441
|
-
"Refresh the descriptor and request a new visible offer before retrying.",
|
|
442
|
-
{ expected: offer.descriptorDigest, actual: request.descriptorDigest }
|
|
443
|
-
)
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
if (offer.recipeDigest !== void 0 && request.recipeDigest !== offer.recipeDigest) {
|
|
447
|
-
return {
|
|
448
|
-
ok: false,
|
|
449
|
-
error: carrierError(
|
|
450
|
-
"carrier-recipe-mismatch",
|
|
451
|
-
"the recipe digest to match the authenticated offer",
|
|
452
|
-
"Serialize the current snapshot and request a fresh visible offer before retrying.",
|
|
453
|
-
{ expected: offer.recipeDigest, actual: request.recipeDigest }
|
|
454
|
-
)
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
if (request.now >= offer.expiresAt) {
|
|
458
|
-
state = { state: "expired" };
|
|
459
|
-
return {
|
|
460
|
-
ok: false,
|
|
461
|
-
error: carrierError(
|
|
462
|
-
"carrier-offer-expired",
|
|
463
|
-
"the offer to be within its expiry window",
|
|
464
|
-
"Fall back to the ordinary visible carrier before retrying.",
|
|
465
|
-
{ expiresAt: offer.expiresAt, now: request.now }
|
|
466
|
-
)
|
|
467
|
-
};
|
|
468
|
-
}
|
|
469
|
-
if (requestedLeaseId !== void 0 && requestedLeaseId !== lease?.leaseId) {
|
|
470
|
-
return {
|
|
471
|
-
ok: false,
|
|
472
|
-
error: carrierError(
|
|
473
|
-
"carrier-token-invalid",
|
|
474
|
-
"the lease id to match the authenticated offer",
|
|
475
|
-
"Use the lease id returned by the first successful lease.",
|
|
476
|
-
{}
|
|
477
|
-
)
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
lease = {
|
|
481
|
-
leaseId: `lease:${token()}`,
|
|
482
|
-
offerId: offer.offerId,
|
|
483
|
-
consumerId: request.consumerId,
|
|
484
|
-
state: "leased"
|
|
485
|
-
};
|
|
486
|
-
state = { state: "leased", leaseId: lease.leaseId };
|
|
487
|
-
return { ok: true, value: lease, state: "leased" };
|
|
488
|
-
};
|
|
489
|
-
const started = (leaseId) => {
|
|
490
|
-
if (lease?.leaseId !== leaseId) {
|
|
491
|
-
return {
|
|
492
|
-
ok: false,
|
|
493
|
-
error: carrierError(
|
|
494
|
-
"carrier-lease-required",
|
|
495
|
-
"a valid lease before started",
|
|
496
|
-
"Lease the authenticated offer before reporting provider started.",
|
|
497
|
-
{}
|
|
498
|
-
)
|
|
499
|
-
};
|
|
500
|
-
}
|
|
501
|
-
state = { state: "started", leaseId };
|
|
502
|
-
return { ok: true, value: state, state: "started" };
|
|
374
|
+
}
|
|
375
|
+
function eventChannel() {
|
|
376
|
+
const queue = [];
|
|
377
|
+
const waiters = [];
|
|
378
|
+
let closed = false;
|
|
379
|
+
const emit = (event) => {
|
|
380
|
+
const waiter = waiters.shift();
|
|
381
|
+
if (waiter !== void 0) waiter({ done: false, value: event });
|
|
382
|
+
else queue.push(event);
|
|
503
383
|
};
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
ok: false,
|
|
508
|
-
error: carrierError(
|
|
509
|
-
"carrier-lease-required",
|
|
510
|
-
"a started lease before provider exit",
|
|
511
|
-
"Provider exit is terminal only after started has been acknowledged.",
|
|
512
|
-
{}
|
|
513
|
-
)
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
state = { state: "exited", leaseId };
|
|
517
|
-
return { ok: true, value: state, state: "exited" };
|
|
384
|
+
const close = () => {
|
|
385
|
+
closed = true;
|
|
386
|
+
while (waiters.length > 0) waiters.shift()?.({ done: true, value: void 0 });
|
|
518
387
|
};
|
|
519
|
-
const
|
|
520
|
-
|
|
388
|
+
const events = {
|
|
389
|
+
[Symbol.asyncIterator]() {
|
|
521
390
|
return {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
)
|
|
391
|
+
next: async () => {
|
|
392
|
+
const event = queue.shift();
|
|
393
|
+
if (event !== void 0) return { done: false, value: event };
|
|
394
|
+
if (closed) return { done: true, value: void 0 };
|
|
395
|
+
return new Promise((resolve) => waiters.push(resolve));
|
|
396
|
+
}
|
|
529
397
|
};
|
|
530
398
|
}
|
|
531
|
-
state = { state: "fallback" };
|
|
532
|
-
return { ok: true, value: state, state: "fallback" };
|
|
533
|
-
};
|
|
534
|
-
return {
|
|
535
|
-
offer,
|
|
536
|
-
lease: leaseOffer,
|
|
537
|
-
started,
|
|
538
|
-
exit,
|
|
539
|
-
fallback,
|
|
540
|
-
snapshot: () => state
|
|
541
399
|
};
|
|
400
|
+
return { emit, close, events };
|
|
542
401
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
let state = "active";
|
|
548
|
-
let terminalId;
|
|
549
|
-
let termination;
|
|
550
|
-
const terminate = (reason) => {
|
|
551
|
-
if (termination !== void 0) return termination;
|
|
552
|
-
terminalId = `${runId}:terminal:${crypto.randomUUID()}`;
|
|
553
|
-
state = "terminating";
|
|
554
|
-
termination = (async () => {
|
|
555
|
-
const failures = [];
|
|
556
|
-
for (let index = cleanups.length - 1; index >= 0; index -= 1) {
|
|
557
|
-
const entry = cleanups[index];
|
|
558
|
-
if (entry === void 0) continue;
|
|
559
|
-
try {
|
|
560
|
-
await entry.cleanup();
|
|
561
|
-
} catch (cause) {
|
|
562
|
-
failures.push({
|
|
563
|
-
owner: entry.owner,
|
|
564
|
-
message: cause instanceof Error ? cause.message : String(cause)
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
state = "terminated";
|
|
569
|
-
return { terminalId, reason, failures };
|
|
570
|
-
})();
|
|
571
|
-
return termination;
|
|
572
|
-
};
|
|
573
|
-
return {
|
|
574
|
-
get state() {
|
|
575
|
-
return state;
|
|
576
|
-
},
|
|
577
|
-
register(owner, cleanup) {
|
|
578
|
-
if (state !== "active") return false;
|
|
579
|
-
cleanups.push({ owner, cleanup });
|
|
580
|
-
return true;
|
|
581
|
-
},
|
|
582
|
-
terminate
|
|
583
|
-
};
|
|
402
|
+
function isTerminal(value) {
|
|
403
|
+
if (typeof value !== "object" || value === null) return false;
|
|
404
|
+
const outcome = Reflect.get(value, "outcome");
|
|
405
|
+
return outcome === "succeeded" || outcome === "failed";
|
|
584
406
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
"analyze"
|
|
595
|
-
];
|
|
596
|
-
function createExclusiveTiming(now = () => performance.now()) {
|
|
597
|
-
const phases = Object.fromEntries(
|
|
598
|
-
PHASES.map((phase) => [phase, { status: "not-applicable" }])
|
|
599
|
-
);
|
|
600
|
-
const closed = /* @__PURE__ */ new Set();
|
|
601
|
-
let active;
|
|
602
|
-
let startedAtMs;
|
|
603
|
-
let endedAtMs;
|
|
604
|
-
return {
|
|
605
|
-
begin(phase) {
|
|
606
|
-
if (active !== void 0) throw new TypeError(`phase '${active.phase}' is still open`);
|
|
607
|
-
if (closed.has(phase)) throw new TypeError(`phase '${phase}' was already closed`);
|
|
608
|
-
const at = now();
|
|
609
|
-
startedAtMs ??= at;
|
|
610
|
-
active = { phase, startedAtMs: at };
|
|
611
|
-
},
|
|
612
|
-
end(phase) {
|
|
613
|
-
if (active?.phase !== phase) throw new TypeError(`phase '${phase}' is not the active phase`);
|
|
614
|
-
const at = now();
|
|
615
|
-
phases[phase] = { status: "observed", durationMs: Math.max(0, at - active.startedAtMs) };
|
|
616
|
-
closed.add(phase);
|
|
617
|
-
active = void 0;
|
|
618
|
-
endedAtMs = at;
|
|
619
|
-
},
|
|
620
|
-
record(phase, durationMs) {
|
|
621
|
-
if (!Number.isFinite(durationMs) || durationMs < 0)
|
|
622
|
-
throw new TypeError("phase duration must be finite and non-negative");
|
|
623
|
-
if (closed.has(phase)) throw new TypeError(`phase '${phase}' was already closed`);
|
|
624
|
-
const at = now();
|
|
625
|
-
startedAtMs ??= at - durationMs;
|
|
626
|
-
phases[phase] = { status: "observed", durationMs };
|
|
627
|
-
closed.add(phase);
|
|
628
|
-
endedAtMs = at;
|
|
629
|
-
},
|
|
630
|
-
finish() {
|
|
631
|
-
if (active !== void 0) throw new TypeError(`phase '${active.phase}' is still open`);
|
|
632
|
-
const start = startedAtMs ?? now();
|
|
633
|
-
const end = endedAtMs ?? start;
|
|
634
|
-
return {
|
|
635
|
-
startedAtMs: start,
|
|
636
|
-
endedAtMs: end,
|
|
637
|
-
totalMs: Math.max(0, end - start),
|
|
638
|
-
phases: { ...phases }
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
function startToolTiming() {
|
|
644
|
-
return performance.now();
|
|
645
|
-
}
|
|
646
|
-
function finishToolTiming(startedAtMs, operationTiming) {
|
|
647
|
-
const endedAtMs = performance.now();
|
|
648
|
-
const result = operationTiming?.finish();
|
|
649
|
-
const durationMs = Math.max(0, endedAtMs - startedAtMs);
|
|
650
|
-
const attributedMs = result === void 0 ? 0 : Object.values(result.phases).reduce(
|
|
651
|
-
(sum, observation) => observation.status === "observed" ? sum + observation.durationMs : sum,
|
|
652
|
-
0
|
|
653
|
-
);
|
|
654
|
-
return {
|
|
655
|
-
startedAtMs,
|
|
656
|
-
endedAtMs,
|
|
657
|
-
durationMs,
|
|
658
|
-
...result === void 0 ? {} : { phases: result.phases, unattributedMs: Math.max(0, durationMs - attributedMs) }
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// src/runtime.ts
|
|
663
|
-
function defineTool(descriptor, execute) {
|
|
664
|
-
if (!/^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/.test(descriptor.id)) {
|
|
665
|
-
throw new TypeError(`Tool id must use a stable lower-case path: ${descriptor.id}`);
|
|
666
|
-
}
|
|
667
|
-
if (descriptor.title.trim().length === 0 || descriptor.summary.trim().length === 0) {
|
|
668
|
-
throw new TypeError("Tool title and summary must not be empty");
|
|
669
|
-
}
|
|
670
|
-
if (!Array.isArray(descriptor.evidence)) throw new TypeError("Tool evidence must be an array");
|
|
671
|
-
if (descriptor.preview !== void 0 && descriptor.preview.realm !== descriptor.realm) {
|
|
672
|
-
throw new TypeError(
|
|
673
|
-
`Tool ${descriptor.id} preview contract declares ${descriptor.preview.realm} but descriptor declares ${descriptor.realm}`
|
|
674
|
-
);
|
|
675
|
-
}
|
|
676
|
-
const argsSchema = descriptor.argsSchema;
|
|
677
|
-
const resultSchema = descriptor.resultSchema;
|
|
678
|
-
return {
|
|
679
|
-
descriptor: { ...descriptor, argsSchema, resultSchema, evidence: [...descriptor.evidence] },
|
|
680
|
-
execute
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
function eventChannel() {
|
|
684
|
-
const queue = [];
|
|
685
|
-
const waiters = [];
|
|
686
|
-
let closed = false;
|
|
687
|
-
const emit = (event) => {
|
|
688
|
-
const waiter = waiters.shift();
|
|
689
|
-
if (waiter !== void 0) waiter({ done: false, value: event });
|
|
690
|
-
else queue.push(event);
|
|
691
|
-
};
|
|
692
|
-
const close = () => {
|
|
693
|
-
closed = true;
|
|
694
|
-
while (waiters.length > 0) waiters.shift()?.({ done: true, value: void 0 });
|
|
695
|
-
};
|
|
696
|
-
const events = {
|
|
697
|
-
[Symbol.asyncIterator]() {
|
|
698
|
-
return {
|
|
699
|
-
next: async () => {
|
|
700
|
-
const event = queue.shift();
|
|
701
|
-
if (event !== void 0) return { done: false, value: event };
|
|
702
|
-
if (closed) return { done: true, value: void 0 };
|
|
703
|
-
return new Promise((resolve) => waiters.push(resolve));
|
|
704
|
-
}
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
};
|
|
708
|
-
return { emit, close, events };
|
|
709
|
-
}
|
|
710
|
-
function isTerminal(value) {
|
|
711
|
-
if (typeof value !== "object" || value === null) return false;
|
|
712
|
-
const outcome = Reflect.get(value, "outcome");
|
|
713
|
-
return outcome === "succeeded" || outcome === "failed";
|
|
714
|
-
}
|
|
715
|
-
function serializablePreview(value) {
|
|
716
|
-
return isSerializableValue(value) ? value : null;
|
|
717
|
-
}
|
|
718
|
-
function domainError(error) {
|
|
719
|
-
return domainFailureError(
|
|
720
|
-
error.code,
|
|
721
|
-
error.expected ?? "the producer operation to succeed",
|
|
722
|
-
error.hint ?? "Inspect detail and repair the owning producer before retrying.",
|
|
723
|
-
error.detail
|
|
407
|
+
function serializablePreview(value) {
|
|
408
|
+
return isSerializableValue(value) ? value : null;
|
|
409
|
+
}
|
|
410
|
+
function domainError(error) {
|
|
411
|
+
return domainFailureError(
|
|
412
|
+
error.code,
|
|
413
|
+
error.expected ?? "the producer operation to succeed",
|
|
414
|
+
error.hint ?? "Inspect detail and repair the owning producer before retrying.",
|
|
415
|
+
error.detail
|
|
724
416
|
);
|
|
725
417
|
}
|
|
726
418
|
function hasOkField(value) {
|
|
@@ -765,6 +457,10 @@ function createToolRuntime(contributions) {
|
|
|
765
457
|
const terminal = new Promise((resolve) => {
|
|
766
458
|
resolveTerminal = resolve;
|
|
767
459
|
});
|
|
460
|
+
let resolveExecutorExited;
|
|
461
|
+
const executorExited = new Promise((resolve) => {
|
|
462
|
+
resolveExecutorExited = resolve;
|
|
463
|
+
});
|
|
768
464
|
const settle = async (candidate, reason = "terminal") => {
|
|
769
465
|
if (terminalStarted) return;
|
|
770
466
|
terminalStarted = true;
|
|
@@ -802,6 +498,8 @@ function createToolRuntime(contributions) {
|
|
|
802
498
|
const context = {
|
|
803
499
|
runId,
|
|
804
500
|
signal: controller.signal,
|
|
501
|
+
...options.owner === void 0 ? {} : { owner: options.owner },
|
|
502
|
+
...options.caller === void 0 ? {} : { caller: options.caller },
|
|
805
503
|
...options.snapshot === void 0 ? {} : { snapshot: options.snapshot },
|
|
806
504
|
emit: (event) => {
|
|
807
505
|
if (!terminalStarted) channel.emit({ ...event, runId });
|
|
@@ -896,12 +594,25 @@ function createToolRuntime(contributions) {
|
|
|
896
594
|
);
|
|
897
595
|
channel.emit({ kind: "started", runId, atMs: performance.now() });
|
|
898
596
|
void (async () => {
|
|
899
|
-
const parsedArgs = contribution.descriptor.argsSchema.parse(args);
|
|
900
|
-
if (!parsedArgs.ok) {
|
|
901
|
-
fail(invalidArgsError(parsedArgs.error, serializablePreview(args)));
|
|
902
|
-
return;
|
|
903
|
-
}
|
|
904
597
|
try {
|
|
598
|
+
let parsedArgs;
|
|
599
|
+
try {
|
|
600
|
+
parsedArgs = contribution.descriptor.argsSchema.parse(args);
|
|
601
|
+
} catch (cause) {
|
|
602
|
+
await settle({
|
|
603
|
+
outcome: "failed",
|
|
604
|
+
failure: invalidArgsError(
|
|
605
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
606
|
+
serializablePreview(args)
|
|
607
|
+
),
|
|
608
|
+
artifacts: []
|
|
609
|
+
});
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if (!parsedArgs.ok) {
|
|
613
|
+
fail(invalidArgsError(parsedArgs.error, serializablePreview(args)));
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
905
616
|
if (options.signal?.aborted) {
|
|
906
617
|
cancelReason = "aborted by caller";
|
|
907
618
|
fail(cancellationError(cancelReason));
|
|
@@ -1021,12 +732,14 @@ function createToolRuntime(contributions) {
|
|
|
1021
732
|
});
|
|
1022
733
|
} finally {
|
|
1023
734
|
if (timeout !== void 0) clearTimeout(timeout);
|
|
735
|
+
resolveExecutorExited();
|
|
1024
736
|
}
|
|
1025
737
|
})();
|
|
1026
738
|
const runtimeRun = {
|
|
1027
739
|
id: runId,
|
|
1028
740
|
events: channel.events,
|
|
1029
741
|
terminal,
|
|
742
|
+
executorExited,
|
|
1030
743
|
cancel,
|
|
1031
744
|
disconnect,
|
|
1032
745
|
providerExit
|
|
@@ -1042,6 +755,670 @@ function createToolRuntime(contributions) {
|
|
|
1042
755
|
return runtime;
|
|
1043
756
|
}
|
|
1044
757
|
|
|
758
|
+
// src/api.ts
|
|
759
|
+
function assertName(value, label) {
|
|
760
|
+
if (typeof value !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9._:/-]*$/.test(value)) {
|
|
761
|
+
throw new TypeError(`${label} must be a stable non-empty identity`);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
function operationPath(descriptor) {
|
|
765
|
+
return (descriptor.path ?? descriptor.id.split(".")).join(" ");
|
|
766
|
+
}
|
|
767
|
+
function providerKey(sourceId, providerId) {
|
|
768
|
+
return `${sourceId}\0${providerId}`;
|
|
769
|
+
}
|
|
770
|
+
function apiFailure(code, expected, hint, detail) {
|
|
771
|
+
return domainFailureError(code, expected, hint, detail);
|
|
772
|
+
}
|
|
773
|
+
function failedRun(failure) {
|
|
774
|
+
const id = `api:${crypto.randomUUID()}`;
|
|
775
|
+
const terminal = Promise.resolve({
|
|
776
|
+
outcome: "failed",
|
|
777
|
+
failure,
|
|
778
|
+
artifacts: []
|
|
779
|
+
});
|
|
780
|
+
const events = {
|
|
781
|
+
async *[Symbol.asyncIterator]() {
|
|
782
|
+
yield { kind: "started", runId: id, atMs: performance.now() };
|
|
783
|
+
yield { kind: "terminal", runId: id, outcome: "failed", atMs: performance.now() };
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
return {
|
|
787
|
+
id,
|
|
788
|
+
events,
|
|
789
|
+
terminal,
|
|
790
|
+
executorExited: Promise.resolve(),
|
|
791
|
+
cancel() {
|
|
792
|
+
},
|
|
793
|
+
disconnect() {
|
|
794
|
+
},
|
|
795
|
+
providerExit() {
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
function validateProvider(input) {
|
|
800
|
+
assertName(input.providerId, "providerId");
|
|
801
|
+
assertName(input.sourceId, "sourceId");
|
|
802
|
+
if (!["build", "host", "engine"].includes(input.realm))
|
|
803
|
+
throw new TypeError(`unsupported Tool API realm ${String(input.realm)}`);
|
|
804
|
+
if (!Array.isArray(input.tools) || input.tools.length === 0)
|
|
805
|
+
throw new TypeError("Tool API providers must publish at least one contribution");
|
|
806
|
+
const ids = /* @__PURE__ */ new Set();
|
|
807
|
+
const paths = /* @__PURE__ */ new Set();
|
|
808
|
+
if (input.initialState !== void 0 && input.initialState !== "pending" && input.initialState !== "active")
|
|
809
|
+
throw new TypeError("Tool API provider initialState must be pending or active");
|
|
810
|
+
for (const contribution of input.tools) {
|
|
811
|
+
if (contribution === null || typeof contribution !== "object")
|
|
812
|
+
throw new TypeError("Tool API contributions must be objects");
|
|
813
|
+
if (typeof contribution.execute !== "function")
|
|
814
|
+
throw new TypeError(
|
|
815
|
+
`Tool API contribution ${String(contribution.descriptor?.id)} needs an executor`
|
|
816
|
+
);
|
|
817
|
+
const descriptor = contribution.descriptor;
|
|
818
|
+
if (descriptor.realm !== input.realm)
|
|
819
|
+
throw new TypeError(
|
|
820
|
+
`Tool API ${descriptor.id} declares ${descriptor.realm} but provider is ${input.realm}`
|
|
821
|
+
);
|
|
822
|
+
if (ids.has(descriptor.id))
|
|
823
|
+
throw new TypeError(`duplicate Tool API operation id ${descriptor.id}`);
|
|
824
|
+
ids.add(descriptor.id);
|
|
825
|
+
const path = operationPath(descriptor);
|
|
826
|
+
if (paths.has(path)) throw new TypeError(`duplicate Tool API command path ${path}`);
|
|
827
|
+
paths.add(path);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
function createToolApi() {
|
|
831
|
+
const providers = /* @__PURE__ */ new Map();
|
|
832
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
833
|
+
let providerGeneration = 0;
|
|
834
|
+
let disposed = false;
|
|
835
|
+
const notify = () => {
|
|
836
|
+
const value = api.snapshot();
|
|
837
|
+
for (const listener of listeners) {
|
|
838
|
+
try {
|
|
839
|
+
listener(value);
|
|
840
|
+
} catch {
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
const snapshot = () => {
|
|
845
|
+
const providerSnapshots = [];
|
|
846
|
+
const operations = [];
|
|
847
|
+
for (const record of providers.values()) {
|
|
848
|
+
providerSnapshots.push({
|
|
849
|
+
owner: record.owner,
|
|
850
|
+
state: record.state,
|
|
851
|
+
...record.fiberState === void 0 ? {} : { fiberState: record.fiberState },
|
|
852
|
+
callable: record.state === "active",
|
|
853
|
+
operationIds: record.input.tools.map(({ descriptor }) => descriptor.id)
|
|
854
|
+
});
|
|
855
|
+
for (const contribution of record.input.tools) {
|
|
856
|
+
operations.push({
|
|
857
|
+
descriptor: contribution.descriptor,
|
|
858
|
+
owner: record.owner,
|
|
859
|
+
providerState: record.state,
|
|
860
|
+
declared: true,
|
|
861
|
+
callable: record.state === "active",
|
|
862
|
+
...record.fiberState === void 0 ? {} : { fiberState: record.fiberState }
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
providerSnapshots.sort(
|
|
867
|
+
(left, right) => providerKey(left.owner.sourceId, left.owner.providerId).localeCompare(
|
|
868
|
+
providerKey(right.owner.sourceId, right.owner.providerId)
|
|
869
|
+
)
|
|
870
|
+
);
|
|
871
|
+
operations.sort((left, right) => {
|
|
872
|
+
const source = left.owner.sourceId.localeCompare(right.owner.sourceId);
|
|
873
|
+
return source !== 0 ? source : left.descriptor.id.localeCompare(right.descriptor.id);
|
|
874
|
+
});
|
|
875
|
+
return { providers: providerSnapshots, operations };
|
|
876
|
+
};
|
|
877
|
+
const registerProvider = (input) => {
|
|
878
|
+
if (disposed) throw new Error("Tool API is disposed");
|
|
879
|
+
validateProvider(input);
|
|
880
|
+
const key = providerKey(input.sourceId, input.providerId);
|
|
881
|
+
if (providers.get(key)?.state === "active" || providers.get(key)?.state === "revoking") {
|
|
882
|
+
throw new TypeError(
|
|
883
|
+
`Tool API provider ${input.sourceId}/${input.providerId} is already registered`
|
|
884
|
+
);
|
|
885
|
+
}
|
|
886
|
+
const operationKeys = /* @__PURE__ */ new Set();
|
|
887
|
+
for (const contribution of input.tools) {
|
|
888
|
+
const operationKey = `${input.sourceId}\0${contribution.descriptor.id}`;
|
|
889
|
+
const pathKey2 = `${input.sourceId}\0${operationPath(contribution.descriptor)}`;
|
|
890
|
+
if (operationKeys.has(operationKey) || operationKeys.has(pathKey2))
|
|
891
|
+
throw new TypeError(`Tool API contribution conflict for ${contribution.descriptor.id}`);
|
|
892
|
+
operationKeys.add(operationKey);
|
|
893
|
+
operationKeys.add(pathKey2);
|
|
894
|
+
for (const record2 of providers.values()) {
|
|
895
|
+
if (!["pending", "active", "revoking"].includes(record2.state) || record2.owner.sourceId !== input.sourceId)
|
|
896
|
+
continue;
|
|
897
|
+
if (record2.input.tools.some(({ descriptor }) => descriptor.id === contribution.descriptor.id)) {
|
|
898
|
+
throw new TypeError(
|
|
899
|
+
`Tool API operation ${contribution.descriptor.id} already exists for source ${input.sourceId}`
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
if (record2.input.tools.some(
|
|
903
|
+
({ descriptor }) => operationPath(descriptor) === operationPath(contribution.descriptor)
|
|
904
|
+
)) {
|
|
905
|
+
throw new TypeError(
|
|
906
|
+
`Tool API command path ${operationPath(contribution.descriptor)} already exists for source ${input.sourceId}`
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
const generation = input.generation ?? ++providerGeneration;
|
|
912
|
+
if (!Number.isSafeInteger(generation) || generation <= 0)
|
|
913
|
+
throw new TypeError("Tool API provider generation must be a positive integer");
|
|
914
|
+
providerGeneration = Math.max(providerGeneration, generation);
|
|
915
|
+
const owner = {
|
|
916
|
+
providerId: input.providerId,
|
|
917
|
+
sourceId: input.sourceId,
|
|
918
|
+
generation,
|
|
919
|
+
realm: input.realm,
|
|
920
|
+
...input.fiberId === void 0 ? {} : { fiberId: input.fiberId },
|
|
921
|
+
...input.module === void 0 ? {} : { module: input.module }
|
|
922
|
+
};
|
|
923
|
+
const runtime = createToolRuntime(input.tools);
|
|
924
|
+
const record = {
|
|
925
|
+
input: { ...input, tools: [...input.tools] },
|
|
926
|
+
owner,
|
|
927
|
+
runtime,
|
|
928
|
+
runs: /* @__PURE__ */ new Set(),
|
|
929
|
+
state: input.initialState ?? "active",
|
|
930
|
+
...input.fiberState === void 0 ? {} : { fiberState: input.fiberState }
|
|
931
|
+
};
|
|
932
|
+
providers.set(key, record);
|
|
933
|
+
notify();
|
|
934
|
+
const activate = (fiberState = "active") => {
|
|
935
|
+
if (record.state !== "pending") return;
|
|
936
|
+
record.state = "active";
|
|
937
|
+
record.fiberState = fiberState;
|
|
938
|
+
notify();
|
|
939
|
+
};
|
|
940
|
+
const fail = (reason = "provider failed", fiberState = "failed") => {
|
|
941
|
+
if (record.state !== "pending" && record.state !== "active") return;
|
|
942
|
+
record.state = "failed";
|
|
943
|
+
record.reason = reason;
|
|
944
|
+
record.fiberState = fiberState;
|
|
945
|
+
for (const run2 of record.runs) run2.cancel(reason);
|
|
946
|
+
notify();
|
|
947
|
+
};
|
|
948
|
+
const revoke = async (reason = "provider revoked") => {
|
|
949
|
+
if (record.state === "revoked") return;
|
|
950
|
+
if (record.state === "active" || record.state === "pending") {
|
|
951
|
+
record.state = "revoking";
|
|
952
|
+
record.reason = reason;
|
|
953
|
+
record.fiberState = "unloading";
|
|
954
|
+
notify();
|
|
955
|
+
for (const run2 of record.runs) run2.cancel(reason);
|
|
956
|
+
}
|
|
957
|
+
await Promise.all([...record.runs].map((run2) => run2.executorExited));
|
|
958
|
+
if (record.state !== "failed") {
|
|
959
|
+
record.state = "revoked";
|
|
960
|
+
record.fiberState = "disposed";
|
|
961
|
+
}
|
|
962
|
+
notify();
|
|
963
|
+
};
|
|
964
|
+
return Object.freeze({
|
|
965
|
+
owner,
|
|
966
|
+
activate,
|
|
967
|
+
fail,
|
|
968
|
+
snapshot: () => ({
|
|
969
|
+
owner,
|
|
970
|
+
state: record.state,
|
|
971
|
+
...record.fiberState === void 0 ? {} : { fiberState: record.fiberState },
|
|
972
|
+
callable: record.state === "active",
|
|
973
|
+
operationIds: record.input.tools.map(({ descriptor }) => descriptor.id)
|
|
974
|
+
}),
|
|
975
|
+
revoke
|
|
976
|
+
});
|
|
977
|
+
};
|
|
978
|
+
const findRecords = (id, sourceId) => [...providers.values()].filter(
|
|
979
|
+
(record) => (sourceId === void 0 || record.owner.sourceId === sourceId) && record.input.tools.some(({ descriptor }) => descriptor.id === id)
|
|
980
|
+
);
|
|
981
|
+
const run = (id, args, options = {}) => {
|
|
982
|
+
if (disposed) {
|
|
983
|
+
return failedRun(
|
|
984
|
+
apiFailure(
|
|
985
|
+
"api-disposed",
|
|
986
|
+
"the Tool API owner to remain available",
|
|
987
|
+
"Create a fresh owner and retry the operation.",
|
|
988
|
+
{ operation: id }
|
|
989
|
+
)
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
if (options.providerId !== void 0 && options.sourceId === void 0) {
|
|
993
|
+
return failedRun(
|
|
994
|
+
apiFailure(
|
|
995
|
+
"api-source-required",
|
|
996
|
+
`operation ${id} to include its explicit sourceId with providerId`,
|
|
997
|
+
"Refresh Tool API sources and pass both sourceId and providerId from one snapshot.",
|
|
998
|
+
{ operation: id, providerId: options.providerId }
|
|
999
|
+
)
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
const matches = findRecords(id, options.sourceId);
|
|
1003
|
+
const active = matches.filter((record) => record.state === "active");
|
|
1004
|
+
const selected = options.providerId === void 0 ? active.length === 1 ? active[0] : void 0 : active.find((record) => record.owner.providerId === options.providerId);
|
|
1005
|
+
if (selected === void 0) {
|
|
1006
|
+
const code = matches.length === 0 || active.length === 0 ? "api-operation-unavailable" : "api-provider-route-required";
|
|
1007
|
+
return failedRun(
|
|
1008
|
+
apiFailure(
|
|
1009
|
+
code,
|
|
1010
|
+
`operation ${id} to have one active, explicitly routable provider`,
|
|
1011
|
+
"Refresh Tool API sources and select the providerId/sourceId returned by discovery.",
|
|
1012
|
+
{
|
|
1013
|
+
operation: id,
|
|
1014
|
+
...options.providerId === void 0 ? {} : { providerId: options.providerId },
|
|
1015
|
+
providers: matches.map((record) => record.owner.providerId)
|
|
1016
|
+
}
|
|
1017
|
+
)
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
if (options.generation !== void 0 && options.generation !== selected.owner.generation) {
|
|
1021
|
+
return failedRun(
|
|
1022
|
+
apiFailure(
|
|
1023
|
+
"api-stale-generation",
|
|
1024
|
+
`provider ${selected.owner.providerId} generation ${options.generation} to match ${selected.owner.generation}`,
|
|
1025
|
+
"Refresh the source snapshot before retrying the operation.",
|
|
1026
|
+
{
|
|
1027
|
+
operation: id,
|
|
1028
|
+
providerId: selected.owner.providerId,
|
|
1029
|
+
expectedGeneration: selected.owner.generation,
|
|
1030
|
+
actualGeneration: options.generation
|
|
1031
|
+
}
|
|
1032
|
+
)
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
const contribution = selected.input.tools.find(({ descriptor }) => descriptor.id === id);
|
|
1036
|
+
if (contribution === void 0) {
|
|
1037
|
+
return failedRun(
|
|
1038
|
+
apiFailure(
|
|
1039
|
+
"api-operation-unavailable",
|
|
1040
|
+
`operation ${id} to remain published by its provider`,
|
|
1041
|
+
"Refresh Tool API sources before retrying.",
|
|
1042
|
+
{ operation: id }
|
|
1043
|
+
)
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
1046
|
+
if (selected.input.authorize?.(options.caller, contribution.descriptor) === false) {
|
|
1047
|
+
return failedRun(
|
|
1048
|
+
apiFailure(
|
|
1049
|
+
"api-unauthorized",
|
|
1050
|
+
`caller to be authorized for operation ${id}`,
|
|
1051
|
+
"Use the authenticated Host connection and the capability it was granted.",
|
|
1052
|
+
{ operation: id, providerId: selected.owner.providerId }
|
|
1053
|
+
)
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
const runOptions = {
|
|
1057
|
+
...options,
|
|
1058
|
+
owner: selected.owner,
|
|
1059
|
+
...options.caller === void 0 ? {} : { caller: options.caller }
|
|
1060
|
+
};
|
|
1061
|
+
const activeRun = selected.runtime.run(contribution, args, runOptions);
|
|
1062
|
+
selected.runs.add(activeRun);
|
|
1063
|
+
void activeRun.executorExited.finally(
|
|
1064
|
+
() => selected.runs.delete(activeRun)
|
|
1065
|
+
);
|
|
1066
|
+
return activeRun;
|
|
1067
|
+
};
|
|
1068
|
+
const api = {
|
|
1069
|
+
snapshot,
|
|
1070
|
+
list: () => snapshot().operations,
|
|
1071
|
+
describe: (id, sourceId) => findRecords(id, sourceId).flatMap((record) => {
|
|
1072
|
+
const contribution = record.input.tools.find(({ descriptor }) => descriptor.id === id);
|
|
1073
|
+
return contribution === void 0 ? [] : [
|
|
1074
|
+
{
|
|
1075
|
+
descriptor: contribution.descriptor,
|
|
1076
|
+
owner: record.owner,
|
|
1077
|
+
providerState: record.state,
|
|
1078
|
+
declared: true,
|
|
1079
|
+
callable: record.state === "active",
|
|
1080
|
+
...record.fiberState === void 0 ? {} : { fiberState: record.fiberState }
|
|
1081
|
+
}
|
|
1082
|
+
];
|
|
1083
|
+
}),
|
|
1084
|
+
registerProvider,
|
|
1085
|
+
run,
|
|
1086
|
+
subscribe(listener) {
|
|
1087
|
+
listeners.add(listener);
|
|
1088
|
+
return () => listeners.delete(listener);
|
|
1089
|
+
},
|
|
1090
|
+
async dispose() {
|
|
1091
|
+
if (disposed) return;
|
|
1092
|
+
disposed = true;
|
|
1093
|
+
const pending = [...providers.values()].map((record) => {
|
|
1094
|
+
if (record.state === "active" || record.state === "pending") {
|
|
1095
|
+
record.state = "revoking";
|
|
1096
|
+
record.fiberState = "unloading";
|
|
1097
|
+
for (const run2 of record.runs) run2.cancel("Tool API owner disposed");
|
|
1098
|
+
}
|
|
1099
|
+
return Promise.all([...record.runs].map((run2) => run2.executorExited)).then(() => {
|
|
1100
|
+
if (record.state !== "failed") {
|
|
1101
|
+
record.state = "revoked";
|
|
1102
|
+
record.fiberState = "disposed";
|
|
1103
|
+
}
|
|
1104
|
+
});
|
|
1105
|
+
});
|
|
1106
|
+
await Promise.all(pending);
|
|
1107
|
+
notify();
|
|
1108
|
+
listeners.clear();
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
1111
|
+
return api;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
// src/capability.ts
|
|
1115
|
+
var capabilityIdPattern = /^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/;
|
|
1116
|
+
function defineToolCapability(id) {
|
|
1117
|
+
if (!capabilityIdPattern.test(id)) {
|
|
1118
|
+
throw new TypeError(`Tool capability id must use a stable lower-case path: ${id}`);
|
|
1119
|
+
}
|
|
1120
|
+
return Object.freeze({ id });
|
|
1121
|
+
}
|
|
1122
|
+
function createCapabilityResolver(resolve) {
|
|
1123
|
+
return (capability) => {
|
|
1124
|
+
const value = resolve(capability);
|
|
1125
|
+
return value === void 0 ? void 0 : { ok: true, value };
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
function admissionFailure(admission, expected) {
|
|
1129
|
+
if (admission === void 0) return "no workload-scoped admission report was supplied";
|
|
1130
|
+
if (admission.schema !== "forgeax.tool-service-admission-ref.v1" || !/^sha256:[0-9a-f]{64}$/.test(admission.reportDigest)) {
|
|
1131
|
+
return "admission report identity is invalid";
|
|
1132
|
+
}
|
|
1133
|
+
for (const key of [
|
|
1134
|
+
"toolId",
|
|
1135
|
+
"descriptorDigest",
|
|
1136
|
+
"recipeDigest",
|
|
1137
|
+
"workloadClass",
|
|
1138
|
+
"codeDigest",
|
|
1139
|
+
"browserVersion",
|
|
1140
|
+
"backend"
|
|
1141
|
+
]) {
|
|
1142
|
+
if (admission[key] !== expected[key]) return `admission ${key} does not match this run`;
|
|
1143
|
+
}
|
|
1144
|
+
if (admission.frameCount < 300) return "admission workload ran fewer than 300 frames";
|
|
1145
|
+
if (Object.values(admission.samples).some((count) => count < 30)) {
|
|
1146
|
+
return "admission sample set is incomplete";
|
|
1147
|
+
}
|
|
1148
|
+
if (!admission.correctness.terminalEquivalent || !admission.correctness.artifactIntegrity || !admission.correctness.freshReplay || !admission.correctness.hiddenParity || admission.correctness.drawCalls <= 0 || admission.correctness.nonBlackPixels <= 0) {
|
|
1149
|
+
return "admission correctness gate failed";
|
|
1150
|
+
}
|
|
1151
|
+
const performance2 = admission.performance;
|
|
1152
|
+
if (Object.values(performance2).some((value) => !Number.isFinite(value) || value <= 0) || performance2.serviceMedianMs > performance2.privateMedianMs * 0.8 || performance2.serviceP95Ms > performance2.privateP95Ms * 0.9 || performance2.serviceMaxMs > performance2.privateMaxMs * 1.1 || performance2.serviceRssBytes > performance2.privateRssBytes * 1.25) {
|
|
1153
|
+
return "admission performance threshold failed";
|
|
1154
|
+
}
|
|
1155
|
+
if (!admission.cleanupPassed) return "admission cleanup gate failed";
|
|
1156
|
+
if (!admission.evictionPassed) return "admission eviction gate failed";
|
|
1157
|
+
return void 0;
|
|
1158
|
+
}
|
|
1159
|
+
function createServiceCapability(admission, expected) {
|
|
1160
|
+
const reason = admissionFailure(admission, expected);
|
|
1161
|
+
if (reason === void 0 && admission !== void 0) {
|
|
1162
|
+
return { available: true, reportDigest: admission.reportDigest };
|
|
1163
|
+
}
|
|
1164
|
+
return {
|
|
1165
|
+
available: false,
|
|
1166
|
+
code: "tool-service-capability-absent",
|
|
1167
|
+
expected: "an admitted acceleration service",
|
|
1168
|
+
hint: "Use the private executor and rerun benchmark admission before enabling service.",
|
|
1169
|
+
detail: { reason: reason ?? "benchmark admission did not pass" }
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
1172
|
+
function createRealmCapabilityMatrix(input) {
|
|
1173
|
+
const realms = ["build", "host", "engine"].reduce(
|
|
1174
|
+
(result, realm) => {
|
|
1175
|
+
const supported = input.supported[realm];
|
|
1176
|
+
result[realm] = supported ? { realm, supported: true } : { realm, supported: false, reason: "realm-capability-unavailable" };
|
|
1177
|
+
return result;
|
|
1178
|
+
},
|
|
1179
|
+
{}
|
|
1180
|
+
);
|
|
1181
|
+
return { catalogDigest: input.catalogDigest, realms };
|
|
1182
|
+
}
|
|
1183
|
+
function bootstrapNotCloneSafeError(detail) {
|
|
1184
|
+
return {
|
|
1185
|
+
code: "tool-bootstrap-not-clone-safe",
|
|
1186
|
+
expected: "bootstrap input to contain structured-clone-safe data",
|
|
1187
|
+
hint: "Remove live handles, functions, ports, and realm-owned objects from bootstrap input.",
|
|
1188
|
+
detail
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
function validateRealmBootstrapPayload(value) {
|
|
1192
|
+
try {
|
|
1193
|
+
structuredClone(value);
|
|
1194
|
+
return { ok: true };
|
|
1195
|
+
} catch (cause) {
|
|
1196
|
+
return {
|
|
1197
|
+
ok: false,
|
|
1198
|
+
error: bootstrapNotCloneSafeError({
|
|
1199
|
+
message: cause instanceof Error ? cause.message : String(cause)
|
|
1200
|
+
})
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
// src/carrier.ts
|
|
1206
|
+
function token() {
|
|
1207
|
+
return crypto.randomUUID().replaceAll("-", "");
|
|
1208
|
+
}
|
|
1209
|
+
function carrierError(code, expected, hint, detail) {
|
|
1210
|
+
return { code, expected, hint, detail };
|
|
1211
|
+
}
|
|
1212
|
+
function containsLiveKey(value, seen = /* @__PURE__ */ new Set()) {
|
|
1213
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1214
|
+
if (seen.has(value)) return false;
|
|
1215
|
+
seen.add(value);
|
|
1216
|
+
if (Array.isArray(value)) return value.some((entry) => containsLiveKey(entry, seen));
|
|
1217
|
+
return Object.entries(value).some(([key, nested]) => {
|
|
1218
|
+
if (["world", "renderer", "canvas", "ui", "profile", "liveHandle", "context", "fiber"].includes(
|
|
1219
|
+
key
|
|
1220
|
+
))
|
|
1221
|
+
return true;
|
|
1222
|
+
return containsLiveKey(nested, seen);
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1225
|
+
function validateOptions(options) {
|
|
1226
|
+
if (options.projectId.length === 0 || options.consumerId.length === 0) {
|
|
1227
|
+
throw new TypeError("carrier projectId and consumerId must not be empty");
|
|
1228
|
+
}
|
|
1229
|
+
const endpoint = new URL(options.endpoint);
|
|
1230
|
+
if (endpoint.protocol !== "http:" || !["127.0.0.1", "localhost"].includes(endpoint.hostname)) {
|
|
1231
|
+
throw new TypeError("carrier endpoint must be loopback HTTP");
|
|
1232
|
+
}
|
|
1233
|
+
if (!Number.isFinite(options.now) || !Number.isFinite(options.ttlMs) || options.ttlMs <= 0) {
|
|
1234
|
+
throw new TypeError("carrier clock and ttl must be finite and positive");
|
|
1235
|
+
}
|
|
1236
|
+
if (containsLiveKey(options.payload)) throw new TypeError("carrier-payload-live-state");
|
|
1237
|
+
}
|
|
1238
|
+
function createCarrierStateMachine(options) {
|
|
1239
|
+
validateOptions(options);
|
|
1240
|
+
const offer = {
|
|
1241
|
+
schemaVersion: "1.0.0",
|
|
1242
|
+
projectId: options.projectId,
|
|
1243
|
+
consumerId: options.consumerId,
|
|
1244
|
+
offerId: `offer:${token()}`,
|
|
1245
|
+
endpoint: options.endpoint,
|
|
1246
|
+
bearerToken: token(),
|
|
1247
|
+
livenessToken: token(),
|
|
1248
|
+
expiresAt: options.now + options.ttlMs,
|
|
1249
|
+
...options.descriptorDigest === void 0 ? {} : { descriptorDigest: options.descriptorDigest },
|
|
1250
|
+
...options.recipeDigest === void 0 ? {} : { recipeDigest: options.recipeDigest },
|
|
1251
|
+
state: "offered"
|
|
1252
|
+
};
|
|
1253
|
+
let state = { state: "offered" };
|
|
1254
|
+
let lease;
|
|
1255
|
+
const leaseOffer = (requestOrId, maybeRequest) => {
|
|
1256
|
+
const request = typeof requestOrId === "string" ? maybeRequest : requestOrId;
|
|
1257
|
+
const requestedLeaseId = typeof requestOrId === "string" ? requestOrId : void 0;
|
|
1258
|
+
if (request === void 0) {
|
|
1259
|
+
return {
|
|
1260
|
+
ok: false,
|
|
1261
|
+
error: carrierError(
|
|
1262
|
+
"carrier-token-invalid",
|
|
1263
|
+
"a complete lease request",
|
|
1264
|
+
"Provide consumer identity, bearer token, and current time.",
|
|
1265
|
+
{}
|
|
1266
|
+
)
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
if (state.state === "started") {
|
|
1270
|
+
return {
|
|
1271
|
+
ok: false,
|
|
1272
|
+
error: carrierError(
|
|
1273
|
+
"carrier-started",
|
|
1274
|
+
"a started carrier not to be retried",
|
|
1275
|
+
"Report one terminal failure and clean up the existing started lease.",
|
|
1276
|
+
{}
|
|
1277
|
+
)
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
if (state.state === "exited") {
|
|
1281
|
+
return {
|
|
1282
|
+
ok: false,
|
|
1283
|
+
error: carrierError(
|
|
1284
|
+
"carrier-exited",
|
|
1285
|
+
"an exited carrier not to be retried",
|
|
1286
|
+
"Re-run the operation from a serialized snapshot instead of migrating live state.",
|
|
1287
|
+
{}
|
|
1288
|
+
)
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
if (request.consumerId !== offer.consumerId) {
|
|
1292
|
+
return {
|
|
1293
|
+
ok: false,
|
|
1294
|
+
error: carrierError(
|
|
1295
|
+
"carrier-consumer-mismatch",
|
|
1296
|
+
"the offer consumer identity to match",
|
|
1297
|
+
"Use the consumer identity that was authenticated for this project offer.",
|
|
1298
|
+
{ expected: offer.consumerId, actual: request.consumerId }
|
|
1299
|
+
)
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
if (request.bearerToken !== offer.bearerToken) {
|
|
1303
|
+
return {
|
|
1304
|
+
ok: false,
|
|
1305
|
+
error: carrierError(
|
|
1306
|
+
"carrier-token-invalid",
|
|
1307
|
+
"the bearer token to match the ephemeral offer",
|
|
1308
|
+
"Request a fresh visible offer; never persist or guess bearer tokens.",
|
|
1309
|
+
{}
|
|
1310
|
+
)
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
if (offer.descriptorDigest !== void 0 && request.descriptorDigest !== offer.descriptorDigest) {
|
|
1314
|
+
return {
|
|
1315
|
+
ok: false,
|
|
1316
|
+
error: carrierError(
|
|
1317
|
+
"carrier-descriptor-mismatch",
|
|
1318
|
+
"the descriptor digest to match the authenticated offer",
|
|
1319
|
+
"Refresh the descriptor and request a new visible offer before retrying.",
|
|
1320
|
+
{ expected: offer.descriptorDigest, actual: request.descriptorDigest }
|
|
1321
|
+
)
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
if (offer.recipeDigest !== void 0 && request.recipeDigest !== offer.recipeDigest) {
|
|
1325
|
+
return {
|
|
1326
|
+
ok: false,
|
|
1327
|
+
error: carrierError(
|
|
1328
|
+
"carrier-recipe-mismatch",
|
|
1329
|
+
"the recipe digest to match the authenticated offer",
|
|
1330
|
+
"Serialize the current snapshot and request a fresh visible offer before retrying.",
|
|
1331
|
+
{ expected: offer.recipeDigest, actual: request.recipeDigest }
|
|
1332
|
+
)
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
if (request.now >= offer.expiresAt) {
|
|
1336
|
+
state = { state: "expired" };
|
|
1337
|
+
return {
|
|
1338
|
+
ok: false,
|
|
1339
|
+
error: carrierError(
|
|
1340
|
+
"carrier-offer-expired",
|
|
1341
|
+
"the offer to be within its expiry window",
|
|
1342
|
+
"Fall back to the ordinary visible carrier before retrying.",
|
|
1343
|
+
{ expiresAt: offer.expiresAt, now: request.now }
|
|
1344
|
+
)
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
if (requestedLeaseId !== void 0 && requestedLeaseId !== lease?.leaseId) {
|
|
1348
|
+
return {
|
|
1349
|
+
ok: false,
|
|
1350
|
+
error: carrierError(
|
|
1351
|
+
"carrier-token-invalid",
|
|
1352
|
+
"the lease id to match the authenticated offer",
|
|
1353
|
+
"Use the lease id returned by the first successful lease.",
|
|
1354
|
+
{}
|
|
1355
|
+
)
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
lease = {
|
|
1359
|
+
leaseId: `lease:${token()}`,
|
|
1360
|
+
offerId: offer.offerId,
|
|
1361
|
+
consumerId: request.consumerId,
|
|
1362
|
+
state: "leased"
|
|
1363
|
+
};
|
|
1364
|
+
state = { state: "leased", leaseId: lease.leaseId };
|
|
1365
|
+
return { ok: true, value: lease, state: "leased" };
|
|
1366
|
+
};
|
|
1367
|
+
const started = (leaseId) => {
|
|
1368
|
+
if (lease?.leaseId !== leaseId) {
|
|
1369
|
+
return {
|
|
1370
|
+
ok: false,
|
|
1371
|
+
error: carrierError(
|
|
1372
|
+
"carrier-lease-required",
|
|
1373
|
+
"a valid lease before started",
|
|
1374
|
+
"Lease the authenticated offer before reporting provider started.",
|
|
1375
|
+
{}
|
|
1376
|
+
)
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
state = { state: "started", leaseId };
|
|
1380
|
+
return { ok: true, value: state, state: "started" };
|
|
1381
|
+
};
|
|
1382
|
+
const exit = (leaseId) => {
|
|
1383
|
+
if (lease?.leaseId !== leaseId || state.state !== "started") {
|
|
1384
|
+
return {
|
|
1385
|
+
ok: false,
|
|
1386
|
+
error: carrierError(
|
|
1387
|
+
"carrier-lease-required",
|
|
1388
|
+
"a started lease before provider exit",
|
|
1389
|
+
"Provider exit is terminal only after started has been acknowledged.",
|
|
1390
|
+
{}
|
|
1391
|
+
)
|
|
1392
|
+
};
|
|
1393
|
+
}
|
|
1394
|
+
state = { state: "exited", leaseId };
|
|
1395
|
+
return { ok: true, value: state, state: "exited" };
|
|
1396
|
+
};
|
|
1397
|
+
const fallback = () => {
|
|
1398
|
+
if (state.state === "started" || state.state === "exited") {
|
|
1399
|
+
return {
|
|
1400
|
+
ok: false,
|
|
1401
|
+
error: carrierError(
|
|
1402
|
+
"carrier-started",
|
|
1403
|
+
"fallback to happen before provider started",
|
|
1404
|
+
"Do not retry or migrate a carrier after started; return its terminal failure.",
|
|
1405
|
+
{ state: state.state }
|
|
1406
|
+
)
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
state = { state: "fallback" };
|
|
1410
|
+
return { ok: true, value: state, state: "fallback" };
|
|
1411
|
+
};
|
|
1412
|
+
return {
|
|
1413
|
+
offer,
|
|
1414
|
+
lease: leaseOffer,
|
|
1415
|
+
started,
|
|
1416
|
+
exit,
|
|
1417
|
+
fallback,
|
|
1418
|
+
snapshot: () => state
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1045
1422
|
// src/command-tree.ts
|
|
1046
1423
|
var ToolCommandError = class extends Error {
|
|
1047
1424
|
code;
|
|
@@ -1543,6 +1920,6 @@ function createAuthenticatedLoopbackTransport(options) {
|
|
|
1543
1920
|
};
|
|
1544
1921
|
}
|
|
1545
1922
|
|
|
1546
|
-
export { CarrierTransportError, ToolCommandError, artifactIncompleteError, cancellationError, capabilityUnavailableError, cleanupError, commandPath, createArtifactManifest, createArtifactRef, createAuthenticatedCarrierTransport, createAuthenticatedLoopbackTransport, createCapabilityResolver, createCapabilityToken, createCarrierStateMachine, createExclusiveTiming, createLexicalLease, createLoopbackTransport, createMigrationRecipe, createPreviewArtifactManifest, createRealmCapabilityMatrix, createServiceCapability, createSnapshotRef, createToolCommandRegistry, createToolRuntime, defineCommand, defineTool, defineToolCapability, disconnectedError, domainFailureError, finishToolTiming, invalidArgsError, isSerializableValue, isSnapshotRef, parseToolJsonSchema, probeMigrationTarget, snapshotStaleError, startToolTiming, terminalError, terminalSnapshot, timeoutError, toolJsonSchema, validateArtifactManifest, validateArtifactRefs, validateMigrationPayload, validatePreviewArtifactManifest, validateRealmBootstrapPayload };
|
|
1923
|
+
export { CarrierTransportError, ToolCommandError, artifactIncompleteError, cancellationError, capabilityUnavailableError, cleanupError, commandPath, createArtifactManifest, createArtifactRef, createAuthenticatedCarrierTransport, createAuthenticatedLoopbackTransport, createCapabilityResolver, createCapabilityToken, createCarrierStateMachine, createExclusiveTiming, createLexicalLease, createLoopbackTransport, createMigrationRecipe, createPreviewArtifactManifest, createRealmCapabilityMatrix, createServiceCapability, createSnapshotRef, createToolApi, createToolCommandRegistry, createToolRuntime, defineCommand, defineTool, defineToolCapability, disconnectedError, domainFailureError, finishToolTiming, invalidArgsError, isSerializableValue, isSnapshotRef, parseToolJsonSchema, probeMigrationTarget, snapshotStaleError, startToolTiming, terminalError, terminalSnapshot, timeoutError, toolJsonSchema, validateArtifactManifest, validateArtifactRefs, validateMigrationPayload, validatePreviewArtifactManifest, validateRealmBootstrapPayload };
|
|
1547
1924
|
//# sourceMappingURL=index.mjs.map
|
|
1548
1925
|
//# sourceMappingURL=index.mjs.map
|