@axiom-lattice/core 4.3.0 → 4.4.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 +172 -49
- package/dist/index.d.ts +172 -49
- package/dist/index.js +1131 -501
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1072 -446
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1747,6 +1747,7 @@ __export(index_exports, {
|
|
|
1747
1747
|
TaskLifecycleNotifier: () => TaskLifecycleNotifier,
|
|
1748
1748
|
TaskLifecycleService: () => TaskLifecycleService,
|
|
1749
1749
|
TaskRunBridgeStoresRequiredError: () => TaskRunBridgeStoresRequiredError,
|
|
1750
|
+
TaskRunRegistry: () => TaskRunRegistry,
|
|
1750
1751
|
TaskStatus: () => TaskStatus,
|
|
1751
1752
|
TeamAgentGraphBuilder: () => TeamAgentGraphBuilder,
|
|
1752
1753
|
TenantPluginCatalog: () => TenantPluginCatalog,
|
|
@@ -1758,7 +1759,6 @@ __export(index_exports, {
|
|
|
1758
1759
|
VectorStoreProviderManager: () => VectorStoreProviderManager,
|
|
1759
1760
|
VolumeFilesystem: () => VolumeFilesystem,
|
|
1760
1761
|
abortWorkflowRun: () => abortWorkflowRun,
|
|
1761
|
-
agentHasManagedTaskCapability: () => agentHasManagedTaskCapability,
|
|
1762
1762
|
agentInstanceManager: () => agentInstanceManager,
|
|
1763
1763
|
agentLatticeManager: () => agentLatticeManager,
|
|
1764
1764
|
appendReconciliationWarning: () => appendReconciliationWarning,
|
|
@@ -1933,6 +1933,9 @@ __export(index_exports, {
|
|
|
1933
1933
|
projectTaskAdmissionNotifier: () => projectTaskAdmissionNotifier,
|
|
1934
1934
|
queueLatticeManager: () => queueLatticeManager,
|
|
1935
1935
|
readLoopBreakerConfig: () => readLoopBreakerConfig,
|
|
1936
|
+
reconcileAllTenantTaskRuns: () => reconcileAllTenantTaskRuns,
|
|
1937
|
+
reconcileStaleTaskRuns: () => reconcileStaleTaskRuns,
|
|
1938
|
+
reconcileTenantTaskRuns: () => reconcileTenantTaskRuns,
|
|
1936
1939
|
registerAgentLattice: () => registerAgentLattice,
|
|
1937
1940
|
registerAgentLatticeWithTenant: () => registerAgentLatticeWithTenant,
|
|
1938
1941
|
registerAgentLattices: () => registerAgentLattices,
|
|
@@ -1981,6 +1984,7 @@ __export(index_exports, {
|
|
|
1981
1984
|
storeLatticeManager: () => storeLatticeManager,
|
|
1982
1985
|
sttModelLatticeManager: () => sttModelLatticeManager,
|
|
1983
1986
|
taskLifecycleNotifier: () => taskLifecycleNotifier,
|
|
1987
|
+
taskRunRegistry: () => taskRunRegistry,
|
|
1984
1988
|
toJsonSchema: () => toJsonSchema,
|
|
1985
1989
|
toSafeStateExpr: () => toSafeStateExpr,
|
|
1986
1990
|
toolLatticeManager: () => toolLatticeManager,
|
|
@@ -13205,7 +13209,7 @@ function readLoopBreakerConfig(env = process.env) {
|
|
|
13205
13209
|
return {
|
|
13206
13210
|
repeatWarn: parse(env.AGENT_REPEATED_TOOL_CALL_WARN, 3),
|
|
13207
13211
|
repeatStop: parse(env.AGENT_REPEATED_TOOL_CALL_STOP, 5),
|
|
13208
|
-
runLimit: parse(env.AGENT_TOOL_CALL_RUN_LIMIT,
|
|
13212
|
+
runLimit: parse(env.AGENT_TOOL_CALL_RUN_LIMIT, 300),
|
|
13209
13213
|
skillRunLimit: parse(env.AGENT_SKILL_CALL_RUN_LIMIT, 8)
|
|
13210
13214
|
};
|
|
13211
13215
|
}
|
|
@@ -16889,6 +16893,41 @@ var AgentManager = class _AgentManager {
|
|
|
16889
16893
|
}
|
|
16890
16894
|
};
|
|
16891
16895
|
|
|
16896
|
+
// src/services/TaskExecutionContext.ts
|
|
16897
|
+
var DELEGATED_WORKER_SCOPE_TOKEN = Symbol("delegated-worker-scope");
|
|
16898
|
+
var delegatedWorkerScopeSecret = Object.freeze({});
|
|
16899
|
+
function createDelegatedWorkerRunConfig(taskId) {
|
|
16900
|
+
return {
|
|
16901
|
+
taskId,
|
|
16902
|
+
delegatedTaskId: taskId,
|
|
16903
|
+
taskExecutionRole: "worker",
|
|
16904
|
+
execution: { taskId },
|
|
16905
|
+
[DELEGATED_WORKER_SCOPE_TOKEN]: delegatedWorkerScopeSecret
|
|
16906
|
+
};
|
|
16907
|
+
}
|
|
16908
|
+
function getDelegatedTaskId(runConfig) {
|
|
16909
|
+
return runConfig[DELEGATED_WORKER_SCOPE_TOKEN] === delegatedWorkerScopeSecret && runConfig.taskExecutionRole === "worker" && typeof runConfig.taskId === "string" && runConfig.taskId.trim() !== "" && typeof runConfig.delegatedTaskId === "string" && runConfig.taskId === runConfig.delegatedTaskId ? runConfig.taskId : void 0;
|
|
16910
|
+
}
|
|
16911
|
+
function hasDelegatedWorkerToken(runConfig) {
|
|
16912
|
+
return Object.prototype.hasOwnProperty.call(runConfig, DELEGATED_WORKER_SCOPE_TOKEN);
|
|
16913
|
+
}
|
|
16914
|
+
function preserveDelegatedWorkerContext(source, target) {
|
|
16915
|
+
const delegatedTaskId = getDelegatedTaskId(source);
|
|
16916
|
+
if (!delegatedTaskId) return;
|
|
16917
|
+
target.taskId = delegatedTaskId;
|
|
16918
|
+
target.delegatedTaskId = delegatedTaskId;
|
|
16919
|
+
target.taskExecutionRole = "worker";
|
|
16920
|
+
target.execution = { taskId: delegatedTaskId };
|
|
16921
|
+
target[DELEGATED_WORKER_SCOPE_TOKEN] = delegatedWorkerScopeSecret;
|
|
16922
|
+
}
|
|
16923
|
+
function stripDelegatedWorkerContext(target) {
|
|
16924
|
+
delete target.taskId;
|
|
16925
|
+
delete target.delegatedTaskId;
|
|
16926
|
+
delete target.taskExecutionRole;
|
|
16927
|
+
delete target.execution;
|
|
16928
|
+
delete target[DELEGATED_WORKER_SCOPE_TOKEN];
|
|
16929
|
+
}
|
|
16930
|
+
|
|
16892
16931
|
// src/agent_worker/agent_worker_graph.ts
|
|
16893
16932
|
var AgentWorkerState = import_langgraph5.Annotation.Root({
|
|
16894
16933
|
// Input parameters
|
|
@@ -16913,6 +16952,13 @@ var AgentWorkerState = import_langgraph5.Annotation.Root({
|
|
|
16913
16952
|
reducer: (x, y) => y ?? x,
|
|
16914
16953
|
default: () => void 0
|
|
16915
16954
|
}),
|
|
16955
|
+
// Optional persistent TaskItem binding. Rebuilt into an authentic delegated
|
|
16956
|
+
// worker scope on every execute (the in-process scope symbol cannot survive
|
|
16957
|
+
// LangGraph checkpointing, so it is re-derived from this plain task id).
|
|
16958
|
+
taskId: (0, import_langgraph5.Annotation)({
|
|
16959
|
+
reducer: (x, y) => y ?? x,
|
|
16960
|
+
default: () => ""
|
|
16961
|
+
}),
|
|
16916
16962
|
// Execution result
|
|
16917
16963
|
result: (0, import_langgraph5.Annotation)({
|
|
16918
16964
|
reducer: (x, y) => y ?? x,
|
|
@@ -16930,14 +16976,15 @@ var AgentWorkerState = import_langgraph5.Annotation.Root({
|
|
|
16930
16976
|
})
|
|
16931
16977
|
});
|
|
16932
16978
|
async function executeNode(state) {
|
|
16933
|
-
const { assistant_id, thread_id, input, command2, runConfig } = state;
|
|
16979
|
+
const { assistant_id, thread_id, input, command2, runConfig, taskId } = state;
|
|
16980
|
+
const effectiveRunConfig = taskId ? { ...runConfig ?? {}, ...createDelegatedWorkerRunConfig(taskId) } : runConfig;
|
|
16934
16981
|
const callParams = {
|
|
16935
16982
|
assistant_id,
|
|
16936
16983
|
"x-tenant-id": runConfig?.tenantId,
|
|
16937
16984
|
thread_id,
|
|
16938
16985
|
input,
|
|
16939
16986
|
command: command2,
|
|
16940
|
-
runConfig
|
|
16987
|
+
runConfig: effectiveRunConfig
|
|
16941
16988
|
};
|
|
16942
16989
|
const result = await AgentManager.getInstance().callAgentInQueue(
|
|
16943
16990
|
callParams,
|
|
@@ -18288,38 +18335,6 @@ var CapabilityRuntimeResolver = class {
|
|
|
18288
18335
|
}
|
|
18289
18336
|
};
|
|
18290
18337
|
|
|
18291
|
-
// src/services/TaskExecutionContext.ts
|
|
18292
|
-
var DELEGATED_WORKER_SCOPE_TOKEN = Symbol("delegated-worker-scope");
|
|
18293
|
-
var delegatedWorkerScopeSecret = Object.freeze({});
|
|
18294
|
-
function createDelegatedWorkerRunConfig(taskId) {
|
|
18295
|
-
return {
|
|
18296
|
-
taskId,
|
|
18297
|
-
delegatedTaskId: taskId,
|
|
18298
|
-
taskExecutionRole: "worker",
|
|
18299
|
-
[DELEGATED_WORKER_SCOPE_TOKEN]: delegatedWorkerScopeSecret
|
|
18300
|
-
};
|
|
18301
|
-
}
|
|
18302
|
-
function getDelegatedTaskId(runConfig) {
|
|
18303
|
-
return runConfig[DELEGATED_WORKER_SCOPE_TOKEN] === delegatedWorkerScopeSecret && runConfig.taskExecutionRole === "worker" && typeof runConfig.taskId === "string" && runConfig.taskId.trim() !== "" && typeof runConfig.delegatedTaskId === "string" && runConfig.taskId === runConfig.delegatedTaskId ? runConfig.taskId : void 0;
|
|
18304
|
-
}
|
|
18305
|
-
function hasDelegatedWorkerToken(runConfig) {
|
|
18306
|
-
return Object.prototype.hasOwnProperty.call(runConfig, DELEGATED_WORKER_SCOPE_TOKEN);
|
|
18307
|
-
}
|
|
18308
|
-
function preserveDelegatedWorkerContext(source, target) {
|
|
18309
|
-
const delegatedTaskId = getDelegatedTaskId(source);
|
|
18310
|
-
if (!delegatedTaskId) return;
|
|
18311
|
-
target.taskId = delegatedTaskId;
|
|
18312
|
-
target.delegatedTaskId = delegatedTaskId;
|
|
18313
|
-
target.taskExecutionRole = "worker";
|
|
18314
|
-
target[DELEGATED_WORKER_SCOPE_TOKEN] = delegatedWorkerScopeSecret;
|
|
18315
|
-
}
|
|
18316
|
-
function stripDelegatedWorkerContext(target) {
|
|
18317
|
-
delete target.taskId;
|
|
18318
|
-
delete target.delegatedTaskId;
|
|
18319
|
-
delete target.taskExecutionRole;
|
|
18320
|
-
delete target[DELEGATED_WORKER_SCOPE_TOKEN];
|
|
18321
|
-
}
|
|
18322
|
-
|
|
18323
18338
|
// src/services/TrustedAgentDispatchCapability.ts
|
|
18324
18339
|
var TRUSTED_AGENT_DISPATCH = Symbol("axiom.trustedAgentDispatch");
|
|
18325
18340
|
|
|
@@ -18483,8 +18498,22 @@ function sanitizeCallerRunConfig(value, preserveDelegatedContext = true) {
|
|
|
18483
18498
|
} else {
|
|
18484
18499
|
stripDelegatedWorkerContext(callerRunConfig);
|
|
18485
18500
|
}
|
|
18501
|
+
preserveExecutionBinding(value, callerRunConfig);
|
|
18486
18502
|
return callerRunConfig;
|
|
18487
18503
|
}
|
|
18504
|
+
function preserveExecutionBinding(source, target) {
|
|
18505
|
+
if (typeof source !== "object" || source === null || Array.isArray(source)) return;
|
|
18506
|
+
const execution = (0, import_protocols10.descriptorDataValue)(Object.getOwnPropertyDescriptor(source, "execution"))?.value;
|
|
18507
|
+
if (typeof execution !== "object" || execution === null || Array.isArray(execution)) return;
|
|
18508
|
+
const taskId = (0, import_protocols10.descriptorDataValue)(Object.getOwnPropertyDescriptor(execution, "taskId"))?.value;
|
|
18509
|
+
if (typeof taskId !== "string" || taskId.trim() === "") return;
|
|
18510
|
+
Object.defineProperty(target, "execution", {
|
|
18511
|
+
value: { taskId },
|
|
18512
|
+
enumerable: true,
|
|
18513
|
+
configurable: true,
|
|
18514
|
+
writable: true
|
|
18515
|
+
});
|
|
18516
|
+
}
|
|
18488
18517
|
function sanitizeExecutionRunConfig(value) {
|
|
18489
18518
|
return cloneRunConfig(value, false);
|
|
18490
18519
|
}
|
|
@@ -18604,6 +18633,7 @@ function checkpointCapabilityRevision(state) {
|
|
|
18604
18633
|
}
|
|
18605
18634
|
var QUEUE_PROCESSOR_RETRY_BASE_MS = 100;
|
|
18606
18635
|
var QUEUE_PROCESSOR_MAX_RETRIES = 3;
|
|
18636
|
+
var AGENT_RECURSION_LIMIT = 1e3;
|
|
18607
18637
|
function hasExactKeys(record, required, optional = []) {
|
|
18608
18638
|
const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
|
|
18609
18639
|
return required.every((key5) => Object.prototype.hasOwnProperty.call(record, key5)) && Reflect.ownKeys(record).every((key5) => typeof key5 === "string" && allowed.has(key5));
|
|
@@ -18656,7 +18686,7 @@ var Agent = class {
|
|
|
18656
18686
|
...executionRunConfig,
|
|
18657
18687
|
runConfig: executionRunConfig
|
|
18658
18688
|
},
|
|
18659
|
-
recursionLimit:
|
|
18689
|
+
recursionLimit: AGENT_RECURSION_LIMIT,
|
|
18660
18690
|
signal
|
|
18661
18691
|
}
|
|
18662
18692
|
);
|
|
@@ -18731,7 +18761,7 @@ var Agent = class {
|
|
|
18731
18761
|
},
|
|
18732
18762
|
streamMode: ["updates", "messages"],
|
|
18733
18763
|
subgraphs: false,
|
|
18734
|
-
recursionLimit:
|
|
18764
|
+
recursionLimit: AGENT_RECURSION_LIMIT,
|
|
18735
18765
|
signal
|
|
18736
18766
|
}
|
|
18737
18767
|
);
|
|
@@ -19229,6 +19259,15 @@ var Agent = class {
|
|
|
19229
19259
|
configurable: true,
|
|
19230
19260
|
writable: true
|
|
19231
19261
|
});
|
|
19262
|
+
const trustedTaskId = parsed.projectTask?.taskId;
|
|
19263
|
+
if (trustedTaskId) {
|
|
19264
|
+
Object.defineProperty(base, "execution", {
|
|
19265
|
+
value: { taskId: trustedTaskId },
|
|
19266
|
+
enumerable: true,
|
|
19267
|
+
configurable: true,
|
|
19268
|
+
writable: true
|
|
19269
|
+
});
|
|
19270
|
+
}
|
|
19232
19271
|
return base;
|
|
19233
19272
|
}
|
|
19234
19273
|
getHumanPendingContent(message) {
|
|
@@ -19432,7 +19471,7 @@ var Agent = class {
|
|
|
19432
19471
|
...executionRunConfig,
|
|
19433
19472
|
runConfig: executionRunConfig
|
|
19434
19473
|
},
|
|
19435
|
-
recursionLimit:
|
|
19474
|
+
recursionLimit: AGENT_RECURSION_LIMIT,
|
|
19436
19475
|
signal
|
|
19437
19476
|
}
|
|
19438
19477
|
);
|
|
@@ -19543,7 +19582,7 @@ var Agent = class {
|
|
|
19543
19582
|
},
|
|
19544
19583
|
streamMode: ["updates", "messages"],
|
|
19545
19584
|
subgraphs: false,
|
|
19546
|
-
recursionLimit:
|
|
19585
|
+
recursionLimit: AGENT_RECURSION_LIMIT,
|
|
19547
19586
|
signal
|
|
19548
19587
|
}
|
|
19549
19588
|
);
|
|
@@ -20300,6 +20339,20 @@ var agentInstanceManager = AgentInstanceManager.getInstance();
|
|
|
20300
20339
|
var DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools.";
|
|
20301
20340
|
var EXCLUDED_STATE_KEYS = ["messages", "todos", "jumpTo"];
|
|
20302
20341
|
var DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.";
|
|
20342
|
+
function createGeneralPurposeAgent(options) {
|
|
20343
|
+
const middleware = [...options.middleware];
|
|
20344
|
+
if (options.interruptOn) {
|
|
20345
|
+
middleware.push((0, import_langchain53.humanInTheLoopMiddleware)({ interruptOn: options.interruptOn }));
|
|
20346
|
+
}
|
|
20347
|
+
return (0, import_langchain53.createAgent)({
|
|
20348
|
+
model: options.model,
|
|
20349
|
+
systemPrompt: DEFAULT_SUBAGENT_PROMPT,
|
|
20350
|
+
tools: options.tools,
|
|
20351
|
+
middleware,
|
|
20352
|
+
checkpointer: getCheckpointSaver("default"),
|
|
20353
|
+
name: "general-purpose"
|
|
20354
|
+
});
|
|
20355
|
+
}
|
|
20303
20356
|
function getTaskToolDescription(subagentDescriptions) {
|
|
20304
20357
|
return subagentDescriptions.length > 0 ? `
|
|
20305
20358
|
Launch an ephemeral subagent to handle complex, multi-step independent tasks with isolated context windows.
|
|
@@ -20479,21 +20532,12 @@ function getSubagents(options) {
|
|
|
20479
20532
|
const agents = {};
|
|
20480
20533
|
const subagentDescriptions = [];
|
|
20481
20534
|
if (generalPurposeAgent) {
|
|
20482
|
-
|
|
20483
|
-
if (defaultInterruptOn) {
|
|
20484
|
-
generalPurposeMiddleware.push(
|
|
20485
|
-
(0, import_langchain53.humanInTheLoopMiddleware)({ interruptOn: defaultInterruptOn })
|
|
20486
|
-
);
|
|
20487
|
-
}
|
|
20488
|
-
const generalPurposeSubagent = (0, import_langchain53.createAgent)({
|
|
20535
|
+
agents["general-purpose"] = createGeneralPurposeAgent({
|
|
20489
20536
|
model: defaultModel,
|
|
20490
|
-
systemPrompt: DEFAULT_SUBAGENT_PROMPT,
|
|
20491
20537
|
tools: defaultTools,
|
|
20492
|
-
middleware:
|
|
20493
|
-
|
|
20494
|
-
name: "general-purpose"
|
|
20538
|
+
middleware: defaultSubagentMiddleware,
|
|
20539
|
+
interruptOn: defaultInterruptOn
|
|
20495
20540
|
});
|
|
20496
|
-
agents["general-purpose"] = generalPurposeSubagent;
|
|
20497
20541
|
subagentDescriptions.push(
|
|
20498
20542
|
`- general-purpose: ${DEFAULT_GENERAL_PURPOSE_DESCRIPTION}`
|
|
20499
20543
|
);
|
|
@@ -23932,6 +23976,7 @@ ${BASE_PROMPT}` : BASE_PROMPT;
|
|
|
23932
23976
|
}
|
|
23933
23977
|
|
|
23934
23978
|
// src/agent_lattice/builders/DeepAgentGraphBuilder.ts
|
|
23979
|
+
var import_protocols15 = require("@axiom-lattice/protocols");
|
|
23935
23980
|
init_MemoryLatticeManager();
|
|
23936
23981
|
var DeepAgentGraphBuilder = class {
|
|
23937
23982
|
/**
|
|
@@ -23981,6 +24026,28 @@ var DeepAgentGraphBuilder = class {
|
|
|
23981
24026
|
backend: filesystemBackend,
|
|
23982
24027
|
middleware: middlewares
|
|
23983
24028
|
});
|
|
24029
|
+
if (middlewares.some((candidate) => candidate.name === "TaskMiddleware") && agentLattice.config.key) {
|
|
24030
|
+
const tenantId2 = params.tenantId ?? "default";
|
|
24031
|
+
const generalPurposeKey = `${agentLattice.config.key}-general-purpose`;
|
|
24032
|
+
if (!agentLatticeManager.hasAgentLatticeWithTenant(tenantId2, generalPurposeKey)) {
|
|
24033
|
+
const generalPurposeAgent = createGeneralPurposeAgent({
|
|
24034
|
+
model: params.model,
|
|
24035
|
+
tools,
|
|
24036
|
+
middleware: middlewares
|
|
24037
|
+
});
|
|
24038
|
+
agentLatticeManager.registerWithTenant(tenantId2, generalPurposeKey, {
|
|
24039
|
+
config: {
|
|
24040
|
+
key: generalPurposeKey,
|
|
24041
|
+
name: "general-purpose",
|
|
24042
|
+
description: DEFAULT_GENERAL_PURPOSE_DESCRIPTION,
|
|
24043
|
+
type: import_protocols15.AgentType.REACT,
|
|
24044
|
+
prompt: DEFAULT_SUBAGENT_PROMPT,
|
|
24045
|
+
tenantId: tenantId2
|
|
24046
|
+
},
|
|
24047
|
+
client: generalPurposeAgent
|
|
24048
|
+
});
|
|
24049
|
+
}
|
|
24050
|
+
}
|
|
23984
24051
|
return deepAgent;
|
|
23985
24052
|
}
|
|
23986
24053
|
};
|
|
@@ -25932,11 +25999,11 @@ _A2ARemoteClient.MAX_CACHED_TASKS = 100;
|
|
|
25932
25999
|
var A2ARemoteClient = _A2ARemoteClient;
|
|
25933
26000
|
|
|
25934
26001
|
// src/agent_lattice/builders/RemoteAgentGraphBuilder.ts
|
|
25935
|
-
var
|
|
26002
|
+
var import_protocols16 = require("@axiom-lattice/protocols");
|
|
25936
26003
|
init_MemoryLatticeManager();
|
|
25937
26004
|
var RemoteAgentGraphBuilder = class {
|
|
25938
26005
|
async build(agentLattice, params) {
|
|
25939
|
-
if (agentLattice.config.type !==
|
|
26006
|
+
if (agentLattice.config.type !== import_protocols16.AgentType.A2A_REMOTE) {
|
|
25940
26007
|
throw new Error(
|
|
25941
26008
|
`RemoteAgentGraphBuilder received wrong agent type: ${agentLattice.config.type}`
|
|
25942
26009
|
);
|
|
@@ -26001,7 +26068,7 @@ function extractLastHumanMessage(messages) {
|
|
|
26001
26068
|
// src/agent_lattice/builders/WorkflowAgentGraphBuilder.ts
|
|
26002
26069
|
var import_langchain61 = require("langchain");
|
|
26003
26070
|
init_MemoryLatticeManager();
|
|
26004
|
-
var
|
|
26071
|
+
var import_protocols17 = require("@axiom-lattice/protocols");
|
|
26005
26072
|
init_compile();
|
|
26006
26073
|
|
|
26007
26074
|
// src/agent_lattice/builders/middlewareSanitize.ts
|
|
@@ -26039,7 +26106,7 @@ ${configPrompt}` : base;
|
|
|
26039
26106
|
}
|
|
26040
26107
|
var WorkflowAgentGraphBuilder = class {
|
|
26041
26108
|
async build(agentLattice, params) {
|
|
26042
|
-
if (!(0,
|
|
26109
|
+
if (!(0, import_protocols17.isWorkflowAgentConfig)(agentLattice.config)) {
|
|
26043
26110
|
throw new Error(
|
|
26044
26111
|
`WorkflowAgentGraphBuilder received wrong agent type: ${agentLattice.config.type}`
|
|
26045
26112
|
);
|
|
@@ -26177,7 +26244,7 @@ var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
|
26177
26244
|
};
|
|
26178
26245
|
|
|
26179
26246
|
// src/agent_lattice/builders/AgentParamsBuilder.ts
|
|
26180
|
-
var
|
|
26247
|
+
var import_protocols18 = require("@axiom-lattice/protocols");
|
|
26181
26248
|
var AgentParamsBuilder = class {
|
|
26182
26249
|
/**
|
|
26183
26250
|
* constructor
|
|
@@ -26195,8 +26262,8 @@ var AgentParamsBuilder = class {
|
|
|
26195
26262
|
* @returns Agent build parameters
|
|
26196
26263
|
*/
|
|
26197
26264
|
async buildParams(agentLattice, options) {
|
|
26198
|
-
const skills = (0,
|
|
26199
|
-
const toolKeys = options?.overrideTools || (0,
|
|
26265
|
+
const skills = (0, import_protocols18.isDeepAgentConfig)(agentLattice.config) || (0, import_protocols18.isProcessingAgentConfig)(agentLattice.config) ? agentLattice.config.skillCategories : void 0;
|
|
26266
|
+
const toolKeys = options?.overrideTools || (0, import_protocols18.getToolsFromConfig)(agentLattice.config);
|
|
26200
26267
|
const tenantId2 = agentLattice.config.tenantId || "default";
|
|
26201
26268
|
const tools = toolKeys.map((toolKey) => {
|
|
26202
26269
|
const toolLattice = toolLatticeManager.getToolLatticeWithTenant(tenantId2, toolKey) ?? toolLatticeManager.getToolLatticeWithTenant("default", toolKey);
|
|
@@ -26215,7 +26282,7 @@ var AgentParamsBuilder = class {
|
|
|
26215
26282
|
if (!model) {
|
|
26216
26283
|
throw new Error(`Model "${modelKey}" does not exist`);
|
|
26217
26284
|
}
|
|
26218
|
-
const subAgentKeys = (0,
|
|
26285
|
+
const subAgentKeys = (0, import_protocols18.getSubAgentsFromConfig)(agentLattice.config);
|
|
26219
26286
|
const subAgents = await Promise.all(subAgentKeys.map(async (agentKey) => {
|
|
26220
26287
|
const subAgentLattice = await this.getAgentLatticeFunc(agentKey);
|
|
26221
26288
|
if (!subAgentLattice) {
|
|
@@ -26232,7 +26299,7 @@ var AgentParamsBuilder = class {
|
|
|
26232
26299
|
}));
|
|
26233
26300
|
const resolvedSubAgents = subAgents.filter((s) => s !== null);
|
|
26234
26301
|
let internalSubAgents = [];
|
|
26235
|
-
if ((0,
|
|
26302
|
+
if ((0, import_protocols18.isDeepAgentConfig)(agentLattice.config) || (0, import_protocols18.isProcessingAgentConfig)(agentLattice.config)) {
|
|
26236
26303
|
internalSubAgents = agentLattice.config.internalSubAgents?.map((i) => ({
|
|
26237
26304
|
key: i.key,
|
|
26238
26305
|
config: i
|
|
@@ -26710,9 +26777,15 @@ For human judgment, use the actual HITL payload \`status: "interrupted"\` plus
|
|
|
26710
26777
|
handled by the configured HITL lifecycle; \`review_required\` is not a task status.
|
|
26711
26778
|
|
|
26712
26779
|
Create the active parent and each started subtask as records: \`manage_task
|
|
26713
|
-
create\` always persists \`pending\`.
|
|
26714
|
-
|
|
26715
|
-
|
|
26780
|
+
create\` always persists \`pending\`. **Process the task you were assigned in this
|
|
26781
|
+
run: set it \`in_progress\` with \`manage_task set_status\` when you start (a
|
|
26782
|
+
dispatched task is claimed automatically by the engine).** To bring
|
|
26783
|
+
in a more suitable expert, create a subtask (\`pending\`) and dispatch THAT with
|
|
26784
|
+
\`task { taskId, agentId }\` (a specialist, or agentId "general-purpose" to run your
|
|
26785
|
+
own capabilities in an isolated run). **Never re-dispatch the task you are
|
|
26786
|
+
currently processing** \u2014 delegating to an expert means giving them a child task,
|
|
26787
|
+
not handing over your own. Report the outcome with \`set_status completed\` (result
|
|
26788
|
+
+ beliefImpact), \`failed\`, or \`interrupted\`. Use \`pending\` only for future or
|
|
26716
26789
|
dependency-blocked work.
|
|
26717
26790
|
Before marking the parent completed, call \`list(parentId)\`: every child must
|
|
26718
26791
|
be completed or cancelled, while a failed or interrupted child blocks completion
|
|
@@ -28003,34 +28076,24 @@ Renew HITL approval when a foundational assumption or authority boundary changes
|
|
|
28003
28076
|
|
|
28004
28077
|
## Skill Loading Policy
|
|
28005
28078
|
|
|
28006
|
-
Visible in <available_skills> does not mean loaded.
|
|
28007
|
-
|
|
28008
|
-
|
|
28009
|
-
|
|
28010
|
-
|
|
28011
|
-
- [[
|
|
28012
|
-
|
|
28013
|
-
|
|
28014
|
-
|
|
28015
|
-
|
|
28016
|
-
|
|
28017
|
-
-
|
|
28018
|
-
|
|
28019
|
-
-
|
|
28020
|
-
|
|
28021
|
-
|
|
28022
|
-
|
|
28023
|
-
|
|
28024
|
-
- Placing or authoring knowledge files (company vs project level) \u2192 [[knowledge-management]]
|
|
28025
|
-
|
|
28026
|
-
If a Tier 2 load fails, retry once, then stop and tell the user which
|
|
28027
|
-
capability is unavailable. Do not improvise the scenario from partial knowledge.
|
|
28028
|
-
|
|
28029
|
-
### Tier 3 \u2014 Reference (load on demand, never preload)
|
|
28030
|
-
Deep details reachable through wiki-links inside loaded skills, and plugin
|
|
28031
|
-
skills outside this chain (for example task-definition for non-architect
|
|
28032
|
-
agents, or sandbox-plugins-authoring for the \`plugin-builder\` agent). Load one
|
|
28033
|
-
only when the current step actually needs it.
|
|
28079
|
+
Visible in <available_skills> does not mean loaded. Load a skill only when the
|
|
28080
|
+
current step actually requires its procedure \u2014 one at a time, never preloaded.
|
|
28081
|
+
Do not load skills speculatively or to "see what exists": inspect existing
|
|
28082
|
+
assets with a bounded read-only survey, not by loading skill content.
|
|
28083
|
+
|
|
28084
|
+
- [[agent-architecture]] (this skill) \u2014 loaded at session start by the bootstrap
|
|
28085
|
+
prompt; it is the shared policy and router.
|
|
28086
|
+
- [[task-tracking]] \u2014 load right before your first \`manage_task\` call; Task
|
|
28087
|
+
management is the planning surface (gated again under Architect Task Policy).
|
|
28088
|
+
- Procedure skills \u2014 [[agent-build]], [[design-workflow]],
|
|
28089
|
+
[[document-learning-learn-capability]], [[eval-verify]], [[completion-gate]],
|
|
28090
|
+
[[review-agent]], [[knowledge-management]]: load the ONE that owns the step you
|
|
28091
|
+
are about to perform, immediately before performing it. Never preload the chain.
|
|
28092
|
+
- Reference and plugin skills (deep wiki-links, task-definition, sandbox authoring,
|
|
28093
|
+
and any plugin skills): load only when the current step needs them; never preload.
|
|
28094
|
+
|
|
28095
|
+
Loading a skill is a tool call, not a plan. If a required load fails, retry once,
|
|
28096
|
+
then stop and tell the user which capability is unavailable.
|
|
28034
28097
|
|
|
28035
28098
|
## Agent Forms and Routing
|
|
28036
28099
|
- **Capability** (\`react\`) for bounded direct work: [[agent-build]]
|
|
@@ -28043,9 +28106,19 @@ only when the current step actually needs it.
|
|
|
28043
28106
|
- **Tenant plugin** (sandbox-authored tool + optional HTML UI) \u2192 use the \`plugin-builder\` agent, or load [[sandbox-plugins-authoring]].
|
|
28044
28107
|
|
|
28045
28108
|
## Architect Task Policy
|
|
28046
|
-
The Agent Architect
|
|
28047
|
-
|
|
28109
|
+
The Agent Architect MUST use persistent TaskItems as its single working surface;
|
|
28110
|
+
Architect must not use \`write_todos\` for independently verifiable outcomes, and
|
|
28111
|
+
working without a corresponding TaskItem is a policy violation.
|
|
28112
|
+
Create a persistent child only for an independently verifiable
|
|
28048
28113
|
outcome; tool calls and file reads are actions inside the active Task.
|
|
28114
|
+
**Each task is your evidence ledger**: its Acceptance Criteria + Belief State define
|
|
28115
|
+
what counts as evidence, the work runs inside your own run (eval / \`invoke_agent\` for
|
|
28116
|
+
subject agents) and produces that evidence, and the parent completes only when the
|
|
28117
|
+
evidence is sufficient. Process the task you were assigned in this run; set it
|
|
28118
|
+
\`in_progress\` with \`manage_task set_status\` when you start. Delegate a subtask only
|
|
28119
|
+
when it belongs to another agent \u2014 create it (\`pending\`) and dispatch it with
|
|
28120
|
+
\`task { taskId, agentId }\`. To exercise a designed/subject agent, use eval /
|
|
28121
|
+
\`invoke_agent\` inside your own run instead of \`task\` dispatch.
|
|
28049
28122
|
**MANDATORY: before your first \`manage_task\` call in this session, load
|
|
28050
28123
|
[[task-tracking]] with the \`skill\` tool.** Do not create, update, or transition
|
|
28051
28124
|
any Task until it is loaded. If the load fails, retry once, then tell the user
|
|
@@ -28116,11 +28189,11 @@ When a room request is actionable work, decide between two paths:
|
|
|
28116
28189
|
\`assistantId\`, then dispatch it with
|
|
28117
28190
|
\`task { taskId, agentId: <bot assistantId> }\` so the specialist actually runs
|
|
28118
28191
|
(creating the task alone starts nothing). \`task\` transfers the task owner to
|
|
28119
|
-
\`agentId\` and
|
|
28120
|
-
|
|
28121
|
-
\`
|
|
28122
|
-
acceptance criteria in the task description so the assigned bot can
|
|
28123
|
-
own work.
|
|
28192
|
+
\`agentId\` and runs it in an isolated thread; the target does not need task
|
|
28193
|
+
tools \u2014 if it has \`manage_task\` it records status itself, otherwise reconcile
|
|
28194
|
+
its returned \`executionResultId\` with \`manage_task\` update. State the expected output
|
|
28195
|
+
and acceptance criteria in the task description so the assigned bot can
|
|
28196
|
+
verify its own work.
|
|
28124
28197
|
|
|
28125
28198
|
## Discovering bots
|
|
28126
28199
|
Before delegating, call \`list_room_roster\` to see the active room bots and their
|
|
@@ -28271,9 +28344,15 @@ criteria are truly met \u2014 never as a workaround.
|
|
|
28271
28344
|
uncertainties, with no required minimum and a maximum of seven:
|
|
28272
28345
|
\`manage_task create(title: <goal>, description: <contract + Belief State>, ownerType: "agent")\`
|
|
28273
28346
|
\`create\` always yields a \`pending\` record \u2014 it never starts execution. Record
|
|
28274
|
-
the returned parent task id, then
|
|
28275
|
-
\`
|
|
28276
|
-
\`
|
|
28347
|
+
the returned parent task id, then **process it in this run**, setting it
|
|
28348
|
+
\`in_progress\` with \`manage_task set_status\` when you start. To decompose, create each subtask
|
|
28349
|
+
with \`manage_task create\` (\`pending\`) and delegate it with \`task { taskId,
|
|
28350
|
+
agentId }\` to the agent that should execute it (a specialist, or
|
|
28351
|
+
"general-purpose" for your own capabilities). The executor does not need
|
|
28352
|
+
\`manage_task\`: it returns an observation and \`executionResultId\`, and the caller
|
|
28353
|
+
records the outcome with \`manage_task\`. To exercise a subject application agent,
|
|
28354
|
+
use eval cases / \`invoke_agent\` inside your own run \u2014 \`task\` dispatch is
|
|
28355
|
+
delegation of persistent work, not an evaluation mechanism.
|
|
28277
28356
|
- **Create a subtask for a verifiable result**, not per phase: identify its
|
|
28278
28357
|
deliverable, define observable acceptance criteria and required evidence, and
|
|
28279
28358
|
state positive and negative result branches under Targets / Expected Impact
|
|
@@ -28298,10 +28377,15 @@ ${TASK_BELIEF_REFERENCE_EXAMPLE}
|
|
|
28298
28377
|
|
|
28299
28378
|
## Status discipline \u2014 MANDATORY
|
|
28300
28379
|
|
|
28380
|
+
- Execution ownership: process the task you were assigned in this run; set it
|
|
28381
|
+
\`in_progress\` with \`manage_task set_status\` when you start. To involve a more
|
|
28382
|
+
suitable expert, create a subtask and dispatch it with \`task { taskId, agentId }\`
|
|
28383
|
+
\u2014 never re-dispatch the task you are processing. Report the outcome with
|
|
28384
|
+
\`set_status completed\` (result + beliefImpact), \`failed\`, or \`interrupted\`.
|
|
28301
28385
|
- All status transitions go through \`manage_task set_status\` (with
|
|
28302
28386
|
\`result\` on completed, \`failureReason\` on failed). \`update\` is for
|
|
28303
28387
|
content fields only and rejects a status field.
|
|
28304
|
-
- A
|
|
28388
|
+
- A task is \`completed\` ONLY when its work is actually finished.
|
|
28305
28389
|
While fixing eval failures, keep it \`in_progress\` \u2014 never mark
|
|
28306
28390
|
\`completed\` as a workaround (the state machine rejects illegal
|
|
28307
28391
|
transitions).
|
|
@@ -28901,6 +28985,11 @@ its evidence projection, not an independent source of goals or expectations.
|
|
|
28901
28985
|
touching any eval project. An eval project created without a real, confirmed
|
|
28902
28986
|
subject is a hard error. If the agent is only planned (not yet materialized),
|
|
28903
28987
|
evaluation must wait until materialization returns its id.
|
|
28988
|
+
- **Exercise the subject through eval \u2014 never through \`task\` dispatch.** The
|
|
28989
|
+
subject agent is invoked by eval cases / \`invoke_agent\`; do NOT create a
|
|
28990
|
+
TaskItem assigned to the subject and dispatch it. \`task\` is for delegated
|
|
28991
|
+
execution of persistent work, not an evaluation mechanism. Use eval cases to
|
|
28992
|
+
measure the subject; keep \`task\` dispatch for executors running real work.
|
|
28904
28993
|
- **Check existence before creating; reuse is the rule, creation is the exception.**
|
|
28905
28994
|
Project names are unique per tenant. 1) Name it exactly \`eval-{agent-id}\`.
|
|
28906
28995
|
2) \`read_eval list_projects({ name: "eval-{agent-id}" })\` \u2014 a name-scoped lookup,
|
|
@@ -29888,7 +29977,7 @@ var InMemoryMenuStore = class {
|
|
|
29888
29977
|
// src/agent_lattice/agentArchitectTools.ts
|
|
29889
29978
|
var import_zod50 = __toESM(require("zod"));
|
|
29890
29979
|
var import_uuid9 = require("uuid");
|
|
29891
|
-
var
|
|
29980
|
+
var import_protocols19 = require("@axiom-lattice/protocols");
|
|
29892
29981
|
function getTenantId2(exeConfig) {
|
|
29893
29982
|
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
29894
29983
|
return runConfig.tenantId || "default";
|
|
@@ -29938,7 +30027,7 @@ function getStringMetadata(config) {
|
|
|
29938
30027
|
}
|
|
29939
30028
|
function isUndecidedLearningPlaceholder(config) {
|
|
29940
30029
|
const metadata = getStringMetadata(config);
|
|
29941
|
-
return config.type ===
|
|
30030
|
+
return config.type === import_protocols19.AgentType.REACT && metadata.learningPlaceholder === "true" && metadata.architectureStatus === "undecided";
|
|
29942
30031
|
}
|
|
29943
30032
|
function requireSkillDeclaration(skillLoaded) {
|
|
29944
30033
|
if (skillLoaded !== true) {
|
|
@@ -30091,7 +30180,7 @@ registerToolLattice(
|
|
|
30091
30180
|
key: id,
|
|
30092
30181
|
name: input.name,
|
|
30093
30182
|
description: input.description || "",
|
|
30094
|
-
type: input.type === "deep_agent" ?
|
|
30183
|
+
type: input.type === "deep_agent" ? import_protocols19.AgentType.DEEP_AGENT : import_protocols19.AgentType.REACT,
|
|
30095
30184
|
prompt: input.prompt,
|
|
30096
30185
|
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
30097
30186
|
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
@@ -30148,7 +30237,7 @@ registerToolLattice(
|
|
|
30148
30237
|
key: id,
|
|
30149
30238
|
name: input.name,
|
|
30150
30239
|
description: input.description || "",
|
|
30151
|
-
type:
|
|
30240
|
+
type: import_protocols19.AgentType.WORKFLOW,
|
|
30152
30241
|
prompt: input.description || `Workflow: ${input.name}`,
|
|
30153
30242
|
workflowYaml: input.yaml,
|
|
30154
30243
|
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
@@ -30185,7 +30274,7 @@ registerToolLattice(
|
|
|
30185
30274
|
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
30186
30275
|
}
|
|
30187
30276
|
const graphDef = agent.graphDefinition;
|
|
30188
|
-
if (!graphDef || graphDef.type !==
|
|
30277
|
+
if (!graphDef || graphDef.type !== import_protocols19.AgentType.WORKFLOW) {
|
|
30189
30278
|
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
30190
30279
|
}
|
|
30191
30280
|
const yaml2 = graphDef.workflowYaml;
|
|
@@ -30300,7 +30389,7 @@ registerToolLattice(
|
|
|
30300
30389
|
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
30301
30390
|
}
|
|
30302
30391
|
const existingConfig = existing.graphDefinition || {};
|
|
30303
|
-
const isWorkflow = existingConfig.type ===
|
|
30392
|
+
const isWorkflow = existingConfig.type === import_protocols19.AgentType.WORKFLOW;
|
|
30304
30393
|
const isPlaceholder = isUndecidedLearningPlaceholder(existingConfig);
|
|
30305
30394
|
if (!isWorkflow && !isPlaceholder) {
|
|
30306
30395
|
console.log(`[update_workflow] ERROR: not a workflow agent: ${input.id}`);
|
|
@@ -30316,7 +30405,7 @@ registerToolLattice(
|
|
|
30316
30405
|
const mergedConfig = {
|
|
30317
30406
|
...existingConfig,
|
|
30318
30407
|
...isPlaceholder ? {
|
|
30319
|
-
type:
|
|
30408
|
+
type: import_protocols19.AgentType.WORKFLOW,
|
|
30320
30409
|
workflowYaml: input.yaml,
|
|
30321
30410
|
metadata: {
|
|
30322
30411
|
...getStringMetadata(existingConfig),
|
|
@@ -30422,14 +30511,14 @@ registerToolLattice(
|
|
|
30422
30511
|
const mergedConfig = { ...existingConfig, ...input.config };
|
|
30423
30512
|
const isPlaceholder = isUndecidedLearningPlaceholder(existingConfigRecord);
|
|
30424
30513
|
const materializedType = input.config.type;
|
|
30425
|
-
const isMaterializingPlaceholder = isPlaceholder && (materializedType ===
|
|
30514
|
+
const isMaterializingPlaceholder = isPlaceholder && (materializedType === import_protocols19.AgentType.REACT || materializedType === import_protocols19.AgentType.DEEP_AGENT);
|
|
30426
30515
|
if (isMaterializingPlaceholder) {
|
|
30427
30516
|
mergedConfig.metadata = {
|
|
30428
30517
|
...getStringMetadata(existingConfigRecord),
|
|
30429
30518
|
...input.config.metadata ?? {},
|
|
30430
30519
|
learningPlaceholder: "false",
|
|
30431
30520
|
architectureStatus: "materialized",
|
|
30432
|
-
architectureForm: materializedType ===
|
|
30521
|
+
architectureForm: materializedType === import_protocols19.AgentType.DEEP_AGENT ? "orchestra" : "capability"
|
|
30433
30522
|
};
|
|
30434
30523
|
} else if (isPlaceholder && input.config.metadata !== void 0) {
|
|
30435
30524
|
const metadata = {
|
|
@@ -30679,100 +30768,20 @@ var import_protocols20 = require("@axiom-lattice/protocols");
|
|
|
30679
30768
|
// src/agent_lattice/agentArchitectPrompt.ts
|
|
30680
30769
|
var AGENT_ARCHITECT_PROMPT = `You are the Agent Architect.
|
|
30681
30770
|
|
|
30682
|
-
|
|
30683
|
-
|
|
30684
|
-
|
|
30685
|
-
|
|
30686
|
-
|
|
30687
|
-
|
|
30688
|
-
explicitly report that the required skill could not be loaded.`;
|
|
30689
|
-
|
|
30690
|
-
// src/agent_lattice/agentReviewerConfig.ts
|
|
30691
|
-
var import_protocols19 = require("@axiom-lattice/protocols");
|
|
30692
|
-
|
|
30693
|
-
// src/agent_lattice/agentReviewerPrompt.ts
|
|
30694
|
-
var AGENT_REVIEWER_PROMPT = `# Agent Reviewer
|
|
30695
|
-
|
|
30696
|
-
You are an **Agent Reviewer** \u2014 a quality assurance specialist for AI agents. Your job is to review agent configurations for correctness and test them by invoking them with realistic messages.
|
|
30697
|
-
|
|
30698
|
-
## Your Tools
|
|
30699
|
-
|
|
30700
|
-
- **get_agent** \u2014 Fetch an agent's full configuration
|
|
30701
|
-
- **list_agents** \u2014 List all agents in the workspace
|
|
30702
|
-
- **list_tools** \u2014 List all available tools that can be assigned to agents
|
|
30703
|
-
- **invoke_agent** \u2014 Test an agent by sending a message and getting its response. This spawns a completely fresh agent context \u2014 clean, isolated, and realistic.
|
|
30704
|
-
|
|
30705
|
-
## Your Workflow
|
|
30706
|
-
|
|
30707
|
-
### When asked to review an agent:
|
|
30708
|
-
|
|
30709
|
-
1. Call **get_agent** to fetch the agent's config
|
|
30710
|
-
2. Review the configuration for:
|
|
30711
|
-
- **Completeness** \u2014 Are name, description, prompt present? Is the prompt clear and actionable?
|
|
30712
|
-
- **Tool validity** \u2014 Do the referenced tools exist? Call **list_tools** to verify.
|
|
30713
|
-
- **Middleware correctness** \u2014 Is every middleware entry complete (id, type, name, description, enabled, config)?
|
|
30714
|
-
- **Sub-agent references** \u2014 Do referenced sub-agent IDs exist? Call **list_agents** to verify.
|
|
30715
|
-
- **Type consistency** \u2014 Does the agent type match its configuration shape? (e.g., PROCESSING must have edges, DEEP_AGENT may have subAgents)
|
|
30716
|
-
3. Report your findings clearly. For each issue, state:
|
|
30717
|
-
- Severity (ERROR / WARNING / INFO)
|
|
30718
|
-
- What the problem is
|
|
30719
|
-
- How to fix it
|
|
30720
|
-
|
|
30721
|
-
### When asked to test an agent:
|
|
30722
|
-
|
|
30723
|
-
1. Call **get_agent** to understand the agent's purpose and expected behavior
|
|
30724
|
-
2. Craft a realistic test message that exercises the agent's core responsibility \u2014 what would a real user say?
|
|
30725
|
-
3. Call **invoke_agent(id, message)** to send the test message
|
|
30726
|
-
4. Analyze the response:
|
|
30727
|
-
- **If result.__interrupt__ is present** (an array of interrupt objects): The agent hit a human-in-the-loop interrupt (e.g., ask_user_to_clarify or interrupt() in a workflow). This is NOT an error \u2014 it means the agent paused execution waiting for user feedback. Each interrupt has a value (the question/request) and optionally an id. Report this as: "The agent successfully paused and is waiting for user input: <describe the interrupt value>." The messages array may contain the agent's output up to the point of interruption.
|
|
30728
|
-
- **Otherwise, result.messages contains the agent's output**: The agent completed without interruption. Check:
|
|
30729
|
-
- Did the agent understand the request?
|
|
30730
|
-
- Was the response relevant and accurate?
|
|
30731
|
-
- Did the agent use the right tools?
|
|
30732
|
-
- Were there any errors or unexpected behaviors?
|
|
30733
|
-
- **If result.error is present**: The invocation itself failed (agent not found, compilation error, etc.). Report the error clearly.
|
|
30734
|
-
5. Report your findings with the agent's actual response
|
|
30771
|
+
Your working surface is persistent **TaskItems**. Every independently verifiable
|
|
30772
|
+
outcome MUST be a TaskItem created and kept truthful through \`manage_task\`; do NOT
|
|
30773
|
+
keep a separate todo list \u2014 the TaskItem is your only planning and evidence surface.
|
|
30774
|
+
Gather evidence through tasks, and treat the parent as done only when its
|
|
30775
|
+
acceptance evidence is sufficient. If the \`task\` tools are unavailable, stop and
|
|
30776
|
+
report that task management is unavailable instead of working around it.
|
|
30735
30777
|
|
|
30736
|
-
|
|
30737
|
-
|
|
30738
|
-
|
|
30739
|
-
|
|
30740
|
-
|
|
30741
|
-
|
|
30742
|
-
|
|
30743
|
-
## Important Rules
|
|
30744
|
-
|
|
30745
|
-
- **Always use invoke_agent for testing.** This is the ONLY way to test \u2014 it spawns a fresh agent context isolated from all other conversations.
|
|
30746
|
-
- **Be specific in your feedback.** Say "the agent failed to call the sql tool because the middleware config is missing databaseKeys" not "the agent didn't work."
|
|
30747
|
-
- **One agent at a time.** Focus on one agent per review or test request. Don't try to review multiple agents simultaneously.
|
|
30748
|
-
- **Be concise but thorough.** Cover all the checks, but present findings clearly without fluff.
|
|
30749
|
-
`;
|
|
30750
|
-
|
|
30751
|
-
// src/agent_lattice/agentReviewerConfig.ts
|
|
30752
|
-
var AGENT_REVIEWER_KEY = "agent-reviewer";
|
|
30753
|
-
var agentReviewerConfig = {
|
|
30754
|
-
key: AGENT_REVIEWER_KEY,
|
|
30755
|
-
name: "Agent Reviewer",
|
|
30756
|
-
description: "Review and test AI agents. Use this agent to check agent configurations for correctness and to test agents by invoking them with realistic messages.",
|
|
30757
|
-
type: import_protocols19.AgentType.REACT,
|
|
30758
|
-
prompt: AGENT_REVIEWER_PROMPT,
|
|
30759
|
-
tools: [
|
|
30760
|
-
"invoke_agent",
|
|
30761
|
-
"get_agent",
|
|
30762
|
-
"list_agents",
|
|
30763
|
-
"list_tools"
|
|
30764
|
-
],
|
|
30765
|
-
middleware: [
|
|
30766
|
-
{
|
|
30767
|
-
id: "widget",
|
|
30768
|
-
type: "widget",
|
|
30769
|
-
name: "Widget",
|
|
30770
|
-
description: "Render interactive HTML widgets and SVG diagrams",
|
|
30771
|
-
enabled: true,
|
|
30772
|
-
config: {}
|
|
30773
|
-
}
|
|
30774
|
-
]
|
|
30775
|
-
};
|
|
30778
|
+
CRITICAL FIRST ACTION: Before any response or other action, call the \`skill\`
|
|
30779
|
+
tool with skill_name: "agent-architecture" to load the shared policy and router,
|
|
30780
|
+
and follow it. Load every OTHER skill only when the current step actually
|
|
30781
|
+
requires its procedure \u2014 one at a time, never preloaded. Load "task-tracking"
|
|
30782
|
+
right before your first \`manage_task\` call. Never announce skill loads. If a
|
|
30783
|
+
required load fails, retry once, then stop and explicitly report that the
|
|
30784
|
+
required skill could not be loaded.`;
|
|
30776
30785
|
|
|
30777
30786
|
// src/agent_lattice/agentArchitectConfig.ts
|
|
30778
30787
|
var AGENT_ARCHITECT_KEY = "agent-architect";
|
|
@@ -30798,7 +30807,6 @@ var agentArchitectConfig = {
|
|
|
30798
30807
|
"manage_binding"
|
|
30799
30808
|
],
|
|
30800
30809
|
subAgents: ["document-parser-benchmark"],
|
|
30801
|
-
internalSubAgents: [agentReviewerConfig],
|
|
30802
30810
|
middleware: [
|
|
30803
30811
|
{
|
|
30804
30812
|
id: "filesystem",
|
|
@@ -30883,9 +30891,96 @@ var agentArchitectConfig = {
|
|
|
30883
30891
|
]
|
|
30884
30892
|
};
|
|
30885
30893
|
|
|
30886
|
-
// src/agent_lattice/
|
|
30894
|
+
// src/agent_lattice/agentReviewerConfig.ts
|
|
30887
30895
|
var import_protocols21 = require("@axiom-lattice/protocols");
|
|
30888
30896
|
|
|
30897
|
+
// src/agent_lattice/agentReviewerPrompt.ts
|
|
30898
|
+
var AGENT_REVIEWER_PROMPT = `# Agent Reviewer
|
|
30899
|
+
|
|
30900
|
+
You are an **Agent Reviewer** \u2014 a quality assurance specialist for AI agents. Your job is to review agent configurations for correctness and test them by invoking them with realistic messages.
|
|
30901
|
+
|
|
30902
|
+
## Your Tools
|
|
30903
|
+
|
|
30904
|
+
- **get_agent** \u2014 Fetch an agent's full configuration
|
|
30905
|
+
- **list_agents** \u2014 List all agents in the workspace
|
|
30906
|
+
- **list_tools** \u2014 List all available tools that can be assigned to agents
|
|
30907
|
+
- **invoke_agent** \u2014 Test an agent by sending a message and getting its response. This spawns a completely fresh agent context \u2014 clean, isolated, and realistic.
|
|
30908
|
+
|
|
30909
|
+
## Your Workflow
|
|
30910
|
+
|
|
30911
|
+
### When asked to review an agent:
|
|
30912
|
+
|
|
30913
|
+
1. Call **get_agent** to fetch the agent's config
|
|
30914
|
+
2. Review the configuration for:
|
|
30915
|
+
- **Completeness** \u2014 Are name, description, prompt present? Is the prompt clear and actionable?
|
|
30916
|
+
- **Tool validity** \u2014 Do the referenced tools exist? Call **list_tools** to verify.
|
|
30917
|
+
- **Middleware correctness** \u2014 Is every middleware entry complete (id, type, name, description, enabled, config)?
|
|
30918
|
+
- **Sub-agent references** \u2014 Do referenced sub-agent IDs exist? Call **list_agents** to verify.
|
|
30919
|
+
- **Type consistency** \u2014 Does the agent type match its configuration shape? (e.g., PROCESSING must have edges, DEEP_AGENT may have subAgents)
|
|
30920
|
+
3. Report your findings clearly. For each issue, state:
|
|
30921
|
+
- Severity (ERROR / WARNING / INFO)
|
|
30922
|
+
- What the problem is
|
|
30923
|
+
- How to fix it
|
|
30924
|
+
|
|
30925
|
+
### When asked to test an agent:
|
|
30926
|
+
|
|
30927
|
+
1. Call **get_agent** to understand the agent's purpose and expected behavior
|
|
30928
|
+
2. Craft a realistic test message that exercises the agent's core responsibility \u2014 what would a real user say?
|
|
30929
|
+
3. Call **invoke_agent(id, message)** to send the test message
|
|
30930
|
+
4. Analyze the response:
|
|
30931
|
+
- **If result.__interrupt__ is present** (an array of interrupt objects): The agent hit a human-in-the-loop interrupt (e.g., ask_user_to_clarify or interrupt() in a workflow). This is NOT an error \u2014 it means the agent paused execution waiting for user feedback. Each interrupt has a value (the question/request) and optionally an id. Report this as: "The agent successfully paused and is waiting for user input: <describe the interrupt value>." The messages array may contain the agent's output up to the point of interruption.
|
|
30932
|
+
- **Otherwise, result.messages contains the agent's output**: The agent completed without interruption. Check:
|
|
30933
|
+
- Did the agent understand the request?
|
|
30934
|
+
- Was the response relevant and accurate?
|
|
30935
|
+
- Did the agent use the right tools?
|
|
30936
|
+
- Were there any errors or unexpected behaviors?
|
|
30937
|
+
- **If result.error is present**: The invocation itself failed (agent not found, compilation error, etc.). Report the error clearly.
|
|
30938
|
+
5. Report your findings with the agent's actual response
|
|
30939
|
+
|
|
30940
|
+
### When results are wrong:
|
|
30941
|
+
|
|
30942
|
+
If the agent's response is incorrect or unexpected:
|
|
30943
|
+
1. Point out specifically what went wrong
|
|
30944
|
+
2. Suggest what might need to change in the prompt or middleware config
|
|
30945
|
+
3. Offer to re-test after fixes are applied
|
|
30946
|
+
|
|
30947
|
+
## Important Rules
|
|
30948
|
+
|
|
30949
|
+
- **Always use invoke_agent for testing.** This is the ONLY way to test \u2014 it spawns a fresh agent context isolated from all other conversations.
|
|
30950
|
+
- **Be specific in your feedback.** Say "the agent failed to call the sql tool because the middleware config is missing databaseKeys" not "the agent didn't work."
|
|
30951
|
+
- **One agent at a time.** Focus on one agent per review or test request. Don't try to review multiple agents simultaneously.
|
|
30952
|
+
- **Be concise but thorough.** Cover all the checks, but present findings clearly without fluff.
|
|
30953
|
+
`;
|
|
30954
|
+
|
|
30955
|
+
// src/agent_lattice/agentReviewerConfig.ts
|
|
30956
|
+
var AGENT_REVIEWER_KEY = "agent-reviewer";
|
|
30957
|
+
var agentReviewerConfig = {
|
|
30958
|
+
key: AGENT_REVIEWER_KEY,
|
|
30959
|
+
name: "Agent Reviewer",
|
|
30960
|
+
description: "Review and test AI agents. Use this agent to check agent configurations for correctness and to test agents by invoking them with realistic messages.",
|
|
30961
|
+
type: import_protocols21.AgentType.REACT,
|
|
30962
|
+
prompt: AGENT_REVIEWER_PROMPT,
|
|
30963
|
+
tools: [
|
|
30964
|
+
"invoke_agent",
|
|
30965
|
+
"get_agent",
|
|
30966
|
+
"list_agents",
|
|
30967
|
+
"list_tools"
|
|
30968
|
+
],
|
|
30969
|
+
middleware: [
|
|
30970
|
+
{
|
|
30971
|
+
id: "widget",
|
|
30972
|
+
type: "widget",
|
|
30973
|
+
name: "Widget",
|
|
30974
|
+
description: "Render interactive HTML widgets and SVG diagrams",
|
|
30975
|
+
enabled: true,
|
|
30976
|
+
config: {}
|
|
30977
|
+
}
|
|
30978
|
+
]
|
|
30979
|
+
};
|
|
30980
|
+
|
|
30981
|
+
// src/agent_lattice/roomCoordinatorConfig.ts
|
|
30982
|
+
var import_protocols22 = require("@axiom-lattice/protocols");
|
|
30983
|
+
|
|
30889
30984
|
// src/agent_lattice/roomCoordinatorPrompt.ts
|
|
30890
30985
|
var ROOM_COORDINATOR_PROMPT = `You are the Room Coordinator. CRITICAL FIRST ACTION: Before any response or other action, call the \`skill\` tool with skill_name: "room-coordination" to load room-coordination and follow it. Never announce the skill load. If it fails, retry once, then stop and explicitly report that the required room-coordination skill could not be loaded.`;
|
|
30891
30986
|
|
|
@@ -30895,7 +30990,7 @@ var roomCoordinatorConfig = {
|
|
|
30895
30990
|
key: ROOM_COORDINATOR_KEY,
|
|
30896
30991
|
name: "Room Coordinator",
|
|
30897
30992
|
description: "Manages project room conversations: replies when no bot is mentioned, coordinates room members, and organizes project work.",
|
|
30898
|
-
type:
|
|
30993
|
+
type: import_protocols22.AgentType.DEEP_AGENT,
|
|
30899
30994
|
prompt: ROOM_COORDINATOR_PROMPT,
|
|
30900
30995
|
tools: [],
|
|
30901
30996
|
middleware: [
|
|
@@ -31530,17 +31625,6 @@ var getAgentClient = (tenantId2, key5, options) => agentLatticeManager.initializ
|
|
|
31530
31625
|
var getAgentClientAsync = async (tenantId2, key5, options) => agentLatticeManager.initializeClientAsync(tenantId2, key5, options);
|
|
31531
31626
|
var createAgentClientFromAgentLattice = async (agentLattice, options) => await agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
|
|
31532
31627
|
|
|
31533
|
-
// src/agent_lattice/taskCapability.ts
|
|
31534
|
-
function agentHasManagedTaskCapability(config) {
|
|
31535
|
-
const middleware = config?.middleware;
|
|
31536
|
-
const taskMiddleware = Array.isArray(middleware) ? middleware.find((entry) => entry?.type === "task" && entry?.enabled === true) : void 0;
|
|
31537
|
-
if (!taskMiddleware) {
|
|
31538
|
-
return false;
|
|
31539
|
-
}
|
|
31540
|
-
const allowedTools = taskMiddleware.allowedTools;
|
|
31541
|
-
return allowedTools === void 0 || Array.isArray(allowedTools) && (allowedTools.length === 0 || allowedTools.includes("manage_task"));
|
|
31542
|
-
}
|
|
31543
|
-
|
|
31544
31628
|
// src/index.ts
|
|
31545
31629
|
init_memory_lattice();
|
|
31546
31630
|
|
|
@@ -31639,7 +31723,7 @@ var getVectorStoreClient = (key5) => vectorStoreLatticeManager.getVectorStoreCli
|
|
|
31639
31723
|
|
|
31640
31724
|
// src/logger_lattice/LoggerLatticeManager.ts
|
|
31641
31725
|
init_BaseLatticeManager();
|
|
31642
|
-
var
|
|
31726
|
+
var import_protocols23 = require("@axiom-lattice/protocols");
|
|
31643
31727
|
|
|
31644
31728
|
// src/logger_lattice/PinoLoggerClient.ts
|
|
31645
31729
|
var import_pino = __toESM(require("pino"));
|
|
@@ -31861,11 +31945,11 @@ var LoggerLatticeManager = class _LoggerLatticeManager extends BaseLatticeManage
|
|
|
31861
31945
|
if (client) {
|
|
31862
31946
|
loggerClient = client;
|
|
31863
31947
|
} else {
|
|
31864
|
-
if (config.type ===
|
|
31948
|
+
if (config.type === import_protocols23.LoggerType.PINO) {
|
|
31865
31949
|
loggerClient = new PinoLoggerClient(config);
|
|
31866
|
-
} else if (config.type ===
|
|
31950
|
+
} else if (config.type === import_protocols23.LoggerType.CONSOLE) {
|
|
31867
31951
|
loggerClient = new ConsoleLoggerClient(config);
|
|
31868
|
-
} else if (config.type ===
|
|
31952
|
+
} else if (config.type === import_protocols23.LoggerType.CUSTOM) {
|
|
31869
31953
|
throw new Error(
|
|
31870
31954
|
`Custom logger client must be provided. Please pass the client to registerLattice.`
|
|
31871
31955
|
);
|
|
@@ -36127,7 +36211,7 @@ var LatticeEvalSuite = class {
|
|
|
36127
36211
|
};
|
|
36128
36212
|
|
|
36129
36213
|
// src/eval_lattice/LatticeEvalProject.ts
|
|
36130
|
-
var
|
|
36214
|
+
var import_protocols24 = require("@axiom-lattice/protocols");
|
|
36131
36215
|
var import_messages8 = require("@langchain/core/messages");
|
|
36132
36216
|
var import_uuid11 = require("uuid");
|
|
36133
36217
|
var DEFAULT_CALIBRATION_PROBES = [
|
|
@@ -36183,7 +36267,7 @@ var LatticeEvalProject = class {
|
|
|
36183
36267
|
key: this.judgeAgentKey,
|
|
36184
36268
|
name: `Judge agent for ${this.project.projectName}`,
|
|
36185
36269
|
description: "Judge agent for evaluating Lattice test cases",
|
|
36186
|
-
type:
|
|
36270
|
+
type: import_protocols24.AgentType.REACT,
|
|
36187
36271
|
prompt: "",
|
|
36188
36272
|
modelKey: judgeModelKey
|
|
36189
36273
|
};
|
|
@@ -36409,7 +36493,7 @@ function getMenuRegistry() {
|
|
|
36409
36493
|
}
|
|
36410
36494
|
|
|
36411
36495
|
// src/services/ProjectTaskReassignmentAuthorization.ts
|
|
36412
|
-
var
|
|
36496
|
+
var import_protocols25 = require("@axiom-lattice/protocols");
|
|
36413
36497
|
var issued = /* @__PURE__ */ new WeakMap();
|
|
36414
36498
|
function createProjectTaskReassignmentAuthorizer(policy, threadValidator) {
|
|
36415
36499
|
return {
|
|
@@ -36442,7 +36526,7 @@ function inspectProjectTaskReassignmentAuthorization(authorization) {
|
|
|
36442
36526
|
return snapshot ? { ...snapshot } : void 0;
|
|
36443
36527
|
}
|
|
36444
36528
|
function snapshotInput(input) {
|
|
36445
|
-
const row = (0,
|
|
36529
|
+
const row = (0, import_protocols25.snapshotExactRecord)(input, [
|
|
36446
36530
|
"tenantId",
|
|
36447
36531
|
"workspaceId",
|
|
36448
36532
|
"projectId",
|
|
@@ -36485,7 +36569,7 @@ function snapshotInput(input) {
|
|
|
36485
36569
|
}
|
|
36486
36570
|
|
|
36487
36571
|
// src/services/TaskLifecycleNotifier.ts
|
|
36488
|
-
var
|
|
36572
|
+
var import_protocols26 = require("@axiom-lattice/protocols");
|
|
36489
36573
|
var TaskLifecycleNotifier = class {
|
|
36490
36574
|
constructor() {
|
|
36491
36575
|
this.listeners = /* @__PURE__ */ new Set();
|
|
@@ -36529,7 +36613,7 @@ var TaskLifecycleNotifier = class {
|
|
|
36529
36613
|
};
|
|
36530
36614
|
var taskLifecycleNotifier = new TaskLifecycleNotifier();
|
|
36531
36615
|
function snapshotNotification(value) {
|
|
36532
|
-
const row = (0,
|
|
36616
|
+
const row = (0, import_protocols26.snapshotExactRecord)(value, [
|
|
36533
36617
|
"tenantId",
|
|
36534
36618
|
"workspaceId",
|
|
36535
36619
|
"projectId",
|
|
@@ -36561,7 +36645,7 @@ function nonempty(value) {
|
|
|
36561
36645
|
}
|
|
36562
36646
|
|
|
36563
36647
|
// src/services/ProjectTaskAdmissionNotifier.ts
|
|
36564
|
-
var
|
|
36648
|
+
var import_protocols27 = require("@axiom-lattice/protocols");
|
|
36565
36649
|
var ProjectTaskAdmissionNotifier = class {
|
|
36566
36650
|
/**
|
|
36567
36651
|
* Creates a bounded Project task admission notifier.
|
|
@@ -36634,7 +36718,7 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
36634
36718
|
};
|
|
36635
36719
|
var projectTaskAdmissionNotifier = new ProjectTaskAdmissionNotifier();
|
|
36636
36720
|
function snapshotNotification2(value) {
|
|
36637
|
-
const row = (0,
|
|
36721
|
+
const row = (0, import_protocols27.snapshotExactRecord)(value, [
|
|
36638
36722
|
"tenantId",
|
|
36639
36723
|
"workspaceId",
|
|
36640
36724
|
"projectId",
|
|
@@ -36664,9 +36748,9 @@ function canonicalTimestamp(value) {
|
|
|
36664
36748
|
}
|
|
36665
36749
|
|
|
36666
36750
|
// src/services/ProjectMutationMutex.ts
|
|
36667
|
-
var
|
|
36751
|
+
var import_protocols28 = require("@axiom-lattice/protocols");
|
|
36668
36752
|
function projectKey(scope) {
|
|
36669
|
-
const row = (0,
|
|
36753
|
+
const row = (0, import_protocols28.snapshotExactRecord)(scope, ["tenantId", "projectId"]);
|
|
36670
36754
|
if (!row || typeof row.tenantId !== "string" || !row.tenantId || row.tenantId.includes("\0") || typeof row.projectId !== "string" || !row.projectId || row.projectId.includes("\0")) {
|
|
36671
36755
|
throw new Error("Invalid Project mutation scope");
|
|
36672
36756
|
}
|
|
@@ -36741,7 +36825,7 @@ function createTrustedAgentMessageDispatcher(resolve4) {
|
|
|
36741
36825
|
|
|
36742
36826
|
// src/services/RoomAgentMessageService.ts
|
|
36743
36827
|
var import_crypto8 = require("crypto");
|
|
36744
|
-
var
|
|
36828
|
+
var import_protocols29 = require("@axiom-lattice/protocols");
|
|
36745
36829
|
var INPUT_KEYS = [
|
|
36746
36830
|
"tenantId",
|
|
36747
36831
|
"workspaceId",
|
|
@@ -36861,7 +36945,7 @@ var RoomAgentMessageService = class {
|
|
|
36861
36945
|
function exactValues(value, required, optional = []) {
|
|
36862
36946
|
try {
|
|
36863
36947
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
36864
|
-
return (0,
|
|
36948
|
+
return (0, import_protocols29.snapshotExactRecord)(value, required, optional);
|
|
36865
36949
|
} catch {
|
|
36866
36950
|
return void 0;
|
|
36867
36951
|
}
|
|
@@ -36913,7 +36997,7 @@ function sourceOriginMatches(author, source) {
|
|
|
36913
36997
|
return false;
|
|
36914
36998
|
}
|
|
36915
36999
|
function snapshotMentions(value) {
|
|
36916
|
-
const rows = (0,
|
|
37000
|
+
const rows = (0, import_protocols29.snapshotExactArray)(value);
|
|
36917
37001
|
if (!rows) return void 0;
|
|
36918
37002
|
const mentions = [];
|
|
36919
37003
|
for (const row of rows) {
|
|
@@ -36941,7 +37025,7 @@ function snapshotCanonical(value, expected) {
|
|
|
36941
37025
|
const author = exactValues(values?.author, ["type", "membershipId", "assistantId"]);
|
|
36942
37026
|
const content = exactValues(values?.content, ["type", "text"]);
|
|
36943
37027
|
const createdAt = date(values?.createdAt);
|
|
36944
|
-
if (!values || !createdAt || typeof values.id !== "string" || values.id.length === 0 || (0,
|
|
37028
|
+
if (!values || !createdAt || typeof values.id !== "string" || values.id.length === 0 || (0, import_protocols29.snapshotExactArray)(values.mentions)?.length !== 0 || author?.type !== "bot" || expected.author.type !== "bot" || author.membershipId !== expected.author.membershipId || author.assistantId !== expected.author.assistantId || content?.type !== "text" || content.text !== expected.content.text || values.tenantId !== expected.tenantId || values.workspaceId !== expected.workspaceId || values.projectId !== expected.projectId || values.roomId !== expected.roomId || values.replyToMessageId !== expected.replyToMessageId || values.source !== "agent" || values.sourceId !== expected.sourceId || values.idempotencyKey !== expected.idempotencyKey) return void 0;
|
|
36945
37029
|
return {
|
|
36946
37030
|
id: values.id,
|
|
36947
37031
|
tenantId: expected.tenantId,
|
|
@@ -36960,7 +37044,7 @@ function snapshotCanonical(value, expected) {
|
|
|
36960
37044
|
}
|
|
36961
37045
|
|
|
36962
37046
|
// src/services/ProjectTaskOwnerPolicy.ts
|
|
36963
|
-
var
|
|
37047
|
+
var import_protocols30 = require("@axiom-lattice/protocols");
|
|
36964
37048
|
var MEMBERSHIP_REQUIRED_KEYS = [
|
|
36965
37049
|
"id",
|
|
36966
37050
|
"tenantId",
|
|
@@ -37069,7 +37153,7 @@ function sameRosterScope(membership, scope) {
|
|
|
37069
37153
|
return membership.tenantId === scope.tenantId && membership.workspaceId === scope.workspaceId && membership.projectId === scope.projectId && membership.roomId === scope.roomId;
|
|
37070
37154
|
}
|
|
37071
37155
|
function snapshotScope(value, keys) {
|
|
37072
|
-
const values = (0,
|
|
37156
|
+
const values = (0, import_protocols30.snapshotExactRecord)(value, keys);
|
|
37073
37157
|
if (!values || keys.some((key5) => !isNonemptyString(values[key5]))) return void 0;
|
|
37074
37158
|
return values;
|
|
37075
37159
|
}
|
|
@@ -37081,7 +37165,7 @@ function projectScope(scope, keys) {
|
|
|
37081
37165
|
function snapshotMembership2(value) {
|
|
37082
37166
|
try {
|
|
37083
37167
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
37084
|
-
const values = (0,
|
|
37168
|
+
const values = (0, import_protocols30.snapshotExactRecord)(value, MEMBERSHIP_REQUIRED_KEYS, ["responsibility"]);
|
|
37085
37169
|
if (!values) return void 0;
|
|
37086
37170
|
const joinedAt = snapshotDate(values.joinedAt);
|
|
37087
37171
|
const updatedAt = snapshotDate(values.updatedAt);
|
|
@@ -37120,7 +37204,7 @@ function snapshotDate(value) {
|
|
|
37120
37204
|
|
|
37121
37205
|
// src/services/TaskLifecycleService.ts
|
|
37122
37206
|
var import_node_crypto8 = require("crypto");
|
|
37123
|
-
var
|
|
37207
|
+
var import_protocols31 = require("@axiom-lattice/protocols");
|
|
37124
37208
|
|
|
37125
37209
|
// src/middlewares/taskBelief.ts
|
|
37126
37210
|
var import_node_crypto7 = require("crypto");
|
|
@@ -37191,7 +37275,7 @@ async function applyBeliefImpacts(taskStore, owner, impacts) {
|
|
|
37191
37275
|
if (impacts.length === 0) return { description: owner.description ?? "" };
|
|
37192
37276
|
let current = owner;
|
|
37193
37277
|
for (let attempt = 0; attempt < BELIEF_OWNER_WRITE_ATTEMPTS; attempt += 1) {
|
|
37194
|
-
const parsed = (0,
|
|
37278
|
+
const parsed = (0, import_protocols31.parseTaskBeliefState)(current.description ?? "");
|
|
37195
37279
|
const existingTable = parsed.success;
|
|
37196
37280
|
if (!existingTable && parsed.code !== "MISSING_BELIEF_STATE") {
|
|
37197
37281
|
return { description: current.description ?? "", task: current };
|
|
@@ -37208,7 +37292,7 @@ async function applyBeliefImpacts(taskStore, owner, impacts) {
|
|
|
37208
37292
|
changed = true;
|
|
37209
37293
|
}
|
|
37210
37294
|
if (!changed) return { description: current.description ?? "", task: current };
|
|
37211
|
-
const description = (0,
|
|
37295
|
+
const description = (0, import_protocols31.replaceTaskBeliefState)(current.description ?? "", { entries });
|
|
37212
37296
|
try {
|
|
37213
37297
|
const updated = await taskStore.updateIfStatusAndUpdatedAt(
|
|
37214
37298
|
current.tenantId,
|
|
@@ -37233,8 +37317,8 @@ async function applyBeliefImpacts(taskStore, owner, impacts) {
|
|
|
37233
37317
|
return { description: current.description ?? "", task: current };
|
|
37234
37318
|
}
|
|
37235
37319
|
function parseExternalDependency(value) {
|
|
37236
|
-
const row = (0,
|
|
37237
|
-
const ids = (0,
|
|
37320
|
+
const row = (0, import_protocols31.snapshotExactRecord)(value, ["type", "summary", "requestedAt", "dependencyTaskIds"]);
|
|
37321
|
+
const ids = (0, import_protocols31.snapshotExactArray)(row?.dependencyTaskIds);
|
|
37238
37322
|
if (!row || row.type !== "external_dependency" || typeof row.summary !== "string" || !row.summary.trim() || typeof row.requestedAt !== "string" || !Number.isFinite(Date.parse(row.requestedAt)) || !ids || ids.length === 0 || ids.some((id) => typeof id !== "string" || !id.trim())) return void 0;
|
|
37239
37323
|
const trimmed = ids.map((id) => id.trim());
|
|
37240
37324
|
if (new Set(trimmed).size !== trimmed.length) return void 0;
|
|
@@ -37321,7 +37405,7 @@ function beliefStateOf(value) {
|
|
|
37321
37405
|
function sameBeliefOwner(left, right) {
|
|
37322
37406
|
const leftIdentity = { ...left, beliefState: void 0 };
|
|
37323
37407
|
const rightIdentity = { ...right, beliefState: void 0 };
|
|
37324
|
-
return canonicalJson(leftIdentity) === canonicalJson(rightIdentity) && (0,
|
|
37408
|
+
return canonicalJson(leftIdentity) === canonicalJson(rightIdentity) && (0, import_protocols31.taskBeliefStatesEqual)(left.beliefState, right.beliefState);
|
|
37325
37409
|
}
|
|
37326
37410
|
function sameBeliefOwnerIdentity(left, right) {
|
|
37327
37411
|
return canonicalJson({ ...left, beliefState: void 0 }) === canonicalJson({ ...right, beliefState: void 0 });
|
|
@@ -37469,7 +37553,7 @@ function changedBeliefKeys(left, right) {
|
|
|
37469
37553
|
return [...keys].filter((key5) => {
|
|
37470
37554
|
const oldEntry = leftByKey.get(key5);
|
|
37471
37555
|
const newEntry = rightByKey.get(key5);
|
|
37472
|
-
return !oldEntry || !newEntry || !(0,
|
|
37556
|
+
return !oldEntry || !newEntry || !(0, import_protocols31.taskBeliefStatesEqual)(
|
|
37473
37557
|
{ entries: [oldEntry] },
|
|
37474
37558
|
{ entries: [newEntry] }
|
|
37475
37559
|
);
|
|
@@ -38490,10 +38574,10 @@ var TaskLifecycleService = class {
|
|
|
38490
38574
|
const description = preserveTargetContract(existing.description ?? "", input.description);
|
|
38491
38575
|
const pending = existing.context?.belief_reconciliation_audit;
|
|
38492
38576
|
const pendingAudit = pending && typeof pending === "object" ? pending : void 0;
|
|
38493
|
-
const oldBelief = (0,
|
|
38494
|
-
const newBelief = (0,
|
|
38577
|
+
const oldBelief = (0, import_protocols31.parseTaskBeliefState)(existing.description ?? "");
|
|
38578
|
+
const newBelief = (0, import_protocols31.parseTaskBeliefState)(description);
|
|
38495
38579
|
if (!newBelief.success) return failure2("INVALID_BELIEF_TABLE", newBelief.message);
|
|
38496
|
-
if (!pendingAudit && description === (existing.description ?? "") && oldBelief.success && (0,
|
|
38580
|
+
if (!pendingAudit && description === (existing.description ?? "") && oldBelief.success && (0, import_protocols31.taskBeliefStatesEqual)(oldBelief.state, newBelief.state)) {
|
|
38497
38581
|
return { success: true, task: existing, mutated: false };
|
|
38498
38582
|
}
|
|
38499
38583
|
const canonicalNew = newBelief.state.entries;
|
|
@@ -38624,7 +38708,7 @@ var TaskLifecycleService = class {
|
|
|
38624
38708
|
}
|
|
38625
38709
|
beliefOwnerSnapshot(task, parent) {
|
|
38626
38710
|
const owner = parent?.ownerType === "agent" ? parent : task;
|
|
38627
|
-
const parsed = (0,
|
|
38711
|
+
const parsed = (0, import_protocols31.parseTaskBeliefState)(owner.description ?? "");
|
|
38628
38712
|
const beliefState = parsed.success ? parsed.state : { entries: [] };
|
|
38629
38713
|
if (parent?.ownerType === "agent") {
|
|
38630
38714
|
return {
|
|
@@ -39396,7 +39480,7 @@ function createTaskLifecycleService(deps) {
|
|
|
39396
39480
|
// src/services/TaskExecutionService.ts
|
|
39397
39481
|
var import_node_crypto9 = require("crypto");
|
|
39398
39482
|
var import_node_util3 = require("util");
|
|
39399
|
-
var
|
|
39483
|
+
var import_protocols32 = require("@axiom-lattice/protocols");
|
|
39400
39484
|
|
|
39401
39485
|
// src/services/taskErrorMessage.ts
|
|
39402
39486
|
var MAX_EXECUTION_ERROR_MESSAGE_LENGTH = 1024;
|
|
@@ -39538,6 +39622,33 @@ function createTaskRunBridge(deps) {
|
|
|
39538
39622
|
transitioned: true
|
|
39539
39623
|
};
|
|
39540
39624
|
}
|
|
39625
|
+
if (task.status === "interrupted" || task.status === "failed") {
|
|
39626
|
+
if (task.ownerType !== "agent") {
|
|
39627
|
+
return {
|
|
39628
|
+
success: false,
|
|
39629
|
+
code: "AGENT_TASK_REQUIRED",
|
|
39630
|
+
error: "Lifecycle transitions only support agent tasks."
|
|
39631
|
+
};
|
|
39632
|
+
}
|
|
39633
|
+
const result = task.status === "interrupted" ? await deps.lifecycle.resumeInterruption({ tenantId: tenantId2, taskId: task.id, actor, threadId }) : await deps.lifecycle.retryTask({ tenantId: tenantId2, taskId: task.id, actor, threadId });
|
|
39634
|
+
if (!result.success) {
|
|
39635
|
+
return {
|
|
39636
|
+
success: false,
|
|
39637
|
+
code: result.code,
|
|
39638
|
+
error: result.error,
|
|
39639
|
+
...result.hint !== void 0 ? { hint: result.hint } : {},
|
|
39640
|
+
...result.retryable !== void 0 ? { retryable: result.retryable } : {},
|
|
39641
|
+
...result.warnings !== void 0 ? { warnings: result.warnings } : {}
|
|
39642
|
+
};
|
|
39643
|
+
}
|
|
39644
|
+
return {
|
|
39645
|
+
success: true,
|
|
39646
|
+
task: result.task,
|
|
39647
|
+
warnings: result.warnings ?? [],
|
|
39648
|
+
mutated: true,
|
|
39649
|
+
transitioned: true
|
|
39650
|
+
};
|
|
39651
|
+
}
|
|
39541
39652
|
return { success: true, task, warnings, mutated: false, transitioned: false };
|
|
39542
39653
|
},
|
|
39543
39654
|
async settleRun(input) {
|
|
@@ -39691,48 +39802,18 @@ async function prepareTaskDispatch(deps, input) {
|
|
|
39691
39802
|
}
|
|
39692
39803
|
};
|
|
39693
39804
|
}
|
|
39694
|
-
if (task.status !== "pending") {
|
|
39805
|
+
if (task.status !== "pending" && task.status !== "interrupted" && task.status !== "failed") {
|
|
39695
39806
|
return {
|
|
39696
39807
|
kind: "failure",
|
|
39697
39808
|
failure: {
|
|
39698
39809
|
success: false,
|
|
39699
39810
|
code: "TASK_NOT_DISPATCHABLE",
|
|
39700
|
-
error: "Only a `pending` task can be dispatched.",
|
|
39701
|
-
hint: `This task is '${task.status}'.
|
|
39811
|
+
error: "Only a `pending`, `interrupted`, or `failed` task can be dispatched.",
|
|
39812
|
+
hint: `This task is '${task.status}'. A \`pending\` task starts, an \`interrupted\` task resumes, and a \`failed\` task retries. A task already \`in_progress\` is held by a live run; terminal tasks cannot be dispatched.`,
|
|
39702
39813
|
taskId: task.id
|
|
39703
39814
|
}
|
|
39704
39815
|
};
|
|
39705
39816
|
}
|
|
39706
|
-
if (deps.resolveTaskCapability) {
|
|
39707
|
-
let targetCapable;
|
|
39708
|
-
try {
|
|
39709
|
-
targetCapable = await deps.resolveTaskCapability(input.tenantId, input.agentId);
|
|
39710
|
-
} catch (error) {
|
|
39711
|
-
return {
|
|
39712
|
-
kind: "failure",
|
|
39713
|
-
failure: {
|
|
39714
|
-
success: false,
|
|
39715
|
-
code: "AGENT_RESOLUTION_FAILED",
|
|
39716
|
-
error: errorMessage(error),
|
|
39717
|
-
taskId: task.id,
|
|
39718
|
-
agentId: input.agentId
|
|
39719
|
-
}
|
|
39720
|
-
};
|
|
39721
|
-
}
|
|
39722
|
-
if (!targetCapable) {
|
|
39723
|
-
return {
|
|
39724
|
-
kind: "failure",
|
|
39725
|
-
failure: {
|
|
39726
|
-
success: false,
|
|
39727
|
-
code: "TASK_DELEGATE_TARGET_NOT_CAPABLE",
|
|
39728
|
-
taskId: task.id,
|
|
39729
|
-
agentId: input.agentId,
|
|
39730
|
-
error: `Agent '${input.agentId}' cannot manage tasks, so a dispatched TaskItem could never be completed.`,
|
|
39731
|
-
hint: "Delegate to an agent with the `task` middleware (exposes `manage_task`), or do the work inline and update the task with `manage_task set_status`."
|
|
39732
|
-
}
|
|
39733
|
-
};
|
|
39734
|
-
}
|
|
39735
|
-
}
|
|
39736
39817
|
const managedAuthority = executionAuthorityRegistry.resolve(task);
|
|
39737
39818
|
if (managedAuthority) {
|
|
39738
39819
|
if (managedAuthority.onManagedStart) {
|
|
@@ -40144,6 +40225,7 @@ function toJsonSafeValue(value) {
|
|
|
40144
40225
|
}
|
|
40145
40226
|
|
|
40146
40227
|
// src/services/TaskExecutionService.ts
|
|
40228
|
+
var import_langgraph14 = require("@langchain/langgraph");
|
|
40147
40229
|
function persistedExecutionObservation(item, attempted) {
|
|
40148
40230
|
const detail = item.detail;
|
|
40149
40231
|
const persistedObservation = toJsonSafeValue(detail?.observation);
|
|
@@ -40190,9 +40272,10 @@ function createTaskExecutionService(deps) {
|
|
|
40190
40272
|
const run = async (plan) => {
|
|
40191
40273
|
const { tenantId: tenantId2, agentId, actor, parent, completedDependencies } = plan;
|
|
40192
40274
|
let task = plan.task;
|
|
40275
|
+
const persistedThreadId = (task.status === "interrupted" || task.status === "failed") && typeof task.context?.thread_id === "string" && task.context.thread_id.trim() !== "" ? task.context.thread_id : void 0;
|
|
40193
40276
|
let threadId;
|
|
40194
40277
|
try {
|
|
40195
|
-
threadId = (deps.createThreadId ?? import_node_crypto9.randomUUID)();
|
|
40278
|
+
threadId = persistedThreadId ?? (deps.createThreadId ?? import_node_crypto9.randomUUID)();
|
|
40196
40279
|
} catch (error) {
|
|
40197
40280
|
return {
|
|
40198
40281
|
success: false,
|
|
@@ -40203,7 +40286,7 @@ function createTaskExecutionService(deps) {
|
|
|
40203
40286
|
};
|
|
40204
40287
|
}
|
|
40205
40288
|
const eventKey = `execution-result:${threadId}`;
|
|
40206
|
-
if (!(0,
|
|
40289
|
+
if (!(0, import_protocols32.isExecutionResultEventKey)(eventKey)) {
|
|
40207
40290
|
return {
|
|
40208
40291
|
success: false,
|
|
40209
40292
|
code: "INVALID_EXECUTION_RESULT_ID",
|
|
@@ -40231,12 +40314,12 @@ function createTaskExecutionService(deps) {
|
|
|
40231
40314
|
task = transfer.task;
|
|
40232
40315
|
}
|
|
40233
40316
|
const warnings = [];
|
|
40234
|
-
if (task.status === "pending") {
|
|
40317
|
+
if (task.status === "pending" || task.status === "interrupted" || task.status === "failed") {
|
|
40235
40318
|
const begun = await bridge.beginRun({
|
|
40236
40319
|
tenantId: tenantId2,
|
|
40237
40320
|
task,
|
|
40238
40321
|
actor,
|
|
40239
|
-
threadId
|
|
40322
|
+
threadId
|
|
40240
40323
|
});
|
|
40241
40324
|
if (!begun.success) return { ...begun, taskId: task.id };
|
|
40242
40325
|
if (!begun.mutated || !begun.transitioned) {
|
|
@@ -40265,6 +40348,19 @@ function createTaskExecutionService(deps) {
|
|
|
40265
40348
|
try {
|
|
40266
40349
|
observation = toJsonSafeValue(await deps.invokeAgent(invocation));
|
|
40267
40350
|
} catch (error) {
|
|
40351
|
+
if (error instanceof import_langgraph14.GraphInterrupt) {
|
|
40352
|
+
try {
|
|
40353
|
+
await bridge.settleRun({
|
|
40354
|
+
tenantId: tenantId2,
|
|
40355
|
+
task,
|
|
40356
|
+
actor,
|
|
40357
|
+
threadId,
|
|
40358
|
+
outcome: { kind: "interrupted", summary: "Awaiting user input" }
|
|
40359
|
+
});
|
|
40360
|
+
} catch {
|
|
40361
|
+
}
|
|
40362
|
+
throw error;
|
|
40363
|
+
}
|
|
40268
40364
|
const normalizationError = error instanceof JsonSafeValueError;
|
|
40269
40365
|
const message = normalizationError ? `${error.code}: ${error.message}` : errorMessage(error);
|
|
40270
40366
|
const failureCode = normalizationError ? "EXECUTION_RESULT_NORMALIZATION_FAILED" : "AGENT_INVOCATION_FAILED";
|
|
@@ -40395,6 +40491,76 @@ function createTaskExecutionService(deps) {
|
|
|
40395
40491
|
};
|
|
40396
40492
|
}
|
|
40397
40493
|
|
|
40494
|
+
// src/services/TaskRunRegistry.ts
|
|
40495
|
+
var TaskRunRegistry = class {
|
|
40496
|
+
constructor() {
|
|
40497
|
+
this.live = /* @__PURE__ */ new Set();
|
|
40498
|
+
}
|
|
40499
|
+
/** Marks a task as currently held by a live run. */
|
|
40500
|
+
register(taskId) {
|
|
40501
|
+
this.live.add(taskId);
|
|
40502
|
+
}
|
|
40503
|
+
/** Removes a task once its run has ended. */
|
|
40504
|
+
unregister(taskId) {
|
|
40505
|
+
this.live.delete(taskId);
|
|
40506
|
+
}
|
|
40507
|
+
/** Reports whether a task is currently held by a live run. */
|
|
40508
|
+
isLive(taskId) {
|
|
40509
|
+
return this.live.has(taskId);
|
|
40510
|
+
}
|
|
40511
|
+
/** Returns a snapshot of the live task ids (diagnostics/tests). */
|
|
40512
|
+
snapshot() {
|
|
40513
|
+
return [...this.live];
|
|
40514
|
+
}
|
|
40515
|
+
/** Clears all live entries (tests / process teardown). */
|
|
40516
|
+
clear() {
|
|
40517
|
+
this.live.clear();
|
|
40518
|
+
}
|
|
40519
|
+
};
|
|
40520
|
+
var taskRunRegistry = new TaskRunRegistry();
|
|
40521
|
+
async function reconcileStaleTaskRuns(input) {
|
|
40522
|
+
const registry4 = input.registry ?? taskRunRegistry;
|
|
40523
|
+
const converged = [];
|
|
40524
|
+
for (const task of input.tasks) {
|
|
40525
|
+
if (task.status !== "in_progress" || registry4.isLive(task.id)) continue;
|
|
40526
|
+
const result = await input.lifecycle.interruptTask({
|
|
40527
|
+
tenantId: task.tenantId,
|
|
40528
|
+
taskId: task.id,
|
|
40529
|
+
actor: input.actor,
|
|
40530
|
+
type: "missing_input",
|
|
40531
|
+
summary: "Run is no longer executing this task (no_executor)"
|
|
40532
|
+
});
|
|
40533
|
+
if (result.success) converged.push(task.id);
|
|
40534
|
+
}
|
|
40535
|
+
return { converged };
|
|
40536
|
+
}
|
|
40537
|
+
async function reconcileTenantTaskRuns(input) {
|
|
40538
|
+
const tasks = await input.taskStore.list({ tenantId: input.tenantId, status: "in_progress" });
|
|
40539
|
+
const candidates = input.include ? tasks.filter(input.include) : tasks;
|
|
40540
|
+
return reconcileStaleTaskRuns({
|
|
40541
|
+
tasks: candidates,
|
|
40542
|
+
actor: input.actor,
|
|
40543
|
+
lifecycle: input.lifecycle,
|
|
40544
|
+
...input.registry ? { registry: input.registry } : {}
|
|
40545
|
+
});
|
|
40546
|
+
}
|
|
40547
|
+
async function reconcileAllTenantTaskRuns(input) {
|
|
40548
|
+
const tenants = await input.tenantStore.listTenants();
|
|
40549
|
+
const converged = [];
|
|
40550
|
+
for (const tenant of tenants) {
|
|
40551
|
+
const result = await reconcileTenantTaskRuns({
|
|
40552
|
+
tenantId: tenant.id,
|
|
40553
|
+
actor: input.actor,
|
|
40554
|
+
taskStore: input.taskStore,
|
|
40555
|
+
lifecycle: input.lifecycle,
|
|
40556
|
+
...input.registry ? { registry: input.registry } : {},
|
|
40557
|
+
...input.include ? { include: input.include } : {}
|
|
40558
|
+
});
|
|
40559
|
+
converged.push(...result.converged);
|
|
40560
|
+
}
|
|
40561
|
+
return { converged };
|
|
40562
|
+
}
|
|
40563
|
+
|
|
40398
40564
|
// src/index.ts
|
|
40399
40565
|
var Protocols = __toESM(require("@axiom-lattice/protocols"));
|
|
40400
40566
|
|
|
@@ -41759,7 +41925,7 @@ function createMetricsRuntimeTool(params) {
|
|
|
41759
41925
|
// src/middlewares/semanticMetricsModelingSkill.ts
|
|
41760
41926
|
var CONTENT = `---
|
|
41761
41927
|
name: semantic-metrics-modeling
|
|
41762
|
-
description: Builder policy for turning a granted datasource into published semantic tables and metrics. Governs goal agreement, FEP verification,
|
|
41928
|
+
description: Builder policy for turning a granted datasource into published semantic tables and metrics. Defines the orchestrator/worker contract \u2014 the orchestrator agrees goals, proposes the model, plans persistent tasks, and delegates execution to general-purpose workers with self-contained briefs; workers execute one bound brief each. Governs goal agreement, delegation, FEP verification, belief-state reconciliation, and continuous refinement until acceptance evidence is met.
|
|
41763
41929
|
---
|
|
41764
41930
|
|
|
41765
41931
|
# Semantic Metrics Modeling
|
|
@@ -41768,6 +41934,15 @@ You are the Semantic Metrics Builder. You turn physical datasource tables into r
|
|
|
41768
41934
|
**semantic tables** and **business metrics** on a Metrics Server (\`/api/v1\`). Work is
|
|
41769
41935
|
governed, observable, and continuously refined \u2014 never a one-shot guess.
|
|
41770
41936
|
|
|
41937
|
+
You always operate in exactly ONE of two roles:
|
|
41938
|
+
|
|
41939
|
+
- **Orchestrator** (default; no \`## Bound Task\` section in your context): you face the
|
|
41940
|
+
user. You agree the Goal Model, propose the model, plan persistent tasks, dispatch
|
|
41941
|
+
execution to workers, reconcile belief, and own every user interaction.
|
|
41942
|
+
- **Worker** (your context contains a \`## Bound Task\` section naming you executor of one
|
|
41943
|
+
task): you execute that task's brief only. See **Worker mode** \u2014 its rules override the
|
|
41944
|
+
orchestrator policy.
|
|
41945
|
+
|
|
41771
41946
|
## Goal Model
|
|
41772
41947
|
|
|
41773
41948
|
Before any exploration or publishing, agree with the user on:
|
|
@@ -41776,16 +41951,17 @@ Before any exploration or publishing, agree with the user on:
|
|
|
41776
41951
|
- **Usable state**: observable conditions that make the published meta useful.
|
|
41777
41952
|
- **Scope**: which datasource/tables, and what is explicitly out of scope.
|
|
41778
41953
|
- **Acceptance evidence**: objective criteria (e.g. "metric \`sell_in_nes\` returns sane monthly
|
|
41779
|
-
totals for 2024") used to decide success.
|
|
41954
|
+
totals for 2024") used to decide success. Verbatim acceptance evidence is required later by
|
|
41955
|
+
the Verify dispatch \u2014 record it exactly.
|
|
41780
41956
|
Do not guess material goals, consumers, or acceptance evidence.
|
|
41781
41957
|
|
|
41782
41958
|
**Vague requests** (e.g. "build the metric layer") \u2014 do not act and do not ask blind questions.
|
|
41783
|
-
First run cheap read-only observations (\`list_datasources\`, \`get_grants\`, \`
|
|
41784
|
-
|
|
41785
|
-
|
|
41786
|
-
|
|
41787
|
-
options for the user to answer in one step. Only after the user picks a direction does the
|
|
41788
|
-
Model become confirmable \u2014 record it, create the task, and proceed to the workflow.
|
|
41959
|
+
First run cheap read-only observations (\`list_datasources\`, \`get_grants\`, \`list_metrics\`) to
|
|
41960
|
+
see what is authorized and already published, then ask focused questions that carry that
|
|
41961
|
+
context and offer concrete options (which datasource/tables, which business questions, extend
|
|
41962
|
+
existing metrics or build new). Every clarification question must include enough context and
|
|
41963
|
+
options for the user to answer in one step. Only after the user picks a direction does the
|
|
41964
|
+
Goal Model become confirmable \u2014 record it, create the task, and proceed to the workflow.
|
|
41789
41965
|
|
|
41790
41966
|
## Target model and quality bar
|
|
41791
41967
|
|
|
@@ -41823,19 +41999,152 @@ Apply this loop to every step (explore, publish table, publish metric, verify):
|
|
|
41823
41999
|
- **Decide**: classify as **RETAIN** (confirmed), **REVERT** (rejected), or **INCONCLUSIVE**.
|
|
41824
42000
|
- **Reconcile**: update the belief state and plan, then repeat while decision-relevant action remains.
|
|
41825
42001
|
|
|
41826
|
-
|
|
42002
|
+
The orchestrator applies the loop **between dispatches** (each observation updates the plan
|
|
42003
|
+
before the next brief is written). A worker applies it **inside its brief**.
|
|
41827
42004
|
|
|
41828
|
-
|
|
41829
|
-
|
|
41830
|
-
Use persistent TaskItems as your planning surface. Do not use \`write_todos\`. Create a child task
|
|
41831
|
-
only for an independently verifiable outcome (e.g. "publish table meta for \`hankel_distr_sell_in\`").
|
|
41832
|
-
Exploration queries and tool calls are activities inside the active task. See the
|
|
41833
|
-
\`task-definition\` skill for \`manage_task\` operation details.
|
|
41834
|
-
|
|
41835
|
-
## Belief State
|
|
42005
|
+
Renew user approval when a foundational assumption or the goal changes.
|
|
41836
42006
|
|
|
41837
|
-
|
|
41838
|
-
|
|
42007
|
+
## Orchestrator: Task Policy
|
|
42008
|
+
|
|
42009
|
+
You are an orchestrator, not the hands. Exactly five duties:
|
|
42010
|
+
|
|
42011
|
+
1. **Goal Model agreement** \u2014 including cheap read-only observation for vague requests
|
|
42012
|
+
(\`list_datasources\`, \`get_grants\`, \`list_metrics\`). This is your ONLY inline datasource
|
|
42013
|
+
access; do not use \`write_todos\`.
|
|
42014
|
+
2. **Propose the model** and get user approval.
|
|
42015
|
+
3. **Task tree** \u2014 parent task = contract + \`## Belief State\`; child tasks = independently
|
|
42016
|
+
verifiable outcomes (explore / publish-table / publish-metric / verify), one per dispatch.
|
|
42017
|
+
See the \`task-definition\` skill for \`manage_task\` operation details.
|
|
42018
|
+
4. **Dispatch and collect** \u2014 \`task { taskId, agentId: "general-purpose" }\`; read the
|
|
42019
|
+
observation; record the \`executionResultId\` on the child task with \`manage_task update\` or
|
|
42020
|
+
\`add_activity\`; reconcile \`## Belief State\`.
|
|
42021
|
+
5. **HITL** \u2014 every \`ask_user_to_clarify\` is yours. Workers never ask the user.
|
|
42022
|
+
|
|
42023
|
+
Hard rules:
|
|
42024
|
+
- Never run exploration SQL inline. Never build or publish payloads inline (sole exception:
|
|
42025
|
+
the Publish/Verify inline fallback below).
|
|
42026
|
+
- **Belief State: you are the sole writer.** Workers return findings in their results; you
|
|
42027
|
+
update \`## Belief State\` via \`manage_task update\` on the parent task. Workers never touch it.
|
|
42028
|
+
- **Dispatch serially** \u2014 one worker at a time; reconcile belief before writing the next brief.
|
|
42029
|
+
- **Distinguish dispatch failure from worker outcome**: a dispatch failure is a tool-level
|
|
42030
|
+
error where the worker never ran. A worker returning INCONCLUSIVE or failed is a normal FEP
|
|
42031
|
+
input \u2014 reconcile it, never treat it as a dispatch failure.
|
|
42032
|
+
|
|
42033
|
+
Dispatch failure handling (worker never ran, tool error):
|
|
42034
|
+
1. Retry the dispatch once (recreate the child task if the store reports it unusable).
|
|
42035
|
+
2. **Explore: never execute inline.** If the retry fails, stop and ask the user via
|
|
42036
|
+
\`ask_user_to_clarify\` (report what is blocked and why).
|
|
42037
|
+
3. **Publish/Verify: after a failed retry you MAY execute inline** to preserve delivery \u2014
|
|
42038
|
+
the payload decisions are already in your context. Follow the same gate self-check as a
|
|
42039
|
+
worker would.
|
|
42040
|
+
|
|
42041
|
+
## Delegation Protocol
|
|
42042
|
+
|
|
42043
|
+
Mechanics every brief must be designed around:
|
|
42044
|
+
|
|
42045
|
+
- A worker sees ONLY: its task title + description, the parent task's description, and the
|
|
42046
|
+
results of completed dependency tasks. It does NOT see this conversation.
|
|
42047
|
+
- Therefore **every brief is self-contained**: all decisions, boundaries, and evidence travel
|
|
42048
|
+
inside the task description.
|
|
42049
|
+
- Dispatch is synchronous: \`task { taskId, agentId: "general-purpose" }\` returns an
|
|
42050
|
+
observation (the worker's final message, truncated at ~8k chars) and an
|
|
42051
|
+
\`executionResultId\`. Record the id on the child task (\`manage_task update\`/\`add_activity\`).
|
|
42052
|
+
- The worker settles its own task (\`set_status\` with \`result\`/\`failureReason\`). Read both the
|
|
42053
|
+
observation and the task result before reconciling.
|
|
42054
|
+
|
|
42055
|
+
Write briefs as field checklists adapted to the situation \u2014 decisions and evidence, not prose.
|
|
42056
|
+
The worker assembles payloads from the reference sections of this skill; the brief carries the
|
|
42057
|
+
approved decisions, never full payload JSON.
|
|
42058
|
+
|
|
42059
|
+
### Explore brief (\`Explore <schema>.<table> for <goal>\`)
|
|
42060
|
+
|
|
42061
|
+
Required fields:
|
|
42062
|
+
1. Datasource: serverKey/connectionKey + datasourceId (and \`runConfig.metricsDataSource\` preset if present).
|
|
42063
|
+
2. Grant boundary: the allowed schema + table pattern from \`get_grants\`, verbatim; never probe outside it.
|
|
42064
|
+
3. Target table(s): schema-qualified names; one brief per table.
|
|
42065
|
+
4. Question list: per column (or column group) \u2014 business meaning candidates, expected role
|
|
42066
|
+
(dimension | measure | time), net/gross, grain.
|
|
42067
|
+
5. Method: read-only SELECT/WITH only; use the \`references/metadata-sql.md\` templates
|
|
42068
|
+
(columns, sample rows, value distribution); cap sample size (e.g. \u22641000 rows, \u226450 groups).
|
|
42069
|
+
Prefer targeted queries over bulk catalog dumps. A large single read (e.g. full
|
|
42070
|
+
\`read_semantic_catalog\` detail) is allowed \u2014 your isolation protects the orchestrator's
|
|
42071
|
+
context \u2014 but findings must be compressed to conclusion level.
|
|
42072
|
+
6. Output contract: structured findings \u2014 per column: observed type, sample values,
|
|
42073
|
+
distribution highlights, role candidate + evidence, \`INCONCLUSIVE\` marking for unresolved
|
|
42074
|
+
semantics.
|
|
42075
|
+
7. Invariants: read-only only; grant boundary absolute; never guess \u2014 \`INCONCLUSIVE\` instead.
|
|
42076
|
+
8. Closing: settle the task (\`set_status completed\`, result = findings summary); final message
|
|
42077
|
+
= the structured findings (it becomes the observation).
|
|
42078
|
+
|
|
42079
|
+
### Publish-table brief (\`Publish table meta <objectKey>\`)
|
|
42080
|
+
|
|
42081
|
+
Required fields:
|
|
42082
|
+
1. Approved decisions: full column list (name/type/role/label/description), grain,
|
|
42083
|
+
displayName/docType/shortDesc/sourceSystem/sourceTables.
|
|
42084
|
+
2. Identity: \`objectKey\` (stable, unique per datasource) + \`schemaName.tableName\`.
|
|
42085
|
+
3. Assembly instruction: full \`table_view_detail\` payload per **Publish table meta** below,
|
|
42086
|
+
plus the identity twin (\`table_catalog\`, same \`objectKey\`), plus an EXACT \`accessGrant\`
|
|
42087
|
+
matching the tenant grant.
|
|
42088
|
+
4. Gate self-check: publish gate items 1\u20133 \u2014 do not publish if any fails.
|
|
42089
|
+
5. Publish via \`metrics_meta_tool\` \`create_table\`; then \`get_meta\` to confirm visibility.
|
|
42090
|
+
6. Mistakes: fix with \`update_table\`; never leave a partial publish.
|
|
42091
|
+
7. Invariants: EXACT patternType; every column tagged and labeled.
|
|
42092
|
+
8. Closing: settle the task; final message = receipts (objectKeys + get_meta confirmation).
|
|
42093
|
+
|
|
42094
|
+
### Publish-metric brief (\`Publish metric <objectKey>\`)
|
|
42095
|
+
|
|
42096
|
+
Required fields (per metric):
|
|
42097
|
+
1. Identity: \`objectKey\` = \`metric_name\`, display_name, domain, description, data_type, format.
|
|
42098
|
+
2. Source: schema-qualified \`source.table_view\` (must match the published table meta).
|
|
42099
|
+
3. Calculation: aggregate (\`aggregation\` + \`measure\`, with the confirmed business meaning) or
|
|
42100
|
+
derived (ratio references / formula) \u2014 exactly as approved in Propose the model.
|
|
42101
|
+
4. \`supported_dimensions\`: array of objects \`{dim_id, field_name, label, data_type}\`,
|
|
42102
|
+
including the time dimension.
|
|
42103
|
+
5. \`default_time_context\`: time_dimension + granularity + supported_grains (+ window if requested).
|
|
42104
|
+
6. \`ai_agent_context\`: polarity, synonyms, human_readable_explanation.
|
|
42105
|
+
7. Assembly instruction: \`metric_index\` then \`metric_detail\` in the FULL runtime style per
|
|
42106
|
+
**Publish metric meta** below; publish via \`metrics_meta_tool\` \`create_metric\`.
|
|
42107
|
+
8. Gate self-check + smoke \`query\` (one grouping by the default time grain) + \`get_meta\`
|
|
42108
|
+
receipts; closing = settle the task, final message = receipts.
|
|
42109
|
+
|
|
42110
|
+
### Verify brief (\`Verify <metric> against acceptance evidence\`)
|
|
42111
|
+
|
|
42112
|
+
Required fields:
|
|
42113
|
+
1. Acceptance evidence verbatim (from the Goal Model).
|
|
42114
|
+
2. Queries to run (semantic \`query\` via \`metrics_runtime_tool\`) and the expected shape/values.
|
|
42115
|
+
3. Report contract: PASS/FAIL verdict + actual vs expected; on FAIL include the differences
|
|
42116
|
+
and a suspicion list \u2014 do NOT modify meta (fixes are new Publish tasks).
|
|
42117
|
+
4. Invariants: read-only only.
|
|
42118
|
+
5. Closing: settle the task; final message = the verdict summary.
|
|
42119
|
+
|
|
42120
|
+
### Brief closing (all types)
|
|
42121
|
+
|
|
42122
|
+
- Invariants line: grant boundary + read-only SQL + publish gate before any create.
|
|
42123
|
+
- Result structure: the structured summary the orchestrator expects back.
|
|
42124
|
+
- Finish by settling the task (\`set_status completed\` with result, or \`failed\` with
|
|
42125
|
+
failureReason) and making the final message that structured summary.
|
|
42126
|
+
|
|
42127
|
+
## Worker mode
|
|
42128
|
+
|
|
42129
|
+
Trigger: your context contains \`## Bound Task\`. You are a worker; these rules override the
|
|
42130
|
+
orchestrator policy (Safety and the reference sections still apply):
|
|
42131
|
+
|
|
42132
|
+
- Execute the bound task's brief only. Read the contract with \`manage_task get\`; the task
|
|
42133
|
+
description is authoritative. Load this skill if the bootstrap asks \u2014 you need its payload
|
|
42134
|
+
reference sections.
|
|
42135
|
+
- Do NOT: re-agree the Goal Model, create sibling or child tasks, dispatch \`task\`, call
|
|
42136
|
+
\`ask_user_to_clarify\`, or update the parent task's \`## Belief State\`.
|
|
42137
|
+
- Apply the FEP loop inside the brief; obey the grant boundary and read-only SQL; run the
|
|
42138
|
+
publish gate before any create.
|
|
42139
|
+
- Unclear semantics: mark \`INCONCLUSIVE\` with candidates + evidence in your findings. Never
|
|
42140
|
+
guess, never publish on a guess.
|
|
42141
|
+
- Finish: \`set_status completed\` with a structured result (or \`failed\` with failureReason),
|
|
42142
|
+
and make your final message the structured summary \u2014 it is the observation your
|
|
42143
|
+
orchestrator reads.
|
|
42144
|
+
|
|
42145
|
+
## Belief State (orchestrator-owned)
|
|
42146
|
+
|
|
42147
|
+
The parent task's description carries a \`## Belief State\` section as a Markdown table:
|
|
41839
42148
|
|
|
41840
42149
|
\`\`\`
|
|
41841
42150
|
| Belief Key | Probability | Target | Basis |
|
|
@@ -41844,31 +42153,35 @@ a Markdown table:
|
|
|
41844
42153
|
\`\`\`
|
|
41845
42154
|
|
|
41846
42155
|
Rules: belief keys are lowercase kebab-case; probability/target are percentages 0\u2013100% that
|
|
41847
|
-
represent evidence support, not calibrated probability.
|
|
41848
|
-
the
|
|
42156
|
+
represent evidence support, not calibrated probability. Only the orchestrator writes this
|
|
42157
|
+
section \u2014 after each dispatch it folds the worker's findings into the table so the parent
|
|
42158
|
+
task always reflects the current evidence.
|
|
41849
42159
|
|
|
41850
42160
|
## Workflow
|
|
41851
42161
|
|
|
41852
|
-
1. **Pick the datasource.** \`metrics_datasource_tool\` action
|
|
41853
|
-
\`runConfig.metricsDataSource\` (\`serverKey\`\u2192connectionKey,
|
|
41854
|
-
|
|
41855
|
-
|
|
41856
|
-
|
|
41857
|
-
|
|
41858
|
-
|
|
41859
|
-
|
|
41860
|
-
|
|
41861
|
-
|
|
41862
|
-
|
|
41863
|
-
7. **
|
|
41864
|
-
|
|
41865
|
-
|
|
42162
|
+
1. **Pick the datasource + cheap observation.** \`metrics_datasource_tool\` action
|
|
42163
|
+
\`list_datasources\`, or the preset \`runConfig.metricsDataSource\` (\`serverKey\`\u2192connectionKey,
|
|
42164
|
+
\`datasourceId\`). Inline, read-only.
|
|
42165
|
+
2. **Agree the Goal Model.** (HITL)
|
|
42166
|
+
3. **Create the parent task** \u2014 contract + \`## Belief State\` (seeded from the Goal Model).
|
|
42167
|
+
4. **Explore by dispatch** \u2014 one Explore brief per table, serial; collect findings; reconcile
|
|
42168
|
+
\`## Belief State\`; collect \`INCONCLUSIVE\` columns.
|
|
42169
|
+
5. **Propose the model** (HITL) \u2014 present table columns (with \`role: dimension | measure\`)
|
|
42170
|
+
and the metrics (aggregate/derived) for approval; include clarify questions for
|
|
42171
|
+
\`INCONCLUSIVE\` columns in the same ask.
|
|
42172
|
+
6. **Publish tables by dispatch** \u2014 one Publish-table brief per table; check receipts.
|
|
42173
|
+
7. **Publish metrics by dispatch** \u2014 one Publish-metric brief per metric; receipts + smoke query.
|
|
42174
|
+
8. **Verify by dispatch** \u2014 Verify brief against acceptance evidence. FAIL \u2192 reconcile
|
|
42175
|
+
belief \u2192 fix decisions \u2192 new Publish task (\`update_table\`/\`update_metric\`) \u2192 re-Verify.
|
|
42176
|
+
PASS \u2192 complete the parent task (result = acceptance evidence met).
|
|
42177
|
+
|
|
42178
|
+
## Explore (reference)
|
|
41866
42179
|
|
|
41867
42180
|
Read \`table-grants\`, then probe with \`query\`. SQL is validated read-only by the client and the
|
|
41868
42181
|
server enforces the grant; un-granted tables return \`TABLE_NOT_GRANTED\`. Prefer the
|
|
41869
42182
|
\`references/metadata-sql.md\` templates because dialect varies (PostgreSQL / SQL Server / HANA).
|
|
41870
|
-
If the user provides a data dictionary or sample data file, read it with filesystem and
|
|
41871
|
-
against the probed columns.
|
|
42183
|
+
If the user provides a data dictionary or sample data file, read it with filesystem and
|
|
42184
|
+
reconcile it against the probed columns.
|
|
41872
42185
|
|
|
41873
42186
|
## Unclear field semantics
|
|
41874
42187
|
|
|
@@ -41877,7 +42190,7 @@ sum, a rate to average, or an enum to filter). Publishing meta on a misunderstoo
|
|
|
41877
42190
|
the runtime and every downstream metric that depends on it, and delete is not available. Treat this
|
|
41878
42191
|
as FEP **INCONCLUSIVE** \u2014 never guess, and never publish on an unverified guess.
|
|
41879
42192
|
|
|
41880
|
-
Resolve in order of increasing cost:
|
|
42193
|
+
Resolve in order of increasing cost (inside the Explore brief):
|
|
41881
42194
|
1. **Probe sample values and distribution** (\`query\`, templates in \`references/metadata-sql.md\`):
|
|
41882
42195
|
- numbers in (0,1) or clustered near 100 \u2192 likely a ratio/percentage \u2192 dimension or \`avg\`, rarely \`sum\`;
|
|
41883
42196
|
- large additive amounts (currency, counts) \u2192 measure with \`sum\`;
|
|
@@ -41889,14 +42202,16 @@ Resolve in order of increasing cost:
|
|
|
41889
42202
|
|
|
41890
42203
|
If evidence is still INCONCLUSIVE:
|
|
41891
42204
|
- Do **not** publish meta that depends on the unclear field.
|
|
41892
|
-
-
|
|
41893
|
-
|
|
41894
|
-
|
|
41895
|
-
|
|
41896
|
-
|
|
41897
|
-
|
|
42205
|
+
- The worker marks the column \`INCONCLUSIVE\` (candidates + evidence) in its findings; the
|
|
42206
|
+
**orchestrator** lists it with candidate interpretations in the **Propose the model** step
|
|
42207
|
+
and asks the user to confirm its semantics (role, value meaning, net/gross) via
|
|
42208
|
+
\`ask_user_to_clarify\`. The user does not need to see the table \u2014 probed schema, samples, and
|
|
42209
|
+
candidates are enough.
|
|
42210
|
+
- The orchestrator records a low-probability belief entry (e.g.
|
|
42211
|
+
\`| sales-nes-semantics | 40% | 100% | user must confirm role / net amount |\`) so verify/refine
|
|
42212
|
+
can revisit it later instead of assuming it is settled.
|
|
41898
42213
|
|
|
41899
|
-
##
|
|
42214
|
+
## Publish table meta (\`create_table\`)
|
|
41900
42215
|
|
|
41901
42216
|
Publish the authoritative shape below (objectType \`table_view_detail\`, with an EXACT accessGrant):
|
|
41902
42217
|
|
|
@@ -41939,7 +42254,7 @@ Design rules:
|
|
|
41939
42254
|
- Runtime table publication uses \`patternType: "EXACT"\` (\`PREFIX\` is only for datasource-level exploration scopes).
|
|
41940
42255
|
- For each semantic table also publish the identity twin: the same body with \`objectType: "table_catalog"\` and the same \`objectKey\` (same or richer payload).
|
|
41941
42256
|
|
|
41942
|
-
##
|
|
42257
|
+
## Publish metric meta (\`create_metric\`)
|
|
41943
42258
|
|
|
41944
42259
|
Two steps for the same \`objectKey\`.
|
|
41945
42260
|
|
|
@@ -42047,11 +42362,13 @@ Design rules:
|
|
|
42047
42362
|
- Do not inline raw SQL for new DB-backed metrics (complex logic belongs in a view).
|
|
42048
42363
|
- Use \`update_metric\` / \`update_table\` to correct mistakes; no removal actions are exposed.
|
|
42049
42364
|
|
|
42050
|
-
##
|
|
42365
|
+
## Verify and refine
|
|
42051
42366
|
|
|
42052
|
-
- \`get_meta\` \u2192
|
|
42053
|
-
|
|
42054
|
-
|
|
42367
|
+
- Verify is **dispatched** (Verify brief). The worker runs \`get_meta\` \u2192 confirms the table and
|
|
42368
|
+
metric are visible, then \`query\`es the metric against acceptance evidence.
|
|
42369
|
+
- On FAIL the worker reports differences; the **orchestrator** applies the FEP reconcile:
|
|
42370
|
+
update \`## Belief State\`, fix the decisions, and dispatch a new Publish task
|
|
42371
|
+
(\`update_table\`/\`update_metric\`) \u2014 then re-Verify \u2014 until acceptance evidence is met.
|
|
42055
42372
|
|
|
42056
42373
|
## Troubleshooting
|
|
42057
42374
|
|
|
@@ -42063,6 +42380,8 @@ Design rules:
|
|
|
42063
42380
|
| derived metric create fails | numerator/denominator metrics don't exist yet \u2014 publish them first |
|
|
42064
42381
|
| datasource \`query\` rejected | SQL was not read-only (SELECT/WITH only) or multi-statement |
|
|
42065
42382
|
| \`403 Metric is not authorized\` on query_metrics | the metric meta is not in the queryable runtime schema (e.g. missing \`source.table_view\` / \`supported_dimensions\` / \`default_time_context\`) or genuinely unauthorized \u2014 re-publish with the full runtime payload and verify; never retry blindly |
|
|
42383
|
+
| worker observation truncated | findings exceeded ~8k chars; worker must keep the final message a compact structured summary |
|
|
42384
|
+
| dispatch failed (tool error) | retry once; Explore never goes inline \u2014 ask the user; Publish/Verify may go inline after the failed retry |
|
|
42066
42385
|
|
|
42067
42386
|
## Safety
|
|
42068
42387
|
|
|
@@ -42119,15 +42438,35 @@ the SQL is validated read-only.
|
|
|
42119
42438
|
"examples/metric-aggregate.json": {
|
|
42120
42439
|
content: `{
|
|
42121
42440
|
"objectType": "metric_detail",
|
|
42122
|
-
"objectKey": "
|
|
42441
|
+
"objectKey": "sell_in_nes",
|
|
42123
42442
|
"status": 1,
|
|
42124
42443
|
"payload": {
|
|
42125
|
-
"
|
|
42126
|
-
"
|
|
42444
|
+
"metric_name": "sell_in_nes",
|
|
42445
|
+
"display_name": "Sell-in NES",
|
|
42446
|
+
"domain": "sales",
|
|
42127
42447
|
"description": "Net external sales amount from distributor sell-in rows.",
|
|
42128
|
-
"
|
|
42448
|
+
"data_type": "numeric",
|
|
42449
|
+
"format": "currency",
|
|
42450
|
+
"source_type": "cdp_postgres",
|
|
42451
|
+
"source": { "table_view": "public.hankel_distr_sell_in", "base_filters": [] },
|
|
42129
42452
|
"calculation": { "type": "aggregate", "aggregation": "sum", "measure": "nes" },
|
|
42130
|
-
"
|
|
42453
|
+
"supported_dimensions": [
|
|
42454
|
+
{ "dim_id": "posting_year", "field_name": "posting_year", "label": "Posting Year", "data_type": "number" },
|
|
42455
|
+
{ "dim_id": "sales_team", "field_name": "sales_team", "label": "Sales Team", "data_type": "string" },
|
|
42456
|
+
{ "dim_id": "posting_date", "field_name": "posting_date", "label": "Posting Date", "data_type": "string" }
|
|
42457
|
+
],
|
|
42458
|
+
"default_time_context": {
|
|
42459
|
+
"time_dimension": "posting_date",
|
|
42460
|
+
"label": "Posting date",
|
|
42461
|
+
"granularity": "month",
|
|
42462
|
+
"window": "YTD",
|
|
42463
|
+
"supported_grains": ["month", "year"]
|
|
42464
|
+
},
|
|
42465
|
+
"ai_agent_context": {
|
|
42466
|
+
"polarity": "positive",
|
|
42467
|
+
"synonyms": ["sell in", "nes", "net external sales"],
|
|
42468
|
+
"human_readable_explanation": "Higher sell-in NES means more goods purchased from the distributor."
|
|
42469
|
+
}
|
|
42131
42470
|
}
|
|
42132
42471
|
}
|
|
42133
42472
|
`
|
|
@@ -42135,27 +42474,40 @@ the SQL is validated read-only.
|
|
|
42135
42474
|
"examples/metric-derived.json": {
|
|
42136
42475
|
content: `{
|
|
42137
42476
|
"objectType": "metric_detail",
|
|
42138
|
-
"objectKey": "
|
|
42477
|
+
"objectKey": "gross_margin_rate",
|
|
42139
42478
|
"status": 1,
|
|
42140
42479
|
"payload": {
|
|
42141
|
-
"
|
|
42142
|
-
"
|
|
42480
|
+
"metric_name": "gross_margin_rate",
|
|
42481
|
+
"display_name": "Gross Margin Rate",
|
|
42482
|
+
"domain": "sales",
|
|
42143
42483
|
"description": "Gross margin divided by sell-in NES.",
|
|
42144
|
-
"
|
|
42145
|
-
"
|
|
42146
|
-
|
|
42147
|
-
|
|
42148
|
-
|
|
42149
|
-
|
|
42484
|
+
"data_type": "numeric",
|
|
42485
|
+
"format": "percent",
|
|
42486
|
+
"source_type": "cdp_postgres",
|
|
42487
|
+
"source": { "table_view": "public.hankel_distr_sell_in", "base_filters": [] },
|
|
42488
|
+
"calculation": { "type": "derived", "operator": "ratio", "numerator": "gross_margin", "denominator": "sell_in_nes" },
|
|
42489
|
+
"supported_dimensions": [
|
|
42490
|
+
{ "dim_id": "posting_year", "field_name": "posting_year", "label": "Posting Year", "data_type": "number" },
|
|
42491
|
+
{ "dim_id": "posting_date", "field_name": "posting_date", "label": "Posting Date", "data_type": "string" }
|
|
42492
|
+
],
|
|
42493
|
+
"default_time_context": {
|
|
42494
|
+
"time_dimension": "posting_date",
|
|
42495
|
+
"label": "Posting date",
|
|
42496
|
+
"granularity": "month",
|
|
42497
|
+
"supported_grains": ["month", "year"]
|
|
42150
42498
|
},
|
|
42151
|
-
"
|
|
42499
|
+
"ai_agent_context": {
|
|
42500
|
+
"polarity": "positive",
|
|
42501
|
+
"synonyms": ["gross margin rate", "margin rate"],
|
|
42502
|
+
"human_readable_explanation": "Gross margin rate divides gross margin by sell-in NES; higher means more margin retained on sold-in goods."
|
|
42503
|
+
}
|
|
42152
42504
|
}
|
|
42153
42505
|
}
|
|
42154
42506
|
`
|
|
42155
42507
|
}
|
|
42156
42508
|
};
|
|
42157
42509
|
var SEMANTIC_METRICS_MODELING_SKILL = {
|
|
42158
|
-
version: "1.
|
|
42510
|
+
version: "1.1.2",
|
|
42159
42511
|
content: CONTENT,
|
|
42160
42512
|
resources
|
|
42161
42513
|
};
|
|
@@ -42169,7 +42521,7 @@ Never announce the skill load. If it fails, retry once, then stop and explicitly
|
|
|
42169
42521
|
report that the required Semantic Metrics Builder skill could not be loaded.`;
|
|
42170
42522
|
|
|
42171
42523
|
// src/middlewares/semanticMetricsMiddleware.ts
|
|
42172
|
-
var
|
|
42524
|
+
var import_protocols33 = require("@axiom-lattice/protocols");
|
|
42173
42525
|
function createSemanticMetricsMiddleware(config) {
|
|
42174
42526
|
const connections = config.connections ?? [];
|
|
42175
42527
|
const connectAll = config.connectAll === true;
|
|
@@ -42321,7 +42673,7 @@ var semanticMetricsPlugin = {
|
|
|
42321
42673
|
key: "semantic-metrics-builder",
|
|
42322
42674
|
name: "Semantic Metrics Builder",
|
|
42323
42675
|
description: "Explore a granted datasource and build semantic tables and metrics interactively, tracking the work as persistent tasks with belief state and verifying each step.",
|
|
42324
|
-
type:
|
|
42676
|
+
type: import_protocols33.AgentType.DEEP_AGENT,
|
|
42325
42677
|
prompt: SEMANTIC_METRICS_BUILDER_PROMPT,
|
|
42326
42678
|
middleware: [
|
|
42327
42679
|
{
|
|
@@ -42854,7 +43206,7 @@ var collectionPlugin = {
|
|
|
42854
43206
|
|
|
42855
43207
|
// src/middlewares/askUserClarifyMiddleware.ts
|
|
42856
43208
|
var import_langchain83 = require("langchain");
|
|
42857
|
-
var
|
|
43209
|
+
var import_langgraph15 = require("@langchain/langgraph");
|
|
42858
43210
|
|
|
42859
43211
|
// src/tool_lattice/ask_user_to_clarify/index.ts
|
|
42860
43212
|
var import_langchain82 = require("langchain");
|
|
@@ -42930,7 +43282,7 @@ function createAskUserClarifyMiddleware() {
|
|
|
42930
43282
|
}))
|
|
42931
43283
|
};
|
|
42932
43284
|
const md = genUIMarkdown("clarify", uiData);
|
|
42933
|
-
const result = await (0,
|
|
43285
|
+
const result = await (0, import_langgraph15.interrupt)(md);
|
|
42934
43286
|
const response = result.data;
|
|
42935
43287
|
if (!response?.answers || response.answers.length === 0) {
|
|
42936
43288
|
return new import_langchain83.ToolMessage({
|
|
@@ -43907,8 +44259,66 @@ var widgetPlugin = {
|
|
|
43907
44259
|
// src/middlewares/taskMiddleware.ts
|
|
43908
44260
|
var import_langchain87 = require("langchain");
|
|
43909
44261
|
var import_zod71 = require("zod");
|
|
43910
|
-
var
|
|
43911
|
-
|
|
44262
|
+
var import_langgraph16 = require("@langchain/langgraph");
|
|
44263
|
+
|
|
44264
|
+
// src/util/truncateForJson.ts
|
|
44265
|
+
var TRUNCATION_MARKER = "...[truncated]";
|
|
44266
|
+
function truncateString(value, cap) {
|
|
44267
|
+
if (value.length <= cap) return value;
|
|
44268
|
+
const budget = Math.max(0, cap - TRUNCATION_MARKER.length);
|
|
44269
|
+
return value.slice(0, budget) + TRUNCATION_MARKER;
|
|
44270
|
+
}
|
|
44271
|
+
function truncateValue(value, depth, maxDepth, maxEntries, maxStringLength, seen) {
|
|
44272
|
+
if (typeof value === "string") return truncateString(value, maxStringLength);
|
|
44273
|
+
if (value === null || typeof value !== "object") return value;
|
|
44274
|
+
if (depth >= maxDepth) return "[truncated:max-depth]";
|
|
44275
|
+
if (seen.has(value)) return "[Circular]";
|
|
44276
|
+
seen.add(value);
|
|
44277
|
+
try {
|
|
44278
|
+
if (value instanceof Date) return value.toISOString();
|
|
44279
|
+
if (Array.isArray(value)) {
|
|
44280
|
+
const limit2 = Math.min(value.length, maxEntries);
|
|
44281
|
+
const output2 = [];
|
|
44282
|
+
for (let index = 0; index < limit2; index += 1) {
|
|
44283
|
+
output2.push(truncateValue(value[index], depth + 1, maxDepth, maxEntries, maxStringLength, seen));
|
|
44284
|
+
}
|
|
44285
|
+
if (value.length > limit2) output2.push("[truncated:entries]");
|
|
44286
|
+
return output2;
|
|
44287
|
+
}
|
|
44288
|
+
const record = value;
|
|
44289
|
+
const output = {};
|
|
44290
|
+
const keys = Object.keys(record);
|
|
44291
|
+
const limit = Math.min(keys.length, maxEntries);
|
|
44292
|
+
for (let index = 0; index < limit; index += 1) {
|
|
44293
|
+
const key5 = keys[index];
|
|
44294
|
+
output[truncateString(key5, maxStringLength)] = truncateValue(
|
|
44295
|
+
record[key5],
|
|
44296
|
+
depth + 1,
|
|
44297
|
+
maxDepth,
|
|
44298
|
+
maxEntries,
|
|
44299
|
+
maxStringLength,
|
|
44300
|
+
seen
|
|
44301
|
+
);
|
|
44302
|
+
}
|
|
44303
|
+
if (keys.length > limit) output["[truncated]"] = true;
|
|
44304
|
+
return output;
|
|
44305
|
+
} finally {
|
|
44306
|
+
seen.delete(value);
|
|
44307
|
+
}
|
|
44308
|
+
}
|
|
44309
|
+
function truncateForJson(value, options = {}) {
|
|
44310
|
+
return truncateValue(
|
|
44311
|
+
value,
|
|
44312
|
+
0,
|
|
44313
|
+
options.maxDepth ?? JSON_SAFE_MAX_DEPTH,
|
|
44314
|
+
options.maxEntries ?? JSON_SAFE_MAX_COLLECTION_ENTRIES,
|
|
44315
|
+
options.maxStringLength ?? JSON_SAFE_MAX_STRING_LENGTH,
|
|
44316
|
+
/* @__PURE__ */ new WeakSet()
|
|
44317
|
+
);
|
|
44318
|
+
}
|
|
44319
|
+
|
|
44320
|
+
// src/middlewares/taskMiddleware.ts
|
|
44321
|
+
var import_protocols34 = require("@axiom-lattice/protocols");
|
|
43912
44322
|
|
|
43913
44323
|
// src/middlewares/taskResponseSerialization.ts
|
|
43914
44324
|
var TASK_RESPONSE_SCALAR_MAX_BYTES = 4096;
|
|
@@ -44232,6 +44642,132 @@ function getRuntimeActor2(runConfig) {
|
|
|
44232
44642
|
if (runConfig.user_id) return `user:${String(runConfig.user_id)}`;
|
|
44233
44643
|
return void 0;
|
|
44234
44644
|
}
|
|
44645
|
+
function readRuntimeRunConfig(source) {
|
|
44646
|
+
const s = source;
|
|
44647
|
+
const rc = s?.context?.runConfig ?? s?.configurable?.runConfig;
|
|
44648
|
+
return rc && typeof rc === "object" && !Array.isArray(rc) ? rc : {};
|
|
44649
|
+
}
|
|
44650
|
+
function readExecutionTaskId(runConfig) {
|
|
44651
|
+
const execution = runConfig.execution;
|
|
44652
|
+
if (!execution || typeof execution !== "object" || Array.isArray(execution)) return void 0;
|
|
44653
|
+
const value = execution.taskId;
|
|
44654
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
44655
|
+
}
|
|
44656
|
+
function renderTaskBinding(taskId) {
|
|
44657
|
+
return `
|
|
44658
|
+
|
|
44659
|
+
## Bound Task
|
|
44660
|
+
|
|
44661
|
+
You are executing task \`${taskId}\`. Read its contract with \`manage_task get\`, update it as you work, and complete it when done.
|
|
44662
|
+
`;
|
|
44663
|
+
}
|
|
44664
|
+
function createBoundTaskLifecycle() {
|
|
44665
|
+
return createTaskLifecycleService({ taskStore: getTaskStore(), workItemStore: getTaskWorkItemStore() });
|
|
44666
|
+
}
|
|
44667
|
+
function createBoundTaskBridge() {
|
|
44668
|
+
return createTaskRunBridge({ lifecycle: createBoundTaskLifecycle() });
|
|
44669
|
+
}
|
|
44670
|
+
function isResumableInterruption(interruption) {
|
|
44671
|
+
if (!interruption || typeof interruption !== "object" || Array.isArray(interruption)) return false;
|
|
44672
|
+
const type = interruption.type;
|
|
44673
|
+
return type === "missing_input" || type === "user_decision";
|
|
44674
|
+
}
|
|
44675
|
+
var TASK_WORKER_OBSERVATION_MAX_CHARS = 8192;
|
|
44676
|
+
function snapshotMessages(state) {
|
|
44677
|
+
if (!state || typeof state !== "object") return [];
|
|
44678
|
+
const values = state.values;
|
|
44679
|
+
if (!values || typeof values !== "object") return [];
|
|
44680
|
+
const messages = values.messages;
|
|
44681
|
+
return Array.isArray(messages) ? messages : [];
|
|
44682
|
+
}
|
|
44683
|
+
function messageText(value) {
|
|
44684
|
+
if (typeof value === "string") return value;
|
|
44685
|
+
if (!Array.isArray(value)) return void 0;
|
|
44686
|
+
return value.flatMap((part) => {
|
|
44687
|
+
if (typeof part === "string") return [part];
|
|
44688
|
+
if (part && typeof part === "object" && typeof part.text === "string") {
|
|
44689
|
+
return [part.text];
|
|
44690
|
+
}
|
|
44691
|
+
return [];
|
|
44692
|
+
}).join("");
|
|
44693
|
+
}
|
|
44694
|
+
function lastAssistantText(source) {
|
|
44695
|
+
const messages = Array.isArray(source) ? source : source && typeof source === "object" && Array.isArray(source.messages) ? source.messages : snapshotMessages(source);
|
|
44696
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
44697
|
+
const message = messages[index];
|
|
44698
|
+
if (!message || typeof message !== "object") continue;
|
|
44699
|
+
const role = message.role ?? message.type;
|
|
44700
|
+
if (role !== "ai" && role !== "assistant") continue;
|
|
44701
|
+
const text = messageText(message.content);
|
|
44702
|
+
if (text !== void 0) return text;
|
|
44703
|
+
}
|
|
44704
|
+
return void 0;
|
|
44705
|
+
}
|
|
44706
|
+
function boundedWorkerObservation(result, state) {
|
|
44707
|
+
const text = lastAssistantText(state) ?? lastAssistantText(result) ?? "";
|
|
44708
|
+
return {
|
|
44709
|
+
status: "completed",
|
|
44710
|
+
output: truncateForJson(text, { maxStringLength: TASK_WORKER_OBSERVATION_MAX_CHARS })
|
|
44711
|
+
};
|
|
44712
|
+
}
|
|
44713
|
+
var EXECUTOR_CACHE_TTL_MS = 3e4;
|
|
44714
|
+
var executorCache = /* @__PURE__ */ new Map();
|
|
44715
|
+
function executorString(value) {
|
|
44716
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
44717
|
+
}
|
|
44718
|
+
async function renderAvailableExecutors(rc, tenantId2) {
|
|
44719
|
+
const authority = classifyTaskAuthority(rc);
|
|
44720
|
+
const governed = authority.kind === "projectRoom" || authority.kind === "projectTask";
|
|
44721
|
+
const projectId = governed ? (authority.trusted.projectTask ?? authority.trusted.projectRoom)?.projectId : void 0;
|
|
44722
|
+
const cacheKey = `${tenantId2}:${governed ? `project:${projectId ?? ""}` : "ordinary"}`;
|
|
44723
|
+
const cached = executorCache.get(cacheKey);
|
|
44724
|
+
const now = Date.now();
|
|
44725
|
+
if (cached && now - cached.at < EXECUTOR_CACHE_TTL_MS) return cached.text;
|
|
44726
|
+
const lines = [];
|
|
44727
|
+
try {
|
|
44728
|
+
if (governed && projectId) {
|
|
44729
|
+
const store = getStoreLattice("default", "projectBotMembership").store;
|
|
44730
|
+
if (typeof store.list === "function") {
|
|
44731
|
+
const bots = await store.list(tenantId2, projectId);
|
|
44732
|
+
for (const bot of (Array.isArray(bots) ? bots : []).slice(0, 40)) {
|
|
44733
|
+
const row = bot;
|
|
44734
|
+
if (row.status !== "active") continue;
|
|
44735
|
+
const id = executorString(row.assistantId);
|
|
44736
|
+
if (!id) continue;
|
|
44737
|
+
const title = executorString(row.title);
|
|
44738
|
+
const responsibility = executorString(row.responsibility);
|
|
44739
|
+
lines.push(`- ${id}${title ? ` \u2014 ${title}` : ""}${responsibility ? ` (${responsibility})` : ""}`);
|
|
44740
|
+
}
|
|
44741
|
+
}
|
|
44742
|
+
} else {
|
|
44743
|
+
const configs = await agentLatticeManager.getAllAgentConfigsByTenant(tenantId2);
|
|
44744
|
+
for (const config of configs.slice(0, 40)) {
|
|
44745
|
+
const row = config;
|
|
44746
|
+
const id = executorString(row.key);
|
|
44747
|
+
if (!id) continue;
|
|
44748
|
+
const name = executorString(row.name);
|
|
44749
|
+
const description = executorString(row.description);
|
|
44750
|
+
lines.push(`- ${id}${name ? ` \u2014 ${name}` : ""}${description ? ` (${description.slice(0, 120)})` : ""}`);
|
|
44751
|
+
}
|
|
44752
|
+
}
|
|
44753
|
+
} catch {
|
|
44754
|
+
}
|
|
44755
|
+
if (lines.length === 0) {
|
|
44756
|
+
executorCache.set(cacheKey, { at: now, text: "" });
|
|
44757
|
+
return "";
|
|
44758
|
+
}
|
|
44759
|
+
const header = governed ? "## Available task executors (Project roster)" : "## Available task executors";
|
|
44760
|
+
const text = `
|
|
44761
|
+
|
|
44762
|
+
${header}
|
|
44763
|
+
|
|
44764
|
+
Dispatch \`task\` only to an executor that has the tools the work needs (for example \`update_agent\`/\`create_agent\` for materialization). Never dispatch to the subject agent you are building. Use \`general-purpose\` to run your own capabilities.
|
|
44765
|
+
|
|
44766
|
+
${lines.join("\n")}
|
|
44767
|
+
`;
|
|
44768
|
+
executorCache.set(cacheKey, { at: now, text });
|
|
44769
|
+
return text;
|
|
44770
|
+
}
|
|
44235
44771
|
function delegatedTaskScopeError(taskId) {
|
|
44236
44772
|
return JSON.stringify({
|
|
44237
44773
|
success: false,
|
|
@@ -44250,7 +44786,7 @@ function classifyTaskAuthority(runConfig) {
|
|
|
44250
44786
|
return delegatedTaskId ? { kind: "delegated", taskId: delegatedTaskId } : { kind: "ordinary" };
|
|
44251
44787
|
}
|
|
44252
44788
|
try {
|
|
44253
|
-
const trusted = (0,
|
|
44789
|
+
const trusted = (0, import_protocols34.parseTrustedRunContext)(hasProjectTask ? { projectTask: runConfig.projectTask } : { projectRoom: runConfig.projectRoom });
|
|
44254
44790
|
return { kind: hasProjectTask ? "projectTask" : "projectRoom", trusted };
|
|
44255
44791
|
} catch {
|
|
44256
44792
|
return { kind: "invalid" };
|
|
@@ -44583,7 +45119,7 @@ function getTaskWorkItemStore() {
|
|
|
44583
45119
|
return getStoreLattice("default", "taskWorkItem").store;
|
|
44584
45120
|
}
|
|
44585
45121
|
function getProjectTaskWorkItemStore() {
|
|
44586
|
-
return (0,
|
|
45122
|
+
return (0, import_protocols34.requireProjectTaskWorkItemStore)(getTaskWorkItemStore());
|
|
44587
45123
|
}
|
|
44588
45124
|
function reviewInterruption(task) {
|
|
44589
45125
|
const value = task.context?.interruption;
|
|
@@ -44601,11 +45137,11 @@ function buildReviewMarkdown(task) {
|
|
|
44601
45137
|
}
|
|
44602
45138
|
var manageTaskSchema = import_zod71.z.object({
|
|
44603
45139
|
action: import_zod71.z.enum(["create", "get", "list", "update", "set_status", "add_activity", "delete"]).describe("Action to perform. Available: create, get, list, update, set_status, add_activity, delete. To change status, use set_status. To change content fields, use update."),
|
|
44604
|
-
id: import_zod71.z.string().optional().describe("Task ID (required for get, update, add_activity
|
|
45140
|
+
id: import_zod71.z.string().optional().describe("Task ID (required for get, update, add_activity; required for delete unless ids is given)"),
|
|
44605
45141
|
title: import_zod71.z.string().optional().describe("Task title (required for create)"),
|
|
44606
45142
|
description: import_zod71.z.string().optional().describe("Task description in Markdown"),
|
|
44607
45143
|
priority: import_zod71.z.enum(["low", "medium", "high"]).optional().describe("Priority level"),
|
|
44608
|
-
status: import_zod71.z.enum(["pending", "in_progress", "review", "failed", "interrupted", "completed", "cancelled"]).optional().describe("Task status. For status-only changes, prefer set_status action. Agent summary-only interrupted updates default to missing_input"),
|
|
45144
|
+
status: import_zod71.z.enum(["pending", "in_progress", "review", "failed", "interrupted", "completed", "cancelled"]).optional().describe("Task status. For status-only changes, prefer set_status action. Set 'in_progress' when you start processing a task you hold; 'completed'/'failed' require the task to be 'in_progress'. Agent summary-only interrupted updates default to missing_input"),
|
|
44609
45145
|
dueDate: import_zod71.z.string().optional().describe("Due date (ISO 8601 format)"),
|
|
44610
45146
|
metadata: import_zod71.z.record(import_zod71.z.unknown()).optional().describe("Structured metadata (e.g. projectId, module)"),
|
|
44611
45147
|
metadataFilter: import_zod71.z.record(
|
|
@@ -44634,11 +45170,12 @@ var manageTaskSchema = import_zod71.z.object({
|
|
|
44634
45170
|
})).optional().describe("Structured belief reports required when an agent-owned task completes; existing keys update the belief owner's table, and a brand-new key must be declared with isNew: true"),
|
|
44635
45171
|
content: import_zod71.z.string().optional().describe("Markdown content required for add_activity"),
|
|
44636
45172
|
summary: import_zod71.z.string().optional().describe("Brief summary of the operation"),
|
|
44637
|
-
executionResultId: import_zod71.z.string().refine(
|
|
45173
|
+
executionResultId: import_zod71.z.string().refine(import_protocols34.isExecutionResultEventKey, {
|
|
44638
45174
|
message: "executionResultId must be the execution-result:<threadId> event key returned by task()"
|
|
44639
45175
|
}).optional().describe(
|
|
44640
45176
|
"Canonical ASCII `execution-result:<suffix>` event key returned by task(); the nonempty suffix allows only A-Z, a-z, 0-9, period, underscore, colon, and hyphen, and is not a database row ID"
|
|
44641
|
-
)
|
|
45177
|
+
),
|
|
45178
|
+
ids: import_zod71.z.array(import_zod71.z.string().trim().min(1)).optional().describe("Task IDs to delete in one batch (delete action only). Use with or instead of id.")
|
|
44642
45179
|
}).superRefine((input, context) => {
|
|
44643
45180
|
if (input.executionResultId && input.action !== "update" && input.action !== "set_status" && input.action !== "add_activity") {
|
|
44644
45181
|
context.addIssue({
|
|
@@ -44654,10 +45191,19 @@ var manageTaskSchema = import_zod71.z.object({
|
|
|
44654
45191
|
message: "metadataFilter is valid only for list"
|
|
44655
45192
|
});
|
|
44656
45193
|
}
|
|
45194
|
+
if (input.ids && input.action !== "delete") {
|
|
45195
|
+
context.addIssue({
|
|
45196
|
+
code: import_zod71.z.ZodIssueCode.custom,
|
|
45197
|
+
path: ["ids"],
|
|
45198
|
+
message: "ids is valid only for delete"
|
|
45199
|
+
});
|
|
45200
|
+
}
|
|
44657
45201
|
});
|
|
44658
45202
|
var startTaskSchema = import_zod71.z.object({
|
|
44659
45203
|
taskId: import_zod71.z.string().trim().min(1).describe("ID of the persisted TaskItem to start"),
|
|
44660
|
-
agentId: import_zod71.z.string().trim().min(1).describe(
|
|
45204
|
+
agentId: import_zod71.z.string().trim().min(1).describe(
|
|
45205
|
+
`ID of the Agent that should execute the task. Use "general-purpose" to run the caller's own capabilities as an isolated worker.`
|
|
45206
|
+
)
|
|
44661
45207
|
});
|
|
44662
45208
|
function mergeTaskUpdateWarnings(existing, added) {
|
|
44663
45209
|
const warnings = [...existing ?? [], ...added ?? []];
|
|
@@ -44689,7 +45235,7 @@ async function getPendingExecutionResultIds(store, tenantId2, taskId) {
|
|
|
44689
45235
|
order: "desc",
|
|
44690
45236
|
limit: PENDING_EXECUTION_RESULT_LIMIT + 1
|
|
44691
45237
|
});
|
|
44692
|
-
const canonicalCandidates = candidates.slice(0, PENDING_EXECUTION_RESULT_LIMIT + 1).filter((item) => (0,
|
|
45238
|
+
const canonicalCandidates = candidates.slice(0, PENDING_EXECUTION_RESULT_LIMIT + 1).filter((item) => (0, import_protocols34.isExecutionResultEventKey)(item.eventKey));
|
|
44693
45239
|
const reconciliationRows = new Array(canonicalCandidates.length);
|
|
44694
45240
|
let nextCandidateIndex = 0;
|
|
44695
45241
|
let firstError;
|
|
@@ -44794,6 +45340,49 @@ function createTaskMiddleware(options = {}) {
|
|
|
44794
45340
|
}
|
|
44795
45341
|
const ownerId = input.ownerId || trustedScope?.assistantId || (input.ownerType === "agent" ? rc.assistant_id : null) || rc.user_id;
|
|
44796
45342
|
const store = getTaskStore();
|
|
45343
|
+
const deleteOneTask = async (id) => {
|
|
45344
|
+
if (delegatedTaskId && id !== delegatedTaskId) {
|
|
45345
|
+
return delegatedTaskScopeError(delegatedTaskId);
|
|
45346
|
+
}
|
|
45347
|
+
const existing = await store.getById(tenantId2, id);
|
|
45348
|
+
if (!existing) {
|
|
45349
|
+
return JSON.stringify({
|
|
45350
|
+
success: false,
|
|
45351
|
+
code: "TASK_NOT_FOUND",
|
|
45352
|
+
error: `Task '${id}' was not found.`,
|
|
45353
|
+
hint: "Use manage_task list to see available tasks and their correct IDs."
|
|
45354
|
+
});
|
|
45355
|
+
}
|
|
45356
|
+
if (!taskMatchesRuntimeScope3(existing, workspaceId, projectId)) {
|
|
45357
|
+
return taskScopeAccessError(id);
|
|
45358
|
+
}
|
|
45359
|
+
if (trustedProject?.projectTask) {
|
|
45360
|
+
const trustedFailure = trustedTaskContextFailure(existing, trustedProject.projectTask);
|
|
45361
|
+
if (trustedFailure) return trustedFailure;
|
|
45362
|
+
}
|
|
45363
|
+
let deleted;
|
|
45364
|
+
if (trustedProject) {
|
|
45365
|
+
const snapshot = taskMutationSnapshot(existing);
|
|
45366
|
+
if (!snapshot) return trustedContextError();
|
|
45367
|
+
try {
|
|
45368
|
+
await createProjectTaskOwnerPolicy().requireCaller(trustedRosterScope(trustedProject));
|
|
45369
|
+
} catch (error) {
|
|
45370
|
+
return projectPolicyError(error);
|
|
45371
|
+
}
|
|
45372
|
+
deleted = await store.deleteIfSnapshot(tenantId2, id, snapshot);
|
|
45373
|
+
} else {
|
|
45374
|
+
deleted = await store.delete(tenantId2, id);
|
|
45375
|
+
}
|
|
45376
|
+
if (!deleted) {
|
|
45377
|
+
return JSON.stringify({
|
|
45378
|
+
success: false,
|
|
45379
|
+
code: "TASK_DELETE_FAILED",
|
|
45380
|
+
error: `Task '${id}' was not found or could not be deleted.`,
|
|
45381
|
+
hint: "Use manage_task list to verify the task exists and you have access to it."
|
|
45382
|
+
});
|
|
45383
|
+
}
|
|
45384
|
+
return JSON.stringify({ success: true, message: `Task '${id}' deleted` });
|
|
45385
|
+
};
|
|
44797
45386
|
switch (input.action) {
|
|
44798
45387
|
case "create": {
|
|
44799
45388
|
if (delegatedTaskId && input.parentId !== delegatedTaskId) {
|
|
@@ -44949,9 +45538,6 @@ function createTaskMiddleware(options = {}) {
|
|
|
44949
45538
|
hint: "Pass the task ID you want to retrieve"
|
|
44950
45539
|
});
|
|
44951
45540
|
}
|
|
44952
|
-
if (delegatedTaskId && input.id !== delegatedTaskId) {
|
|
44953
|
-
return delegatedTaskScopeError(delegatedTaskId);
|
|
44954
|
-
}
|
|
44955
45541
|
const task = await store.getById(tenantId2, input.id);
|
|
44956
45542
|
if (!task) {
|
|
44957
45543
|
return JSON.stringify({
|
|
@@ -44997,25 +45583,6 @@ function createTaskMiddleware(options = {}) {
|
|
|
44997
45583
|
});
|
|
44998
45584
|
}
|
|
44999
45585
|
case "list": {
|
|
45000
|
-
if (delegatedTaskId) {
|
|
45001
|
-
const delegatedTask = await store.getById(tenantId2, delegatedTaskId);
|
|
45002
|
-
if (!delegatedTask || !taskMatchesRuntimeScope3(delegatedTask, workspaceId, projectId)) {
|
|
45003
|
-
return serializeTaskReadResponse({ success: true, data: [], count: 0 });
|
|
45004
|
-
}
|
|
45005
|
-
const children = await store.list({
|
|
45006
|
-
tenantId: tenantId2,
|
|
45007
|
-
workspaceId,
|
|
45008
|
-
projectId,
|
|
45009
|
-
parentId: delegatedTaskId,
|
|
45010
|
-
metadata: input.metadataFilter
|
|
45011
|
-
});
|
|
45012
|
-
const scopedChildren = children.filter((child) => child.id !== delegatedTaskId && child.parentId === delegatedTaskId && exactScopeMatch(child, delegatedTask));
|
|
45013
|
-
return serializeTaskReadResponse({
|
|
45014
|
-
success: true,
|
|
45015
|
-
data: [delegatedTask, ...scopedChildren],
|
|
45016
|
-
count: scopedChildren.length + 1
|
|
45017
|
-
});
|
|
45018
|
-
}
|
|
45019
45586
|
const filter2 = {
|
|
45020
45587
|
tenantId: tenantId2,
|
|
45021
45588
|
ownerType: input.ownerType,
|
|
@@ -45310,8 +45877,8 @@ function createTaskMiddleware(options = {}) {
|
|
|
45310
45877
|
let reconciliationMetadata = {};
|
|
45311
45878
|
let descriptionMutated = false;
|
|
45312
45879
|
if (isAgentTask && input.description !== void 0 && !valuesEqual(input.description, existing.description)) {
|
|
45313
|
-
const oldBelief = (0,
|
|
45314
|
-
const newBelief = (0,
|
|
45880
|
+
const oldBelief = (0, import_protocols34.parseTaskBeliefState)(existing.description ?? "");
|
|
45881
|
+
const newBelief = (0, import_protocols34.parseTaskBeliefState)(input.description);
|
|
45315
45882
|
const hasBeliefState = oldBelief.success || newBelief.success;
|
|
45316
45883
|
if (hasBeliefState) {
|
|
45317
45884
|
await validateExecutionResult();
|
|
@@ -45610,41 +46177,31 @@ function createTaskMiddleware(options = {}) {
|
|
|
45610
46177
|
});
|
|
45611
46178
|
return lifecycleMutationResponse(interrupted);
|
|
45612
46179
|
}
|
|
45613
|
-
if (lifecycle && input.status === "in_progress"
|
|
45614
|
-
await validateExecutionResult();
|
|
45615
|
-
const callerError = await revalidateCaller();
|
|
45616
|
-
if (callerError) return callerError;
|
|
45617
|
-
const resumed = await lifecycle.resumeInterruption({
|
|
45618
|
-
tenantId: tenantId2,
|
|
45619
|
-
taskId: input.id,
|
|
45620
|
-
actor,
|
|
45621
|
-
threadId: statusThreadId
|
|
45622
|
-
});
|
|
45623
|
-
return lifecycleMutationResponse(resumed);
|
|
45624
|
-
}
|
|
45625
|
-
if (lifecycle && input.status === "in_progress" && existing.status === "pending") {
|
|
45626
|
-
await validateExecutionResult();
|
|
46180
|
+
if (lifecycle && input.status === "in_progress") {
|
|
45627
46181
|
const callerError = await revalidateCaller();
|
|
45628
46182
|
if (callerError) return callerError;
|
|
45629
|
-
|
|
45630
|
-
|
|
45631
|
-
|
|
45632
|
-
|
|
45633
|
-
|
|
45634
|
-
|
|
45635
|
-
|
|
45636
|
-
|
|
45637
|
-
|
|
45638
|
-
|
|
45639
|
-
|
|
45640
|
-
|
|
45641
|
-
|
|
46183
|
+
if (existing.status === "interrupted") {
|
|
46184
|
+
return lifecycleMutationResponse(await lifecycle.resumeInterruption({
|
|
46185
|
+
tenantId: tenantId2,
|
|
46186
|
+
taskId: input.id,
|
|
46187
|
+
actor,
|
|
46188
|
+
threadId: statusThreadId
|
|
46189
|
+
}));
|
|
46190
|
+
}
|
|
46191
|
+
if (existing.status === "failed") {
|
|
46192
|
+
return lifecycleMutationResponse(await lifecycle.retryTask({
|
|
46193
|
+
tenantId: tenantId2,
|
|
46194
|
+
taskId: input.id,
|
|
46195
|
+
actor,
|
|
46196
|
+
threadId: statusThreadId
|
|
46197
|
+
}));
|
|
46198
|
+
}
|
|
46199
|
+
return lifecycleMutationResponse(await lifecycle.startTask({
|
|
45642
46200
|
tenantId: tenantId2,
|
|
45643
46201
|
taskId: input.id,
|
|
45644
46202
|
actor,
|
|
45645
46203
|
threadId: statusThreadId
|
|
45646
|
-
});
|
|
45647
|
-
return lifecycleMutationResponse(retried);
|
|
46204
|
+
}));
|
|
45648
46205
|
}
|
|
45649
46206
|
const effectiveRequireReview = existing.requireReview === true || input.requireReview === true;
|
|
45650
46207
|
const candidateReviewInterruption = input.status === "interrupted" && input.context?.interruption && typeof input.context.interruption === "object" && input.context.interruption.type === "review_required" && !!input.result?.trim();
|
|
@@ -45711,9 +46268,9 @@ function createTaskMiddleware(options = {}) {
|
|
|
45711
46268
|
}
|
|
45712
46269
|
let response;
|
|
45713
46270
|
try {
|
|
45714
|
-
response = await (0,
|
|
46271
|
+
response = await (0, import_langgraph16.interrupt)(buildReviewMarkdown(submitted.task));
|
|
45715
46272
|
} catch (error) {
|
|
45716
|
-
if (error instanceof
|
|
46273
|
+
if (error instanceof import_langgraph16.GraphInterrupt) throw error;
|
|
45717
46274
|
return lifecycleMutationResponse(submitted, { code: "REVIEW_REQUIRED" });
|
|
45718
46275
|
}
|
|
45719
46276
|
if (response?.action === "approve") {
|
|
@@ -45825,54 +46382,49 @@ function createTaskMiddleware(options = {}) {
|
|
|
45825
46382
|
return successfulTaskResponse(input.id, updatedStatus, true);
|
|
45826
46383
|
}
|
|
45827
46384
|
case "delete": {
|
|
45828
|
-
|
|
45829
|
-
|
|
45830
|
-
|
|
45831
|
-
|
|
45832
|
-
|
|
45833
|
-
|
|
45834
|
-
|
|
45835
|
-
|
|
45836
|
-
|
|
45837
|
-
|
|
45838
|
-
|
|
45839
|
-
if (!existing) {
|
|
45840
|
-
return JSON.stringify({
|
|
45841
|
-
success: false,
|
|
45842
|
-
code: "TASK_NOT_FOUND",
|
|
45843
|
-
error: `Task '${input.id}' was not found.`,
|
|
45844
|
-
hint: "Use manage_task list to see available tasks and their correct IDs."
|
|
45845
|
-
});
|
|
45846
|
-
}
|
|
45847
|
-
if (!taskMatchesRuntimeScope3(existing, workspaceId, projectId)) {
|
|
45848
|
-
return taskScopeAccessError(input.id);
|
|
45849
|
-
}
|
|
45850
|
-
if (trustedProject?.projectTask) {
|
|
45851
|
-
const trustedFailure = trustedTaskContextFailure(existing, trustedProject.projectTask);
|
|
45852
|
-
if (trustedFailure) return trustedFailure;
|
|
46385
|
+
const missingTargetError = JSON.stringify({
|
|
46386
|
+
success: false,
|
|
46387
|
+
error: "id or ids is required for delete action",
|
|
46388
|
+
hint: "Pass the task ID(s) you want to delete"
|
|
46389
|
+
});
|
|
46390
|
+
const requestedIds = input.ids && input.ids.length > 0 ? [.../* @__PURE__ */ new Set([...input.id ? [input.id] : [], ...input.ids])] : void 0;
|
|
46391
|
+
if (requestedIds === void 0) {
|
|
46392
|
+
if (!input.id) {
|
|
46393
|
+
return missingTargetError;
|
|
46394
|
+
}
|
|
46395
|
+
return deleteOneTask(input.id);
|
|
45853
46396
|
}
|
|
45854
|
-
|
|
45855
|
-
|
|
45856
|
-
|
|
45857
|
-
|
|
46397
|
+
const deletedIds = [];
|
|
46398
|
+
const failed = [];
|
|
46399
|
+
for (const id of requestedIds) {
|
|
46400
|
+
let raw;
|
|
45858
46401
|
try {
|
|
45859
|
-
await
|
|
46402
|
+
raw = await deleteOneTask(id);
|
|
45860
46403
|
} catch (error) {
|
|
45861
|
-
|
|
46404
|
+
failed.push({
|
|
46405
|
+
id,
|
|
46406
|
+
code: "TASK_DELETE_FAILED",
|
|
46407
|
+
error: error instanceof Error ? error.message : String(error)
|
|
46408
|
+
});
|
|
46409
|
+
continue;
|
|
46410
|
+
}
|
|
46411
|
+
const result = JSON.parse(raw);
|
|
46412
|
+
if (result.success) {
|
|
46413
|
+
deletedIds.push(id);
|
|
46414
|
+
} else {
|
|
46415
|
+
failed.push({
|
|
46416
|
+
id,
|
|
46417
|
+
...result.code ? { code: result.code } : {},
|
|
46418
|
+
error: result.error ?? `Task '${id}' could not be deleted.`
|
|
46419
|
+
});
|
|
45862
46420
|
}
|
|
45863
|
-
deleted = await store.deleteIfSnapshot(tenantId2, input.id, snapshot);
|
|
45864
|
-
} else {
|
|
45865
|
-
deleted = await store.delete(tenantId2, input.id);
|
|
45866
|
-
}
|
|
45867
|
-
if (!deleted) {
|
|
45868
|
-
return JSON.stringify({
|
|
45869
|
-
success: false,
|
|
45870
|
-
code: "TASK_DELETE_FAILED",
|
|
45871
|
-
error: `Task '${input.id}' was not found or could not be deleted.`,
|
|
45872
|
-
hint: "Use manage_task list to verify the task exists and you have access to it."
|
|
45873
|
-
});
|
|
45874
46421
|
}
|
|
45875
|
-
return JSON.stringify({
|
|
46422
|
+
return JSON.stringify({
|
|
46423
|
+
success: failed.length === 0,
|
|
46424
|
+
deleted: deletedIds,
|
|
46425
|
+
failed,
|
|
46426
|
+
summary: `${deletedIds.length} of ${requestedIds.length} deleted`
|
|
46427
|
+
});
|
|
45876
46428
|
}
|
|
45877
46429
|
default:
|
|
45878
46430
|
return JSON.stringify({
|
|
@@ -45987,23 +46539,29 @@ function createTaskMiddleware(options = {}) {
|
|
|
45987
46539
|
error: "Runtime actor identity is required for persistent task execution"
|
|
45988
46540
|
});
|
|
45989
46541
|
}
|
|
46542
|
+
const callerAssistantId = rc.assistant_id;
|
|
46543
|
+
const agentId = input.agentId === "general-purpose" && callerAssistantId ? `${callerAssistantId}-general-purpose` : input.agentId;
|
|
45990
46544
|
const service2 = createTaskExecutionService({
|
|
45991
46545
|
taskStore: getTaskStore(),
|
|
45992
46546
|
workItemStore: getTaskWorkItemStore(),
|
|
45993
|
-
resolveAgent: async (targetTenantId,
|
|
45994
|
-
resolveTaskCapability: async (targetTenantId, agentId) => agentHasManagedTaskCapability(
|
|
45995
|
-
(await agentLatticeManager.getOrLoadWithTenant(targetTenantId, agentId))?.config
|
|
45996
|
-
),
|
|
46547
|
+
resolveAgent: async (targetTenantId, agentId2) => !!await agentLatticeManager.getOrLoadWithTenant(targetTenantId, agentId2),
|
|
45997
46548
|
invokeAgent: async (invocation) => {
|
|
45998
|
-
const
|
|
45999
|
-
tenant_id: invocation.tenantId,
|
|
46549
|
+
const workerResult = await agentWorkerGraph.invoke({
|
|
46000
46550
|
assistant_id: invocation.agentId,
|
|
46001
46551
|
thread_id: invocation.threadId,
|
|
46002
|
-
|
|
46003
|
-
|
|
46004
|
-
|
|
46552
|
+
input: { message: invocation.message },
|
|
46553
|
+
runConfig: {
|
|
46554
|
+
...rc,
|
|
46555
|
+
assistant_id: invocation.agentId,
|
|
46556
|
+
thread_id: invocation.threadId,
|
|
46557
|
+
taskId: invocation.taskId,
|
|
46558
|
+
tenantId: invocation.tenantId,
|
|
46559
|
+
workspaceId: invocation.workspaceId,
|
|
46560
|
+
projectId: invocation.projectId
|
|
46561
|
+
}
|
|
46005
46562
|
});
|
|
46006
|
-
|
|
46563
|
+
const finalState = workerResult?.finalState;
|
|
46564
|
+
return boundedWorkerObservation(finalState, void 0);
|
|
46007
46565
|
}
|
|
46008
46566
|
});
|
|
46009
46567
|
const trustedCaller = authority.kind === "projectTask" || authority.kind === "projectRoom" ? authority.trusted.projectTask ?? authority.trusted.projectRoom : void 0;
|
|
@@ -46012,7 +46570,7 @@ function createTaskMiddleware(options = {}) {
|
|
|
46012
46570
|
workspaceId: rc.workspaceId,
|
|
46013
46571
|
projectId: rc.projectId,
|
|
46014
46572
|
taskId: input.taskId,
|
|
46015
|
-
agentId
|
|
46573
|
+
agentId,
|
|
46016
46574
|
actor,
|
|
46017
46575
|
callerThreadId: rc.thread_id,
|
|
46018
46576
|
...trustedCaller ? { callerMembershipId: trustedCaller.membershipId, callerAssistantId: trustedCaller.assistantId } : {}
|
|
@@ -46021,6 +46579,66 @@ function createTaskMiddleware(options = {}) {
|
|
|
46021
46579
|
return (0, import_langchain87.createMiddleware)({
|
|
46022
46580
|
name: "TaskMiddleware",
|
|
46023
46581
|
contextSchema,
|
|
46582
|
+
// Persisted between invocations (ADRs: the run↔task binding survives turns).
|
|
46583
|
+
stateSchema: import_zod71.z.object({
|
|
46584
|
+
taskId: import_zod71.z.string().default("")
|
|
46585
|
+
}),
|
|
46586
|
+
// CLAIM: a run that holds a task moves it to in_progress (idempotent).
|
|
46587
|
+
beforeAgent: async (state, runtime) => {
|
|
46588
|
+
const rc = readRuntimeRunConfig(runtime);
|
|
46589
|
+
const bound = typeof state?.taskId === "string" ? state.taskId : "";
|
|
46590
|
+
const taskId = bound || readExecutionTaskId(rc) || "";
|
|
46591
|
+
if (!taskId) return {};
|
|
46592
|
+
if (!taskId) return {};
|
|
46593
|
+
const tenantId2 = rc.tenantId || "default";
|
|
46594
|
+
const threadId = runtime?.configurable?.thread_id;
|
|
46595
|
+
const task = await getTaskStore().getById(tenantId2, taskId);
|
|
46596
|
+
if (!task) return {};
|
|
46597
|
+
const runWorkspaceId = typeof rc.workspaceId === "string" ? rc.workspaceId : void 0;
|
|
46598
|
+
const runProjectId = typeof rc.projectId === "string" ? rc.projectId : void 0;
|
|
46599
|
+
if (task.workspaceId && task.workspaceId !== runWorkspaceId) return {};
|
|
46600
|
+
if (task.projectId && task.projectId !== runProjectId) return {};
|
|
46601
|
+
if (task.status === "completed" || task.status === "failed" || task.status === "cancelled") {
|
|
46602
|
+
return bound ? {} : { taskId };
|
|
46603
|
+
}
|
|
46604
|
+
taskRunRegistry.register(taskId);
|
|
46605
|
+
if (task.status === "pending") {
|
|
46606
|
+
await createBoundTaskBridge().beginRun({
|
|
46607
|
+
tenantId: tenantId2,
|
|
46608
|
+
task,
|
|
46609
|
+
actor: getRuntimeActor2(rc) ?? "system",
|
|
46610
|
+
...threadId ? { threadId } : {}
|
|
46611
|
+
});
|
|
46612
|
+
} else if (task.status === "interrupted" && isResumableInterruption(task.context?.interruption)) {
|
|
46613
|
+
await createBoundTaskLifecycle().resumeInterruption({
|
|
46614
|
+
tenantId: tenantId2,
|
|
46615
|
+
taskId: task.id,
|
|
46616
|
+
actor: getRuntimeActor2(rc) ?? "system",
|
|
46617
|
+
...threadId ? { threadId } : {}
|
|
46618
|
+
});
|
|
46619
|
+
}
|
|
46620
|
+
return bound ? {} : { taskId };
|
|
46621
|
+
},
|
|
46622
|
+
// SETTLE: a run that ends without a lifecycle transition converges the task.
|
|
46623
|
+
afterAgent: async (state, runtime) => {
|
|
46624
|
+
const taskId = typeof state?.taskId === "string" ? state.taskId : "";
|
|
46625
|
+
if (!taskId) return {};
|
|
46626
|
+
const rc = readRuntimeRunConfig(runtime);
|
|
46627
|
+
const tenantId2 = rc.tenantId || "default";
|
|
46628
|
+
const threadId = runtime?.configurable?.thread_id;
|
|
46629
|
+
const task = await getTaskStore().getById(tenantId2, taskId);
|
|
46630
|
+
if (task?.status === "in_progress" && task.context?.thread_id === threadId) {
|
|
46631
|
+
await createBoundTaskBridge().settleRun({
|
|
46632
|
+
tenantId: tenantId2,
|
|
46633
|
+
task,
|
|
46634
|
+
actor: getRuntimeActor2(rc) ?? "system",
|
|
46635
|
+
...threadId ? { threadId } : {},
|
|
46636
|
+
outcome: { kind: "interrupted", summary: "Run ended without a task lifecycle transition" }
|
|
46637
|
+
});
|
|
46638
|
+
}
|
|
46639
|
+
taskRunRegistry.unregister(taskId);
|
|
46640
|
+
return {};
|
|
46641
|
+
},
|
|
46024
46642
|
wrapModelCall: async (request, handler) => {
|
|
46025
46643
|
const taskPrompt = `## Task Management
|
|
46026
46644
|
|
|
@@ -46029,8 +46647,11 @@ ongoing record of a GOAL and its ACCEPTANCE CRITERIA.
|
|
|
46029
46647
|
|
|
46030
46648
|
### When to create a task
|
|
46031
46649
|
- Agent-owned work is multi-step and needs a persistent contract and plan ->
|
|
46032
|
-
create the parent task FIRST (a \`pending\` record), then
|
|
46033
|
-
|
|
46650
|
+
create the parent task FIRST (a \`pending\` record), then process it in this run;
|
|
46651
|
+
mark it \`in_progress\` with \`manage_task set_status\` when you start, and
|
|
46652
|
+
\`completed\` when the acceptance criteria are met. To bring in an
|
|
46653
|
+
expert, create a subtask and dispatch it with \`task { taskId, agentId }\` \u2014 never
|
|
46654
|
+
re-dispatch the task you are processing.
|
|
46034
46655
|
- Persistence is useful for resumption, review, or visibility across the
|
|
46035
46656
|
independently verifiable business results.
|
|
46036
46657
|
|
|
@@ -46060,9 +46681,13 @@ ${TASK_CONVERGENCE_GUIDANCE}
|
|
|
46060
46681
|
- No params: ownerType defaults to "user" with current user's ID
|
|
46061
46682
|
- ownerType="agent": auto-fills ownerId from current agent (subtask for yourself)
|
|
46062
46683
|
- Explicit ownerId: assign to a specific agent or user`;
|
|
46684
|
+
const boundTaskId = request.state?.taskId;
|
|
46685
|
+
const binding = typeof boundTaskId === "string" && boundTaskId ? renderTaskBinding(boundTaskId) : "";
|
|
46686
|
+
const rc = readRuntimeRunConfig(request.runtime);
|
|
46687
|
+
const executors = await renderAvailableExecutors(rc, rc.tenantId || "default");
|
|
46063
46688
|
return handler({
|
|
46064
46689
|
...request,
|
|
46065
|
-
systemPrompt: taskPrompt + "\n\n" + (request.systemPrompt ?? "")
|
|
46690
|
+
systemPrompt: taskPrompt + binding + executors + "\n\n" + (request.systemPrompt ?? "")
|
|
46066
46691
|
});
|
|
46067
46692
|
},
|
|
46068
46693
|
tools: [
|
|
@@ -46087,15 +46712,14 @@ ${TASK_CONVERGENCE_GUIDANCE}
|
|
|
46087
46712
|
- update: Update a task's content fields (title/description/priority/dueDate/metadata/parentId/sourceId/context/ownerId/result/failureReason/requireReview/dependencies/files)
|
|
46088
46713
|
Status changes can also be done here, but use set_status for a simpler dedicated status update.
|
|
46089
46714
|
- set_status: Change a task's status (id and status required). Use this when you only need to change the status.
|
|
46090
|
-
|
|
46091
|
-
|
|
46092
|
-
To mark complete: set_status with status='completed', result='...'
|
|
46715
|
+
Start processing a task you hold: set_status with status='in_progress' (the engine binds it to this run's thread).
|
|
46716
|
+
To mark complete: set_status with status='completed', result='...' (the task must be in_progress)
|
|
46093
46717
|
To mark failed: set_status with status='failed', failureReason='...'
|
|
46094
46718
|
To pause for input: set_status with status='interrupted', summary='what is needed'
|
|
46095
|
-
|
|
46719
|
+
Valid status values: pending, in_progress, review, failed, interrupted, completed, cancelled.
|
|
46096
46720
|
set_status only changes the record; it never dispatches execution (only the \`task\` tool does).
|
|
46097
46721
|
- add_activity: Add a Markdown activity without changing task fields or status (id and content required)
|
|
46098
|
-
- delete: Delete
|
|
46722
|
+
- delete: Delete one task by id, or a batch with ids (best-effort per id; returns deleted/failed lists). At least one of id/ids is required.
|
|
46099
46723
|
|
|
46100
46724
|
## Agent completion beliefs
|
|
46101
46725
|
Completing an agent-owned task MAY include a beliefImpact array reporting which
|
|
@@ -46106,14 +46730,16 @@ Report existing keys directly; set 'isNew: true' to add a key the owner does not
|
|
|
46106
46730
|
track yet. Belief is evidence metadata: it never blocks a completion, and an
|
|
46107
46731
|
unmatched or malformed entry is recorded without changing the owner's table.
|
|
46108
46732
|
Create always persists a pending record \u2014 a supplied status is coerced and no
|
|
46109
|
-
execution is dispatched.
|
|
46110
|
-
|
|
46733
|
+
execution is dispatched. When you start processing a task you hold, set it
|
|
46734
|
+
\`in_progress\` with \`manage_task set_status\`; a dispatched task is claimed
|
|
46735
|
+
automatically by the engine. Use \`task { taskId, agentId }\` to delegate a subtask
|
|
46736
|
+
to an expert \u2014 never re-dispatch the task you are processing.`,
|
|
46111
46737
|
schema: manageTaskSchema
|
|
46112
46738
|
}
|
|
46113
46739
|
),
|
|
46114
46740
|
(0, import_langchain87.tool)(handleStartTask, {
|
|
46115
46741
|
name: "task",
|
|
46116
|
-
description:
|
|
46742
|
+
description: `Start a persisted TaskItem with any existing Agent in a fresh isolated thread. Use this to delegate work \u2014 dispatch a subtask you created to the agent that should execute it; never re-dispatch the task you are currently processing (give the expert a child task instead). Pass agentId "general-purpose" for the general-purpose worker \u2014 ${DEFAULT_GENERAL_PURPOSE_DESCRIPTION} It has access to all the caller's tools, model, and middleware, so use it for general-purpose subtasks, to isolate context and token usage, and whenever no specialized agent fits. The target does NOT need task-management tools: it runs and returns an observation plus an executionResultId, and the caller passes that executionResultId to the manage_task update or add_activity that interprets and records it. A project task instead returns a managed result (success:true, managed:true) because the project-lifecycle queue owns execution.`,
|
|
46117
46743
|
schema: startTaskSchema
|
|
46118
46744
|
})
|
|
46119
46745
|
]
|
|
@@ -46255,7 +46881,7 @@ canonical Belief State:
|
|
|
46255
46881
|
};
|
|
46256
46882
|
|
|
46257
46883
|
// src/middlewares/documentLearningMiddleware.ts
|
|
46258
|
-
var
|
|
46884
|
+
var import_protocols35 = require("@axiom-lattice/protocols");
|
|
46259
46885
|
var import_langchain88 = require("langchain");
|
|
46260
46886
|
|
|
46261
46887
|
// src/middlewares/documentLearningSkills.ts
|
|
@@ -46522,7 +47148,7 @@ var documentLearningPlugin = {
|
|
|
46522
47148
|
key: "document-learner",
|
|
46523
47149
|
name: "Document Learning Agent",
|
|
46524
47150
|
description: "Read documents and build structured skill systems with evaluations. Use this agent when you need to extract knowledge from documents and turn it into reusable, testable agent skills.",
|
|
46525
|
-
type:
|
|
47151
|
+
type: import_protocols35.AgentType.DEEP_AGENT,
|
|
46526
47152
|
prompt: DOCUMENT_LEARNER_SYSTEM_PROMPT,
|
|
46527
47153
|
subAgents: ["document-parser-benchmark"],
|
|
46528
47154
|
tools: [
|
|
@@ -46831,7 +47457,7 @@ function createParseDocumentTool({
|
|
|
46831
47457
|
}
|
|
46832
47458
|
|
|
46833
47459
|
// src/middlewares/documentParserMiddleware.ts
|
|
46834
|
-
var
|
|
47460
|
+
var import_protocols36 = require("@axiom-lattice/protocols");
|
|
46835
47461
|
|
|
46836
47462
|
// src/middlewares/documentBenchmarkWorkflow.ts
|
|
46837
47463
|
var DOCUMENT_PARSER_BENCHMARK_YAML = `name: document-parser-benchmark
|
|
@@ -47356,7 +47982,7 @@ var documentParserPlugin = {
|
|
|
47356
47982
|
agents: {
|
|
47357
47983
|
"document-parser-benchmark": {
|
|
47358
47984
|
key: "document-parser-benchmark",
|
|
47359
|
-
type:
|
|
47985
|
+
type: import_protocols36.AgentType.WORKFLOW,
|
|
47360
47986
|
name: "Document Parser Benchmark",
|
|
47361
47987
|
description: "Benchmark document parsing engines. Parses a document with 5 engines in parallel, scores results, and produces a ranking report. Use this when you need to evaluate which parsing engine works best for a given document.",
|
|
47362
47988
|
prompt: "Benchmark document parsing engines: parse with 5 engines, score, and rank results.",
|
|
@@ -47393,7 +48019,7 @@ var documentParserPlugin = {
|
|
|
47393
48019
|
|
|
47394
48020
|
// src/middlewares/projectRoomMiddleware.ts
|
|
47395
48021
|
var import_crypto10 = require("crypto");
|
|
47396
|
-
var
|
|
48022
|
+
var import_protocols37 = require("@axiom-lattice/protocols");
|
|
47397
48023
|
var import_langchain91 = require("langchain");
|
|
47398
48024
|
var import_zod73 = require("zod");
|
|
47399
48025
|
var PROJECT_ROOM_CONTEXT_REQUIRED = "PROJECT_ROOM_CONTEXT_REQUIRED";
|
|
@@ -47423,7 +48049,7 @@ function ownDataValue2(record, key5) {
|
|
|
47423
48049
|
if (typeof record !== "object" || record === null || Array.isArray(record)) return void 0;
|
|
47424
48050
|
try {
|
|
47425
48051
|
const descriptor = Object.getOwnPropertyDescriptor(record, key5);
|
|
47426
|
-
return (0,
|
|
48052
|
+
return (0, import_protocols37.descriptorDataValue)(descriptor)?.value;
|
|
47427
48053
|
} catch {
|
|
47428
48054
|
return void 0;
|
|
47429
48055
|
}
|
|
@@ -47433,14 +48059,14 @@ function readTrustedRoomScope(config) {
|
|
|
47433
48059
|
const runConfig = ownDataValue2(configurable, "runConfig");
|
|
47434
48060
|
const projectRoom = ownDataValue2(runConfig, "projectRoom");
|
|
47435
48061
|
try {
|
|
47436
|
-
return (0,
|
|
48062
|
+
return (0, import_protocols37.parseTrustedRunContext)({ projectRoom }).projectRoom;
|
|
47437
48063
|
} catch {
|
|
47438
48064
|
return void 0;
|
|
47439
48065
|
}
|
|
47440
48066
|
}
|
|
47441
48067
|
function exactValues2(value, required, optional = []) {
|
|
47442
48068
|
try {
|
|
47443
|
-
return (0,
|
|
48069
|
+
return (0, import_protocols37.snapshotExactRecord)(value, required, optional);
|
|
47444
48070
|
} catch {
|
|
47445
48071
|
return void 0;
|
|
47446
48072
|
}
|
|
@@ -47476,7 +48102,7 @@ function snapshotMembership3(value) {
|
|
|
47476
48102
|
return { ...values, joinedAt, updatedAt };
|
|
47477
48103
|
}
|
|
47478
48104
|
function snapshotRows(value) {
|
|
47479
|
-
return (0,
|
|
48105
|
+
return (0, import_protocols37.snapshotExactArray)(value) ?? [];
|
|
47480
48106
|
}
|
|
47481
48107
|
async function hasActiveCurrentMembership(scope) {
|
|
47482
48108
|
const memberships = getStoreLattice("default", "projectBotMembership").store;
|
|
@@ -47563,7 +48189,7 @@ var projectRoomPlugin = {
|
|
|
47563
48189
|
// src/middlewares/sandboxPluginsMiddleware.ts
|
|
47564
48190
|
var import_langchain92 = require("langchain");
|
|
47565
48191
|
var import_zod74 = require("zod");
|
|
47566
|
-
var
|
|
48192
|
+
var import_protocols38 = require("@axiom-lattice/protocols");
|
|
47567
48193
|
|
|
47568
48194
|
// src/middlewares/sandboxPluginsSkills.ts
|
|
47569
48195
|
var PLUGIN_JSON_TEMPLATE = `{
|
|
@@ -48313,7 +48939,7 @@ var sandboxPluginsPlugin = {
|
|
|
48313
48939
|
key: "plugin-builder",
|
|
48314
48940
|
name: "Plugin Builder",
|
|
48315
48941
|
description: "Author and manage tenant plugins in the shared sandbox: clarify goal, inputs/outputs, credentials, and whether a UI is needed; then write the manifest and JS handlers, add an optional HTML MCP App UI, and validate/test with the manage_plugin tool.",
|
|
48316
|
-
type:
|
|
48942
|
+
type: import_protocols38.AgentType.DEEP_AGENT,
|
|
48317
48943
|
prompt: PLUGIN_BUILDER_PROMPT,
|
|
48318
48944
|
middleware: [
|
|
48319
48945
|
{
|
|
@@ -49087,6 +49713,7 @@ registerBuiltinPlugins();
|
|
|
49087
49713
|
TaskLifecycleNotifier,
|
|
49088
49714
|
TaskLifecycleService,
|
|
49089
49715
|
TaskRunBridgeStoresRequiredError,
|
|
49716
|
+
TaskRunRegistry,
|
|
49090
49717
|
TaskStatus,
|
|
49091
49718
|
TeamAgentGraphBuilder,
|
|
49092
49719
|
TenantPluginCatalog,
|
|
@@ -49098,7 +49725,6 @@ registerBuiltinPlugins();
|
|
|
49098
49725
|
VectorStoreProviderManager,
|
|
49099
49726
|
VolumeFilesystem,
|
|
49100
49727
|
abortWorkflowRun,
|
|
49101
|
-
agentHasManagedTaskCapability,
|
|
49102
49728
|
agentInstanceManager,
|
|
49103
49729
|
agentLatticeManager,
|
|
49104
49730
|
appendReconciliationWarning,
|
|
@@ -49273,6 +49899,9 @@ registerBuiltinPlugins();
|
|
|
49273
49899
|
projectTaskAdmissionNotifier,
|
|
49274
49900
|
queueLatticeManager,
|
|
49275
49901
|
readLoopBreakerConfig,
|
|
49902
|
+
reconcileAllTenantTaskRuns,
|
|
49903
|
+
reconcileStaleTaskRuns,
|
|
49904
|
+
reconcileTenantTaskRuns,
|
|
49276
49905
|
registerAgentLattice,
|
|
49277
49906
|
registerAgentLatticeWithTenant,
|
|
49278
49907
|
registerAgentLattices,
|
|
@@ -49321,6 +49950,7 @@ registerBuiltinPlugins();
|
|
|
49321
49950
|
storeLatticeManager,
|
|
49322
49951
|
sttModelLatticeManager,
|
|
49323
49952
|
taskLifecycleNotifier,
|
|
49953
|
+
taskRunRegistry,
|
|
49324
49954
|
toJsonSchema,
|
|
49325
49955
|
toSafeStateExpr,
|
|
49326
49956
|
toolLatticeManager,
|