@axiom-lattice/core 6.1.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +113 -28
- package/dist/index.d.ts +113 -28
- package/dist/index.js +763 -590
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +745 -573
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -11551,8 +11551,8 @@ function readLoopBreakerConfig(env = process.env) {
|
|
|
11551
11551
|
return Math.floor(parsed);
|
|
11552
11552
|
};
|
|
11553
11553
|
return {
|
|
11554
|
-
repeatWarn: parse(env.AGENT_REPEATED_TOOL_CALL_WARN,
|
|
11555
|
-
repeatStop: parse(env.AGENT_REPEATED_TOOL_CALL_STOP,
|
|
11554
|
+
repeatWarn: parse(env.AGENT_REPEATED_TOOL_CALL_WARN, 20),
|
|
11555
|
+
repeatStop: parse(env.AGENT_REPEATED_TOOL_CALL_STOP, 25),
|
|
11556
11556
|
runLimit: parse(env.AGENT_TOOL_CALL_RUN_LIMIT, 300),
|
|
11557
11557
|
skillRunLimit: parse(env.AGENT_SKILL_CALL_RUN_LIMIT, 8)
|
|
11558
11558
|
};
|
|
@@ -11575,9 +11575,9 @@ var BREAKER_STATE_SCHEMA = z41.object({
|
|
|
11575
11575
|
repeatedToolCallMemberSignatures: z41.array(z41.string()).default([])
|
|
11576
11576
|
});
|
|
11577
11577
|
function createRepeatedToolCallBreakerMiddleware(options = {}) {
|
|
11578
|
-
const rawWarn = options.warnThreshold ??
|
|
11578
|
+
const rawWarn = options.warnThreshold ?? 20;
|
|
11579
11579
|
const warnThreshold = rawWarn > 0 ? Math.max(2, rawWarn) : 0;
|
|
11580
|
-
const stopThreshold = Math.max(1, options.stopThreshold ??
|
|
11580
|
+
const stopThreshold = Math.max(1, options.stopThreshold ?? 25);
|
|
11581
11581
|
return createMiddleware10({
|
|
11582
11582
|
name: "RepeatedToolCallBreaker",
|
|
11583
11583
|
stateSchema: BREAKER_STATE_SCHEMA,
|
|
@@ -15404,6 +15404,324 @@ function createAgentWorkerGraph() {
|
|
|
15404
15404
|
}
|
|
15405
15405
|
var agentWorkerGraph = createAgentWorkerGraph();
|
|
15406
15406
|
|
|
15407
|
+
// src/util/toJsonSafeValue.ts
|
|
15408
|
+
var CIRCULAR_VALUE = "[Circular]";
|
|
15409
|
+
var REPEATED_VALUE = "[Repeated]";
|
|
15410
|
+
var arrayFrom = Array.from.bind(Array);
|
|
15411
|
+
var arrayIsArray = Array.isArray.bind(Array);
|
|
15412
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
|
|
15413
|
+
var isPrototypeOf = Object.prototype.isPrototypeOf.call.bind(Object.prototype.isPrototypeOf);
|
|
15414
|
+
var objectCreate = Object.create.bind(Object);
|
|
15415
|
+
var objectDefineProperty = Object.defineProperty.bind(Object);
|
|
15416
|
+
var objectIs = Object.is.bind(Object);
|
|
15417
|
+
var reflectGet = Reflect.get.bind(Reflect);
|
|
15418
|
+
var reflectGetOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor.bind(Reflect);
|
|
15419
|
+
var reflectOwnKeys = Reflect.ownKeys.bind(Reflect);
|
|
15420
|
+
var stringifyJson = JSON.stringify.bind(JSON);
|
|
15421
|
+
var numberIsFinite = Number.isFinite.bind(Number);
|
|
15422
|
+
var numberIsNaN = Number.isNaN.bind(Number);
|
|
15423
|
+
var numberIsSafeInteger = Number.isSafeInteger.bind(Number);
|
|
15424
|
+
var mathMax = Math.max.bind(Math);
|
|
15425
|
+
var dateConstructor = Date;
|
|
15426
|
+
var datePrototype = dateConstructor.prototype;
|
|
15427
|
+
var dateGetTime = datePrototype.getTime.call.bind(datePrototype.getTime);
|
|
15428
|
+
var dateToISOString = datePrototype.toISOString.call.bind(datePrototype.toISOString);
|
|
15429
|
+
var bigintToString = BigInt.prototype.toString.call.bind(BigInt.prototype.toString);
|
|
15430
|
+
var stringSlice = String.prototype.slice.call.bind(String.prototype.slice);
|
|
15431
|
+
var weakMapGet = WeakMap.prototype.get.call.bind(WeakMap.prototype.get);
|
|
15432
|
+
var weakMapSet = WeakMap.prototype.set.call.bind(WeakMap.prototype.set);
|
|
15433
|
+
var WeakMapConstructor = WeakMap;
|
|
15434
|
+
var utf8Encoder = new TextEncoder();
|
|
15435
|
+
var encodeUtf8 = TextEncoder.prototype.encode.bind(utf8Encoder);
|
|
15436
|
+
var typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
|
15437
|
+
var typedArrayByteLengthGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength")?.get;
|
|
15438
|
+
if (!typedArrayByteLengthGetter) throw new Error("TypedArray byteLength getter is unavailable");
|
|
15439
|
+
var typedArrayByteLength = typedArrayByteLengthGetter.call.bind(typedArrayByteLengthGetter);
|
|
15440
|
+
var JSON_SAFE_MAX_DEPTH = 32;
|
|
15441
|
+
var JSON_SAFE_MAX_NODES = 1e4;
|
|
15442
|
+
var JSON_SAFE_MAX_COLLECTION_ENTRIES = 1e4;
|
|
15443
|
+
var JSON_SAFE_MAX_STRING_LENGTH = 64 * 1024;
|
|
15444
|
+
var JSON_SAFE_MAX_PROPERTY_KEY_LENGTH = JSON_SAFE_MAX_STRING_LENGTH;
|
|
15445
|
+
var JSON_SAFE_MAX_PROPERTY_KEY_BYTES = 256 * 1024;
|
|
15446
|
+
var JSON_SAFE_MAX_SERIALIZED_BYTES = 256 * 1024;
|
|
15447
|
+
var JsonSafeValueError = class extends Error {
|
|
15448
|
+
/**
|
|
15449
|
+
* Create a bounded normalization error.
|
|
15450
|
+
*
|
|
15451
|
+
* @param code Stable normalization failure code.
|
|
15452
|
+
* @param message Human-readable bounded failure description.
|
|
15453
|
+
*/
|
|
15454
|
+
constructor(code, message) {
|
|
15455
|
+
super(message);
|
|
15456
|
+
objectDefineProperty(this, "name", {
|
|
15457
|
+
value: "JsonSafeValueError",
|
|
15458
|
+
writable: true,
|
|
15459
|
+
configurable: true
|
|
15460
|
+
});
|
|
15461
|
+
objectDefineProperty(this, "code", {
|
|
15462
|
+
value: code,
|
|
15463
|
+
writable: true,
|
|
15464
|
+
configurable: true
|
|
15465
|
+
});
|
|
15466
|
+
}
|
|
15467
|
+
};
|
|
15468
|
+
function fail(code, message) {
|
|
15469
|
+
throw new JsonSafeValueError(code, message);
|
|
15470
|
+
}
|
|
15471
|
+
function propertyAccess(operation, path8) {
|
|
15472
|
+
try {
|
|
15473
|
+
return operation();
|
|
15474
|
+
} catch {
|
|
15475
|
+
fail("PROPERTY_ACCESS_FAILED", `Unable to inspect JSON-safe value at ${path8}`);
|
|
15476
|
+
}
|
|
15477
|
+
}
|
|
15478
|
+
function serializedStringBytes(value) {
|
|
15479
|
+
if (value.length > JSON_SAFE_MAX_STRING_LENGTH) {
|
|
15480
|
+
fail("MAX_STRING_LENGTH", `JSON-safe string exceeds ${JSON_SAFE_MAX_STRING_LENGTH} characters`);
|
|
15481
|
+
}
|
|
15482
|
+
return typedArrayByteLength(encodeUtf8(stringifyJson(value)));
|
|
15483
|
+
}
|
|
15484
|
+
function validatePropertyKey(key5) {
|
|
15485
|
+
if (key5.length > JSON_SAFE_MAX_PROPERTY_KEY_LENGTH) {
|
|
15486
|
+
fail(
|
|
15487
|
+
"MAX_STRING_LENGTH",
|
|
15488
|
+
`JSON-safe property key exceeds ${JSON_SAFE_MAX_PROPERTY_KEY_LENGTH} characters`
|
|
15489
|
+
);
|
|
15490
|
+
}
|
|
15491
|
+
}
|
|
15492
|
+
function chargePropertyKey(state, key5) {
|
|
15493
|
+
state.propertyKeyBytes += typedArrayByteLength(encodeUtf8(key5));
|
|
15494
|
+
if (state.propertyKeyBytes > JSON_SAFE_MAX_PROPERTY_KEY_BYTES) {
|
|
15495
|
+
fail(
|
|
15496
|
+
"MAX_PROPERTY_KEY_BYTES",
|
|
15497
|
+
`JSON-safe property keys exceed ${JSON_SAFE_MAX_PROPERTY_KEY_BYTES} traversed UTF-8 bytes`
|
|
15498
|
+
);
|
|
15499
|
+
}
|
|
15500
|
+
}
|
|
15501
|
+
function chargeBytes(state, bytes) {
|
|
15502
|
+
state.serializedBytes += bytes;
|
|
15503
|
+
if (state.serializedBytes > JSON_SAFE_MAX_SERIALIZED_BYTES) {
|
|
15504
|
+
fail(
|
|
15505
|
+
"MAX_SERIALIZED_BYTES",
|
|
15506
|
+
`JSON-safe value exceeds ${JSON_SAFE_MAX_SERIALIZED_BYTES} serialized bytes`
|
|
15507
|
+
);
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15510
|
+
function chargeString(state, value) {
|
|
15511
|
+
chargeBytes(state, serializedStringBytes(value));
|
|
15512
|
+
}
|
|
15513
|
+
function objectPropertyPath(path8, key5) {
|
|
15514
|
+
const boundedKey = key5.length > 128 ? `${stringSlice(key5, 0, 128)}...` : key5;
|
|
15515
|
+
return `${path8}[${stringifyJson(boundedKey)}]`;
|
|
15516
|
+
}
|
|
15517
|
+
function convertJsonValue(value, state, depth, inArray, path8) {
|
|
15518
|
+
state.nodes += 1;
|
|
15519
|
+
if (state.nodes > JSON_SAFE_MAX_NODES) {
|
|
15520
|
+
fail("MAX_NODES", `JSON-safe value exceeds ${JSON_SAFE_MAX_NODES} total nodes`);
|
|
15521
|
+
}
|
|
15522
|
+
if (typeof value === "string") {
|
|
15523
|
+
chargeString(state, value);
|
|
15524
|
+
return value;
|
|
15525
|
+
}
|
|
15526
|
+
if (value === null) {
|
|
15527
|
+
chargeBytes(state, 4);
|
|
15528
|
+
return value;
|
|
15529
|
+
}
|
|
15530
|
+
if (typeof value === "boolean") {
|
|
15531
|
+
chargeBytes(state, value ? 4 : 5);
|
|
15532
|
+
return value;
|
|
15533
|
+
}
|
|
15534
|
+
if (typeof value === "number") {
|
|
15535
|
+
const normalized = numberIsFinite(value) ? objectIs(value, -0) ? 0 : value : null;
|
|
15536
|
+
chargeBytes(state, normalized === null ? 4 : stringifyJson(normalized).length);
|
|
15537
|
+
return normalized;
|
|
15538
|
+
}
|
|
15539
|
+
if (typeof value === "bigint") {
|
|
15540
|
+
const normalized = bigintToString(value);
|
|
15541
|
+
chargeString(state, normalized);
|
|
15542
|
+
return normalized;
|
|
15543
|
+
}
|
|
15544
|
+
if (typeof value === "undefined" || typeof value === "function" || typeof value === "symbol") {
|
|
15545
|
+
if (inArray) chargeBytes(state, 4);
|
|
15546
|
+
return inArray ? null : void 0;
|
|
15547
|
+
}
|
|
15548
|
+
const isDate = propertyAccess(() => isPrototypeOf(datePrototype, value), path8);
|
|
15549
|
+
if (isDate) {
|
|
15550
|
+
const time = propertyAccess(() => dateGetTime(value), path8);
|
|
15551
|
+
if (numberIsNaN(time)) {
|
|
15552
|
+
chargeBytes(state, 4);
|
|
15553
|
+
return null;
|
|
15554
|
+
}
|
|
15555
|
+
const normalized = propertyAccess(() => dateToISOString(value), path8);
|
|
15556
|
+
chargeString(state, normalized);
|
|
15557
|
+
return normalized;
|
|
15558
|
+
}
|
|
15559
|
+
if (depth > JSON_SAFE_MAX_DEPTH) {
|
|
15560
|
+
fail("MAX_DEPTH", `JSON-safe value exceeds maximum depth ${JSON_SAFE_MAX_DEPTH}`);
|
|
15561
|
+
}
|
|
15562
|
+
const referenceState = weakMapGet(state.references, value);
|
|
15563
|
+
if (referenceState === "visiting") {
|
|
15564
|
+
chargeString(state, CIRCULAR_VALUE);
|
|
15565
|
+
return CIRCULAR_VALUE;
|
|
15566
|
+
}
|
|
15567
|
+
if (referenceState === "visited") {
|
|
15568
|
+
chargeString(state, REPEATED_VALUE);
|
|
15569
|
+
return REPEATED_VALUE;
|
|
15570
|
+
}
|
|
15571
|
+
weakMapSet(state.references, value, "visiting");
|
|
15572
|
+
if (propertyAccess(() => arrayIsArray(value), path8)) {
|
|
15573
|
+
const arrayValue = value;
|
|
15574
|
+
const length = propertyAccess(
|
|
15575
|
+
() => arrayValue.length,
|
|
15576
|
+
path8
|
|
15577
|
+
);
|
|
15578
|
+
if (typeof length !== "number" || !numberIsSafeInteger(length) || length < 0) {
|
|
15579
|
+
fail("PROPERTY_ACCESS_FAILED", `Unable to inspect JSON-safe array length at ${path8}`);
|
|
15580
|
+
}
|
|
15581
|
+
if (length > JSON_SAFE_MAX_COLLECTION_ENTRIES) {
|
|
15582
|
+
fail(
|
|
15583
|
+
"COLLECTION_TOO_LARGE",
|
|
15584
|
+
`JSON-safe array exceeds ${JSON_SAFE_MAX_COLLECTION_ENTRIES} entries`
|
|
15585
|
+
);
|
|
15586
|
+
}
|
|
15587
|
+
chargeBytes(state, 2 + mathMax(0, length - 1));
|
|
15588
|
+
const result2 = arrayFrom({ length }, (_, index) => {
|
|
15589
|
+
const entryPath = `${path8}[${index}]`;
|
|
15590
|
+
const hasEntry = propertyAccess(
|
|
15591
|
+
() => hasOwnProperty(arrayValue, index),
|
|
15592
|
+
entryPath
|
|
15593
|
+
);
|
|
15594
|
+
if (!hasEntry) {
|
|
15595
|
+
chargeBytes(state, 4);
|
|
15596
|
+
return null;
|
|
15597
|
+
}
|
|
15598
|
+
const entry = propertyAccess(() => arrayValue[index], entryPath);
|
|
15599
|
+
return convertJsonValue(entry, state, depth + 1, true, `${path8}[${index}]`);
|
|
15600
|
+
});
|
|
15601
|
+
objectDefineProperty(result2, "toJSON", {
|
|
15602
|
+
value: void 0,
|
|
15603
|
+
configurable: true,
|
|
15604
|
+
writable: true
|
|
15605
|
+
});
|
|
15606
|
+
weakMapSet(state.references, value, "visited");
|
|
15607
|
+
return result2;
|
|
15608
|
+
}
|
|
15609
|
+
const keys = propertyAccess(() => reflectOwnKeys(value), path8);
|
|
15610
|
+
if (keys.length > JSON_SAFE_MAX_COLLECTION_ENTRIES) {
|
|
15611
|
+
fail(
|
|
15612
|
+
"COLLECTION_TOO_LARGE",
|
|
15613
|
+
`JSON-safe object exceeds ${JSON_SAFE_MAX_COLLECTION_ENTRIES} own keys`
|
|
15614
|
+
);
|
|
15615
|
+
}
|
|
15616
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
15617
|
+
const key5 = keys[index];
|
|
15618
|
+
if (typeof key5 !== "string") continue;
|
|
15619
|
+
validatePropertyKey(key5);
|
|
15620
|
+
chargePropertyKey(state, key5);
|
|
15621
|
+
}
|
|
15622
|
+
chargeBytes(state, 2);
|
|
15623
|
+
const result = objectCreate(null);
|
|
15624
|
+
let emittedProperties = 0;
|
|
15625
|
+
for (let index = 0; index < keys.length; index += 1) {
|
|
15626
|
+
const key5 = keys[index];
|
|
15627
|
+
const entryPath = typeof key5 === "string" ? objectPropertyPath(path8, key5) : path8;
|
|
15628
|
+
const descriptor = propertyAccess(
|
|
15629
|
+
() => reflectGetOwnPropertyDescriptor(value, key5),
|
|
15630
|
+
entryPath
|
|
15631
|
+
);
|
|
15632
|
+
if (typeof key5 !== "string" || !descriptor?.enumerable) continue;
|
|
15633
|
+
const entry = propertyAccess(() => reflectGet(value, key5), entryPath);
|
|
15634
|
+
const converted = convertJsonValue(entry, state, depth + 1, false, entryPath);
|
|
15635
|
+
if (converted !== void 0) {
|
|
15636
|
+
chargeBytes(state, serializedStringBytes(key5) + 1 + (emittedProperties === 0 ? 0 : 1));
|
|
15637
|
+
propertyAccess(() => objectDefineProperty(result, key5, {
|
|
15638
|
+
value: converted,
|
|
15639
|
+
enumerable: true,
|
|
15640
|
+
configurable: true,
|
|
15641
|
+
writable: true
|
|
15642
|
+
}), entryPath);
|
|
15643
|
+
emittedProperties += 1;
|
|
15644
|
+
}
|
|
15645
|
+
}
|
|
15646
|
+
weakMapSet(state.references, value, "visited");
|
|
15647
|
+
return result;
|
|
15648
|
+
}
|
|
15649
|
+
function toJsonSafeValue(value) {
|
|
15650
|
+
const state = {
|
|
15651
|
+
nodes: 0,
|
|
15652
|
+
propertyKeyBytes: 0,
|
|
15653
|
+
serializedBytes: 0,
|
|
15654
|
+
references: new WeakMapConstructor()
|
|
15655
|
+
};
|
|
15656
|
+
const converted = convertJsonValue(value, state, 0, false, "$");
|
|
15657
|
+
if (converted === void 0) chargeBytes(state, 4);
|
|
15658
|
+
const result = converted ?? null;
|
|
15659
|
+
const serialized = propertyAccess(() => stringifyJson(result), "$");
|
|
15660
|
+
if (typedArrayByteLength(encodeUtf8(serialized)) > JSON_SAFE_MAX_SERIALIZED_BYTES) {
|
|
15661
|
+
fail(
|
|
15662
|
+
"MAX_SERIALIZED_BYTES",
|
|
15663
|
+
`JSON-safe value exceeds ${JSON_SAFE_MAX_SERIALIZED_BYTES} serialized bytes`
|
|
15664
|
+
);
|
|
15665
|
+
}
|
|
15666
|
+
return result;
|
|
15667
|
+
}
|
|
15668
|
+
|
|
15669
|
+
// src/util/truncateForJson.ts
|
|
15670
|
+
var TRUNCATION_MARKER = "...[truncated]";
|
|
15671
|
+
function truncateString(value, cap) {
|
|
15672
|
+
if (value.length <= cap) return value;
|
|
15673
|
+
const budget = Math.max(0, cap - TRUNCATION_MARKER.length);
|
|
15674
|
+
return value.slice(0, budget) + TRUNCATION_MARKER;
|
|
15675
|
+
}
|
|
15676
|
+
function truncateValue(value, depth, maxDepth, maxEntries, maxStringLength, seen) {
|
|
15677
|
+
if (typeof value === "string") return truncateString(value, maxStringLength);
|
|
15678
|
+
if (value === null || typeof value !== "object") return value;
|
|
15679
|
+
if (depth >= maxDepth) return "[truncated:max-depth]";
|
|
15680
|
+
if (seen.has(value)) return "[Circular]";
|
|
15681
|
+
seen.add(value);
|
|
15682
|
+
try {
|
|
15683
|
+
if (value instanceof Date) return value.toISOString();
|
|
15684
|
+
if (Array.isArray(value)) {
|
|
15685
|
+
const limit2 = Math.min(value.length, maxEntries);
|
|
15686
|
+
const output2 = [];
|
|
15687
|
+
for (let index = 0; index < limit2; index += 1) {
|
|
15688
|
+
output2.push(truncateValue(value[index], depth + 1, maxDepth, maxEntries, maxStringLength, seen));
|
|
15689
|
+
}
|
|
15690
|
+
if (value.length > limit2) output2.push("[truncated:entries]");
|
|
15691
|
+
return output2;
|
|
15692
|
+
}
|
|
15693
|
+
const record = value;
|
|
15694
|
+
const output = {};
|
|
15695
|
+
const keys = Object.keys(record);
|
|
15696
|
+
const limit = Math.min(keys.length, maxEntries);
|
|
15697
|
+
for (let index = 0; index < limit; index += 1) {
|
|
15698
|
+
const key5 = keys[index];
|
|
15699
|
+
output[truncateString(key5, maxStringLength)] = truncateValue(
|
|
15700
|
+
record[key5],
|
|
15701
|
+
depth + 1,
|
|
15702
|
+
maxDepth,
|
|
15703
|
+
maxEntries,
|
|
15704
|
+
maxStringLength,
|
|
15705
|
+
seen
|
|
15706
|
+
);
|
|
15707
|
+
}
|
|
15708
|
+
if (keys.length > limit) output["[truncated]"] = true;
|
|
15709
|
+
return output;
|
|
15710
|
+
} finally {
|
|
15711
|
+
seen.delete(value);
|
|
15712
|
+
}
|
|
15713
|
+
}
|
|
15714
|
+
function truncateForJson(value, options = {}) {
|
|
15715
|
+
return truncateValue(
|
|
15716
|
+
value,
|
|
15717
|
+
0,
|
|
15718
|
+
options.maxDepth ?? JSON_SAFE_MAX_DEPTH,
|
|
15719
|
+
options.maxEntries ?? JSON_SAFE_MAX_COLLECTION_ENTRIES,
|
|
15720
|
+
options.maxStringLength ?? JSON_SAFE_MAX_STRING_LENGTH,
|
|
15721
|
+
/* @__PURE__ */ new WeakSet()
|
|
15722
|
+
);
|
|
15723
|
+
}
|
|
15724
|
+
|
|
15407
15725
|
// src/services/Agent.ts
|
|
15408
15726
|
import { descriptorDataValue } from "@axiom-lattice/protocols";
|
|
15409
15727
|
import { Command as Command2 } from "@langchain/langgraph";
|
|
@@ -16945,6 +17263,27 @@ function statusFromSnapshot(state) {
|
|
|
16945
17263
|
if (Array.isArray(state.next) && state.next.length > 0) return "busy" /* BUSY */;
|
|
16946
17264
|
return "idle" /* IDLE */;
|
|
16947
17265
|
}
|
|
17266
|
+
var MAX_EXECUTION_ERROR_LENGTH = 2e3;
|
|
17267
|
+
function executionErrorFromSnapshot(state) {
|
|
17268
|
+
if (!isPlainRecord(state) || !Array.isArray(state.tasks)) return void 0;
|
|
17269
|
+
for (const task of state.tasks) {
|
|
17270
|
+
if (!isPlainRecord(task) || task.error === void 0 || task.error === null) continue;
|
|
17271
|
+
const raw = task.error;
|
|
17272
|
+
const message = typeof raw === "string" ? raw : raw instanceof Error ? raw.message : isPlainRecord(raw) && typeof raw.message === "string" ? raw.message : (() => {
|
|
17273
|
+
try {
|
|
17274
|
+
return JSON.stringify(raw);
|
|
17275
|
+
} catch {
|
|
17276
|
+
return String(raw);
|
|
17277
|
+
}
|
|
17278
|
+
})();
|
|
17279
|
+
if (typeof message !== "string") continue;
|
|
17280
|
+
const trimmed = message.trim();
|
|
17281
|
+
if (trimmed.length === 0) continue;
|
|
17282
|
+
const bounded = truncateForJson(trimmed, { maxStringLength: MAX_EXECUTION_ERROR_LENGTH });
|
|
17283
|
+
if (typeof bounded === "string" && bounded.length > 0) return bounded;
|
|
17284
|
+
}
|
|
17285
|
+
return void 0;
|
|
17286
|
+
}
|
|
16948
17287
|
function freshReply(state, preRunMarker, inputMessageId, consumedInputMessageIds) {
|
|
16949
17288
|
const output = finalAiMessageMarker(state);
|
|
16950
17289
|
if (output?.text === void 0 || output.index <= (preRunMarker?.index ?? -1) || output.totalMessageCount <= (preRunMarker?.totalMessageCount ?? 0)) return void 0;
|
|
@@ -17224,7 +17563,7 @@ var Agent = class {
|
|
|
17224
17563
|
state
|
|
17225
17564
|
});
|
|
17226
17565
|
} else if (runStatus === "error" /* ERROR */) {
|
|
17227
|
-
const failureReason = "Agent execution ended in an error state";
|
|
17566
|
+
const failureReason = executionErrorFromSnapshot(state) ?? "Agent execution ended in an error state";
|
|
17228
17567
|
this.addChunk({
|
|
17229
17568
|
type: "message_failed",
|
|
17230
17569
|
data: { id: humanContent.id, content: failureReason }
|
|
@@ -17337,7 +17676,7 @@ var Agent = class {
|
|
|
17337
17676
|
}
|
|
17338
17677
|
if (runStatus === "busy" /* BUSY */) return;
|
|
17339
17678
|
if (runStatus === "error" /* ERROR */) {
|
|
17340
|
-
const failureReason = "Agent execution ended in an error state";
|
|
17679
|
+
const failureReason = executionErrorFromSnapshot(state) ?? "Agent execution ended in an error state";
|
|
17341
17680
|
for (const p of collectPendings) {
|
|
17342
17681
|
const messageId = p.content.id;
|
|
17343
17682
|
this.addChunk({
|
|
@@ -17438,7 +17777,7 @@ var Agent = class {
|
|
|
17438
17777
|
});
|
|
17439
17778
|
if (p.execution_mode === "followup") return;
|
|
17440
17779
|
} else if (runStatus === "error" /* ERROR */) {
|
|
17441
|
-
const failureReason = "Agent execution ended in an error state";
|
|
17780
|
+
const failureReason = executionErrorFromSnapshot(state) ?? "Agent execution ended in an error state";
|
|
17442
17781
|
this.addChunk({
|
|
17443
17782
|
type: "message_failed",
|
|
17444
17783
|
data: { id: humanContent.id, content: failureReason }
|
|
@@ -17745,12 +18084,17 @@ var Agent = class {
|
|
|
17745
18084
|
capabilityRuntimeRevision: capabilityRuntime.revision,
|
|
17746
18085
|
tenantId: this.tenant_id,
|
|
17747
18086
|
workspaceId: this.workspace_id,
|
|
17748
|
-
|
|
18087
|
+
// The propagated project scope must not fabricate `"default"`:
|
|
18088
|
+
// `queue_project_id` is `null` when the run had no project, so an unscoped
|
|
18089
|
+
// run stays unscoped instead of later querying a project that may not
|
|
18090
|
+
// exist. An explicitly passed `"default"` is a real project for some
|
|
18091
|
+
// tenants and is preserved.
|
|
18092
|
+
projectId: this.queue_project_id ?? void 0,
|
|
17749
18093
|
assistant_id: this.assistant_id,
|
|
17750
18094
|
thread_id: this.thread_id,
|
|
17751
18095
|
"x-tenant-id": this.tenant_id,
|
|
17752
18096
|
"x-workspace-id": this.workspace_id,
|
|
17753
|
-
"x-project-id": this.
|
|
18097
|
+
"x-project-id": this.queue_project_id ?? void 0,
|
|
17754
18098
|
"x-thread-id": this.thread_id,
|
|
17755
18099
|
"x-assistant-id": this.assistant_id
|
|
17756
18100
|
};
|
|
@@ -18095,7 +18439,15 @@ var Agent = class {
|
|
|
18095
18439
|
if (!accepted) throw new Error(`Queue is full (max ${maxSize} messages)`);
|
|
18096
18440
|
if (useMode === "steer" /* STEER */ && !queueMessage.command) {
|
|
18097
18441
|
this.stopQueueProcessor();
|
|
18098
|
-
|
|
18442
|
+
let runStatus;
|
|
18443
|
+
try {
|
|
18444
|
+
runStatus = await this.getRunStatus();
|
|
18445
|
+
} catch {
|
|
18446
|
+
runStatus = void 0;
|
|
18447
|
+
}
|
|
18448
|
+
if (runStatus !== "interrupted" /* INTERRUPTED */) {
|
|
18449
|
+
await store.resetProcessingToPending(this.thread_id, this.queueScope());
|
|
18450
|
+
}
|
|
18099
18451
|
console.log(`[Agent] STEER mode: stopped current processing, reset queue, message ${messageId} will execute next`);
|
|
18100
18452
|
}
|
|
18101
18453
|
} else {
|
|
@@ -18411,7 +18763,7 @@ var Agent = class {
|
|
|
18411
18763
|
}
|
|
18412
18764
|
} else if (resumedStatus === "error" /* ERROR */) {
|
|
18413
18765
|
this.clearRecoveryBlock();
|
|
18414
|
-
const failureReason = "Agent execution ended in an error state";
|
|
18766
|
+
const failureReason = executionErrorFromSnapshot(state) ?? "Agent execution ended in an error state";
|
|
18415
18767
|
for (const msg of processingMessages) {
|
|
18416
18768
|
this.addChunk({ type: "message_failed", data: { id: msg.id, content: failureReason } });
|
|
18417
18769
|
this.publish("message:failed", {
|
|
@@ -18447,7 +18799,7 @@ var Agent = class {
|
|
|
18447
18799
|
} else if (runStatus === "error" /* ERROR */) {
|
|
18448
18800
|
this.processingExecutionContext(processingMessages);
|
|
18449
18801
|
this.clearRecoveryBlock();
|
|
18450
|
-
const failureReason = "Agent execution ended in an error state";
|
|
18802
|
+
const failureReason = executionErrorFromSnapshot(preRunState) ?? "Agent execution ended in an error state";
|
|
18451
18803
|
for (const msg of processingMessages) {
|
|
18452
18804
|
this.addChunk({ type: "message_failed", data: { id: msg.id, content: failureReason } });
|
|
18453
18805
|
this.publish("message:failed", {
|
|
@@ -18593,8 +18945,19 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
18593
18945
|
}
|
|
18594
18946
|
return _AgentInstanceManager._instance;
|
|
18595
18947
|
}
|
|
18948
|
+
/**
|
|
18949
|
+
* A thread's identity is `(tenant_id, assistant_id, thread_id)`.
|
|
18950
|
+
*
|
|
18951
|
+
* Workspace/project are execution scope chosen when the instance is created,
|
|
18952
|
+
* not part of identity: including them let the same thread exist as several
|
|
18953
|
+
* Agents when callers defaulted optional workspace/project headers
|
|
18954
|
+
* differently (e.g. `createRun` passing `undefined` while `abort` defaulted
|
|
18955
|
+
* to `"default"`), so control-plane calls could address a different instance
|
|
18956
|
+
* than the one running. `undefined`/`null` normalize to `""`; ids are assumed
|
|
18957
|
+
* not to contain `:` (UUID-shaped in practice).
|
|
18958
|
+
*/
|
|
18596
18959
|
getKey(params) {
|
|
18597
|
-
return
|
|
18960
|
+
return [params.tenant_id, params.assistant_id, params.thread_id].map((value) => value ?? "").join(":");
|
|
18598
18961
|
}
|
|
18599
18962
|
/**
|
|
18600
18963
|
* Get or create Agent instance for a thread
|
|
@@ -18608,6 +18971,24 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
18608
18971
|
}
|
|
18609
18972
|
return this.agents.get(key5);
|
|
18610
18973
|
}
|
|
18974
|
+
/**
|
|
18975
|
+
* Get the managed Agent for a thread WITHOUT creating or registering one.
|
|
18976
|
+
*
|
|
18977
|
+
* Read-only control-plane callers (state, memory, inbox) must not be the first
|
|
18978
|
+
* to establish a thread's execution scope: since identity is
|
|
18979
|
+
* `(tenant_id, assistant_id, thread_id)`, whichever caller reaches
|
|
18980
|
+
* {@link getAgent} first fixes the instance's workspace/project for its whole
|
|
18981
|
+
* lifetime, and a later trusted dispatch on that thread would then fail
|
|
18982
|
+
* trusted-scope validation. This returns the existing managed instance when
|
|
18983
|
+
* present, otherwise a transient unregistered Agent that is sufficient for
|
|
18984
|
+
* state reads and disappears with the request.
|
|
18985
|
+
*
|
|
18986
|
+
* @param params - Thread identity; scope is only used for the transient Agent.
|
|
18987
|
+
* @returns The managed instance if any, else an unregistered read-only Agent.
|
|
18988
|
+
*/
|
|
18989
|
+
getAgentForRead(params) {
|
|
18990
|
+
return this.agents.get(this.getKey(params)) ?? new Agent(params);
|
|
18991
|
+
}
|
|
18611
18992
|
/**
|
|
18612
18993
|
* Check if an agent instance exists for the thread
|
|
18613
18994
|
*/
|
|
@@ -18643,55 +19024,6 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
18643
19024
|
});
|
|
18644
19025
|
this.agents.clear();
|
|
18645
19026
|
}
|
|
18646
|
-
/**
|
|
18647
|
-
* Restore agent instances for threads with pending messages after server restart
|
|
18648
|
-
* Queries the message queue store for threads with pending/processing messages
|
|
18649
|
-
* and recreates agent instances to resume processing
|
|
18650
|
-
*/
|
|
18651
|
-
async restore() {
|
|
18652
|
-
const stats = { restored: 0, errors: 0 };
|
|
18653
|
-
try {
|
|
18654
|
-
const queueStoreLattice = storeLatticeManager.getStoreLattice("default", "threadMessageQueue");
|
|
18655
|
-
const queueStore = queueStoreLattice.store;
|
|
18656
|
-
const threadsWithPending = await queueStore.getThreadsWithPendingMessages();
|
|
18657
|
-
if (threadsWithPending.length === 0) {
|
|
18658
|
-
console.log("[AgentInstanceManager] No threads with pending messages found");
|
|
18659
|
-
return stats;
|
|
18660
|
-
}
|
|
18661
|
-
console.log(`[AgentInstanceManager] Found ${threadsWithPending.length} threads with pending messages, restoring...`);
|
|
18662
|
-
for (const threadInfo of threadsWithPending) {
|
|
18663
|
-
try {
|
|
18664
|
-
await this.restoreThread(threadInfo);
|
|
18665
|
-
stats.restored++;
|
|
18666
|
-
} catch (error) {
|
|
18667
|
-
console.error(`[AgentInstanceManager] Failed to restore thread ${threadInfo.threadId}:`, error);
|
|
18668
|
-
stats.errors++;
|
|
18669
|
-
}
|
|
18670
|
-
}
|
|
18671
|
-
console.log(`[AgentInstanceManager] Restore complete: ${stats.restored} restored, ${stats.errors} errors`);
|
|
18672
|
-
return stats;
|
|
18673
|
-
} catch (error) {
|
|
18674
|
-
console.error("[AgentInstanceManager] Restore failed:", error);
|
|
18675
|
-
throw error;
|
|
18676
|
-
}
|
|
18677
|
-
}
|
|
18678
|
-
/**
|
|
18679
|
-
* Restore a single thread
|
|
18680
|
-
* Delegates actual recovery logic to Agent.resumeTask()
|
|
18681
|
-
*/
|
|
18682
|
-
async restoreThread(threadInfo) {
|
|
18683
|
-
const { tenantId: tenantId2, assistantId, threadId, workspaceId, projectId } = threadInfo;
|
|
18684
|
-
const threadParams = {
|
|
18685
|
-
tenant_id: tenantId2,
|
|
18686
|
-
assistant_id: assistantId,
|
|
18687
|
-
thread_id: threadId,
|
|
18688
|
-
workspace_id: workspaceId,
|
|
18689
|
-
project_id: projectId
|
|
18690
|
-
};
|
|
18691
|
-
const agent = this.getAgent(threadParams);
|
|
18692
|
-
await agent.resumeTask();
|
|
18693
|
-
console.log(`[AgentInstanceManager] Restored thread ${threadId}`);
|
|
18694
|
-
}
|
|
18695
19027
|
};
|
|
18696
19028
|
var agentInstanceManager = AgentInstanceManager.getInstance();
|
|
18697
19029
|
|
|
@@ -35687,6 +36019,8 @@ function buildParentBeliefActivity(input) {
|
|
|
35687
36019
|
}
|
|
35688
36020
|
|
|
35689
36021
|
// src/services/TaskLifecycleService.ts
|
|
36022
|
+
var WORK_ITEM_WRITE_ATTEMPTS = 3;
|
|
36023
|
+
var WORK_ITEM_WRITE_RETRY_DELAYS_MS = [20, 50];
|
|
35690
36024
|
var RETRYABLE_LIFECYCLE_CODES = /* @__PURE__ */ new Set([
|
|
35691
36025
|
"TASK_STATUS_CONFLICT",
|
|
35692
36026
|
"TASK_STORE_WRITE_FAILED",
|
|
@@ -36053,7 +36387,8 @@ var TaskLifecycleService = class {
|
|
|
36053
36387
|
const resumeKey = this.resumeEventKey(task);
|
|
36054
36388
|
const audit = { eventKey: resumeKey, previousInterruption };
|
|
36055
36389
|
const context = withLifecycleAudit(task.context, "lifecycle_resume_audit", audit);
|
|
36056
|
-
if (input.threadId
|
|
36390
|
+
if (input.threadId) context.thread_id = input.threadId;
|
|
36391
|
+
if (input.runId) context.run_id = input.runId;
|
|
36057
36392
|
const updated = await this.deps.taskStore.updateIfStatusAndUpdatedAt(
|
|
36058
36393
|
input.tenantId,
|
|
36059
36394
|
input.taskId,
|
|
@@ -36150,7 +36485,13 @@ var TaskLifecycleService = class {
|
|
|
36150
36485
|
if (task.status !== "pending") {
|
|
36151
36486
|
return { ...failure2("TASK_STATUS_CONFLICT", "Task cannot start."), transitioned: false };
|
|
36152
36487
|
}
|
|
36153
|
-
const context = {
|
|
36488
|
+
const context = {
|
|
36489
|
+
...task.context ?? {},
|
|
36490
|
+
...input.threadId ? { thread_id: input.threadId } : {},
|
|
36491
|
+
...input.runId ? { run_id: input.runId } : {},
|
|
36492
|
+
...input.callerThreadId ? { caller_thread_id: input.callerThreadId } : {},
|
|
36493
|
+
...input.callerAssistantId ? { caller_assistant_id: input.callerAssistantId } : {}
|
|
36494
|
+
};
|
|
36154
36495
|
let updated;
|
|
36155
36496
|
try {
|
|
36156
36497
|
updated = await this.deps.taskStore.updateIfStatusAndUpdatedAt(
|
|
@@ -36226,7 +36567,9 @@ var TaskLifecycleService = class {
|
|
|
36226
36567
|
expectedStatuses: ["failed"],
|
|
36227
36568
|
updates: { status: "in_progress", failureReason: null },
|
|
36228
36569
|
summary: "Task retried",
|
|
36229
|
-
detail: { previousStatus: "failed" }
|
|
36570
|
+
detail: { previousStatus: "failed" },
|
|
36571
|
+
// A retry dispatches a new run thread; replace a stale persisted link.
|
|
36572
|
+
replaceThread: true
|
|
36230
36573
|
});
|
|
36231
36574
|
}
|
|
36232
36575
|
/**
|
|
@@ -37712,7 +38055,9 @@ var TaskLifecycleService = class {
|
|
|
37712
38055
|
}
|
|
37713
38056
|
if (!input.expectedStatuses.includes(task.status)) return failure2("TASK_STATUS_CONFLICT", "Task status cannot make this transition.");
|
|
37714
38057
|
const clearedContext = clearInterruptionContext(task.context);
|
|
37715
|
-
const
|
|
38058
|
+
const threadInput = input.threadId && (input.replaceThread || task.context?.thread_id === void 0) ? { thread_id: input.threadId } : {};
|
|
38059
|
+
const runInput = input.runId ? { run_id: input.runId } : {};
|
|
38060
|
+
const withThread = Object.keys(threadInput).length > 0 || Object.keys(runInput).length > 0 ? { ...clearedContext ?? {}, ...threadInput, ...runInput } : clearedContext;
|
|
37716
38061
|
const updates = { ...input.updates, context: withThread };
|
|
37717
38062
|
let updated;
|
|
37718
38063
|
try {
|
|
@@ -37750,6 +38095,31 @@ var TaskLifecycleService = class {
|
|
|
37750
38095
|
statusEventKey(task, status, detail) {
|
|
37751
38096
|
return `task-lifecycle:${task.id}:${status}:${task.updatedAt.toISOString()}:${sha256(detail)}`;
|
|
37752
38097
|
}
|
|
38098
|
+
/**
|
|
38099
|
+
* Writes a lifecycle work-item event, retrying transient store failures.
|
|
38100
|
+
*
|
|
38101
|
+
* @param request Event request passed through to the work-item store.
|
|
38102
|
+
* @returns The persisted or pre-existing work item.
|
|
38103
|
+
* @remarks The write is idempotent by `eventKey`
|
|
38104
|
+
* (`createIfAbsentByEventKey`), so retrying after a transient failure (pool
|
|
38105
|
+
* exhaustion, shutdown, statement timeout, disk IO) is safe. The status CAS has
|
|
38106
|
+
* already committed by this point, and the event key embeds `updatedAt`, so a
|
|
38107
|
+
* lost event cannot be reconstructed later — hence the bounded retry.
|
|
38108
|
+
*/
|
|
38109
|
+
async writeWorkItemWithRetry(request) {
|
|
38110
|
+
let lastError;
|
|
38111
|
+
for (let attempt = 0; attempt < WORK_ITEM_WRITE_ATTEMPTS; attempt += 1) {
|
|
38112
|
+
if (attempt > 0) {
|
|
38113
|
+
await new Promise((resolve4) => setTimeout(resolve4, WORK_ITEM_WRITE_RETRY_DELAYS_MS[attempt - 1]));
|
|
38114
|
+
}
|
|
38115
|
+
try {
|
|
38116
|
+
return await this.deps.workItemStore.createIfAbsentByEventKey(request);
|
|
38117
|
+
} catch (error) {
|
|
38118
|
+
lastError = error;
|
|
38119
|
+
}
|
|
38120
|
+
}
|
|
38121
|
+
throw lastError;
|
|
38122
|
+
}
|
|
37753
38123
|
async writeStatusEvent(task, actor, threadId, action, summary, detail, eventKey) {
|
|
37754
38124
|
const warningCode = `${action.toUpperCase()}_WORK_ITEM_WRITE_FAILED`;
|
|
37755
38125
|
const request = {
|
|
@@ -37765,7 +38135,7 @@ var TaskLifecycleService = class {
|
|
|
37765
38135
|
eventKey
|
|
37766
38136
|
};
|
|
37767
38137
|
try {
|
|
37768
|
-
const item = await this.
|
|
38138
|
+
const item = await this.writeWorkItemWithRetry(request);
|
|
37769
38139
|
if (item.eventKey !== request.eventKey) throw new Error("Canonical lifecycle event key mismatch");
|
|
37770
38140
|
return { eventKey: item.eventKey };
|
|
37771
38141
|
} catch {
|
|
@@ -37951,7 +38321,7 @@ function createTaskRunBridge(deps) {
|
|
|
37951
38321
|
return { success: true, task: updated };
|
|
37952
38322
|
},
|
|
37953
38323
|
async beginRun(input) {
|
|
37954
|
-
const { tenantId: tenantId2, actor, threadId } = input;
|
|
38324
|
+
const { tenantId: tenantId2, actor, threadId, runId, callerThreadId, callerAssistantId } = input;
|
|
37955
38325
|
let task = input.task;
|
|
37956
38326
|
const warnings = [];
|
|
37957
38327
|
if (task.status === "pending") {
|
|
@@ -37960,7 +38330,10 @@ function createTaskRunBridge(deps) {
|
|
|
37960
38330
|
tenantId: tenantId2,
|
|
37961
38331
|
taskId: task.id,
|
|
37962
38332
|
actor,
|
|
37963
|
-
threadId
|
|
38333
|
+
...threadId !== void 0 ? { threadId } : {},
|
|
38334
|
+
...runId !== void 0 ? { runId } : {},
|
|
38335
|
+
...callerThreadId ? { callerThreadId } : {},
|
|
38336
|
+
...callerAssistantId ? { callerAssistantId } : {}
|
|
37964
38337
|
});
|
|
37965
38338
|
if (!started.success) {
|
|
37966
38339
|
return {
|
|
@@ -38048,7 +38421,19 @@ function createTaskRunBridge(deps) {
|
|
|
38048
38421
|
error: "Lifecycle transitions only support agent tasks."
|
|
38049
38422
|
};
|
|
38050
38423
|
}
|
|
38051
|
-
const result = task.status === "interrupted" ? await deps.lifecycle.resumeInterruption({
|
|
38424
|
+
const result = task.status === "interrupted" ? await deps.lifecycle.resumeInterruption({
|
|
38425
|
+
tenantId: tenantId2,
|
|
38426
|
+
taskId: task.id,
|
|
38427
|
+
actor,
|
|
38428
|
+
...threadId !== void 0 ? { threadId } : {},
|
|
38429
|
+
...runId !== void 0 ? { runId } : {}
|
|
38430
|
+
}) : await deps.lifecycle.retryTask({
|
|
38431
|
+
tenantId: tenantId2,
|
|
38432
|
+
taskId: task.id,
|
|
38433
|
+
actor,
|
|
38434
|
+
...threadId !== void 0 ? { threadId } : {},
|
|
38435
|
+
...runId !== void 0 ? { runId } : {}
|
|
38436
|
+
});
|
|
38052
38437
|
if (!result.success) {
|
|
38053
38438
|
return {
|
|
38054
38439
|
success: false,
|
|
@@ -38113,6 +38498,86 @@ function createTaskRunBridge(deps) {
|
|
|
38113
38498
|
};
|
|
38114
38499
|
}
|
|
38115
38500
|
|
|
38501
|
+
// src/services/TaskRunRegistry.ts
|
|
38502
|
+
var TaskRunRegistry = class {
|
|
38503
|
+
constructor() {
|
|
38504
|
+
this.live = /* @__PURE__ */ new Set();
|
|
38505
|
+
}
|
|
38506
|
+
/** Marks a task as currently held by a live run. */
|
|
38507
|
+
register(taskId) {
|
|
38508
|
+
this.live.add(taskId);
|
|
38509
|
+
}
|
|
38510
|
+
/** Removes a task once its run has ended. */
|
|
38511
|
+
unregister(taskId) {
|
|
38512
|
+
this.live.delete(taskId);
|
|
38513
|
+
}
|
|
38514
|
+
/** Reports whether a task is currently held by a live run. */
|
|
38515
|
+
isLive(taskId) {
|
|
38516
|
+
return this.live.has(taskId);
|
|
38517
|
+
}
|
|
38518
|
+
/** Returns a snapshot of the live task ids (diagnostics/tests). */
|
|
38519
|
+
snapshot() {
|
|
38520
|
+
return [...this.live];
|
|
38521
|
+
}
|
|
38522
|
+
/** Clears all live entries (tests / process teardown). */
|
|
38523
|
+
clear() {
|
|
38524
|
+
this.live.clear();
|
|
38525
|
+
}
|
|
38526
|
+
};
|
|
38527
|
+
var taskRunRegistry = new TaskRunRegistry();
|
|
38528
|
+
async function reconcileStaleTaskRuns(input) {
|
|
38529
|
+
const registry4 = input.registry ?? taskRunRegistry;
|
|
38530
|
+
const converged = [];
|
|
38531
|
+
const convergedTasks = [];
|
|
38532
|
+
for (const task of input.tasks) {
|
|
38533
|
+
if (task.status !== "in_progress" || registry4.isLive(task.id)) continue;
|
|
38534
|
+
const result = await input.lifecycle.failTask({
|
|
38535
|
+
tenantId: task.tenantId,
|
|
38536
|
+
taskId: task.id,
|
|
38537
|
+
actor: input.actor,
|
|
38538
|
+
failureReason: "Run is no longer executing this task (no_executor)"
|
|
38539
|
+
});
|
|
38540
|
+
if (result.success) {
|
|
38541
|
+
converged.push(task.id);
|
|
38542
|
+
convergedTasks.push(result.task);
|
|
38543
|
+
}
|
|
38544
|
+
}
|
|
38545
|
+
return { converged, convergedTasks };
|
|
38546
|
+
}
|
|
38547
|
+
async function reconcileTenantTaskRuns(input) {
|
|
38548
|
+
const tasks = await input.taskStore.list({ tenantId: input.tenantId, status: "in_progress" });
|
|
38549
|
+
const candidates = input.include ? tasks.filter(input.include) : tasks;
|
|
38550
|
+
return reconcileStaleTaskRuns({
|
|
38551
|
+
tasks: candidates,
|
|
38552
|
+
actor: input.actor,
|
|
38553
|
+
lifecycle: input.lifecycle,
|
|
38554
|
+
...input.registry ? { registry: input.registry } : {}
|
|
38555
|
+
});
|
|
38556
|
+
}
|
|
38557
|
+
async function reconcileAllTenantTaskRuns(input) {
|
|
38558
|
+
const tenants = await input.tenantStore.listTenants();
|
|
38559
|
+
const converged = [];
|
|
38560
|
+
const convergedTasks = [];
|
|
38561
|
+
for (const tenant of tenants) {
|
|
38562
|
+
let result;
|
|
38563
|
+
try {
|
|
38564
|
+
result = await reconcileTenantTaskRuns({
|
|
38565
|
+
tenantId: tenant.id,
|
|
38566
|
+
actor: input.actor,
|
|
38567
|
+
taskStore: input.taskStore,
|
|
38568
|
+
lifecycle: input.lifecycle,
|
|
38569
|
+
...input.registry ? { registry: input.registry } : {},
|
|
38570
|
+
...input.include ? { include: input.include } : {}
|
|
38571
|
+
});
|
|
38572
|
+
} catch {
|
|
38573
|
+
continue;
|
|
38574
|
+
}
|
|
38575
|
+
converged.push(...result.converged);
|
|
38576
|
+
convergedTasks.push(...result.convergedTasks);
|
|
38577
|
+
}
|
|
38578
|
+
return { converged, convergedTasks };
|
|
38579
|
+
}
|
|
38580
|
+
|
|
38116
38581
|
// src/services/ExecutionAuthorityRegistry.ts
|
|
38117
38582
|
var ManagedTaskStartError = class extends Error {
|
|
38118
38583
|
/**
|
|
@@ -38374,274 +38839,13 @@ async function prepareTaskDispatch(deps, input) {
|
|
|
38374
38839
|
agentId: input.agentId,
|
|
38375
38840
|
actor: input.actor,
|
|
38376
38841
|
...input.callerThreadId !== void 0 ? { callerThreadId: input.callerThreadId } : {},
|
|
38842
|
+
...input.callerAssistantId !== void 0 ? { callerAssistantId: input.callerAssistantId } : {},
|
|
38377
38843
|
parent,
|
|
38378
38844
|
completedDependencies
|
|
38379
38845
|
}
|
|
38380
38846
|
};
|
|
38381
38847
|
}
|
|
38382
38848
|
|
|
38383
|
-
// src/util/toJsonSafeValue.ts
|
|
38384
|
-
var CIRCULAR_VALUE = "[Circular]";
|
|
38385
|
-
var REPEATED_VALUE = "[Repeated]";
|
|
38386
|
-
var arrayFrom = Array.from.bind(Array);
|
|
38387
|
-
var arrayIsArray = Array.isArray.bind(Array);
|
|
38388
|
-
var hasOwnProperty = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
|
|
38389
|
-
var isPrototypeOf = Object.prototype.isPrototypeOf.call.bind(Object.prototype.isPrototypeOf);
|
|
38390
|
-
var objectCreate = Object.create.bind(Object);
|
|
38391
|
-
var objectDefineProperty = Object.defineProperty.bind(Object);
|
|
38392
|
-
var objectIs = Object.is.bind(Object);
|
|
38393
|
-
var reflectGet = Reflect.get.bind(Reflect);
|
|
38394
|
-
var reflectGetOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor.bind(Reflect);
|
|
38395
|
-
var reflectOwnKeys = Reflect.ownKeys.bind(Reflect);
|
|
38396
|
-
var stringifyJson = JSON.stringify.bind(JSON);
|
|
38397
|
-
var numberIsFinite = Number.isFinite.bind(Number);
|
|
38398
|
-
var numberIsNaN = Number.isNaN.bind(Number);
|
|
38399
|
-
var numberIsSafeInteger = Number.isSafeInteger.bind(Number);
|
|
38400
|
-
var mathMax = Math.max.bind(Math);
|
|
38401
|
-
var dateConstructor = Date;
|
|
38402
|
-
var datePrototype = dateConstructor.prototype;
|
|
38403
|
-
var dateGetTime = datePrototype.getTime.call.bind(datePrototype.getTime);
|
|
38404
|
-
var dateToISOString = datePrototype.toISOString.call.bind(datePrototype.toISOString);
|
|
38405
|
-
var bigintToString = BigInt.prototype.toString.call.bind(BigInt.prototype.toString);
|
|
38406
|
-
var stringSlice = String.prototype.slice.call.bind(String.prototype.slice);
|
|
38407
|
-
var weakMapGet = WeakMap.prototype.get.call.bind(WeakMap.prototype.get);
|
|
38408
|
-
var weakMapSet = WeakMap.prototype.set.call.bind(WeakMap.prototype.set);
|
|
38409
|
-
var WeakMapConstructor = WeakMap;
|
|
38410
|
-
var utf8Encoder = new TextEncoder();
|
|
38411
|
-
var encodeUtf8 = TextEncoder.prototype.encode.bind(utf8Encoder);
|
|
38412
|
-
var typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
|
38413
|
-
var typedArrayByteLengthGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength")?.get;
|
|
38414
|
-
if (!typedArrayByteLengthGetter) throw new Error("TypedArray byteLength getter is unavailable");
|
|
38415
|
-
var typedArrayByteLength = typedArrayByteLengthGetter.call.bind(typedArrayByteLengthGetter);
|
|
38416
|
-
var JSON_SAFE_MAX_DEPTH = 32;
|
|
38417
|
-
var JSON_SAFE_MAX_NODES = 1e4;
|
|
38418
|
-
var JSON_SAFE_MAX_COLLECTION_ENTRIES = 1e4;
|
|
38419
|
-
var JSON_SAFE_MAX_STRING_LENGTH = 64 * 1024;
|
|
38420
|
-
var JSON_SAFE_MAX_PROPERTY_KEY_LENGTH = JSON_SAFE_MAX_STRING_LENGTH;
|
|
38421
|
-
var JSON_SAFE_MAX_PROPERTY_KEY_BYTES = 256 * 1024;
|
|
38422
|
-
var JSON_SAFE_MAX_SERIALIZED_BYTES = 256 * 1024;
|
|
38423
|
-
var JsonSafeValueError = class extends Error {
|
|
38424
|
-
/**
|
|
38425
|
-
* Create a bounded normalization error.
|
|
38426
|
-
*
|
|
38427
|
-
* @param code Stable normalization failure code.
|
|
38428
|
-
* @param message Human-readable bounded failure description.
|
|
38429
|
-
*/
|
|
38430
|
-
constructor(code, message) {
|
|
38431
|
-
super(message);
|
|
38432
|
-
objectDefineProperty(this, "name", {
|
|
38433
|
-
value: "JsonSafeValueError",
|
|
38434
|
-
writable: true,
|
|
38435
|
-
configurable: true
|
|
38436
|
-
});
|
|
38437
|
-
objectDefineProperty(this, "code", {
|
|
38438
|
-
value: code,
|
|
38439
|
-
writable: true,
|
|
38440
|
-
configurable: true
|
|
38441
|
-
});
|
|
38442
|
-
}
|
|
38443
|
-
};
|
|
38444
|
-
function fail(code, message) {
|
|
38445
|
-
throw new JsonSafeValueError(code, message);
|
|
38446
|
-
}
|
|
38447
|
-
function propertyAccess(operation, path8) {
|
|
38448
|
-
try {
|
|
38449
|
-
return operation();
|
|
38450
|
-
} catch {
|
|
38451
|
-
fail("PROPERTY_ACCESS_FAILED", `Unable to inspect JSON-safe value at ${path8}`);
|
|
38452
|
-
}
|
|
38453
|
-
}
|
|
38454
|
-
function serializedStringBytes(value) {
|
|
38455
|
-
if (value.length > JSON_SAFE_MAX_STRING_LENGTH) {
|
|
38456
|
-
fail("MAX_STRING_LENGTH", `JSON-safe string exceeds ${JSON_SAFE_MAX_STRING_LENGTH} characters`);
|
|
38457
|
-
}
|
|
38458
|
-
return typedArrayByteLength(encodeUtf8(stringifyJson(value)));
|
|
38459
|
-
}
|
|
38460
|
-
function validatePropertyKey(key5) {
|
|
38461
|
-
if (key5.length > JSON_SAFE_MAX_PROPERTY_KEY_LENGTH) {
|
|
38462
|
-
fail(
|
|
38463
|
-
"MAX_STRING_LENGTH",
|
|
38464
|
-
`JSON-safe property key exceeds ${JSON_SAFE_MAX_PROPERTY_KEY_LENGTH} characters`
|
|
38465
|
-
);
|
|
38466
|
-
}
|
|
38467
|
-
}
|
|
38468
|
-
function chargePropertyKey(state, key5) {
|
|
38469
|
-
state.propertyKeyBytes += typedArrayByteLength(encodeUtf8(key5));
|
|
38470
|
-
if (state.propertyKeyBytes > JSON_SAFE_MAX_PROPERTY_KEY_BYTES) {
|
|
38471
|
-
fail(
|
|
38472
|
-
"MAX_PROPERTY_KEY_BYTES",
|
|
38473
|
-
`JSON-safe property keys exceed ${JSON_SAFE_MAX_PROPERTY_KEY_BYTES} traversed UTF-8 bytes`
|
|
38474
|
-
);
|
|
38475
|
-
}
|
|
38476
|
-
}
|
|
38477
|
-
function chargeBytes(state, bytes) {
|
|
38478
|
-
state.serializedBytes += bytes;
|
|
38479
|
-
if (state.serializedBytes > JSON_SAFE_MAX_SERIALIZED_BYTES) {
|
|
38480
|
-
fail(
|
|
38481
|
-
"MAX_SERIALIZED_BYTES",
|
|
38482
|
-
`JSON-safe value exceeds ${JSON_SAFE_MAX_SERIALIZED_BYTES} serialized bytes`
|
|
38483
|
-
);
|
|
38484
|
-
}
|
|
38485
|
-
}
|
|
38486
|
-
function chargeString(state, value) {
|
|
38487
|
-
chargeBytes(state, serializedStringBytes(value));
|
|
38488
|
-
}
|
|
38489
|
-
function objectPropertyPath(path8, key5) {
|
|
38490
|
-
const boundedKey = key5.length > 128 ? `${stringSlice(key5, 0, 128)}...` : key5;
|
|
38491
|
-
return `${path8}[${stringifyJson(boundedKey)}]`;
|
|
38492
|
-
}
|
|
38493
|
-
function convertJsonValue(value, state, depth, inArray, path8) {
|
|
38494
|
-
state.nodes += 1;
|
|
38495
|
-
if (state.nodes > JSON_SAFE_MAX_NODES) {
|
|
38496
|
-
fail("MAX_NODES", `JSON-safe value exceeds ${JSON_SAFE_MAX_NODES} total nodes`);
|
|
38497
|
-
}
|
|
38498
|
-
if (typeof value === "string") {
|
|
38499
|
-
chargeString(state, value);
|
|
38500
|
-
return value;
|
|
38501
|
-
}
|
|
38502
|
-
if (value === null) {
|
|
38503
|
-
chargeBytes(state, 4);
|
|
38504
|
-
return value;
|
|
38505
|
-
}
|
|
38506
|
-
if (typeof value === "boolean") {
|
|
38507
|
-
chargeBytes(state, value ? 4 : 5);
|
|
38508
|
-
return value;
|
|
38509
|
-
}
|
|
38510
|
-
if (typeof value === "number") {
|
|
38511
|
-
const normalized = numberIsFinite(value) ? objectIs(value, -0) ? 0 : value : null;
|
|
38512
|
-
chargeBytes(state, normalized === null ? 4 : stringifyJson(normalized).length);
|
|
38513
|
-
return normalized;
|
|
38514
|
-
}
|
|
38515
|
-
if (typeof value === "bigint") {
|
|
38516
|
-
const normalized = bigintToString(value);
|
|
38517
|
-
chargeString(state, normalized);
|
|
38518
|
-
return normalized;
|
|
38519
|
-
}
|
|
38520
|
-
if (typeof value === "undefined" || typeof value === "function" || typeof value === "symbol") {
|
|
38521
|
-
if (inArray) chargeBytes(state, 4);
|
|
38522
|
-
return inArray ? null : void 0;
|
|
38523
|
-
}
|
|
38524
|
-
const isDate = propertyAccess(() => isPrototypeOf(datePrototype, value), path8);
|
|
38525
|
-
if (isDate) {
|
|
38526
|
-
const time = propertyAccess(() => dateGetTime(value), path8);
|
|
38527
|
-
if (numberIsNaN(time)) {
|
|
38528
|
-
chargeBytes(state, 4);
|
|
38529
|
-
return null;
|
|
38530
|
-
}
|
|
38531
|
-
const normalized = propertyAccess(() => dateToISOString(value), path8);
|
|
38532
|
-
chargeString(state, normalized);
|
|
38533
|
-
return normalized;
|
|
38534
|
-
}
|
|
38535
|
-
if (depth > JSON_SAFE_MAX_DEPTH) {
|
|
38536
|
-
fail("MAX_DEPTH", `JSON-safe value exceeds maximum depth ${JSON_SAFE_MAX_DEPTH}`);
|
|
38537
|
-
}
|
|
38538
|
-
const referenceState = weakMapGet(state.references, value);
|
|
38539
|
-
if (referenceState === "visiting") {
|
|
38540
|
-
chargeString(state, CIRCULAR_VALUE);
|
|
38541
|
-
return CIRCULAR_VALUE;
|
|
38542
|
-
}
|
|
38543
|
-
if (referenceState === "visited") {
|
|
38544
|
-
chargeString(state, REPEATED_VALUE);
|
|
38545
|
-
return REPEATED_VALUE;
|
|
38546
|
-
}
|
|
38547
|
-
weakMapSet(state.references, value, "visiting");
|
|
38548
|
-
if (propertyAccess(() => arrayIsArray(value), path8)) {
|
|
38549
|
-
const arrayValue = value;
|
|
38550
|
-
const length = propertyAccess(
|
|
38551
|
-
() => arrayValue.length,
|
|
38552
|
-
path8
|
|
38553
|
-
);
|
|
38554
|
-
if (typeof length !== "number" || !numberIsSafeInteger(length) || length < 0) {
|
|
38555
|
-
fail("PROPERTY_ACCESS_FAILED", `Unable to inspect JSON-safe array length at ${path8}`);
|
|
38556
|
-
}
|
|
38557
|
-
if (length > JSON_SAFE_MAX_COLLECTION_ENTRIES) {
|
|
38558
|
-
fail(
|
|
38559
|
-
"COLLECTION_TOO_LARGE",
|
|
38560
|
-
`JSON-safe array exceeds ${JSON_SAFE_MAX_COLLECTION_ENTRIES} entries`
|
|
38561
|
-
);
|
|
38562
|
-
}
|
|
38563
|
-
chargeBytes(state, 2 + mathMax(0, length - 1));
|
|
38564
|
-
const result2 = arrayFrom({ length }, (_, index) => {
|
|
38565
|
-
const entryPath = `${path8}[${index}]`;
|
|
38566
|
-
const hasEntry = propertyAccess(
|
|
38567
|
-
() => hasOwnProperty(arrayValue, index),
|
|
38568
|
-
entryPath
|
|
38569
|
-
);
|
|
38570
|
-
if (!hasEntry) {
|
|
38571
|
-
chargeBytes(state, 4);
|
|
38572
|
-
return null;
|
|
38573
|
-
}
|
|
38574
|
-
const entry = propertyAccess(() => arrayValue[index], entryPath);
|
|
38575
|
-
return convertJsonValue(entry, state, depth + 1, true, `${path8}[${index}]`);
|
|
38576
|
-
});
|
|
38577
|
-
objectDefineProperty(result2, "toJSON", {
|
|
38578
|
-
value: void 0,
|
|
38579
|
-
configurable: true,
|
|
38580
|
-
writable: true
|
|
38581
|
-
});
|
|
38582
|
-
weakMapSet(state.references, value, "visited");
|
|
38583
|
-
return result2;
|
|
38584
|
-
}
|
|
38585
|
-
const keys = propertyAccess(() => reflectOwnKeys(value), path8);
|
|
38586
|
-
if (keys.length > JSON_SAFE_MAX_COLLECTION_ENTRIES) {
|
|
38587
|
-
fail(
|
|
38588
|
-
"COLLECTION_TOO_LARGE",
|
|
38589
|
-
`JSON-safe object exceeds ${JSON_SAFE_MAX_COLLECTION_ENTRIES} own keys`
|
|
38590
|
-
);
|
|
38591
|
-
}
|
|
38592
|
-
for (let index = 0; index < keys.length; index += 1) {
|
|
38593
|
-
const key5 = keys[index];
|
|
38594
|
-
if (typeof key5 !== "string") continue;
|
|
38595
|
-
validatePropertyKey(key5);
|
|
38596
|
-
chargePropertyKey(state, key5);
|
|
38597
|
-
}
|
|
38598
|
-
chargeBytes(state, 2);
|
|
38599
|
-
const result = objectCreate(null);
|
|
38600
|
-
let emittedProperties = 0;
|
|
38601
|
-
for (let index = 0; index < keys.length; index += 1) {
|
|
38602
|
-
const key5 = keys[index];
|
|
38603
|
-
const entryPath = typeof key5 === "string" ? objectPropertyPath(path8, key5) : path8;
|
|
38604
|
-
const descriptor = propertyAccess(
|
|
38605
|
-
() => reflectGetOwnPropertyDescriptor(value, key5),
|
|
38606
|
-
entryPath
|
|
38607
|
-
);
|
|
38608
|
-
if (typeof key5 !== "string" || !descriptor?.enumerable) continue;
|
|
38609
|
-
const entry = propertyAccess(() => reflectGet(value, key5), entryPath);
|
|
38610
|
-
const converted = convertJsonValue(entry, state, depth + 1, false, entryPath);
|
|
38611
|
-
if (converted !== void 0) {
|
|
38612
|
-
chargeBytes(state, serializedStringBytes(key5) + 1 + (emittedProperties === 0 ? 0 : 1));
|
|
38613
|
-
propertyAccess(() => objectDefineProperty(result, key5, {
|
|
38614
|
-
value: converted,
|
|
38615
|
-
enumerable: true,
|
|
38616
|
-
configurable: true,
|
|
38617
|
-
writable: true
|
|
38618
|
-
}), entryPath);
|
|
38619
|
-
emittedProperties += 1;
|
|
38620
|
-
}
|
|
38621
|
-
}
|
|
38622
|
-
weakMapSet(state.references, value, "visited");
|
|
38623
|
-
return result;
|
|
38624
|
-
}
|
|
38625
|
-
function toJsonSafeValue(value) {
|
|
38626
|
-
const state = {
|
|
38627
|
-
nodes: 0,
|
|
38628
|
-
propertyKeyBytes: 0,
|
|
38629
|
-
serializedBytes: 0,
|
|
38630
|
-
references: new WeakMapConstructor()
|
|
38631
|
-
};
|
|
38632
|
-
const converted = convertJsonValue(value, state, 0, false, "$");
|
|
38633
|
-
if (converted === void 0) chargeBytes(state, 4);
|
|
38634
|
-
const result = converted ?? null;
|
|
38635
|
-
const serialized = propertyAccess(() => stringifyJson(result), "$");
|
|
38636
|
-
if (typedArrayByteLength(encodeUtf8(serialized)) > JSON_SAFE_MAX_SERIALIZED_BYTES) {
|
|
38637
|
-
fail(
|
|
38638
|
-
"MAX_SERIALIZED_BYTES",
|
|
38639
|
-
`JSON-safe value exceeds ${JSON_SAFE_MAX_SERIALIZED_BYTES} serialized bytes`
|
|
38640
|
-
);
|
|
38641
|
-
}
|
|
38642
|
-
return result;
|
|
38643
|
-
}
|
|
38644
|
-
|
|
38645
38849
|
// src/services/TaskExecutionService.ts
|
|
38646
38850
|
import { GraphInterrupt as GraphInterrupt2 } from "@langchain/langgraph";
|
|
38647
38851
|
function persistedExecutionObservation(item, attempted) {
|
|
@@ -38690,10 +38894,26 @@ function createTaskExecutionService(deps) {
|
|
|
38690
38894
|
const run = async (plan) => {
|
|
38691
38895
|
const { tenantId: tenantId2, agentId, actor, parent, completedDependencies } = plan;
|
|
38692
38896
|
let task = plan.task;
|
|
38693
|
-
const
|
|
38897
|
+
const storedThreadId = (task.status === "interrupted" || task.status === "failed") && typeof task.context?.thread_id === "string" && task.context.thread_id.trim() !== "" ? task.context.thread_id : void 0;
|
|
38898
|
+
const storedRunId = typeof task.context?.run_id === "string" && task.context.run_id.trim() !== "" ? task.context.run_id : void 0;
|
|
38899
|
+
let reuseCurrentRun = false;
|
|
38900
|
+
if (task.status === "interrupted" && storedThreadId) {
|
|
38901
|
+
const currentKey = storedRunId ? `execution-result:${storedThreadId}:${storedRunId}` : `execution-result:${storedThreadId}`;
|
|
38902
|
+
try {
|
|
38903
|
+
reuseCurrentRun = await deps.workItemStore.findByEventKey(tenantId2, task.id, currentKey) === null;
|
|
38904
|
+
} catch {
|
|
38905
|
+
reuseCurrentRun = false;
|
|
38906
|
+
}
|
|
38907
|
+
}
|
|
38694
38908
|
let threadId;
|
|
38909
|
+
let runId;
|
|
38695
38910
|
try {
|
|
38696
|
-
threadId =
|
|
38911
|
+
threadId = storedThreadId ?? (deps.createThreadId ?? randomUUID8)();
|
|
38912
|
+
if (task.status === "interrupted" && reuseCurrentRun) {
|
|
38913
|
+
runId = storedRunId;
|
|
38914
|
+
} else if (task.status === "interrupted" || task.status === "failed") {
|
|
38915
|
+
runId = (deps.createRunId ?? randomUUID8)();
|
|
38916
|
+
}
|
|
38697
38917
|
} catch (error) {
|
|
38698
38918
|
return {
|
|
38699
38919
|
success: false,
|
|
@@ -38703,7 +38923,7 @@ function createTaskExecutionService(deps) {
|
|
|
38703
38923
|
agentId
|
|
38704
38924
|
};
|
|
38705
38925
|
}
|
|
38706
|
-
const eventKey = `execution-result:${threadId}`;
|
|
38926
|
+
const eventKey = runId ? `execution-result:${threadId}:${runId}` : `execution-result:${threadId}`;
|
|
38707
38927
|
if (!isExecutionResultEventKey2(eventKey)) {
|
|
38708
38928
|
return {
|
|
38709
38929
|
success: false,
|
|
@@ -38737,7 +38957,10 @@ function createTaskExecutionService(deps) {
|
|
|
38737
38957
|
tenantId: tenantId2,
|
|
38738
38958
|
task,
|
|
38739
38959
|
actor,
|
|
38740
|
-
threadId
|
|
38960
|
+
threadId,
|
|
38961
|
+
...runId ? { runId } : {},
|
|
38962
|
+
...plan.callerThreadId ? { callerThreadId: plan.callerThreadId } : {},
|
|
38963
|
+
...plan.callerAssistantId ? { callerAssistantId: plan.callerAssistantId } : {}
|
|
38741
38964
|
});
|
|
38742
38965
|
if (!begun.success) return { ...begun, taskId: task.id };
|
|
38743
38966
|
if (!begun.mutated || !begun.transitioned) {
|
|
@@ -38751,38 +38974,120 @@ function createTaskExecutionService(deps) {
|
|
|
38751
38974
|
task = begun.task;
|
|
38752
38975
|
warnings.push(...begun.warnings);
|
|
38753
38976
|
}
|
|
38754
|
-
|
|
38755
|
-
tenantId: tenantId2,
|
|
38756
|
-
workspaceId: task.workspaceId,
|
|
38757
|
-
projectId: task.projectId,
|
|
38758
|
-
taskId: task.id,
|
|
38759
|
-
agentId,
|
|
38760
|
-
threadId,
|
|
38761
|
-
message: buildWorkerMessage(task, parent, completedDependencies),
|
|
38762
|
-
delegatedTaskId: task.id,
|
|
38763
|
-
taskExecutionRole: "worker"
|
|
38764
|
-
};
|
|
38765
|
-
let observation;
|
|
38977
|
+
taskRunRegistry.register(task.id);
|
|
38766
38978
|
try {
|
|
38767
|
-
|
|
38768
|
-
|
|
38769
|
-
|
|
38979
|
+
const invocation = {
|
|
38980
|
+
tenantId: tenantId2,
|
|
38981
|
+
workspaceId: task.workspaceId,
|
|
38982
|
+
projectId: task.projectId,
|
|
38983
|
+
taskId: task.id,
|
|
38984
|
+
agentId,
|
|
38985
|
+
threadId,
|
|
38986
|
+
message: buildWorkerMessage(task, parent, completedDependencies),
|
|
38987
|
+
delegatedTaskId: task.id,
|
|
38988
|
+
taskExecutionRole: "worker"
|
|
38989
|
+
};
|
|
38990
|
+
let observation;
|
|
38991
|
+
try {
|
|
38992
|
+
observation = toJsonSafeValue(await deps.invokeAgent(invocation));
|
|
38993
|
+
} catch (error) {
|
|
38994
|
+
if (error instanceof GraphInterrupt2) {
|
|
38995
|
+
try {
|
|
38996
|
+
await bridge.settleRun({
|
|
38997
|
+
tenantId: tenantId2,
|
|
38998
|
+
task,
|
|
38999
|
+
actor,
|
|
39000
|
+
threadId,
|
|
39001
|
+
outcome: { kind: "interrupted", summary: "Awaiting user input" }
|
|
39002
|
+
});
|
|
39003
|
+
} catch {
|
|
39004
|
+
}
|
|
39005
|
+
throw error;
|
|
39006
|
+
}
|
|
39007
|
+
const normalizationError = error instanceof JsonSafeValueError;
|
|
39008
|
+
const message = normalizationError ? `${error.code}: ${error.message}` : errorMessage(error);
|
|
39009
|
+
const failureCode = normalizationError ? "EXECUTION_RESULT_NORMALIZATION_FAILED" : "AGENT_INVOCATION_FAILED";
|
|
38770
39010
|
try {
|
|
38771
|
-
await bridge.settleRun({
|
|
39011
|
+
const settled = await bridge.settleRun({
|
|
38772
39012
|
tenantId: tenantId2,
|
|
38773
39013
|
task,
|
|
38774
39014
|
actor,
|
|
38775
39015
|
threadId,
|
|
38776
|
-
outcome: {
|
|
39016
|
+
outcome: {
|
|
39017
|
+
kind: "failed",
|
|
39018
|
+
lifecycleHandled: false,
|
|
39019
|
+
error: message.trim() || "Agent invocation failed"
|
|
39020
|
+
}
|
|
38777
39021
|
});
|
|
39022
|
+
if (!settled.success) {
|
|
39023
|
+
warnings.push({ code: "TASK_FAILED_SETTLE_FAILED", taskId: task.id });
|
|
39024
|
+
}
|
|
38778
39025
|
} catch {
|
|
39026
|
+
warnings.push({ code: "TASK_FAILED_SETTLE_FAILED", taskId: task.id });
|
|
39027
|
+
}
|
|
39028
|
+
const failedObservation = toJsonSafeValue(normalizationError ? { code: failureCode, error: message } : { error: message });
|
|
39029
|
+
try {
|
|
39030
|
+
const persisted = await deps.workItemStore.createIfAbsentByEventKey({
|
|
39031
|
+
taskId: task.id,
|
|
39032
|
+
tenantId: tenantId2,
|
|
39033
|
+
workspaceId: task.workspaceId,
|
|
39034
|
+
projectId: task.projectId,
|
|
39035
|
+
action: "execution_result",
|
|
39036
|
+
actor,
|
|
39037
|
+
threadId,
|
|
39038
|
+
summary: normalizationError ? `Agent ${agentId} returned an invalid execution observation` : `Agent ${agentId} invocation failed`,
|
|
39039
|
+
detail: {
|
|
39040
|
+
agentId,
|
|
39041
|
+
threadId,
|
|
39042
|
+
observation: failedObservation,
|
|
39043
|
+
success: false
|
|
39044
|
+
},
|
|
39045
|
+
eventKey
|
|
39046
|
+
});
|
|
39047
|
+
const validated = persistedExecutionObservation(persisted, {
|
|
39048
|
+
tenantId: tenantId2,
|
|
39049
|
+
taskId: task.id,
|
|
39050
|
+
agentId,
|
|
39051
|
+
threadId,
|
|
39052
|
+
eventKey,
|
|
39053
|
+
success: false,
|
|
39054
|
+
observation: failedObservation
|
|
39055
|
+
});
|
|
39056
|
+
if (!validated.matches) {
|
|
39057
|
+
return {
|
|
39058
|
+
success: false,
|
|
39059
|
+
code: "EXECUTION_RESULT_IDENTITY_CONFLICT",
|
|
39060
|
+
error: "The execution result identity is already bound to a different execution payload",
|
|
39061
|
+
...!normalizationError ? { invocationError: message } : {},
|
|
39062
|
+
taskId: task.id,
|
|
39063
|
+
agentId,
|
|
39064
|
+
threadId,
|
|
39065
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
39066
|
+
};
|
|
39067
|
+
}
|
|
39068
|
+
return {
|
|
39069
|
+
success: false,
|
|
39070
|
+
code: failureCode,
|
|
39071
|
+
error: typeof validated.observation?.error === "string" ? validated.observation.error : message,
|
|
39072
|
+
taskId: task.id,
|
|
39073
|
+
agentId,
|
|
39074
|
+
threadId,
|
|
39075
|
+
executionResultId: eventKey,
|
|
39076
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
39077
|
+
};
|
|
39078
|
+
} catch (persistenceError) {
|
|
39079
|
+
return {
|
|
39080
|
+
success: false,
|
|
39081
|
+
code: "EXECUTION_RESULT_WRITE_FAILED",
|
|
39082
|
+
error: errorMessage(persistenceError),
|
|
39083
|
+
...!normalizationError ? { invocationError: message } : {},
|
|
39084
|
+
taskId: task.id,
|
|
39085
|
+
agentId,
|
|
39086
|
+
threadId,
|
|
39087
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
39088
|
+
};
|
|
38779
39089
|
}
|
|
38780
|
-
throw error;
|
|
38781
39090
|
}
|
|
38782
|
-
const normalizationError = error instanceof JsonSafeValueError;
|
|
38783
|
-
const message = normalizationError ? `${error.code}: ${error.message}` : errorMessage(error);
|
|
38784
|
-
const failureCode = normalizationError ? "EXECUTION_RESULT_NORMALIZATION_FAILED" : "AGENT_INVOCATION_FAILED";
|
|
38785
|
-
const failedObservation = toJsonSafeValue(normalizationError ? { code: failureCode, error: message } : { error: message });
|
|
38786
39091
|
try {
|
|
38787
39092
|
const persisted = await deps.workItemStore.createIfAbsentByEventKey({
|
|
38788
39093
|
taskId: task.id,
|
|
@@ -38792,13 +39097,8 @@ function createTaskExecutionService(deps) {
|
|
|
38792
39097
|
action: "execution_result",
|
|
38793
39098
|
actor,
|
|
38794
39099
|
threadId,
|
|
38795
|
-
summary:
|
|
38796
|
-
detail: {
|
|
38797
|
-
agentId,
|
|
38798
|
-
threadId,
|
|
38799
|
-
observation: failedObservation,
|
|
38800
|
-
success: false
|
|
38801
|
-
},
|
|
39100
|
+
summary: `Agent ${agentId} returned an execution observation`,
|
|
39101
|
+
detail: { agentId, threadId, observation, success: true },
|
|
38802
39102
|
eventKey
|
|
38803
39103
|
});
|
|
38804
39104
|
const validated = persistedExecutionObservation(persisted, {
|
|
@@ -38807,15 +39107,14 @@ function createTaskExecutionService(deps) {
|
|
|
38807
39107
|
agentId,
|
|
38808
39108
|
threadId,
|
|
38809
39109
|
eventKey,
|
|
38810
|
-
success:
|
|
38811
|
-
observation
|
|
39110
|
+
success: true,
|
|
39111
|
+
observation
|
|
38812
39112
|
});
|
|
38813
39113
|
if (!validated.matches) {
|
|
38814
39114
|
return {
|
|
38815
39115
|
success: false,
|
|
38816
39116
|
code: "EXECUTION_RESULT_IDENTITY_CONFLICT",
|
|
38817
39117
|
error: "The execution result identity is already bound to a different execution payload",
|
|
38818
|
-
...!normalizationError ? { invocationError: message } : {},
|
|
38819
39118
|
taskId: task.id,
|
|
38820
39119
|
agentId,
|
|
38821
39120
|
threadId,
|
|
@@ -38823,80 +39122,27 @@ function createTaskExecutionService(deps) {
|
|
|
38823
39122
|
};
|
|
38824
39123
|
}
|
|
38825
39124
|
return {
|
|
38826
|
-
success:
|
|
38827
|
-
code: failureCode,
|
|
38828
|
-
error: typeof validated.observation?.error === "string" ? validated.observation.error : message,
|
|
39125
|
+
success: true,
|
|
38829
39126
|
taskId: task.id,
|
|
38830
39127
|
agentId,
|
|
38831
39128
|
threadId,
|
|
39129
|
+
observation: validated.observation,
|
|
38832
39130
|
executionResultId: eventKey,
|
|
38833
39131
|
...warnings.length > 0 ? { warnings } : {}
|
|
38834
39132
|
};
|
|
38835
|
-
} catch (
|
|
39133
|
+
} catch (error) {
|
|
38836
39134
|
return {
|
|
38837
39135
|
success: false,
|
|
38838
39136
|
code: "EXECUTION_RESULT_WRITE_FAILED",
|
|
38839
|
-
error: errorMessage(
|
|
38840
|
-
...!normalizationError ? { invocationError: message } : {},
|
|
38841
|
-
taskId: task.id,
|
|
38842
|
-
agentId,
|
|
38843
|
-
threadId,
|
|
38844
|
-
...warnings.length > 0 ? { warnings } : {}
|
|
38845
|
-
};
|
|
38846
|
-
}
|
|
38847
|
-
}
|
|
38848
|
-
try {
|
|
38849
|
-
const persisted = await deps.workItemStore.createIfAbsentByEventKey({
|
|
38850
|
-
taskId: task.id,
|
|
38851
|
-
tenantId: tenantId2,
|
|
38852
|
-
workspaceId: task.workspaceId,
|
|
38853
|
-
projectId: task.projectId,
|
|
38854
|
-
action: "execution_result",
|
|
38855
|
-
actor,
|
|
38856
|
-
threadId,
|
|
38857
|
-
summary: `Agent ${agentId} returned an execution observation`,
|
|
38858
|
-
detail: { agentId, threadId, observation, success: true },
|
|
38859
|
-
eventKey
|
|
38860
|
-
});
|
|
38861
|
-
const validated = persistedExecutionObservation(persisted, {
|
|
38862
|
-
tenantId: tenantId2,
|
|
38863
|
-
taskId: task.id,
|
|
38864
|
-
agentId,
|
|
38865
|
-
threadId,
|
|
38866
|
-
eventKey,
|
|
38867
|
-
success: true,
|
|
38868
|
-
observation
|
|
38869
|
-
});
|
|
38870
|
-
if (!validated.matches) {
|
|
38871
|
-
return {
|
|
38872
|
-
success: false,
|
|
38873
|
-
code: "EXECUTION_RESULT_IDENTITY_CONFLICT",
|
|
38874
|
-
error: "The execution result identity is already bound to a different execution payload",
|
|
39137
|
+
error: errorMessage(error),
|
|
38875
39138
|
taskId: task.id,
|
|
38876
39139
|
agentId,
|
|
38877
39140
|
threadId,
|
|
38878
39141
|
...warnings.length > 0 ? { warnings } : {}
|
|
38879
39142
|
};
|
|
38880
39143
|
}
|
|
38881
|
-
|
|
38882
|
-
|
|
38883
|
-
taskId: task.id,
|
|
38884
|
-
agentId,
|
|
38885
|
-
threadId,
|
|
38886
|
-
observation: validated.observation,
|
|
38887
|
-
executionResultId: eventKey,
|
|
38888
|
-
...warnings.length > 0 ? { warnings } : {}
|
|
38889
|
-
};
|
|
38890
|
-
} catch (error) {
|
|
38891
|
-
return {
|
|
38892
|
-
success: false,
|
|
38893
|
-
code: "EXECUTION_RESULT_WRITE_FAILED",
|
|
38894
|
-
error: errorMessage(error),
|
|
38895
|
-
taskId: task.id,
|
|
38896
|
-
agentId,
|
|
38897
|
-
threadId,
|
|
38898
|
-
...warnings.length > 0 ? { warnings } : {}
|
|
38899
|
-
};
|
|
39144
|
+
} finally {
|
|
39145
|
+
taskRunRegistry.unregister(task.id);
|
|
38900
39146
|
}
|
|
38901
39147
|
};
|
|
38902
39148
|
return {
|
|
@@ -38909,76 +39155,6 @@ function createTaskExecutionService(deps) {
|
|
|
38909
39155
|
};
|
|
38910
39156
|
}
|
|
38911
39157
|
|
|
38912
|
-
// src/services/TaskRunRegistry.ts
|
|
38913
|
-
var TaskRunRegistry = class {
|
|
38914
|
-
constructor() {
|
|
38915
|
-
this.live = /* @__PURE__ */ new Set();
|
|
38916
|
-
}
|
|
38917
|
-
/** Marks a task as currently held by a live run. */
|
|
38918
|
-
register(taskId) {
|
|
38919
|
-
this.live.add(taskId);
|
|
38920
|
-
}
|
|
38921
|
-
/** Removes a task once its run has ended. */
|
|
38922
|
-
unregister(taskId) {
|
|
38923
|
-
this.live.delete(taskId);
|
|
38924
|
-
}
|
|
38925
|
-
/** Reports whether a task is currently held by a live run. */
|
|
38926
|
-
isLive(taskId) {
|
|
38927
|
-
return this.live.has(taskId);
|
|
38928
|
-
}
|
|
38929
|
-
/** Returns a snapshot of the live task ids (diagnostics/tests). */
|
|
38930
|
-
snapshot() {
|
|
38931
|
-
return [...this.live];
|
|
38932
|
-
}
|
|
38933
|
-
/** Clears all live entries (tests / process teardown). */
|
|
38934
|
-
clear() {
|
|
38935
|
-
this.live.clear();
|
|
38936
|
-
}
|
|
38937
|
-
};
|
|
38938
|
-
var taskRunRegistry = new TaskRunRegistry();
|
|
38939
|
-
async function reconcileStaleTaskRuns(input) {
|
|
38940
|
-
const registry4 = input.registry ?? taskRunRegistry;
|
|
38941
|
-
const converged = [];
|
|
38942
|
-
for (const task of input.tasks) {
|
|
38943
|
-
if (task.status !== "in_progress" || registry4.isLive(task.id)) continue;
|
|
38944
|
-
const result = await input.lifecycle.interruptTask({
|
|
38945
|
-
tenantId: task.tenantId,
|
|
38946
|
-
taskId: task.id,
|
|
38947
|
-
actor: input.actor,
|
|
38948
|
-
type: "missing_input",
|
|
38949
|
-
summary: "Run is no longer executing this task (no_executor)"
|
|
38950
|
-
});
|
|
38951
|
-
if (result.success) converged.push(task.id);
|
|
38952
|
-
}
|
|
38953
|
-
return { converged };
|
|
38954
|
-
}
|
|
38955
|
-
async function reconcileTenantTaskRuns(input) {
|
|
38956
|
-
const tasks = await input.taskStore.list({ tenantId: input.tenantId, status: "in_progress" });
|
|
38957
|
-
const candidates = input.include ? tasks.filter(input.include) : tasks;
|
|
38958
|
-
return reconcileStaleTaskRuns({
|
|
38959
|
-
tasks: candidates,
|
|
38960
|
-
actor: input.actor,
|
|
38961
|
-
lifecycle: input.lifecycle,
|
|
38962
|
-
...input.registry ? { registry: input.registry } : {}
|
|
38963
|
-
});
|
|
38964
|
-
}
|
|
38965
|
-
async function reconcileAllTenantTaskRuns(input) {
|
|
38966
|
-
const tenants = await input.tenantStore.listTenants();
|
|
38967
|
-
const converged = [];
|
|
38968
|
-
for (const tenant of tenants) {
|
|
38969
|
-
const result = await reconcileTenantTaskRuns({
|
|
38970
|
-
tenantId: tenant.id,
|
|
38971
|
-
actor: input.actor,
|
|
38972
|
-
taskStore: input.taskStore,
|
|
38973
|
-
lifecycle: input.lifecycle,
|
|
38974
|
-
...input.registry ? { registry: input.registry } : {},
|
|
38975
|
-
...input.include ? { include: input.include } : {}
|
|
38976
|
-
});
|
|
38977
|
-
converged.push(...result.converged);
|
|
38978
|
-
}
|
|
38979
|
-
return { converged };
|
|
38980
|
-
}
|
|
38981
|
-
|
|
38982
39158
|
// src/index.ts
|
|
38983
39159
|
import * as Protocols from "@axiom-lattice/protocols";
|
|
38984
39160
|
|
|
@@ -41178,61 +41354,28 @@ var widgetPlugin = {
|
|
|
41178
41354
|
import { createMiddleware as createMiddleware23, tool as tool64 } from "langchain";
|
|
41179
41355
|
import { z as z70 } from "zod";
|
|
41180
41356
|
import { GraphInterrupt as GraphInterrupt3, interrupt as interrupt4 } from "@langchain/langgraph";
|
|
41357
|
+
import { resolveRunScope as resolveRunScope2 } from "@axiom-lattice/protocols";
|
|
41181
41358
|
|
|
41182
|
-
// src/
|
|
41183
|
-
|
|
41184
|
-
function
|
|
41185
|
-
|
|
41186
|
-
|
|
41187
|
-
|
|
41359
|
+
// src/services/taskWorkerRunConfig.ts
|
|
41360
|
+
import { firstNonEmptyString, resolveRunScope } from "@axiom-lattice/protocols";
|
|
41361
|
+
function resolveWorkerRunScope(input) {
|
|
41362
|
+
const caller = resolveRunScope(input.runConfig);
|
|
41363
|
+
return {
|
|
41364
|
+
workspaceId: firstNonEmptyString(input.invocation.workspaceId) ?? caller.workspaceId,
|
|
41365
|
+
projectId: firstNonEmptyString(input.invocation.projectId) ?? caller.projectId
|
|
41366
|
+
};
|
|
41188
41367
|
}
|
|
41189
|
-
function
|
|
41190
|
-
|
|
41191
|
-
if (
|
|
41192
|
-
|
|
41193
|
-
|
|
41194
|
-
seen.add(value);
|
|
41195
|
-
try {
|
|
41196
|
-
if (value instanceof Date) return value.toISOString();
|
|
41197
|
-
if (Array.isArray(value)) {
|
|
41198
|
-
const limit2 = Math.min(value.length, maxEntries);
|
|
41199
|
-
const output2 = [];
|
|
41200
|
-
for (let index = 0; index < limit2; index += 1) {
|
|
41201
|
-
output2.push(truncateValue(value[index], depth + 1, maxDepth, maxEntries, maxStringLength, seen));
|
|
41202
|
-
}
|
|
41203
|
-
if (value.length > limit2) output2.push("[truncated:entries]");
|
|
41204
|
-
return output2;
|
|
41205
|
-
}
|
|
41206
|
-
const record = value;
|
|
41207
|
-
const output = {};
|
|
41208
|
-
const keys = Object.keys(record);
|
|
41209
|
-
const limit = Math.min(keys.length, maxEntries);
|
|
41210
|
-
for (let index = 0; index < limit; index += 1) {
|
|
41211
|
-
const key5 = keys[index];
|
|
41212
|
-
output[truncateString(key5, maxStringLength)] = truncateValue(
|
|
41213
|
-
record[key5],
|
|
41214
|
-
depth + 1,
|
|
41215
|
-
maxDepth,
|
|
41216
|
-
maxEntries,
|
|
41217
|
-
maxStringLength,
|
|
41218
|
-
seen
|
|
41219
|
-
);
|
|
41220
|
-
}
|
|
41221
|
-
if (keys.length > limit) output["[truncated]"] = true;
|
|
41222
|
-
return output;
|
|
41223
|
-
} finally {
|
|
41224
|
-
seen.delete(value);
|
|
41368
|
+
function applyWorkerRunScope(runConfig, scope) {
|
|
41369
|
+
const next = { ...runConfig };
|
|
41370
|
+
if (scope.workspaceId !== void 0) {
|
|
41371
|
+
next.workspaceId = scope.workspaceId;
|
|
41372
|
+
next["x-workspace-id"] = scope.workspaceId;
|
|
41225
41373
|
}
|
|
41226
|
-
|
|
41227
|
-
|
|
41228
|
-
|
|
41229
|
-
|
|
41230
|
-
|
|
41231
|
-
options.maxDepth ?? JSON_SAFE_MAX_DEPTH,
|
|
41232
|
-
options.maxEntries ?? JSON_SAFE_MAX_COLLECTION_ENTRIES,
|
|
41233
|
-
options.maxStringLength ?? JSON_SAFE_MAX_STRING_LENGTH,
|
|
41234
|
-
/* @__PURE__ */ new WeakSet()
|
|
41235
|
-
);
|
|
41374
|
+
if (scope.projectId !== void 0) {
|
|
41375
|
+
next.projectId = scope.projectId;
|
|
41376
|
+
next["x-project-id"] = scope.projectId;
|
|
41377
|
+
}
|
|
41378
|
+
return next;
|
|
41236
41379
|
}
|
|
41237
41380
|
|
|
41238
41381
|
// src/middlewares/taskMiddleware.ts
|
|
@@ -42077,7 +42220,7 @@ var manageTaskSchema = z70.object({
|
|
|
42077
42220
|
parentId: z70.string().optional().describe("Parent task ID for grouping subtasks"),
|
|
42078
42221
|
sourceId: z70.string().optional().describe("Source session/thread ID"),
|
|
42079
42222
|
context: z70.record(z70.unknown()).optional().describe("Additional context data"),
|
|
42080
|
-
ownerType: z70.enum(["user", "agent"]).optional().describe("Owner type. Defaults to
|
|
42223
|
+
ownerType: z70.enum(["user", "agent"]).optional().describe("Owner type. Defaults to the runtime actor: agent runtime (no user identity) -> 'agent', user runtime -> 'user'."),
|
|
42081
42224
|
ownerId: z70.string().optional().describe("Owner ID. Auto-filled from current user/agent if omitted"),
|
|
42082
42225
|
requireReview: z70.boolean().optional().describe("If true, agent completion pauses as interrupted(review_required) for HITL approval"),
|
|
42083
42226
|
dependencies: z70.array(z70.string()).optional().describe("List of task IDs that must be completed before this task can start"),
|
|
@@ -42246,8 +42389,9 @@ function createTaskMiddleware(options = {}) {
|
|
|
42246
42389
|
const trustedProject = authority.kind === "projectRoom" || authority.kind === "projectTask" ? authority.trusted : void 0;
|
|
42247
42390
|
const trustedScope = trustedProject?.projectTask ?? trustedProject?.projectRoom;
|
|
42248
42391
|
const tenantId2 = trustedScope?.tenantId ?? (rc.tenantId || "default");
|
|
42249
|
-
const
|
|
42250
|
-
const
|
|
42392
|
+
const runScope = resolveRunScope2(rc);
|
|
42393
|
+
const workspaceId = trustedScope?.workspaceId ?? runScope.workspaceId;
|
|
42394
|
+
const projectId = trustedScope?.projectId ?? runScope.projectId;
|
|
42251
42395
|
const revalidateCaller = async () => {
|
|
42252
42396
|
if (!trustedProject || trustedRosterExempt(trustedProject)) return void 0;
|
|
42253
42397
|
try {
|
|
@@ -42264,7 +42408,9 @@ function createTaskMiddleware(options = {}) {
|
|
|
42264
42408
|
return projectPolicyError(error);
|
|
42265
42409
|
}
|
|
42266
42410
|
}
|
|
42267
|
-
const
|
|
42411
|
+
const runtimeOwnerType = rc.user_id ? "user" : rc.assistant_id ? "agent" : "user";
|
|
42412
|
+
const requestedOwnerType = input.ownerType ?? runtimeOwnerType;
|
|
42413
|
+
const ownerId = input.ownerId || trustedScope?.assistantId || (requestedOwnerType === "agent" ? rc.assistant_id : null) || rc.user_id;
|
|
42268
42414
|
const store = getTaskStore();
|
|
42269
42415
|
const deleteOneTask = async (id) => {
|
|
42270
42416
|
if (delegatedTaskId && id !== delegatedTaskId) {
|
|
@@ -42333,7 +42479,7 @@ function createTaskMiddleware(options = {}) {
|
|
|
42333
42479
|
createScopeProjectId = createScopeProjectId ?? parentTask.projectId;
|
|
42334
42480
|
}
|
|
42335
42481
|
}
|
|
42336
|
-
const effectiveOwnerType = delegatedTaskId ? "agent" : trustedProject ? "agent" :
|
|
42482
|
+
const effectiveOwnerType = delegatedTaskId ? "agent" : trustedProject ? "agent" : requestedOwnerType;
|
|
42337
42483
|
const effectiveOwnerId = delegatedTaskId ? rc.assistant_id : ownerId;
|
|
42338
42484
|
if (delegatedTaskId && !effectiveOwnerId) {
|
|
42339
42485
|
return delegatedTaskScopeError(delegatedTaskId);
|
|
@@ -42359,6 +42505,14 @@ function createTaskMiddleware(options = {}) {
|
|
|
42359
42505
|
}
|
|
42360
42506
|
}
|
|
42361
42507
|
}
|
|
42508
|
+
if (!delegatedTaskId && (typeof effectiveOwnerId !== "string" || effectiveOwnerId.length === 0)) {
|
|
42509
|
+
return JSON.stringify({
|
|
42510
|
+
success: false,
|
|
42511
|
+
code: "TASK_OWNER_REQUIRED",
|
|
42512
|
+
error: "Cannot resolve task owner: no user or agent identity in this run.",
|
|
42513
|
+
hint: 'Provide an explicit ownerId, or retry with ownerType:"agent" if this run has an agent identity.'
|
|
42514
|
+
});
|
|
42515
|
+
}
|
|
42362
42516
|
if (effectiveOwnerType === "agent" && (input.result !== void 0 || input.failureReason !== void 0)) {
|
|
42363
42517
|
return JSON.stringify({
|
|
42364
42518
|
success: false,
|
|
@@ -43413,13 +43567,22 @@ function createTaskMiddleware(options = {}) {
|
|
|
43413
43567
|
try {
|
|
43414
43568
|
response = await handleManageTaskAction(input, config, validateExecutionResult, markMutation);
|
|
43415
43569
|
} catch (error) {
|
|
43416
|
-
if (
|
|
43570
|
+
if (error instanceof GraphInterrupt3) throw error;
|
|
43571
|
+
if (error instanceof ExecutionResultNotPendingError) {
|
|
43572
|
+
return JSON.stringify({
|
|
43573
|
+
success: false,
|
|
43574
|
+
code: "EXECUTION_RESULT_NOT_PENDING",
|
|
43575
|
+
taskId: error.taskId,
|
|
43576
|
+
executionResultId: error.executionResultId,
|
|
43577
|
+
error: error.message
|
|
43578
|
+
});
|
|
43579
|
+
}
|
|
43580
|
+
if (input.executionResultId) throw error;
|
|
43417
43581
|
return JSON.stringify({
|
|
43418
43582
|
success: false,
|
|
43419
|
-
code: "
|
|
43420
|
-
|
|
43421
|
-
|
|
43422
|
-
error: error.message
|
|
43583
|
+
code: "TASK_ACTION_FAILED",
|
|
43584
|
+
error: error instanceof Error ? error.message : String(error),
|
|
43585
|
+
hint: "The action did not complete. Fix the input or retry; do not repeat the identical call."
|
|
43423
43586
|
});
|
|
43424
43587
|
}
|
|
43425
43588
|
return reconcileExplicitExecutionResult(
|
|
@@ -43457,15 +43620,16 @@ function createTaskMiddleware(options = {}) {
|
|
|
43457
43620
|
assistant_id: invocation.agentId,
|
|
43458
43621
|
thread_id: invocation.threadId,
|
|
43459
43622
|
input: { message: invocation.message },
|
|
43460
|
-
runConfig:
|
|
43461
|
-
|
|
43462
|
-
|
|
43463
|
-
|
|
43464
|
-
|
|
43465
|
-
|
|
43466
|
-
|
|
43467
|
-
|
|
43468
|
-
|
|
43623
|
+
runConfig: applyWorkerRunScope(
|
|
43624
|
+
{
|
|
43625
|
+
...rc,
|
|
43626
|
+
assistant_id: invocation.agentId,
|
|
43627
|
+
thread_id: invocation.threadId,
|
|
43628
|
+
taskId: invocation.taskId,
|
|
43629
|
+
tenantId: invocation.tenantId
|
|
43630
|
+
},
|
|
43631
|
+
resolveWorkerRunScope({ invocation, runConfig: rc })
|
|
43632
|
+
)
|
|
43469
43633
|
});
|
|
43470
43634
|
const finalState = workerResult?.finalState;
|
|
43471
43635
|
return boundedWorkerObservation(finalState, void 0);
|
|
@@ -43480,7 +43644,7 @@ function createTaskMiddleware(options = {}) {
|
|
|
43480
43644
|
agentId,
|
|
43481
43645
|
actor,
|
|
43482
43646
|
callerThreadId: rc.thread_id,
|
|
43483
|
-
...trustedCaller ? { callerMembershipId: trustedCaller.membershipId, callerAssistantId: trustedCaller.assistantId } : {}
|
|
43647
|
+
...trustedCaller ? { callerMembershipId: trustedCaller.membershipId, callerAssistantId: trustedCaller.assistantId } : rc.assistant_id ? { callerAssistantId: rc.assistant_id } : {}
|
|
43484
43648
|
}));
|
|
43485
43649
|
};
|
|
43486
43650
|
return createMiddleware23({
|
|
@@ -43540,7 +43704,14 @@ function createTaskMiddleware(options = {}) {
|
|
|
43540
43704
|
task,
|
|
43541
43705
|
actor: getRuntimeActor2(rc) ?? "system",
|
|
43542
43706
|
...threadId ? { threadId } : {},
|
|
43543
|
-
|
|
43707
|
+
// A run that ended without its own lifecycle transition is a mechanical
|
|
43708
|
+
// failure, NOT HITL. Human-in-the-loop pauses arrive as GraphInterrupt
|
|
43709
|
+
// and never reach afterAgent.
|
|
43710
|
+
outcome: {
|
|
43711
|
+
kind: "failed",
|
|
43712
|
+
lifecycleHandled: false,
|
|
43713
|
+
error: "Run ended without a task lifecycle transition"
|
|
43714
|
+
}
|
|
43544
43715
|
});
|
|
43545
43716
|
}
|
|
43546
43717
|
taskRunRegistry.unregister(taskId);
|
|
@@ -43585,8 +43756,8 @@ changes only when acceptance criteria are truly met.
|
|
|
43585
43756
|
${TASK_CONVERGENCE_GUIDANCE}
|
|
43586
43757
|
|
|
43587
43758
|
### Ownership defaults
|
|
43588
|
-
- No params: ownerType defaults to
|
|
43589
|
-
- ownerType="agent": auto-fills ownerId from current agent (subtask for yourself)
|
|
43759
|
+
- No params: ownerType defaults to the runtime actor (user runtime -> current user's ID; agent runtime -> current agent's ID)
|
|
43760
|
+
- ownerType="agent": auto-fills ownerId from the current agent (subtask for yourself)
|
|
43590
43761
|
- Explicit ownerId: assign to a specific agent or user`;
|
|
43591
43762
|
const boundTaskId = request.state?.taskId;
|
|
43592
43763
|
const binding = typeof boundTaskId === "string" && boundTaskId ? renderTaskBinding(boundTaskId) : "";
|
|
@@ -43605,7 +43776,7 @@ ${TASK_CONVERGENCE_GUIDANCE}
|
|
|
43605
43776
|
description: `Manage persistent tasks and their activity timelines for user and agent tasks.
|
|
43606
43777
|
|
|
43607
43778
|
## Owner defaults
|
|
43608
|
-
- No ownerType/ownerId: auto-assigned to current user
|
|
43779
|
+
- No ownerType/ownerId: auto-assigned to the runtime actor (user runtime -> current user; agent runtime -> current agent)
|
|
43609
43780
|
- ownerType="agent" without ownerId: auto-assigned to current agent
|
|
43610
43781
|
- Explicit ownerId: assign to a specific agent (cross-agent delegation)
|
|
43611
43782
|
|
|
@@ -46689,6 +46860,7 @@ export {
|
|
|
46689
46860
|
generateDirectHumanProjectId,
|
|
46690
46861
|
generateToken,
|
|
46691
46862
|
getAgentClient,
|
|
46863
|
+
getAgentClientAsync,
|
|
46692
46864
|
getAgentConfig,
|
|
46693
46865
|
getAllAgentConfigs,
|
|
46694
46866
|
getAllBuiltInSkillMetas,
|