@axiom-lattice/core 4.3.0 → 5.0.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 -69
- package/dist/index.d.ts +172 -69
- package/dist/index.js +1096 -2012
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1043 -1961
- 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,
|
|
@@ -1811,7 +1811,6 @@ __export(index_exports, {
|
|
|
1811
1811
|
createSandboxProvider: () => createSandboxProvider,
|
|
1812
1812
|
createSandboxResolver: () => createSandboxResolver,
|
|
1813
1813
|
createSchedulerMiddleware: () => createSchedulerMiddleware,
|
|
1814
|
-
createSemanticMetricsMiddleware: () => createSemanticMetricsMiddleware,
|
|
1815
1814
|
createSharePayload: () => createSharePayload,
|
|
1816
1815
|
createTaskExecutionService: () => createTaskExecutionService,
|
|
1817
1816
|
createTaskLifecycleService: () => createTaskLifecycleService,
|
|
@@ -1933,6 +1932,9 @@ __export(index_exports, {
|
|
|
1933
1932
|
projectTaskAdmissionNotifier: () => projectTaskAdmissionNotifier,
|
|
1934
1933
|
queueLatticeManager: () => queueLatticeManager,
|
|
1935
1934
|
readLoopBreakerConfig: () => readLoopBreakerConfig,
|
|
1935
|
+
reconcileAllTenantTaskRuns: () => reconcileAllTenantTaskRuns,
|
|
1936
|
+
reconcileStaleTaskRuns: () => reconcileStaleTaskRuns,
|
|
1937
|
+
reconcileTenantTaskRuns: () => reconcileTenantTaskRuns,
|
|
1936
1938
|
registerAgentLattice: () => registerAgentLattice,
|
|
1937
1939
|
registerAgentLatticeWithTenant: () => registerAgentLatticeWithTenant,
|
|
1938
1940
|
registerAgentLattices: () => registerAgentLattices,
|
|
@@ -1967,7 +1969,6 @@ __export(index_exports, {
|
|
|
1967
1969
|
sandboxLatticeManager: () => sandboxLatticeManager,
|
|
1968
1970
|
sanitizeToolCallId: () => sanitizeToolCallId,
|
|
1969
1971
|
scheduleLatticeManager: () => scheduleLatticeManager,
|
|
1970
|
-
semanticMetricsPlugin: () => semanticMetricsPlugin,
|
|
1971
1972
|
serializePluginMeta: () => serializePluginMeta,
|
|
1972
1973
|
serializeTaskMutationSuccess: () => serializeTaskMutationSuccess,
|
|
1973
1974
|
serializeTaskNormalizationFallback: () => serializeTaskNormalizationFallback,
|
|
@@ -1981,6 +1982,7 @@ __export(index_exports, {
|
|
|
1981
1982
|
storeLatticeManager: () => storeLatticeManager,
|
|
1982
1983
|
sttModelLatticeManager: () => sttModelLatticeManager,
|
|
1983
1984
|
taskLifecycleNotifier: () => taskLifecycleNotifier,
|
|
1985
|
+
taskRunRegistry: () => taskRunRegistry,
|
|
1984
1986
|
toJsonSchema: () => toJsonSchema,
|
|
1985
1987
|
toSafeStateExpr: () => toSafeStateExpr,
|
|
1986
1988
|
toolLatticeManager: () => toolLatticeManager,
|
|
@@ -2420,11 +2422,11 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
2420
2422
|
* @param key Lattice键名
|
|
2421
2423
|
* @param tool 已有的StructuredTool实例
|
|
2422
2424
|
*/
|
|
2423
|
-
registerExistingTool(key5,
|
|
2425
|
+
registerExistingTool(key5, tool68) {
|
|
2424
2426
|
const config = {
|
|
2425
|
-
name:
|
|
2426
|
-
description:
|
|
2427
|
-
schema:
|
|
2427
|
+
name: tool68.name,
|
|
2428
|
+
description: tool68.description,
|
|
2429
|
+
schema: tool68.schema,
|
|
2428
2430
|
// StructuredTool的schema已经是Zod兼容的
|
|
2429
2431
|
needUserApprove: false
|
|
2430
2432
|
// MCP工具默认不需要用户批准
|
|
@@ -2432,7 +2434,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
2432
2434
|
const toolLattice = {
|
|
2433
2435
|
key: key5,
|
|
2434
2436
|
config,
|
|
2435
|
-
client:
|
|
2437
|
+
client: tool68
|
|
2436
2438
|
};
|
|
2437
2439
|
this.register(key5, toolLattice);
|
|
2438
2440
|
}
|
|
@@ -2443,14 +2445,14 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
2443
2445
|
* @param key - tool lattice key (no tenant prefix)
|
|
2444
2446
|
* @param tool - the StructuredTool client
|
|
2445
2447
|
*/
|
|
2446
|
-
registerExistingToolWithTenant(tenantId2, key5,
|
|
2448
|
+
registerExistingToolWithTenant(tenantId2, key5, tool68) {
|
|
2447
2449
|
const config = {
|
|
2448
|
-
name:
|
|
2449
|
-
description:
|
|
2450
|
-
schema:
|
|
2450
|
+
name: tool68.name,
|
|
2451
|
+
description: tool68.description,
|
|
2452
|
+
schema: tool68.schema,
|
|
2451
2453
|
needUserApprove: false
|
|
2452
2454
|
};
|
|
2453
|
-
const toolLattice = { key: key5, config, client:
|
|
2455
|
+
const toolLattice = { key: key5, config, client: tool68 };
|
|
2454
2456
|
this.registerWithTenant(tenantId2, key5, toolLattice);
|
|
2455
2457
|
}
|
|
2456
2458
|
/**
|
|
@@ -2500,8 +2502,8 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
2500
2502
|
};
|
|
2501
2503
|
var toolLatticeManager = ToolLatticeManager.getInstance();
|
|
2502
2504
|
var registerToolLattice = (key5, config, executor) => toolLatticeManager.registerLattice(key5, config, executor);
|
|
2503
|
-
var registerExistingTool = (key5,
|
|
2504
|
-
var registerExistingToolWithTenant = (tenantId2, key5,
|
|
2505
|
+
var registerExistingTool = (key5, tool68) => toolLatticeManager.registerExistingTool(key5, tool68);
|
|
2506
|
+
var registerExistingToolWithTenant = (tenantId2, key5, tool68) => toolLatticeManager.registerExistingToolWithTenant(tenantId2, key5, tool68);
|
|
2505
2507
|
var getToolLattice = (key5) => toolLatticeManager.getToolLattice(key5);
|
|
2506
2508
|
var getToolClientWithTenant = (tenantId2, key5) => toolLatticeManager.getToolClientWithTenant(tenantId2, key5);
|
|
2507
2509
|
var getToolDefinition = (key5) => toolLatticeManager.getToolDefinition(key5);
|
|
@@ -3341,15 +3343,15 @@ ${body}` : `${frontmatter}
|
|
|
3341
3343
|
const resourcesDir = path.join(skillDir, "resources");
|
|
3342
3344
|
try {
|
|
3343
3345
|
const entries = await fs.readdir(resourcesDir, { withFileTypes: true, recursive: true });
|
|
3344
|
-
const
|
|
3346
|
+
const resources2 = [];
|
|
3345
3347
|
for (const entry of entries) {
|
|
3346
3348
|
if (!entry.isDirectory()) {
|
|
3347
3349
|
const fullPath = path.join(entry.path, entry.name);
|
|
3348
3350
|
const relativePath = path.relative(resourcesDir, fullPath);
|
|
3349
|
-
|
|
3351
|
+
resources2.push(relativePath.replace(/\\/g, "/"));
|
|
3350
3352
|
}
|
|
3351
3353
|
}
|
|
3352
|
-
return
|
|
3354
|
+
return resources2.sort();
|
|
3353
3355
|
} catch (error) {
|
|
3354
3356
|
if (error.code === "ENOENT") {
|
|
3355
3357
|
return [];
|
|
@@ -13205,7 +13207,7 @@ function readLoopBreakerConfig(env = process.env) {
|
|
|
13205
13207
|
return {
|
|
13206
13208
|
repeatWarn: parse(env.AGENT_REPEATED_TOOL_CALL_WARN, 3),
|
|
13207
13209
|
repeatStop: parse(env.AGENT_REPEATED_TOOL_CALL_STOP, 5),
|
|
13208
|
-
runLimit: parse(env.AGENT_TOOL_CALL_RUN_LIMIT,
|
|
13210
|
+
runLimit: parse(env.AGENT_TOOL_CALL_RUN_LIMIT, 300),
|
|
13209
13211
|
skillRunLimit: parse(env.AGENT_SKILL_CALL_RUN_LIMIT, 8)
|
|
13210
13212
|
};
|
|
13211
13213
|
}
|
|
@@ -13628,11 +13630,11 @@ var PluginRegistry = class {
|
|
|
13628
13630
|
if (!isRecord2(rawDefinition) || typeof rawDefinition.version !== "string" || rawDefinition.version.trim().length === 0 || typeof rawDefinition.content !== "string") {
|
|
13629
13631
|
throw new Error(`Plugin "${key5}": skill "${name}" version and content must be a string`);
|
|
13630
13632
|
}
|
|
13631
|
-
const
|
|
13632
|
-
if (
|
|
13633
|
+
const resources2 = rawDefinition.resources;
|
|
13634
|
+
if (resources2 !== void 0 && !isRecord2(resources2)) {
|
|
13633
13635
|
throw new Error(`Plugin "${key5}": skill "${name}" resources must be an object`);
|
|
13634
13636
|
}
|
|
13635
|
-
for (const [path8, resource] of Object.entries(
|
|
13637
|
+
for (const [path8, resource] of Object.entries(resources2 ?? {})) {
|
|
13636
13638
|
try {
|
|
13637
13639
|
validateRelativePath(path8, "resource");
|
|
13638
13640
|
} catch {
|
|
@@ -14785,7 +14787,7 @@ function isSafeUiPath(path8) {
|
|
|
14785
14787
|
}
|
|
14786
14788
|
function validateSandboxPluginManifest(args) {
|
|
14787
14789
|
const diagnostics = [];
|
|
14788
|
-
const error = (code, message, pluginType,
|
|
14790
|
+
const error = (code, message, pluginType, tool68) => diagnostics.push({ level: "error", code, message, pluginType, tool: tool68 });
|
|
14789
14791
|
const raw = args.raw;
|
|
14790
14792
|
if (!isRecord5(raw)) {
|
|
14791
14793
|
error("MANIFEST_NOT_OBJECT", "manifest must be a JSON object", args.dirName);
|
|
@@ -15793,9 +15795,9 @@ function freezeMetadata(metadata) {
|
|
|
15793
15795
|
...resourceSelector ? { resourceSelector } : {}
|
|
15794
15796
|
});
|
|
15795
15797
|
}
|
|
15796
|
-
function toolName(
|
|
15797
|
-
if (typeof
|
|
15798
|
-
return typeof
|
|
15798
|
+
function toolName(tool68) {
|
|
15799
|
+
if (typeof tool68 !== "object" || tool68 === null || !("name" in tool68)) return void 0;
|
|
15800
|
+
return typeof tool68.name === "string" ? tool68.name : void 0;
|
|
15799
15801
|
}
|
|
15800
15802
|
function schemaHasConnectionKey(schema6) {
|
|
15801
15803
|
const definition = isRecord7(schema6._def) ? schema6._def : void 0;
|
|
@@ -15803,10 +15805,10 @@ function schemaHasConnectionKey(schema6) {
|
|
|
15803
15805
|
const fields = typeof shape === "function" ? shape() : shape;
|
|
15804
15806
|
return isRecord7(fields) && Object.prototype.hasOwnProperty.call(fields, "connectionKey");
|
|
15805
15807
|
}
|
|
15806
|
-
function hasConnectionKeySchema(
|
|
15807
|
-
if (!isRecord7(
|
|
15808
|
-
if (schemaHasConnectionKey(
|
|
15809
|
-
const definition = isRecord7(
|
|
15808
|
+
function hasConnectionKeySchema(tool68) {
|
|
15809
|
+
if (!isRecord7(tool68) || !isRecord7(tool68.schema)) return false;
|
|
15810
|
+
if (schemaHasConnectionKey(tool68.schema)) return true;
|
|
15811
|
+
const definition = isRecord7(tool68.schema._def) ? tool68.schema._def : void 0;
|
|
15810
15812
|
if (Array.isArray(definition?.options) && definition.options.length > 0) {
|
|
15811
15813
|
return definition.options.every(
|
|
15812
15814
|
(option) => isRecord7(option) && schemaHasConnectionKey(option)
|
|
@@ -15861,8 +15863,8 @@ var CapabilityToolRegistry = class {
|
|
|
15861
15863
|
* @remarks Standard connection authorization is captured only for tools whose
|
|
15862
15864
|
* schema declares `connectionKey`; legacy selectors remain explicit metadata.
|
|
15863
15865
|
*/
|
|
15864
|
-
register(name, metadata,
|
|
15865
|
-
this.registerInternal(name, metadata, hasConnectionKeySchema(
|
|
15866
|
+
register(name, metadata, tool68) {
|
|
15867
|
+
this.registerInternal(name, metadata, hasConnectionKeySchema(tool68));
|
|
15866
15868
|
}
|
|
15867
15869
|
/**
|
|
15868
15870
|
* Registers all tools actually exposed by a middleware instance.
|
|
@@ -15873,13 +15875,13 @@ var CapabilityToolRegistry = class {
|
|
|
15873
15875
|
* @returns Nothing.
|
|
15874
15876
|
*/
|
|
15875
15877
|
registerMiddleware(capabilityType, middleware, resourceSelectors = {}) {
|
|
15876
|
-
for (const
|
|
15877
|
-
const name = toolName(
|
|
15878
|
+
for (const tool68 of middleware.tools ?? []) {
|
|
15879
|
+
const name = toolName(tool68);
|
|
15878
15880
|
if (name) {
|
|
15879
15881
|
this.registerInternal(name, {
|
|
15880
15882
|
capabilityType,
|
|
15881
15883
|
resourceSelector: resourceSelectors[name]
|
|
15882
|
-
}, hasConnectionKeySchema(
|
|
15884
|
+
}, hasConnectionKeySchema(tool68));
|
|
15883
15885
|
}
|
|
15884
15886
|
}
|
|
15885
15887
|
}
|
|
@@ -16571,9 +16573,9 @@ var ReActAgentGraphBuilder = class {
|
|
|
16571
16573
|
*/
|
|
16572
16574
|
async build(agentLattice, params) {
|
|
16573
16575
|
const tools = params.tools.map((t) => {
|
|
16574
|
-
const
|
|
16575
|
-
return
|
|
16576
|
-
}).filter((
|
|
16576
|
+
const tool68 = getToolClientWithTenant(params.tenantId ?? "default", t.key);
|
|
16577
|
+
return tool68;
|
|
16578
|
+
}).filter((tool68) => tool68 !== void 0);
|
|
16577
16579
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
16578
16580
|
const middlewareConfigs = params.middleware || [];
|
|
16579
16581
|
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
@@ -16889,6 +16891,41 @@ var AgentManager = class _AgentManager {
|
|
|
16889
16891
|
}
|
|
16890
16892
|
};
|
|
16891
16893
|
|
|
16894
|
+
// src/services/TaskExecutionContext.ts
|
|
16895
|
+
var DELEGATED_WORKER_SCOPE_TOKEN = Symbol("delegated-worker-scope");
|
|
16896
|
+
var delegatedWorkerScopeSecret = Object.freeze({});
|
|
16897
|
+
function createDelegatedWorkerRunConfig(taskId) {
|
|
16898
|
+
return {
|
|
16899
|
+
taskId,
|
|
16900
|
+
delegatedTaskId: taskId,
|
|
16901
|
+
taskExecutionRole: "worker",
|
|
16902
|
+
execution: { taskId },
|
|
16903
|
+
[DELEGATED_WORKER_SCOPE_TOKEN]: delegatedWorkerScopeSecret
|
|
16904
|
+
};
|
|
16905
|
+
}
|
|
16906
|
+
function getDelegatedTaskId(runConfig) {
|
|
16907
|
+
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;
|
|
16908
|
+
}
|
|
16909
|
+
function hasDelegatedWorkerToken(runConfig) {
|
|
16910
|
+
return Object.prototype.hasOwnProperty.call(runConfig, DELEGATED_WORKER_SCOPE_TOKEN);
|
|
16911
|
+
}
|
|
16912
|
+
function preserveDelegatedWorkerContext(source, target) {
|
|
16913
|
+
const delegatedTaskId = getDelegatedTaskId(source);
|
|
16914
|
+
if (!delegatedTaskId) return;
|
|
16915
|
+
target.taskId = delegatedTaskId;
|
|
16916
|
+
target.delegatedTaskId = delegatedTaskId;
|
|
16917
|
+
target.taskExecutionRole = "worker";
|
|
16918
|
+
target.execution = { taskId: delegatedTaskId };
|
|
16919
|
+
target[DELEGATED_WORKER_SCOPE_TOKEN] = delegatedWorkerScopeSecret;
|
|
16920
|
+
}
|
|
16921
|
+
function stripDelegatedWorkerContext(target) {
|
|
16922
|
+
delete target.taskId;
|
|
16923
|
+
delete target.delegatedTaskId;
|
|
16924
|
+
delete target.taskExecutionRole;
|
|
16925
|
+
delete target.execution;
|
|
16926
|
+
delete target[DELEGATED_WORKER_SCOPE_TOKEN];
|
|
16927
|
+
}
|
|
16928
|
+
|
|
16892
16929
|
// src/agent_worker/agent_worker_graph.ts
|
|
16893
16930
|
var AgentWorkerState = import_langgraph5.Annotation.Root({
|
|
16894
16931
|
// Input parameters
|
|
@@ -16913,6 +16950,13 @@ var AgentWorkerState = import_langgraph5.Annotation.Root({
|
|
|
16913
16950
|
reducer: (x, y) => y ?? x,
|
|
16914
16951
|
default: () => void 0
|
|
16915
16952
|
}),
|
|
16953
|
+
// Optional persistent TaskItem binding. Rebuilt into an authentic delegated
|
|
16954
|
+
// worker scope on every execute (the in-process scope symbol cannot survive
|
|
16955
|
+
// LangGraph checkpointing, so it is re-derived from this plain task id).
|
|
16956
|
+
taskId: (0, import_langgraph5.Annotation)({
|
|
16957
|
+
reducer: (x, y) => y ?? x,
|
|
16958
|
+
default: () => ""
|
|
16959
|
+
}),
|
|
16916
16960
|
// Execution result
|
|
16917
16961
|
result: (0, import_langgraph5.Annotation)({
|
|
16918
16962
|
reducer: (x, y) => y ?? x,
|
|
@@ -16930,14 +16974,15 @@ var AgentWorkerState = import_langgraph5.Annotation.Root({
|
|
|
16930
16974
|
})
|
|
16931
16975
|
});
|
|
16932
16976
|
async function executeNode(state) {
|
|
16933
|
-
const { assistant_id, thread_id, input, command2, runConfig } = state;
|
|
16977
|
+
const { assistant_id, thread_id, input, command2, runConfig, taskId } = state;
|
|
16978
|
+
const effectiveRunConfig = taskId ? { ...runConfig ?? {}, ...createDelegatedWorkerRunConfig(taskId) } : runConfig;
|
|
16934
16979
|
const callParams = {
|
|
16935
16980
|
assistant_id,
|
|
16936
16981
|
"x-tenant-id": runConfig?.tenantId,
|
|
16937
16982
|
thread_id,
|
|
16938
16983
|
input,
|
|
16939
16984
|
command: command2,
|
|
16940
|
-
runConfig
|
|
16985
|
+
runConfig: effectiveRunConfig
|
|
16941
16986
|
};
|
|
16942
16987
|
const result = await AgentManager.getInstance().callAgentInQueue(
|
|
16943
16988
|
callParams,
|
|
@@ -17687,8 +17732,8 @@ function validateCapability(value, index) {
|
|
|
17687
17732
|
fieldPath: `/capabilities/${index}/allowedTools`
|
|
17688
17733
|
});
|
|
17689
17734
|
}
|
|
17690
|
-
for (const [toolIndex,
|
|
17691
|
-
if (typeof
|
|
17735
|
+
for (const [toolIndex, tool68] of capability.allowedTools.entries()) {
|
|
17736
|
+
if (typeof tool68 !== "string") {
|
|
17692
17737
|
throw new CapabilityBundleValidationError(
|
|
17693
17738
|
"CAPABILITY_BUNDLE_INVALID_CAPABILITY",
|
|
17694
17739
|
"allowedTools entries must be strings",
|
|
@@ -17702,10 +17747,10 @@ function validateCapability(value, index) {
|
|
|
17702
17747
|
fieldPath: `/capabilities/${index}/allowedTools`
|
|
17703
17748
|
});
|
|
17704
17749
|
}
|
|
17705
|
-
const toolNames = new Set(plugin.meta.tools.map((
|
|
17706
|
-
for (const [toolIndex,
|
|
17707
|
-
if (typeof
|
|
17708
|
-
throw new CapabilityBundleValidationError("CAPABILITY_BUNDLE_UNKNOWN_TOOL", `Unknown tool '${String(
|
|
17750
|
+
const toolNames = new Set(plugin.meta.tools.map((tool68) => tool68.name));
|
|
17751
|
+
for (const [toolIndex, tool68] of capability.allowedTools.entries()) {
|
|
17752
|
+
if (typeof tool68 !== "string" || !toolNames.has(tool68)) {
|
|
17753
|
+
throw new CapabilityBundleValidationError("CAPABILITY_BUNDLE_UNKNOWN_TOOL", `Unknown tool '${String(tool68)}'`, {
|
|
17709
17754
|
capabilityType,
|
|
17710
17755
|
fieldPath: `/capabilities/${index}/allowedTools/${toolIndex}`
|
|
17711
17756
|
});
|
|
@@ -18188,7 +18233,7 @@ function applyStaticCeiling(capabilities, staticMiddleware) {
|
|
|
18188
18233
|
const projectTools = capability.allowedTools;
|
|
18189
18234
|
const staticTools = ceiling.allowedTools;
|
|
18190
18235
|
const effectiveStaticTools = staticTools?.length === 0 ? void 0 : staticTools;
|
|
18191
|
-
const allowedTools = projectTools === void 0 ? effectiveStaticTools : effectiveStaticTools === void 0 ? projectTools : projectTools.filter((
|
|
18236
|
+
const allowedTools = projectTools === void 0 ? effectiveStaticTools : effectiveStaticTools === void 0 ? projectTools : projectTools.filter((tool68) => effectiveStaticTools.includes(tool68));
|
|
18192
18237
|
runtime[capability.type] = structuredClone({
|
|
18193
18238
|
...capability,
|
|
18194
18239
|
config: applyStaticResourceCeiling(capability, ceiling),
|
|
@@ -18288,38 +18333,6 @@ var CapabilityRuntimeResolver = class {
|
|
|
18288
18333
|
}
|
|
18289
18334
|
};
|
|
18290
18335
|
|
|
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
18336
|
// src/services/TrustedAgentDispatchCapability.ts
|
|
18324
18337
|
var TRUSTED_AGENT_DISPATCH = Symbol("axiom.trustedAgentDispatch");
|
|
18325
18338
|
|
|
@@ -18483,8 +18496,22 @@ function sanitizeCallerRunConfig(value, preserveDelegatedContext = true) {
|
|
|
18483
18496
|
} else {
|
|
18484
18497
|
stripDelegatedWorkerContext(callerRunConfig);
|
|
18485
18498
|
}
|
|
18499
|
+
preserveExecutionBinding(value, callerRunConfig);
|
|
18486
18500
|
return callerRunConfig;
|
|
18487
18501
|
}
|
|
18502
|
+
function preserveExecutionBinding(source, target) {
|
|
18503
|
+
if (typeof source !== "object" || source === null || Array.isArray(source)) return;
|
|
18504
|
+
const execution = (0, import_protocols10.descriptorDataValue)(Object.getOwnPropertyDescriptor(source, "execution"))?.value;
|
|
18505
|
+
if (typeof execution !== "object" || execution === null || Array.isArray(execution)) return;
|
|
18506
|
+
const taskId = (0, import_protocols10.descriptorDataValue)(Object.getOwnPropertyDescriptor(execution, "taskId"))?.value;
|
|
18507
|
+
if (typeof taskId !== "string" || taskId.trim() === "") return;
|
|
18508
|
+
Object.defineProperty(target, "execution", {
|
|
18509
|
+
value: { taskId },
|
|
18510
|
+
enumerable: true,
|
|
18511
|
+
configurable: true,
|
|
18512
|
+
writable: true
|
|
18513
|
+
});
|
|
18514
|
+
}
|
|
18488
18515
|
function sanitizeExecutionRunConfig(value) {
|
|
18489
18516
|
return cloneRunConfig(value, false);
|
|
18490
18517
|
}
|
|
@@ -18604,6 +18631,7 @@ function checkpointCapabilityRevision(state) {
|
|
|
18604
18631
|
}
|
|
18605
18632
|
var QUEUE_PROCESSOR_RETRY_BASE_MS = 100;
|
|
18606
18633
|
var QUEUE_PROCESSOR_MAX_RETRIES = 3;
|
|
18634
|
+
var AGENT_RECURSION_LIMIT = 1e3;
|
|
18607
18635
|
function hasExactKeys(record, required, optional = []) {
|
|
18608
18636
|
const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
|
|
18609
18637
|
return required.every((key5) => Object.prototype.hasOwnProperty.call(record, key5)) && Reflect.ownKeys(record).every((key5) => typeof key5 === "string" && allowed.has(key5));
|
|
@@ -18656,7 +18684,7 @@ var Agent = class {
|
|
|
18656
18684
|
...executionRunConfig,
|
|
18657
18685
|
runConfig: executionRunConfig
|
|
18658
18686
|
},
|
|
18659
|
-
recursionLimit:
|
|
18687
|
+
recursionLimit: AGENT_RECURSION_LIMIT,
|
|
18660
18688
|
signal
|
|
18661
18689
|
}
|
|
18662
18690
|
);
|
|
@@ -18731,7 +18759,7 @@ var Agent = class {
|
|
|
18731
18759
|
},
|
|
18732
18760
|
streamMode: ["updates", "messages"],
|
|
18733
18761
|
subgraphs: false,
|
|
18734
|
-
recursionLimit:
|
|
18762
|
+
recursionLimit: AGENT_RECURSION_LIMIT,
|
|
18735
18763
|
signal
|
|
18736
18764
|
}
|
|
18737
18765
|
);
|
|
@@ -19229,6 +19257,15 @@ var Agent = class {
|
|
|
19229
19257
|
configurable: true,
|
|
19230
19258
|
writable: true
|
|
19231
19259
|
});
|
|
19260
|
+
const trustedTaskId = parsed.projectTask?.taskId;
|
|
19261
|
+
if (trustedTaskId) {
|
|
19262
|
+
Object.defineProperty(base, "execution", {
|
|
19263
|
+
value: { taskId: trustedTaskId },
|
|
19264
|
+
enumerable: true,
|
|
19265
|
+
configurable: true,
|
|
19266
|
+
writable: true
|
|
19267
|
+
});
|
|
19268
|
+
}
|
|
19232
19269
|
return base;
|
|
19233
19270
|
}
|
|
19234
19271
|
getHumanPendingContent(message) {
|
|
@@ -19432,7 +19469,7 @@ var Agent = class {
|
|
|
19432
19469
|
...executionRunConfig,
|
|
19433
19470
|
runConfig: executionRunConfig
|
|
19434
19471
|
},
|
|
19435
|
-
recursionLimit:
|
|
19472
|
+
recursionLimit: AGENT_RECURSION_LIMIT,
|
|
19436
19473
|
signal
|
|
19437
19474
|
}
|
|
19438
19475
|
);
|
|
@@ -19543,7 +19580,7 @@ var Agent = class {
|
|
|
19543
19580
|
},
|
|
19544
19581
|
streamMode: ["updates", "messages"],
|
|
19545
19582
|
subgraphs: false,
|
|
19546
|
-
recursionLimit:
|
|
19583
|
+
recursionLimit: AGENT_RECURSION_LIMIT,
|
|
19547
19584
|
signal
|
|
19548
19585
|
}
|
|
19549
19586
|
);
|
|
@@ -20300,6 +20337,20 @@ var agentInstanceManager = AgentInstanceManager.getInstance();
|
|
|
20300
20337
|
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
20338
|
var EXCLUDED_STATE_KEYS = ["messages", "todos", "jumpTo"];
|
|
20302
20339
|
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.";
|
|
20340
|
+
function createGeneralPurposeAgent(options) {
|
|
20341
|
+
const middleware = [...options.middleware];
|
|
20342
|
+
if (options.interruptOn) {
|
|
20343
|
+
middleware.push((0, import_langchain53.humanInTheLoopMiddleware)({ interruptOn: options.interruptOn }));
|
|
20344
|
+
}
|
|
20345
|
+
return (0, import_langchain53.createAgent)({
|
|
20346
|
+
model: options.model,
|
|
20347
|
+
systemPrompt: DEFAULT_SUBAGENT_PROMPT,
|
|
20348
|
+
tools: options.tools,
|
|
20349
|
+
middleware,
|
|
20350
|
+
checkpointer: getCheckpointSaver("default"),
|
|
20351
|
+
name: "general-purpose"
|
|
20352
|
+
});
|
|
20353
|
+
}
|
|
20303
20354
|
function getTaskToolDescription(subagentDescriptions) {
|
|
20304
20355
|
return subagentDescriptions.length > 0 ? `
|
|
20305
20356
|
Launch an ephemeral subagent to handle complex, multi-step independent tasks with isolated context windows.
|
|
@@ -20479,21 +20530,12 @@ function getSubagents(options) {
|
|
|
20479
20530
|
const agents = {};
|
|
20480
20531
|
const subagentDescriptions = [];
|
|
20481
20532
|
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)({
|
|
20533
|
+
agents["general-purpose"] = createGeneralPurposeAgent({
|
|
20489
20534
|
model: defaultModel,
|
|
20490
|
-
systemPrompt: DEFAULT_SUBAGENT_PROMPT,
|
|
20491
20535
|
tools: defaultTools,
|
|
20492
|
-
middleware:
|
|
20493
|
-
|
|
20494
|
-
name: "general-purpose"
|
|
20536
|
+
middleware: defaultSubagentMiddleware,
|
|
20537
|
+
interruptOn: defaultInterruptOn
|
|
20495
20538
|
});
|
|
20496
|
-
agents["general-purpose"] = generalPurposeSubagent;
|
|
20497
20539
|
subagentDescriptions.push(
|
|
20498
20540
|
`- general-purpose: ${DEFAULT_GENERAL_PURPOSE_DESCRIPTION}`
|
|
20499
20541
|
);
|
|
@@ -23932,6 +23974,7 @@ ${BASE_PROMPT}` : BASE_PROMPT;
|
|
|
23932
23974
|
}
|
|
23933
23975
|
|
|
23934
23976
|
// src/agent_lattice/builders/DeepAgentGraphBuilder.ts
|
|
23977
|
+
var import_protocols15 = require("@axiom-lattice/protocols");
|
|
23935
23978
|
init_MemoryLatticeManager();
|
|
23936
23979
|
var DeepAgentGraphBuilder = class {
|
|
23937
23980
|
/**
|
|
@@ -23945,7 +23988,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
23945
23988
|
const tools = params.tools.map((t) => {
|
|
23946
23989
|
const toolClient = getToolClientWithTenant(params.tenantId ?? "default", t.key);
|
|
23947
23990
|
return toolClient;
|
|
23948
|
-
}).filter((
|
|
23991
|
+
}).filter((tool68) => tool68 !== void 0);
|
|
23949
23992
|
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
23950
23993
|
if (sa.client) {
|
|
23951
23994
|
return {
|
|
@@ -23981,6 +24024,28 @@ var DeepAgentGraphBuilder = class {
|
|
|
23981
24024
|
backend: filesystemBackend,
|
|
23982
24025
|
middleware: middlewares
|
|
23983
24026
|
});
|
|
24027
|
+
if (middlewares.some((candidate) => candidate.name === "TaskMiddleware") && agentLattice.config.key) {
|
|
24028
|
+
const tenantId2 = params.tenantId ?? "default";
|
|
24029
|
+
const generalPurposeKey = `${agentLattice.config.key}-general-purpose`;
|
|
24030
|
+
if (!agentLatticeManager.hasAgentLatticeWithTenant(tenantId2, generalPurposeKey)) {
|
|
24031
|
+
const generalPurposeAgent = createGeneralPurposeAgent({
|
|
24032
|
+
model: params.model,
|
|
24033
|
+
tools,
|
|
24034
|
+
middleware: middlewares
|
|
24035
|
+
});
|
|
24036
|
+
agentLatticeManager.registerWithTenant(tenantId2, generalPurposeKey, {
|
|
24037
|
+
config: {
|
|
24038
|
+
key: generalPurposeKey,
|
|
24039
|
+
name: "general-purpose",
|
|
24040
|
+
description: DEFAULT_GENERAL_PURPOSE_DESCRIPTION,
|
|
24041
|
+
type: import_protocols15.AgentType.REACT,
|
|
24042
|
+
prompt: DEFAULT_SUBAGENT_PROMPT,
|
|
24043
|
+
tenantId: tenantId2
|
|
24044
|
+
},
|
|
24045
|
+
client: generalPurposeAgent
|
|
24046
|
+
});
|
|
24047
|
+
}
|
|
24048
|
+
}
|
|
23984
24049
|
return deepAgent;
|
|
23985
24050
|
}
|
|
23986
24051
|
};
|
|
@@ -25575,7 +25640,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
25575
25640
|
const tools = params.tools.map((t) => {
|
|
25576
25641
|
const toolClient = getToolClientWithTenant(params.tenantId ?? "default", t.key);
|
|
25577
25642
|
return toolClient;
|
|
25578
|
-
}).filter((
|
|
25643
|
+
}).filter((tool68) => tool68 !== void 0);
|
|
25579
25644
|
const teammates = params.subAgents.map((sa) => {
|
|
25580
25645
|
const baseConfig = sa.config;
|
|
25581
25646
|
return {
|
|
@@ -25932,11 +25997,11 @@ _A2ARemoteClient.MAX_CACHED_TASKS = 100;
|
|
|
25932
25997
|
var A2ARemoteClient = _A2ARemoteClient;
|
|
25933
25998
|
|
|
25934
25999
|
// src/agent_lattice/builders/RemoteAgentGraphBuilder.ts
|
|
25935
|
-
var
|
|
26000
|
+
var import_protocols16 = require("@axiom-lattice/protocols");
|
|
25936
26001
|
init_MemoryLatticeManager();
|
|
25937
26002
|
var RemoteAgentGraphBuilder = class {
|
|
25938
26003
|
async build(agentLattice, params) {
|
|
25939
|
-
if (agentLattice.config.type !==
|
|
26004
|
+
if (agentLattice.config.type !== import_protocols16.AgentType.A2A_REMOTE) {
|
|
25940
26005
|
throw new Error(
|
|
25941
26006
|
`RemoteAgentGraphBuilder received wrong agent type: ${agentLattice.config.type}`
|
|
25942
26007
|
);
|
|
@@ -26001,7 +26066,7 @@ function extractLastHumanMessage(messages) {
|
|
|
26001
26066
|
// src/agent_lattice/builders/WorkflowAgentGraphBuilder.ts
|
|
26002
26067
|
var import_langchain61 = require("langchain");
|
|
26003
26068
|
init_MemoryLatticeManager();
|
|
26004
|
-
var
|
|
26069
|
+
var import_protocols17 = require("@axiom-lattice/protocols");
|
|
26005
26070
|
init_compile();
|
|
26006
26071
|
|
|
26007
26072
|
// src/agent_lattice/builders/middlewareSanitize.ts
|
|
@@ -26039,7 +26104,7 @@ ${configPrompt}` : base;
|
|
|
26039
26104
|
}
|
|
26040
26105
|
var WorkflowAgentGraphBuilder = class {
|
|
26041
26106
|
async build(agentLattice, params) {
|
|
26042
|
-
if (!(0,
|
|
26107
|
+
if (!(0, import_protocols17.isWorkflowAgentConfig)(agentLattice.config)) {
|
|
26043
26108
|
throw new Error(
|
|
26044
26109
|
`WorkflowAgentGraphBuilder received wrong agent type: ${agentLattice.config.type}`
|
|
26045
26110
|
);
|
|
@@ -26177,7 +26242,7 @@ var AgentGraphBuilderFactory = class _AgentGraphBuilderFactory {
|
|
|
26177
26242
|
};
|
|
26178
26243
|
|
|
26179
26244
|
// src/agent_lattice/builders/AgentParamsBuilder.ts
|
|
26180
|
-
var
|
|
26245
|
+
var import_protocols18 = require("@axiom-lattice/protocols");
|
|
26181
26246
|
var AgentParamsBuilder = class {
|
|
26182
26247
|
/**
|
|
26183
26248
|
* constructor
|
|
@@ -26195,8 +26260,8 @@ var AgentParamsBuilder = class {
|
|
|
26195
26260
|
* @returns Agent build parameters
|
|
26196
26261
|
*/
|
|
26197
26262
|
async buildParams(agentLattice, options) {
|
|
26198
|
-
const skills = (0,
|
|
26199
|
-
const toolKeys = options?.overrideTools || (0,
|
|
26263
|
+
const skills = (0, import_protocols18.isDeepAgentConfig)(agentLattice.config) || (0, import_protocols18.isProcessingAgentConfig)(agentLattice.config) ? agentLattice.config.skillCategories : void 0;
|
|
26264
|
+
const toolKeys = options?.overrideTools || (0, import_protocols18.getToolsFromConfig)(agentLattice.config);
|
|
26200
26265
|
const tenantId2 = agentLattice.config.tenantId || "default";
|
|
26201
26266
|
const tools = toolKeys.map((toolKey) => {
|
|
26202
26267
|
const toolLattice = toolLatticeManager.getToolLatticeWithTenant(tenantId2, toolKey) ?? toolLatticeManager.getToolLatticeWithTenant("default", toolKey);
|
|
@@ -26215,7 +26280,7 @@ var AgentParamsBuilder = class {
|
|
|
26215
26280
|
if (!model) {
|
|
26216
26281
|
throw new Error(`Model "${modelKey}" does not exist`);
|
|
26217
26282
|
}
|
|
26218
|
-
const subAgentKeys = (0,
|
|
26283
|
+
const subAgentKeys = (0, import_protocols18.getSubAgentsFromConfig)(agentLattice.config);
|
|
26219
26284
|
const subAgents = await Promise.all(subAgentKeys.map(async (agentKey) => {
|
|
26220
26285
|
const subAgentLattice = await this.getAgentLatticeFunc(agentKey);
|
|
26221
26286
|
if (!subAgentLattice) {
|
|
@@ -26232,7 +26297,7 @@ var AgentParamsBuilder = class {
|
|
|
26232
26297
|
}));
|
|
26233
26298
|
const resolvedSubAgents = subAgents.filter((s) => s !== null);
|
|
26234
26299
|
let internalSubAgents = [];
|
|
26235
|
-
if ((0,
|
|
26300
|
+
if ((0, import_protocols18.isDeepAgentConfig)(agentLattice.config) || (0, import_protocols18.isProcessingAgentConfig)(agentLattice.config)) {
|
|
26236
26301
|
internalSubAgents = agentLattice.config.internalSubAgents?.map((i) => ({
|
|
26237
26302
|
key: i.key,
|
|
26238
26303
|
config: i
|
|
@@ -26710,9 +26775,15 @@ For human judgment, use the actual HITL payload \`status: "interrupted"\` plus
|
|
|
26710
26775
|
handled by the configured HITL lifecycle; \`review_required\` is not a task status.
|
|
26711
26776
|
|
|
26712
26777
|
Create the active parent and each started subtask as records: \`manage_task
|
|
26713
|
-
create\` always persists \`pending\`.
|
|
26714
|
-
|
|
26715
|
-
|
|
26778
|
+
create\` always persists \`pending\`. **Process the task you were assigned in this
|
|
26779
|
+
run: set it \`in_progress\` with \`manage_task set_status\` when you start (a
|
|
26780
|
+
dispatched task is claimed automatically by the engine).** To bring
|
|
26781
|
+
in a more suitable expert, create a subtask (\`pending\`) and dispatch THAT with
|
|
26782
|
+
\`task { taskId, agentId }\` (a specialist, or agentId "general-purpose" to run your
|
|
26783
|
+
own capabilities in an isolated run). **Never re-dispatch the task you are
|
|
26784
|
+
currently processing** \u2014 delegating to an expert means giving them a child task,
|
|
26785
|
+
not handing over your own. Report the outcome with \`set_status completed\` (result
|
|
26786
|
+
+ beliefImpact), \`failed\`, or \`interrupted\`. Use \`pending\` only for future or
|
|
26716
26787
|
dependency-blocked work.
|
|
26717
26788
|
Before marking the parent completed, call \`list(parentId)\`: every child must
|
|
26718
26789
|
be completed or cancelled, while a failed or interrupted child blocks completion
|
|
@@ -28003,34 +28074,24 @@ Renew HITL approval when a foundational assumption or authority boundary changes
|
|
|
28003
28074
|
|
|
28004
28075
|
## Skill Loading Policy
|
|
28005
28076
|
|
|
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.
|
|
28077
|
+
Visible in <available_skills> does not mean loaded. Load a skill only when the
|
|
28078
|
+
current step actually requires its procedure \u2014 one at a time, never preloaded.
|
|
28079
|
+
Do not load skills speculatively or to "see what exists": inspect existing
|
|
28080
|
+
assets with a bounded read-only survey, not by loading skill content.
|
|
28081
|
+
|
|
28082
|
+
- [[agent-architecture]] (this skill) \u2014 loaded at session start by the bootstrap
|
|
28083
|
+
prompt; it is the shared policy and router.
|
|
28084
|
+
- [[task-tracking]] \u2014 load right before your first \`manage_task\` call; Task
|
|
28085
|
+
management is the planning surface (gated again under Architect Task Policy).
|
|
28086
|
+
- Procedure skills \u2014 [[agent-build]], [[design-workflow]],
|
|
28087
|
+
[[document-learning-learn-capability]], [[eval-verify]], [[completion-gate]],
|
|
28088
|
+
[[review-agent]], [[knowledge-management]]: load the ONE that owns the step you
|
|
28089
|
+
are about to perform, immediately before performing it. Never preload the chain.
|
|
28090
|
+
- Reference and plugin skills (deep wiki-links, task-definition, sandbox authoring,
|
|
28091
|
+
and any plugin skills): load only when the current step needs them; never preload.
|
|
28092
|
+
|
|
28093
|
+
Loading a skill is a tool call, not a plan. If a required load fails, retry once,
|
|
28094
|
+
then stop and tell the user which capability is unavailable.
|
|
28034
28095
|
|
|
28035
28096
|
## Agent Forms and Routing
|
|
28036
28097
|
- **Capability** (\`react\`) for bounded direct work: [[agent-build]]
|
|
@@ -28043,9 +28104,19 @@ only when the current step actually needs it.
|
|
|
28043
28104
|
- **Tenant plugin** (sandbox-authored tool + optional HTML UI) \u2192 use the \`plugin-builder\` agent, or load [[sandbox-plugins-authoring]].
|
|
28044
28105
|
|
|
28045
28106
|
## Architect Task Policy
|
|
28046
|
-
The Agent Architect
|
|
28047
|
-
|
|
28107
|
+
The Agent Architect MUST use persistent TaskItems as its single working surface;
|
|
28108
|
+
Architect must not use \`write_todos\` for independently verifiable outcomes, and
|
|
28109
|
+
working without a corresponding TaskItem is a policy violation.
|
|
28110
|
+
Create a persistent child only for an independently verifiable
|
|
28048
28111
|
outcome; tool calls and file reads are actions inside the active Task.
|
|
28112
|
+
**Each task is your evidence ledger**: its Acceptance Criteria + Belief State define
|
|
28113
|
+
what counts as evidence, the work runs inside your own run (eval / \`invoke_agent\` for
|
|
28114
|
+
subject agents) and produces that evidence, and the parent completes only when the
|
|
28115
|
+
evidence is sufficient. Process the task you were assigned in this run; set it
|
|
28116
|
+
\`in_progress\` with \`manage_task set_status\` when you start. Delegate a subtask only
|
|
28117
|
+
when it belongs to another agent \u2014 create it (\`pending\`) and dispatch it with
|
|
28118
|
+
\`task { taskId, agentId }\`. To exercise a designed/subject agent, use eval /
|
|
28119
|
+
\`invoke_agent\` inside your own run instead of \`task\` dispatch.
|
|
28049
28120
|
**MANDATORY: before your first \`manage_task\` call in this session, load
|
|
28050
28121
|
[[task-tracking]] with the \`skill\` tool.** Do not create, update, or transition
|
|
28051
28122
|
any Task until it is loaded. If the load fails, retry once, then tell the user
|
|
@@ -28116,11 +28187,11 @@ When a room request is actionable work, decide between two paths:
|
|
|
28116
28187
|
\`assistantId\`, then dispatch it with
|
|
28117
28188
|
\`task { taskId, agentId: <bot assistantId> }\` so the specialist actually runs
|
|
28118
28189
|
(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.
|
|
28190
|
+
\`agentId\` and runs it in an isolated thread; the target does not need task
|
|
28191
|
+
tools \u2014 if it has \`manage_task\` it records status itself, otherwise reconcile
|
|
28192
|
+
its returned \`executionResultId\` with \`manage_task\` update. State the expected output
|
|
28193
|
+
and acceptance criteria in the task description so the assigned bot can
|
|
28194
|
+
verify its own work.
|
|
28124
28195
|
|
|
28125
28196
|
## Discovering bots
|
|
28126
28197
|
Before delegating, call \`list_room_roster\` to see the active room bots and their
|
|
@@ -28271,9 +28342,15 @@ criteria are truly met \u2014 never as a workaround.
|
|
|
28271
28342
|
uncertainties, with no required minimum and a maximum of seven:
|
|
28272
28343
|
\`manage_task create(title: <goal>, description: <contract + Belief State>, ownerType: "agent")\`
|
|
28273
28344
|
\`create\` always yields a \`pending\` record \u2014 it never starts execution. Record
|
|
28274
|
-
the returned parent task id, then
|
|
28275
|
-
\`
|
|
28276
|
-
\`
|
|
28345
|
+
the returned parent task id, then **process it in this run**, setting it
|
|
28346
|
+
\`in_progress\` with \`manage_task set_status\` when you start. To decompose, create each subtask
|
|
28347
|
+
with \`manage_task create\` (\`pending\`) and delegate it with \`task { taskId,
|
|
28348
|
+
agentId }\` to the agent that should execute it (a specialist, or
|
|
28349
|
+
"general-purpose" for your own capabilities). The executor does not need
|
|
28350
|
+
\`manage_task\`: it returns an observation and \`executionResultId\`, and the caller
|
|
28351
|
+
records the outcome with \`manage_task\`. To exercise a subject application agent,
|
|
28352
|
+
use eval cases / \`invoke_agent\` inside your own run \u2014 \`task\` dispatch is
|
|
28353
|
+
delegation of persistent work, not an evaluation mechanism.
|
|
28277
28354
|
- **Create a subtask for a verifiable result**, not per phase: identify its
|
|
28278
28355
|
deliverable, define observable acceptance criteria and required evidence, and
|
|
28279
28356
|
state positive and negative result branches under Targets / Expected Impact
|
|
@@ -28298,10 +28375,15 @@ ${TASK_BELIEF_REFERENCE_EXAMPLE}
|
|
|
28298
28375
|
|
|
28299
28376
|
## Status discipline \u2014 MANDATORY
|
|
28300
28377
|
|
|
28378
|
+
- Execution ownership: process the task you were assigned in this run; set it
|
|
28379
|
+
\`in_progress\` with \`manage_task set_status\` when you start. To involve a more
|
|
28380
|
+
suitable expert, create a subtask and dispatch it with \`task { taskId, agentId }\`
|
|
28381
|
+
\u2014 never re-dispatch the task you are processing. Report the outcome with
|
|
28382
|
+
\`set_status completed\` (result + beliefImpact), \`failed\`, or \`interrupted\`.
|
|
28301
28383
|
- All status transitions go through \`manage_task set_status\` (with
|
|
28302
28384
|
\`result\` on completed, \`failureReason\` on failed). \`update\` is for
|
|
28303
28385
|
content fields only and rejects a status field.
|
|
28304
|
-
- A
|
|
28386
|
+
- A task is \`completed\` ONLY when its work is actually finished.
|
|
28305
28387
|
While fixing eval failures, keep it \`in_progress\` \u2014 never mark
|
|
28306
28388
|
\`completed\` as a workaround (the state machine rejects illegal
|
|
28307
28389
|
transitions).
|
|
@@ -28901,6 +28983,11 @@ its evidence projection, not an independent source of goals or expectations.
|
|
|
28901
28983
|
touching any eval project. An eval project created without a real, confirmed
|
|
28902
28984
|
subject is a hard error. If the agent is only planned (not yet materialized),
|
|
28903
28985
|
evaluation must wait until materialization returns its id.
|
|
28986
|
+
- **Exercise the subject through eval \u2014 never through \`task\` dispatch.** The
|
|
28987
|
+
subject agent is invoked by eval cases / \`invoke_agent\`; do NOT create a
|
|
28988
|
+
TaskItem assigned to the subject and dispatch it. \`task\` is for delegated
|
|
28989
|
+
execution of persistent work, not an evaluation mechanism. Use eval cases to
|
|
28990
|
+
measure the subject; keep \`task\` dispatch for executors running real work.
|
|
28904
28991
|
- **Check existence before creating; reuse is the rule, creation is the exception.**
|
|
28905
28992
|
Project names are unique per tenant. 1) Name it exactly \`eval-{agent-id}\`.
|
|
28906
28993
|
2) \`read_eval list_projects({ name: "eval-{agent-id}" })\` \u2014 a name-scoped lookup,
|
|
@@ -29888,7 +29975,7 @@ var InMemoryMenuStore = class {
|
|
|
29888
29975
|
// src/agent_lattice/agentArchitectTools.ts
|
|
29889
29976
|
var import_zod50 = __toESM(require("zod"));
|
|
29890
29977
|
var import_uuid9 = require("uuid");
|
|
29891
|
-
var
|
|
29978
|
+
var import_protocols19 = require("@axiom-lattice/protocols");
|
|
29892
29979
|
function getTenantId2(exeConfig) {
|
|
29893
29980
|
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
29894
29981
|
return runConfig.tenantId || "default";
|
|
@@ -29938,7 +30025,7 @@ function getStringMetadata(config) {
|
|
|
29938
30025
|
}
|
|
29939
30026
|
function isUndecidedLearningPlaceholder(config) {
|
|
29940
30027
|
const metadata = getStringMetadata(config);
|
|
29941
|
-
return config.type ===
|
|
30028
|
+
return config.type === import_protocols19.AgentType.REACT && metadata.learningPlaceholder === "true" && metadata.architectureStatus === "undecided";
|
|
29942
30029
|
}
|
|
29943
30030
|
function requireSkillDeclaration(skillLoaded) {
|
|
29944
30031
|
if (skillLoaded !== true) {
|
|
@@ -29950,7 +30037,7 @@ function requireSkillDeclaration(skillLoaded) {
|
|
|
29950
30037
|
return void 0;
|
|
29951
30038
|
}
|
|
29952
30039
|
async function validateAgentReferences(input, tenantId2) {
|
|
29953
|
-
const availableTools = getAvailableTools(tenantId2).map((
|
|
30040
|
+
const availableTools = getAvailableTools(tenantId2).map((tool68) => tool68.key);
|
|
29954
30041
|
const availableMiddlewareTypes = getAvailableMiddlewareTypes();
|
|
29955
30042
|
const availableCustomMiddlewareKeys = CustomMiddlewareRegistry.list().filter(
|
|
29956
30043
|
(key5) => CustomMiddlewareRegistry.get(key5) !== void 0
|
|
@@ -30091,7 +30178,7 @@ registerToolLattice(
|
|
|
30091
30178
|
key: id,
|
|
30092
30179
|
name: input.name,
|
|
30093
30180
|
description: input.description || "",
|
|
30094
|
-
type: input.type === "deep_agent" ?
|
|
30181
|
+
type: input.type === "deep_agent" ? import_protocols19.AgentType.DEEP_AGENT : import_protocols19.AgentType.REACT,
|
|
30095
30182
|
prompt: input.prompt,
|
|
30096
30183
|
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
30097
30184
|
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
@@ -30148,7 +30235,7 @@ registerToolLattice(
|
|
|
30148
30235
|
key: id,
|
|
30149
30236
|
name: input.name,
|
|
30150
30237
|
description: input.description || "",
|
|
30151
|
-
type:
|
|
30238
|
+
type: import_protocols19.AgentType.WORKFLOW,
|
|
30152
30239
|
prompt: input.description || `Workflow: ${input.name}`,
|
|
30153
30240
|
workflowYaml: input.yaml,
|
|
30154
30241
|
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
@@ -30185,7 +30272,7 @@ registerToolLattice(
|
|
|
30185
30272
|
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
30186
30273
|
}
|
|
30187
30274
|
const graphDef = agent.graphDefinition;
|
|
30188
|
-
if (!graphDef || graphDef.type !==
|
|
30275
|
+
if (!graphDef || graphDef.type !== import_protocols19.AgentType.WORKFLOW) {
|
|
30189
30276
|
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
30190
30277
|
}
|
|
30191
30278
|
const yaml2 = graphDef.workflowYaml;
|
|
@@ -30300,7 +30387,7 @@ registerToolLattice(
|
|
|
30300
30387
|
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
30301
30388
|
}
|
|
30302
30389
|
const existingConfig = existing.graphDefinition || {};
|
|
30303
|
-
const isWorkflow = existingConfig.type ===
|
|
30390
|
+
const isWorkflow = existingConfig.type === import_protocols19.AgentType.WORKFLOW;
|
|
30304
30391
|
const isPlaceholder = isUndecidedLearningPlaceholder(existingConfig);
|
|
30305
30392
|
if (!isWorkflow && !isPlaceholder) {
|
|
30306
30393
|
console.log(`[update_workflow] ERROR: not a workflow agent: ${input.id}`);
|
|
@@ -30316,7 +30403,7 @@ registerToolLattice(
|
|
|
30316
30403
|
const mergedConfig = {
|
|
30317
30404
|
...existingConfig,
|
|
30318
30405
|
...isPlaceholder ? {
|
|
30319
|
-
type:
|
|
30406
|
+
type: import_protocols19.AgentType.WORKFLOW,
|
|
30320
30407
|
workflowYaml: input.yaml,
|
|
30321
30408
|
metadata: {
|
|
30322
30409
|
...getStringMetadata(existingConfig),
|
|
@@ -30422,14 +30509,14 @@ registerToolLattice(
|
|
|
30422
30509
|
const mergedConfig = { ...existingConfig, ...input.config };
|
|
30423
30510
|
const isPlaceholder = isUndecidedLearningPlaceholder(existingConfigRecord);
|
|
30424
30511
|
const materializedType = input.config.type;
|
|
30425
|
-
const isMaterializingPlaceholder = isPlaceholder && (materializedType ===
|
|
30512
|
+
const isMaterializingPlaceholder = isPlaceholder && (materializedType === import_protocols19.AgentType.REACT || materializedType === import_protocols19.AgentType.DEEP_AGENT);
|
|
30426
30513
|
if (isMaterializingPlaceholder) {
|
|
30427
30514
|
mergedConfig.metadata = {
|
|
30428
30515
|
...getStringMetadata(existingConfigRecord),
|
|
30429
30516
|
...input.config.metadata ?? {},
|
|
30430
30517
|
learningPlaceholder: "false",
|
|
30431
30518
|
architectureStatus: "materialized",
|
|
30432
|
-
architectureForm: materializedType ===
|
|
30519
|
+
architectureForm: materializedType === import_protocols19.AgentType.DEEP_AGENT ? "orchestra" : "capability"
|
|
30433
30520
|
};
|
|
30434
30521
|
} else if (isPlaceholder && input.config.metadata !== void 0) {
|
|
30435
30522
|
const metadata = {
|
|
@@ -30679,100 +30766,20 @@ var import_protocols20 = require("@axiom-lattice/protocols");
|
|
|
30679
30766
|
// src/agent_lattice/agentArchitectPrompt.ts
|
|
30680
30767
|
var AGENT_ARCHITECT_PROMPT = `You are the Agent Architect.
|
|
30681
30768
|
|
|
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:
|
|
30769
|
+
Your working surface is persistent **TaskItems**. Every independently verifiable
|
|
30770
|
+
outcome MUST be a TaskItem created and kept truthful through \`manage_task\`; do NOT
|
|
30771
|
+
keep a separate todo list \u2014 the TaskItem is your only planning and evidence surface.
|
|
30772
|
+
Gather evidence through tasks, and treat the parent as done only when its
|
|
30773
|
+
acceptance evidence is sufficient. If the \`task\` tools are unavailable, stop and
|
|
30774
|
+
report that task management is unavailable instead of working around it.
|
|
30722
30775
|
|
|
30723
|
-
|
|
30724
|
-
|
|
30725
|
-
|
|
30726
|
-
|
|
30727
|
-
|
|
30728
|
-
|
|
30729
|
-
|
|
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
|
|
30735
|
-
|
|
30736
|
-
### When results are wrong:
|
|
30737
|
-
|
|
30738
|
-
If the agent's response is incorrect or unexpected:
|
|
30739
|
-
1. Point out specifically what went wrong
|
|
30740
|
-
2. Suggest what might need to change in the prompt or middleware config
|
|
30741
|
-
3. Offer to re-test after fixes are applied
|
|
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
|
-
};
|
|
30776
|
+
CRITICAL FIRST ACTION: Before any response or other action, call the \`skill\`
|
|
30777
|
+
tool with skill_name: "agent-architecture" to load the shared policy and router,
|
|
30778
|
+
and follow it. Load every OTHER skill only when the current step actually
|
|
30779
|
+
requires its procedure \u2014 one at a time, never preloaded. Load "task-tracking"
|
|
30780
|
+
right before your first \`manage_task\` call. Never announce skill loads. If a
|
|
30781
|
+
required load fails, retry once, then stop and explicitly report that the
|
|
30782
|
+
required skill could not be loaded.`;
|
|
30776
30783
|
|
|
30777
30784
|
// src/agent_lattice/agentArchitectConfig.ts
|
|
30778
30785
|
var AGENT_ARCHITECT_KEY = "agent-architect";
|
|
@@ -30798,7 +30805,6 @@ var agentArchitectConfig = {
|
|
|
30798
30805
|
"manage_binding"
|
|
30799
30806
|
],
|
|
30800
30807
|
subAgents: ["document-parser-benchmark"],
|
|
30801
|
-
internalSubAgents: [agentReviewerConfig],
|
|
30802
30808
|
middleware: [
|
|
30803
30809
|
{
|
|
30804
30810
|
id: "filesystem",
|
|
@@ -30883,9 +30889,96 @@ var agentArchitectConfig = {
|
|
|
30883
30889
|
]
|
|
30884
30890
|
};
|
|
30885
30891
|
|
|
30886
|
-
// src/agent_lattice/
|
|
30892
|
+
// src/agent_lattice/agentReviewerConfig.ts
|
|
30887
30893
|
var import_protocols21 = require("@axiom-lattice/protocols");
|
|
30888
30894
|
|
|
30895
|
+
// src/agent_lattice/agentReviewerPrompt.ts
|
|
30896
|
+
var AGENT_REVIEWER_PROMPT = `# Agent Reviewer
|
|
30897
|
+
|
|
30898
|
+
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.
|
|
30899
|
+
|
|
30900
|
+
## Your Tools
|
|
30901
|
+
|
|
30902
|
+
- **get_agent** \u2014 Fetch an agent's full configuration
|
|
30903
|
+
- **list_agents** \u2014 List all agents in the workspace
|
|
30904
|
+
- **list_tools** \u2014 List all available tools that can be assigned to agents
|
|
30905
|
+
- **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.
|
|
30906
|
+
|
|
30907
|
+
## Your Workflow
|
|
30908
|
+
|
|
30909
|
+
### When asked to review an agent:
|
|
30910
|
+
|
|
30911
|
+
1. Call **get_agent** to fetch the agent's config
|
|
30912
|
+
2. Review the configuration for:
|
|
30913
|
+
- **Completeness** \u2014 Are name, description, prompt present? Is the prompt clear and actionable?
|
|
30914
|
+
- **Tool validity** \u2014 Do the referenced tools exist? Call **list_tools** to verify.
|
|
30915
|
+
- **Middleware correctness** \u2014 Is every middleware entry complete (id, type, name, description, enabled, config)?
|
|
30916
|
+
- **Sub-agent references** \u2014 Do referenced sub-agent IDs exist? Call **list_agents** to verify.
|
|
30917
|
+
- **Type consistency** \u2014 Does the agent type match its configuration shape? (e.g., PROCESSING must have edges, DEEP_AGENT may have subAgents)
|
|
30918
|
+
3. Report your findings clearly. For each issue, state:
|
|
30919
|
+
- Severity (ERROR / WARNING / INFO)
|
|
30920
|
+
- What the problem is
|
|
30921
|
+
- How to fix it
|
|
30922
|
+
|
|
30923
|
+
### When asked to test an agent:
|
|
30924
|
+
|
|
30925
|
+
1. Call **get_agent** to understand the agent's purpose and expected behavior
|
|
30926
|
+
2. Craft a realistic test message that exercises the agent's core responsibility \u2014 what would a real user say?
|
|
30927
|
+
3. Call **invoke_agent(id, message)** to send the test message
|
|
30928
|
+
4. Analyze the response:
|
|
30929
|
+
- **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.
|
|
30930
|
+
- **Otherwise, result.messages contains the agent's output**: The agent completed without interruption. Check:
|
|
30931
|
+
- Did the agent understand the request?
|
|
30932
|
+
- Was the response relevant and accurate?
|
|
30933
|
+
- Did the agent use the right tools?
|
|
30934
|
+
- Were there any errors or unexpected behaviors?
|
|
30935
|
+
- **If result.error is present**: The invocation itself failed (agent not found, compilation error, etc.). Report the error clearly.
|
|
30936
|
+
5. Report your findings with the agent's actual response
|
|
30937
|
+
|
|
30938
|
+
### When results are wrong:
|
|
30939
|
+
|
|
30940
|
+
If the agent's response is incorrect or unexpected:
|
|
30941
|
+
1. Point out specifically what went wrong
|
|
30942
|
+
2. Suggest what might need to change in the prompt or middleware config
|
|
30943
|
+
3. Offer to re-test after fixes are applied
|
|
30944
|
+
|
|
30945
|
+
## Important Rules
|
|
30946
|
+
|
|
30947
|
+
- **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.
|
|
30948
|
+
- **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."
|
|
30949
|
+
- **One agent at a time.** Focus on one agent per review or test request. Don't try to review multiple agents simultaneously.
|
|
30950
|
+
- **Be concise but thorough.** Cover all the checks, but present findings clearly without fluff.
|
|
30951
|
+
`;
|
|
30952
|
+
|
|
30953
|
+
// src/agent_lattice/agentReviewerConfig.ts
|
|
30954
|
+
var AGENT_REVIEWER_KEY = "agent-reviewer";
|
|
30955
|
+
var agentReviewerConfig = {
|
|
30956
|
+
key: AGENT_REVIEWER_KEY,
|
|
30957
|
+
name: "Agent Reviewer",
|
|
30958
|
+
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.",
|
|
30959
|
+
type: import_protocols21.AgentType.REACT,
|
|
30960
|
+
prompt: AGENT_REVIEWER_PROMPT,
|
|
30961
|
+
tools: [
|
|
30962
|
+
"invoke_agent",
|
|
30963
|
+
"get_agent",
|
|
30964
|
+
"list_agents",
|
|
30965
|
+
"list_tools"
|
|
30966
|
+
],
|
|
30967
|
+
middleware: [
|
|
30968
|
+
{
|
|
30969
|
+
id: "widget",
|
|
30970
|
+
type: "widget",
|
|
30971
|
+
name: "Widget",
|
|
30972
|
+
description: "Render interactive HTML widgets and SVG diagrams",
|
|
30973
|
+
enabled: true,
|
|
30974
|
+
config: {}
|
|
30975
|
+
}
|
|
30976
|
+
]
|
|
30977
|
+
};
|
|
30978
|
+
|
|
30979
|
+
// src/agent_lattice/roomCoordinatorConfig.ts
|
|
30980
|
+
var import_protocols22 = require("@axiom-lattice/protocols");
|
|
30981
|
+
|
|
30889
30982
|
// src/agent_lattice/roomCoordinatorPrompt.ts
|
|
30890
30983
|
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
30984
|
|
|
@@ -30895,7 +30988,7 @@ var roomCoordinatorConfig = {
|
|
|
30895
30988
|
key: ROOM_COORDINATOR_KEY,
|
|
30896
30989
|
name: "Room Coordinator",
|
|
30897
30990
|
description: "Manages project room conversations: replies when no bot is mentioned, coordinates room members, and organizes project work.",
|
|
30898
|
-
type:
|
|
30991
|
+
type: import_protocols22.AgentType.DEEP_AGENT,
|
|
30899
30992
|
prompt: ROOM_COORDINATOR_PROMPT,
|
|
30900
30993
|
tools: [],
|
|
30901
30994
|
middleware: [
|
|
@@ -31530,17 +31623,6 @@ var getAgentClient = (tenantId2, key5, options) => agentLatticeManager.initializ
|
|
|
31530
31623
|
var getAgentClientAsync = async (tenantId2, key5, options) => agentLatticeManager.initializeClientAsync(tenantId2, key5, options);
|
|
31531
31624
|
var createAgentClientFromAgentLattice = async (agentLattice, options) => await agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
|
|
31532
31625
|
|
|
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
31626
|
// src/index.ts
|
|
31545
31627
|
init_memory_lattice();
|
|
31546
31628
|
|
|
@@ -31639,7 +31721,7 @@ var getVectorStoreClient = (key5) => vectorStoreLatticeManager.getVectorStoreCli
|
|
|
31639
31721
|
|
|
31640
31722
|
// src/logger_lattice/LoggerLatticeManager.ts
|
|
31641
31723
|
init_BaseLatticeManager();
|
|
31642
|
-
var
|
|
31724
|
+
var import_protocols23 = require("@axiom-lattice/protocols");
|
|
31643
31725
|
|
|
31644
31726
|
// src/logger_lattice/PinoLoggerClient.ts
|
|
31645
31727
|
var import_pino = __toESM(require("pino"));
|
|
@@ -31861,11 +31943,11 @@ var LoggerLatticeManager = class _LoggerLatticeManager extends BaseLatticeManage
|
|
|
31861
31943
|
if (client) {
|
|
31862
31944
|
loggerClient = client;
|
|
31863
31945
|
} else {
|
|
31864
|
-
if (config.type ===
|
|
31946
|
+
if (config.type === import_protocols23.LoggerType.PINO) {
|
|
31865
31947
|
loggerClient = new PinoLoggerClient(config);
|
|
31866
|
-
} else if (config.type ===
|
|
31948
|
+
} else if (config.type === import_protocols23.LoggerType.CONSOLE) {
|
|
31867
31949
|
loggerClient = new ConsoleLoggerClient(config);
|
|
31868
|
-
} else if (config.type ===
|
|
31950
|
+
} else if (config.type === import_protocols23.LoggerType.CUSTOM) {
|
|
31869
31951
|
throw new Error(
|
|
31870
31952
|
`Custom logger client must be provided. Please pass the client to registerLattice.`
|
|
31871
31953
|
);
|
|
@@ -32945,15 +33027,15 @@ var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
|
|
|
32945
33027
|
const metaByName = new Map(metaList.map((m) => [m.name, m.meta]));
|
|
32946
33028
|
this.unregisterServerTools(tenantId2, serverKey);
|
|
32947
33029
|
const keys = [];
|
|
32948
|
-
for (const
|
|
32949
|
-
if (rt.selectedTools && !rt.selectedTools.includes(
|
|
32950
|
-
const meta = metaByName.get(
|
|
33030
|
+
for (const tool68 of tools) {
|
|
33031
|
+
if (rt.selectedTools && !rt.selectedTools.includes(tool68.name)) continue;
|
|
33032
|
+
const meta = metaByName.get(tool68.name);
|
|
32951
33033
|
const rawVisibility = meta?.ui?.visibility;
|
|
32952
33034
|
const visibility = Array.isArray(rawVisibility) ? rawVisibility : typeof rawVisibility === "string" ? [rawVisibility] : void 0;
|
|
32953
33035
|
if (visibility && !visibility.includes("model")) continue;
|
|
32954
33036
|
const ref = extractAppsRef(meta, serverKey);
|
|
32955
|
-
const registered = ref ? wrapMcpToolWithUi(
|
|
32956
|
-
const toolKey = _McpLatticeManager.buildToolKey(serverKey,
|
|
33037
|
+
const registered = ref ? wrapMcpToolWithUi(tool68, ref) : tool68;
|
|
33038
|
+
const toolKey = _McpLatticeManager.buildToolKey(serverKey, tool68.name);
|
|
32957
33039
|
try {
|
|
32958
33040
|
toolLatticeManager.registerExistingToolWithTenant(tenantId2, toolKey, registered);
|
|
32959
33041
|
keys.push(toolKey);
|
|
@@ -36127,7 +36209,7 @@ var LatticeEvalSuite = class {
|
|
|
36127
36209
|
};
|
|
36128
36210
|
|
|
36129
36211
|
// src/eval_lattice/LatticeEvalProject.ts
|
|
36130
|
-
var
|
|
36212
|
+
var import_protocols24 = require("@axiom-lattice/protocols");
|
|
36131
36213
|
var import_messages8 = require("@langchain/core/messages");
|
|
36132
36214
|
var import_uuid11 = require("uuid");
|
|
36133
36215
|
var DEFAULT_CALIBRATION_PROBES = [
|
|
@@ -36183,7 +36265,7 @@ var LatticeEvalProject = class {
|
|
|
36183
36265
|
key: this.judgeAgentKey,
|
|
36184
36266
|
name: `Judge agent for ${this.project.projectName}`,
|
|
36185
36267
|
description: "Judge agent for evaluating Lattice test cases",
|
|
36186
|
-
type:
|
|
36268
|
+
type: import_protocols24.AgentType.REACT,
|
|
36187
36269
|
prompt: "",
|
|
36188
36270
|
modelKey: judgeModelKey
|
|
36189
36271
|
};
|
|
@@ -36409,7 +36491,7 @@ function getMenuRegistry() {
|
|
|
36409
36491
|
}
|
|
36410
36492
|
|
|
36411
36493
|
// src/services/ProjectTaskReassignmentAuthorization.ts
|
|
36412
|
-
var
|
|
36494
|
+
var import_protocols25 = require("@axiom-lattice/protocols");
|
|
36413
36495
|
var issued = /* @__PURE__ */ new WeakMap();
|
|
36414
36496
|
function createProjectTaskReassignmentAuthorizer(policy, threadValidator) {
|
|
36415
36497
|
return {
|
|
@@ -36442,7 +36524,7 @@ function inspectProjectTaskReassignmentAuthorization(authorization) {
|
|
|
36442
36524
|
return snapshot ? { ...snapshot } : void 0;
|
|
36443
36525
|
}
|
|
36444
36526
|
function snapshotInput(input) {
|
|
36445
|
-
const row = (0,
|
|
36527
|
+
const row = (0, import_protocols25.snapshotExactRecord)(input, [
|
|
36446
36528
|
"tenantId",
|
|
36447
36529
|
"workspaceId",
|
|
36448
36530
|
"projectId",
|
|
@@ -36485,7 +36567,7 @@ function snapshotInput(input) {
|
|
|
36485
36567
|
}
|
|
36486
36568
|
|
|
36487
36569
|
// src/services/TaskLifecycleNotifier.ts
|
|
36488
|
-
var
|
|
36570
|
+
var import_protocols26 = require("@axiom-lattice/protocols");
|
|
36489
36571
|
var TaskLifecycleNotifier = class {
|
|
36490
36572
|
constructor() {
|
|
36491
36573
|
this.listeners = /* @__PURE__ */ new Set();
|
|
@@ -36529,7 +36611,7 @@ var TaskLifecycleNotifier = class {
|
|
|
36529
36611
|
};
|
|
36530
36612
|
var taskLifecycleNotifier = new TaskLifecycleNotifier();
|
|
36531
36613
|
function snapshotNotification(value) {
|
|
36532
|
-
const row = (0,
|
|
36614
|
+
const row = (0, import_protocols26.snapshotExactRecord)(value, [
|
|
36533
36615
|
"tenantId",
|
|
36534
36616
|
"workspaceId",
|
|
36535
36617
|
"projectId",
|
|
@@ -36561,7 +36643,7 @@ function nonempty(value) {
|
|
|
36561
36643
|
}
|
|
36562
36644
|
|
|
36563
36645
|
// src/services/ProjectTaskAdmissionNotifier.ts
|
|
36564
|
-
var
|
|
36646
|
+
var import_protocols27 = require("@axiom-lattice/protocols");
|
|
36565
36647
|
var ProjectTaskAdmissionNotifier = class {
|
|
36566
36648
|
/**
|
|
36567
36649
|
* Creates a bounded Project task admission notifier.
|
|
@@ -36634,7 +36716,7 @@ var ProjectTaskAdmissionNotifier = class {
|
|
|
36634
36716
|
};
|
|
36635
36717
|
var projectTaskAdmissionNotifier = new ProjectTaskAdmissionNotifier();
|
|
36636
36718
|
function snapshotNotification2(value) {
|
|
36637
|
-
const row = (0,
|
|
36719
|
+
const row = (0, import_protocols27.snapshotExactRecord)(value, [
|
|
36638
36720
|
"tenantId",
|
|
36639
36721
|
"workspaceId",
|
|
36640
36722
|
"projectId",
|
|
@@ -36664,9 +36746,9 @@ function canonicalTimestamp(value) {
|
|
|
36664
36746
|
}
|
|
36665
36747
|
|
|
36666
36748
|
// src/services/ProjectMutationMutex.ts
|
|
36667
|
-
var
|
|
36749
|
+
var import_protocols28 = require("@axiom-lattice/protocols");
|
|
36668
36750
|
function projectKey(scope) {
|
|
36669
|
-
const row = (0,
|
|
36751
|
+
const row = (0, import_protocols28.snapshotExactRecord)(scope, ["tenantId", "projectId"]);
|
|
36670
36752
|
if (!row || typeof row.tenantId !== "string" || !row.tenantId || row.tenantId.includes("\0") || typeof row.projectId !== "string" || !row.projectId || row.projectId.includes("\0")) {
|
|
36671
36753
|
throw new Error("Invalid Project mutation scope");
|
|
36672
36754
|
}
|
|
@@ -36741,7 +36823,7 @@ function createTrustedAgentMessageDispatcher(resolve4) {
|
|
|
36741
36823
|
|
|
36742
36824
|
// src/services/RoomAgentMessageService.ts
|
|
36743
36825
|
var import_crypto8 = require("crypto");
|
|
36744
|
-
var
|
|
36826
|
+
var import_protocols29 = require("@axiom-lattice/protocols");
|
|
36745
36827
|
var INPUT_KEYS = [
|
|
36746
36828
|
"tenantId",
|
|
36747
36829
|
"workspaceId",
|
|
@@ -36861,7 +36943,7 @@ var RoomAgentMessageService = class {
|
|
|
36861
36943
|
function exactValues(value, required, optional = []) {
|
|
36862
36944
|
try {
|
|
36863
36945
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
36864
|
-
return (0,
|
|
36946
|
+
return (0, import_protocols29.snapshotExactRecord)(value, required, optional);
|
|
36865
36947
|
} catch {
|
|
36866
36948
|
return void 0;
|
|
36867
36949
|
}
|
|
@@ -36913,7 +36995,7 @@ function sourceOriginMatches(author, source) {
|
|
|
36913
36995
|
return false;
|
|
36914
36996
|
}
|
|
36915
36997
|
function snapshotMentions(value) {
|
|
36916
|
-
const rows = (0,
|
|
36998
|
+
const rows = (0, import_protocols29.snapshotExactArray)(value);
|
|
36917
36999
|
if (!rows) return void 0;
|
|
36918
37000
|
const mentions = [];
|
|
36919
37001
|
for (const row of rows) {
|
|
@@ -36941,7 +37023,7 @@ function snapshotCanonical(value, expected) {
|
|
|
36941
37023
|
const author = exactValues(values?.author, ["type", "membershipId", "assistantId"]);
|
|
36942
37024
|
const content = exactValues(values?.content, ["type", "text"]);
|
|
36943
37025
|
const createdAt = date(values?.createdAt);
|
|
36944
|
-
if (!values || !createdAt || typeof values.id !== "string" || values.id.length === 0 || (0,
|
|
37026
|
+
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
37027
|
return {
|
|
36946
37028
|
id: values.id,
|
|
36947
37029
|
tenantId: expected.tenantId,
|
|
@@ -36960,7 +37042,7 @@ function snapshotCanonical(value, expected) {
|
|
|
36960
37042
|
}
|
|
36961
37043
|
|
|
36962
37044
|
// src/services/ProjectTaskOwnerPolicy.ts
|
|
36963
|
-
var
|
|
37045
|
+
var import_protocols30 = require("@axiom-lattice/protocols");
|
|
36964
37046
|
var MEMBERSHIP_REQUIRED_KEYS = [
|
|
36965
37047
|
"id",
|
|
36966
37048
|
"tenantId",
|
|
@@ -37069,7 +37151,7 @@ function sameRosterScope(membership, scope) {
|
|
|
37069
37151
|
return membership.tenantId === scope.tenantId && membership.workspaceId === scope.workspaceId && membership.projectId === scope.projectId && membership.roomId === scope.roomId;
|
|
37070
37152
|
}
|
|
37071
37153
|
function snapshotScope(value, keys) {
|
|
37072
|
-
const values = (0,
|
|
37154
|
+
const values = (0, import_protocols30.snapshotExactRecord)(value, keys);
|
|
37073
37155
|
if (!values || keys.some((key5) => !isNonemptyString(values[key5]))) return void 0;
|
|
37074
37156
|
return values;
|
|
37075
37157
|
}
|
|
@@ -37081,7 +37163,7 @@ function projectScope(scope, keys) {
|
|
|
37081
37163
|
function snapshotMembership2(value) {
|
|
37082
37164
|
try {
|
|
37083
37165
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
37084
|
-
const values = (0,
|
|
37166
|
+
const values = (0, import_protocols30.snapshotExactRecord)(value, MEMBERSHIP_REQUIRED_KEYS, ["responsibility"]);
|
|
37085
37167
|
if (!values) return void 0;
|
|
37086
37168
|
const joinedAt = snapshotDate(values.joinedAt);
|
|
37087
37169
|
const updatedAt = snapshotDate(values.updatedAt);
|
|
@@ -37120,7 +37202,7 @@ function snapshotDate(value) {
|
|
|
37120
37202
|
|
|
37121
37203
|
// src/services/TaskLifecycleService.ts
|
|
37122
37204
|
var import_node_crypto8 = require("crypto");
|
|
37123
|
-
var
|
|
37205
|
+
var import_protocols31 = require("@axiom-lattice/protocols");
|
|
37124
37206
|
|
|
37125
37207
|
// src/middlewares/taskBelief.ts
|
|
37126
37208
|
var import_node_crypto7 = require("crypto");
|
|
@@ -37191,7 +37273,7 @@ async function applyBeliefImpacts(taskStore, owner, impacts) {
|
|
|
37191
37273
|
if (impacts.length === 0) return { description: owner.description ?? "" };
|
|
37192
37274
|
let current = owner;
|
|
37193
37275
|
for (let attempt = 0; attempt < BELIEF_OWNER_WRITE_ATTEMPTS; attempt += 1) {
|
|
37194
|
-
const parsed = (0,
|
|
37276
|
+
const parsed = (0, import_protocols31.parseTaskBeliefState)(current.description ?? "");
|
|
37195
37277
|
const existingTable = parsed.success;
|
|
37196
37278
|
if (!existingTable && parsed.code !== "MISSING_BELIEF_STATE") {
|
|
37197
37279
|
return { description: current.description ?? "", task: current };
|
|
@@ -37208,7 +37290,7 @@ async function applyBeliefImpacts(taskStore, owner, impacts) {
|
|
|
37208
37290
|
changed = true;
|
|
37209
37291
|
}
|
|
37210
37292
|
if (!changed) return { description: current.description ?? "", task: current };
|
|
37211
|
-
const description = (0,
|
|
37293
|
+
const description = (0, import_protocols31.replaceTaskBeliefState)(current.description ?? "", { entries });
|
|
37212
37294
|
try {
|
|
37213
37295
|
const updated = await taskStore.updateIfStatusAndUpdatedAt(
|
|
37214
37296
|
current.tenantId,
|
|
@@ -37233,8 +37315,8 @@ async function applyBeliefImpacts(taskStore, owner, impacts) {
|
|
|
37233
37315
|
return { description: current.description ?? "", task: current };
|
|
37234
37316
|
}
|
|
37235
37317
|
function parseExternalDependency(value) {
|
|
37236
|
-
const row = (0,
|
|
37237
|
-
const ids = (0,
|
|
37318
|
+
const row = (0, import_protocols31.snapshotExactRecord)(value, ["type", "summary", "requestedAt", "dependencyTaskIds"]);
|
|
37319
|
+
const ids = (0, import_protocols31.snapshotExactArray)(row?.dependencyTaskIds);
|
|
37238
37320
|
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
37321
|
const trimmed = ids.map((id) => id.trim());
|
|
37240
37322
|
if (new Set(trimmed).size !== trimmed.length) return void 0;
|
|
@@ -37321,7 +37403,7 @@ function beliefStateOf(value) {
|
|
|
37321
37403
|
function sameBeliefOwner(left, right) {
|
|
37322
37404
|
const leftIdentity = { ...left, beliefState: void 0 };
|
|
37323
37405
|
const rightIdentity = { ...right, beliefState: void 0 };
|
|
37324
|
-
return canonicalJson(leftIdentity) === canonicalJson(rightIdentity) && (0,
|
|
37406
|
+
return canonicalJson(leftIdentity) === canonicalJson(rightIdentity) && (0, import_protocols31.taskBeliefStatesEqual)(left.beliefState, right.beliefState);
|
|
37325
37407
|
}
|
|
37326
37408
|
function sameBeliefOwnerIdentity(left, right) {
|
|
37327
37409
|
return canonicalJson({ ...left, beliefState: void 0 }) === canonicalJson({ ...right, beliefState: void 0 });
|
|
@@ -37469,7 +37551,7 @@ function changedBeliefKeys(left, right) {
|
|
|
37469
37551
|
return [...keys].filter((key5) => {
|
|
37470
37552
|
const oldEntry = leftByKey.get(key5);
|
|
37471
37553
|
const newEntry = rightByKey.get(key5);
|
|
37472
|
-
return !oldEntry || !newEntry || !(0,
|
|
37554
|
+
return !oldEntry || !newEntry || !(0, import_protocols31.taskBeliefStatesEqual)(
|
|
37473
37555
|
{ entries: [oldEntry] },
|
|
37474
37556
|
{ entries: [newEntry] }
|
|
37475
37557
|
);
|
|
@@ -38490,10 +38572,10 @@ var TaskLifecycleService = class {
|
|
|
38490
38572
|
const description = preserveTargetContract(existing.description ?? "", input.description);
|
|
38491
38573
|
const pending = existing.context?.belief_reconciliation_audit;
|
|
38492
38574
|
const pendingAudit = pending && typeof pending === "object" ? pending : void 0;
|
|
38493
|
-
const oldBelief = (0,
|
|
38494
|
-
const newBelief = (0,
|
|
38575
|
+
const oldBelief = (0, import_protocols31.parseTaskBeliefState)(existing.description ?? "");
|
|
38576
|
+
const newBelief = (0, import_protocols31.parseTaskBeliefState)(description);
|
|
38495
38577
|
if (!newBelief.success) return failure2("INVALID_BELIEF_TABLE", newBelief.message);
|
|
38496
|
-
if (!pendingAudit && description === (existing.description ?? "") && oldBelief.success && (0,
|
|
38578
|
+
if (!pendingAudit && description === (existing.description ?? "") && oldBelief.success && (0, import_protocols31.taskBeliefStatesEqual)(oldBelief.state, newBelief.state)) {
|
|
38497
38579
|
return { success: true, task: existing, mutated: false };
|
|
38498
38580
|
}
|
|
38499
38581
|
const canonicalNew = newBelief.state.entries;
|
|
@@ -38624,7 +38706,7 @@ var TaskLifecycleService = class {
|
|
|
38624
38706
|
}
|
|
38625
38707
|
beliefOwnerSnapshot(task, parent) {
|
|
38626
38708
|
const owner = parent?.ownerType === "agent" ? parent : task;
|
|
38627
|
-
const parsed = (0,
|
|
38709
|
+
const parsed = (0, import_protocols31.parseTaskBeliefState)(owner.description ?? "");
|
|
38628
38710
|
const beliefState = parsed.success ? parsed.state : { entries: [] };
|
|
38629
38711
|
if (parent?.ownerType === "agent") {
|
|
38630
38712
|
return {
|
|
@@ -39396,7 +39478,7 @@ function createTaskLifecycleService(deps) {
|
|
|
39396
39478
|
// src/services/TaskExecutionService.ts
|
|
39397
39479
|
var import_node_crypto9 = require("crypto");
|
|
39398
39480
|
var import_node_util3 = require("util");
|
|
39399
|
-
var
|
|
39481
|
+
var import_protocols32 = require("@axiom-lattice/protocols");
|
|
39400
39482
|
|
|
39401
39483
|
// src/services/taskErrorMessage.ts
|
|
39402
39484
|
var MAX_EXECUTION_ERROR_MESSAGE_LENGTH = 1024;
|
|
@@ -39538,6 +39620,33 @@ function createTaskRunBridge(deps) {
|
|
|
39538
39620
|
transitioned: true
|
|
39539
39621
|
};
|
|
39540
39622
|
}
|
|
39623
|
+
if (task.status === "interrupted" || task.status === "failed") {
|
|
39624
|
+
if (task.ownerType !== "agent") {
|
|
39625
|
+
return {
|
|
39626
|
+
success: false,
|
|
39627
|
+
code: "AGENT_TASK_REQUIRED",
|
|
39628
|
+
error: "Lifecycle transitions only support agent tasks."
|
|
39629
|
+
};
|
|
39630
|
+
}
|
|
39631
|
+
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 });
|
|
39632
|
+
if (!result.success) {
|
|
39633
|
+
return {
|
|
39634
|
+
success: false,
|
|
39635
|
+
code: result.code,
|
|
39636
|
+
error: result.error,
|
|
39637
|
+
...result.hint !== void 0 ? { hint: result.hint } : {},
|
|
39638
|
+
...result.retryable !== void 0 ? { retryable: result.retryable } : {},
|
|
39639
|
+
...result.warnings !== void 0 ? { warnings: result.warnings } : {}
|
|
39640
|
+
};
|
|
39641
|
+
}
|
|
39642
|
+
return {
|
|
39643
|
+
success: true,
|
|
39644
|
+
task: result.task,
|
|
39645
|
+
warnings: result.warnings ?? [],
|
|
39646
|
+
mutated: true,
|
|
39647
|
+
transitioned: true
|
|
39648
|
+
};
|
|
39649
|
+
}
|
|
39541
39650
|
return { success: true, task, warnings, mutated: false, transitioned: false };
|
|
39542
39651
|
},
|
|
39543
39652
|
async settleRun(input) {
|
|
@@ -39691,48 +39800,18 @@ async function prepareTaskDispatch(deps, input) {
|
|
|
39691
39800
|
}
|
|
39692
39801
|
};
|
|
39693
39802
|
}
|
|
39694
|
-
if (task.status !== "pending") {
|
|
39803
|
+
if (task.status !== "pending" && task.status !== "interrupted" && task.status !== "failed") {
|
|
39695
39804
|
return {
|
|
39696
39805
|
kind: "failure",
|
|
39697
39806
|
failure: {
|
|
39698
39807
|
success: false,
|
|
39699
39808
|
code: "TASK_NOT_DISPATCHABLE",
|
|
39700
|
-
error: "Only a `pending` task can be dispatched.",
|
|
39701
|
-
hint: `This task is '${task.status}'.
|
|
39809
|
+
error: "Only a `pending`, `interrupted`, or `failed` task can be dispatched.",
|
|
39810
|
+
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
39811
|
taskId: task.id
|
|
39703
39812
|
}
|
|
39704
39813
|
};
|
|
39705
39814
|
}
|
|
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
39815
|
const managedAuthority = executionAuthorityRegistry.resolve(task);
|
|
39737
39816
|
if (managedAuthority) {
|
|
39738
39817
|
if (managedAuthority.onManagedStart) {
|
|
@@ -40144,6 +40223,7 @@ function toJsonSafeValue(value) {
|
|
|
40144
40223
|
}
|
|
40145
40224
|
|
|
40146
40225
|
// src/services/TaskExecutionService.ts
|
|
40226
|
+
var import_langgraph14 = require("@langchain/langgraph");
|
|
40147
40227
|
function persistedExecutionObservation(item, attempted) {
|
|
40148
40228
|
const detail = item.detail;
|
|
40149
40229
|
const persistedObservation = toJsonSafeValue(detail?.observation);
|
|
@@ -40190,9 +40270,10 @@ function createTaskExecutionService(deps) {
|
|
|
40190
40270
|
const run = async (plan) => {
|
|
40191
40271
|
const { tenantId: tenantId2, agentId, actor, parent, completedDependencies } = plan;
|
|
40192
40272
|
let task = plan.task;
|
|
40273
|
+
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
40274
|
let threadId;
|
|
40194
40275
|
try {
|
|
40195
|
-
threadId = (deps.createThreadId ?? import_node_crypto9.randomUUID)();
|
|
40276
|
+
threadId = persistedThreadId ?? (deps.createThreadId ?? import_node_crypto9.randomUUID)();
|
|
40196
40277
|
} catch (error) {
|
|
40197
40278
|
return {
|
|
40198
40279
|
success: false,
|
|
@@ -40203,7 +40284,7 @@ function createTaskExecutionService(deps) {
|
|
|
40203
40284
|
};
|
|
40204
40285
|
}
|
|
40205
40286
|
const eventKey = `execution-result:${threadId}`;
|
|
40206
|
-
if (!(0,
|
|
40287
|
+
if (!(0, import_protocols32.isExecutionResultEventKey)(eventKey)) {
|
|
40207
40288
|
return {
|
|
40208
40289
|
success: false,
|
|
40209
40290
|
code: "INVALID_EXECUTION_RESULT_ID",
|
|
@@ -40231,12 +40312,12 @@ function createTaskExecutionService(deps) {
|
|
|
40231
40312
|
task = transfer.task;
|
|
40232
40313
|
}
|
|
40233
40314
|
const warnings = [];
|
|
40234
|
-
if (task.status === "pending") {
|
|
40315
|
+
if (task.status === "pending" || task.status === "interrupted" || task.status === "failed") {
|
|
40235
40316
|
const begun = await bridge.beginRun({
|
|
40236
40317
|
tenantId: tenantId2,
|
|
40237
40318
|
task,
|
|
40238
40319
|
actor,
|
|
40239
|
-
threadId
|
|
40320
|
+
threadId
|
|
40240
40321
|
});
|
|
40241
40322
|
if (!begun.success) return { ...begun, taskId: task.id };
|
|
40242
40323
|
if (!begun.mutated || !begun.transitioned) {
|
|
@@ -40265,6 +40346,19 @@ function createTaskExecutionService(deps) {
|
|
|
40265
40346
|
try {
|
|
40266
40347
|
observation = toJsonSafeValue(await deps.invokeAgent(invocation));
|
|
40267
40348
|
} catch (error) {
|
|
40349
|
+
if (error instanceof import_langgraph14.GraphInterrupt) {
|
|
40350
|
+
try {
|
|
40351
|
+
await bridge.settleRun({
|
|
40352
|
+
tenantId: tenantId2,
|
|
40353
|
+
task,
|
|
40354
|
+
actor,
|
|
40355
|
+
threadId,
|
|
40356
|
+
outcome: { kind: "interrupted", summary: "Awaiting user input" }
|
|
40357
|
+
});
|
|
40358
|
+
} catch {
|
|
40359
|
+
}
|
|
40360
|
+
throw error;
|
|
40361
|
+
}
|
|
40268
40362
|
const normalizationError = error instanceof JsonSafeValueError;
|
|
40269
40363
|
const message = normalizationError ? `${error.code}: ${error.message}` : errorMessage(error);
|
|
40270
40364
|
const failureCode = normalizationError ? "EXECUTION_RESULT_NORMALIZATION_FAILED" : "AGENT_INVOCATION_FAILED";
|
|
@@ -40395,6 +40489,76 @@ function createTaskExecutionService(deps) {
|
|
|
40395
40489
|
};
|
|
40396
40490
|
}
|
|
40397
40491
|
|
|
40492
|
+
// src/services/TaskRunRegistry.ts
|
|
40493
|
+
var TaskRunRegistry = class {
|
|
40494
|
+
constructor() {
|
|
40495
|
+
this.live = /* @__PURE__ */ new Set();
|
|
40496
|
+
}
|
|
40497
|
+
/** Marks a task as currently held by a live run. */
|
|
40498
|
+
register(taskId) {
|
|
40499
|
+
this.live.add(taskId);
|
|
40500
|
+
}
|
|
40501
|
+
/** Removes a task once its run has ended. */
|
|
40502
|
+
unregister(taskId) {
|
|
40503
|
+
this.live.delete(taskId);
|
|
40504
|
+
}
|
|
40505
|
+
/** Reports whether a task is currently held by a live run. */
|
|
40506
|
+
isLive(taskId) {
|
|
40507
|
+
return this.live.has(taskId);
|
|
40508
|
+
}
|
|
40509
|
+
/** Returns a snapshot of the live task ids (diagnostics/tests). */
|
|
40510
|
+
snapshot() {
|
|
40511
|
+
return [...this.live];
|
|
40512
|
+
}
|
|
40513
|
+
/** Clears all live entries (tests / process teardown). */
|
|
40514
|
+
clear() {
|
|
40515
|
+
this.live.clear();
|
|
40516
|
+
}
|
|
40517
|
+
};
|
|
40518
|
+
var taskRunRegistry = new TaskRunRegistry();
|
|
40519
|
+
async function reconcileStaleTaskRuns(input) {
|
|
40520
|
+
const registry4 = input.registry ?? taskRunRegistry;
|
|
40521
|
+
const converged = [];
|
|
40522
|
+
for (const task of input.tasks) {
|
|
40523
|
+
if (task.status !== "in_progress" || registry4.isLive(task.id)) continue;
|
|
40524
|
+
const result = await input.lifecycle.interruptTask({
|
|
40525
|
+
tenantId: task.tenantId,
|
|
40526
|
+
taskId: task.id,
|
|
40527
|
+
actor: input.actor,
|
|
40528
|
+
type: "missing_input",
|
|
40529
|
+
summary: "Run is no longer executing this task (no_executor)"
|
|
40530
|
+
});
|
|
40531
|
+
if (result.success) converged.push(task.id);
|
|
40532
|
+
}
|
|
40533
|
+
return { converged };
|
|
40534
|
+
}
|
|
40535
|
+
async function reconcileTenantTaskRuns(input) {
|
|
40536
|
+
const tasks = await input.taskStore.list({ tenantId: input.tenantId, status: "in_progress" });
|
|
40537
|
+
const candidates = input.include ? tasks.filter(input.include) : tasks;
|
|
40538
|
+
return reconcileStaleTaskRuns({
|
|
40539
|
+
tasks: candidates,
|
|
40540
|
+
actor: input.actor,
|
|
40541
|
+
lifecycle: input.lifecycle,
|
|
40542
|
+
...input.registry ? { registry: input.registry } : {}
|
|
40543
|
+
});
|
|
40544
|
+
}
|
|
40545
|
+
async function reconcileAllTenantTaskRuns(input) {
|
|
40546
|
+
const tenants = await input.tenantStore.listTenants();
|
|
40547
|
+
const converged = [];
|
|
40548
|
+
for (const tenant of tenants) {
|
|
40549
|
+
const result = await reconcileTenantTaskRuns({
|
|
40550
|
+
tenantId: tenant.id,
|
|
40551
|
+
actor: input.actor,
|
|
40552
|
+
taskStore: input.taskStore,
|
|
40553
|
+
lifecycle: input.lifecycle,
|
|
40554
|
+
...input.registry ? { registry: input.registry } : {},
|
|
40555
|
+
...input.include ? { include: input.include } : {}
|
|
40556
|
+
});
|
|
40557
|
+
converged.push(...result.converged);
|
|
40558
|
+
}
|
|
40559
|
+
return { converged };
|
|
40560
|
+
}
|
|
40561
|
+
|
|
40398
40562
|
// src/index.ts
|
|
40399
40563
|
var Protocols = __toESM(require("@axiom-lattice/protocols"));
|
|
40400
40564
|
|
|
@@ -40660,10 +40824,10 @@ var createLoadSkillContentTool = (pluginSkills, pluginSkillOwnersOrStaticSelecti
|
|
|
40660
40824
|
lockIdentity
|
|
40661
40825
|
);
|
|
40662
40826
|
let result2 = pluginSkill.definition.content;
|
|
40663
|
-
const
|
|
40664
|
-
if (
|
|
40827
|
+
const resources2 = Object.entries(pluginSkill.definition.resources ?? {});
|
|
40828
|
+
if (resources2.length > 0) {
|
|
40665
40829
|
result2 += "\n\n---\n\n**Resources** (synced to the sandbox; use `read_file` to access):\n";
|
|
40666
|
-
for (const [resourcePath, resource] of
|
|
40830
|
+
for (const [resourcePath, resource] of resources2) {
|
|
40667
40831
|
result2 += `- ${resourcePath} (mime type: ${resource.mimeType ?? "not specified"})
|
|
40668
40832
|
`;
|
|
40669
40833
|
}
|
|
@@ -40690,10 +40854,10 @@ var createLoadSkillContentTool = (pluginSkills, pluginSkillOwnersOrStaticSelecti
|
|
|
40690
40854
|
`/root/.agents/skills/${input.skill_name}/resources`,
|
|
40691
40855
|
{ recursive: false }
|
|
40692
40856
|
);
|
|
40693
|
-
const
|
|
40694
|
-
if (
|
|
40857
|
+
const resources2 = resourcesResult.files.map((f) => f.path.split("/").pop()).filter(Boolean);
|
|
40858
|
+
if (resources2.length > 0) {
|
|
40695
40859
|
result += "\n\n---\n\n**Resources** (use `read_file` tool to access):\n";
|
|
40696
|
-
|
|
40860
|
+
resources2.forEach((r) => {
|
|
40697
40861
|
result += `- ${r}
|
|
40698
40862
|
`;
|
|
40699
40863
|
});
|
|
@@ -41015,1367 +41179,12 @@ var skillPlugin = {
|
|
|
41015
41179
|
})
|
|
41016
41180
|
};
|
|
41017
41181
|
|
|
41018
|
-
// src/middlewares/semanticMetricsMiddleware.ts
|
|
41019
|
-
var import_langchain70 = require("langchain");
|
|
41020
|
-
|
|
41021
|
-
// src/tool_lattice/semantic_metrics/metrics_datasource_tool.ts
|
|
41022
|
-
var import_zod55 = __toESM(require("zod"));
|
|
41023
|
-
var import_langchain67 = require("langchain");
|
|
41024
|
-
|
|
41025
|
-
// src/tool_lattice/semantic_metrics/types.ts
|
|
41026
|
-
function readToolRunConfig(exeConfig) {
|
|
41027
|
-
return exeConfig?.configurable?.runConfig;
|
|
41028
|
-
}
|
|
41029
|
-
function resolveDatasourceId(input, exeConfig) {
|
|
41030
|
-
const id = input.datasourceId ?? readToolRunConfig(exeConfig)?.metricsDataSource?.datasourceId;
|
|
41031
|
-
if (id === void 0 || id === null || id === "") {
|
|
41032
|
-
throw new Error("datasourceId is required (provide it or set runConfig.metricsDataSource.datasourceId)");
|
|
41033
|
-
}
|
|
41034
|
-
return Number(id);
|
|
41035
|
-
}
|
|
41036
|
-
function assertDatasourceSelected(scope, datasourceId) {
|
|
41037
|
-
if (scope.unrestricted) return;
|
|
41038
|
-
if (!scope.ids.includes(datasourceId)) {
|
|
41039
|
-
throw new Error(
|
|
41040
|
-
`DATASOURCE_NOT_SELECTED: datasource ${datasourceId} is not in the effective scope [${scope.ids.join(", ")}]`
|
|
41041
|
-
);
|
|
41042
|
-
}
|
|
41043
|
-
}
|
|
41044
|
-
function effectiveDatasourceScope(connectionScope) {
|
|
41045
|
-
return connectionScope.length > 0 ? { unrestricted: false, ids: [...connectionScope] } : { unrestricted: true, ids: [] };
|
|
41046
|
-
}
|
|
41047
|
-
var DDL_DML_KEYWORDS = [
|
|
41048
|
-
"insert",
|
|
41049
|
-
"update",
|
|
41050
|
-
"delete",
|
|
41051
|
-
"drop",
|
|
41052
|
-
"alter",
|
|
41053
|
-
"create",
|
|
41054
|
-
"truncate",
|
|
41055
|
-
"grant",
|
|
41056
|
-
"revoke",
|
|
41057
|
-
"merge",
|
|
41058
|
-
"replace",
|
|
41059
|
-
"upsert"
|
|
41060
|
-
];
|
|
41061
|
-
var DDL_DML_RE = new RegExp(`\\b(?:${DDL_DML_KEYWORDS.join("|")})\\b`, "i");
|
|
41062
|
-
var SELECT_INTO_RE = /\bselect\b[\s\S]*?\binto\b/i;
|
|
41063
|
-
function validateSql(sql) {
|
|
41064
|
-
const trimmed = sql.trim();
|
|
41065
|
-
if (!trimmed) {
|
|
41066
|
-
return { ok: false, reason: "SQL is empty" };
|
|
41067
|
-
}
|
|
41068
|
-
const withoutComments = trimmed.replace(/--[^\n]*/g, " ").replace(/\/\*[\s\S]*?\*\//g, " ");
|
|
41069
|
-
const statements = withoutComments.split(";").map((s) => s.trim()).filter(Boolean);
|
|
41070
|
-
if (statements.length > 1) {
|
|
41071
|
-
return { ok: false, reason: "Multiple statements are not allowed" };
|
|
41072
|
-
}
|
|
41073
|
-
const firstKeyword = withoutComments.trim().split(/\s+/)[0].toLowerCase();
|
|
41074
|
-
if (firstKeyword !== "select" && firstKeyword !== "with") {
|
|
41075
|
-
return { ok: false, reason: `Only SELECT or WITH queries are allowed (got "${firstKeyword}")` };
|
|
41076
|
-
}
|
|
41077
|
-
if (SELECT_INTO_RE.test(withoutComments)) {
|
|
41078
|
-
return { ok: false, reason: "SELECT INTO is not allowed (creates a table)" };
|
|
41079
|
-
}
|
|
41080
|
-
if (DDL_DML_RE.test(withoutComments)) {
|
|
41081
|
-
return { ok: false, reason: "Only read-only queries are allowed (DML/DDL detected)" };
|
|
41082
|
-
}
|
|
41083
|
-
return { ok: true };
|
|
41084
|
-
}
|
|
41085
|
-
|
|
41086
|
-
// src/tool_lattice/semantic_metrics/SemanticMetricsV2Client.ts
|
|
41087
|
-
var NO_CONNECTION_HINT = "No semantic-metrics connection is configured for this tenant. Add a connection of type 'semantic-metrics' for the tenant, then select it (connections) or enable connectAll in the agent's middleware config.";
|
|
41088
|
-
async function resolveMetricsClientFromSelector(selector, scope, connectionKey) {
|
|
41089
|
-
let resolved;
|
|
41090
|
-
try {
|
|
41091
|
-
resolved = await resolvePluginConnections(selector.connectionType, selector, scope);
|
|
41092
|
-
} catch (error) {
|
|
41093
|
-
if (error instanceof Error && error.message === "ConnectionStore not configured") {
|
|
41094
|
-
throw new Error(NO_CONNECTION_HINT);
|
|
41095
|
-
}
|
|
41096
|
-
throw error;
|
|
41097
|
-
}
|
|
41098
|
-
const available = resolved.map((c) => c.key).join(", ");
|
|
41099
|
-
if (resolved.length === 0) {
|
|
41100
|
-
throw new Error(NO_CONNECTION_HINT);
|
|
41101
|
-
}
|
|
41102
|
-
const key5 = connectionKey?.trim() || (resolved.length === 1 ? resolved[0].key : "");
|
|
41103
|
-
if (!key5) {
|
|
41104
|
-
throw new Error(
|
|
41105
|
-
`connectionKey is required. Available connections: ${available}`
|
|
41106
|
-
);
|
|
41107
|
-
}
|
|
41108
|
-
const entry = resolved.find((c) => c.key === key5);
|
|
41109
|
-
if (!entry) {
|
|
41110
|
-
throw new Error(`Connection "${key5}" not found. Available connections: ${available}`);
|
|
41111
|
-
}
|
|
41112
|
-
const config = entry.config;
|
|
41113
|
-
return new SemanticMetricsV2Client(config);
|
|
41114
|
-
}
|
|
41115
|
-
var SemanticMetricsV2Client = class {
|
|
41116
|
-
/**
|
|
41117
|
-
* @param config - Connection configuration (server URL, optional API key and headers).
|
|
41118
|
-
*/
|
|
41119
|
-
constructor(config) {
|
|
41120
|
-
this.config = config;
|
|
41121
|
-
this.baseUrl = config.serverUrl.replace(/\/$/, "");
|
|
41122
|
-
}
|
|
41123
|
-
/**
|
|
41124
|
-
* Build default request headers: `Accept: application/json`, custom headers,
|
|
41125
|
-
* and a Bearer `Authorization` header when an API key is configured.
|
|
41126
|
-
*
|
|
41127
|
-
* @returns Merged headers.
|
|
41128
|
-
*/
|
|
41129
|
-
getHeaders() {
|
|
41130
|
-
const headers = {
|
|
41131
|
-
Accept: "application/json",
|
|
41132
|
-
...this.config.headers ?? {}
|
|
41133
|
-
};
|
|
41134
|
-
if (this.config.apiKey) {
|
|
41135
|
-
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
41136
|
-
}
|
|
41137
|
-
return headers;
|
|
41138
|
-
}
|
|
41139
|
-
/**
|
|
41140
|
-
* Numeric selected resource ids of this connection (normalized).
|
|
41141
|
-
*
|
|
41142
|
-
* Reads `selectedEntities` — the standard connection resource-selection
|
|
41143
|
-
* field written by the connection UI (`connection.discover` + selection).
|
|
41144
|
-
*
|
|
41145
|
-
* @returns The selected resource ids; empty when unrestricted.
|
|
41146
|
-
*/
|
|
41147
|
-
getSelectedEntities() {
|
|
41148
|
-
const raw = this.config.selectedEntities;
|
|
41149
|
-
if (!Array.isArray(raw)) return [];
|
|
41150
|
-
return raw.map((v) => Number(v)).filter((n) => Number.isFinite(n));
|
|
41151
|
-
}
|
|
41152
|
-
/**
|
|
41153
|
-
* Perform a JSON request against the base URL.
|
|
41154
|
-
*
|
|
41155
|
-
* The Metrics Server wraps every response as `{ code, message, data }`. A
|
|
41156
|
-
* `code` of 200 resolves to `data`; any other `code` throws a business error
|
|
41157
|
-
* carrying the server message (regardless of HTTP status). Non-envelope
|
|
41158
|
-
* bodies are returned as-is.
|
|
41159
|
-
*
|
|
41160
|
-
* @param path - Path appended to the base URL (must start with `/`).
|
|
41161
|
-
* @param init - Optional `fetch` init overrides (method, body, per-call headers).
|
|
41162
|
-
* @returns The unwrapped `data` payload of the response envelope.
|
|
41163
|
-
* @throws When the server returns a non-200 `code`, or the HTTP response is not OK.
|
|
41164
|
-
*/
|
|
41165
|
-
async request(path8, init = {}) {
|
|
41166
|
-
const response = await fetch(`${this.baseUrl}${path8}`, {
|
|
41167
|
-
...init,
|
|
41168
|
-
method: init.method ?? "GET",
|
|
41169
|
-
headers: { ...this.getHeaders(), ...init.headers ?? {} }
|
|
41170
|
-
});
|
|
41171
|
-
const text = await response.text().catch(() => "");
|
|
41172
|
-
const parsed = this.parseBody(text);
|
|
41173
|
-
if (parsed?.envelope === true) {
|
|
41174
|
-
if (parsed.code !== 200) {
|
|
41175
|
-
throw new Error(`API ${parsed.code}: ${parsed.message || "Unknown error"}`);
|
|
41176
|
-
}
|
|
41177
|
-
return parsed.data;
|
|
41178
|
-
}
|
|
41179
|
-
if (!response.ok) {
|
|
41180
|
-
throw new Error(`HTTP ${response.status}: ${text || response.statusText}`);
|
|
41181
|
-
}
|
|
41182
|
-
return parsed?.value ?? void 0;
|
|
41183
|
-
}
|
|
41184
|
-
/**
|
|
41185
|
-
* Parse a response body text. Detects the server envelope `{ code, message, data }`.
|
|
41186
|
-
*
|
|
41187
|
-
* @param text - Raw response body text.
|
|
41188
|
-
* @returns `{ envelope: true, code, message, data }` for an envelope body,
|
|
41189
|
-
* `{ envelope: false, value }` for anything else (or `{ envelope: false }` when empty/invalid).
|
|
41190
|
-
*/
|
|
41191
|
-
parseBody(text) {
|
|
41192
|
-
if (!text.trim()) return { envelope: false };
|
|
41193
|
-
try {
|
|
41194
|
-
const value = JSON.parse(text);
|
|
41195
|
-
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
41196
|
-
const record = value;
|
|
41197
|
-
if (typeof record.code === "number") {
|
|
41198
|
-
return {
|
|
41199
|
-
envelope: true,
|
|
41200
|
-
code: record.code,
|
|
41201
|
-
message: typeof record.message === "string" ? record.message : void 0,
|
|
41202
|
-
data: record.data
|
|
41203
|
-
};
|
|
41204
|
-
}
|
|
41205
|
-
}
|
|
41206
|
-
return { envelope: false, value };
|
|
41207
|
-
} catch {
|
|
41208
|
-
return { envelope: false, value: text };
|
|
41209
|
-
}
|
|
41210
|
-
}
|
|
41211
|
-
/**
|
|
41212
|
-
* POST a JSON body to a path.
|
|
41213
|
-
*
|
|
41214
|
-
* @param path - Path appended to the base URL.
|
|
41215
|
-
* @param body - Payload serialized as JSON.
|
|
41216
|
-
* @returns Parsed JSON response body.
|
|
41217
|
-
*/
|
|
41218
|
-
post(path8, body) {
|
|
41219
|
-
return this.request(path8, {
|
|
41220
|
-
method: "POST",
|
|
41221
|
-
headers: { "Content-Type": "application/json" },
|
|
41222
|
-
body: JSON.stringify(body)
|
|
41223
|
-
});
|
|
41224
|
-
}
|
|
41225
|
-
/**
|
|
41226
|
-
* PUT a JSON body to a path.
|
|
41227
|
-
*
|
|
41228
|
-
* @param path - Path appended to the base URL.
|
|
41229
|
-
* @param body - Payload serialized as JSON.
|
|
41230
|
-
* @returns Parsed JSON response body.
|
|
41231
|
-
*/
|
|
41232
|
-
put(path8, body) {
|
|
41233
|
-
return this.request(path8, {
|
|
41234
|
-
method: "PUT",
|
|
41235
|
-
headers: { "Content-Type": "application/json" },
|
|
41236
|
-
body: JSON.stringify(body)
|
|
41237
|
-
});
|
|
41238
|
-
}
|
|
41239
|
-
/**
|
|
41240
|
-
* List all datasources.
|
|
41241
|
-
*
|
|
41242
|
-
* @returns Parsed JSON response body.
|
|
41243
|
-
*/
|
|
41244
|
-
listDatasources() {
|
|
41245
|
-
return this.request("/datasources");
|
|
41246
|
-
}
|
|
41247
|
-
/**
|
|
41248
|
-
* Get table grants for a datasource.
|
|
41249
|
-
*
|
|
41250
|
-
* @param datasourceId - Datasource identifier.
|
|
41251
|
-
* @returns Parsed JSON response body.
|
|
41252
|
-
*/
|
|
41253
|
-
getTableGrants(datasourceId) {
|
|
41254
|
-
return this.request(`/datasources/${encodeURIComponent(datasourceId)}/table-grants`);
|
|
41255
|
-
}
|
|
41256
|
-
/**
|
|
41257
|
-
* Run a read-only SQL query against a datasource.
|
|
41258
|
-
*
|
|
41259
|
-
* @param datasourceId - Datasource identifier.
|
|
41260
|
-
* @param input - Query input: `sql` (SELECT/WITH only), optional `params`, `maxRows`, `debug`.
|
|
41261
|
-
* @returns Parsed JSON response body.
|
|
41262
|
-
* @throws When `sql` fails read-only validation (rejected before any fetch).
|
|
41263
|
-
*/
|
|
41264
|
-
async queryDatasource(datasourceId, input) {
|
|
41265
|
-
const validation = validateSql(input.sql);
|
|
41266
|
-
if (!validation.ok) throw new Error(`SQL_NOT_ALLOWED: ${validation.reason}`);
|
|
41267
|
-
return this.post(`/datasources/${encodeURIComponent(datasourceId)}/query`, input);
|
|
41268
|
-
}
|
|
41269
|
-
/**
|
|
41270
|
-
* Test a datasource connection.
|
|
41271
|
-
*
|
|
41272
|
-
* @param datasourceId - Datasource identifier.
|
|
41273
|
-
* @returns Parsed JSON response body.
|
|
41274
|
-
*/
|
|
41275
|
-
testDatasource(datasourceId) {
|
|
41276
|
-
return this.post(`/datasources/${encodeURIComponent(datasourceId)}/test`, {});
|
|
41277
|
-
}
|
|
41278
|
-
/**
|
|
41279
|
-
* Get connection-pool status for a datasource.
|
|
41280
|
-
*
|
|
41281
|
-
* @param datasourceId - Datasource identifier.
|
|
41282
|
-
* @returns Parsed JSON response body.
|
|
41283
|
-
*/
|
|
41284
|
-
getPoolStatus(datasourceId) {
|
|
41285
|
-
return this.request(`/datasources/${encodeURIComponent(datasourceId)}/pool`);
|
|
41286
|
-
}
|
|
41287
|
-
/**
|
|
41288
|
-
* List table metadata for a datasource, auto-paginating.
|
|
41289
|
-
*
|
|
41290
|
-
* The server pages this collection (`page`/`pageSize`, default page size 20),
|
|
41291
|
-
* so requests aggregate every page into one `{ items, total }` result.
|
|
41292
|
-
*
|
|
41293
|
-
* @param datasourceId - Datasource identifier.
|
|
41294
|
-
* @returns `{ items: [...], total }` covering all pages.
|
|
41295
|
-
*/
|
|
41296
|
-
async listTables(datasourceId) {
|
|
41297
|
-
return this.listMetaPage(`/datasources/${encodeURIComponent(datasourceId)}/meta/tables`);
|
|
41298
|
-
}
|
|
41299
|
-
/**
|
|
41300
|
-
* Shared pagination walk for the paged meta collections (`{items,total,page,pageSize}`).
|
|
41301
|
-
*
|
|
41302
|
-
* @param basePath - Collection path (tables or metrics).
|
|
41303
|
-
* @returns `{ items, total }` aggregated across all pages.
|
|
41304
|
-
*/
|
|
41305
|
-
async listMetaPage(basePath) {
|
|
41306
|
-
const pageSize = 100;
|
|
41307
|
-
const items = [];
|
|
41308
|
-
let total = Number.POSITIVE_INFINITY;
|
|
41309
|
-
for (let page = 1; items.length < total; page += 1) {
|
|
41310
|
-
const body = await this.request(`${basePath}?page=${page}&pageSize=${pageSize}`);
|
|
41311
|
-
const record = body !== null && typeof body === "object" ? body : {};
|
|
41312
|
-
const batch = Array.isArray(record.items) ? record.items : [];
|
|
41313
|
-
items.push(...batch);
|
|
41314
|
-
total = typeof record.total === "number" ? record.total : items.length;
|
|
41315
|
-
if (batch.length === 0) break;
|
|
41316
|
-
}
|
|
41317
|
-
return { items, total: items.length };
|
|
41318
|
-
}
|
|
41319
|
-
/**
|
|
41320
|
-
* Get metadata for a single table.
|
|
41321
|
-
*
|
|
41322
|
-
* @param datasourceId - Datasource identifier.
|
|
41323
|
-
* @param tableKey - Table key.
|
|
41324
|
-
* @returns Parsed JSON response body.
|
|
41325
|
-
*/
|
|
41326
|
-
getTable(datasourceId, tableKey) {
|
|
41327
|
-
return this.request(
|
|
41328
|
-
`/datasources/${encodeURIComponent(datasourceId)}/meta/tables/${encodeURIComponent(tableKey)}`
|
|
41329
|
-
);
|
|
41330
|
-
}
|
|
41331
|
-
/**
|
|
41332
|
-
* Create a table definition for a datasource.
|
|
41333
|
-
*
|
|
41334
|
-
* @param datasourceId - Datasource identifier.
|
|
41335
|
-
* @param payload - Table definition payload.
|
|
41336
|
-
* @returns Parsed JSON response body.
|
|
41337
|
-
*/
|
|
41338
|
-
createTable(datasourceId, payload) {
|
|
41339
|
-
return this.post(`/datasources/${encodeURIComponent(datasourceId)}/meta/tables`, payload);
|
|
41340
|
-
}
|
|
41341
|
-
/**
|
|
41342
|
-
* Update a table definition for a datasource.
|
|
41343
|
-
*
|
|
41344
|
-
* @param datasourceId - Datasource identifier.
|
|
41345
|
-
* @param tableKey - Table key.
|
|
41346
|
-
* @param payload - Table definition payload.
|
|
41347
|
-
* @returns Parsed JSON response body.
|
|
41348
|
-
*/
|
|
41349
|
-
/**
|
|
41350
|
-
* Update a published table meta via read-modify-write.
|
|
41351
|
-
*
|
|
41352
|
-
* The server's PUT replaces the whole payload, so the current payload is
|
|
41353
|
-
* fetched first and the incoming fields are merged on top; fields not
|
|
41354
|
-
* mentioned are preserved.
|
|
41355
|
-
*/
|
|
41356
|
-
async updateTable(datasourceId, tableKey, payload) {
|
|
41357
|
-
const existing = await this.readMetaPayload(`${this.baseUrl}/datasources/${encodeURIComponent(datasourceId)}/meta/tables/${encodeURIComponent(tableKey)}`);
|
|
41358
|
-
return this.put(
|
|
41359
|
-
`/datasources/${encodeURIComponent(datasourceId)}/meta/tables/${encodeURIComponent(tableKey)}`,
|
|
41360
|
-
{ payload: { ...existing, ...payload } }
|
|
41361
|
-
);
|
|
41362
|
-
}
|
|
41363
|
-
/**
|
|
41364
|
-
* List metric definitions for a datasource.
|
|
41365
|
-
*
|
|
41366
|
-
* @param datasourceId - Datasource identifier.
|
|
41367
|
-
* @returns Parsed JSON response body.
|
|
41368
|
-
*/
|
|
41369
|
-
/**
|
|
41370
|
-
* List metric metadata for a datasource, auto-paginating.
|
|
41371
|
-
*
|
|
41372
|
-
* The server pages this collection (`page`/`pageSize`, default page size 20),
|
|
41373
|
-
* so requests aggregate every page into one `{ items, total }` result.
|
|
41374
|
-
*
|
|
41375
|
-
* @param datasourceId - Datasource identifier.
|
|
41376
|
-
* @returns `{ items: [...], total }` covering all pages.
|
|
41377
|
-
*/
|
|
41378
|
-
async listMetrics(datasourceId) {
|
|
41379
|
-
return this.listMetaPage(`/datasources/${encodeURIComponent(datasourceId)}/meta/metrics`);
|
|
41380
|
-
}
|
|
41381
|
-
/**
|
|
41382
|
-
* Get a single metric definition.
|
|
41383
|
-
*
|
|
41384
|
-
* @param datasourceId - Datasource identifier.
|
|
41385
|
-
* @param metricKey - Metric key.
|
|
41386
|
-
* @returns Parsed JSON response body.
|
|
41387
|
-
*/
|
|
41388
|
-
getMetric(datasourceId, metricKey) {
|
|
41389
|
-
return this.request(
|
|
41390
|
-
`/datasources/${encodeURIComponent(datasourceId)}/meta/metrics/${encodeURIComponent(metricKey)}`
|
|
41391
|
-
);
|
|
41392
|
-
}
|
|
41393
|
-
/**
|
|
41394
|
-
* Create a metric definition for a datasource.
|
|
41395
|
-
*
|
|
41396
|
-
* @param datasourceId - Datasource identifier.
|
|
41397
|
-
* @param payload - Metric definition payload.
|
|
41398
|
-
* @returns Parsed JSON response body.
|
|
41399
|
-
*/
|
|
41400
|
-
createMetric(datasourceId, payload) {
|
|
41401
|
-
return this.post(`/datasources/${encodeURIComponent(datasourceId)}/meta/metrics`, payload);
|
|
41402
|
-
}
|
|
41403
|
-
/**
|
|
41404
|
-
* Update a metric definition for a datasource.
|
|
41405
|
-
*
|
|
41406
|
-
* @param datasourceId - Datasource identifier.
|
|
41407
|
-
* @param metricKey - Metric key.
|
|
41408
|
-
* @param payload - Metric definition payload.
|
|
41409
|
-
* @returns Parsed JSON response body.
|
|
41410
|
-
*/
|
|
41411
|
-
/**
|
|
41412
|
-
* Update a published metric meta via read-modify-write.
|
|
41413
|
-
*
|
|
41414
|
-
* The server's PUT replaces the whole payload, so the current payload is
|
|
41415
|
-
* fetched first and the incoming fields are merged on top; fields not
|
|
41416
|
-
* mentioned are preserved.
|
|
41417
|
-
*/
|
|
41418
|
-
async updateMetric(datasourceId, metricKey, payload) {
|
|
41419
|
-
const existing = await this.readMetaPayload(`${this.baseUrl}/datasources/${encodeURIComponent(datasourceId)}/meta/metrics/${encodeURIComponent(metricKey)}`);
|
|
41420
|
-
return this.put(
|
|
41421
|
-
`/datasources/${encodeURIComponent(datasourceId)}/meta/metrics/${encodeURIComponent(metricKey)}`,
|
|
41422
|
-
{ payload: { ...existing, ...payload } }
|
|
41423
|
-
);
|
|
41424
|
-
}
|
|
41425
|
-
/**
|
|
41426
|
-
* Fetch the current `payload` object of a published meta entry.
|
|
41427
|
-
*
|
|
41428
|
-
* The single-entry read returns `{ code, data: [entry] }` (already unwrapped
|
|
41429
|
-
* to the array by {@link request}); the payload lives on the first entry.
|
|
41430
|
-
*
|
|
41431
|
-
* @param absoluteUrl - Full URL of the single-entry meta read.
|
|
41432
|
-
* @returns The stored payload object (empty when none exists).
|
|
41433
|
-
*/
|
|
41434
|
-
async readMetaPayload(absoluteUrl) {
|
|
41435
|
-
const response = await fetch(absoluteUrl, { headers: this.getHeaders() });
|
|
41436
|
-
const text = await response.text().catch(() => "");
|
|
41437
|
-
if (!response.ok) {
|
|
41438
|
-
throw new Error(`HTTP ${response.status}: ${text || response.statusText}`);
|
|
41439
|
-
}
|
|
41440
|
-
const parsed = this.parseBody(text);
|
|
41441
|
-
const data = parsed?.envelope === true ? parsed.data : parsed?.value;
|
|
41442
|
-
const entry = Array.isArray(data) ? data[0] : data;
|
|
41443
|
-
const payload = entry?.payload;
|
|
41444
|
-
return payload !== null && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
41445
|
-
}
|
|
41446
|
-
/**
|
|
41447
|
-
* Get runtime metadata for a datasource.
|
|
41448
|
-
*
|
|
41449
|
-
* @param datasourceId - Datasource identifier.
|
|
41450
|
-
* @returns Parsed JSON response body.
|
|
41451
|
-
*/
|
|
41452
|
-
getRuntimeMeta(datasourceId) {
|
|
41453
|
-
return this.request(`/datasources/${encodeURIComponent(datasourceId)}/meta`);
|
|
41454
|
-
}
|
|
41455
|
-
/**
|
|
41456
|
-
* Run a metrics query.
|
|
41457
|
-
*
|
|
41458
|
-
* @param request - Metrics query request payload.
|
|
41459
|
-
* @returns Parsed JSON response body.
|
|
41460
|
-
*/
|
|
41461
|
-
queryMetrics(request) {
|
|
41462
|
-
return this.post("/metrics/query", request);
|
|
41463
|
-
}
|
|
41464
|
-
/**
|
|
41465
|
-
* Run an ad-hoc custom SQL query, validated as read-only before sending.
|
|
41466
|
-
*
|
|
41467
|
-
* @param request - Request with `datasourceId`, `customSql` (SELECT/WITH only),
|
|
41468
|
-
* and optional `limit` / `debug`.
|
|
41469
|
-
* @returns Parsed JSON response body.
|
|
41470
|
-
* @throws When `customSql` fails read-only validation (rejected before any fetch).
|
|
41471
|
-
*/
|
|
41472
|
-
async customSql(request) {
|
|
41473
|
-
const validation = validateSql(request.customSql);
|
|
41474
|
-
if (!validation.ok) throw new Error(`SQL_NOT_ALLOWED: ${validation.reason}`);
|
|
41475
|
-
return this.post("/metrics/query", request);
|
|
41476
|
-
}
|
|
41477
|
-
};
|
|
41478
|
-
|
|
41479
|
-
// src/tool_lattice/semantic_metrics/metrics_datasource_tool.ts
|
|
41480
|
-
var DESCRIPTION = `PHYSICAL LAYER EXPLORATION \u2014 the only tool for probing raw datasource structure (Builder/Admin only; business agents do not need it).
|
|
41481
|
-
|
|
41482
|
-
OWNS: discovering datasources, reading table-grants (the exploration boundary for this tenant), and running read-only SQL (SELECT/WITH only) to inspect physical tables, columns, sample rows, and value distributions. Also: per-datasource connection test and pool status.
|
|
41483
|
-
|
|
41484
|
-
DOES NOT OWN:
|
|
41485
|
-
- Published semantic assets (table meta / metric meta) \u2192 use metrics_meta_tool.
|
|
41486
|
-
- Runtime meta and business metric queries \u2192 use metrics_runtime_tool.
|
|
41487
|
-
|
|
41488
|
-
USE WHEN: starting a modeling task \u2014 \`list_datasources\` is always the FIRST step: it returns the datasource ids that every other action and tool requires (get_grants, query_sql here; read_semantic_catalog, query_metrics in metrics_runtime_tool; the meta actions in metrics_meta_tool). Read grants next, then probe tables, columns, samples, and distributions within the grant. If a field's business meaning is unclear, probe sample values and distributions here before publishing anything.
|
|
41489
|
-
|
|
41490
|
-
COMMON MISTAKES (do not):
|
|
41491
|
-
- Do not answer business metric questions here (e.g. "monthly sales by region") \u2014 that is metrics_runtime_tool \`query\` against published metrics, NOT this tool's \`query_sql\` (physical-table SQL).
|
|
41492
|
-
- Do not read or publish semantic meta through this tool \u2014 metrics_meta_tool owns the semantic layer.
|
|
41493
|
-
- Do not probe tables outside the tenant's table-grants; un-granted probes are rejected and break the exploration boundary.
|
|
41494
|
-
- Do not attempt writes \u2014 SQL is validated read-only and rejected before sending.`;
|
|
41495
|
-
function createMetricsDatasourceTool(params) {
|
|
41496
|
-
const { connectionType, connections, connectAll } = params;
|
|
41497
|
-
return (0, import_langchain67.tool)(
|
|
41498
|
-
async (input, exeConfig) => {
|
|
41499
|
-
try {
|
|
41500
|
-
const client = await resolveMetricsClientFromSelector(
|
|
41501
|
-
{ connectionType, connections, connectAll },
|
|
41502
|
-
readToolRunConfig(exeConfig) ?? {},
|
|
41503
|
-
input.connectionKey
|
|
41504
|
-
);
|
|
41505
|
-
const scope = effectiveDatasourceScope(client.getSelectedEntities());
|
|
41506
|
-
switch (input.action) {
|
|
41507
|
-
case "list_datasources": {
|
|
41508
|
-
const result = await client.listDatasources();
|
|
41509
|
-
const filtered = scope.unrestricted ? result : result.filter((d) => scope.ids.includes(Number(d.id)));
|
|
41510
|
-
const safe = filtered.map((d) => ({
|
|
41511
|
-
id: d.id,
|
|
41512
|
-
name: d.name,
|
|
41513
|
-
sourceType: d.sourceType,
|
|
41514
|
-
description: d.description,
|
|
41515
|
-
statusLabel: d.statusLabel
|
|
41516
|
-
}));
|
|
41517
|
-
return JSON.stringify(safe, null, 2);
|
|
41518
|
-
}
|
|
41519
|
-
case "get_grants": {
|
|
41520
|
-
const ds = resolveDatasourceId(input, exeConfig);
|
|
41521
|
-
assertDatasourceSelected(scope, ds);
|
|
41522
|
-
const result = await client.getTableGrants(ds);
|
|
41523
|
-
return JSON.stringify(result, null, 2);
|
|
41524
|
-
}
|
|
41525
|
-
case "query_sql": {
|
|
41526
|
-
const ds = resolveDatasourceId(input, exeConfig);
|
|
41527
|
-
assertDatasourceSelected(scope, ds);
|
|
41528
|
-
if (!input.sql) throw new Error("sql is required for the 'query_sql' action");
|
|
41529
|
-
const result = await client.queryDatasource(ds, {
|
|
41530
|
-
sql: input.sql,
|
|
41531
|
-
params: input.params,
|
|
41532
|
-
maxRows: input.maxRows
|
|
41533
|
-
});
|
|
41534
|
-
return JSON.stringify(result, null, 2);
|
|
41535
|
-
}
|
|
41536
|
-
case "test_connection": {
|
|
41537
|
-
const ds = resolveDatasourceId(input, exeConfig);
|
|
41538
|
-
assertDatasourceSelected(scope, ds);
|
|
41539
|
-
const result = await client.testDatasource(ds);
|
|
41540
|
-
return JSON.stringify(result, null, 2);
|
|
41541
|
-
}
|
|
41542
|
-
case "pool_status": {
|
|
41543
|
-
const ds = resolveDatasourceId(input, exeConfig);
|
|
41544
|
-
assertDatasourceSelected(scope, ds);
|
|
41545
|
-
const result = await client.getPoolStatus(ds);
|
|
41546
|
-
return JSON.stringify(result, null, 2);
|
|
41547
|
-
}
|
|
41548
|
-
}
|
|
41549
|
-
} catch (error) {
|
|
41550
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
41551
|
-
}
|
|
41552
|
-
},
|
|
41553
|
-
{
|
|
41554
|
-
name: "metrics_datasource_tool",
|
|
41555
|
-
description: DESCRIPTION,
|
|
41556
|
-
schema: import_zod55.default.object({
|
|
41557
|
-
action: import_zod55.default.enum(["list_datasources", "get_grants", "query_sql", "test_connection", "pool_status"]).describe(
|
|
41558
|
-
"list_datasources: list datasources \u2014 ALWAYS call this first to obtain the datasource id used by every other action and tool; get_grants: read table-grants; query_sql: run read-only SQL against PHYSICAL tables (note: this is query_sql, NOT the semantic 'query' action of metrics_runtime_tool); test_connection: test the datasource; pool_status: connection-pool status"
|
|
41559
|
-
),
|
|
41560
|
-
connectionKey: import_zod55.default.string().optional().describe("Connection key. Omit when only one semantic-metrics connection exists"),
|
|
41561
|
-
datasourceId: import_zod55.default.coerce.number().optional().describe("Numeric datasource id, e.g. 15 (required for all actions except list_datasources; optional if set in runConfig.metricsDataSource)"),
|
|
41562
|
-
sql: import_zod55.default.string().optional().describe("Read-only SQL (SELECT/WITH only). Required for the query action. Metadata templates \u2014 PostgreSQL/SQL Server columns: select column_name, data_type from information_schema.columns where table_schema = :schemaName and table_name = :tableName order by ordinal_position; HANA columns: select column_name, data_type_name from table_columns where schema_name = :schemaName and table_name = :tableName order by position; distributions: select <dim>, count(*) as row_count from <table> group by <dim> order by row_count desc limit :maxRows"),
|
|
41563
|
-
params: import_zod55.default.record(import_zod55.default.union([import_zod55.default.string(), import_zod55.default.number(), import_zod55.default.boolean()])).optional().describe("Named :param values for the SQL"),
|
|
41564
|
-
maxRows: import_zod55.default.number().optional().describe("Max rows to return")
|
|
41565
|
-
})
|
|
41566
|
-
}
|
|
41567
|
-
);
|
|
41568
|
-
}
|
|
41569
|
-
|
|
41570
|
-
// src/tool_lattice/semantic_metrics/metrics_meta_tool.ts
|
|
41571
|
-
var import_zod56 = __toESM(require("zod"));
|
|
41572
|
-
var import_langchain68 = require("langchain");
|
|
41573
|
-
var DESCRIPTION2 = `SEMANTIC ASSET REGISTRY (Builder/Admin only) \u2014 the only tool for reading and publishing the runtime's semantic layer: table meta (meta/tables) and metric meta (meta/metrics).
|
|
41574
|
-
|
|
41575
|
-
OWNS: listing published tables and metrics, reading one by objectKey, publishing a semantic table (create_table: columns tagged with role dimension|measure), publishing a metric (create_metric: a metric_index payload then a metric_detail payload using the SQL-free calculation DSL), and correcting published assets (update_table / update_metric).
|
|
41576
|
-
|
|
41577
|
-
DOES NOT OWN:
|
|
41578
|
-
- Running queries or reading the aggregated runtime view \u2192 metrics_runtime_tool (get_meta / query / custom_sql).
|
|
41579
|
-
- Probing physical tables, columns, grants, or samples \u2192 metrics_datasource_tool.
|
|
41580
|
-
|
|
41581
|
-
USE WHEN: physical exploration is done and the model has been proposed and confirmed by the user \u2014 to publish the semantic table and metrics, or to correct published assets afterwards.
|
|
41582
|
-
|
|
41583
|
-
COMMON MISTAKES (do not):
|
|
41584
|
-
- Do not call get_meta here \u2014 that action belongs to metrics_runtime_tool, not this tool.
|
|
41585
|
-
- Do not try to "query numbers" through this tool \u2014 list/read actions return definitions only; use metrics_runtime_tool query for data.
|
|
41586
|
-
- Do not publish a metric whose sourceTable has no published table meta, or whose dimensions are not published columns with role dimension \u2014 the server will reject it.
|
|
41587
|
-
- The builder assistant must load the semantic-metrics-modeling skill and pass modelingSkillLoaded: true on write actions; no removal actions are exposed on purpose.`;
|
|
41588
|
-
var MODELING_SKILL_NAME = "semantic-metrics-modeling";
|
|
41589
|
-
var BUILDER_ASSISTANT_ID = "semantic-metrics-builder";
|
|
41590
|
-
function requireModelingSkillLoaded(action, input, exeConfig) {
|
|
41591
|
-
const isWriteAction = action === "create_table" || action === "update_table" || action === "create_metric" || action === "update_metric";
|
|
41592
|
-
if (!isWriteAction) return void 0;
|
|
41593
|
-
const runConfig = readToolRunConfig(exeConfig);
|
|
41594
|
-
const assistantId = runConfig?.assistant_id;
|
|
41595
|
-
if (assistantId === BUILDER_ASSISTANT_ID && input.modelingSkillLoaded !== true) {
|
|
41596
|
-
return JSON.stringify({
|
|
41597
|
-
success: false,
|
|
41598
|
-
error: `Load the '${MODELING_SKILL_NAME}' skill before publishing meta.`
|
|
41599
|
-
});
|
|
41600
|
-
}
|
|
41601
|
-
return void 0;
|
|
41602
|
-
}
|
|
41603
|
-
function actionRequiresPayload(action) {
|
|
41604
|
-
return action === "create_table" || action === "update_table" || action === "create_metric" || action === "update_metric";
|
|
41605
|
-
}
|
|
41606
|
-
function createMetricsMetaTool(params) {
|
|
41607
|
-
const { connectionType, connections, connectAll } = params;
|
|
41608
|
-
return (0, import_langchain68.tool)(
|
|
41609
|
-
async (input, exeConfig) => {
|
|
41610
|
-
try {
|
|
41611
|
-
const guardError = requireModelingSkillLoaded(input.action, input, exeConfig);
|
|
41612
|
-
if (guardError !== void 0) return guardError;
|
|
41613
|
-
const client = await resolveMetricsClientFromSelector(
|
|
41614
|
-
{ connectionType, connections, connectAll },
|
|
41615
|
-
readToolRunConfig(exeConfig) ?? {},
|
|
41616
|
-
input.connectionKey
|
|
41617
|
-
);
|
|
41618
|
-
const ds = resolveDatasourceId(input, exeConfig);
|
|
41619
|
-
assertDatasourceSelected(effectiveDatasourceScope(client.getSelectedEntities()), ds);
|
|
41620
|
-
if (actionRequiresPayload(input.action) && input.payload === void 0) {
|
|
41621
|
-
throw new Error(`payload is required for ${input.action}`);
|
|
41622
|
-
}
|
|
41623
|
-
const payload = input.payload ?? {};
|
|
41624
|
-
switch (input.action) {
|
|
41625
|
-
case "list_tables": {
|
|
41626
|
-
return JSON.stringify(await client.listTables(ds), null, 2);
|
|
41627
|
-
}
|
|
41628
|
-
case "read_table_meta": {
|
|
41629
|
-
if (!input.objectKey) throw new Error("objectKey is required for read_table_meta");
|
|
41630
|
-
return JSON.stringify(await client.getTable(ds, input.objectKey), null, 2);
|
|
41631
|
-
}
|
|
41632
|
-
case "create_table": {
|
|
41633
|
-
return JSON.stringify(await client.createTable(ds, payload), null, 2);
|
|
41634
|
-
}
|
|
41635
|
-
case "update_table": {
|
|
41636
|
-
if (!input.objectKey) throw new Error("objectKey is required for update_table");
|
|
41637
|
-
return JSON.stringify(await client.updateTable(ds, input.objectKey, payload), null, 2);
|
|
41638
|
-
}
|
|
41639
|
-
case "list_metrics": {
|
|
41640
|
-
return JSON.stringify(await client.listMetrics(ds), null, 2);
|
|
41641
|
-
}
|
|
41642
|
-
case "read_metric_meta": {
|
|
41643
|
-
if (!input.objectKey) throw new Error("objectKey is required for read_metric_meta");
|
|
41644
|
-
return JSON.stringify(await client.getMetric(ds, input.objectKey), null, 2);
|
|
41645
|
-
}
|
|
41646
|
-
case "create_metric": {
|
|
41647
|
-
return JSON.stringify(await client.createMetric(ds, payload), null, 2);
|
|
41648
|
-
}
|
|
41649
|
-
case "update_metric": {
|
|
41650
|
-
if (!input.objectKey) throw new Error("objectKey is required for update_metric");
|
|
41651
|
-
return JSON.stringify(await client.updateMetric(ds, input.objectKey, payload), null, 2);
|
|
41652
|
-
}
|
|
41653
|
-
}
|
|
41654
|
-
} catch (error) {
|
|
41655
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
41656
|
-
}
|
|
41657
|
-
},
|
|
41658
|
-
{
|
|
41659
|
-
name: "metrics_meta_tool",
|
|
41660
|
-
description: DESCRIPTION2,
|
|
41661
|
-
schema: import_zod56.default.object({
|
|
41662
|
-
action: import_zod56.default.enum([
|
|
41663
|
-
"list_tables",
|
|
41664
|
-
"read_table_meta",
|
|
41665
|
-
"create_table",
|
|
41666
|
-
"update_table",
|
|
41667
|
-
"list_metrics",
|
|
41668
|
-
"read_metric_meta",
|
|
41669
|
-
"create_metric",
|
|
41670
|
-
"update_metric"
|
|
41671
|
-
]).describe(
|
|
41672
|
-
"Actions ONLY in this meta tool (runtime query actions like get_meta/query belong to metrics_runtime_tool): list_tables/list_metrics (browse published assets), read_table_meta/read_metric_meta (details by objectKey), create_table/create_metric (publish), update_table/update_metric (correct)"
|
|
41673
|
-
),
|
|
41674
|
-
connectionKey: import_zod56.default.string().optional().describe("Connection key. Omit when only one semantic-metrics connection exists"),
|
|
41675
|
-
datasourceId: import_zod56.default.coerce.number().optional().describe("Numeric datasource id, e.g. 15 (optional if set in runConfig.metricsDataSource)"),
|
|
41676
|
-
objectKey: import_zod56.default.string().optional().describe("Semantic table/metric key (required for read_table_meta/update_table/read_metric_meta/update_metric)"),
|
|
41677
|
-
payload: import_zod56.default.record(import_zod56.default.unknown()).optional().describe("Meta payload (required for create/update actions; objectType/objectKey/status/payload/accessGrant)"),
|
|
41678
|
-
modelingSkillLoaded: import_zod56.default.literal(true).optional().describe("Set true after loading the semantic-metrics-modeling skill (required for the builder assistant on write actions)")
|
|
41679
|
-
})
|
|
41680
|
-
}
|
|
41681
|
-
);
|
|
41682
|
-
}
|
|
41683
|
-
|
|
41684
|
-
// src/tool_lattice/semantic_metrics/metrics_runtime_tool.ts
|
|
41685
|
-
var import_zod57 = __toESM(require("zod"));
|
|
41686
|
-
var import_langchain69 = require("langchain");
|
|
41687
|
-
var DESCRIPTION3 = `RUNTIME QUERY SURFACE \u2014 read what is published and answer business questions with numbers. Business agents use ONLY this tool; Builder agents also use it to verify freshly published metrics.
|
|
41688
|
-
|
|
41689
|
-
OWNS: list_datasources (self-contained datasource discovery \u2014 redacted output, the first step before anything else), read_semantic_catalog (the published semantic model for a datasource: tables, metrics, dimensions, filters) and query_metrics (the semantic metric query: metrics / groupBy / filters / orderBy / limit \u2014 the server generates the SQL, so there is no free-form SQL here).
|
|
41690
|
-
|
|
41691
|
-
DOES NOT OWN:
|
|
41692
|
-
- Publishing or correcting semantic tables/metrics \u2192 metrics_meta_tool (create_table/update_table/create_metric/update_metric/list_tables/read_table_meta/list_metrics/read_metric_meta).
|
|
41693
|
-
- Physical exploration of raw tables, grants, or samples \u2192 metrics_datasource_tool (query_sql).
|
|
41694
|
-
- Free-form custom SQL \u2014 intentionally not provided; use query against published metrics.
|
|
41695
|
-
|
|
41696
|
-
USE WHEN: read_semantic_catalog to see what is published before asking numbers; query_metrics to answer a business question from already-published metrics (Business) or to verify a just-published metric against its acceptance evidence (Builder).
|
|
41697
|
-
|
|
41698
|
-
COMMON MISTAKES (do not):
|
|
41699
|
-
- Do not call meta-tool actions here (create_table / update_table / create_metric / update_metric / list_tables / read_table_meta / list_metrics / read_metric_meta) \u2014 they live in metrics_meta_tool and will fail schema validation here.
|
|
41700
|
-
- Do not look for a custom-SQL action \u2014 there is none; explore physical data with metrics_datasource_tool query_sql, and query business numbers with the semantic query action.
|
|
41701
|
-
- Metrics and dimensions in query_metrics must already be published; querying an unpublished metric fails with "not found in catalog".`;
|
|
41702
|
-
function createMetricsRuntimeTool(params) {
|
|
41703
|
-
const { connectionType, connections, connectAll } = params;
|
|
41704
|
-
return (0, import_langchain69.tool)(
|
|
41705
|
-
async (input, exeConfig) => {
|
|
41706
|
-
try {
|
|
41707
|
-
const client = await resolveMetricsClientFromSelector(
|
|
41708
|
-
{ connectionType, connections, connectAll },
|
|
41709
|
-
readToolRunConfig(exeConfig) ?? {},
|
|
41710
|
-
input.connectionKey
|
|
41711
|
-
);
|
|
41712
|
-
const scope = effectiveDatasourceScope(client.getSelectedEntities());
|
|
41713
|
-
switch (input.action) {
|
|
41714
|
-
case "list_datasources": {
|
|
41715
|
-
const result = await client.listDatasources();
|
|
41716
|
-
const filtered = scope.unrestricted ? result : result.filter((d) => scope.ids.includes(Number(d.id)));
|
|
41717
|
-
const safe = filtered.map((d) => ({
|
|
41718
|
-
id: d.id,
|
|
41719
|
-
name: d.name,
|
|
41720
|
-
sourceType: d.sourceType,
|
|
41721
|
-
description: d.description,
|
|
41722
|
-
statusLabel: d.statusLabel
|
|
41723
|
-
}));
|
|
41724
|
-
return JSON.stringify(safe, null, 2);
|
|
41725
|
-
}
|
|
41726
|
-
case "read_semantic_catalog": {
|
|
41727
|
-
const ds = resolveDatasourceId(input, exeConfig);
|
|
41728
|
-
assertDatasourceSelected(scope, ds);
|
|
41729
|
-
return JSON.stringify(await client.getRuntimeMeta(ds), null, 2);
|
|
41730
|
-
}
|
|
41731
|
-
case "query_metrics": {
|
|
41732
|
-
if (!input.query) throw new Error("query is required for the 'query_metrics' action");
|
|
41733
|
-
const bodyDatasourceId = input.query.datasourceId;
|
|
41734
|
-
if (bodyDatasourceId !== void 0) {
|
|
41735
|
-
assertDatasourceSelected(scope, Number(bodyDatasourceId));
|
|
41736
|
-
}
|
|
41737
|
-
return JSON.stringify(await client.queryMetrics(input.query), null, 2);
|
|
41738
|
-
}
|
|
41739
|
-
}
|
|
41740
|
-
} catch (error) {
|
|
41741
|
-
return `Error: ${error instanceof Error ? error.message : String(error)}`;
|
|
41742
|
-
}
|
|
41743
|
-
},
|
|
41744
|
-
{
|
|
41745
|
-
name: "metrics_runtime_tool",
|
|
41746
|
-
description: DESCRIPTION3,
|
|
41747
|
-
schema: import_zod57.default.object({
|
|
41748
|
-
action: import_zod57.default.enum(["list_datasources", "read_semantic_catalog", "query_metrics"]).describe(
|
|
41749
|
-
"Actions ONLY in this runtime tool: list_datasources (list available datasources \u2014 ALWAYS call this first to obtain the datasourceId; output is redacted to non-sensitive fields), read_semantic_catalog (read the published semantic model: tables, metrics, dimensions), query_metrics (run a semantic metric query \u2014 the only way to get business numbers). Do NOT put meta-tool actions (list_tables/read_table_meta/create_table/update_table/list_metrics/read_metric_meta/create_metric/update_metric) here"
|
|
41750
|
-
),
|
|
41751
|
-
connectionKey: import_zod57.default.string().optional().describe("Connection key. Omit when only one semantic-metrics connection exists"),
|
|
41752
|
-
datasourceId: import_zod57.default.coerce.number().optional().describe("Numeric datasource id, e.g. 15 (required for read_semantic_catalog; optional if set in runConfig.metricsDataSource)"),
|
|
41753
|
-
query: import_zod57.default.record(import_zod57.default.unknown()).optional().describe('Semantic metric query request. Required for the query_metrics action, e.g. { datasourceId: 15, metrics: ["sell_in_nes"], groupBy: ["sales_team"], filters: [{ dimension: "posting_year", operator: "GTE", values: [2024] }], limit: 10 }')
|
|
41754
|
-
})
|
|
41755
|
-
}
|
|
41756
|
-
);
|
|
41757
|
-
}
|
|
41758
|
-
|
|
41759
|
-
// src/middlewares/semanticMetricsModelingSkill.ts
|
|
41760
|
-
var CONTENT = `---
|
|
41761
|
-
name: semantic-metrics-modeling
|
|
41762
|
-
description: Builder policy for turning a granted datasource into published semantic tables and metrics. Governs goal agreement, FEP verification, persistent-task tracking, belief-state updates, and continuous refinement until acceptance evidence is met.
|
|
41763
|
-
---
|
|
41764
|
-
|
|
41765
|
-
# Semantic Metrics Modeling
|
|
41766
|
-
|
|
41767
|
-
You are the Semantic Metrics Builder. You turn physical datasource tables into reusable
|
|
41768
|
-
**semantic tables** and **business metrics** on a Metrics Server (\`/api/v1\`). Work is
|
|
41769
|
-
governed, observable, and continuously refined \u2014 never a one-shot guess.
|
|
41770
|
-
|
|
41771
|
-
## Goal Model
|
|
41772
|
-
|
|
41773
|
-
Before any exploration or publishing, agree with the user on:
|
|
41774
|
-
- **Real goal**: the business outcome (which metrics, for what decision), not just "make a table".
|
|
41775
|
-
- **Consumer**: who reads the result and how.
|
|
41776
|
-
- **Usable state**: observable conditions that make the published meta useful.
|
|
41777
|
-
- **Scope**: which datasource/tables, and what is explicitly out of scope.
|
|
41778
|
-
- **Acceptance evidence**: objective criteria (e.g. "metric \`sell_in_nes\` returns sane monthly
|
|
41779
|
-
totals for 2024") used to decide success.
|
|
41780
|
-
Do not guess material goals, consumers, or acceptance evidence.
|
|
41781
|
-
|
|
41782
|
-
**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\`, \`list_tables\`,
|
|
41784
|
-
\`list_metrics\`) to see what is authorized and already published, then ask focused questions that
|
|
41785
|
-
carry that context and offer concrete options (which datasource/tables, which business questions,
|
|
41786
|
-
extend existing metrics or build new). Every clarification question must include enough context and
|
|
41787
|
-
options for the user to answer in one step. Only after the user picks a direction does the Goal
|
|
41788
|
-
Model become confirmable \u2014 record it, create the task, and proceed to the workflow.
|
|
41789
|
-
|
|
41790
|
-
## Target model and quality bar
|
|
41791
|
-
|
|
41792
|
-
Your goal is a specific, verifiable artifact, not "some tables and metrics".
|
|
41793
|
-
|
|
41794
|
-
**Target shape** \u2014 one delivery is:
|
|
41795
|
-
- a published \`table_view_detail\` meta per logical table, with every column tagged
|
|
41796
|
-
\`role\` (dimension | measure) and a business-readable \`label\`;
|
|
41797
|
-
- a \`metric_index\` + \`metric_detail\` pair per metric, using the SQL-free \`calculation\` DSL;
|
|
41798
|
-
- the set, taken together, answers the user's concrete business question.
|
|
41799
|
-
|
|
41800
|
-
**Publish gate (self-check every metric before create)** \u2014 if any fails, do **not** publish; go
|
|
41801
|
-
explore or ask the user:
|
|
41802
|
-
1. measure: an aggregation is chosen **and** its business meaning is confirmed (net/gross, currency, dedupe or not);
|
|
41803
|
-
2. dimension: has a business meaning and a grain (day/month/year/\u2026);
|
|
41804
|
-
3. \`displayName\`/\`label\` are business-readable;
|
|
41805
|
-
4. the metric answers one concrete question from the user's stated goal;
|
|
41806
|
-
5. a runtime \`query\` returns numbers consistent with the confirmed meaning.
|
|
41807
|
-
|
|
41808
|
-
**Intent gaps first** \u2014 before diving into exploration, list the inputs you still need to meet the
|
|
41809
|
-
quality bar (business meaning, grain, target metric list, table scope, consumer) and ask for them
|
|
41810
|
-
explicitly. Exploration and user questions are both driven by this target shape and quality bar:
|
|
41811
|
-
missing business meaning \u2192 ask; unclear field semantics \u2192 probe or ask; right shape but it does not
|
|
41812
|
-
answer the business question \u2192 do not publish.
|
|
41813
|
-
|
|
41814
|
-
## FEP Loop
|
|
41815
|
-
|
|
41816
|
-
Apply this loop to every step (explore, publish table, publish metric, verify):
|
|
41817
|
-
**OBSERVE \u2192 HYPOTHESIZE \u2192 ACT \u2192 VERIFY \u2192 DECIDE \u2192 RECONCILE**
|
|
41818
|
-
|
|
41819
|
-
- **Observe**: current state, grants, published meta, and decision-relevant uncertainty.
|
|
41820
|
-
- **Hypothesize**: what evidence should appear if your model is right, and how each outcome changes the decision.
|
|
41821
|
-
- **Act**: one proportional action \u2014 no more than necessary.
|
|
41822
|
-
- **Verify**: compare the observed result (e.g. a runtime \`query\`) against the prediction.
|
|
41823
|
-
- **Decide**: classify as **RETAIN** (confirmed), **REVERT** (rejected), or **INCONCLUSIVE**.
|
|
41824
|
-
- **Reconcile**: update the belief state and plan, then repeat while decision-relevant action remains.
|
|
41825
|
-
|
|
41826
|
-
Renew user approval when a foundational assumption or the goal changes.
|
|
41827
|
-
|
|
41828
|
-
## Task Policy
|
|
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
|
|
41836
|
-
|
|
41837
|
-
Record your modeling beliefs in the active task's description under a \`## Belief State\` section as
|
|
41838
|
-
a Markdown table:
|
|
41839
|
-
|
|
41840
|
-
\`\`\`
|
|
41841
|
-
| Belief Key | Probability | Target | Basis |
|
|
41842
|
-
|---|---|---|---|
|
|
41843
|
-
| sell-in-nes-source-table | 70% | 100% | column \`nes\` probed as numeric measure in grant |
|
|
41844
|
-
\`\`\`
|
|
41845
|
-
|
|
41846
|
-
Rules: belief keys are lowercase kebab-case; probability/target are percentages 0\u2013100% that
|
|
41847
|
-
represent evidence support, not calibrated probability. Update this section each FEP reconcile so
|
|
41848
|
-
the task always reflects the current evidence.
|
|
41849
|
-
|
|
41850
|
-
## Workflow
|
|
41851
|
-
|
|
41852
|
-
1. **Pick the datasource.** \`metrics_datasource_tool\` action \`list_datasources\`, or the preset
|
|
41853
|
-
\`runConfig.metricsDataSource\` (\`serverKey\`\u2192connectionKey, \`datasourceId\`).
|
|
41854
|
-
2. **Read the boundary.** \`get_grants\` \u2192 note the allowed schema + table pattern. Never probe outside it.
|
|
41855
|
-
3. **Explore within the grant.** \`query\` with read-only SQL. Use the templates in
|
|
41856
|
-
\`references/metadata-sql.md\`; if the user supplied schema docs or sample files, read them first
|
|
41857
|
-
via filesystem to reduce querying.
|
|
41858
|
-
4. **Propose the model.** Present the table columns (with \`role: dimension | measure\`) and the
|
|
41859
|
-
metrics (aggregate/derived) for approval before publishing.
|
|
41860
|
-
5. **Publish the semantic table.** \`metrics_meta_tool\` \`create_table\`.
|
|
41861
|
-
6. **Publish the metric.** \`metrics_meta_tool\` \`create_metric\` \u2014 \`metric_index\` then \`metric_detail\`
|
|
41862
|
-
using the SQL-free \`calculation\` DSL.
|
|
41863
|
-
7. **Verify.** \`metrics_runtime_tool\` \`get_meta\`, then \`query\` the metric against acceptance evidence.
|
|
41864
|
-
|
|
41865
|
-
## 1. Explore
|
|
41866
|
-
|
|
41867
|
-
Read \`table-grants\`, then probe with \`query\`. SQL is validated read-only by the client and the
|
|
41868
|
-
server enforces the grant; un-granted tables return \`TABLE_NOT_GRANTED\`. Prefer the
|
|
41869
|
-
\`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 reconcile it
|
|
41871
|
-
against the probed columns.
|
|
41872
|
-
|
|
41873
|
-
## Unclear field semantics
|
|
41874
|
-
|
|
41875
|
-
A probed column name may not reveal its business meaning (e.g. whether \`nes\` is a net amount to
|
|
41876
|
-
sum, a rate to average, or an enum to filter). Publishing meta on a misunderstood field pollutes
|
|
41877
|
-
the runtime and every downstream metric that depends on it, and delete is not available. Treat this
|
|
41878
|
-
as FEP **INCONCLUSIVE** \u2014 never guess, and never publish on an unverified guess.
|
|
41879
|
-
|
|
41880
|
-
Resolve in order of increasing cost:
|
|
41881
|
-
1. **Probe sample values and distribution** (\`query\`, templates in \`references/metadata-sql.md\`):
|
|
41882
|
-
- numbers in (0,1) or clustered near 100 \u2192 likely a ratio/percentage \u2192 dimension or \`avg\`, rarely \`sum\`;
|
|
41883
|
-
- large additive amounts (currency, counts) \u2192 measure with \`sum\`;
|
|
41884
|
-
- small enumerations (year 2023/2024, 0/1 flags, codes) \u2192 dimension.
|
|
41885
|
-
The share of zeros/negatives and the value scale usually disambiguate semantics.
|
|
41886
|
-
2. **Read user-provided docs**: if the user supplied a data dictionary or sample file, read it via
|
|
41887
|
-
filesystem and reconcile it against the probed columns.
|
|
41888
|
-
3. **Cross-field correlation**: compare the unclear field with fields whose semantics are confirmed.
|
|
41889
|
-
|
|
41890
|
-
If evidence is still INCONCLUSIVE:
|
|
41891
|
-
- Do **not** publish meta that depends on the unclear field.
|
|
41892
|
-
- List the field with its candidate interpretations in the **Propose the model** step and ask the
|
|
41893
|
-
user to confirm its semantics (role, value meaning, net/gross) via ask_user_to_clarify. The user
|
|
41894
|
-
does not need to see the table \u2014 your probed schema, samples, and candidates are enough.
|
|
41895
|
-
- Record a low-probability belief entry (e.g.
|
|
41896
|
-
\`| sales-nes-semantics | 40% | 100% | user must confirm role / net amount |\`) so verify/refine can
|
|
41897
|
-
revisit it later instead of assuming it is settled.
|
|
41898
|
-
|
|
41899
|
-
## 2. Publish table meta (\`create_table\`)
|
|
41900
|
-
|
|
41901
|
-
Publish the authoritative shape below (objectType \`table_view_detail\`, with an EXACT accessGrant):
|
|
41902
|
-
|
|
41903
|
-
\`\`\`json
|
|
41904
|
-
{
|
|
41905
|
-
"objectType": "table_view_detail",
|
|
41906
|
-
"objectKey": "hankel_view_sales_summary",
|
|
41907
|
-
"status": 1,
|
|
41908
|
-
"payload": {
|
|
41909
|
-
"schemaName": "public",
|
|
41910
|
-
"tableName": "hankel_view_sales_summary",
|
|
41911
|
-
"displayName": "Hankel Sales Summary",
|
|
41912
|
-
"docType": "Sales Summary",
|
|
41913
|
-
"docTypeEn": "Sales Summary",
|
|
41914
|
-
"shortDesc": "Sales-level progress summary.",
|
|
41915
|
-
"grain": "canonical_sales_name",
|
|
41916
|
-
"sourceSystem": "Hankel Run for Gold",
|
|
41917
|
-
"sourceTables": ["hankel_project_opportunity_lines", "hankel_new_order_lines"],
|
|
41918
|
-
"columns": [
|
|
41919
|
-
{ "name": "canonical_sales_name", "label": "Canonical Sales Name", "type": "string", "role": "dimension", "description": "Standardized sales name used for grouping." },
|
|
41920
|
-
{ "name": "nes", "label": "NES", "type": "number", "role": "measure", "description": "Net external sales amount." },
|
|
41921
|
-
{ "name": "report_cutoff_date", "label": "Report Cutoff Date", "type": "date", "role": "time", "description": "Cutoff date of the report snapshot." }
|
|
41922
|
-
]
|
|
41923
|
-
},
|
|
41924
|
-
"accessGrant": {
|
|
41925
|
-
"schemaName": "public",
|
|
41926
|
-
"tablePattern": "hankel_view_sales_summary",
|
|
41927
|
-
"patternType": "EXACT",
|
|
41928
|
-
"caseSensitive": false,
|
|
41929
|
-
"status": 1
|
|
41930
|
-
}
|
|
41931
|
-
}
|
|
41932
|
-
\`\`\`
|
|
41933
|
-
|
|
41934
|
-
Design rules:
|
|
41935
|
-
- \`objectKey\` is stable and unique per datasource (the view/table key).
|
|
41936
|
-
- \`columns[].role\` has THREE values: \`dimension\` (grouping/filtering), \`measure\` (aggregated numbers), \`time\` (the report cutoff/snapshot date used by default_time_context).
|
|
41937
|
-
- Give every column a business \`description\`.
|
|
41938
|
-
- Lineage fields (\`docType\`, \`shortDesc\`, \`grain\`, \`sourceSystem\`, \`sourceTables\`) make the asset findable and trustworthy \u2014 fill them from exploration evidence.
|
|
41939
|
-
- Runtime table publication uses \`patternType: "EXACT"\` (\`PREFIX\` is only for datasource-level exploration scopes).
|
|
41940
|
-
- 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
|
-
|
|
41942
|
-
## 3. Publish metric meta (\`create_metric\`)
|
|
41943
|
-
|
|
41944
|
-
Two steps for the same \`objectKey\`.
|
|
41945
|
-
|
|
41946
|
-
### 3a. Metric index (for lists/search)
|
|
41947
|
-
|
|
41948
|
-
\`\`\`json
|
|
41949
|
-
{
|
|
41950
|
-
"objectType": "metric_index",
|
|
41951
|
-
"objectKey": "sell_in_nes",
|
|
41952
|
-
"status": 1,
|
|
41953
|
-
"payload": {
|
|
41954
|
-
"metric_name": "sell_in_nes",
|
|
41955
|
-
"display_name": "Sell-in NES",
|
|
41956
|
-
"domain": "sales",
|
|
41957
|
-
"short_desc": "Net external sales amount from distributor sell-in rows.",
|
|
41958
|
-
"search_keywords": ["sell in", "nes", "net external sales"],
|
|
41959
|
-
"source_type": "cdp_postgres",
|
|
41960
|
-
"source": { "table_view": "public.hankel_distr_sell_in" }
|
|
41961
|
-
}
|
|
41962
|
-
}
|
|
41963
|
-
\`\`\`
|
|
41964
|
-
|
|
41965
|
-
\`search_keywords\` drive metric retrieval for natural-language questions \u2014 include business synonyms.
|
|
41966
|
-
|
|
41967
|
-
### 3b. Metric detail (the calculation)
|
|
41968
|
-
|
|
41969
|
-
IMPORTANT \u2014 runtime schema requirement: the Metrics Server query runtime only recognizes metrics
|
|
41970
|
-
published in the FULL runtime style below (the same shape as existing working metrics, with
|
|
41971
|
-
snake_case fields like \`metric_name\`, \`source.table_view\`, \`supported_dimensions\` objects, and
|
|
41972
|
-
\`default_time_context\`). A minimal \`{name, sourceTable, calculation, dimensions}\` payload is
|
|
41973
|
-
accepted by the publish API but is NOT queryable \u2014 querying it returns 403 "not authorized".
|
|
41974
|
-
|
|
41975
|
-
Aggregate metric (full runtime style):
|
|
41976
|
-
|
|
41977
|
-
\`\`\`json
|
|
41978
|
-
{
|
|
41979
|
-
"objectType": "metric_detail",
|
|
41980
|
-
"objectKey": "sell_in_nes",
|
|
41981
|
-
"status": 1,
|
|
41982
|
-
"payload": {
|
|
41983
|
-
"metric_name": "sell_in_nes",
|
|
41984
|
-
"display_name": "Sell-in NES",
|
|
41985
|
-
"domain": "sales",
|
|
41986
|
-
"description": "Net external sales amount from distributor sell-in rows.",
|
|
41987
|
-
"data_type": "numeric",
|
|
41988
|
-
"format": "currency",
|
|
41989
|
-
"source_type": "cdp_postgres",
|
|
41990
|
-
"source": { "table_view": "public.hankel_distr_sell_in", "base_filters": [] },
|
|
41991
|
-
"calculation": { "type": "aggregate", "aggregation": "sum", "measure": "nes" },
|
|
41992
|
-
"supported_dimensions": [
|
|
41993
|
-
{ "dim_id": "posting_year", "field_name": "posting_year", "label": "Posting Year", "data_type": "number" },
|
|
41994
|
-
{ "dim_id": "sales_team", "field_name": "sales_team", "label": "Sales Team", "data_type": "string" }
|
|
41995
|
-
],
|
|
41996
|
-
"default_time_context": {
|
|
41997
|
-
"time_dimension": "posting_date",
|
|
41998
|
-
"label": "Posting date",
|
|
41999
|
-
"granularity": "month",
|
|
42000
|
-
"window": "YTD",
|
|
42001
|
-
"supported_grains": ["month", "year"]
|
|
42002
|
-
},
|
|
42003
|
-
"ai_agent_context": {
|
|
42004
|
-
"polarity": "positive",
|
|
42005
|
-
"synonyms": ["sell in", "nes", "net external sales"],
|
|
42006
|
-
"human_readable_explanation": "Higher sell-in NES means more goods purchased from the distributor."
|
|
42007
|
-
}
|
|
42008
|
-
}
|
|
42009
|
-
}
|
|
42010
|
-
\`\`\`
|
|
42011
|
-
|
|
42012
|
-
Derived ratio metric (references two aggregate metrics):
|
|
42013
|
-
|
|
42014
|
-
\`\`\`json
|
|
42015
|
-
{
|
|
42016
|
-
"objectType": "metric_detail",
|
|
42017
|
-
"objectKey": "gross_margin_rate",
|
|
42018
|
-
"status": 1,
|
|
42019
|
-
"payload": {
|
|
42020
|
-
"metric_name": "gross_margin_rate",
|
|
42021
|
-
"display_name": "Gross Margin Rate",
|
|
42022
|
-
"description": "Gross margin divided by sell-in NES.",
|
|
42023
|
-
"domain": "sales",
|
|
42024
|
-
"data_type": "numeric",
|
|
42025
|
-
"format": "percent",
|
|
42026
|
-
"source_type": "cdp_postgres",
|
|
42027
|
-
"source": { "table_view": "public.hankel_distr_sell_in", "base_filters": [] },
|
|
42028
|
-
"calculation": { "type": "derived", "operator": "ratio", "numerator": "gross_margin", "denominator": "sell_in_nes" },
|
|
42029
|
-
"supported_dimensions": [
|
|
42030
|
-
{ "dim_id": "posting_year", "field_name": "posting_year", "label": "Posting Year", "data_type": "number" }
|
|
42031
|
-
],
|
|
42032
|
-
"default_time_context": { "time_dimension": "posting_date", "granularity": "month", "supported_grains": ["month", "year"] }
|
|
42033
|
-
}
|
|
42034
|
-
}
|
|
42035
|
-
\`\`\`
|
|
42036
|
-
|
|
42037
|
-
Design rules:
|
|
42038
|
-
- \`objectKey\` unique per datasource (index and detail share it).
|
|
42039
|
-
- \`payload.metric_name\` must equal \`objectKey\`.
|
|
42040
|
-
- \`source.table_view\` must be schema-qualified and match the published table meta's physical table.
|
|
42041
|
-
- \`supported_dimensions\` is an array of OBJECTS ({dim_id, field_name, label, data_type}); include the time dimension too; each must be a published column of that table meta.
|
|
42042
|
-
- \`calculation.type: "aggregate"\` = one measure + aggregation (sum/avg/count/min/max/count_distinct).
|
|
42043
|
-
- \`calculation.type: "derived"\` operator \`ratio\` references existing metric objectKeys (numerator/denominator); a \`formula\` variant takes an expression of metric names, numbers, parentheses, and + - * / \u2014 referenced metrics must share the same source.table_view.
|
|
42044
|
-
- \`default_time_context\` (\`time_dimension\` + \`granularity\` + \`supported_grains\`, optionally \`window\`) is required by the query runtime; its \`time_dimension\` must appear in supported_dimensions.
|
|
42045
|
-
- \`ai_agent_context\` (\`polarity\`, \`synonyms\`, \`human_readable_explanation\`) improves natural-language metric retrieval \u2014 always provide it.
|
|
42046
|
-
- One semantic query can only combine metrics sharing the same source.table_view; groupBy values must be dim_ids or time-grain expressions like \`posting_date__month\`.
|
|
42047
|
-
- Do not inline raw SQL for new DB-backed metrics (complex logic belongs in a view).
|
|
42048
|
-
- Use \`update_metric\` / \`update_table\` to correct mistakes; no removal actions are exposed.
|
|
42049
|
-
|
|
42050
|
-
## 4. Verify and refine
|
|
42051
|
-
|
|
42052
|
-
- \`get_meta\` \u2192 confirm the table and metric are visible.
|
|
42053
|
-
- \`query\` the metric against the acceptance evidence. On failure, apply the FEP reconcile: update the
|
|
42054
|
-
\`## Belief State\`, fix the meta, and retry \u2014 until acceptance evidence is met.
|
|
42055
|
-
|
|
42056
|
-
## Troubleshooting
|
|
42057
|
-
|
|
42058
|
-
| Symptom | Cause / fix |
|
|
42059
|
-
|---|---|
|
|
42060
|
-
| \`TABLE_NOT_GRANTED\` | SQL referenced a table outside the tenant grant; pick an in-grant table |
|
|
42061
|
-
| metric create fails: sourceTable missing | publish the table meta first |
|
|
42062
|
-
| metric create fails: unknown dimension | publish the dimension column with \`role: dimension\` |
|
|
42063
|
-
| derived metric create fails | numerator/denominator metrics don't exist yet \u2014 publish them first |
|
|
42064
|
-
| datasource \`query\` rejected | SQL was not read-only (SELECT/WITH only) or multi-statement |
|
|
42065
|
-
| \`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 |
|
|
42066
|
-
|
|
42067
|
-
## Safety
|
|
42068
|
-
|
|
42069
|
-
- Only query tables that match the tenant's \`table-grants\`.
|
|
42070
|
-
- Never return a full physical-table inventory or reveal whether an un-granted table exists.
|
|
42071
|
-
- SQL is validated read-only; let the server reject anything outside that.
|
|
42072
|
-
`;
|
|
42073
|
-
var resources = {
|
|
42074
|
-
"references/metadata-sql.md": {
|
|
42075
|
-
content: `# Datasource exploration SQL templates (read-only)
|
|
42076
|
-
|
|
42077
|
-
Pick the block matching the server's database. These run through the datasource \`query\` action;
|
|
42078
|
-
the SQL is validated read-only.
|
|
42079
|
-
|
|
42080
|
-
## PostgreSQL
|
|
42081
|
-
- Tables: \`select table_schema, table_name from information_schema.tables where table_schema not in ('pg_catalog','information_schema') order by table_schema, table_name\`
|
|
42082
|
-
- Columns: \`select column_name, data_type from information_schema.columns where table_schema = :schemaName and table_name = :tableName order by ordinal_position\`
|
|
42083
|
-
- Sample: \`select * from :schemaName.:tableName limit :maxRows\` \u2014 pass a concrete table, not a bound param, if the server does not support binding identifiers.
|
|
42084
|
-
|
|
42085
|
-
## SQL Server
|
|
42086
|
-
- Tables: \`select table_schema, table_name from information_schema.tables order by table_schema, table_name\`
|
|
42087
|
-
- Columns: \`select column_name, data_type from information_schema.columns where table_schema = :schemaName and table_name = :tableName order by ordinal_position\`
|
|
42088
|
-
|
|
42089
|
-
## HANA
|
|
42090
|
-
- Tables: \`select schema_name, table_name from sys.tables where schema_name = :schemaName order by table_name\`
|
|
42091
|
-
- Columns: \`select column_name, data_type_name from table_columns where schema_name = :schemaName and table_name = :tableName order by position\`
|
|
42092
|
-
|
|
42093
|
-
## Value distribution (any dialect)
|
|
42094
|
-
\`select <dim>, count(*) as row_count from <table> group by <dim> order by row_count desc limit :maxRows\`
|
|
42095
|
-
`
|
|
42096
|
-
},
|
|
42097
|
-
"examples/table-meta.json": {
|
|
42098
|
-
content: `{
|
|
42099
|
-
"objectType": "table_view_detail",
|
|
42100
|
-
"objectKey": "hankel_distr_sell_in",
|
|
42101
|
-
"status": 1,
|
|
42102
|
-
"payload": {
|
|
42103
|
-
"schemaName": "public",
|
|
42104
|
-
"tableName": "hankel_distr_sell_in",
|
|
42105
|
-
"displayName": "Hankel Distributor Sell In",
|
|
42106
|
-
"description": "Distributor sell-in transaction rows for the Hankel tenant.",
|
|
42107
|
-
"columns": [
|
|
42108
|
-
{ "name": "posting_year", "label": "Posting Year", "type": "number", "role": "dimension" },
|
|
42109
|
-
{ "name": "posting_month", "label": "Posting Month", "type": "number", "role": "dimension" },
|
|
42110
|
-
{ "name": "sales_team", "label": "Sales Team", "type": "string", "role": "dimension" },
|
|
42111
|
-
{ "name": "region", "label": "Region", "type": "string", "role": "dimension" },
|
|
42112
|
-
{ "name": "nes", "label": "Net External Sales", "type": "number", "role": "measure" },
|
|
42113
|
-
{ "name": "gross_margin", "label": "Gross Margin", "type": "number", "role": "measure" }
|
|
42114
|
-
]
|
|
42115
|
-
}
|
|
42116
|
-
}
|
|
42117
|
-
`
|
|
42118
|
-
},
|
|
42119
|
-
"examples/metric-aggregate.json": {
|
|
42120
|
-
content: `{
|
|
42121
|
-
"objectType": "metric_detail",
|
|
42122
|
-
"objectKey": "hankel_sell_in_nes",
|
|
42123
|
-
"status": 1,
|
|
42124
|
-
"payload": {
|
|
42125
|
-
"name": "hankel_sell_in_nes",
|
|
42126
|
-
"displayName": "Sell-in NES",
|
|
42127
|
-
"description": "Net external sales amount from distributor sell-in rows.",
|
|
42128
|
-
"sourceTable": "hankel_distr_sell_in",
|
|
42129
|
-
"calculation": { "type": "aggregate", "aggregation": "sum", "measure": "nes" },
|
|
42130
|
-
"dimensions": ["posting_year", "posting_month", "sales_team", "region"]
|
|
42131
|
-
}
|
|
42132
|
-
}
|
|
42133
|
-
`
|
|
42134
|
-
},
|
|
42135
|
-
"examples/metric-derived.json": {
|
|
42136
|
-
content: `{
|
|
42137
|
-
"objectType": "metric_detail",
|
|
42138
|
-
"objectKey": "hankel_gross_margin_rate",
|
|
42139
|
-
"status": 1,
|
|
42140
|
-
"payload": {
|
|
42141
|
-
"name": "hankel_gross_margin_rate",
|
|
42142
|
-
"displayName": "Gross Margin Rate",
|
|
42143
|
-
"description": "Gross margin divided by sell-in NES.",
|
|
42144
|
-
"sourceTable": "hankel_distr_sell_in",
|
|
42145
|
-
"calculation": {
|
|
42146
|
-
"type": "derived",
|
|
42147
|
-
"operator": "ratio",
|
|
42148
|
-
"numerator": "hankel_gross_margin",
|
|
42149
|
-
"denominator": "hankel_sell_in_nes"
|
|
42150
|
-
},
|
|
42151
|
-
"dimensions": ["posting_year", "sales_team", "region"]
|
|
42152
|
-
}
|
|
42153
|
-
}
|
|
42154
|
-
`
|
|
42155
|
-
}
|
|
42156
|
-
};
|
|
42157
|
-
var SEMANTIC_METRICS_MODELING_SKILL = {
|
|
42158
|
-
version: "1.0.0",
|
|
42159
|
-
content: CONTENT,
|
|
42160
|
-
resources
|
|
42161
|
-
};
|
|
42162
|
-
|
|
42163
|
-
// src/middlewares/semanticMetricsBuilderPrompt.ts
|
|
42164
|
-
var SEMANTIC_METRICS_BUILDER_PROMPT = `You are the Semantic Metrics Builder.
|
|
42165
|
-
|
|
42166
|
-
CRITICAL FIRST ACTION: Before any response or other action, call the \`skill\`
|
|
42167
|
-
tool with skill_name: "semantic-metrics-modeling" to load semantic-metrics-modeling and follow it.
|
|
42168
|
-
Never announce the skill load. If it fails, retry once, then stop and explicitly
|
|
42169
|
-
report that the required Semantic Metrics Builder skill could not be loaded.`;
|
|
42170
|
-
|
|
42171
|
-
// src/middlewares/semanticMetricsMiddleware.ts
|
|
42172
|
-
var import_protocols32 = require("@axiom-lattice/protocols");
|
|
42173
|
-
function createSemanticMetricsMiddleware(config) {
|
|
42174
|
-
const connections = config.connections ?? [];
|
|
42175
|
-
const connectAll = config.connectAll === true;
|
|
42176
|
-
const selector = { connectionType: "semantic-metrics", connections, connectAll };
|
|
42177
|
-
return (0, import_langchain70.createMiddleware)({
|
|
42178
|
-
name: "SemanticMetrics",
|
|
42179
|
-
contextSchema,
|
|
42180
|
-
tools: [
|
|
42181
|
-
createMetricsDatasourceTool(selector),
|
|
42182
|
-
createMetricsMetaTool(selector),
|
|
42183
|
-
createMetricsRuntimeTool(selector)
|
|
42184
|
-
]
|
|
42185
|
-
});
|
|
42186
|
-
}
|
|
42187
|
-
function buildConnectionHeaders(config) {
|
|
42188
|
-
const headers = {
|
|
42189
|
-
Accept: "application/json",
|
|
42190
|
-
...config.headers !== void 0 && config.headers !== null ? config.headers : {}
|
|
42191
|
-
};
|
|
42192
|
-
if (config.apiKey) headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
42193
|
-
return headers;
|
|
42194
|
-
}
|
|
42195
|
-
function resolveBaseUrl(config) {
|
|
42196
|
-
const serverUrl = config.serverUrl;
|
|
42197
|
-
if (!serverUrl) {
|
|
42198
|
-
throw new Error("serverUrl is required");
|
|
42199
|
-
}
|
|
42200
|
-
return serverUrl.replace(/\/$/, "");
|
|
42201
|
-
}
|
|
42202
|
-
var semanticMetricsPlugin = {
|
|
42203
|
-
meta: {
|
|
42204
|
-
type: "semantic-metrics",
|
|
42205
|
-
category: "data",
|
|
42206
|
-
capabilityBundleEligible: true,
|
|
42207
|
-
openExpose: [
|
|
42208
|
-
// Query-only surface: no writes reach either tool (SQL is read-only).
|
|
42209
|
-
{ name: "metrics_datasource_tool", readOnly: true },
|
|
42210
|
-
{ name: "metrics_runtime_tool", readOnly: true }
|
|
42211
|
-
],
|
|
42212
|
-
name: "Semantic Metrics",
|
|
42213
|
-
description: "Semantic metrics datasource exploration, meta publishing, and runtime querying. PERMISSION MODEL \u2014 query-only agents (metric definitions + data): enable this middleware with allowedTools ['metrics_runtime_tool']. Metric designers (Builder): keep all three tools (metrics_datasource_tool, metrics_meta_tool, metrics_runtime_tool) for exploration, publishing, and verification, or use the built-in 'semantic-metrics-builder' agent.",
|
|
42214
|
-
version: "1.0.0",
|
|
42215
|
-
tools: [
|
|
42216
|
-
{ name: "metrics_datasource_tool", description: "Explore datasource structure within the tenant's granted scope" },
|
|
42217
|
-
{ name: "metrics_meta_tool", description: "Publish and maintain runtime semantic tables and metrics" },
|
|
42218
|
-
{ name: "metrics_runtime_tool", description: "Read runtime meta and execute semantic metric queries" }
|
|
42219
|
-
],
|
|
42220
|
-
configSchema: {
|
|
42221
|
-
type: "object",
|
|
42222
|
-
title: "Semantic Metrics Configuration",
|
|
42223
|
-
description: "First select connections (connections or connectAll). Then scope tools by role via allowedTools: QUERY-ONLY agents (metric definitions + data) set allowedTools to ['metrics_runtime_tool'] \u2014 it is self-contained (list_datasources, read_semantic_catalog, query_metrics); metric DESIGNERS keep all three tools (datasource exploration, meta publishing, runtime verification).",
|
|
42224
|
-
properties: {
|
|
42225
|
-
connections: {
|
|
42226
|
-
type: "array",
|
|
42227
|
-
title: "Connections",
|
|
42228
|
-
items: { type: "string" },
|
|
42229
|
-
widget: "connectionSelect"
|
|
42230
|
-
},
|
|
42231
|
-
connectAll: {
|
|
42232
|
-
type: "boolean",
|
|
42233
|
-
title: "Connect All",
|
|
42234
|
-
default: false,
|
|
42235
|
-
widget: "switch"
|
|
42236
|
-
}
|
|
42237
|
-
}
|
|
42238
|
-
},
|
|
42239
|
-
defaultConfig: { connections: [], connectAll: false }
|
|
42240
|
-
},
|
|
42241
|
-
connection: {
|
|
42242
|
-
// PluginConnectionFieldSchema.type supports only string/number/boolean/password,
|
|
42243
|
-
// so headers is NOT a form field; the V2 client still reads config.headers at runtime.
|
|
42244
|
-
fields: [
|
|
42245
|
-
{ key: "serverUrl", type: "string", title: "Metrics Server Base URL (include /api/v1)", required: true },
|
|
42246
|
-
{ key: "apiKey", type: "password", title: "API Key (optional)" }
|
|
42247
|
-
],
|
|
42248
|
-
test: async (config) => {
|
|
42249
|
-
try {
|
|
42250
|
-
const baseUrl = resolveBaseUrl(config);
|
|
42251
|
-
const res = await fetch(`${baseUrl}/datasources`, {
|
|
42252
|
-
headers: buildConnectionHeaders(config)
|
|
42253
|
-
});
|
|
42254
|
-
const text = await res.text().catch(() => "");
|
|
42255
|
-
let ok = res.ok;
|
|
42256
|
-
let detail = "";
|
|
42257
|
-
try {
|
|
42258
|
-
const parsed = JSON.parse(text);
|
|
42259
|
-
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
42260
|
-
const code = parsed.code;
|
|
42261
|
-
if (typeof code === "number") {
|
|
42262
|
-
ok = res.ok && code === 200;
|
|
42263
|
-
if (!ok) detail = ` (${parsed.message ?? code})`;
|
|
42264
|
-
}
|
|
42265
|
-
}
|
|
42266
|
-
} catch {
|
|
42267
|
-
}
|
|
42268
|
-
return {
|
|
42269
|
-
ok,
|
|
42270
|
-
message: ok ? `Reachable at ${baseUrl}` : `HTTP ${res.status}${detail}`
|
|
42271
|
-
};
|
|
42272
|
-
} catch (err) {
|
|
42273
|
-
return {
|
|
42274
|
-
ok: false,
|
|
42275
|
-
message: `Cannot connect: ${err instanceof Error ? err.message : String(err)}`
|
|
42276
|
-
};
|
|
42277
|
-
}
|
|
42278
|
-
},
|
|
42279
|
-
discover: async (config) => {
|
|
42280
|
-
try {
|
|
42281
|
-
const baseUrl = resolveBaseUrl(config);
|
|
42282
|
-
const res = await fetch(`${baseUrl}/datasources`, {
|
|
42283
|
-
headers: buildConnectionHeaders(config)
|
|
42284
|
-
});
|
|
42285
|
-
const text = await res.text();
|
|
42286
|
-
if (!res.ok) {
|
|
42287
|
-
throw new Error(`HTTP ${res.status}${text ? `: ${text.slice(0, 200)}` : ""}`);
|
|
42288
|
-
}
|
|
42289
|
-
const parsed = JSON.parse(text);
|
|
42290
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
42291
|
-
throw new Error("Metrics server returned an unexpected payload (expected a JSON envelope)");
|
|
42292
|
-
}
|
|
42293
|
-
const envelope = parsed;
|
|
42294
|
-
if (typeof envelope.code === "number" && envelope.code !== 200) {
|
|
42295
|
-
throw new Error(envelope.message || `API ${envelope.code}`);
|
|
42296
|
-
}
|
|
42297
|
-
const data = envelope.data;
|
|
42298
|
-
if (!Array.isArray(data)) {
|
|
42299
|
-
throw new Error("Metrics server returned an unexpected payload (expected a datasource array)");
|
|
42300
|
-
}
|
|
42301
|
-
return data.filter((d) => {
|
|
42302
|
-
if (d === null || typeof d !== "object") return false;
|
|
42303
|
-
const id = d.id;
|
|
42304
|
-
return id !== void 0 && id !== null && id !== "";
|
|
42305
|
-
}).map((item) => ({
|
|
42306
|
-
id: String(item.id),
|
|
42307
|
-
name: item.name ?? String(item.id)
|
|
42308
|
-
}));
|
|
42309
|
-
} catch (err) {
|
|
42310
|
-
throw new Error(
|
|
42311
|
-
`Cannot discover datasources: ${err instanceof Error ? err.message : String(err)}`
|
|
42312
|
-
);
|
|
42313
|
-
}
|
|
42314
|
-
}
|
|
42315
|
-
},
|
|
42316
|
-
skills: {
|
|
42317
|
-
"semantic-metrics-modeling": SEMANTIC_METRICS_MODELING_SKILL
|
|
42318
|
-
},
|
|
42319
|
-
agents: {
|
|
42320
|
-
"semantic-metrics-builder": {
|
|
42321
|
-
key: "semantic-metrics-builder",
|
|
42322
|
-
name: "Semantic Metrics Builder",
|
|
42323
|
-
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: import_protocols32.AgentType.DEEP_AGENT,
|
|
42325
|
-
prompt: SEMANTIC_METRICS_BUILDER_PROMPT,
|
|
42326
|
-
middleware: [
|
|
42327
|
-
{
|
|
42328
|
-
id: "semantic-metrics",
|
|
42329
|
-
type: "semantic-metrics",
|
|
42330
|
-
name: "Semantic Metrics",
|
|
42331
|
-
description: "Explore datasources, publish table/meta metrics, query runtime",
|
|
42332
|
-
enabled: true,
|
|
42333
|
-
config: { connections: [], connectAll: true }
|
|
42334
|
-
},
|
|
42335
|
-
{
|
|
42336
|
-
id: "skill",
|
|
42337
|
-
type: "skill",
|
|
42338
|
-
name: "Skill",
|
|
42339
|
-
description: "Load the semantic-metrics-modeling policy and task-definition reference",
|
|
42340
|
-
enabled: true,
|
|
42341
|
-
config: { readAll: false, skills: ["semantic-metrics-modeling", "task-definition"] }
|
|
42342
|
-
},
|
|
42343
|
-
{
|
|
42344
|
-
id: "task",
|
|
42345
|
-
type: "task",
|
|
42346
|
-
name: "Task",
|
|
42347
|
-
description: "Persistent TaskItems as the planning surface; update Belief State in task descriptions",
|
|
42348
|
-
enabled: true,
|
|
42349
|
-
config: {}
|
|
42350
|
-
},
|
|
42351
|
-
{
|
|
42352
|
-
id: "ask_user_to_clarify",
|
|
42353
|
-
type: "ask_user_to_clarify",
|
|
42354
|
-
name: "Ask User",
|
|
42355
|
-
description: "Wait for user input at modeling approval gates",
|
|
42356
|
-
enabled: true,
|
|
42357
|
-
config: {}
|
|
42358
|
-
},
|
|
42359
|
-
{
|
|
42360
|
-
id: "filesystem",
|
|
42361
|
-
type: "filesystem",
|
|
42362
|
-
name: "Filesystem",
|
|
42363
|
-
description: "Read user-provided schema docs, data dictionaries, or sample data files",
|
|
42364
|
-
enabled: true,
|
|
42365
|
-
config: {}
|
|
42366
|
-
}
|
|
42367
|
-
]
|
|
42368
|
-
}
|
|
42369
|
-
},
|
|
42370
|
-
middleware: (config) => createSemanticMetricsMiddleware(config)
|
|
42371
|
-
};
|
|
42372
|
-
|
|
42373
41182
|
// src/middlewares/collectionMiddleware.ts
|
|
42374
|
-
var
|
|
41183
|
+
var import_langchain77 = require("langchain");
|
|
42375
41184
|
|
|
42376
41185
|
// src/tool_lattice/collection/list_collections.ts
|
|
42377
|
-
var
|
|
42378
|
-
var
|
|
41186
|
+
var import_zod55 = __toESM(require("zod"));
|
|
41187
|
+
var import_langchain67 = require("langchain");
|
|
42379
41188
|
|
|
42380
41189
|
// src/tool_lattice/collection/utils.ts
|
|
42381
41190
|
function getEffectiveCollectionScope(exeConfig, staticScope) {
|
|
@@ -42398,7 +41207,7 @@ var createListCollectionsTool = ({
|
|
|
42398
41207
|
collectionKeys,
|
|
42399
41208
|
connectAll
|
|
42400
41209
|
}) => {
|
|
42401
|
-
return (0,
|
|
41210
|
+
return (0, import_langchain67.tool)(
|
|
42402
41211
|
async (_input, _exeConfig) => {
|
|
42403
41212
|
try {
|
|
42404
41213
|
const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
|
|
@@ -42433,23 +41242,23 @@ var createListCollectionsTool = ({
|
|
|
42433
41242
|
{
|
|
42434
41243
|
name: "list_collections",
|
|
42435
41244
|
description: LIST_COLLECTIONS_DESCRIPTION,
|
|
42436
|
-
schema:
|
|
41245
|
+
schema: import_zod55.default.object({})
|
|
42437
41246
|
}
|
|
42438
41247
|
);
|
|
42439
41248
|
};
|
|
42440
41249
|
|
|
42441
41250
|
// src/tool_lattice/collection/search_collection.ts
|
|
42442
|
-
var
|
|
42443
|
-
var
|
|
41251
|
+
var import_zod56 = __toESM(require("zod"));
|
|
41252
|
+
var import_langchain68 = require("langchain");
|
|
42444
41253
|
var SEARCH_COLLECTION_DESCRIPTION = `Search for content within a specific collection using semantic (vector) similarity. Use the 'filter' parameter to narrow results by metadata fields (e.g., {"category": "cardiovascular"}). Returns the most relevant content entries with similarity scores.`;
|
|
42445
|
-
var searchSchema =
|
|
42446
|
-
collection:
|
|
42447
|
-
query:
|
|
42448
|
-
filter:
|
|
42449
|
-
top_k:
|
|
41254
|
+
var searchSchema = import_zod56.default.object({
|
|
41255
|
+
collection: import_zod56.default.string().describe("The collection name to search in"),
|
|
41256
|
+
query: import_zod56.default.string().describe("The search query text"),
|
|
41257
|
+
filter: import_zod56.default.record(import_zod56.default.unknown()).optional().describe("Metadata filter conditions"),
|
|
41258
|
+
top_k: import_zod56.default.number().optional().default(5).describe("Number of results to return")
|
|
42450
41259
|
});
|
|
42451
41260
|
var createSearchCollectionTool = (scope = { collectionKeys: [], connectAll: true }) => {
|
|
42452
|
-
return (0,
|
|
41261
|
+
return (0, import_langchain68.tool)(
|
|
42453
41262
|
async (input, _exeConfig) => {
|
|
42454
41263
|
try {
|
|
42455
41264
|
const { collection, query, filter: filter2, top_k } = input;
|
|
@@ -42515,10 +41324,10 @@ var createSearchCollectionTool = (scope = { collectionKeys: [], connectAll: true
|
|
|
42515
41324
|
};
|
|
42516
41325
|
|
|
42517
41326
|
// src/tool_lattice/collection/get_collection.ts
|
|
42518
|
-
var
|
|
42519
|
-
var
|
|
41327
|
+
var import_zod57 = __toESM(require("zod"));
|
|
41328
|
+
var import_langchain69 = require("langchain");
|
|
42520
41329
|
var GET_COLLECTION_DESCRIPTION = `Get a collection's full definition including its custom fields schema. Use this to discover what metadata fields are available before adding entries.`;
|
|
42521
|
-
var createGetCollectionTool = (scope = { collectionKeys: [], connectAll: true }) => (0,
|
|
41330
|
+
var createGetCollectionTool = (scope = { collectionKeys: [], connectAll: true }) => (0, import_langchain69.tool)(
|
|
42522
41331
|
async (input, _exeConfig) => {
|
|
42523
41332
|
try {
|
|
42524
41333
|
const scopeError = validateCollectionScope(input.name, _exeConfig, scope);
|
|
@@ -42543,24 +41352,24 @@ Embedding: ${c.embeddingKey}${fieldsDesc}`;
|
|
|
42543
41352
|
return `Error: ${error.message}`;
|
|
42544
41353
|
}
|
|
42545
41354
|
},
|
|
42546
|
-
{ name: "get_collection", description: GET_COLLECTION_DESCRIPTION, schema:
|
|
41355
|
+
{ name: "get_collection", description: GET_COLLECTION_DESCRIPTION, schema: import_zod57.default.object({ name: import_zod57.default.string().describe("Collection name") }) }
|
|
42547
41356
|
);
|
|
42548
41357
|
|
|
42549
41358
|
// src/tool_lattice/collection/create_collection.ts
|
|
42550
|
-
var
|
|
42551
|
-
var
|
|
42552
|
-
var createSchema =
|
|
42553
|
-
name:
|
|
42554
|
-
label:
|
|
42555
|
-
embeddingKey:
|
|
42556
|
-
fields:
|
|
42557
|
-
key:
|
|
42558
|
-
type:
|
|
42559
|
-
enumValues:
|
|
42560
|
-
required:
|
|
41359
|
+
var import_zod58 = __toESM(require("zod"));
|
|
41360
|
+
var import_langchain70 = require("langchain");
|
|
41361
|
+
var createSchema = import_zod58.default.object({
|
|
41362
|
+
name: import_zod58.default.string().describe("Collection name (lowercase, underscores only)"),
|
|
41363
|
+
label: import_zod58.default.string().describe("Display name"),
|
|
41364
|
+
embeddingKey: import_zod58.default.string().describe("Embedding model key"),
|
|
41365
|
+
fields: import_zod58.default.array(import_zod58.default.object({
|
|
41366
|
+
key: import_zod58.default.string().describe("Field key name"),
|
|
41367
|
+
type: import_zod58.default.enum(["string", "number", "enum"]).describe("Field data type"),
|
|
41368
|
+
enumValues: import_zod58.default.array(import_zod58.default.string()).optional().describe("Valid values for enum type"),
|
|
41369
|
+
required: import_zod58.default.boolean().optional().default(false).describe("Whether field is required")
|
|
42561
41370
|
})).optional().describe("Custom field definitions for entries in this collection")
|
|
42562
41371
|
});
|
|
42563
|
-
var createCreateCollectionTool = (scope = {}) => (0,
|
|
41372
|
+
var createCreateCollectionTool = (scope = {}) => (0, import_langchain70.tool)(
|
|
42564
41373
|
async (input, _exeConfig) => {
|
|
42565
41374
|
try {
|
|
42566
41375
|
const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
|
|
@@ -42586,20 +41395,20 @@ var createCreateCollectionTool = (scope = {}) => (0, import_langchain74.tool)(
|
|
|
42586
41395
|
);
|
|
42587
41396
|
|
|
42588
41397
|
// src/tool_lattice/collection/update_collection.ts
|
|
42589
|
-
var
|
|
42590
|
-
var
|
|
42591
|
-
var schema =
|
|
42592
|
-
name:
|
|
42593
|
-
label:
|
|
42594
|
-
embeddingKey:
|
|
42595
|
-
fields:
|
|
42596
|
-
key:
|
|
42597
|
-
type:
|
|
42598
|
-
enumValues:
|
|
42599
|
-
required:
|
|
41398
|
+
var import_zod59 = __toESM(require("zod"));
|
|
41399
|
+
var import_langchain71 = require("langchain");
|
|
41400
|
+
var schema = import_zod59.default.object({
|
|
41401
|
+
name: import_zod59.default.string().describe("Collection name"),
|
|
41402
|
+
label: import_zod59.default.string().optional().describe("New display name"),
|
|
41403
|
+
embeddingKey: import_zod59.default.string().optional().describe("New embedding model key"),
|
|
41404
|
+
fields: import_zod59.default.array(import_zod59.default.object({
|
|
41405
|
+
key: import_zod59.default.string().describe("Field key name"),
|
|
41406
|
+
type: import_zod59.default.enum(["string", "number", "enum"]).describe("Field data type"),
|
|
41407
|
+
enumValues: import_zod59.default.array(import_zod59.default.string()).optional().describe("Valid values for enum type"),
|
|
41408
|
+
required: import_zod59.default.boolean().optional().default(false).describe("Whether field is required")
|
|
42600
41409
|
})).optional().describe("Custom field definitions for entries (replaces existing schema)")
|
|
42601
41410
|
});
|
|
42602
|
-
var createUpdateCollectionTool = (scope = { collectionKeys: [], connectAll: true }) => (0,
|
|
41411
|
+
var createUpdateCollectionTool = (scope = { collectionKeys: [], connectAll: true }) => (0, import_langchain71.tool)(
|
|
42603
41412
|
async (input, _exeConfig) => {
|
|
42604
41413
|
try {
|
|
42605
41414
|
const scopeError = validateCollectionScope(input.name, _exeConfig, scope);
|
|
@@ -42620,9 +41429,9 @@ var createUpdateCollectionTool = (scope = { collectionKeys: [], connectAll: true
|
|
|
42620
41429
|
);
|
|
42621
41430
|
|
|
42622
41431
|
// src/tool_lattice/collection/delete_collection.ts
|
|
42623
|
-
var
|
|
42624
|
-
var
|
|
42625
|
-
var createDeleteCollectionTool = (scope = { collectionKeys: [], connectAll: true }) => (0,
|
|
41432
|
+
var import_zod60 = __toESM(require("zod"));
|
|
41433
|
+
var import_langchain72 = require("langchain");
|
|
41434
|
+
var createDeleteCollectionTool = (scope = { collectionKeys: [], connectAll: true }) => (0, import_langchain72.tool)(
|
|
42626
41435
|
async (input, _exeConfig) => {
|
|
42627
41436
|
try {
|
|
42628
41437
|
const scopeError = validateCollectionScope(input.name, _exeConfig, scope);
|
|
@@ -42634,19 +41443,19 @@ var createDeleteCollectionTool = (scope = { collectionKeys: [], connectAll: true
|
|
|
42634
41443
|
return `Error: ${e.message}`;
|
|
42635
41444
|
}
|
|
42636
41445
|
},
|
|
42637
|
-
{ name: "delete_collection", description: `Delete a collection and all its entries. This cannot be undone.`, schema:
|
|
41446
|
+
{ name: "delete_collection", description: `Delete a collection and all its entries. This cannot be undone.`, schema: import_zod60.default.object({ name: import_zod60.default.string().describe("Collection name") }) }
|
|
42638
41447
|
);
|
|
42639
41448
|
|
|
42640
41449
|
// src/tool_lattice/collection/list_entries.ts
|
|
42641
|
-
var
|
|
42642
|
-
var
|
|
42643
|
-
var schema2 =
|
|
42644
|
-
collection:
|
|
41450
|
+
var import_zod61 = __toESM(require("zod"));
|
|
41451
|
+
var import_langchain73 = require("langchain");
|
|
41452
|
+
var schema2 = import_zod61.default.object({
|
|
41453
|
+
collection: import_zod61.default.string().describe("Collection name")
|
|
42645
41454
|
});
|
|
42646
41455
|
function buildKey2(tenantId2, name) {
|
|
42647
41456
|
return `${tenantId2}:${name}`;
|
|
42648
41457
|
}
|
|
42649
|
-
var createListEntriesTool = (scope = { collectionKeys: [], connectAll: true }) => (0,
|
|
41458
|
+
var createListEntriesTool = (scope = { collectionKeys: [], connectAll: true }) => (0, import_langchain73.tool)(
|
|
42650
41459
|
async (input, _exeConfig) => {
|
|
42651
41460
|
try {
|
|
42652
41461
|
const scopeError = validateCollectionScope(input.collection, _exeConfig, scope);
|
|
@@ -42675,19 +41484,19 @@ var createListEntriesTool = (scope = { collectionKeys: [], connectAll: true }) =
|
|
|
42675
41484
|
);
|
|
42676
41485
|
|
|
42677
41486
|
// src/tool_lattice/collection/add_entry.ts
|
|
42678
|
-
var
|
|
42679
|
-
var
|
|
41487
|
+
var import_zod62 = __toESM(require("zod"));
|
|
41488
|
+
var import_langchain74 = require("langchain");
|
|
42680
41489
|
var import_documents = require("@langchain/core/documents");
|
|
42681
41490
|
var import_uuid12 = require("uuid");
|
|
42682
|
-
var schema3 =
|
|
42683
|
-
collection:
|
|
42684
|
-
content:
|
|
42685
|
-
metadata:
|
|
41491
|
+
var schema3 = import_zod62.default.object({
|
|
41492
|
+
collection: import_zod62.default.string().describe("Collection name"),
|
|
41493
|
+
content: import_zod62.default.string().describe("Entry content text"),
|
|
41494
|
+
metadata: import_zod62.default.record(import_zod62.default.unknown()).optional().describe("Metadata fields matching the collection schema")
|
|
42686
41495
|
});
|
|
42687
41496
|
function key2(t, n) {
|
|
42688
41497
|
return `${t}:${n}`;
|
|
42689
41498
|
}
|
|
42690
|
-
var createAddEntryTool = (scope = { collectionKeys: [], connectAll: true }) => (0,
|
|
41499
|
+
var createAddEntryTool = (scope = { collectionKeys: [], connectAll: true }) => (0, import_langchain74.tool)(
|
|
42691
41500
|
async (input, _exeConfig) => {
|
|
42692
41501
|
try {
|
|
42693
41502
|
const scopeError = validateCollectionScope(input.collection, _exeConfig, scope);
|
|
@@ -42719,18 +41528,18 @@ var createAddEntryTool = (scope = { collectionKeys: [], connectAll: true }) => (
|
|
|
42719
41528
|
);
|
|
42720
41529
|
|
|
42721
41530
|
// src/tool_lattice/collection/update_entry.ts
|
|
42722
|
-
var
|
|
42723
|
-
var
|
|
42724
|
-
var schema4 =
|
|
42725
|
-
collection:
|
|
42726
|
-
entryId:
|
|
42727
|
-
content:
|
|
42728
|
-
metadata:
|
|
41531
|
+
var import_zod63 = __toESM(require("zod"));
|
|
41532
|
+
var import_langchain75 = require("langchain");
|
|
41533
|
+
var schema4 = import_zod63.default.object({
|
|
41534
|
+
collection: import_zod63.default.string().describe("Collection name"),
|
|
41535
|
+
entryId: import_zod63.default.string().describe("Entry ID to update"),
|
|
41536
|
+
content: import_zod63.default.string().optional().describe("New content"),
|
|
41537
|
+
metadata: import_zod63.default.record(import_zod63.default.unknown()).optional().describe("New metadata")
|
|
42729
41538
|
});
|
|
42730
41539
|
function key3(t, n) {
|
|
42731
41540
|
return `${t}:${n}`;
|
|
42732
41541
|
}
|
|
42733
|
-
var createUpdateEntryTool = (scope = { collectionKeys: [], connectAll: true }) => (0,
|
|
41542
|
+
var createUpdateEntryTool = (scope = { collectionKeys: [], connectAll: true }) => (0, import_langchain75.tool)(
|
|
42734
41543
|
async (input, _exeConfig) => {
|
|
42735
41544
|
try {
|
|
42736
41545
|
const scopeError = validateCollectionScope(input.collection, _exeConfig, scope);
|
|
@@ -42751,16 +41560,16 @@ var createUpdateEntryTool = (scope = { collectionKeys: [], connectAll: true }) =
|
|
|
42751
41560
|
);
|
|
42752
41561
|
|
|
42753
41562
|
// src/tool_lattice/collection/delete_entry.ts
|
|
42754
|
-
var
|
|
42755
|
-
var
|
|
42756
|
-
var schema5 =
|
|
42757
|
-
collection:
|
|
42758
|
-
entryId:
|
|
41563
|
+
var import_zod64 = __toESM(require("zod"));
|
|
41564
|
+
var import_langchain76 = require("langchain");
|
|
41565
|
+
var schema5 = import_zod64.default.object({
|
|
41566
|
+
collection: import_zod64.default.string().describe("Collection name"),
|
|
41567
|
+
entryId: import_zod64.default.string().describe("Entry ID to delete")
|
|
42759
41568
|
});
|
|
42760
41569
|
function key4(t, n) {
|
|
42761
41570
|
return `${t}:${n}`;
|
|
42762
41571
|
}
|
|
42763
|
-
var createDeleteEntryTool = (scope = { collectionKeys: [], connectAll: true }) => (0,
|
|
41572
|
+
var createDeleteEntryTool = (scope = { collectionKeys: [], connectAll: true }) => (0, import_langchain76.tool)(
|
|
42764
41573
|
async (input, _exeConfig) => {
|
|
42765
41574
|
try {
|
|
42766
41575
|
const scopeError = validateCollectionScope(input.collection, _exeConfig, scope);
|
|
@@ -42780,7 +41589,7 @@ var createDeleteEntryTool = (scope = { collectionKeys: [], connectAll: true }) =
|
|
|
42780
41589
|
function createCollectionMiddleware(params) {
|
|
42781
41590
|
const { collectionKeys, connectAll, compileStableCandidateTools = false } = params;
|
|
42782
41591
|
if (!compileStableCandidateTools && !connectAll && (!collectionKeys || collectionKeys.length === 0)) {
|
|
42783
|
-
return (0,
|
|
41592
|
+
return (0, import_langchain77.createMiddleware)({
|
|
42784
41593
|
name: "collectionMiddleware",
|
|
42785
41594
|
contextSchema,
|
|
42786
41595
|
tools: [
|
|
@@ -42790,7 +41599,7 @@ function createCollectionMiddleware(params) {
|
|
|
42790
41599
|
});
|
|
42791
41600
|
}
|
|
42792
41601
|
const toolParams = { collectionKeys, connectAll };
|
|
42793
|
-
return (0,
|
|
41602
|
+
return (0, import_langchain77.createMiddleware)({
|
|
42794
41603
|
name: "collectionMiddleware",
|
|
42795
41604
|
contextSchema,
|
|
42796
41605
|
tools: [
|
|
@@ -42853,24 +41662,24 @@ var collectionPlugin = {
|
|
|
42853
41662
|
};
|
|
42854
41663
|
|
|
42855
41664
|
// src/middlewares/askUserClarifyMiddleware.ts
|
|
42856
|
-
var
|
|
42857
|
-
var
|
|
41665
|
+
var import_langchain79 = require("langchain");
|
|
41666
|
+
var import_langgraph15 = require("@langchain/langgraph");
|
|
42858
41667
|
|
|
42859
41668
|
// src/tool_lattice/ask_user_to_clarify/index.ts
|
|
42860
|
-
var
|
|
42861
|
-
var
|
|
42862
|
-
var questionSchema =
|
|
42863
|
-
question:
|
|
42864
|
-
options:
|
|
42865
|
-
type:
|
|
42866
|
-
required:
|
|
42867
|
-
allowOther:
|
|
41669
|
+
var import_langchain78 = require("langchain");
|
|
41670
|
+
var import_zod65 = __toESM(require("zod"));
|
|
41671
|
+
var questionSchema = import_zod65.default.object({
|
|
41672
|
+
question: import_zod65.default.string().describe("The question text to ask the user. MUST include the specific context, options, or details being clarified \u2014 never use a bare generic label. Good: 'Confirm the plan: use Redis cache + PostgreSQL primary, split microservices as needed?' Bad: 'Confirm the plan?'"),
|
|
41673
|
+
options: import_zod65.default.array(import_zod65.default.string()).optional().default([]).describe("List of EXACT, selectable values. Maximum 3 options allowed. DO NOT include placeholder values like 'Other' or 'Enter manually'. For free-text with predefined choices, use allowOther=true (works with 'single' and 'multiple'). For pure free-text without choices, use type='input' instead. For file_upload and input, pass an empty array."),
|
|
41674
|
+
type: import_zod65.default.enum(["single", "multiple", "file_upload", "input"]).describe("The question format. 'single' = pick one from options (default, see tool description for guidance). 'multiple' = pick several from options. 'input' = free-text field (only when options cannot express the answer). 'file_upload' = file picker."),
|
|
41675
|
+
required: import_zod65.default.boolean().optional().default(false).describe("Whether this question must be answered"),
|
|
41676
|
+
allowOther: import_zod65.default.boolean().optional().default(true).describe("Set to true to append an 'Other' checkbox with a free-text input field. Works with 'single' and 'multiple' types. Use for open-ended answers or when the options cannot cover all possibilities. Not applicable for 'input' or 'file_upload' types.")
|
|
42868
41677
|
});
|
|
42869
|
-
var inputSchema =
|
|
42870
|
-
questions:
|
|
41678
|
+
var inputSchema = import_zod65.default.object({
|
|
41679
|
+
questions: import_zod65.default.array(questionSchema).min(1, "At least one question is required").describe("A structured sequence of clarification questions. Use these to gather missing parameters or disambiguate user intent before proceeding.")
|
|
42871
41680
|
});
|
|
42872
41681
|
function createAskUserToClarifyTool() {
|
|
42873
|
-
return (0,
|
|
41682
|
+
return (0, import_langchain78.tool)(
|
|
42874
41683
|
async (input) => {
|
|
42875
41684
|
return JSON.stringify(input);
|
|
42876
41685
|
},
|
|
@@ -42895,7 +41704,7 @@ function isProjectRoomRun(request) {
|
|
|
42895
41704
|
return isRecord9(runConfig?.projectRoom);
|
|
42896
41705
|
}
|
|
42897
41706
|
function createAskUserClarifyMiddleware() {
|
|
42898
|
-
return (0,
|
|
41707
|
+
return (0, import_langchain79.createMiddleware)({
|
|
42899
41708
|
name: "AskUserClarifyMiddleware",
|
|
42900
41709
|
tools: [createAskUserToClarifyTool()],
|
|
42901
41710
|
wrapToolCall: async (request, handler) => {
|
|
@@ -42905,7 +41714,7 @@ function createAskUserClarifyMiddleware() {
|
|
|
42905
41714
|
return handler(request);
|
|
42906
41715
|
}
|
|
42907
41716
|
if (isProjectRoomRun(request)) {
|
|
42908
|
-
return new
|
|
41717
|
+
return new import_langchain79.ToolMessage({
|
|
42909
41718
|
content: "You are replying inside a project room, which has no interactive clarification UI. Ask your clarifying questions directly in your reply text and stop; the user's next room message will continue the conversation.",
|
|
42910
41719
|
tool_call_id: toolCall?.id,
|
|
42911
41720
|
name: toolName2
|
|
@@ -42913,7 +41722,7 @@ function createAskUserClarifyMiddleware() {
|
|
|
42913
41722
|
}
|
|
42914
41723
|
const parsed = inputSchema.safeParse(toolCall?.args);
|
|
42915
41724
|
if (!parsed.success) {
|
|
42916
|
-
return new
|
|
41725
|
+
return new import_langchain79.ToolMessage({
|
|
42917
41726
|
content: `Invalid clarify tool arguments: ${parsed.error.message}`,
|
|
42918
41727
|
tool_call_id: toolCall?.id,
|
|
42919
41728
|
name: toolName2
|
|
@@ -42930,10 +41739,10 @@ function createAskUserClarifyMiddleware() {
|
|
|
42930
41739
|
}))
|
|
42931
41740
|
};
|
|
42932
41741
|
const md = genUIMarkdown("clarify", uiData);
|
|
42933
|
-
const result = await (0,
|
|
41742
|
+
const result = await (0, import_langgraph15.interrupt)(md);
|
|
42934
41743
|
const response = result.data;
|
|
42935
41744
|
if (!response?.answers || response.answers.length === 0) {
|
|
42936
|
-
return new
|
|
41745
|
+
return new import_langchain79.ToolMessage({
|
|
42937
41746
|
content: "No clarification questions were answered.",
|
|
42938
41747
|
tool_call_id: toolCall?.id,
|
|
42939
41748
|
name: toolName2
|
|
@@ -42943,7 +41752,7 @@ function createAskUserClarifyMiddleware() {
|
|
|
42943
41752
|
(answer) => (answer.selectedOptions?.length ?? 0) > 0 || answer.otherText && answer.otherText.trim() !== "" || answer.filePath && answer.filePath.trim() !== ""
|
|
42944
41753
|
);
|
|
42945
41754
|
if (answeredQuestions.length === 0) {
|
|
42946
|
-
return new
|
|
41755
|
+
return new import_langchain79.ToolMessage({
|
|
42947
41756
|
content: "No clarification questions were answered.",
|
|
42948
41757
|
tool_call_id: toolCall?.id,
|
|
42949
41758
|
name: toolName2
|
|
@@ -42973,7 +41782,7 @@ function createAskUserClarifyMiddleware() {
|
|
|
42973
41782
|
}
|
|
42974
41783
|
lines.push("");
|
|
42975
41784
|
}
|
|
42976
|
-
return new
|
|
41785
|
+
return new import_langchain79.ToolMessage({
|
|
42977
41786
|
content: lines.join("\n"),
|
|
42978
41787
|
tool_call_id: toolCall?.id,
|
|
42979
41788
|
name: toolName2
|
|
@@ -42999,11 +41808,11 @@ var askUserClarifyPlugin = {
|
|
|
42999
41808
|
};
|
|
43000
41809
|
|
|
43001
41810
|
// src/middlewares/widgetMiddleware.ts
|
|
43002
|
-
var
|
|
41811
|
+
var import_langchain82 = require("langchain");
|
|
43003
41812
|
|
|
43004
41813
|
// src/tool_lattice/widget/loadGuidelines.ts
|
|
43005
|
-
var
|
|
43006
|
-
var
|
|
41814
|
+
var import_langchain80 = require("langchain");
|
|
41815
|
+
var import_zod66 = require("zod");
|
|
43007
41816
|
|
|
43008
41817
|
// src/middlewares/guidelines/index.ts
|
|
43009
41818
|
var CORE = `# Imagine \u2014 Visual Creation Suite
|
|
@@ -43794,13 +42603,13 @@ function getGuidelines(modules) {
|
|
|
43794
42603
|
var AVAILABLE_MODULES = Object.keys(MODULE_SECTIONS);
|
|
43795
42604
|
|
|
43796
42605
|
// src/tool_lattice/widget/loadGuidelines.ts
|
|
43797
|
-
var LoadGuidelinesInputSchema =
|
|
43798
|
-
modules:
|
|
42606
|
+
var LoadGuidelinesInputSchema = import_zod66.z.object({
|
|
42607
|
+
modules: import_zod66.z.array(import_zod66.z.string()).describe(
|
|
43799
42608
|
"Which design modules to load. Choose all that apply. Available modules: [" + AVAILABLE_MODULES.join(",") + "]"
|
|
43800
42609
|
)
|
|
43801
42610
|
});
|
|
43802
42611
|
function createLoadGuidelinesTool() {
|
|
43803
|
-
return (0,
|
|
42612
|
+
return (0, import_langchain80.tool)(
|
|
43804
42613
|
async (input) => {
|
|
43805
42614
|
const result = getGuidelines(input.modules);
|
|
43806
42615
|
return result;
|
|
@@ -43814,8 +42623,8 @@ function createLoadGuidelinesTool() {
|
|
|
43814
42623
|
}
|
|
43815
42624
|
|
|
43816
42625
|
// src/tool_lattice/widget/showWidget.ts
|
|
43817
|
-
var
|
|
43818
|
-
var
|
|
42626
|
+
var import_langchain81 = require("langchain");
|
|
42627
|
+
var import_zod67 = require("zod");
|
|
43819
42628
|
function containsForbiddenTags(code) {
|
|
43820
42629
|
const forbiddenPatterns = [
|
|
43821
42630
|
/<!DOCTYPE/i,
|
|
@@ -43837,20 +42646,20 @@ function validateWidgetCode(code) {
|
|
|
43837
42646
|
}
|
|
43838
42647
|
return { valid: true };
|
|
43839
42648
|
}
|
|
43840
|
-
var ShowWidgetInputSchema =
|
|
43841
|
-
i_have_seen_guidelines:
|
|
42649
|
+
var ShowWidgetInputSchema = import_zod67.z.object({
|
|
42650
|
+
i_have_seen_guidelines: import_zod67.z.boolean().describe(
|
|
43842
42651
|
"Must be true. Confirm you have called load_guidelines first."
|
|
43843
42652
|
),
|
|
43844
|
-
title:
|
|
43845
|
-
loading_messages:
|
|
42653
|
+
title: import_zod67.z.string().describe("Title displayed above the widget"),
|
|
42654
|
+
loading_messages: import_zod67.z.array(import_zod67.z.string()).optional().describe(
|
|
43846
42655
|
"1-4 short strings shown while the widget renders"
|
|
43847
42656
|
),
|
|
43848
|
-
widget_code:
|
|
42657
|
+
widget_code: import_zod67.z.string().describe(
|
|
43849
42658
|
"HTML fragment to render. Rules: 1. No DOCTYPE, <html>, <head>, or <body> tags. 2. Order: <style> block first, then HTML content, then <script> last. 3. Use only CSS variables for colors (e.g. var(--color-accent)). 4. No gradients, shadows, or blur effects. For SVG: start directly with <svg> tag."
|
|
43850
42659
|
)
|
|
43851
42660
|
});
|
|
43852
42661
|
function createShowWidgetTool() {
|
|
43853
|
-
return (0,
|
|
42662
|
+
return (0, import_langchain81.tool)(
|
|
43854
42663
|
async (input) => {
|
|
43855
42664
|
if (!input.i_have_seen_guidelines) {
|
|
43856
42665
|
return "Error: You must call load_guidelines before using show_widget. Set i_have_seen_guidelines to true only after loading guidelines.";
|
|
@@ -43881,7 +42690,7 @@ function createWidgetMiddleware() {
|
|
|
43881
42690
|
createLoadGuidelinesTool(),
|
|
43882
42691
|
createShowWidgetTool()
|
|
43883
42692
|
];
|
|
43884
|
-
return (0,
|
|
42693
|
+
return (0, import_langchain82.createMiddleware)({
|
|
43885
42694
|
name: "widgetMiddleware",
|
|
43886
42695
|
contextSchema,
|
|
43887
42696
|
tools
|
|
@@ -43905,9 +42714,67 @@ var widgetPlugin = {
|
|
|
43905
42714
|
};
|
|
43906
42715
|
|
|
43907
42716
|
// src/middlewares/taskMiddleware.ts
|
|
43908
|
-
var
|
|
43909
|
-
var
|
|
43910
|
-
var
|
|
42717
|
+
var import_langchain83 = require("langchain");
|
|
42718
|
+
var import_zod68 = require("zod");
|
|
42719
|
+
var import_langgraph16 = require("@langchain/langgraph");
|
|
42720
|
+
|
|
42721
|
+
// src/util/truncateForJson.ts
|
|
42722
|
+
var TRUNCATION_MARKER = "...[truncated]";
|
|
42723
|
+
function truncateString(value, cap) {
|
|
42724
|
+
if (value.length <= cap) return value;
|
|
42725
|
+
const budget = Math.max(0, cap - TRUNCATION_MARKER.length);
|
|
42726
|
+
return value.slice(0, budget) + TRUNCATION_MARKER;
|
|
42727
|
+
}
|
|
42728
|
+
function truncateValue(value, depth, maxDepth, maxEntries, maxStringLength, seen) {
|
|
42729
|
+
if (typeof value === "string") return truncateString(value, maxStringLength);
|
|
42730
|
+
if (value === null || typeof value !== "object") return value;
|
|
42731
|
+
if (depth >= maxDepth) return "[truncated:max-depth]";
|
|
42732
|
+
if (seen.has(value)) return "[Circular]";
|
|
42733
|
+
seen.add(value);
|
|
42734
|
+
try {
|
|
42735
|
+
if (value instanceof Date) return value.toISOString();
|
|
42736
|
+
if (Array.isArray(value)) {
|
|
42737
|
+
const limit2 = Math.min(value.length, maxEntries);
|
|
42738
|
+
const output2 = [];
|
|
42739
|
+
for (let index = 0; index < limit2; index += 1) {
|
|
42740
|
+
output2.push(truncateValue(value[index], depth + 1, maxDepth, maxEntries, maxStringLength, seen));
|
|
42741
|
+
}
|
|
42742
|
+
if (value.length > limit2) output2.push("[truncated:entries]");
|
|
42743
|
+
return output2;
|
|
42744
|
+
}
|
|
42745
|
+
const record = value;
|
|
42746
|
+
const output = {};
|
|
42747
|
+
const keys = Object.keys(record);
|
|
42748
|
+
const limit = Math.min(keys.length, maxEntries);
|
|
42749
|
+
for (let index = 0; index < limit; index += 1) {
|
|
42750
|
+
const key5 = keys[index];
|
|
42751
|
+
output[truncateString(key5, maxStringLength)] = truncateValue(
|
|
42752
|
+
record[key5],
|
|
42753
|
+
depth + 1,
|
|
42754
|
+
maxDepth,
|
|
42755
|
+
maxEntries,
|
|
42756
|
+
maxStringLength,
|
|
42757
|
+
seen
|
|
42758
|
+
);
|
|
42759
|
+
}
|
|
42760
|
+
if (keys.length > limit) output["[truncated]"] = true;
|
|
42761
|
+
return output;
|
|
42762
|
+
} finally {
|
|
42763
|
+
seen.delete(value);
|
|
42764
|
+
}
|
|
42765
|
+
}
|
|
42766
|
+
function truncateForJson(value, options = {}) {
|
|
42767
|
+
return truncateValue(
|
|
42768
|
+
value,
|
|
42769
|
+
0,
|
|
42770
|
+
options.maxDepth ?? JSON_SAFE_MAX_DEPTH,
|
|
42771
|
+
options.maxEntries ?? JSON_SAFE_MAX_COLLECTION_ENTRIES,
|
|
42772
|
+
options.maxStringLength ?? JSON_SAFE_MAX_STRING_LENGTH,
|
|
42773
|
+
/* @__PURE__ */ new WeakSet()
|
|
42774
|
+
);
|
|
42775
|
+
}
|
|
42776
|
+
|
|
42777
|
+
// src/middlewares/taskMiddleware.ts
|
|
43911
42778
|
var import_protocols33 = require("@axiom-lattice/protocols");
|
|
43912
42779
|
|
|
43913
42780
|
// src/middlewares/taskResponseSerialization.ts
|
|
@@ -44232,6 +43099,132 @@ function getRuntimeActor2(runConfig) {
|
|
|
44232
43099
|
if (runConfig.user_id) return `user:${String(runConfig.user_id)}`;
|
|
44233
43100
|
return void 0;
|
|
44234
43101
|
}
|
|
43102
|
+
function readRuntimeRunConfig(source) {
|
|
43103
|
+
const s = source;
|
|
43104
|
+
const rc = s?.context?.runConfig ?? s?.configurable?.runConfig;
|
|
43105
|
+
return rc && typeof rc === "object" && !Array.isArray(rc) ? rc : {};
|
|
43106
|
+
}
|
|
43107
|
+
function readExecutionTaskId(runConfig) {
|
|
43108
|
+
const execution = runConfig.execution;
|
|
43109
|
+
if (!execution || typeof execution !== "object" || Array.isArray(execution)) return void 0;
|
|
43110
|
+
const value = execution.taskId;
|
|
43111
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
43112
|
+
}
|
|
43113
|
+
function renderTaskBinding(taskId) {
|
|
43114
|
+
return `
|
|
43115
|
+
|
|
43116
|
+
## Bound Task
|
|
43117
|
+
|
|
43118
|
+
You are executing task \`${taskId}\`. Read its contract with \`manage_task get\`, update it as you work, and complete it when done.
|
|
43119
|
+
`;
|
|
43120
|
+
}
|
|
43121
|
+
function createBoundTaskLifecycle() {
|
|
43122
|
+
return createTaskLifecycleService({ taskStore: getTaskStore(), workItemStore: getTaskWorkItemStore() });
|
|
43123
|
+
}
|
|
43124
|
+
function createBoundTaskBridge() {
|
|
43125
|
+
return createTaskRunBridge({ lifecycle: createBoundTaskLifecycle() });
|
|
43126
|
+
}
|
|
43127
|
+
function isResumableInterruption(interruption) {
|
|
43128
|
+
if (!interruption || typeof interruption !== "object" || Array.isArray(interruption)) return false;
|
|
43129
|
+
const type = interruption.type;
|
|
43130
|
+
return type === "missing_input" || type === "user_decision";
|
|
43131
|
+
}
|
|
43132
|
+
var TASK_WORKER_OBSERVATION_MAX_CHARS = 8192;
|
|
43133
|
+
function snapshotMessages(state) {
|
|
43134
|
+
if (!state || typeof state !== "object") return [];
|
|
43135
|
+
const values = state.values;
|
|
43136
|
+
if (!values || typeof values !== "object") return [];
|
|
43137
|
+
const messages = values.messages;
|
|
43138
|
+
return Array.isArray(messages) ? messages : [];
|
|
43139
|
+
}
|
|
43140
|
+
function messageText(value) {
|
|
43141
|
+
if (typeof value === "string") return value;
|
|
43142
|
+
if (!Array.isArray(value)) return void 0;
|
|
43143
|
+
return value.flatMap((part) => {
|
|
43144
|
+
if (typeof part === "string") return [part];
|
|
43145
|
+
if (part && typeof part === "object" && typeof part.text === "string") {
|
|
43146
|
+
return [part.text];
|
|
43147
|
+
}
|
|
43148
|
+
return [];
|
|
43149
|
+
}).join("");
|
|
43150
|
+
}
|
|
43151
|
+
function lastAssistantText(source) {
|
|
43152
|
+
const messages = Array.isArray(source) ? source : source && typeof source === "object" && Array.isArray(source.messages) ? source.messages : snapshotMessages(source);
|
|
43153
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
43154
|
+
const message = messages[index];
|
|
43155
|
+
if (!message || typeof message !== "object") continue;
|
|
43156
|
+
const role = message.role ?? message.type;
|
|
43157
|
+
if (role !== "ai" && role !== "assistant") continue;
|
|
43158
|
+
const text = messageText(message.content);
|
|
43159
|
+
if (text !== void 0) return text;
|
|
43160
|
+
}
|
|
43161
|
+
return void 0;
|
|
43162
|
+
}
|
|
43163
|
+
function boundedWorkerObservation(result, state) {
|
|
43164
|
+
const text = lastAssistantText(state) ?? lastAssistantText(result) ?? "";
|
|
43165
|
+
return {
|
|
43166
|
+
status: "completed",
|
|
43167
|
+
output: truncateForJson(text, { maxStringLength: TASK_WORKER_OBSERVATION_MAX_CHARS })
|
|
43168
|
+
};
|
|
43169
|
+
}
|
|
43170
|
+
var EXECUTOR_CACHE_TTL_MS = 3e4;
|
|
43171
|
+
var executorCache = /* @__PURE__ */ new Map();
|
|
43172
|
+
function executorString(value) {
|
|
43173
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
43174
|
+
}
|
|
43175
|
+
async function renderAvailableExecutors(rc, tenantId2) {
|
|
43176
|
+
const authority = classifyTaskAuthority(rc);
|
|
43177
|
+
const governed = authority.kind === "projectRoom" || authority.kind === "projectTask";
|
|
43178
|
+
const projectId = governed ? (authority.trusted.projectTask ?? authority.trusted.projectRoom)?.projectId : void 0;
|
|
43179
|
+
const cacheKey = `${tenantId2}:${governed ? `project:${projectId ?? ""}` : "ordinary"}`;
|
|
43180
|
+
const cached = executorCache.get(cacheKey);
|
|
43181
|
+
const now = Date.now();
|
|
43182
|
+
if (cached && now - cached.at < EXECUTOR_CACHE_TTL_MS) return cached.text;
|
|
43183
|
+
const lines = [];
|
|
43184
|
+
try {
|
|
43185
|
+
if (governed && projectId) {
|
|
43186
|
+
const store = getStoreLattice("default", "projectBotMembership").store;
|
|
43187
|
+
if (typeof store.list === "function") {
|
|
43188
|
+
const bots = await store.list(tenantId2, projectId);
|
|
43189
|
+
for (const bot of (Array.isArray(bots) ? bots : []).slice(0, 40)) {
|
|
43190
|
+
const row = bot;
|
|
43191
|
+
if (row.status !== "active") continue;
|
|
43192
|
+
const id = executorString(row.assistantId);
|
|
43193
|
+
if (!id) continue;
|
|
43194
|
+
const title = executorString(row.title);
|
|
43195
|
+
const responsibility = executorString(row.responsibility);
|
|
43196
|
+
lines.push(`- ${id}${title ? ` \u2014 ${title}` : ""}${responsibility ? ` (${responsibility})` : ""}`);
|
|
43197
|
+
}
|
|
43198
|
+
}
|
|
43199
|
+
} else {
|
|
43200
|
+
const configs = await agentLatticeManager.getAllAgentConfigsByTenant(tenantId2);
|
|
43201
|
+
for (const config of configs.slice(0, 40)) {
|
|
43202
|
+
const row = config;
|
|
43203
|
+
const id = executorString(row.key);
|
|
43204
|
+
if (!id) continue;
|
|
43205
|
+
const name = executorString(row.name);
|
|
43206
|
+
const description = executorString(row.description);
|
|
43207
|
+
lines.push(`- ${id}${name ? ` \u2014 ${name}` : ""}${description ? ` (${description.slice(0, 120)})` : ""}`);
|
|
43208
|
+
}
|
|
43209
|
+
}
|
|
43210
|
+
} catch {
|
|
43211
|
+
}
|
|
43212
|
+
if (lines.length === 0) {
|
|
43213
|
+
executorCache.set(cacheKey, { at: now, text: "" });
|
|
43214
|
+
return "";
|
|
43215
|
+
}
|
|
43216
|
+
const header = governed ? "## Available task executors (Project roster)" : "## Available task executors";
|
|
43217
|
+
const text = `
|
|
43218
|
+
|
|
43219
|
+
${header}
|
|
43220
|
+
|
|
43221
|
+
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.
|
|
43222
|
+
|
|
43223
|
+
${lines.join("\n")}
|
|
43224
|
+
`;
|
|
43225
|
+
executorCache.set(cacheKey, { at: now, text });
|
|
43226
|
+
return text;
|
|
43227
|
+
}
|
|
44235
43228
|
function delegatedTaskScopeError(taskId) {
|
|
44236
43229
|
return JSON.stringify({
|
|
44237
43230
|
success: false,
|
|
@@ -44599,65 +43592,75 @@ function buildReviewMarkdown(task) {
|
|
|
44599
43592
|
result: task.result
|
|
44600
43593
|
});
|
|
44601
43594
|
}
|
|
44602
|
-
var manageTaskSchema =
|
|
44603
|
-
action:
|
|
44604
|
-
id:
|
|
44605
|
-
title:
|
|
44606
|
-
description:
|
|
44607
|
-
priority:
|
|
44608
|
-
status:
|
|
44609
|
-
dueDate:
|
|
44610
|
-
metadata:
|
|
44611
|
-
metadataFilter:
|
|
44612
|
-
|
|
43595
|
+
var manageTaskSchema = import_zod68.z.object({
|
|
43596
|
+
action: import_zod68.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."),
|
|
43597
|
+
id: import_zod68.z.string().optional().describe("Task ID (required for get, update, add_activity; required for delete unless ids is given)"),
|
|
43598
|
+
title: import_zod68.z.string().optional().describe("Task title (required for create)"),
|
|
43599
|
+
description: import_zod68.z.string().optional().describe("Task description in Markdown"),
|
|
43600
|
+
priority: import_zod68.z.enum(["low", "medium", "high"]).optional().describe("Priority level"),
|
|
43601
|
+
status: import_zod68.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"),
|
|
43602
|
+
dueDate: import_zod68.z.string().optional().describe("Due date (ISO 8601 format)"),
|
|
43603
|
+
metadata: import_zod68.z.record(import_zod68.z.unknown()).optional().describe("Structured metadata (e.g. projectId, module)"),
|
|
43604
|
+
metadataFilter: import_zod68.z.record(
|
|
43605
|
+
import_zod68.z.union([import_zod68.z.string(), import_zod68.z.number(), import_zod68.z.boolean()])
|
|
44613
43606
|
).optional().describe("List-only filter. Every key must equal the task metadata value, e.g. {projectId:'p1', retries:2}. Multiple keys AND together."),
|
|
44614
|
-
parentId:
|
|
44615
|
-
sourceId:
|
|
44616
|
-
context:
|
|
44617
|
-
ownerType:
|
|
44618
|
-
ownerId:
|
|
44619
|
-
requireReview:
|
|
44620
|
-
dependencies:
|
|
44621
|
-
dependencyTaskIds:
|
|
44622
|
-
result:
|
|
44623
|
-
failureReason:
|
|
44624
|
-
files:
|
|
44625
|
-
uri:
|
|
44626
|
-
name:
|
|
44627
|
-
addedBy:
|
|
43607
|
+
parentId: import_zod68.z.string().optional().describe("Parent task ID for grouping subtasks"),
|
|
43608
|
+
sourceId: import_zod68.z.string().optional().describe("Source session/thread ID"),
|
|
43609
|
+
context: import_zod68.z.record(import_zod68.z.unknown()).optional().describe("Additional context data"),
|
|
43610
|
+
ownerType: import_zod68.z.enum(["user", "agent"]).optional().describe("Owner type. Defaults to 'user' if omitted"),
|
|
43611
|
+
ownerId: import_zod68.z.string().optional().describe("Owner ID. Auto-filled from current user/agent if omitted"),
|
|
43612
|
+
requireReview: import_zod68.z.boolean().optional().describe("If true, agent completion pauses as interrupted(review_required) for HITL approval"),
|
|
43613
|
+
dependencies: import_zod68.z.array(import_zod68.z.string()).optional().describe("List of task IDs that must be completed before this task can start"),
|
|
43614
|
+
dependencyTaskIds: import_zod68.z.array(import_zod68.z.string().trim().min(1)).optional().describe("Exact blocking task IDs required for an external_dependency interruption"),
|
|
43615
|
+
result: import_zod68.z.string().optional().describe("Result summary. Used with set_status status='completed' or update status='completed'"),
|
|
43616
|
+
failureReason: import_zod68.z.string().optional().describe("Failure reason. Used with set_status status='failed' or update status='failed'"),
|
|
43617
|
+
files: import_zod68.z.array(import_zod68.z.object({
|
|
43618
|
+
uri: import_zod68.z.string().describe("Uniquely locates the resource: http(s):// URL, /s/:token share, or sandbox path"),
|
|
43619
|
+
name: import_zod68.z.string().optional().describe("Display name"),
|
|
43620
|
+
addedBy: import_zod68.z.enum(["user", "agent"]).optional().describe("Who attached the file")
|
|
44628
43621
|
})).optional().describe("File references attached to this task"),
|
|
44629
|
-
beliefImpact:
|
|
44630
|
-
key:
|
|
44631
|
-
after:
|
|
44632
|
-
basis:
|
|
44633
|
-
isNew:
|
|
43622
|
+
beliefImpact: import_zod68.z.array(import_zod68.z.object({
|
|
43623
|
+
key: import_zod68.z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),
|
|
43624
|
+
after: import_zod68.z.number().int().min(0).max(100),
|
|
43625
|
+
basis: import_zod68.z.string().trim().min(1).max(1e3),
|
|
43626
|
+
isNew: import_zod68.z.boolean().optional().describe("Set true only to add a belief key that is absent from the belief owner's Belief State; omit for keys that already exist")
|
|
44634
43627
|
})).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
|
-
content:
|
|
44636
|
-
summary:
|
|
44637
|
-
executionResultId:
|
|
43628
|
+
content: import_zod68.z.string().optional().describe("Markdown content required for add_activity"),
|
|
43629
|
+
summary: import_zod68.z.string().optional().describe("Brief summary of the operation"),
|
|
43630
|
+
executionResultId: import_zod68.z.string().refine(import_protocols33.isExecutionResultEventKey, {
|
|
44638
43631
|
message: "executionResultId must be the execution-result:<threadId> event key returned by task()"
|
|
44639
43632
|
}).optional().describe(
|
|
44640
43633
|
"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
|
-
)
|
|
43634
|
+
),
|
|
43635
|
+
ids: import_zod68.z.array(import_zod68.z.string().trim().min(1)).optional().describe("Task IDs to delete in one batch (delete action only). Use with or instead of id.")
|
|
44642
43636
|
}).superRefine((input, context) => {
|
|
44643
43637
|
if (input.executionResultId && input.action !== "update" && input.action !== "set_status" && input.action !== "add_activity") {
|
|
44644
43638
|
context.addIssue({
|
|
44645
|
-
code:
|
|
43639
|
+
code: import_zod68.z.ZodIssueCode.custom,
|
|
44646
43640
|
path: ["executionResultId"],
|
|
44647
43641
|
message: "executionResultId is valid only for update, set_status, or add_activity"
|
|
44648
43642
|
});
|
|
44649
43643
|
}
|
|
44650
43644
|
if (input.metadataFilter && input.action !== "list") {
|
|
44651
43645
|
context.addIssue({
|
|
44652
|
-
code:
|
|
43646
|
+
code: import_zod68.z.ZodIssueCode.custom,
|
|
44653
43647
|
path: ["metadataFilter"],
|
|
44654
43648
|
message: "metadataFilter is valid only for list"
|
|
44655
43649
|
});
|
|
44656
43650
|
}
|
|
43651
|
+
if (input.ids && input.action !== "delete") {
|
|
43652
|
+
context.addIssue({
|
|
43653
|
+
code: import_zod68.z.ZodIssueCode.custom,
|
|
43654
|
+
path: ["ids"],
|
|
43655
|
+
message: "ids is valid only for delete"
|
|
43656
|
+
});
|
|
43657
|
+
}
|
|
44657
43658
|
});
|
|
44658
|
-
var startTaskSchema =
|
|
44659
|
-
taskId:
|
|
44660
|
-
agentId:
|
|
43659
|
+
var startTaskSchema = import_zod68.z.object({
|
|
43660
|
+
taskId: import_zod68.z.string().trim().min(1).describe("ID of the persisted TaskItem to start"),
|
|
43661
|
+
agentId: import_zod68.z.string().trim().min(1).describe(
|
|
43662
|
+
`ID of the Agent that should execute the task. Use "general-purpose" to run the caller's own capabilities as an isolated worker.`
|
|
43663
|
+
)
|
|
44661
43664
|
});
|
|
44662
43665
|
function mergeTaskUpdateWarnings(existing, added) {
|
|
44663
43666
|
const warnings = [...existing ?? [], ...added ?? []];
|
|
@@ -44794,6 +43797,49 @@ function createTaskMiddleware(options = {}) {
|
|
|
44794
43797
|
}
|
|
44795
43798
|
const ownerId = input.ownerId || trustedScope?.assistantId || (input.ownerType === "agent" ? rc.assistant_id : null) || rc.user_id;
|
|
44796
43799
|
const store = getTaskStore();
|
|
43800
|
+
const deleteOneTask = async (id) => {
|
|
43801
|
+
if (delegatedTaskId && id !== delegatedTaskId) {
|
|
43802
|
+
return delegatedTaskScopeError(delegatedTaskId);
|
|
43803
|
+
}
|
|
43804
|
+
const existing = await store.getById(tenantId2, id);
|
|
43805
|
+
if (!existing) {
|
|
43806
|
+
return JSON.stringify({
|
|
43807
|
+
success: false,
|
|
43808
|
+
code: "TASK_NOT_FOUND",
|
|
43809
|
+
error: `Task '${id}' was not found.`,
|
|
43810
|
+
hint: "Use manage_task list to see available tasks and their correct IDs."
|
|
43811
|
+
});
|
|
43812
|
+
}
|
|
43813
|
+
if (!taskMatchesRuntimeScope3(existing, workspaceId, projectId)) {
|
|
43814
|
+
return taskScopeAccessError(id);
|
|
43815
|
+
}
|
|
43816
|
+
if (trustedProject?.projectTask) {
|
|
43817
|
+
const trustedFailure = trustedTaskContextFailure(existing, trustedProject.projectTask);
|
|
43818
|
+
if (trustedFailure) return trustedFailure;
|
|
43819
|
+
}
|
|
43820
|
+
let deleted;
|
|
43821
|
+
if (trustedProject) {
|
|
43822
|
+
const snapshot = taskMutationSnapshot(existing);
|
|
43823
|
+
if (!snapshot) return trustedContextError();
|
|
43824
|
+
try {
|
|
43825
|
+
await createProjectTaskOwnerPolicy().requireCaller(trustedRosterScope(trustedProject));
|
|
43826
|
+
} catch (error) {
|
|
43827
|
+
return projectPolicyError(error);
|
|
43828
|
+
}
|
|
43829
|
+
deleted = await store.deleteIfSnapshot(tenantId2, id, snapshot);
|
|
43830
|
+
} else {
|
|
43831
|
+
deleted = await store.delete(tenantId2, id);
|
|
43832
|
+
}
|
|
43833
|
+
if (!deleted) {
|
|
43834
|
+
return JSON.stringify({
|
|
43835
|
+
success: false,
|
|
43836
|
+
code: "TASK_DELETE_FAILED",
|
|
43837
|
+
error: `Task '${id}' was not found or could not be deleted.`,
|
|
43838
|
+
hint: "Use manage_task list to verify the task exists and you have access to it."
|
|
43839
|
+
});
|
|
43840
|
+
}
|
|
43841
|
+
return JSON.stringify({ success: true, message: `Task '${id}' deleted` });
|
|
43842
|
+
};
|
|
44797
43843
|
switch (input.action) {
|
|
44798
43844
|
case "create": {
|
|
44799
43845
|
if (delegatedTaskId && input.parentId !== delegatedTaskId) {
|
|
@@ -44949,9 +43995,6 @@ function createTaskMiddleware(options = {}) {
|
|
|
44949
43995
|
hint: "Pass the task ID you want to retrieve"
|
|
44950
43996
|
});
|
|
44951
43997
|
}
|
|
44952
|
-
if (delegatedTaskId && input.id !== delegatedTaskId) {
|
|
44953
|
-
return delegatedTaskScopeError(delegatedTaskId);
|
|
44954
|
-
}
|
|
44955
43998
|
const task = await store.getById(tenantId2, input.id);
|
|
44956
43999
|
if (!task) {
|
|
44957
44000
|
return JSON.stringify({
|
|
@@ -44997,25 +44040,6 @@ function createTaskMiddleware(options = {}) {
|
|
|
44997
44040
|
});
|
|
44998
44041
|
}
|
|
44999
44042
|
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
44043
|
const filter2 = {
|
|
45020
44044
|
tenantId: tenantId2,
|
|
45021
44045
|
ownerType: input.ownerType,
|
|
@@ -45610,41 +44634,31 @@ function createTaskMiddleware(options = {}) {
|
|
|
45610
44634
|
});
|
|
45611
44635
|
return lifecycleMutationResponse(interrupted);
|
|
45612
44636
|
}
|
|
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();
|
|
44637
|
+
if (lifecycle && input.status === "in_progress") {
|
|
45627
44638
|
const callerError = await revalidateCaller();
|
|
45628
44639
|
if (callerError) return callerError;
|
|
45629
|
-
|
|
45630
|
-
|
|
45631
|
-
|
|
45632
|
-
|
|
45633
|
-
|
|
45634
|
-
|
|
45635
|
-
|
|
45636
|
-
|
|
45637
|
-
|
|
45638
|
-
|
|
45639
|
-
|
|
45640
|
-
|
|
45641
|
-
|
|
44640
|
+
if (existing.status === "interrupted") {
|
|
44641
|
+
return lifecycleMutationResponse(await lifecycle.resumeInterruption({
|
|
44642
|
+
tenantId: tenantId2,
|
|
44643
|
+
taskId: input.id,
|
|
44644
|
+
actor,
|
|
44645
|
+
threadId: statusThreadId
|
|
44646
|
+
}));
|
|
44647
|
+
}
|
|
44648
|
+
if (existing.status === "failed") {
|
|
44649
|
+
return lifecycleMutationResponse(await lifecycle.retryTask({
|
|
44650
|
+
tenantId: tenantId2,
|
|
44651
|
+
taskId: input.id,
|
|
44652
|
+
actor,
|
|
44653
|
+
threadId: statusThreadId
|
|
44654
|
+
}));
|
|
44655
|
+
}
|
|
44656
|
+
return lifecycleMutationResponse(await lifecycle.startTask({
|
|
45642
44657
|
tenantId: tenantId2,
|
|
45643
44658
|
taskId: input.id,
|
|
45644
44659
|
actor,
|
|
45645
44660
|
threadId: statusThreadId
|
|
45646
|
-
});
|
|
45647
|
-
return lifecycleMutationResponse(retried);
|
|
44661
|
+
}));
|
|
45648
44662
|
}
|
|
45649
44663
|
const effectiveRequireReview = existing.requireReview === true || input.requireReview === true;
|
|
45650
44664
|
const candidateReviewInterruption = input.status === "interrupted" && input.context?.interruption && typeof input.context.interruption === "object" && input.context.interruption.type === "review_required" && !!input.result?.trim();
|
|
@@ -45711,9 +44725,9 @@ function createTaskMiddleware(options = {}) {
|
|
|
45711
44725
|
}
|
|
45712
44726
|
let response;
|
|
45713
44727
|
try {
|
|
45714
|
-
response = await (0,
|
|
44728
|
+
response = await (0, import_langgraph16.interrupt)(buildReviewMarkdown(submitted.task));
|
|
45715
44729
|
} catch (error) {
|
|
45716
|
-
if (error instanceof
|
|
44730
|
+
if (error instanceof import_langgraph16.GraphInterrupt) throw error;
|
|
45717
44731
|
return lifecycleMutationResponse(submitted, { code: "REVIEW_REQUIRED" });
|
|
45718
44732
|
}
|
|
45719
44733
|
if (response?.action === "approve") {
|
|
@@ -45825,54 +44839,49 @@ function createTaskMiddleware(options = {}) {
|
|
|
45825
44839
|
return successfulTaskResponse(input.id, updatedStatus, true);
|
|
45826
44840
|
}
|
|
45827
44841
|
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;
|
|
44842
|
+
const missingTargetError = JSON.stringify({
|
|
44843
|
+
success: false,
|
|
44844
|
+
error: "id or ids is required for delete action",
|
|
44845
|
+
hint: "Pass the task ID(s) you want to delete"
|
|
44846
|
+
});
|
|
44847
|
+
const requestedIds = input.ids && input.ids.length > 0 ? [.../* @__PURE__ */ new Set([...input.id ? [input.id] : [], ...input.ids])] : void 0;
|
|
44848
|
+
if (requestedIds === void 0) {
|
|
44849
|
+
if (!input.id) {
|
|
44850
|
+
return missingTargetError;
|
|
44851
|
+
}
|
|
44852
|
+
return deleteOneTask(input.id);
|
|
45853
44853
|
}
|
|
45854
|
-
|
|
45855
|
-
|
|
45856
|
-
|
|
45857
|
-
|
|
44854
|
+
const deletedIds = [];
|
|
44855
|
+
const failed = [];
|
|
44856
|
+
for (const id of requestedIds) {
|
|
44857
|
+
let raw;
|
|
45858
44858
|
try {
|
|
45859
|
-
await
|
|
44859
|
+
raw = await deleteOneTask(id);
|
|
45860
44860
|
} catch (error) {
|
|
45861
|
-
|
|
44861
|
+
failed.push({
|
|
44862
|
+
id,
|
|
44863
|
+
code: "TASK_DELETE_FAILED",
|
|
44864
|
+
error: error instanceof Error ? error.message : String(error)
|
|
44865
|
+
});
|
|
44866
|
+
continue;
|
|
44867
|
+
}
|
|
44868
|
+
const result = JSON.parse(raw);
|
|
44869
|
+
if (result.success) {
|
|
44870
|
+
deletedIds.push(id);
|
|
44871
|
+
} else {
|
|
44872
|
+
failed.push({
|
|
44873
|
+
id,
|
|
44874
|
+
...result.code ? { code: result.code } : {},
|
|
44875
|
+
error: result.error ?? `Task '${id}' could not be deleted.`
|
|
44876
|
+
});
|
|
45862
44877
|
}
|
|
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
44878
|
}
|
|
45875
|
-
return JSON.stringify({
|
|
44879
|
+
return JSON.stringify({
|
|
44880
|
+
success: failed.length === 0,
|
|
44881
|
+
deleted: deletedIds,
|
|
44882
|
+
failed,
|
|
44883
|
+
summary: `${deletedIds.length} of ${requestedIds.length} deleted`
|
|
44884
|
+
});
|
|
45876
44885
|
}
|
|
45877
44886
|
default:
|
|
45878
44887
|
return JSON.stringify({
|
|
@@ -45987,23 +44996,29 @@ function createTaskMiddleware(options = {}) {
|
|
|
45987
44996
|
error: "Runtime actor identity is required for persistent task execution"
|
|
45988
44997
|
});
|
|
45989
44998
|
}
|
|
44999
|
+
const callerAssistantId = rc.assistant_id;
|
|
45000
|
+
const agentId = input.agentId === "general-purpose" && callerAssistantId ? `${callerAssistantId}-general-purpose` : input.agentId;
|
|
45990
45001
|
const service2 = createTaskExecutionService({
|
|
45991
45002
|
taskStore: getTaskStore(),
|
|
45992
45003
|
workItemStore: getTaskWorkItemStore(),
|
|
45993
|
-
resolveAgent: async (targetTenantId,
|
|
45994
|
-
resolveTaskCapability: async (targetTenantId, agentId) => agentHasManagedTaskCapability(
|
|
45995
|
-
(await agentLatticeManager.getOrLoadWithTenant(targetTenantId, agentId))?.config
|
|
45996
|
-
),
|
|
45004
|
+
resolveAgent: async (targetTenantId, agentId2) => !!await agentLatticeManager.getOrLoadWithTenant(targetTenantId, agentId2),
|
|
45997
45005
|
invokeAgent: async (invocation) => {
|
|
45998
|
-
const
|
|
45999
|
-
tenant_id: invocation.tenantId,
|
|
45006
|
+
const workerResult = await agentWorkerGraph.invoke({
|
|
46000
45007
|
assistant_id: invocation.agentId,
|
|
46001
45008
|
thread_id: invocation.threadId,
|
|
46002
|
-
|
|
46003
|
-
|
|
46004
|
-
|
|
45009
|
+
input: { message: invocation.message },
|
|
45010
|
+
runConfig: {
|
|
45011
|
+
...rc,
|
|
45012
|
+
assistant_id: invocation.agentId,
|
|
45013
|
+
thread_id: invocation.threadId,
|
|
45014
|
+
taskId: invocation.taskId,
|
|
45015
|
+
tenantId: invocation.tenantId,
|
|
45016
|
+
workspaceId: invocation.workspaceId,
|
|
45017
|
+
projectId: invocation.projectId
|
|
45018
|
+
}
|
|
46005
45019
|
});
|
|
46006
|
-
|
|
45020
|
+
const finalState = workerResult?.finalState;
|
|
45021
|
+
return boundedWorkerObservation(finalState, void 0);
|
|
46007
45022
|
}
|
|
46008
45023
|
});
|
|
46009
45024
|
const trustedCaller = authority.kind === "projectTask" || authority.kind === "projectRoom" ? authority.trusted.projectTask ?? authority.trusted.projectRoom : void 0;
|
|
@@ -46012,15 +45027,75 @@ function createTaskMiddleware(options = {}) {
|
|
|
46012
45027
|
workspaceId: rc.workspaceId,
|
|
46013
45028
|
projectId: rc.projectId,
|
|
46014
45029
|
taskId: input.taskId,
|
|
46015
|
-
agentId
|
|
45030
|
+
agentId,
|
|
46016
45031
|
actor,
|
|
46017
45032
|
callerThreadId: rc.thread_id,
|
|
46018
45033
|
...trustedCaller ? { callerMembershipId: trustedCaller.membershipId, callerAssistantId: trustedCaller.assistantId } : {}
|
|
46019
45034
|
}));
|
|
46020
45035
|
};
|
|
46021
|
-
return (0,
|
|
45036
|
+
return (0, import_langchain83.createMiddleware)({
|
|
46022
45037
|
name: "TaskMiddleware",
|
|
46023
45038
|
contextSchema,
|
|
45039
|
+
// Persisted between invocations (ADRs: the run↔task binding survives turns).
|
|
45040
|
+
stateSchema: import_zod68.z.object({
|
|
45041
|
+
taskId: import_zod68.z.string().default("")
|
|
45042
|
+
}),
|
|
45043
|
+
// CLAIM: a run that holds a task moves it to in_progress (idempotent).
|
|
45044
|
+
beforeAgent: async (state, runtime) => {
|
|
45045
|
+
const rc = readRuntimeRunConfig(runtime);
|
|
45046
|
+
const bound = typeof state?.taskId === "string" ? state.taskId : "";
|
|
45047
|
+
const taskId = bound || readExecutionTaskId(rc) || "";
|
|
45048
|
+
if (!taskId) return {};
|
|
45049
|
+
if (!taskId) return {};
|
|
45050
|
+
const tenantId2 = rc.tenantId || "default";
|
|
45051
|
+
const threadId = runtime?.configurable?.thread_id;
|
|
45052
|
+
const task = await getTaskStore().getById(tenantId2, taskId);
|
|
45053
|
+
if (!task) return {};
|
|
45054
|
+
const runWorkspaceId = typeof rc.workspaceId === "string" ? rc.workspaceId : void 0;
|
|
45055
|
+
const runProjectId = typeof rc.projectId === "string" ? rc.projectId : void 0;
|
|
45056
|
+
if (task.workspaceId && task.workspaceId !== runWorkspaceId) return {};
|
|
45057
|
+
if (task.projectId && task.projectId !== runProjectId) return {};
|
|
45058
|
+
if (task.status === "completed" || task.status === "failed" || task.status === "cancelled") {
|
|
45059
|
+
return bound ? {} : { taskId };
|
|
45060
|
+
}
|
|
45061
|
+
taskRunRegistry.register(taskId);
|
|
45062
|
+
if (task.status === "pending") {
|
|
45063
|
+
await createBoundTaskBridge().beginRun({
|
|
45064
|
+
tenantId: tenantId2,
|
|
45065
|
+
task,
|
|
45066
|
+
actor: getRuntimeActor2(rc) ?? "system",
|
|
45067
|
+
...threadId ? { threadId } : {}
|
|
45068
|
+
});
|
|
45069
|
+
} else if (task.status === "interrupted" && isResumableInterruption(task.context?.interruption)) {
|
|
45070
|
+
await createBoundTaskLifecycle().resumeInterruption({
|
|
45071
|
+
tenantId: tenantId2,
|
|
45072
|
+
taskId: task.id,
|
|
45073
|
+
actor: getRuntimeActor2(rc) ?? "system",
|
|
45074
|
+
...threadId ? { threadId } : {}
|
|
45075
|
+
});
|
|
45076
|
+
}
|
|
45077
|
+
return bound ? {} : { taskId };
|
|
45078
|
+
},
|
|
45079
|
+
// SETTLE: a run that ends without a lifecycle transition converges the task.
|
|
45080
|
+
afterAgent: async (state, runtime) => {
|
|
45081
|
+
const taskId = typeof state?.taskId === "string" ? state.taskId : "";
|
|
45082
|
+
if (!taskId) return {};
|
|
45083
|
+
const rc = readRuntimeRunConfig(runtime);
|
|
45084
|
+
const tenantId2 = rc.tenantId || "default";
|
|
45085
|
+
const threadId = runtime?.configurable?.thread_id;
|
|
45086
|
+
const task = await getTaskStore().getById(tenantId2, taskId);
|
|
45087
|
+
if (task?.status === "in_progress" && task.context?.thread_id === threadId) {
|
|
45088
|
+
await createBoundTaskBridge().settleRun({
|
|
45089
|
+
tenantId: tenantId2,
|
|
45090
|
+
task,
|
|
45091
|
+
actor: getRuntimeActor2(rc) ?? "system",
|
|
45092
|
+
...threadId ? { threadId } : {},
|
|
45093
|
+
outcome: { kind: "interrupted", summary: "Run ended without a task lifecycle transition" }
|
|
45094
|
+
});
|
|
45095
|
+
}
|
|
45096
|
+
taskRunRegistry.unregister(taskId);
|
|
45097
|
+
return {};
|
|
45098
|
+
},
|
|
46024
45099
|
wrapModelCall: async (request, handler) => {
|
|
46025
45100
|
const taskPrompt = `## Task Management
|
|
46026
45101
|
|
|
@@ -46029,8 +45104,11 @@ ongoing record of a GOAL and its ACCEPTANCE CRITERIA.
|
|
|
46029
45104
|
|
|
46030
45105
|
### When to create a task
|
|
46031
45106
|
- Agent-owned work is multi-step and needs a persistent contract and plan ->
|
|
46032
|
-
create the parent task FIRST (a \`pending\` record), then
|
|
46033
|
-
|
|
45107
|
+
create the parent task FIRST (a \`pending\` record), then process it in this run;
|
|
45108
|
+
mark it \`in_progress\` with \`manage_task set_status\` when you start, and
|
|
45109
|
+
\`completed\` when the acceptance criteria are met. To bring in an
|
|
45110
|
+
expert, create a subtask and dispatch it with \`task { taskId, agentId }\` \u2014 never
|
|
45111
|
+
re-dispatch the task you are processing.
|
|
46034
45112
|
- Persistence is useful for resumption, review, or visibility across the
|
|
46035
45113
|
independently verifiable business results.
|
|
46036
45114
|
|
|
@@ -46060,13 +45138,17 @@ ${TASK_CONVERGENCE_GUIDANCE}
|
|
|
46060
45138
|
- No params: ownerType defaults to "user" with current user's ID
|
|
46061
45139
|
- ownerType="agent": auto-fills ownerId from current agent (subtask for yourself)
|
|
46062
45140
|
- Explicit ownerId: assign to a specific agent or user`;
|
|
45141
|
+
const boundTaskId = request.state?.taskId;
|
|
45142
|
+
const binding = typeof boundTaskId === "string" && boundTaskId ? renderTaskBinding(boundTaskId) : "";
|
|
45143
|
+
const rc = readRuntimeRunConfig(request.runtime);
|
|
45144
|
+
const executors = await renderAvailableExecutors(rc, rc.tenantId || "default");
|
|
46063
45145
|
return handler({
|
|
46064
45146
|
...request,
|
|
46065
|
-
systemPrompt: taskPrompt + "\n\n" + (request.systemPrompt ?? "")
|
|
45147
|
+
systemPrompt: taskPrompt + binding + executors + "\n\n" + (request.systemPrompt ?? "")
|
|
46066
45148
|
});
|
|
46067
45149
|
},
|
|
46068
45150
|
tools: [
|
|
46069
|
-
(0,
|
|
45151
|
+
(0, import_langchain83.tool)(
|
|
46070
45152
|
handleManageTask,
|
|
46071
45153
|
{
|
|
46072
45154
|
name: "manage_task",
|
|
@@ -46087,15 +45169,14 @@ ${TASK_CONVERGENCE_GUIDANCE}
|
|
|
46087
45169
|
- update: Update a task's content fields (title/description/priority/dueDate/metadata/parentId/sourceId/context/ownerId/result/failureReason/requireReview/dependencies/files)
|
|
46088
45170
|
Status changes can also be done here, but use set_status for a simpler dedicated status update.
|
|
46089
45171
|
- 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='...'
|
|
45172
|
+
Start processing a task you hold: set_status with status='in_progress' (the engine binds it to this run's thread).
|
|
45173
|
+
To mark complete: set_status with status='completed', result='...' (the task must be in_progress)
|
|
46093
45174
|
To mark failed: set_status with status='failed', failureReason='...'
|
|
46094
45175
|
To pause for input: set_status with status='interrupted', summary='what is needed'
|
|
46095
|
-
|
|
45176
|
+
Valid status values: pending, in_progress, review, failed, interrupted, completed, cancelled.
|
|
46096
45177
|
set_status only changes the record; it never dispatches execution (only the \`task\` tool does).
|
|
46097
45178
|
- add_activity: Add a Markdown activity without changing task fields or status (id and content required)
|
|
46098
|
-
- delete: Delete
|
|
45179
|
+
- 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
45180
|
|
|
46100
45181
|
## Agent completion beliefs
|
|
46101
45182
|
Completing an agent-owned task MAY include a beliefImpact array reporting which
|
|
@@ -46106,14 +45187,16 @@ Report existing keys directly; set 'isNew: true' to add a key the owner does not
|
|
|
46106
45187
|
track yet. Belief is evidence metadata: it never blocks a completion, and an
|
|
46107
45188
|
unmatched or malformed entry is recorded without changing the owner's table.
|
|
46108
45189
|
Create always persists a pending record \u2014 a supplied status is coerced and no
|
|
46109
|
-
execution is dispatched.
|
|
46110
|
-
|
|
45190
|
+
execution is dispatched. When you start processing a task you hold, set it
|
|
45191
|
+
\`in_progress\` with \`manage_task set_status\`; a dispatched task is claimed
|
|
45192
|
+
automatically by the engine. Use \`task { taskId, agentId }\` to delegate a subtask
|
|
45193
|
+
to an expert \u2014 never re-dispatch the task you are processing.`,
|
|
46111
45194
|
schema: manageTaskSchema
|
|
46112
45195
|
}
|
|
46113
45196
|
),
|
|
46114
|
-
(0,
|
|
45197
|
+
(0, import_langchain83.tool)(handleStartTask, {
|
|
46115
45198
|
name: "task",
|
|
46116
|
-
description:
|
|
45199
|
+
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
45200
|
schema: startTaskSchema
|
|
46118
45201
|
})
|
|
46119
45202
|
]
|
|
@@ -46256,7 +45339,7 @@ canonical Belief State:
|
|
|
46256
45339
|
|
|
46257
45340
|
// src/middlewares/documentLearningMiddleware.ts
|
|
46258
45341
|
var import_protocols34 = require("@axiom-lattice/protocols");
|
|
46259
|
-
var
|
|
45342
|
+
var import_langchain84 = require("langchain");
|
|
46260
45343
|
|
|
46261
45344
|
// src/middlewares/documentLearningSkills.ts
|
|
46262
45345
|
var LEARN_CAPABILITY_SKILL = `---
|
|
@@ -46495,7 +45578,7 @@ patterns discovered, recommendations. Include validation coverage: user-sample N
|
|
|
46495
45578
|
`;
|
|
46496
45579
|
|
|
46497
45580
|
// src/middlewares/documentLearningMiddleware.ts
|
|
46498
|
-
var createDocumentLearningMiddleware = () => (0,
|
|
45581
|
+
var createDocumentLearningMiddleware = () => (0, import_langchain84.createMiddleware)({
|
|
46499
45582
|
name: "DocumentLearningMiddleware",
|
|
46500
45583
|
contextSchema,
|
|
46501
45584
|
tools: []
|
|
@@ -46613,12 +45696,12 @@ var documentLearningPlugin = {
|
|
|
46613
45696
|
};
|
|
46614
45697
|
|
|
46615
45698
|
// src/middlewares/documentParserMiddleware.ts
|
|
46616
|
-
var
|
|
45699
|
+
var import_langchain86 = require("langchain");
|
|
46617
45700
|
|
|
46618
45701
|
// src/tool_lattice/document_parser/index.ts
|
|
46619
45702
|
var path7 = __toESM(require("path"));
|
|
46620
|
-
var
|
|
46621
|
-
var
|
|
45703
|
+
var import_zod69 = __toESM(require("zod"));
|
|
45704
|
+
var import_langchain85 = require("langchain");
|
|
46622
45705
|
var PARSE_DOCUMENT_DESCRIPTION = `Parse a document file (docx, pdf) into structured Markdown using a remote document parsing service.
|
|
46623
45706
|
This tool handles the full pipeline internally: file upload \u2192 document parsing \u2192 polling until complete \u2192 download result \u2192 save to filesystem.
|
|
46624
45707
|
|
|
@@ -46741,7 +45824,7 @@ function createParseDocumentTool({
|
|
|
46741
45824
|
baseUrl = "",
|
|
46742
45825
|
apiKey = ""
|
|
46743
45826
|
}) {
|
|
46744
|
-
return (0,
|
|
45827
|
+
return (0, import_langchain85.tool)(
|
|
46745
45828
|
async (input, exe_config) => {
|
|
46746
45829
|
try {
|
|
46747
45830
|
const runConfig = exe_config?.configurable?.runConfig ?? { assistant_id: "", thread_id: "" };
|
|
@@ -46812,17 +45895,17 @@ function createParseDocumentTool({
|
|
|
46812
45895
|
{
|
|
46813
45896
|
name: "parse_document",
|
|
46814
45897
|
description: PARSE_DOCUMENT_DESCRIPTION,
|
|
46815
|
-
schema:
|
|
46816
|
-
file_path:
|
|
45898
|
+
schema: import_zod69.default.object({
|
|
45899
|
+
file_path: import_zod69.default.string().describe(
|
|
46817
45900
|
'Absolute path to the document file. Must point to an existing .docx or .pdf file. Example: "/project/reports/contract.docx". The file must be accessible from the current workspace.'
|
|
46818
45901
|
),
|
|
46819
|
-
engine:
|
|
45902
|
+
engine: import_zod69.default.string().describe(
|
|
46820
45903
|
'Parsing engine to use. Available options: "textin" (recommended, works with local files, supports docx/pdf), "datalab" (alternative engine for docx/pdf), "mineru" (requires public URL, use only if textin/datalab fail), "paddleocr_remote" (PaddleOCR, good for scanned documents), "qwen_ocr" (OCR-focused, best for image-heavy PDFs).'
|
|
46821
45904
|
),
|
|
46822
|
-
output_path:
|
|
45905
|
+
output_path: import_zod69.default.string().optional().describe(
|
|
46823
45906
|
'Path to save the parsed result. If not specified, the input extension is replaced with .md. Example: "/project/report.docx" becomes "/project/report.md". Parent directories are created automatically.'
|
|
46824
45907
|
),
|
|
46825
|
-
output_format:
|
|
45908
|
+
output_format: import_zod69.default.enum(["markdown", "json"]).optional().default("markdown").describe(
|
|
46826
45909
|
'Output format. "markdown": structured Markdown with tables, headers, formatting preserved (recommended). "json": raw JSON output from the parsing engine (for programmatic use).'
|
|
46827
45910
|
)
|
|
46828
45911
|
})
|
|
@@ -47240,7 +46323,7 @@ def main() -> None:
|
|
|
47240
46323
|
if __name__ == "__main__":
|
|
47241
46324
|
main()
|
|
47242
46325
|
`;
|
|
47243
|
-
var
|
|
46326
|
+
var resources = {
|
|
47244
46327
|
"references/api_reference.md": { mimeType: "text/markdown", content: `# API reference
|
|
47245
46328
|
|
|
47246
46329
|
The supported command-line form is 'markitdown input -o output.md'. The Python API uses 'MarkItDown().convert(path)' upstream, but this runtime prefers the installed CLI and does not provide direct Python SDK LLM calls. Use local conversion for local files and keep output as Markdown.` },
|
|
@@ -47269,7 +46352,7 @@ Single file: 'markitdown input -o output.md'. Ordinary directory: 'scripts/batch
|
|
|
47269
46352
|
var DOCUMENT_PARSER_MARKITDOWN_SKILL = {
|
|
47270
46353
|
version: "1.1.0",
|
|
47271
46354
|
content: MARKITDOWN_SKILL_CONTENT,
|
|
47272
|
-
resources
|
|
46355
|
+
resources
|
|
47273
46356
|
};
|
|
47274
46357
|
|
|
47275
46358
|
// src/middlewares/documentParserMiddleware.ts
|
|
@@ -47278,7 +46361,7 @@ function createDocumentParserMiddleware(config) {
|
|
|
47278
46361
|
const baseUrl = config.baseUrl || "";
|
|
47279
46362
|
const apiKey = config.apiKey || "";
|
|
47280
46363
|
const connections = Array.isArray(config.connections) ? config.connections.filter((key5) => typeof key5 === "string") : [];
|
|
47281
|
-
return (0,
|
|
46364
|
+
return (0, import_langchain86.createMiddleware)({
|
|
47282
46365
|
name: "DocumentParser",
|
|
47283
46366
|
contextSchema,
|
|
47284
46367
|
tools: [createParseDocumentTool({ connectAll, connections, baseUrl, apiKey })]
|
|
@@ -47394,8 +46477,8 @@ var documentParserPlugin = {
|
|
|
47394
46477
|
// src/middlewares/projectRoomMiddleware.ts
|
|
47395
46478
|
var import_crypto10 = require("crypto");
|
|
47396
46479
|
var import_protocols36 = require("@axiom-lattice/protocols");
|
|
47397
|
-
var
|
|
47398
|
-
var
|
|
46480
|
+
var import_langchain87 = require("langchain");
|
|
46481
|
+
var import_zod70 = require("zod");
|
|
47399
46482
|
var PROJECT_ROOM_CONTEXT_REQUIRED = "PROJECT_ROOM_CONTEXT_REQUIRED";
|
|
47400
46483
|
var PROJECT_ROOM_POST_FAILED = "PROJECT_ROOM_POST_FAILED";
|
|
47401
46484
|
var PROJECT_ROOM_ROSTER_FAILED = "PROJECT_ROOM_ROSTER_FAILED";
|
|
@@ -47415,10 +46498,10 @@ var ROSTER_FAILED = JSON.stringify({
|
|
|
47415
46498
|
error: PROJECT_ROOM_ROSTER_FAILED,
|
|
47416
46499
|
message: PROJECT_ROOM_ROSTER_FAILED_MESSAGE
|
|
47417
46500
|
});
|
|
47418
|
-
var postSchema =
|
|
47419
|
-
text:
|
|
46501
|
+
var postSchema = import_zod70.z.object({
|
|
46502
|
+
text: import_zod70.z.string().trim().min(1).max(2e4)
|
|
47420
46503
|
}).strict();
|
|
47421
|
-
var listSchema =
|
|
46504
|
+
var listSchema = import_zod70.z.object({}).strict();
|
|
47422
46505
|
function ownDataValue2(record, key5) {
|
|
47423
46506
|
if (typeof record !== "object" || record === null || Array.isArray(record)) return void 0;
|
|
47424
46507
|
try {
|
|
@@ -47485,10 +46568,10 @@ async function hasActiveCurrentMembership(scope) {
|
|
|
47485
46568
|
return true;
|
|
47486
46569
|
}
|
|
47487
46570
|
function createProjectRoomMiddleware() {
|
|
47488
|
-
return (0,
|
|
46571
|
+
return (0, import_langchain87.createMiddleware)({
|
|
47489
46572
|
name: "ProjectRoomMiddleware",
|
|
47490
46573
|
tools: [
|
|
47491
|
-
(0,
|
|
46574
|
+
(0, import_langchain87.tool)(async (input, config) => {
|
|
47492
46575
|
const { text } = input;
|
|
47493
46576
|
const scope = readTrustedRoomScope(config);
|
|
47494
46577
|
if (!scope) return CONTEXT_REQUIRED;
|
|
@@ -47519,7 +46602,7 @@ function createProjectRoomMiddleware() {
|
|
|
47519
46602
|
description: "Post a text reply to the current trusted Project Room message",
|
|
47520
46603
|
schema: postSchema
|
|
47521
46604
|
}),
|
|
47522
|
-
(0,
|
|
46605
|
+
(0, import_langchain87.tool)(async (_input, config) => {
|
|
47523
46606
|
const scope = readTrustedRoomScope(config);
|
|
47524
46607
|
if (!scope) return CONTEXT_REQUIRED;
|
|
47525
46608
|
try {
|
|
@@ -47561,8 +46644,8 @@ var projectRoomPlugin = {
|
|
|
47561
46644
|
};
|
|
47562
46645
|
|
|
47563
46646
|
// src/middlewares/sandboxPluginsMiddleware.ts
|
|
47564
|
-
var
|
|
47565
|
-
var
|
|
46647
|
+
var import_langchain88 = require("langchain");
|
|
46648
|
+
var import_zod71 = require("zod");
|
|
47566
46649
|
var import_protocols37 = require("@axiom-lattice/protocols");
|
|
47567
46650
|
|
|
47568
46651
|
// src/middlewares/sandboxPluginsSkills.ts
|
|
@@ -48284,16 +47367,16 @@ function tenantIdFrom(exeConfig) {
|
|
|
48284
47367
|
const c = exeConfig;
|
|
48285
47368
|
return c?.configurable?.runConfig?.tenantId ?? "default";
|
|
48286
47369
|
}
|
|
48287
|
-
var managePluginSchema =
|
|
48288
|
-
action:
|
|
48289
|
-
type:
|
|
48290
|
-
manifest:
|
|
48291
|
-
handlers:
|
|
48292
|
-
target:
|
|
48293
|
-
kind:
|
|
48294
|
-
name:
|
|
48295
|
-
input:
|
|
48296
|
-
connectionKey:
|
|
47370
|
+
var managePluginSchema = import_zod71.z.object({
|
|
47371
|
+
action: import_zod71.z.enum(["list", "get", "validate", "create", "update", "delete", "reload", "test"]),
|
|
47372
|
+
type: import_zod71.z.string().optional(),
|
|
47373
|
+
manifest: import_zod71.z.record(import_zod71.z.unknown()).optional(),
|
|
47374
|
+
handlers: import_zod71.z.record(import_zod71.z.string()).optional(),
|
|
47375
|
+
target: import_zod71.z.object({
|
|
47376
|
+
kind: import_zod71.z.enum(["tool", "connection-test", "connection-discover"]),
|
|
47377
|
+
name: import_zod71.z.string().optional(),
|
|
47378
|
+
input: import_zod71.z.unknown().optional(),
|
|
47379
|
+
connectionKey: import_zod71.z.string().optional()
|
|
48297
47380
|
}).optional()
|
|
48298
47381
|
});
|
|
48299
47382
|
var sandboxPluginsPlugin = {
|
|
@@ -48367,10 +47450,10 @@ var sandboxPluginsPlugin = {
|
|
|
48367
47450
|
]
|
|
48368
47451
|
}
|
|
48369
47452
|
},
|
|
48370
|
-
middleware: () => (0,
|
|
47453
|
+
middleware: () => (0, import_langchain88.createMiddleware)({
|
|
48371
47454
|
name: "SandboxPluginsMiddleware",
|
|
48372
47455
|
tools: [
|
|
48373
|
-
(0,
|
|
47456
|
+
(0, import_langchain88.tool)(
|
|
48374
47457
|
async (input, exeConfig) => {
|
|
48375
47458
|
const tenantId2 = tenantIdFrom(exeConfig);
|
|
48376
47459
|
const catalog2 = getSandboxPluginCatalog();
|
|
@@ -48511,7 +47594,6 @@ var BUILTIN_PLUGINS = [
|
|
|
48511
47594
|
sqlPlugin,
|
|
48512
47595
|
skillPlugin,
|
|
48513
47596
|
metricsPlugin,
|
|
48514
|
-
semanticMetricsPlugin,
|
|
48515
47597
|
askUserClarifyPlugin,
|
|
48516
47598
|
widgetPlugin,
|
|
48517
47599
|
clawPlugin,
|
|
@@ -49087,6 +48169,7 @@ registerBuiltinPlugins();
|
|
|
49087
48169
|
TaskLifecycleNotifier,
|
|
49088
48170
|
TaskLifecycleService,
|
|
49089
48171
|
TaskRunBridgeStoresRequiredError,
|
|
48172
|
+
TaskRunRegistry,
|
|
49090
48173
|
TaskStatus,
|
|
49091
48174
|
TeamAgentGraphBuilder,
|
|
49092
48175
|
TenantPluginCatalog,
|
|
@@ -49098,7 +48181,6 @@ registerBuiltinPlugins();
|
|
|
49098
48181
|
VectorStoreProviderManager,
|
|
49099
48182
|
VolumeFilesystem,
|
|
49100
48183
|
abortWorkflowRun,
|
|
49101
|
-
agentHasManagedTaskCapability,
|
|
49102
48184
|
agentInstanceManager,
|
|
49103
48185
|
agentLatticeManager,
|
|
49104
48186
|
appendReconciliationWarning,
|
|
@@ -49151,7 +48233,6 @@ registerBuiltinPlugins();
|
|
|
49151
48233
|
createSandboxProvider,
|
|
49152
48234
|
createSandboxResolver,
|
|
49153
48235
|
createSchedulerMiddleware,
|
|
49154
|
-
createSemanticMetricsMiddleware,
|
|
49155
48236
|
createSharePayload,
|
|
49156
48237
|
createTaskExecutionService,
|
|
49157
48238
|
createTaskLifecycleService,
|
|
@@ -49273,6 +48354,9 @@ registerBuiltinPlugins();
|
|
|
49273
48354
|
projectTaskAdmissionNotifier,
|
|
49274
48355
|
queueLatticeManager,
|
|
49275
48356
|
readLoopBreakerConfig,
|
|
48357
|
+
reconcileAllTenantTaskRuns,
|
|
48358
|
+
reconcileStaleTaskRuns,
|
|
48359
|
+
reconcileTenantTaskRuns,
|
|
49276
48360
|
registerAgentLattice,
|
|
49277
48361
|
registerAgentLatticeWithTenant,
|
|
49278
48362
|
registerAgentLattices,
|
|
@@ -49307,7 +48391,6 @@ registerBuiltinPlugins();
|
|
|
49307
48391
|
sandboxLatticeManager,
|
|
49308
48392
|
sanitizeToolCallId,
|
|
49309
48393
|
scheduleLatticeManager,
|
|
49310
|
-
semanticMetricsPlugin,
|
|
49311
48394
|
serializePluginMeta,
|
|
49312
48395
|
serializeTaskMutationSuccess,
|
|
49313
48396
|
serializeTaskNormalizationFallback,
|
|
@@ -49321,6 +48404,7 @@ registerBuiltinPlugins();
|
|
|
49321
48404
|
storeLatticeManager,
|
|
49322
48405
|
sttModelLatticeManager,
|
|
49323
48406
|
taskLifecycleNotifier,
|
|
48407
|
+
taskRunRegistry,
|
|
49324
48408
|
toJsonSchema,
|
|
49325
48409
|
toSafeStateExpr,
|
|
49326
48410
|
toolLatticeManager,
|