@axiom-lattice/core 2.1.80 → 2.1.82
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/{chunk-FN4TRQK4.mjs → chunk-SGRFQY3E.mjs} +386 -504
- package/dist/chunk-SGRFQY3E.mjs.map +1 -0
- package/dist/compile-4RFYHUBE.mjs +11 -0
- package/dist/index.d.mts +219 -34
- package/dist/index.d.ts +219 -34
- package/dist/index.js +1725 -1299
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1278 -745
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-FN4TRQK4.mjs.map +0 -1
- package/dist/compile-SYSKVQHB.mjs +0 -9
- /package/dist/{compile-SYSKVQHB.mjs.map → compile-4RFYHUBE.mjs.map} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -8,20 +8,21 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
buildInput,
|
|
10
10
|
buildStateAnnotation,
|
|
11
|
+
compileInternal,
|
|
11
12
|
compileWorkflow,
|
|
12
13
|
createAgentNode,
|
|
13
|
-
createHumanFeedbackNode,
|
|
14
14
|
createMapNode,
|
|
15
15
|
createNodeHandler,
|
|
16
|
-
createTerminalNode,
|
|
17
|
-
expand,
|
|
18
16
|
extractOutput,
|
|
19
17
|
invokeWithRetry,
|
|
20
18
|
parallelLimit,
|
|
19
|
+
parseYaml,
|
|
21
20
|
renderTemplate,
|
|
22
21
|
resolvePath,
|
|
22
|
+
toJsonSchema,
|
|
23
|
+
toSafeStateExpr,
|
|
23
24
|
validateDSL
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-SGRFQY3E.mjs";
|
|
25
26
|
|
|
26
27
|
// src/model_lattice/ModelLattice.ts
|
|
27
28
|
import { ChatDeepSeek } from "@langchain/deepseek";
|
|
@@ -146,9 +147,11 @@ var ModelLattice = class extends BaseChatModel {
|
|
|
146
147
|
maxRetries: config.maxRetries || 2,
|
|
147
148
|
apiKey: config.apiKey || process.env[config.apiKeyEnvName || "SILICONCLOUD_API_KEY"],
|
|
148
149
|
configuration: {
|
|
149
|
-
baseURL: "https://api.siliconflow.cn/v1"
|
|
150
|
+
baseURL: config.baseURL || "https://api.siliconflow.cn/v1"
|
|
150
151
|
},
|
|
151
|
-
streaming: config.streaming
|
|
152
|
+
streaming: config.streaming,
|
|
153
|
+
modelKwargs: config.modelKwargs,
|
|
154
|
+
...config.extra || {}
|
|
152
155
|
});
|
|
153
156
|
} else if (config.provider === "volcengine") {
|
|
154
157
|
return new ChatOpenAI({
|
|
@@ -430,11 +433,11 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
430
433
|
* @param key Lattice键名
|
|
431
434
|
* @param tool 已有的StructuredTool实例
|
|
432
435
|
*/
|
|
433
|
-
registerExistingTool(key,
|
|
436
|
+
registerExistingTool(key, tool52) {
|
|
434
437
|
const config = {
|
|
435
|
-
name:
|
|
436
|
-
description:
|
|
437
|
-
schema:
|
|
438
|
+
name: tool52.name,
|
|
439
|
+
description: tool52.description,
|
|
440
|
+
schema: tool52.schema,
|
|
438
441
|
// StructuredTool的schema已经是Zod兼容的
|
|
439
442
|
needUserApprove: false
|
|
440
443
|
// MCP工具默认不需要用户批准
|
|
@@ -442,7 +445,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
442
445
|
const toolLattice = {
|
|
443
446
|
key,
|
|
444
447
|
config,
|
|
445
|
-
client:
|
|
448
|
+
client: tool52
|
|
446
449
|
};
|
|
447
450
|
this.register(key, toolLattice);
|
|
448
451
|
}
|
|
@@ -468,7 +471,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
468
471
|
};
|
|
469
472
|
var toolLatticeManager = ToolLatticeManager.getInstance();
|
|
470
473
|
var registerToolLattice = (key, config, executor) => toolLatticeManager.registerLattice(key, config, executor);
|
|
471
|
-
var registerExistingTool = (key,
|
|
474
|
+
var registerExistingTool = (key, tool52) => toolLatticeManager.registerExistingTool(key, tool52);
|
|
472
475
|
var getToolLattice = (key) => toolLatticeManager.getToolLattice(key);
|
|
473
476
|
var getToolDefinition = (key) => toolLatticeManager.getToolDefinition(key);
|
|
474
477
|
var getToolClient = (key) => toolLatticeManager.getToolClient(key);
|
|
@@ -735,6 +738,7 @@ var InMemoryAssistantStore = class {
|
|
|
735
738
|
name: data.name,
|
|
736
739
|
description: data.description,
|
|
737
740
|
graphDefinition: data.graphDefinition,
|
|
741
|
+
ownerUserId: data.ownerUserId,
|
|
738
742
|
createdAt: now,
|
|
739
743
|
updatedAt: now
|
|
740
744
|
};
|
|
@@ -781,6 +785,17 @@ var InMemoryAssistantStore = class {
|
|
|
781
785
|
}
|
|
782
786
|
return tenantAssistants.has(id);
|
|
783
787
|
}
|
|
788
|
+
/**
|
|
789
|
+
* Get assistant by owner user ID
|
|
790
|
+
*/
|
|
791
|
+
async getByOwner(tenantId, userId) {
|
|
792
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
793
|
+
if (!tenantAssistants) return null;
|
|
794
|
+
for (const assistant of tenantAssistants.values()) {
|
|
795
|
+
if (assistant.ownerUserId === userId) return assistant;
|
|
796
|
+
}
|
|
797
|
+
return null;
|
|
798
|
+
}
|
|
784
799
|
/**
|
|
785
800
|
* Clear all assistants for a tenant (useful for testing)
|
|
786
801
|
*/
|
|
@@ -2013,7 +2028,7 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2013
2028
|
return this.messages.get(threadId);
|
|
2014
2029
|
}
|
|
2015
2030
|
async addMessage(params) {
|
|
2016
|
-
const { threadId, tenantId, assistantId, content, type = "human", priority = 0, command, custom_run_config, id } = params;
|
|
2031
|
+
const { threadId, tenantId, assistantId, workspaceId, projectId, content, type = "human", priority = 0, command, custom_run_config, id } = params;
|
|
2017
2032
|
const threadMessages = this.getMessagesForThread(threadId);
|
|
2018
2033
|
const message = {
|
|
2019
2034
|
id: id || this.generateId(),
|
|
@@ -2024,6 +2039,8 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2024
2039
|
status: "pending",
|
|
2025
2040
|
tenantId,
|
|
2026
2041
|
assistantId,
|
|
2042
|
+
workspaceId,
|
|
2043
|
+
projectId,
|
|
2027
2044
|
priority,
|
|
2028
2045
|
command,
|
|
2029
2046
|
custom_run_config
|
|
@@ -2032,7 +2049,7 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2032
2049
|
return message;
|
|
2033
2050
|
}
|
|
2034
2051
|
async addMessageAtHead(params) {
|
|
2035
|
-
const { threadId, tenantId, assistantId, content, type = "system", id, command, custom_run_config } = params;
|
|
2052
|
+
const { threadId, tenantId, assistantId, workspaceId, projectId, content, type = "system", id, command, custom_run_config } = params;
|
|
2036
2053
|
const threadMessages = this.getMessagesForThread(threadId);
|
|
2037
2054
|
let resolvedTenantId = tenantId || "default";
|
|
2038
2055
|
let resolvedAssistantId = assistantId || "";
|
|
@@ -2050,6 +2067,8 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2050
2067
|
status: "pending",
|
|
2051
2068
|
tenantId: resolvedTenantId,
|
|
2052
2069
|
assistantId: resolvedAssistantId,
|
|
2070
|
+
workspaceId,
|
|
2071
|
+
projectId,
|
|
2053
2072
|
priority: 100,
|
|
2054
2073
|
// High priority for head messages (STEER/Command)
|
|
2055
2074
|
command,
|
|
@@ -2081,7 +2100,9 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2081
2100
|
result.push({
|
|
2082
2101
|
tenantId: firstMessage.tenantId || "default",
|
|
2083
2102
|
assistantId: firstMessage.assistantId || "",
|
|
2084
|
-
threadId
|
|
2103
|
+
threadId,
|
|
2104
|
+
workspaceId: firstMessage.workspaceId || void 0,
|
|
2105
|
+
projectId: firstMessage.projectId || void 0
|
|
2085
2106
|
});
|
|
2086
2107
|
}
|
|
2087
2108
|
}
|
|
@@ -2204,6 +2225,7 @@ var InMemoryWorkflowTrackingStore = class {
|
|
|
2204
2225
|
tenantId: request.tenantId,
|
|
2205
2226
|
stepType: request.stepType,
|
|
2206
2227
|
stepName: request.stepName,
|
|
2228
|
+
threadId: request.threadId,
|
|
2207
2229
|
edgeFrom: request.edgeFrom,
|
|
2208
2230
|
edgeTo: request.edgeTo,
|
|
2209
2231
|
edgePurpose: request.edgePurpose,
|
|
@@ -2223,7 +2245,12 @@ var InMemoryWorkflowTrackingStore = class {
|
|
|
2223
2245
|
const existing = runSteps.find(
|
|
2224
2246
|
(s) => s.stepType === request.stepType && s.stepName === request.stepName
|
|
2225
2247
|
);
|
|
2226
|
-
if (existing)
|
|
2248
|
+
if (existing) {
|
|
2249
|
+
if (!existing.threadId && request.threadId) {
|
|
2250
|
+
existing.threadId = request.threadId;
|
|
2251
|
+
}
|
|
2252
|
+
return existing;
|
|
2253
|
+
}
|
|
2227
2254
|
return this.createRunStep(request);
|
|
2228
2255
|
}
|
|
2229
2256
|
async updateRunStep(runId, stepId, updates) {
|
|
@@ -2282,6 +2309,11 @@ var InMemoryChannelInstallationStore = class {
|
|
|
2282
2309
|
(inst) => inst.tenantId === tenantId && (!channel || inst.channel === channel)
|
|
2283
2310
|
);
|
|
2284
2311
|
}
|
|
2312
|
+
async getAllInstallations(channel) {
|
|
2313
|
+
return Array.from(this.installations.values()).filter(
|
|
2314
|
+
(inst) => !channel || inst.channel === channel
|
|
2315
|
+
);
|
|
2316
|
+
}
|
|
2285
2317
|
/**
|
|
2286
2318
|
* Creates a new channel installation for a tenant.
|
|
2287
2319
|
*
|
|
@@ -2558,6 +2590,107 @@ var InMemoryA2AApiKeyStore = class {
|
|
|
2558
2590
|
}
|
|
2559
2591
|
};
|
|
2560
2592
|
|
|
2593
|
+
// src/store_lattice/InMemoryTaskStore.ts
|
|
2594
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2595
|
+
var InMemoryTaskStore = class {
|
|
2596
|
+
constructor() {
|
|
2597
|
+
this.tasks = /* @__PURE__ */ new Map();
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Create a new task
|
|
2601
|
+
*/
|
|
2602
|
+
async create(params) {
|
|
2603
|
+
if (!this.tasks.has(params.tenantId)) {
|
|
2604
|
+
this.tasks.set(params.tenantId, /* @__PURE__ */ new Map());
|
|
2605
|
+
}
|
|
2606
|
+
const now = /* @__PURE__ */ new Date();
|
|
2607
|
+
const task = {
|
|
2608
|
+
id: uuidv4(),
|
|
2609
|
+
tenantId: params.tenantId,
|
|
2610
|
+
ownerType: params.ownerType,
|
|
2611
|
+
ownerId: params.ownerId,
|
|
2612
|
+
title: params.title,
|
|
2613
|
+
description: params.description,
|
|
2614
|
+
status: params.status || "pending",
|
|
2615
|
+
priority: params.priority || "medium",
|
|
2616
|
+
dueDate: params.dueDate,
|
|
2617
|
+
metadata: params.metadata,
|
|
2618
|
+
parentId: params.parentId,
|
|
2619
|
+
sourceId: params.sourceId,
|
|
2620
|
+
context: params.context,
|
|
2621
|
+
createdAt: now,
|
|
2622
|
+
updatedAt: now
|
|
2623
|
+
};
|
|
2624
|
+
this.tasks.get(params.tenantId).set(task.id, task);
|
|
2625
|
+
return task;
|
|
2626
|
+
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Get task by ID
|
|
2629
|
+
*/
|
|
2630
|
+
async getById(tenantId, id) {
|
|
2631
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
2632
|
+
if (!tenantTasks) return null;
|
|
2633
|
+
return tenantTasks.get(id) || null;
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* List tasks matching filter criteria
|
|
2637
|
+
*/
|
|
2638
|
+
async list(filter2) {
|
|
2639
|
+
const tenantTasks = this.tasks.get(filter2.tenantId);
|
|
2640
|
+
if (!tenantTasks) return [];
|
|
2641
|
+
let results = Array.from(tenantTasks.values());
|
|
2642
|
+
if (filter2.ownerType) results = results.filter((t) => t.ownerType === filter2.ownerType);
|
|
2643
|
+
if (filter2.ownerId) results = results.filter((t) => t.ownerId === filter2.ownerId);
|
|
2644
|
+
if (filter2.status) results = results.filter((t) => t.status === filter2.status);
|
|
2645
|
+
if (filter2.priority) results = results.filter((t) => t.priority === filter2.priority);
|
|
2646
|
+
if (filter2.parentId) results = results.filter((t) => t.parentId === filter2.parentId);
|
|
2647
|
+
if (filter2.sourceId) results = results.filter((t) => t.sourceId === filter2.sourceId);
|
|
2648
|
+
if (filter2.metadata) {
|
|
2649
|
+
for (const [key, value] of Object.entries(filter2.metadata)) {
|
|
2650
|
+
results = results.filter((t) => t.metadata?.[key] === value);
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
results.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
2654
|
+
const offset = filter2.offset || 0;
|
|
2655
|
+
const limit = filter2.limit || 100;
|
|
2656
|
+
return results.slice(offset, offset + limit);
|
|
2657
|
+
}
|
|
2658
|
+
/**
|
|
2659
|
+
* Update an existing task
|
|
2660
|
+
*/
|
|
2661
|
+
async update(tenantId, id, updates) {
|
|
2662
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
2663
|
+
if (!tenantTasks) return null;
|
|
2664
|
+
const existing = tenantTasks.get(id);
|
|
2665
|
+
if (!existing) return null;
|
|
2666
|
+
const updated = {
|
|
2667
|
+
...existing,
|
|
2668
|
+
...updates,
|
|
2669
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
2670
|
+
};
|
|
2671
|
+
tenantTasks.set(id, updated);
|
|
2672
|
+
return updated;
|
|
2673
|
+
}
|
|
2674
|
+
/**
|
|
2675
|
+
* Delete a task by ID
|
|
2676
|
+
*/
|
|
2677
|
+
async delete(tenantId, id) {
|
|
2678
|
+
const tenantTasks = this.tasks.get(tenantId);
|
|
2679
|
+
if (!tenantTasks) return false;
|
|
2680
|
+
return tenantTasks.delete(id);
|
|
2681
|
+
}
|
|
2682
|
+
/**
|
|
2683
|
+
* Clear all tasks for a tenant (useful for testing)
|
|
2684
|
+
*/
|
|
2685
|
+
clear(tenantId) {
|
|
2686
|
+
if (tenantId) {
|
|
2687
|
+
this.tasks.delete(tenantId);
|
|
2688
|
+
} else {
|
|
2689
|
+
this.tasks.clear();
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
};
|
|
2693
|
+
|
|
2561
2694
|
// src/store_lattice/StoreLatticeManager.ts
|
|
2562
2695
|
var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager {
|
|
2563
2696
|
/**
|
|
@@ -2738,6 +2871,12 @@ storeLatticeManager.registerLattice(
|
|
|
2738
2871
|
"a2aApiKey",
|
|
2739
2872
|
defaultA2AApiKeyStore
|
|
2740
2873
|
);
|
|
2874
|
+
var defaultTaskStore = new InMemoryTaskStore();
|
|
2875
|
+
storeLatticeManager.registerLattice(
|
|
2876
|
+
"default",
|
|
2877
|
+
"task",
|
|
2878
|
+
defaultTaskStore
|
|
2879
|
+
);
|
|
2741
2880
|
|
|
2742
2881
|
// src/tool_lattice/manage_binding/index.ts
|
|
2743
2882
|
function getInstallationStore() {
|
|
@@ -2749,7 +2888,7 @@ var manageBindingSchema = z3.object({
|
|
|
2749
2888
|
channelInstallationId: z3.string().optional().describe("Channel installation ID (auto-detected if omitted and only one exists for this channel)"),
|
|
2750
2889
|
senderId: z3.string().optional().describe("Sender identifier (email address, Lark openId, Slack userId)"),
|
|
2751
2890
|
agentId: z3.string().optional().describe("Target agent ID to route messages to"),
|
|
2752
|
-
threadMode: z3.enum(["fixed", "per_conversation"]).optional().default("per_conversation").describe("Thread mode
|
|
2891
|
+
threadMode: z3.enum(["fixed", "per_conversation"]).optional().default("per_conversation").describe("Thread mode (ignored when channel adapter has its own thread strategy, e.g. Lark)"),
|
|
2753
2892
|
senderDisplayName: z3.string().optional().describe("Human-readable name for the sender")
|
|
2754
2893
|
});
|
|
2755
2894
|
registerToolLattice(
|
|
@@ -2758,9 +2897,13 @@ registerToolLattice(
|
|
|
2758
2897
|
name: "manage_binding",
|
|
2759
2898
|
description: `Manage sender-to-agent bindings for external channels (email, Lark, Slack).
|
|
2760
2899
|
|
|
2900
|
+
Bindings are OPTIONAL \u2014 if no binding exists for a sender, messages route to the installation's fallbackAgentId. Only create a binding when a specific sender needs a different agent.
|
|
2901
|
+
|
|
2902
|
+
Thread isolation is handled automatically by the channel adapter (e.g. Lark isolates by sender+date). threadMode is only used when the channel adapter does not have its own strategy.
|
|
2903
|
+
|
|
2761
2904
|
- list_installations: List available channel installations. Filter by channel type (optional). Use this first to discover available channelInstallationIds.
|
|
2762
|
-
- create: Bind a sender to an agent. Required: channel, senderId, agentId. Optional: threadMode
|
|
2763
|
-
- update: Update an existing binding. Required: channel, senderId. Optional: agentId, threadMode
|
|
2905
|
+
- create: Bind a sender to an agent. Required: channel, senderId, agentId. Optional: threadMode. channelInstallationId auto-detected if only one exists.
|
|
2906
|
+
- update: Update an existing binding. Required: channel, senderId. Optional: agentId, threadMode, senderDisplayName.
|
|
2764
2907
|
- delete: Remove a binding. Required: channel, senderId.
|
|
2765
2908
|
- list: List all bindings. Optional: channel, agentId, channelInstallationId.
|
|
2766
2909
|
|
|
@@ -2768,7 +2911,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
2768
2911
|
schema: manageBindingSchema
|
|
2769
2912
|
},
|
|
2770
2913
|
async (input, config) => {
|
|
2771
|
-
const
|
|
2914
|
+
const registry3 = getBindingRegistry();
|
|
2772
2915
|
const runConfig = config?.configurable?.runConfig || {};
|
|
2773
2916
|
const tenantId = runConfig.tenantId || "default";
|
|
2774
2917
|
switch (input.action) {
|
|
@@ -2791,7 +2934,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
2791
2934
|
error: `No channelInstallationId provided and unable to auto-detect. Use action=list_installations to find available installations for channel "${input.channel}".`
|
|
2792
2935
|
});
|
|
2793
2936
|
}
|
|
2794
|
-
const binding = await
|
|
2937
|
+
const binding = await registry3.create({
|
|
2795
2938
|
channel: input.channel,
|
|
2796
2939
|
channelInstallationId: installId,
|
|
2797
2940
|
tenantId,
|
|
@@ -2813,7 +2956,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
2813
2956
|
error: `No channelInstallationId provided and unable to auto-detect. Use action=list_installations first.`
|
|
2814
2957
|
});
|
|
2815
2958
|
}
|
|
2816
|
-
const existing = await
|
|
2959
|
+
const existing = await registry3.resolve({
|
|
2817
2960
|
channel: input.channel,
|
|
2818
2961
|
senderId: input.senderId,
|
|
2819
2962
|
channelInstallationId: installId,
|
|
@@ -2822,7 +2965,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
2822
2965
|
if (!existing) {
|
|
2823
2966
|
return JSON.stringify({ success: false, error: "Binding not found" });
|
|
2824
2967
|
}
|
|
2825
|
-
const updated = await
|
|
2968
|
+
const updated = await registry3.update(existing.id, {
|
|
2826
2969
|
agentId: input.agentId,
|
|
2827
2970
|
threadMode: input.threadMode,
|
|
2828
2971
|
senderDisplayName: input.senderDisplayName
|
|
@@ -2840,7 +2983,7 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
2840
2983
|
error: `No channelInstallationId provided and unable to auto-detect.`
|
|
2841
2984
|
});
|
|
2842
2985
|
}
|
|
2843
|
-
const existing = await
|
|
2986
|
+
const existing = await registry3.resolve({
|
|
2844
2987
|
channel: input.channel,
|
|
2845
2988
|
senderId: input.senderId,
|
|
2846
2989
|
channelInstallationId: installId,
|
|
@@ -2849,11 +2992,11 @@ A sender can only be bound to ONE agent per channel+installation combination.`,
|
|
|
2849
2992
|
if (!existing) {
|
|
2850
2993
|
return JSON.stringify({ success: false, error: "Binding not found" });
|
|
2851
2994
|
}
|
|
2852
|
-
await
|
|
2995
|
+
await registry3.delete(existing.id);
|
|
2853
2996
|
return JSON.stringify({ success: true, message: "Binding deleted" });
|
|
2854
2997
|
}
|
|
2855
2998
|
case "list": {
|
|
2856
|
-
const bindings = await
|
|
2999
|
+
const bindings = await registry3.list({
|
|
2857
3000
|
channel: input.channel,
|
|
2858
3001
|
agentId: input.agentId,
|
|
2859
3002
|
tenantId,
|
|
@@ -3751,7 +3894,8 @@ function getTenantIdFromConfig2(exeConfig, getTenantId2) {
|
|
|
3751
3894
|
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
3752
3895
|
return runConfig.tenantId || (getTenantId2 ? getTenantId2() : "default");
|
|
3753
3896
|
}
|
|
3754
|
-
function filterServerKeysByTenant(serverKeys, tenantId, manager = metricsServerManager) {
|
|
3897
|
+
async function filterServerKeysByTenant(serverKeys, tenantId, manager = metricsServerManager) {
|
|
3898
|
+
await manager.ensureLoaded();
|
|
3755
3899
|
return serverKeys.filter((key) => {
|
|
3756
3900
|
return manager.hasServer(tenantId, key);
|
|
3757
3901
|
});
|
|
@@ -4529,6 +4673,14 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
4529
4673
|
}
|
|
4530
4674
|
return config;
|
|
4531
4675
|
}
|
|
4676
|
+
/**
|
|
4677
|
+
* Ensure server configs are loaded from the store.
|
|
4678
|
+
* Public wrapper around the internal lazy-loading mechanism.
|
|
4679
|
+
* Safe to call multiple times — loading happens at most once.
|
|
4680
|
+
*/
|
|
4681
|
+
async ensureLoaded() {
|
|
4682
|
+
await this._ensureLoaded();
|
|
4683
|
+
}
|
|
4532
4684
|
/**
|
|
4533
4685
|
* Check if a metrics server is registered for a tenant
|
|
4534
4686
|
* @param tenantId - Tenant identifier
|
|
@@ -4669,7 +4821,7 @@ ${serverKeys.map(
|
|
|
4669
4821
|
if (connectAll) {
|
|
4670
4822
|
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
4671
4823
|
}
|
|
4672
|
-
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
4824
|
+
const filteredServerKeys = await filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
4673
4825
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
4674
4826
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
4675
4827
|
if (metricsDataSource) {
|
|
@@ -4788,7 +4940,7 @@ ${serverKeys.map(
|
|
|
4788
4940
|
if (connectAll) {
|
|
4789
4941
|
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
4790
4942
|
}
|
|
4791
|
-
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
4943
|
+
const filteredServerKeys = await filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
4792
4944
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
4793
4945
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
4794
4946
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
@@ -4946,7 +5098,7 @@ ${serverKeys.map(
|
|
|
4946
5098
|
if (connectAll) {
|
|
4947
5099
|
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
4948
5100
|
}
|
|
4949
|
-
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5101
|
+
const filteredServerKeys = await filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
4950
5102
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
4951
5103
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
4952
5104
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
@@ -5182,7 +5334,7 @@ ${serverKeys.map(
|
|
|
5182
5334
|
if (connectAll) {
|
|
5183
5335
|
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5184
5336
|
}
|
|
5185
|
-
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5337
|
+
const filteredServerKeys = await filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5186
5338
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
5187
5339
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
5188
5340
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
@@ -5263,7 +5415,7 @@ ${serverKeys.map(
|
|
|
5263
5415
|
if (connectAll) {
|
|
5264
5416
|
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5265
5417
|
}
|
|
5266
|
-
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5418
|
+
const filteredServerKeys = await filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5267
5419
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
5268
5420
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
5269
5421
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
@@ -5368,7 +5520,7 @@ ${serverKeys.map(
|
|
|
5368
5520
|
if (connectAll) {
|
|
5369
5521
|
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5370
5522
|
}
|
|
5371
|
-
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5523
|
+
const filteredServerKeys = await filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5372
5524
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
5373
5525
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
5374
5526
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
@@ -5508,7 +5660,7 @@ ${serverKeys.map(
|
|
|
5508
5660
|
if (connectAll) {
|
|
5509
5661
|
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5510
5662
|
}
|
|
5511
|
-
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5663
|
+
const filteredServerKeys = await filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5512
5664
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
5513
5665
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
5514
5666
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
@@ -5566,7 +5718,9 @@ var VolumeFilesystem = class {
|
|
|
5566
5718
|
this.mountPrefix = mountPrefix;
|
|
5567
5719
|
}
|
|
5568
5720
|
async lsInfo(path3) {
|
|
5721
|
+
console.log(`[VolumeFilesystem.lsInfo] path=${path3} mountPrefix=${this.mountPrefix}`);
|
|
5569
5722
|
const entries = await this.client.list(path3);
|
|
5723
|
+
console.log(`[VolumeFilesystem.lsInfo] got ${entries.length} entries`);
|
|
5570
5724
|
const prefix = this.mountPrefix.endsWith("/") ? this.mountPrefix : this.mountPrefix + "/";
|
|
5571
5725
|
return entries.map((entry) => ({
|
|
5572
5726
|
path: entry.path.startsWith("/") ? entry.path : prefix + entry.path,
|
|
@@ -5758,30 +5912,45 @@ var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeMana
|
|
|
5758
5912
|
async getVolumeBackendForPath(config, filePath) {
|
|
5759
5913
|
const provider = this._requireProvider();
|
|
5760
5914
|
if (!provider.createVolumeFsClient) {
|
|
5915
|
+
console.log(`[getVolumeBackendForPath] provider has no createVolumeFsClient, returning null`);
|
|
5761
5916
|
return null;
|
|
5762
5917
|
}
|
|
5763
5918
|
const tenantId = config.tenantId ?? "default";
|
|
5764
5919
|
const mapping = this._resolveVolumeForPath(config, tenantId, filePath);
|
|
5765
|
-
if (!mapping)
|
|
5920
|
+
if (!mapping) {
|
|
5921
|
+
console.log(`[getVolumeBackendForPath] no volume mapping for path=${filePath}`);
|
|
5922
|
+
return null;
|
|
5923
|
+
}
|
|
5924
|
+
console.log(`[getVolumeBackendForPath] path=${filePath} volume=${mapping.volumeName} prefix=${mapping.pathPrefix}`);
|
|
5766
5925
|
const client = provider.createVolumeFsClient(mapping.volumeName, mapping.pathPrefix);
|
|
5767
5926
|
return new VolumeFilesystem(stripPrefixClient(client, mapping.pathPrefix), mapping.pathPrefix);
|
|
5768
5927
|
}
|
|
5769
5928
|
_resolveVolumeForPath(config, tenantId, filePath) {
|
|
5770
5929
|
const normalized = normalizeExternalSandboxPath(filePath);
|
|
5930
|
+
console.log(`[_resolveVolumeForPath] filePath=${filePath} normalized=${normalized} assistant_id=${config.assistant_id} projectId=${config.projectId}`);
|
|
5771
5931
|
if (normalized === "/root/.agents" || normalized.startsWith("/root/.agents/")) {
|
|
5932
|
+
console.log(`[_resolveVolumeForPath] \u2192 skills volume`);
|
|
5772
5933
|
return {
|
|
5773
5934
|
volumeName: buildNamedVolumeName("s", "skills", tenantId),
|
|
5774
5935
|
pathPrefix: "/root/.agents"
|
|
5775
5936
|
};
|
|
5776
5937
|
}
|
|
5777
5938
|
if (normalized === "/agent" || normalized.startsWith("/agent/")) {
|
|
5778
|
-
if (!config.assistant_id)
|
|
5939
|
+
if (!config.assistant_id) {
|
|
5940
|
+
console.log(`[_resolveVolumeForPath] agent volume but no assistant_id, returning null`);
|
|
5941
|
+
return null;
|
|
5942
|
+
}
|
|
5943
|
+
console.log(`[_resolveVolumeForPath] \u2192 agent volume`);
|
|
5779
5944
|
return {
|
|
5780
5945
|
volumeName: buildNamedVolumeName("a", "agent", tenantId, config.assistant_id),
|
|
5781
5946
|
pathPrefix: "/agent"
|
|
5782
5947
|
};
|
|
5783
5948
|
}
|
|
5784
|
-
if (!config.projectId)
|
|
5949
|
+
if (!config.projectId) {
|
|
5950
|
+
console.log(`[_resolveVolumeForPath] project volume but no projectId, returning null`);
|
|
5951
|
+
return null;
|
|
5952
|
+
}
|
|
5953
|
+
console.log(`[_resolveVolumeForPath] \u2192 project volume`);
|
|
5785
5954
|
return {
|
|
5786
5955
|
volumeName: buildNamedVolumeName("p", "project", tenantId, config.workspaceId, config.projectId),
|
|
5787
5956
|
pathPrefix: "/project"
|
|
@@ -7318,353 +7487,233 @@ metadata:
|
|
|
7318
7487
|
Then iterate based on what the user says.
|
|
7319
7488
|
`,
|
|
7320
7489
|
"create-workflow": `---
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
# Workflow Designer
|
|
7330
|
-
|
|
7331
|
-
This skill guides you through designing and creating workflow agents. A workflow is a LangGraph state machine compiled from a concise JSON DSL \u2014 steps define what happens, order defines the flow, and the engine handles the rest.
|
|
7332
|
-
|
|
7333
|
-
Every step runs on the workflow's built-in general-purpose agent \u2014 no external agent registration needed.
|
|
7334
|
-
|
|
7335
|
-
## Core Principle: id is everything
|
|
7490
|
+
name: create-workflow
|
|
7491
|
+
description: Design and build multi-step AI workflows using the YAML linear DSL. Use whenever users want to orchestrate agents in a pipeline with routing, parallelism, human-in-the-loop, or batch processing.
|
|
7492
|
+
license: MIT
|
|
7493
|
+
metadata:
|
|
7494
|
+
category: meta
|
|
7495
|
+
version: "5.0"
|
|
7496
|
+
---
|
|
7336
7497
|
|
|
7337
|
-
|
|
7338
|
-
1. **Node identifier** in the graph
|
|
7339
|
-
2. **State key** \u2014 output is stored at \`state.<id>\`
|
|
7340
|
-
3. **Template reference** \u2014 downstream steps use \`{{id}}\` to read it
|
|
7498
|
+
# YAML Workflow Designer
|
|
7341
7499
|
|
|
7342
|
-
|
|
7500
|
+
Use the linear YAML DSL \u2014 steps execute top-to-bottom. Use \`parallel:\` for concurrency. No dependency graph thinking required.
|
|
7343
7501
|
|
|
7344
|
-
|
|
7502
|
+
## Core Model: Linear + Parallel
|
|
7345
7503
|
|
|
7346
|
-
|
|
7504
|
+
- **Linear** \u2014 steps execute in written order. No \`needs\`, no dependency declarations.
|
|
7505
|
+
- **parallel** \u2014 a block where all children run concurrently. Block completes when all children finish.
|
|
7506
|
+
- **if** \u2014 JS expression. Step runs only when truthy. Omit to always run.
|
|
7507
|
+
- **prompt** \u2014 agent instruction with **{{label}}** refs. **{{input}}** is the user message.
|
|
7508
|
+
- **output** \u2014 shorthand schema using **{ field: type }** notation.
|
|
7509
|
+
- **ask** \u2014 boolean. Injects user clarification middleware for human interaction.
|
|
7347
7510
|
|
|
7348
|
-
|
|
7349
|
-
{ "id": "classify", "name": "Classify Intent", "prompt": "Classify the intent of: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } }
|
|
7350
|
-
\`\`\`
|
|
7511
|
+
## When to Use parallel vs map
|
|
7351
7512
|
|
|
7352
|
-
|
|
7353
|
-
|-------|----------|-------------|
|
|
7354
|
-
| id | no | State key for referencing output. Auto-generated if omitted, but required if downstream steps reference this step via \`{{id}}\` |
|
|
7355
|
-
| name | no | Human-readable label for this step |
|
|
7356
|
-
| prompt | yes | Task description with {{id}} refs |
|
|
7357
|
-
| schema | **yes** | Standard JSON Schema ONLY: \`{ "type": "object", "properties": { "field": { "type": "string" } } }\`. \`true\` is REJECTED \u2014 must be a concrete schema. Legacy shorthand \`{ "field": "string" }\` is REJECTED.
|
|
7513
|
+
This is the most important design decision. **They are fundamentally different:**
|
|
7358
7514
|
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
-
|
|
7364
|
-
|
|
7515
|
+
| | parallel | map |
|
|
7516
|
+
|---|---|---|
|
|
7517
|
+
| **Concern** | **Business parallelism** \u2014 reduce business processing time | **Data parallelism** \u2014 handle data volume |
|
|
7518
|
+
| **Tasks** | Each child does a **different** task | All items do the **same** task |
|
|
7519
|
+
| **Count** | Few (2-5), each hand-written | Dynamic, driven by source data |
|
|
7520
|
+
| **Input** | Independent prompts per child | Single \`each.prompt\` template, \`{{item}}\` for current element |
|
|
7521
|
+
| **if** | Per-child conditional | Whole block conditional |
|
|
7522
|
+
| **Example** | Legal review + Market analysis in parallel | Audit each line item in an invoice |
|
|
7365
7523
|
|
|
7366
|
-
|
|
7524
|
+
**Rule of thumb:** If you're writing the same prompt twice, you probably want \`map\`. If each branch has a unique purpose, use \`parallel\`.
|
|
7367
7525
|
|
|
7368
|
-
|
|
7526
|
+
## Step Format
|
|
7369
7527
|
|
|
7370
|
-
|
|
7528
|
+
### Agent Step
|
|
7371
7529
|
|
|
7372
|
-
\`\`\`
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
}
|
|
7530
|
+
\`\`\`yaml
|
|
7531
|
+
- label:
|
|
7532
|
+
prompt: instruction with {{refs}}
|
|
7533
|
+
if: "expression"
|
|
7534
|
+
output: { field: type }
|
|
7535
|
+
ask: true
|
|
7377
7536
|
\`\`\`
|
|
7378
7537
|
|
|
7379
|
-
|
|
7380
|
-
|-------|----------|-------------|
|
|
7381
|
-
| if | yes | State field name (e.g. "approved") or expression (e.g. "score >= 60"). **CRITICAL: \`{{}}\` is FORBIDDEN in \`if\`** \u2014 it is a plain JavaScript expression, not a template. \u274C \`"if": "{{intent}}"\` is WRONG. \u2705 \`"if": "intent"\` is correct. |
|
|
7382
|
-
| then | yes | Step(s) to run when condition is truthy |
|
|
7383
|
-
| else | no | Step(s) to run when condition is falsy |
|
|
7384
|
-
|
|
7385
|
-
The engine evaluates \`if\` as a JavaScript expression prefixed with \`state.\`. Both \`then\` and \`else\` can be a single step or an array of steps. After both branches, execution rejoins at the next step after the condition.
|
|
7386
|
-
|
|
7387
|
-
**Switch (branches):**
|
|
7538
|
+
### Parallel Block
|
|
7388
7539
|
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
"billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
|
|
7397
|
-
"default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
|
|
7398
|
-
}
|
|
7399
|
-
}
|
|
7540
|
+
\`\`\`yaml
|
|
7541
|
+
- parallel:
|
|
7542
|
+
- child1:
|
|
7543
|
+
prompt: ...
|
|
7544
|
+
if: "expression"
|
|
7545
|
+
- child2:
|
|
7546
|
+
prompt: ...
|
|
7400
7547
|
\`\`\`
|
|
7401
7548
|
|
|
7402
|
-
|
|
7403
|
-
|-------|----------|-------------|
|
|
7404
|
-
| if | yes | State field whose STRING VALUE is matched against branch keys. **Same rule \u2014 \`{{}}\` is FORBIDDEN here.** |
|
|
7405
|
-
| branches | yes | Map of value \u2192 step(s). \`"default"\` key is a catch-all for unmatched values |
|
|
7406
|
-
| then/else | no | Not used when branches is present |
|
|
7407
|
-
|
|
7408
|
-
Unlike \`then\`/\`else\` (truthy/falsy ternary), \`branches\` does exact string match against the state field value. Always include a \`"default"\` branch.
|
|
7549
|
+
Parallel children are agent steps only. No nested parallel or map inside parallel.
|
|
7409
7550
|
|
|
7410
|
-
|
|
7551
|
+
### Map Step
|
|
7411
7552
|
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
}
|
|
7553
|
+
\`\`\`yaml
|
|
7554
|
+
- label:
|
|
7555
|
+
map:
|
|
7556
|
+
source: "extract.items"
|
|
7557
|
+
if: "extract.items.length > 0"
|
|
7558
|
+
each:
|
|
7559
|
+
prompt: Process {{item}}
|
|
7560
|
+
output: { result: string }
|
|
7561
|
+
batch: 50
|
|
7562
|
+
concurrency: 5
|
|
7420
7563
|
\`\`\`
|
|
7421
7564
|
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
| Field | Required | Description |
|
|
7425
|
-
|-------|----------|-------------|
|
|
7426
|
-
| id | no | State key for the agent's structured output |
|
|
7427
|
-
| type | yes | Must be \`"human"\` |
|
|
7428
|
-
| prompt | yes | Tell the agent what to present to the user and what to ask. The agent is a facilitator \u2014 write instructions like "Present X to the user and ask Y", NOT "You are a reviewer. Review X..." |
|
|
7429
|
-
| title | no | Display label for the human step |
|
|
7430
|
-
| schema | no | JSON Schema constraining the agent's structured output format |
|
|
7431
|
-
|
|
7432
|
-
### map \u2014 iterate over an array
|
|
7433
|
-
|
|
7434
|
-
\`\`\`json
|
|
7435
|
-
{ "id": "results", "type": "map",
|
|
7436
|
-
"source": "items",
|
|
7437
|
-
"each": { "prompt": "Audit: {{item}}", "schema": { "type": "object", "properties": { "result": { "type": "string" } } } },
|
|
7438
|
-
"batch": 10, "concurrency": 3
|
|
7439
|
-
}
|
|
7440
|
-
\`\`\`
|
|
7441
|
-
|
|
7442
|
-
| Field | Required | Description |
|
|
7443
|
-
|-------|----------|-------------|
|
|
7444
|
-
| id | yes | Output key for the results array |
|
|
7445
|
-
| source | yes | id of the step whose output is the array to iterate |
|
|
7446
|
-
| each | yes | Step applied to each element. Use {{item}} for the current element |
|
|
7447
|
-
| reduce | no | Step to aggregate results |
|
|
7448
|
-
| batch | no | Items per batch (default 50) |
|
|
7449
|
-
| concurrency | no | Max parallel items (default 5) |
|
|
7450
|
-
|
|
7451
|
-
### parallel \u2014 fixed fan-out
|
|
7452
|
-
|
|
7453
|
-
\`\`\`json
|
|
7454
|
-
{ "type": "parallel", "steps": [
|
|
7455
|
-
{ "id": "legal", "prompt": "Legal review: {{input}}" },
|
|
7456
|
-
{ "id": "finance", "prompt": "Finance: {{input}}" }
|
|
7457
|
-
]}
|
|
7458
|
-
\`\`\`
|
|
7459
|
-
|
|
7460
|
-
All steps run simultaneously. After all complete, execution continues to the next step.
|
|
7565
|
+
## Schema Shorthand
|
|
7461
7566
|
|
|
7462
|
-
|
|
7567
|
+
Write **{ field: type }** instead of JSON Schema:
|
|
7463
7568
|
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7569
|
+
| Shorthand | Meaning |
|
|
7570
|
+
|-----------|---------|
|
|
7571
|
+
| **field: string** | string property |
|
|
7572
|
+
| **field: number** | number property |
|
|
7573
|
+
| **field: boolean** | boolean property |
|
|
7574
|
+
| **field: string[]** | array of strings |
|
|
7575
|
+
| **field: number[]** | array of numbers |
|
|
7576
|
+
| **field: [{ a: string, b: number }]** | array of objects |
|
|
7577
|
+
| **field: { sub: string }** | nested object |
|
|
7467
7578
|
|
|
7468
|
-
|
|
7579
|
+
Use **block style** (each field on its own line). Flow style \`{ field: "type" }\` with quoted values also works.
|
|
7469
7580
|
|
|
7470
|
-
|
|
7581
|
+
## Template Syntax
|
|
7471
7582
|
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7583
|
+
| Syntax | Resolves to |
|
|
7584
|
+
|--------|------------|
|
|
7585
|
+
| \`{{input}}\` | Initial user message |
|
|
7586
|
+
| \`{{label}}\` | Full output of step |
|
|
7587
|
+
| \`{{label.field}}\` | Nested field access |
|
|
7588
|
+
| \`{{item}}\` | Current element in map iteration |
|
|
7475
7589
|
|
|
7476
|
-
|
|
7477
|
-
{ "type": "condition", "if": "score >= 60",
|
|
7478
|
-
"then": { "type": "end", "status": "success" },
|
|
7479
|
-
"else": { "type": "end", "status": "failed" }
|
|
7480
|
-
}
|
|
7481
|
-
\`\`\`
|
|
7590
|
+
## Design Patterns
|
|
7482
7591
|
|
|
7483
|
-
|
|
7592
|
+
### Linear Pipeline
|
|
7484
7593
|
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7594
|
+
\`\`\`yaml
|
|
7595
|
+
steps:
|
|
7596
|
+
- extract:
|
|
7597
|
+
prompt: Extract data from {{input}}
|
|
7598
|
+
- transform:
|
|
7599
|
+
prompt: Transform {{extract}}
|
|
7600
|
+
- final:
|
|
7601
|
+
prompt: Combine raw {{extract}} with transformed {{transform}}
|
|
7602
|
+
\`\`\`
|
|
7492
7603
|
|
|
7493
|
-
|
|
7604
|
+
### Classify -> Route via Parallel + if
|
|
7494
7605
|
|
|
7495
|
-
|
|
7606
|
+
\`\`\`yaml
|
|
7607
|
+
steps:
|
|
7608
|
+
- classify:
|
|
7609
|
+
prompt: Classify intent from {{input}}
|
|
7610
|
+
output:
|
|
7611
|
+
intent: string
|
|
7612
|
+
urgency: number
|
|
7613
|
+
- parallel:
|
|
7614
|
+
- billing:
|
|
7615
|
+
if: "classify.intent == 'billing'"
|
|
7616
|
+
prompt: Handle billing: {{input}}
|
|
7617
|
+
ask: true
|
|
7618
|
+
- technical:
|
|
7619
|
+
if: "classify.intent == 'technical'"
|
|
7620
|
+
prompt: Handle technical: {{input}}
|
|
7621
|
+
- escalate:
|
|
7622
|
+
if: "classify.urgency >= 8"
|
|
7623
|
+
prompt: Urgent handling
|
|
7624
|
+
ask: true
|
|
7625
|
+
\`\`\`
|
|
7496
7626
|
|
|
7497
|
-
|
|
7498
|
-
\`\`\`json
|
|
7499
|
-
// \u274C WRONG \u2014 {{}} does not belong in if:
|
|
7500
|
-
{ "type": "condition", "if": "{{intent}}", "then": {...}, "else": {...} }
|
|
7627
|
+
### Parallel Processing
|
|
7501
7628
|
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7629
|
+
\`\`\`yaml
|
|
7630
|
+
steps:
|
|
7631
|
+
- gather:
|
|
7632
|
+
prompt: Gather data from {{input}}
|
|
7633
|
+
- parallel:
|
|
7634
|
+
- legal:
|
|
7635
|
+
prompt: Legal analysis of {{gather}}
|
|
7636
|
+
output:
|
|
7637
|
+
risk: string
|
|
7638
|
+
compliant: boolean
|
|
7639
|
+
- market:
|
|
7640
|
+
prompt: Market analysis of {{gather}}
|
|
7641
|
+
output:
|
|
7642
|
+
opportunity: string
|
|
7643
|
+
score: number
|
|
7644
|
+
- report:
|
|
7645
|
+
prompt: |
|
|
7646
|
+
Synthesize findings:
|
|
7647
|
+
Legal: {{legal}}
|
|
7648
|
+
Market: {{market}}
|
|
7649
|
+
\`\`\`
|
|
7505
7650
|
|
|
7506
|
-
|
|
7651
|
+
### Approval Flow with Human
|
|
7507
7652
|
|
|
7508
|
-
|
|
7653
|
+
\`\`\`yaml
|
|
7654
|
+
steps:
|
|
7655
|
+
- draft:
|
|
7656
|
+
prompt: Draft response to {{input}}
|
|
7657
|
+
- review:
|
|
7658
|
+
prompt: Present {{draft}} to user for approval
|
|
7659
|
+
output:
|
|
7660
|
+
approved: boolean
|
|
7661
|
+
comments: string
|
|
7662
|
+
ask: true
|
|
7663
|
+
- publish:
|
|
7664
|
+
if: "review.approved"
|
|
7665
|
+
prompt: Publish {{draft}}
|
|
7666
|
+
- revise:
|
|
7667
|
+
if: "!review.approved"
|
|
7668
|
+
prompt: Revise based on {{review.comments}}
|
|
7669
|
+
\`\`\`
|
|
7509
7670
|
|
|
7510
|
-
|
|
7511
|
-
- **edges** \u2014 auto-generated from step order (linear) and types (fan-out for parallel, conditional for condition)
|
|
7512
|
-
- **output.key** \u2014 always equals \`id\`
|
|
7513
|
-
- **version** \u2014 always "1.0" internally
|
|
7514
|
-
- **node IDs** \u2014 prefixed internally to avoid conflicts with state channel names
|
|
7515
|
-
- **human step type** \u2014 the human step has ask_user_to_clarify built-in. Use \`{ "type": "human", ... }\` in the DSL for user interaction. Do NOT manually add ask_user_to_clarify middleware to regular agent steps \u2014 use the dedicated \`human\` step instead.
|
|
7671
|
+
### Map (Iteration)
|
|
7516
7672
|
|
|
7517
|
-
|
|
7673
|
+
\`\`\`yaml
|
|
7674
|
+
steps:
|
|
7675
|
+
- extract:
|
|
7676
|
+
prompt: Extract items from {{input}}
|
|
7677
|
+
output:
|
|
7678
|
+
items:
|
|
7679
|
+
- name: string
|
|
7680
|
+
- map_items:
|
|
7681
|
+
map:
|
|
7682
|
+
source: "extract.items"
|
|
7683
|
+
each:
|
|
7684
|
+
prompt: Audit {{item.name}}
|
|
7685
|
+
output:
|
|
7686
|
+
result: string
|
|
7687
|
+
- summary:
|
|
7688
|
+
prompt: Summarize findings: {{map_items}}
|
|
7689
|
+
\`\`\`
|
|
7518
7690
|
|
|
7519
|
-
|
|
7691
|
+
## Keep Business Logic in Agents
|
|
7520
7692
|
|
|
7521
|
-
|
|
7522
|
-
{
|
|
7523
|
-
"name": "knowledge-qa",
|
|
7524
|
-
"steps": [
|
|
7525
|
-
{ "id": "research", "name": "Research Topic", "prompt": "Research: {{input}}", "schema": { "type": "object", "properties": { "findings": { "type": "string" } } } },
|
|
7526
|
-
{ "id": "answer", "name": "Write Answer", "prompt": "Write answer based on: {{research}}", "schema": { "type": "object", "properties": { "answer": { "type": "string" } } } },
|
|
7527
|
-
{ "type": "end" }
|
|
7528
|
-
]
|
|
7529
|
-
}
|
|
7530
|
-
\`\`\`
|
|
7693
|
+
The DSL is for orchestration (what runs when). Business logic (validation, branching, error handling, user interaction) belongs inside agent prompts, not as workflow if conditions. An agent can validate, branch, and ask questions \u2014 all in one step.
|
|
7531
7694
|
|
|
7532
|
-
|
|
7695
|
+
**Rule:** if you have more if conditions than workflow phases, move logic into richer agent prompts.
|
|
7533
7696
|
|
|
7534
|
-
|
|
7535
|
-
{
|
|
7536
|
-
"name": "customer-router",
|
|
7537
|
-
"steps": [
|
|
7538
|
-
{ "id": "intent", "name": "Classify Intent", "prompt": "Classify: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } },
|
|
7539
|
-
{ "type": "condition", "if": "intent",
|
|
7540
|
-
"then": { "id": "support", "name": "Handle Support", "prompt": "Handle support: {{input}}", "schema": { "type": "object", "properties": { "response": { "type": "string" } } } },
|
|
7541
|
-
"else": { "id": "sales", "name": "Handle Sales", "prompt": "Handle sales: {{input}}", "schema": { "type": "object", "properties": { "response": { "type": "string" } } } }
|
|
7542
|
-
},
|
|
7543
|
-
{ "type": "end" }
|
|
7544
|
-
]
|
|
7545
|
-
}
|
|
7546
|
-
\`\`\`
|
|
7697
|
+
## What You NEVER Write
|
|
7547
7698
|
|
|
7548
|
-
|
|
7699
|
+
- **needs** \u2014 not supported. Steps execute linearly. Use parallel for concurrency.
|
|
7700
|
+
- **edges** \u2014 auto-generated from step order and parallel structure
|
|
7701
|
+
- **nested parallel** \u2014 parallel children are flat agent steps only
|
|
7702
|
+
- **map inside parallel** \u2014 map is a top-level step only
|
|
7703
|
+
- **json schema** \u2014 use **{ field: type }** block style
|
|
7704
|
+
- do not use {{}} markers in if expressions
|
|
7705
|
+
- **workflow-level business logic** \u2014 decisions belong inside agent prompts
|
|
7549
7706
|
|
|
7550
|
-
|
|
7707
|
+
## Checklist
|
|
7551
7708
|
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
"sales": { "id": "sales", "prompt": "Handle sales: {{input}}" },
|
|
7561
|
-
"billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
|
|
7562
|
-
"default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
|
|
7563
|
-
}
|
|
7564
|
-
},
|
|
7565
|
-
{ "type": "end" }
|
|
7566
|
-
]
|
|
7567
|
-
}
|
|
7568
|
-
\`\`\`
|
|
7569
|
-
|
|
7570
|
-
### Pattern 3: Extract \u2192 Review \u2192 Approve
|
|
7571
|
-
|
|
7572
|
-
\`\`\`json
|
|
7573
|
-
{
|
|
7574
|
-
"name": "approval-flow",
|
|
7575
|
-
"steps": [
|
|
7576
|
-
{ "id": "draft", "name": "Draft Response", "prompt": "Draft a response to: {{input}}", "schema": { "type": "object", "properties": { "content": { "type": "string" } } } },
|
|
7577
|
-
{ "id": "review", "type": "human",
|
|
7578
|
-
"title": "Approval",
|
|
7579
|
-
"prompt": "Present the draft below to the user for approval. Ask whether to approve or reject with comments.\\n\\nDraft:\\n{{draft}}",
|
|
7580
|
-
"schema": { "type": "object", "properties": { "approved": { "type": "boolean" }, "comments": { "type": "string" } } } },
|
|
7581
|
-
{ "type": "condition", "if": "review.approved",
|
|
7582
|
-
"then": { "id": "published", "name": "Publish", "prompt": "Publish: {{draft}}", "schema": { "type": "object", "properties": { "status": { "type": "string" } } } },
|
|
7583
|
-
"else": { "id": "revised", "name": "Revise", "prompt": "Revise based on: {{review.comments}}", "schema": { "type": "object", "properties": { "content": { "type": "string" } } } }
|
|
7584
|
-
},
|
|
7585
|
-
{ "type": "end" }
|
|
7586
|
-
]
|
|
7587
|
-
}
|
|
7588
|
-
\`\`\`
|
|
7589
|
-
|
|
7590
|
-
### Pattern 4: Parallel Research
|
|
7591
|
-
|
|
7592
|
-
\`\`\`json
|
|
7593
|
-
{
|
|
7594
|
-
"name": "due-diligence",
|
|
7595
|
-
"steps": [
|
|
7596
|
-
{ "id": "info", "name": "Gather Info", "prompt": "Gather info: {{input}}", "schema": { "type": "object", "properties": { "rawData": { "type": "string" } } } },
|
|
7597
|
-
{ "type": "parallel", "steps": [
|
|
7598
|
-
{ "id": "legal", "name": "Legal Review", "prompt": "Legal review: {{info}}", "schema": { "type": "object", "properties": { "risks": { "type": "array", "items": { "type": "string" } } } } },
|
|
7599
|
-
{ "id": "finance", "name": "Finance Review", "prompt": "Finance review: {{info}}", "schema": { "type": "object", "properties": { "score": { "type": "number" } } } },
|
|
7600
|
-
{ "id": "market", "name": "Market Analysis", "prompt": "Market analysis: {{info}}", "schema": { "type": "object", "properties": { "trend": { "type": "string" } } } }
|
|
7601
|
-
]},
|
|
7602
|
-
{ "id": "synthesis", "name": "Synthesize", "prompt": "Synthesize: legal={{legal}} finance={{finance}} market={{market}}", "schema": { "type": "object", "properties": { "report": { "type": "string" } } } },
|
|
7603
|
-
{ "type": "end" }
|
|
7604
|
-
]
|
|
7605
|
-
}
|
|
7606
|
-
\`\`\`
|
|
7607
|
-
|
|
7608
|
-
### Pattern 5: Batch Map + Reduce
|
|
7609
|
-
|
|
7610
|
-
\`\`\`json
|
|
7611
|
-
{
|
|
7612
|
-
"name": "sentiment-analysis",
|
|
7613
|
-
"steps": [
|
|
7614
|
-
{ "id": "posts", "name": "Scrape Posts", "prompt": "Scrape posts about: {{input}}", "schema": { "type": "object", "properties": { "posts": { "type": "array", "items": { "type": "object", "properties": { "text": { "type": "string" } } } } } } },
|
|
7615
|
-
{ "id": "sentiments", "type": "map", "source": "posts",
|
|
7616
|
-
"each": { "prompt": "Analyze sentiment: {{item}}", "schema": { "type": "object", "properties": { "sentiment": { "type": "string" } } } },
|
|
7617
|
-
"reduce": { "prompt": "Summarize: {{sentiments}}", "schema": { "type": "object", "properties": { "summary": { "type": "string" } } } }
|
|
7618
|
-
},
|
|
7619
|
-
{ "id": "report", "name": "Generate Report", "prompt": "Generate report from: {{sentiments}}", "schema": { "type": "object", "properties": { "report": { "type": "string" } } } },
|
|
7620
|
-
{ "type": "end" }
|
|
7621
|
-
]
|
|
7622
|
-
}
|
|
7623
|
-
\`\`\`
|
|
7624
|
-
|
|
7625
|
-
## Step 1: Understand the Process
|
|
7626
|
-
|
|
7627
|
-
Ask the user:
|
|
7628
|
-
- What are the steps in order?
|
|
7629
|
-
- Are there branches (if condition then A else B)?
|
|
7630
|
-
- Can any steps run in parallel?
|
|
7631
|
-
- Is human approval/review needed?
|
|
7632
|
-
- What data flows between steps?
|
|
7633
|
-
|
|
7634
|
-
## Step 2: Prepare Dependencies
|
|
7635
|
-
|
|
7636
|
-
1. Call \`list_tools\` to see available tools for the workflow agent.
|
|
7637
|
-
|
|
7638
|
-
## Step 3: Write the DSL
|
|
7639
|
-
|
|
7640
|
-
Use \`create_workflow\` with \`skillLoaded: true\`. Never write \`state.fields\`, \`edges\`, \`version\`, or \`output.key\` \u2014 they are auto-generated.
|
|
7641
|
-
|
|
7642
|
-
**Checklist before calling:**
|
|
7643
|
-
- Every step that produces data referenced downstream has an \`id\`
|
|
7644
|
-
- Every agent/map-each step has a valid \`schema\` in standard JSON Schema format (with \`"type": "object"\` and \`"properties"\`)
|
|
7645
|
-
- Schema uses \`{ "type": "object", "properties": { ... } }\` \u2014 \`true\` and legacy \`{ "field": "string" }\` are REJECTED
|
|
7646
|
-
- Downstream steps reference upstream data with \`{{id}}\`
|
|
7647
|
-
- **Condition \`if\` fields do NOT use \`{{}}\`** \u2014 they are plain expressions like \`"intent"\` or \`"score >= 60"\`
|
|
7648
|
-
- Condition steps have \`then\`/\`else\` (binary) or \`branches\` (switch)
|
|
7649
|
-
- Human steps have \`schema\` constraining the agent's structured output
|
|
7650
|
-
- Map steps have \`source\` pointing to an existing step id
|
|
7651
|
-
- Parallel steps have sibling steps with unique \`id\`s
|
|
7652
|
-
- Workflow ends with \`{ "type": "end" }\`
|
|
7653
|
-
- Use \`human\` step type for user interaction (clarify middleware is built-in)
|
|
7654
|
-
|
|
7655
|
-
## Step 4: Test
|
|
7656
|
-
|
|
7657
|
-
After creating, optionally call \`validate_workflow(id)\` to check the workflow compiles correctly. Then test with \`invoke_agent\`.
|
|
7658
|
-
|
|
7659
|
-
## Debugging Tips
|
|
7660
|
-
|
|
7661
|
-
- If output is missing: check the producing step has an \`id\`
|
|
7662
|
-
- The human step invokes an agent that can use ask_user_to_clarify. The agent's structured output is stored under the step's \`id\`. Access nested results with dot notation: \`{{review.approved}}\`, \`{{review.comments}}\`
|
|
7663
|
-
- Map results are an array; use \`reduce\` to aggregate into a summary
|
|
7664
|
-
- Condition branching uses truthiness: empty string, 0, null, false \u2192 else path
|
|
7665
|
-
- \`{{input}}\` contains the user's initial message; it's always available
|
|
7666
|
-
- Parallel + condition: a parallel group cannot be the first step inside a condition's then/else (LangGraph limitation). Add a preceding agent step.
|
|
7667
|
-
`
|
|
7709
|
+
- Every step has a unique label
|
|
7710
|
+
- Steps execute top-to-bottom \u2014 no dependency thinking needed
|
|
7711
|
+
- \`{{label}}\` can reference ANY upstream step output
|
|
7712
|
+
- if uses plain JS, no {{}}
|
|
7713
|
+
- Schema uses block style shorthand
|
|
7714
|
+
- parallel children are flat agent steps
|
|
7715
|
+
- Business logic stays inside agent prompts
|
|
7716
|
+
- ask: true for human interaction`
|
|
7668
7717
|
};
|
|
7669
7718
|
function getBuiltInSkillMeta(name) {
|
|
7670
7719
|
const content = BUILTIN_SKILLS[name];
|
|
@@ -10575,7 +10624,7 @@ ${currentSystemPrompt}` : dateContext;
|
|
|
10575
10624
|
// src/deep_agent_new/middleware/scheduler.ts
|
|
10576
10625
|
import { tool as tool45, createMiddleware as createMiddleware13 } from "langchain";
|
|
10577
10626
|
import { z as z48 } from "zod";
|
|
10578
|
-
import { v4 as
|
|
10627
|
+
import { v4 as uuidv42 } from "uuid";
|
|
10579
10628
|
import { ScheduledTaskStatus as ScheduledTaskStatus3, ScheduleExecutionType as ScheduleExecutionType3 } from "@axiom-lattice/protocols";
|
|
10580
10629
|
|
|
10581
10630
|
// src/schedule_lattice/ScheduleLatticeManager.ts
|
|
@@ -12220,7 +12269,6 @@ var Agent = class {
|
|
|
12220
12269
|
const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
|
|
12221
12270
|
const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
|
|
12222
12271
|
const { messages, ...rest } = input;
|
|
12223
|
-
const lifecycleManager = this;
|
|
12224
12272
|
const runConfig = {
|
|
12225
12273
|
thread_id: this.thread_id,
|
|
12226
12274
|
"x-tenant-id": this.tenant_id,
|
|
@@ -12272,43 +12320,13 @@ var Agent = class {
|
|
|
12272
12320
|
}
|
|
12273
12321
|
);
|
|
12274
12322
|
try {
|
|
12275
|
-
|
|
12276
|
-
if (signal?.aborted) {
|
|
12277
|
-
await lifecycleManager.chunkBuffer.abortThread(lifecycleManager.thread_id);
|
|
12278
|
-
throw new Error("Agent execution was aborted");
|
|
12279
|
-
}
|
|
12280
|
-
let data;
|
|
12281
|
-
let chunkContent = "";
|
|
12282
|
-
if (chunk[0] === "updates") {
|
|
12283
|
-
const update = chunk[1];
|
|
12284
|
-
const values = Object.values(update);
|
|
12285
|
-
const messages2 = values[0]?.messages;
|
|
12286
|
-
if (messages2?.[0]?.tool_call_id) {
|
|
12287
|
-
data = messages2[0].toDict();
|
|
12288
|
-
}
|
|
12289
|
-
} else if (chunk[0] === "messages") {
|
|
12290
|
-
const messages2 = chunk[1];
|
|
12291
|
-
data = messages2?.[0]?.toDict();
|
|
12292
|
-
}
|
|
12293
|
-
if (chunk?.[1]?.__interrupt__) {
|
|
12294
|
-
const interruptData = chunk?.[1]?.__interrupt__[0];
|
|
12295
|
-
data = {
|
|
12296
|
-
type: "interrupt",
|
|
12297
|
-
id: interruptData.id,
|
|
12298
|
-
data: { content: interruptData.value }
|
|
12299
|
-
};
|
|
12300
|
-
}
|
|
12301
|
-
if (data) {
|
|
12302
|
-
lifecycleManager.addChunk(data);
|
|
12303
|
-
}
|
|
12304
|
-
}
|
|
12323
|
+
await this.consumeAgentStream(agentStream, signal);
|
|
12305
12324
|
} catch (error) {
|
|
12306
12325
|
console.error("Stream error:", error);
|
|
12307
|
-
await lifecycleManager.chunkBuffer.abortThread(lifecycleManager.thread_id);
|
|
12308
12326
|
throw error;
|
|
12309
12327
|
}
|
|
12310
12328
|
} catch (error) {
|
|
12311
|
-
await this.chunkBuffer.abortThread(
|
|
12329
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
12312
12330
|
throw error;
|
|
12313
12331
|
}
|
|
12314
12332
|
};
|
|
@@ -12589,8 +12607,8 @@ var Agent = class {
|
|
|
12589
12607
|
this.assistant_id = assistant_id;
|
|
12590
12608
|
this.thread_id = thread_id;
|
|
12591
12609
|
this.tenant_id = tenant_id;
|
|
12592
|
-
this.workspace_id = workspace_id;
|
|
12593
|
-
this.project_id = project_id;
|
|
12610
|
+
this.workspace_id = workspace_id || "default";
|
|
12611
|
+
this.project_id = project_id || "default";
|
|
12594
12612
|
this.custom_run_config = custom_run_config;
|
|
12595
12613
|
}
|
|
12596
12614
|
getHumanPendingContent(message) {
|
|
@@ -12684,10 +12702,132 @@ var Agent = class {
|
|
|
12684
12702
|
const inputMessage = { ...queueMessage, input };
|
|
12685
12703
|
return this.agentExecutor(inputMessage, signal);
|
|
12686
12704
|
}
|
|
12705
|
+
/**
|
|
12706
|
+
* Like {@link invoke} but returns the full LangGraph state (all annotations)
|
|
12707
|
+
* instead of only messages. Messages are serialized to dicts; other state
|
|
12708
|
+
* fields are returned as-is.
|
|
12709
|
+
*
|
|
12710
|
+
* @remarks
|
|
12711
|
+
* Only call this when you need the full state. Existing callers (gateway,
|
|
12712
|
+
* workflows) should keep using {@link invoke} which returns only messages
|
|
12713
|
+
* to avoid exposing internal annotation data.
|
|
12714
|
+
*/
|
|
12715
|
+
async invokeWithState(queueMessage, signal) {
|
|
12716
|
+
const messageId = v4();
|
|
12717
|
+
const input = {
|
|
12718
|
+
...queueMessage.input,
|
|
12719
|
+
messages: [new HumanMessage({ id: messageId, content: queueMessage.input.message })]
|
|
12720
|
+
};
|
|
12721
|
+
const inputMessage = { ...queueMessage, input };
|
|
12722
|
+
const { runnable_agent, runConfig } = await this.getLatticeClientAndRuntimeConfig(inputMessage.custom_run_config);
|
|
12723
|
+
const { messages, ...rest } = inputMessage.input;
|
|
12724
|
+
if (signal?.aborted) {
|
|
12725
|
+
throw new Error("Agent execution was aborted");
|
|
12726
|
+
}
|
|
12727
|
+
let result;
|
|
12728
|
+
result = await runnable_agent.invoke(
|
|
12729
|
+
inputMessage.command ? new Command2(inputMessage.command) : { ...rest, messages, "x-tenant-id": this.tenant_id },
|
|
12730
|
+
{
|
|
12731
|
+
context: { runConfig },
|
|
12732
|
+
configurable: {
|
|
12733
|
+
run_id: v4(),
|
|
12734
|
+
...runConfig,
|
|
12735
|
+
runConfig
|
|
12736
|
+
},
|
|
12737
|
+
recursionLimit: 200,
|
|
12738
|
+
signal
|
|
12739
|
+
}
|
|
12740
|
+
);
|
|
12741
|
+
if (signal?.aborted) {
|
|
12742
|
+
throw new Error("Agent execution was aborted");
|
|
12743
|
+
}
|
|
12744
|
+
const { messages: _rawMessages, ...restState } = result;
|
|
12745
|
+
const serializedMessages = result.messages.map((message) => {
|
|
12746
|
+
const { type, data } = message.toDict();
|
|
12747
|
+
return { ...data, role: type };
|
|
12748
|
+
});
|
|
12749
|
+
return { messages: serializedMessages, ...restState };
|
|
12750
|
+
}
|
|
12687
12751
|
async getPendingMessages() {
|
|
12688
12752
|
const store = this.getQueueStore();
|
|
12689
12753
|
return await store.getPendingMessages(this.thread_id);
|
|
12690
12754
|
}
|
|
12755
|
+
async consumeAgentStream(agentStream, signal) {
|
|
12756
|
+
for await (const chunk of agentStream) {
|
|
12757
|
+
if (signal?.aborted) {
|
|
12758
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
12759
|
+
throw new Error("Agent execution was aborted");
|
|
12760
|
+
}
|
|
12761
|
+
let data;
|
|
12762
|
+
if (chunk[0] === "updates") {
|
|
12763
|
+
const update = chunk[1];
|
|
12764
|
+
const values = Object.values(update);
|
|
12765
|
+
const messages = values[0]?.messages;
|
|
12766
|
+
if (messages?.[0]?.tool_call_id) {
|
|
12767
|
+
data = messages[0].toDict();
|
|
12768
|
+
}
|
|
12769
|
+
} else if (chunk[0] === "messages") {
|
|
12770
|
+
const messages = chunk[1];
|
|
12771
|
+
data = messages?.[0]?.toDict();
|
|
12772
|
+
}
|
|
12773
|
+
if (chunk?.[1]?.__interrupt__) {
|
|
12774
|
+
const interruptData = chunk?.[1]?.__interrupt__[0];
|
|
12775
|
+
data = {
|
|
12776
|
+
type: "interrupt",
|
|
12777
|
+
id: interruptData.id,
|
|
12778
|
+
data: { content: interruptData.value }
|
|
12779
|
+
};
|
|
12780
|
+
}
|
|
12781
|
+
if (data) {
|
|
12782
|
+
this.addChunk(data);
|
|
12783
|
+
}
|
|
12784
|
+
}
|
|
12785
|
+
}
|
|
12786
|
+
/**
|
|
12787
|
+
* Resume LangGraph execution from the last checkpoint.
|
|
12788
|
+
*
|
|
12789
|
+
* Streams with `null` input — this tells LangGraph to continue from
|
|
12790
|
+
* wherever it left off using the checkpointed state for this thread.
|
|
12791
|
+
* All output chunks are buffered via {@link addChunk}.
|
|
12792
|
+
*/
|
|
12793
|
+
async resumeGraphFromCheckpoint(signal) {
|
|
12794
|
+
const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
|
|
12795
|
+
const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
|
|
12796
|
+
if (!runnable_agent) {
|
|
12797
|
+
throw new Error(`Agent ${this.assistant_id} not found`);
|
|
12798
|
+
}
|
|
12799
|
+
const runConfig = {
|
|
12800
|
+
thread_id: this.thread_id,
|
|
12801
|
+
"x-tenant-id": this.tenant_id,
|
|
12802
|
+
"x-workspace-id": this.workspace_id,
|
|
12803
|
+
"x-project-id": this.project_id,
|
|
12804
|
+
"x-thread-id": this.thread_id,
|
|
12805
|
+
"x-assistant-id": this.assistant_id,
|
|
12806
|
+
...agentLattice?.config?.runConfig || {},
|
|
12807
|
+
tenantId: this.tenant_id,
|
|
12808
|
+
workspaceId: this.workspace_id,
|
|
12809
|
+
projectId: this.project_id,
|
|
12810
|
+
...this.custom_run_config || {},
|
|
12811
|
+
assistant_id: this.assistant_id
|
|
12812
|
+
};
|
|
12813
|
+
const agentStream = await runnable_agent.stream(
|
|
12814
|
+
null,
|
|
12815
|
+
{
|
|
12816
|
+
context: {
|
|
12817
|
+
runConfig
|
|
12818
|
+
},
|
|
12819
|
+
configurable: {
|
|
12820
|
+
...runConfig,
|
|
12821
|
+
runConfig
|
|
12822
|
+
},
|
|
12823
|
+
streamMode: ["updates", "messages"],
|
|
12824
|
+
subgraphs: false,
|
|
12825
|
+
recursionLimit: 200,
|
|
12826
|
+
signal
|
|
12827
|
+
}
|
|
12828
|
+
);
|
|
12829
|
+
await this.consumeAgentStream(agentStream, signal);
|
|
12830
|
+
}
|
|
12691
12831
|
getQueueStore() {
|
|
12692
12832
|
if (!this.queueStore) {
|
|
12693
12833
|
try {
|
|
@@ -12817,6 +12957,8 @@ var Agent = class {
|
|
|
12817
12957
|
threadId: this.thread_id,
|
|
12818
12958
|
tenantId: this.tenant_id,
|
|
12819
12959
|
assistantId: this.assistant_id,
|
|
12960
|
+
workspaceId: this.workspace_id,
|
|
12961
|
+
projectId: this.project_id,
|
|
12820
12962
|
content,
|
|
12821
12963
|
type: pendingType,
|
|
12822
12964
|
command: queueMessage.command,
|
|
@@ -12833,6 +12975,8 @@ var Agent = class {
|
|
|
12833
12975
|
threadId: this.thread_id,
|
|
12834
12976
|
tenantId: this.tenant_id,
|
|
12835
12977
|
assistantId: this.assistant_id,
|
|
12978
|
+
workspaceId: this.workspace_id,
|
|
12979
|
+
projectId: this.project_id,
|
|
12836
12980
|
content,
|
|
12837
12981
|
type: pendingType,
|
|
12838
12982
|
command: queueMessage.command,
|
|
@@ -12906,6 +13050,8 @@ var Agent = class {
|
|
|
12906
13050
|
threadId: thread.threadId,
|
|
12907
13051
|
tenantId: thread.tenantId,
|
|
12908
13052
|
assistantId: thread.assistantId,
|
|
13053
|
+
workspaceId: this.workspace_id,
|
|
13054
|
+
projectId: this.project_id,
|
|
12909
13055
|
content: reminderContent,
|
|
12910
13056
|
type: "system"
|
|
12911
13057
|
});
|
|
@@ -12977,9 +13123,14 @@ var Agent = class {
|
|
|
12977
13123
|
/**
|
|
12978
13124
|
* Resume processing after a server restart.
|
|
12979
13125
|
*
|
|
12980
|
-
*
|
|
12981
|
-
*
|
|
12982
|
-
*
|
|
13126
|
+
* If the graph was mid-execution (BUSY) it resumes from the LangGraph
|
|
13127
|
+
* checkpoint without re-injecting the message — the message has already
|
|
13128
|
+
* been consumed and is in the graph state. Processing messages are removed
|
|
13129
|
+
* rather than replayed.
|
|
13130
|
+
*
|
|
13131
|
+
* Skips threads that are in `INTERRUPTED` state (the interruption was
|
|
13132
|
+
* intentional). IDLE threads simply clean up and restart the queue
|
|
13133
|
+
* processor for any remaining pending messages.
|
|
12983
13134
|
*
|
|
12984
13135
|
* Called during gateway startup to recover threads that were mid-execution
|
|
12985
13136
|
* when the server went down.
|
|
@@ -12997,9 +13148,32 @@ var Agent = class {
|
|
|
12997
13148
|
return;
|
|
12998
13149
|
}
|
|
12999
13150
|
const store = this.getQueueStore();
|
|
13000
|
-
|
|
13001
|
-
|
|
13002
|
-
|
|
13151
|
+
if (runStatus === "busy" /* BUSY */) {
|
|
13152
|
+
this.abortController = new AbortController();
|
|
13153
|
+
try {
|
|
13154
|
+
await this.resumeGraphFromCheckpoint(this.abortController.signal);
|
|
13155
|
+
const processingMessages = await store.getProcessingMessages(this.thread_id);
|
|
13156
|
+
for (const msg of processingMessages) {
|
|
13157
|
+
await store.removeMessage(msg.id);
|
|
13158
|
+
}
|
|
13159
|
+
if (processingMessages.length > 0) {
|
|
13160
|
+
console.log(`[Agent] Removed ${processingMessages.length} processing messages for thread ${this.thread_id}`);
|
|
13161
|
+
}
|
|
13162
|
+
} catch (error) {
|
|
13163
|
+
console.error(`[Agent] Failed to resume graph for thread ${this.thread_id}:`, error);
|
|
13164
|
+
await this.chunkBuffer.abortThread(this.thread_id);
|
|
13165
|
+
throw error;
|
|
13166
|
+
} finally {
|
|
13167
|
+
this.abortController = null;
|
|
13168
|
+
}
|
|
13169
|
+
} else {
|
|
13170
|
+
const processingMessages = await store.getProcessingMessages(this.thread_id);
|
|
13171
|
+
for (const msg of processingMessages) {
|
|
13172
|
+
await store.removeMessage(msg.id);
|
|
13173
|
+
}
|
|
13174
|
+
if (processingMessages.length > 0) {
|
|
13175
|
+
console.log(`[Agent] Removed ${processingMessages.length} processing messages for thread ${this.thread_id}`);
|
|
13176
|
+
}
|
|
13003
13177
|
}
|
|
13004
13178
|
await this.startQueueProcessorIfNeeded();
|
|
13005
13179
|
}
|
|
@@ -13190,7 +13364,7 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
13190
13364
|
console.log(`[AgentInstanceManager] Found ${threadsWithPending.length} threads with pending messages, restoring...`);
|
|
13191
13365
|
for (const threadInfo of threadsWithPending) {
|
|
13192
13366
|
try {
|
|
13193
|
-
await this.restoreThread(threadInfo
|
|
13367
|
+
await this.restoreThread(threadInfo);
|
|
13194
13368
|
stats.restored++;
|
|
13195
13369
|
} catch (error) {
|
|
13196
13370
|
console.error(`[AgentInstanceManager] Failed to restore thread ${threadInfo.threadId}:`, error);
|
|
@@ -13208,16 +13382,14 @@ var AgentInstanceManager = class _AgentInstanceManager {
|
|
|
13208
13382
|
* Restore a single thread
|
|
13209
13383
|
* Delegates actual recovery logic to Agent.resumeTask()
|
|
13210
13384
|
*/
|
|
13211
|
-
async restoreThread(threadInfo
|
|
13212
|
-
const { tenantId, assistantId, threadId } = threadInfo;
|
|
13385
|
+
async restoreThread(threadInfo) {
|
|
13386
|
+
const { tenantId, assistantId, threadId, workspaceId, projectId } = threadInfo;
|
|
13213
13387
|
const threadParams = {
|
|
13214
13388
|
tenant_id: tenantId,
|
|
13215
13389
|
assistant_id: assistantId,
|
|
13216
13390
|
thread_id: threadId,
|
|
13217
|
-
workspace_id:
|
|
13218
|
-
|
|
13219
|
-
project_id: "default"
|
|
13220
|
-
// TODO: Get from thread store
|
|
13391
|
+
workspace_id: workspaceId,
|
|
13392
|
+
project_id: projectId
|
|
13221
13393
|
};
|
|
13222
13394
|
const agent = this.getAgent(threadParams);
|
|
13223
13395
|
await agent.resumeTask();
|
|
@@ -13308,7 +13480,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13308
13480
|
async (input, config) => {
|
|
13309
13481
|
const runConfig = getRunConfig(config);
|
|
13310
13482
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
13311
|
-
const taskId =
|
|
13483
|
+
const taskId = uuidv42();
|
|
13312
13484
|
const executeAt = input.executeAt;
|
|
13313
13485
|
const success = await scheduleLattice.client.scheduleOnce(
|
|
13314
13486
|
taskId,
|
|
@@ -13343,7 +13515,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13343
13515
|
async (input, config) => {
|
|
13344
13516
|
const runConfig = getRunConfig(config);
|
|
13345
13517
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
13346
|
-
const taskId =
|
|
13518
|
+
const taskId = uuidv42();
|
|
13347
13519
|
const executeAt = Date.now() + input.delayMs;
|
|
13348
13520
|
const success = await scheduleLattice.client.scheduleOnce(
|
|
13349
13521
|
taskId,
|
|
@@ -13378,7 +13550,7 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13378
13550
|
async (input, config) => {
|
|
13379
13551
|
const runConfig = getRunConfig(config);
|
|
13380
13552
|
const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
|
|
13381
|
-
const taskId =
|
|
13553
|
+
const taskId = uuidv42();
|
|
13382
13554
|
const success = await scheduleLattice.client.scheduleCron(
|
|
13383
13555
|
taskId,
|
|
13384
13556
|
AGENT_ADD_MESSAGE_TASK_TYPE,
|
|
@@ -13466,6 +13638,138 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13466
13638
|
});
|
|
13467
13639
|
}
|
|
13468
13640
|
|
|
13641
|
+
// src/middlewares/taskMiddleware.ts
|
|
13642
|
+
import { createMiddleware as createMiddleware14, tool as tool46 } from "langchain";
|
|
13643
|
+
import { z as z49 } from "zod";
|
|
13644
|
+
function getRunConfig2(config) {
|
|
13645
|
+
const c = config;
|
|
13646
|
+
return c?.configurable?.runConfig ?? {};
|
|
13647
|
+
}
|
|
13648
|
+
function getTaskStore() {
|
|
13649
|
+
return getStoreLattice("default", "task").store;
|
|
13650
|
+
}
|
|
13651
|
+
var manageTaskSchema = z49.object({
|
|
13652
|
+
action: z49.enum(["create", "list", "update", "delete", "complete"]).describe("\u64CD\u4F5C\u7C7B\u578B"),
|
|
13653
|
+
id: z49.string().optional().describe("\u4EFB\u52A1 ID (update/delete/complete \u5FC5\u586B)"),
|
|
13654
|
+
title: z49.string().optional().describe("\u4EFB\u52A1\u6807\u9898 (create \u5FC5\u586B)"),
|
|
13655
|
+
description: z49.string().optional().describe("\u4EFB\u52A1\u63CF\u8FF0"),
|
|
13656
|
+
priority: z49.enum(["low", "medium", "high"]).optional().describe("\u4F18\u5148\u7EA7"),
|
|
13657
|
+
status: z49.enum(["pending", "in_progress", "completed", "cancelled"]).optional().describe("\u72B6\u6001"),
|
|
13658
|
+
dueDate: z49.string().optional().describe("\u622A\u6B62\u65E5\u671F (ISO 8601)"),
|
|
13659
|
+
metadata: z49.record(z49.unknown()).optional().describe("\u7ED3\u6784\u5316\u5143\u6570\u636E (projectId, module \u7B49)"),
|
|
13660
|
+
parentId: z49.string().optional().describe("\u7236\u4EFB\u52A1 ID (\u5B50\u4EFB\u52A1\u5173\u8054)"),
|
|
13661
|
+
sourceId: z49.string().optional().describe("\u6765\u6E90\u4F1A\u8BDD/thread ID"),
|
|
13662
|
+
context: z49.record(z49.unknown()).optional().describe("\u9644\u52A0\u4E0A\u4E0B\u6587"),
|
|
13663
|
+
ownerType: z49.enum(["user", "agent"]).optional().describe("\u6240\u6709\u8005\u7C7B\u578B\uFF0C\u4E0D\u4F20\u9ED8\u8BA4\u4E3A user"),
|
|
13664
|
+
ownerId: z49.string().optional().describe("\u6240\u6709\u8005 ID\uFF0C\u4E0D\u4F20\u81EA\u52A8\u53D6\u5F53\u524D\u7528\u6237/Agent")
|
|
13665
|
+
});
|
|
13666
|
+
function createTaskMiddleware() {
|
|
13667
|
+
return createMiddleware14({
|
|
13668
|
+
name: "TaskMiddleware",
|
|
13669
|
+
contextSchema,
|
|
13670
|
+
wrapModelCall: async (request, handler) => {
|
|
13671
|
+
const taskPrompt = `## \u4EFB\u52A1\u7BA1\u7406\u80FD\u529B
|
|
13672
|
+
\u4F60\u53EF\u4EE5\u901A\u8FC7 manage_task \u5DE5\u5177\u7BA1\u7406\u6301\u4E45\u5316\u4EFB\u52A1\u3002ownerType \u548C ownerId \u7684\u9ED8\u8BA4\u884C\u4E3A\uFF1A
|
|
13673
|
+
- \u4E0D\u4F20\u53C2\u6570: \u9ED8\u8BA4\u4E3A\u5F53\u524D\u7528\u6237\u521B\u5EFA\u4EFB\u52A1 (ownerType="user", ownerId \u81EA\u52A8\u53D6\u5F53\u524D\u7528\u6237)
|
|
13674
|
+
- ownerType="agent": \u4E3A\u81EA\u5DF1\u521B\u5EFA\u6267\u884C\u5B50\u4EFB\u52A1 (ownerId \u81EA\u52A8\u53D6\u5F53\u524D Agent)
|
|
13675
|
+
- \u663E\u5F0F\u4F20 ownerId: \u4E3A\u6307\u5B9A agent/user \u521B\u5EFA\u4EFB\u52A1\uFF08\u62D3\u6251\u573A\u666F\uFF09`;
|
|
13676
|
+
return handler({
|
|
13677
|
+
...request,
|
|
13678
|
+
systemPrompt: taskPrompt + "\n\n" + (request.systemPrompt ?? "")
|
|
13679
|
+
});
|
|
13680
|
+
},
|
|
13681
|
+
tools: [
|
|
13682
|
+
tool46(
|
|
13683
|
+
async (input, config) => {
|
|
13684
|
+
const rc = getRunConfig2(config);
|
|
13685
|
+
const tenantId = rc.tenantId || "default";
|
|
13686
|
+
const ownerId = input.ownerId || (input.ownerType === "agent" ? rc.assistant_id : null) || rc.user_id;
|
|
13687
|
+
const store = getTaskStore();
|
|
13688
|
+
switch (input.action) {
|
|
13689
|
+
case "create": {
|
|
13690
|
+
if (!input.title) {
|
|
13691
|
+
return JSON.stringify({ success: false, error: "create requires title" });
|
|
13692
|
+
}
|
|
13693
|
+
const task = await store.create({
|
|
13694
|
+
tenantId,
|
|
13695
|
+
ownerType: input.ownerType || "user",
|
|
13696
|
+
ownerId,
|
|
13697
|
+
title: input.title,
|
|
13698
|
+
description: input.description,
|
|
13699
|
+
priority: input.priority || "medium",
|
|
13700
|
+
status: input.status || "pending",
|
|
13701
|
+
dueDate: input.dueDate,
|
|
13702
|
+
metadata: input.metadata,
|
|
13703
|
+
parentId: input.parentId,
|
|
13704
|
+
sourceId: input.sourceId,
|
|
13705
|
+
context: input.context
|
|
13706
|
+
});
|
|
13707
|
+
return JSON.stringify({ success: true, data: task });
|
|
13708
|
+
}
|
|
13709
|
+
case "list": {
|
|
13710
|
+
const tasks = await store.list({
|
|
13711
|
+
tenantId,
|
|
13712
|
+
ownerType: input.ownerType,
|
|
13713
|
+
ownerId: input.ownerId,
|
|
13714
|
+
status: input.status,
|
|
13715
|
+
priority: input.priority
|
|
13716
|
+
});
|
|
13717
|
+
return JSON.stringify({ success: true, data: tasks, count: tasks.length });
|
|
13718
|
+
}
|
|
13719
|
+
case "update": {
|
|
13720
|
+
if (!input.id) {
|
|
13721
|
+
return JSON.stringify({ success: false, error: "update requires id" });
|
|
13722
|
+
}
|
|
13723
|
+
const { action, ...updates } = input;
|
|
13724
|
+
const updated = await store.update(tenantId, input.id, updates);
|
|
13725
|
+
if (!updated) {
|
|
13726
|
+
return JSON.stringify({ success: false, error: "Task not found" });
|
|
13727
|
+
}
|
|
13728
|
+
return JSON.stringify({ success: true, data: updated });
|
|
13729
|
+
}
|
|
13730
|
+
case "delete": {
|
|
13731
|
+
if (!input.id) {
|
|
13732
|
+
return JSON.stringify({ success: false, error: "delete requires id" });
|
|
13733
|
+
}
|
|
13734
|
+
const deleted = await store.delete(tenantId, input.id);
|
|
13735
|
+
return JSON.stringify({ success: deleted, message: deleted ? "Task deleted" : "Task not found" });
|
|
13736
|
+
}
|
|
13737
|
+
case "complete": {
|
|
13738
|
+
if (!input.id) {
|
|
13739
|
+
return JSON.stringify({ success: false, error: "complete requires id" });
|
|
13740
|
+
}
|
|
13741
|
+
const updated = await store.update(tenantId, input.id, { status: "completed" });
|
|
13742
|
+
if (!updated) {
|
|
13743
|
+
return JSON.stringify({ success: false, error: "Task not found" });
|
|
13744
|
+
}
|
|
13745
|
+
return JSON.stringify({ success: true, data: updated });
|
|
13746
|
+
}
|
|
13747
|
+
default:
|
|
13748
|
+
return JSON.stringify({ success: false, error: `Unknown action: ${input.action}` });
|
|
13749
|
+
}
|
|
13750
|
+
},
|
|
13751
|
+
{
|
|
13752
|
+
name: "manage_task",
|
|
13753
|
+
description: `\u7BA1\u7406\u6301\u4E45\u5316\u4EFB\u52A1\u7CFB\u7EDF\u3002CRUD \u64CD\u4F5C\u7528\u6237\u548C Agent \u7684\u4EFB\u52A1\u3002
|
|
13754
|
+
|
|
13755
|
+
## ownerType \u548C ownerId \u7684\u9ED8\u8BA4\u903B\u8F91
|
|
13756
|
+
- \u4E0D\u4F20 ownerType \u548C ownerId: \u7CFB\u7EDF\u81EA\u52A8\u4E3A\u5F53\u524D\u7528\u6237\u521B\u5EFA\u4EFB\u52A1 (ownerType="user", ownerId \u53D6\u81EA\u5F53\u524D\u767B\u5F55\u7528\u6237)
|
|
13757
|
+
- \u4F20 ownerType="agent" \u4E0D\u4F20 ownerId: \u7CFB\u7EDF\u81EA\u52A8\u4E3A\u5F53\u524D Agent \u521B\u5EFA\u5B50\u4EFB\u52A1
|
|
13758
|
+
- \u663E\u5F0F\u4F20 ownerId: \u7CFB\u7EDF\u4F7F\u7528\u4F60\u6307\u5B9A\u7684 ID\uFF0C\u53EF\u8DE8 Agent \u6D3E\u53D1\u4EFB\u52A1\uFF08\u62D3\u6251\u573A\u666F\uFF09
|
|
13759
|
+
|
|
13760
|
+
## Actions
|
|
13761
|
+
- create: \u521B\u5EFA\u4EFB\u52A1 (title \u5FC5\u586B, priority/description/dueDate/metadata/parentId/context \u53EF\u9009)
|
|
13762
|
+
- list: \u5217\u51FA\u4EFB\u52A1\uFF0C\u53EF\u6309 ownerType/status/priority \u8FC7\u6EE4
|
|
13763
|
+
- update: \u66F4\u65B0\u4EFB\u52A1 (id \u5FC5\u586B\uFF0C\u53EA\u4F20\u8981\u6539\u7684\u5B57\u6BB5)
|
|
13764
|
+
- delete: \u5220\u9664\u4EFB\u52A1 (id \u5FC5\u586B)
|
|
13765
|
+
- complete: \u5FEB\u901F\u6807\u8BB0\u5B8C\u6210 (id \u5FC5\u586B)`,
|
|
13766
|
+
schema: manageTaskSchema
|
|
13767
|
+
}
|
|
13768
|
+
)
|
|
13769
|
+
]
|
|
13770
|
+
});
|
|
13771
|
+
}
|
|
13772
|
+
|
|
13469
13773
|
// src/agent_lattice/builders/CustomMiddlewareRegistry.ts
|
|
13470
13774
|
var CustomMiddlewareRegistry = class {
|
|
13471
13775
|
/**
|
|
@@ -13601,6 +13905,9 @@ async function createCommonMiddlewares(middlewareConfigs, filesystemBackend, fsI
|
|
|
13601
13905
|
case "scheduler":
|
|
13602
13906
|
middlewares.push(createSchedulerMiddleware(config.config));
|
|
13603
13907
|
break;
|
|
13908
|
+
case "task":
|
|
13909
|
+
middlewares.push(createTaskMiddleware());
|
|
13910
|
+
break;
|
|
13604
13911
|
case "custom":
|
|
13605
13912
|
{
|
|
13606
13913
|
const customConfig = config.config;
|
|
@@ -13633,10 +13940,12 @@ var SandboxFilesystem = class {
|
|
|
13633
13940
|
}
|
|
13634
13941
|
async lsInfo(dirPath) {
|
|
13635
13942
|
try {
|
|
13943
|
+
console.log(`[SandboxFilesystem.lsInfo] calling sandbox.file.listPath(${dirPath})`);
|
|
13636
13944
|
const result = await this.sandbox.file.listPath(dirPath, { recursive: false });
|
|
13945
|
+
console.log(`[SandboxFilesystem.lsInfo] got ${result.files.length} entries`);
|
|
13637
13946
|
return result.files;
|
|
13638
13947
|
} catch (e) {
|
|
13639
|
-
console.error(`
|
|
13948
|
+
console.error(`[SandboxFilesystem.lsInfo] error listing ${dirPath}:`, e);
|
|
13640
13949
|
return [];
|
|
13641
13950
|
}
|
|
13642
13951
|
}
|
|
@@ -13808,9 +14117,9 @@ var ReActAgentGraphBuilder = class {
|
|
|
13808
14117
|
*/
|
|
13809
14118
|
async build(agentLattice, params) {
|
|
13810
14119
|
const tools = params.tools.map((t) => {
|
|
13811
|
-
const
|
|
13812
|
-
return
|
|
13813
|
-
}).filter((
|
|
14120
|
+
const tool52 = getToolClient(t.key);
|
|
14121
|
+
return tool52;
|
|
14122
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
13814
14123
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
13815
14124
|
const middlewareConfigs = params.middleware || [];
|
|
13816
14125
|
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
@@ -13837,11 +14146,11 @@ import {
|
|
|
13837
14146
|
} from "langchain";
|
|
13838
14147
|
|
|
13839
14148
|
// src/deep_agent_new/middleware/subagents.ts
|
|
13840
|
-
import { z as
|
|
14149
|
+
import { z as z50 } from "zod/v3";
|
|
13841
14150
|
import {
|
|
13842
|
-
createMiddleware as
|
|
14151
|
+
createMiddleware as createMiddleware15,
|
|
13843
14152
|
createAgent as createAgent2,
|
|
13844
|
-
tool as
|
|
14153
|
+
tool as tool47,
|
|
13845
14154
|
ToolMessage as ToolMessage4,
|
|
13846
14155
|
humanInTheLoopMiddleware
|
|
13847
14156
|
} from "langchain";
|
|
@@ -14274,7 +14583,7 @@ function createTaskTool(options) {
|
|
|
14274
14583
|
generalPurposeAgent
|
|
14275
14584
|
});
|
|
14276
14585
|
const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
|
|
14277
|
-
return
|
|
14586
|
+
return tool47(
|
|
14278
14587
|
async (input, config) => {
|
|
14279
14588
|
const { description, subagent_type, async } = input;
|
|
14280
14589
|
let assistant_id = subagent_type;
|
|
@@ -14308,12 +14617,16 @@ function createTaskTool(options) {
|
|
|
14308
14617
|
const subagent_thread_id = config.configurable?.thread_id + "____" + assistant_id + "_" + config.toolCall.id;
|
|
14309
14618
|
if (async) {
|
|
14310
14619
|
const tenantId = config.configurable?.runConfig?.tenantId;
|
|
14620
|
+
const workspaceId = config.configurable?.runConfig?.workspaceId;
|
|
14621
|
+
const projectId = config.configurable?.runConfig?.projectId;
|
|
14311
14622
|
const mainAssistantId = config.configurable?.runConfig?.assistant_id;
|
|
14312
14623
|
const mainThreadId = config.configurable?.runConfig?.thread_id;
|
|
14313
14624
|
const mainRuntimeAgent = agentInstanceManager.getAgent({
|
|
14314
14625
|
assistant_id: mainAssistantId,
|
|
14315
14626
|
thread_id: mainThreadId,
|
|
14316
|
-
tenant_id: tenantId
|
|
14627
|
+
tenant_id: tenantId,
|
|
14628
|
+
workspace_id: workspaceId,
|
|
14629
|
+
project_id: projectId
|
|
14317
14630
|
});
|
|
14318
14631
|
if (mainRuntimeAgent) {
|
|
14319
14632
|
mainRuntimeAgent.addAsyncTask({
|
|
@@ -14392,15 +14705,15 @@ The result will be delivered as a notification when complete. Do not poll.`,
|
|
|
14392
14705
|
{
|
|
14393
14706
|
name: "task",
|
|
14394
14707
|
description: finalTaskDescription,
|
|
14395
|
-
schema:
|
|
14396
|
-
description:
|
|
14397
|
-
subagent_type:
|
|
14708
|
+
schema: z50.object({
|
|
14709
|
+
description: z50.string().describe("The task to execute with the selected agent"),
|
|
14710
|
+
subagent_type: z50.string().describe(
|
|
14398
14711
|
`Name of the agent to use. Available: ${Object.keys(
|
|
14399
14712
|
subagentGraphs
|
|
14400
14713
|
).join(", ")}`
|
|
14401
14714
|
),
|
|
14402
14715
|
...allowAsync ? {
|
|
14403
|
-
async:
|
|
14716
|
+
async: z50.boolean().default(false).describe(
|
|
14404
14717
|
"When true, runs the task in the background and returns immediately. Use for independent tasks that can run in parallel. The result is delivered as a notification when complete. Use check_async_task or list_async_tasks to monitor progress."
|
|
14405
14718
|
)
|
|
14406
14719
|
} : {}
|
|
@@ -14419,7 +14732,7 @@ function getMainAgentFromConfig(config) {
|
|
|
14419
14732
|
});
|
|
14420
14733
|
}
|
|
14421
14734
|
function createCheckAsyncTaskTool() {
|
|
14422
|
-
return
|
|
14735
|
+
return tool47(
|
|
14423
14736
|
async (input, config) => {
|
|
14424
14737
|
const { task_id } = input;
|
|
14425
14738
|
const mainAgent = getMainAgentFromConfig(config);
|
|
@@ -14479,14 +14792,14 @@ Description: ${cached.description}`;
|
|
|
14479
14792
|
{
|
|
14480
14793
|
name: "check_async_task",
|
|
14481
14794
|
description: "Get the current status and result of an async background task. Use this to check if a previously launched async task has completed.",
|
|
14482
|
-
schema:
|
|
14483
|
-
task_id:
|
|
14795
|
+
schema: z50.object({
|
|
14796
|
+
task_id: z50.string().describe("The task ID returned when the async task was started")
|
|
14484
14797
|
})
|
|
14485
14798
|
}
|
|
14486
14799
|
);
|
|
14487
14800
|
}
|
|
14488
14801
|
function createListAsyncTasksTool() {
|
|
14489
|
-
return
|
|
14802
|
+
return tool47(
|
|
14490
14803
|
async (_input, config) => {
|
|
14491
14804
|
const mainAgent = getMainAgentFromConfig(config);
|
|
14492
14805
|
if (!mainAgent) {
|
|
@@ -14532,12 +14845,12 @@ function createListAsyncTasksTool() {
|
|
|
14532
14845
|
{
|
|
14533
14846
|
name: "list_async_tasks",
|
|
14534
14847
|
description: "List all async background tasks with their current status. Use this before reporting task status to the user. Statuses in conversation history may be stale.",
|
|
14535
|
-
schema:
|
|
14848
|
+
schema: z50.object({})
|
|
14536
14849
|
}
|
|
14537
14850
|
);
|
|
14538
14851
|
}
|
|
14539
14852
|
function createCancelAsyncTaskTool() {
|
|
14540
|
-
return
|
|
14853
|
+
return tool47(
|
|
14541
14854
|
async (input, config) => {
|
|
14542
14855
|
const { task_id } = input;
|
|
14543
14856
|
const mainAgent = getMainAgentFromConfig(config);
|
|
@@ -14576,8 +14889,8 @@ function createCancelAsyncTaskTool() {
|
|
|
14576
14889
|
{
|
|
14577
14890
|
name: "cancel_async_task",
|
|
14578
14891
|
description: "Cancel a running async background task.",
|
|
14579
|
-
schema:
|
|
14580
|
-
task_id:
|
|
14892
|
+
schema: z50.object({
|
|
14893
|
+
task_id: z50.string().describe("The task ID to cancel")
|
|
14581
14894
|
})
|
|
14582
14895
|
}
|
|
14583
14896
|
);
|
|
@@ -14613,7 +14926,7 @@ function createSubAgentMiddleware(options) {
|
|
|
14613
14926
|
);
|
|
14614
14927
|
}
|
|
14615
14928
|
const effectiveSystemPrompt = allowAsync ? systemPrompt + getAsyncPromptText() : systemPrompt;
|
|
14616
|
-
return
|
|
14929
|
+
return createMiddleware15({
|
|
14617
14930
|
name: "subAgentMiddleware",
|
|
14618
14931
|
tools: allTools,
|
|
14619
14932
|
wrapModelCall: async (request, handler) => {
|
|
@@ -14634,14 +14947,12 @@ ${effectiveSystemPrompt}` : effectiveSystemPrompt;
|
|
|
14634
14947
|
|
|
14635
14948
|
// src/deep_agent_new/middleware/patch_tool_calls.ts
|
|
14636
14949
|
import {
|
|
14637
|
-
createMiddleware as
|
|
14950
|
+
createMiddleware as createMiddleware16,
|
|
14638
14951
|
ToolMessage as ToolMessage5,
|
|
14639
14952
|
AIMessage as AIMessage2
|
|
14640
14953
|
} from "langchain";
|
|
14641
|
-
import { RemoveMessage } from "@langchain/core/messages";
|
|
14642
|
-
import { REMOVE_ALL_MESSAGES } from "@langchain/langgraph";
|
|
14643
14954
|
function createPatchToolCallsMiddleware() {
|
|
14644
|
-
return
|
|
14955
|
+
return createMiddleware16({
|
|
14645
14956
|
name: "patchToolCallsMiddleware",
|
|
14646
14957
|
beforeAgent: async (state) => {
|
|
14647
14958
|
const messages = state.messages;
|
|
@@ -14670,11 +14981,12 @@ function createPatchToolCallsMiddleware() {
|
|
|
14670
14981
|
}
|
|
14671
14982
|
}
|
|
14672
14983
|
}
|
|
14984
|
+
if (patchedMessages.length === messages.length) {
|
|
14985
|
+
return;
|
|
14986
|
+
}
|
|
14673
14987
|
return {
|
|
14674
|
-
messages:
|
|
14675
|
-
|
|
14676
|
-
...patchedMessages
|
|
14677
|
-
]
|
|
14988
|
+
messages: patchedMessages.slice(messages.length)
|
|
14989
|
+
// only the new ToolMessage patches
|
|
14678
14990
|
};
|
|
14679
14991
|
}
|
|
14680
14992
|
});
|
|
@@ -15787,8 +16099,8 @@ var MemoryBackend = class {
|
|
|
15787
16099
|
|
|
15788
16100
|
// src/deep_agent_new/middleware/todos.ts
|
|
15789
16101
|
import { Command as Command4 } from "@langchain/langgraph";
|
|
15790
|
-
import { z as
|
|
15791
|
-
import { createMiddleware as
|
|
16102
|
+
import { z as z51 } from "zod";
|
|
16103
|
+
import { createMiddleware as createMiddleware17, tool as tool48, ToolMessage as ToolMessage6 } from "langchain";
|
|
15792
16104
|
var WRITE_TODOS_DESCRIPTION = `Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
|
|
15793
16105
|
It also helps the user understand the progress of the task and overall progress of their requests.
|
|
15794
16106
|
Only use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the taks directly.
|
|
@@ -16015,14 +16327,14 @@ Writing todos takes time and tokens, use it when it is helpful for managing comp
|
|
|
16015
16327
|
## Important To-Do List Usage Notes to Remember
|
|
16016
16328
|
- The \`write_todos\` tool should never be called multiple times in parallel.
|
|
16017
16329
|
- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.`;
|
|
16018
|
-
var TodoStatus =
|
|
16019
|
-
var TodoSchema =
|
|
16020
|
-
content:
|
|
16330
|
+
var TodoStatus = z51.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
|
|
16331
|
+
var TodoSchema = z51.object({
|
|
16332
|
+
content: z51.string().describe("Content of the todo item"),
|
|
16021
16333
|
status: TodoStatus
|
|
16022
16334
|
});
|
|
16023
|
-
var stateSchema =
|
|
16335
|
+
var stateSchema = z51.object({ todos: z51.array(TodoSchema).default([]) });
|
|
16024
16336
|
function todoListMiddleware(options) {
|
|
16025
|
-
const writeTodos =
|
|
16337
|
+
const writeTodos = tool48(
|
|
16026
16338
|
({ todos }, config) => {
|
|
16027
16339
|
return new Command4({
|
|
16028
16340
|
update: {
|
|
@@ -16039,12 +16351,12 @@ function todoListMiddleware(options) {
|
|
|
16039
16351
|
{
|
|
16040
16352
|
name: "write_todos",
|
|
16041
16353
|
description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,
|
|
16042
|
-
schema:
|
|
16043
|
-
todos:
|
|
16354
|
+
schema: z51.object({
|
|
16355
|
+
todos: z51.array(TodoSchema).describe("List of todo items to update")
|
|
16044
16356
|
})
|
|
16045
16357
|
}
|
|
16046
16358
|
);
|
|
16047
|
-
return
|
|
16359
|
+
return createMiddleware17({
|
|
16048
16360
|
name: "todoListMiddleware",
|
|
16049
16361
|
stateSchema,
|
|
16050
16362
|
tools: [writeTodos],
|
|
@@ -16156,7 +16468,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
16156
16468
|
const tools = params.tools.map((t) => {
|
|
16157
16469
|
const toolClient = getToolClient(t.key);
|
|
16158
16470
|
return toolClient;
|
|
16159
|
-
}).filter((
|
|
16471
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
16160
16472
|
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
16161
16473
|
if (sa.client) {
|
|
16162
16474
|
return {
|
|
@@ -16197,7 +16509,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
16197
16509
|
};
|
|
16198
16510
|
|
|
16199
16511
|
// src/agent_team/agent_team.ts
|
|
16200
|
-
import { z as
|
|
16512
|
+
import { z as z54 } from "zod/v3";
|
|
16201
16513
|
import { createAgent as createAgent5 } from "langchain";
|
|
16202
16514
|
|
|
16203
16515
|
// src/agent_team/types.ts
|
|
@@ -16633,14 +16945,14 @@ var InMemoryMailboxStore = class {
|
|
|
16633
16945
|
};
|
|
16634
16946
|
|
|
16635
16947
|
// src/agent_team/middleware/team.ts
|
|
16636
|
-
import { z as
|
|
16637
|
-
import { createMiddleware as
|
|
16948
|
+
import { z as z53 } from "zod/v3";
|
|
16949
|
+
import { createMiddleware as createMiddleware18, createAgent as createAgent4, tool as tool50, ToolMessage as ToolMessage8 } from "langchain";
|
|
16638
16950
|
import { Command as Command6, getCurrentTaskInput as getCurrentTaskInput3 } from "@langchain/langgraph";
|
|
16639
|
-
import { v4 as
|
|
16951
|
+
import { v4 as uuidv43 } from "uuid";
|
|
16640
16952
|
|
|
16641
16953
|
// src/agent_team/middleware/teammate_tools.ts
|
|
16642
|
-
import { z as
|
|
16643
|
-
import { tool as
|
|
16954
|
+
import { z as z52 } from "zod/v3";
|
|
16955
|
+
import { tool as tool49, ToolMessage as ToolMessage7 } from "langchain";
|
|
16644
16956
|
import { Command as Command5 } from "@langchain/langgraph";
|
|
16645
16957
|
|
|
16646
16958
|
// src/agent_team/middleware/formatMessages.ts
|
|
@@ -16665,7 +16977,7 @@ ${meta}${body}`;
|
|
|
16665
16977
|
// src/agent_team/middleware/teammate_tools.ts
|
|
16666
16978
|
function createTeammateTools(options) {
|
|
16667
16979
|
const { teamId, agentId, taskListStore, mailboxStore } = options;
|
|
16668
|
-
const claimTaskTool =
|
|
16980
|
+
const claimTaskTool = tool49(
|
|
16669
16981
|
async (input) => {
|
|
16670
16982
|
const task = await taskListStore.claimTaskById(
|
|
16671
16983
|
teamId,
|
|
@@ -16690,12 +17002,12 @@ function createTeammateTools(options) {
|
|
|
16690
17002
|
{
|
|
16691
17003
|
name: "claim_task",
|
|
16692
17004
|
description: "Pick a task to work on by task_id. Use check_tasks first to see all tasks; then call this with the task_id you choose. The task's assignee is set to you and you should focus on that task until you complete_task or fail_task it.",
|
|
16693
|
-
schema:
|
|
16694
|
-
task_id:
|
|
17005
|
+
schema: z52.object({
|
|
17006
|
+
task_id: z52.string().describe("ID of the task to claim (e.g. task-01). Use check_tasks to see IDs.")
|
|
16695
17007
|
})
|
|
16696
17008
|
}
|
|
16697
17009
|
);
|
|
16698
|
-
const completeTaskTool =
|
|
17010
|
+
const completeTaskTool = tool49(
|
|
16699
17011
|
async (input) => {
|
|
16700
17012
|
const task = await taskListStore.completeTask(
|
|
16701
17013
|
teamId,
|
|
@@ -16716,13 +17028,13 @@ function createTeammateTools(options) {
|
|
|
16716
17028
|
{
|
|
16717
17029
|
name: "complete_task",
|
|
16718
17030
|
description: "Mark a claimed task as completed with a result summary. Call this after you have finished working on a task.",
|
|
16719
|
-
schema:
|
|
16720
|
-
task_id:
|
|
16721
|
-
result:
|
|
17031
|
+
schema: z52.object({
|
|
17032
|
+
task_id: z52.string().describe("ID of the task to complete"),
|
|
17033
|
+
result: z52.string().describe("Summary of the task result")
|
|
16722
17034
|
})
|
|
16723
17035
|
}
|
|
16724
17036
|
);
|
|
16725
|
-
const failTaskTool =
|
|
17037
|
+
const failTaskTool = tool49(
|
|
16726
17038
|
async (input) => {
|
|
16727
17039
|
const task = await taskListStore.failTask(
|
|
16728
17040
|
teamId,
|
|
@@ -16743,13 +17055,13 @@ function createTeammateTools(options) {
|
|
|
16743
17055
|
{
|
|
16744
17056
|
name: "fail_task",
|
|
16745
17057
|
description: "Mark a claimed task as failed with an error description. Call this if you cannot complete the task.",
|
|
16746
|
-
schema:
|
|
16747
|
-
task_id:
|
|
16748
|
-
error:
|
|
17058
|
+
schema: z52.object({
|
|
17059
|
+
task_id: z52.string().describe("ID of the task to fail"),
|
|
17060
|
+
error: z52.string().describe("Description of why the task failed")
|
|
16749
17061
|
})
|
|
16750
17062
|
}
|
|
16751
17063
|
);
|
|
16752
|
-
const sendMessageTool =
|
|
17064
|
+
const sendMessageTool = tool49(
|
|
16753
17065
|
async (input) => {
|
|
16754
17066
|
await mailboxStore.sendMessage(
|
|
16755
17067
|
teamId,
|
|
@@ -16763,11 +17075,11 @@ function createTeammateTools(options) {
|
|
|
16763
17075
|
{
|
|
16764
17076
|
name: "send_message",
|
|
16765
17077
|
description: 'Send a message to the team lead or another teammate via the mailbox. Use "team_lead" to message the team lead. Use this to report discoveries, request guidance, or suggest new tasks.',
|
|
16766
|
-
schema:
|
|
16767
|
-
to:
|
|
17078
|
+
schema: z52.object({
|
|
17079
|
+
to: z52.string().describe(
|
|
16768
17080
|
'Recipient agent name (e.g. "team_lead" or a teammate name)'
|
|
16769
17081
|
),
|
|
16770
|
-
content:
|
|
17082
|
+
content: z52.string().describe("Message content")
|
|
16771
17083
|
})
|
|
16772
17084
|
}
|
|
16773
17085
|
);
|
|
@@ -16787,7 +17099,7 @@ function createTeammateTools(options) {
|
|
|
16787
17099
|
read: msg.read
|
|
16788
17100
|
}));
|
|
16789
17101
|
};
|
|
16790
|
-
const readMessagesTool =
|
|
17102
|
+
const readMessagesTool = tool49(
|
|
16791
17103
|
async (input, config) => {
|
|
16792
17104
|
const formatAndMarkAsRead = async (msgs2) => {
|
|
16793
17105
|
for (const msg of msgs2) {
|
|
@@ -16846,10 +17158,10 @@ function createTeammateTools(options) {
|
|
|
16846
17158
|
{
|
|
16847
17159
|
name: "read_messages",
|
|
16848
17160
|
description: "Read unread messages from the mailbox. Returns immediately if messages exist, otherwise waits for up to 3 minutes for new messages.",
|
|
16849
|
-
schema:
|
|
17161
|
+
schema: z52.object({})
|
|
16850
17162
|
}
|
|
16851
17163
|
);
|
|
16852
|
-
const checkTasksTool =
|
|
17164
|
+
const checkTasksTool = tool49(
|
|
16853
17165
|
async () => {
|
|
16854
17166
|
const tasks = await taskListStore.getAllTasks(teamId);
|
|
16855
17167
|
return formatTaskSummary(tasks);
|
|
@@ -16857,10 +17169,10 @@ function createTeammateTools(options) {
|
|
|
16857
17169
|
{
|
|
16858
17170
|
name: "check_tasks",
|
|
16859
17171
|
description: "Use this tool to get the current status of all tasks in a team. This is your primary way to monitor task progress.",
|
|
16860
|
-
schema:
|
|
17172
|
+
schema: z52.object({})
|
|
16861
17173
|
}
|
|
16862
17174
|
);
|
|
16863
|
-
const broadcastMessageTool =
|
|
17175
|
+
const broadcastMessageTool = tool49(
|
|
16864
17176
|
async (input) => {
|
|
16865
17177
|
const allAgents = await mailboxStore.getRegisteredAgents(teamId);
|
|
16866
17178
|
const recipients = allAgents.filter((a) => a !== agentId);
|
|
@@ -16879,8 +17191,8 @@ function createTeammateTools(options) {
|
|
|
16879
17191
|
{
|
|
16880
17192
|
name: "broadcast_message",
|
|
16881
17193
|
description: "Send a message to everyone in the team except yourself. Use this to share updates or information with all teammates and the team lead at once.",
|
|
16882
|
-
schema:
|
|
16883
|
-
content:
|
|
17194
|
+
schema: z52.object({
|
|
17195
|
+
content: z52.string().describe("Message content to broadcast to others")
|
|
16884
17196
|
})
|
|
16885
17197
|
}
|
|
16886
17198
|
);
|
|
@@ -17114,7 +17426,7 @@ async function spawnTeammate(options) {
|
|
|
17114
17426
|
function createTeamMiddleware(options) {
|
|
17115
17427
|
const { teamConfig, taskListStore, mailboxStore, tenantId } = options;
|
|
17116
17428
|
const defaultModel = teamConfig.model ?? "claude-sonnet-4-5-20250929";
|
|
17117
|
-
const createTeamTool =
|
|
17429
|
+
const createTeamTool = tool50(
|
|
17118
17430
|
async (input, config) => {
|
|
17119
17431
|
const state = getCurrentTaskInput3();
|
|
17120
17432
|
if (state?.team?.teamId) {
|
|
@@ -17126,7 +17438,7 @@ function createTeamMiddleware(options) {
|
|
|
17126
17438
|
});
|
|
17127
17439
|
return msg;
|
|
17128
17440
|
}
|
|
17129
|
-
const teamId =
|
|
17441
|
+
const teamId = uuidv43();
|
|
17130
17442
|
const createdTasks = await taskListStore.addTasks(
|
|
17131
17443
|
teamId,
|
|
17132
17444
|
input.tasks.map((t) => ({
|
|
@@ -17269,20 +17581,20 @@ After calling create_team, you MUST:
|
|
|
17269
17581
|
2. When messages indicate task changes, call check_tasks to get full task status
|
|
17270
17582
|
3. Continue until all tasks show "completed" or "failed"
|
|
17271
17583
|
4. Do NOT assume tasks are done - always verify with check_tasks`,
|
|
17272
|
-
schema:
|
|
17273
|
-
tasks:
|
|
17274
|
-
|
|
17275
|
-
id:
|
|
17276
|
-
title:
|
|
17277
|
-
description:
|
|
17278
|
-
dependencies:
|
|
17584
|
+
schema: z53.object({
|
|
17585
|
+
tasks: z53.array(
|
|
17586
|
+
z53.object({
|
|
17587
|
+
id: z53.string().describe("Task ID in format task-01, task-02, etc."),
|
|
17588
|
+
title: z53.string().describe("Short task title"),
|
|
17589
|
+
description: z53.string().describe("Detailed task description - what exactly needs to be done"),
|
|
17590
|
+
dependencies: z53.array(z53.string()).optional().default([]).describe('Array of task IDs that must complete before this task (e.g. ["task-01"])')
|
|
17279
17591
|
})
|
|
17280
17592
|
).describe("List of tasks for teammates to work on. Each task needs unique ID (task-01, task-02, etc.)."),
|
|
17281
|
-
teammates:
|
|
17282
|
-
|
|
17283
|
-
name:
|
|
17284
|
-
role:
|
|
17285
|
-
description:
|
|
17593
|
+
teammates: z53.array(
|
|
17594
|
+
z53.object({
|
|
17595
|
+
name: z53.string().describe("Teammate name (must match a pre-configured teammate type)"),
|
|
17596
|
+
role: z53.string().describe("Role category (e.g. researcher, writer, coder, reviewer)"),
|
|
17597
|
+
description: z53.string().describe("What this teammate will focus on - specific instructions for their work")
|
|
17286
17598
|
})
|
|
17287
17599
|
).describe("Teammate agents to create. Each should have a clear role and focus.")
|
|
17288
17600
|
})
|
|
@@ -17293,7 +17605,7 @@ After calling create_team, you MUST:
|
|
|
17293
17605
|
if (state?.team?.teamId) return state.team.teamId;
|
|
17294
17606
|
throw new Error("No team_id provided and no team in state. Call create_team first.");
|
|
17295
17607
|
};
|
|
17296
|
-
const addTasksTool =
|
|
17608
|
+
const addTasksTool = tool50(
|
|
17297
17609
|
async (input, config) => {
|
|
17298
17610
|
const teamId = resolveTeamId();
|
|
17299
17611
|
const created = await taskListStore.addTasks(
|
|
@@ -17345,20 +17657,20 @@ IMPORTANT: Dependencies
|
|
|
17345
17657
|
|
|
17346
17658
|
IMPORTANT: Assigning to a specific teammate
|
|
17347
17659
|
- When you need a particular teammate to do the work, set assignee to that teammate's name (e.g. assignee: "researcher"). They can then claim or see the task as assigned to them.`,
|
|
17348
|
-
schema:
|
|
17349
|
-
tasks:
|
|
17350
|
-
|
|
17351
|
-
id:
|
|
17352
|
-
title:
|
|
17353
|
-
description:
|
|
17354
|
-
assignee:
|
|
17355
|
-
dependencies:
|
|
17660
|
+
schema: z53.object({
|
|
17661
|
+
tasks: z53.array(
|
|
17662
|
+
z53.object({
|
|
17663
|
+
id: z53.string().describe("Task ID in format task-01, task-02, etc. Must be unique."),
|
|
17664
|
+
title: z53.string().describe("Short task title"),
|
|
17665
|
+
description: z53.string().describe("Detailed task description - what needs to be done"),
|
|
17666
|
+
assignee: z53.string().optional().describe("Teammate name to assign this task to (use when you need that person to do the work)"),
|
|
17667
|
+
dependencies: z53.array(z53.string()).optional().default([]).describe("Array of task IDs that must complete before this task")
|
|
17356
17668
|
})
|
|
17357
17669
|
).describe("New tasks to add to the team")
|
|
17358
17670
|
})
|
|
17359
17671
|
}
|
|
17360
17672
|
);
|
|
17361
|
-
const assignTaskTool =
|
|
17673
|
+
const assignTaskTool = tool50(
|
|
17362
17674
|
async (input, config) => {
|
|
17363
17675
|
const teamId = resolveTeamId();
|
|
17364
17676
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
@@ -17380,13 +17692,13 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
17380
17692
|
{
|
|
17381
17693
|
name: "assign_task",
|
|
17382
17694
|
description: "Assign a task to a specific teammate. Use when you need to reassign work to a different teammate. Omit team_id to use the active team from state.",
|
|
17383
|
-
schema:
|
|
17384
|
-
task_id:
|
|
17385
|
-
assignee:
|
|
17695
|
+
schema: z53.object({
|
|
17696
|
+
task_id: z53.string().describe("Task ID to assign"),
|
|
17697
|
+
assignee: z53.string().describe("Teammate name to assign this task to")
|
|
17386
17698
|
})
|
|
17387
17699
|
}
|
|
17388
17700
|
);
|
|
17389
|
-
const setTaskStatusTool =
|
|
17701
|
+
const setTaskStatusTool = tool50(
|
|
17390
17702
|
async (input, config) => {
|
|
17391
17703
|
const teamId = resolveTeamId();
|
|
17392
17704
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
@@ -17408,13 +17720,13 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
17408
17720
|
{
|
|
17409
17721
|
name: "set_task_status",
|
|
17410
17722
|
description: "Set a task's status. Use to reopen a task (set to pending), mark as failed, or correct status. Values: pending, claimed, in_progress, completed, failed. Omit team_id to use the active team from state.",
|
|
17411
|
-
schema:
|
|
17412
|
-
task_id:
|
|
17413
|
-
status:
|
|
17723
|
+
schema: z53.object({
|
|
17724
|
+
task_id: z53.string().describe("Task ID to update"),
|
|
17725
|
+
status: z53.enum(["pending", "claimed", "in_progress", "completed", "failed"]).describe("New status for the task")
|
|
17414
17726
|
})
|
|
17415
17727
|
}
|
|
17416
17728
|
);
|
|
17417
|
-
const setTaskDependenciesTool =
|
|
17729
|
+
const setTaskDependenciesTool = tool50(
|
|
17418
17730
|
async (input, config) => {
|
|
17419
17731
|
const teamId = resolveTeamId();
|
|
17420
17732
|
const task = await taskListStore.updateTask(teamId, input.task_id, {
|
|
@@ -17436,13 +17748,13 @@ IMPORTANT: Assigning to a specific teammate
|
|
|
17436
17748
|
{
|
|
17437
17749
|
name: "set_task_dependencies",
|
|
17438
17750
|
description: 'Set which task IDs must complete before this task can be claimed. Pass an array of task IDs (e.g. ["task-01", "task-02"]). Use to fix task order or add/remove dependencies. Omit team_id to use the active team from state.',
|
|
17439
|
-
schema:
|
|
17440
|
-
task_id:
|
|
17441
|
-
dependencies:
|
|
17751
|
+
schema: z53.object({
|
|
17752
|
+
task_id: z53.string().describe("Task ID to update"),
|
|
17753
|
+
dependencies: z53.array(z53.string()).describe("Task IDs that must complete before this task can be claimed")
|
|
17442
17754
|
})
|
|
17443
17755
|
}
|
|
17444
17756
|
);
|
|
17445
|
-
const checkTasksTool =
|
|
17757
|
+
const checkTasksTool = tool50(
|
|
17446
17758
|
async (input, config) => {
|
|
17447
17759
|
const teamId = resolveTeamId();
|
|
17448
17760
|
const tasks = await taskListStore.getAllTasks(teamId);
|
|
@@ -17482,12 +17794,12 @@ Task Status Values:
|
|
|
17482
17794
|
- in_progress: Teammate is actively working on this task
|
|
17483
17795
|
- completed: Task finished successfully
|
|
17484
17796
|
- failed: Task encountered an error`,
|
|
17485
|
-
schema:
|
|
17486
|
-
team_id:
|
|
17797
|
+
schema: z53.object({
|
|
17798
|
+
team_id: z53.string().optional().describe("Team ID (omit to use active team)")
|
|
17487
17799
|
})
|
|
17488
17800
|
}
|
|
17489
17801
|
);
|
|
17490
|
-
const sendMessageTool =
|
|
17802
|
+
const sendMessageTool = tool50(
|
|
17491
17803
|
async (input, config) => {
|
|
17492
17804
|
const teamId = resolveTeamId();
|
|
17493
17805
|
await mailboxStore.sendMessage(
|
|
@@ -17506,13 +17818,13 @@ Task Status Values:
|
|
|
17506
17818
|
{
|
|
17507
17819
|
name: "send_message",
|
|
17508
17820
|
description: "Send a message to a specific teammate in the team. Omit team_id to use the active team from state.",
|
|
17509
|
-
schema:
|
|
17510
|
-
to:
|
|
17511
|
-
content:
|
|
17821
|
+
schema: z53.object({
|
|
17822
|
+
to: z53.string().describe("Recipient teammate name"),
|
|
17823
|
+
content: z53.string().describe("Message content")
|
|
17512
17824
|
})
|
|
17513
17825
|
}
|
|
17514
17826
|
);
|
|
17515
|
-
const readMessagesTool =
|
|
17827
|
+
const readMessagesTool = tool50(
|
|
17516
17828
|
async (input, config) => {
|
|
17517
17829
|
const teamId = resolveTeamId();
|
|
17518
17830
|
const formatAndMarkAsRead = async (msgs2) => {
|
|
@@ -17594,12 +17906,12 @@ Task Status Values:
|
|
|
17594
17906
|
{
|
|
17595
17907
|
name: "read_messages",
|
|
17596
17908
|
description: "Read unread messages from teammates. Returns immediately if messages exist, otherwise waits for up to 3 minutes for new messages.",
|
|
17597
|
-
schema:
|
|
17598
|
-
team_id:
|
|
17909
|
+
schema: z53.object({
|
|
17910
|
+
team_id: z53.string().optional().describe("Team ID (omit to use active team)")
|
|
17599
17911
|
})
|
|
17600
17912
|
}
|
|
17601
17913
|
);
|
|
17602
|
-
const disbandTeamTool =
|
|
17914
|
+
const disbandTeamTool = tool50(
|
|
17603
17915
|
async (input, config) => {
|
|
17604
17916
|
const teamId = resolveTeamId();
|
|
17605
17917
|
await mailboxStore.broadcastMessage(
|
|
@@ -17620,7 +17932,7 @@ Task Status Values:
|
|
|
17620
17932
|
description: "Disband a team when all work is done. Before calling: (1) Call check_tasks to verify no tasks are still pending/in_progress; (2) if any are, discuss with the team via read_messages and broadcast_message/send_message whether to continue or stop/cancel them; (3) only after alignment (all tasks completed/failed or explicitly stopped), then call this tool. This will: 1) Send a shutdown message to all teammates, 2) Wait briefly for them to clean up, 3) Clear all tasks and messages. Omit team_id to use the active team from state."
|
|
17621
17933
|
}
|
|
17622
17934
|
);
|
|
17623
|
-
const broadcastMessageTool =
|
|
17935
|
+
const broadcastMessageTool = tool50(
|
|
17624
17936
|
async (input, config) => {
|
|
17625
17937
|
const teamId = resolveTeamId();
|
|
17626
17938
|
await mailboxStore.broadcastMessage(
|
|
@@ -17638,12 +17950,12 @@ Task Status Values:
|
|
|
17638
17950
|
{
|
|
17639
17951
|
name: "broadcast_message",
|
|
17640
17952
|
description: "Send a message to all teammates at once. Use this to communicate with everyone in the team. Omit team_id to use the active team from state.",
|
|
17641
|
-
schema:
|
|
17642
|
-
content:
|
|
17953
|
+
schema: z53.object({
|
|
17954
|
+
content: z53.string().describe("Message content to broadcast to all teammates")
|
|
17643
17955
|
})
|
|
17644
17956
|
}
|
|
17645
17957
|
);
|
|
17646
|
-
return
|
|
17958
|
+
return createMiddleware18({
|
|
17647
17959
|
name: "teamMiddleware",
|
|
17648
17960
|
tools: [
|
|
17649
17961
|
createTeamTool,
|
|
@@ -17671,37 +17983,37 @@ ${TEAM_SYSTEM_PROMPT}` : TEAM_SYSTEM_PROMPT;
|
|
|
17671
17983
|
}
|
|
17672
17984
|
|
|
17673
17985
|
// src/agent_team/agent_team.ts
|
|
17674
|
-
var TeammateInfoSchema =
|
|
17675
|
-
name:
|
|
17676
|
-
role:
|
|
17677
|
-
description:
|
|
17986
|
+
var TeammateInfoSchema = z54.object({
|
|
17987
|
+
name: z54.string().describe("Teammate name"),
|
|
17988
|
+
role: z54.string().describe("Role category (e.g. research, writing, review)"),
|
|
17989
|
+
description: z54.string().describe("What this teammate focuses on")
|
|
17678
17990
|
});
|
|
17679
|
-
var TeamTaskInfoSchema =
|
|
17680
|
-
id:
|
|
17681
|
-
title:
|
|
17682
|
-
description:
|
|
17683
|
-
status:
|
|
17991
|
+
var TeamTaskInfoSchema = z54.object({
|
|
17992
|
+
id: z54.string(),
|
|
17993
|
+
title: z54.string(),
|
|
17994
|
+
description: z54.string(),
|
|
17995
|
+
status: z54.string().optional()
|
|
17684
17996
|
});
|
|
17685
|
-
var MailboxMessageSchema =
|
|
17686
|
-
id:
|
|
17687
|
-
from:
|
|
17688
|
-
to:
|
|
17689
|
-
content:
|
|
17690
|
-
timestamp:
|
|
17691
|
-
type:
|
|
17692
|
-
read:
|
|
17997
|
+
var MailboxMessageSchema = z54.object({
|
|
17998
|
+
id: z54.string().describe("Unique message identifier"),
|
|
17999
|
+
from: z54.string().describe("Sender agent name"),
|
|
18000
|
+
to: z54.string().describe("Recipient agent name"),
|
|
18001
|
+
content: z54.string().describe("Message content"),
|
|
18002
|
+
timestamp: z54.string().describe("ISO timestamp when the message was sent"),
|
|
18003
|
+
type: z54.nativeEnum(MessageType).describe("Message type"),
|
|
18004
|
+
read: z54.boolean().describe("Whether the recipient has read this message")
|
|
17693
18005
|
});
|
|
17694
|
-
var TeamInfoSchema =
|
|
17695
|
-
teamId:
|
|
17696
|
-
teamLeadId:
|
|
17697
|
-
teammates:
|
|
17698
|
-
tasks:
|
|
17699
|
-
createdAt:
|
|
18006
|
+
var TeamInfoSchema = z54.object({
|
|
18007
|
+
teamId: z54.string().describe("Unique team identifier"),
|
|
18008
|
+
teamLeadId: z54.string().default("team_lead").describe("Team lead agent ID"),
|
|
18009
|
+
teammates: z54.array(TeammateInfoSchema).describe("Active teammates in this team"),
|
|
18010
|
+
tasks: z54.array(TeamTaskInfoSchema).optional().describe("Initial tasks snapshot"),
|
|
18011
|
+
createdAt: z54.string().optional().describe("ISO timestamp when team was created")
|
|
17700
18012
|
});
|
|
17701
|
-
var TEAM_STATE_SCHEMA =
|
|
18013
|
+
var TEAM_STATE_SCHEMA = z54.object({
|
|
17702
18014
|
team: TeamInfoSchema.optional().describe("Team info: teamId, teamLeadId, teammates, tasks. Set when create_team succeeds."),
|
|
17703
|
-
tasks:
|
|
17704
|
-
team_mailbox:
|
|
18015
|
+
tasks: z54.array(TeamTaskInfoSchema).optional().describe("Current tasks snapshot from check_tasks. Updated on each check."),
|
|
18016
|
+
team_mailbox: z54.array(MailboxMessageSchema).optional().describe("All team mailbox messages for display")
|
|
17705
18017
|
});
|
|
17706
18018
|
var TEAM_LEAD_BASE_PROMPT = `You are a team lead that coordinates a team of specialized agents. In order to complete the objective that the user asks of you, you will need to:
|
|
17707
18019
|
|
|
@@ -17782,7 +18094,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
17782
18094
|
const tools = params.tools.map((t) => {
|
|
17783
18095
|
const toolClient = getToolClient(t.key);
|
|
17784
18096
|
return toolClient;
|
|
17785
|
-
}).filter((
|
|
18097
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
17786
18098
|
const teammates = params.subAgents.map((sa) => {
|
|
17787
18099
|
const baseConfig = sa.config;
|
|
17788
18100
|
return {
|
|
@@ -17828,14 +18140,14 @@ import {
|
|
|
17828
18140
|
} from "langchain";
|
|
17829
18141
|
|
|
17830
18142
|
// src/middlewares/topologyMiddleware.ts
|
|
17831
|
-
import { createMiddleware as
|
|
18143
|
+
import { createMiddleware as createMiddleware19 } from "langchain";
|
|
17832
18144
|
import { AIMessage as AIMessage3, ToolMessage as ToolMessage9 } from "@langchain/core/messages";
|
|
17833
|
-
import { tool as
|
|
17834
|
-
import { z as
|
|
18145
|
+
import { tool as tool51 } from "langchain";
|
|
18146
|
+
import { z as z55 } from "zod";
|
|
17835
18147
|
import { GraphInterrupt as GraphInterrupt4 } from "@langchain/langgraph";
|
|
17836
|
-
var CompletedEdgeSchema =
|
|
17837
|
-
to:
|
|
17838
|
-
purpose:
|
|
18148
|
+
var CompletedEdgeSchema = z55.object({
|
|
18149
|
+
to: z55.string(),
|
|
18150
|
+
purpose: z55.string()
|
|
17839
18151
|
});
|
|
17840
18152
|
function deriveCompletedEdges(messages, edges) {
|
|
17841
18153
|
const completedToolCallIds = /* @__PURE__ */ new Set();
|
|
@@ -17862,16 +18174,16 @@ function deriveCompletedEdges(messages, edges) {
|
|
|
17862
18174
|
}
|
|
17863
18175
|
function createTopologyMiddleware(options) {
|
|
17864
18176
|
const { edges, trackingStore } = options;
|
|
17865
|
-
return
|
|
18177
|
+
return createMiddleware19({
|
|
17866
18178
|
name: "TopologyMiddleware",
|
|
17867
|
-
contextSchema:
|
|
17868
|
-
runConfig:
|
|
18179
|
+
contextSchema: z55.object({
|
|
18180
|
+
runConfig: z55.any()
|
|
17869
18181
|
}),
|
|
17870
|
-
stateSchema:
|
|
17871
|
-
currentAgentId:
|
|
17872
|
-
completedEdges:
|
|
17873
|
-
runId:
|
|
17874
|
-
stepIdMap:
|
|
18182
|
+
stateSchema: z55.object({
|
|
18183
|
+
currentAgentId: z55.string().default(""),
|
|
18184
|
+
completedEdges: z55.array(CompletedEdgeSchema).default([]),
|
|
18185
|
+
runId: z55.string().default(""),
|
|
18186
|
+
stepIdMap: z55.record(z55.string()).default({})
|
|
17875
18187
|
}),
|
|
17876
18188
|
beforeAgent: async (state, runtime) => {
|
|
17877
18189
|
if (state.runId) {
|
|
@@ -17922,14 +18234,14 @@ ${request.systemPrompt}` : topologyPrompt;
|
|
|
17922
18234
|
return handler({ ...request, systemPrompt: newSystemPrompt });
|
|
17923
18235
|
},
|
|
17924
18236
|
tools: [
|
|
17925
|
-
|
|
18237
|
+
tool51(
|
|
17926
18238
|
async (_input) => {
|
|
17927
18239
|
return "placeholder";
|
|
17928
18240
|
},
|
|
17929
18241
|
{
|
|
17930
18242
|
name: "read_topo_progress",
|
|
17931
18243
|
description: "Check the current progress of the workflow execution plan. Returns which steps have been completed and which are still pending.",
|
|
17932
|
-
schema:
|
|
18244
|
+
schema: z55.object({})
|
|
17933
18245
|
}
|
|
17934
18246
|
)
|
|
17935
18247
|
],
|
|
@@ -18205,7 +18517,7 @@ var ProcessingAgentGraphBuilder = class {
|
|
|
18205
18517
|
const tools = params.tools.map((t) => {
|
|
18206
18518
|
const toolClient = getToolClient(t.key);
|
|
18207
18519
|
return toolClient;
|
|
18208
|
-
}).filter((
|
|
18520
|
+
}).filter((tool52) => tool52 !== void 0);
|
|
18209
18521
|
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
18210
18522
|
if (sa.client) {
|
|
18211
18523
|
return {
|
|
@@ -18483,24 +18795,24 @@ var WorkflowAgentGraphBuilder = class {
|
|
|
18483
18795
|
);
|
|
18484
18796
|
}
|
|
18485
18797
|
const config = agentLattice.config;
|
|
18486
|
-
const
|
|
18798
|
+
const yaml = config.workflowYaml;
|
|
18487
18799
|
const tenantId = agentLattice.config.tenantId ?? "default";
|
|
18488
18800
|
const checkpointer = getCheckpointSaver("default");
|
|
18489
18801
|
const tools = params.tools.map((t) => t.executor).filter(Boolean);
|
|
18490
18802
|
const middlewareConfigs = params.middleware || [];
|
|
18491
18803
|
const middlewares = await createCommonMiddlewares(middlewareConfigs, void 0, false);
|
|
18492
|
-
const
|
|
18804
|
+
const askMiddlewares = await createCommonMiddlewares([
|
|
18493
18805
|
{
|
|
18494
18806
|
id: "ask_user_to_clarify",
|
|
18495
18807
|
type: "ask_user_to_clarify",
|
|
18496
18808
|
name: "Ask User Clarify",
|
|
18497
|
-
description: "For
|
|
18809
|
+
description: "For workflow steps requiring user interaction",
|
|
18498
18810
|
enabled: true,
|
|
18499
18811
|
config: {}
|
|
18500
18812
|
}
|
|
18501
18813
|
], void 0, false);
|
|
18502
18814
|
const noWrapMiddlewares = middlewares.filter((m) => !m.wrapModelCall);
|
|
18503
|
-
const
|
|
18815
|
+
const noWrapAskMiddlewares = askMiddlewares.filter((m) => !m.wrapModelCall);
|
|
18504
18816
|
console.log(`[WF BUILDER] building default agent | toolCount=${tools.length} | middlewareCount=${middlewares.length}`);
|
|
18505
18817
|
const defaultAgent = createAgent7({
|
|
18506
18818
|
model: params.model,
|
|
@@ -18516,34 +18828,34 @@ var WorkflowAgentGraphBuilder = class {
|
|
|
18516
18828
|
console.log(`[WF BUILDER] resolveAgent: looking up ref="${ref}"`);
|
|
18517
18829
|
return await getAgentClientAsync(tenantId, ref);
|
|
18518
18830
|
}
|
|
18519
|
-
const
|
|
18831
|
+
const isAsk = stepType === "ask";
|
|
18520
18832
|
if (responseFormat) {
|
|
18521
|
-
const key = (
|
|
18833
|
+
const key = (isAsk ? "ask:" : "agent:") + JSON.stringify(responseFormat);
|
|
18522
18834
|
console.log(`[WF BUILDER] resolveAgent: cacheKey=${key.slice(0, 80)}... | cached=${agentCache.has(key)}`);
|
|
18523
18835
|
if (!agentCache.has(key)) {
|
|
18524
|
-
console.log(`[WF BUILDER] creating ${
|
|
18836
|
+
console.log(`[WF BUILDER] creating ${isAsk ? "ask" : "agent"} with responseFormat`);
|
|
18525
18837
|
const agent = createAgent7({
|
|
18526
18838
|
model: params.model,
|
|
18527
18839
|
tools,
|
|
18528
18840
|
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
18529
18841
|
checkpointer,
|
|
18530
|
-
middleware:
|
|
18842
|
+
middleware: isAsk ? noWrapAskMiddlewares : noWrapMiddlewares,
|
|
18531
18843
|
responseFormat
|
|
18532
18844
|
});
|
|
18533
18845
|
agentCache.set(key, agent);
|
|
18534
18846
|
}
|
|
18535
18847
|
return agentCache.get(key);
|
|
18536
18848
|
}
|
|
18537
|
-
if (
|
|
18538
|
-
const key = "
|
|
18849
|
+
if (isAsk) {
|
|
18850
|
+
const key = "ask:default";
|
|
18539
18851
|
if (!agentCache.has(key)) {
|
|
18540
|
-
console.log(`[WF BUILDER] creating
|
|
18852
|
+
console.log(`[WF BUILDER] creating ask default agent`);
|
|
18541
18853
|
const agent = createAgent7({
|
|
18542
18854
|
model: params.model,
|
|
18543
18855
|
tools,
|
|
18544
18856
|
systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
|
|
18545
18857
|
checkpointer,
|
|
18546
|
-
middleware:
|
|
18858
|
+
middleware: askMiddlewares
|
|
18547
18859
|
});
|
|
18548
18860
|
agentCache.set(key, agent);
|
|
18549
18861
|
}
|
|
@@ -18556,11 +18868,11 @@ var WorkflowAgentGraphBuilder = class {
|
|
|
18556
18868
|
try {
|
|
18557
18869
|
const storeLattice = getStoreLattice("default", "workflowTracking");
|
|
18558
18870
|
trackingStore = storeLattice.store;
|
|
18559
|
-
console.log(`[WF BUILDER] trackingStore registered
|
|
18871
|
+
console.log(`[WF BUILDER] trackingStore registered`);
|
|
18560
18872
|
} catch {
|
|
18561
|
-
console.warn(`[WF BUILDER] no trackingStore registered
|
|
18873
|
+
console.warn(`[WF BUILDER] no trackingStore registered`);
|
|
18562
18874
|
}
|
|
18563
|
-
const graph = compileWorkflow(
|
|
18875
|
+
const graph = compileWorkflow(yaml, resolveAgent, checkpointer, trackingStore);
|
|
18564
18876
|
return graph;
|
|
18565
18877
|
}
|
|
18566
18878
|
};
|
|
@@ -19265,8 +19577,65 @@ ${body}` : `${frontmatter}
|
|
|
19265
19577
|
}
|
|
19266
19578
|
};
|
|
19267
19579
|
|
|
19580
|
+
// src/store_lattice/InMemoryMenuStore.ts
|
|
19581
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
19582
|
+
var InMemoryMenuStore = class {
|
|
19583
|
+
constructor() {
|
|
19584
|
+
this.items = /* @__PURE__ */ new Map();
|
|
19585
|
+
}
|
|
19586
|
+
async list(params) {
|
|
19587
|
+
const results = Array.from(this.items.values()).filter((item) => {
|
|
19588
|
+
if (item.tenantId !== params.tenantId) return false;
|
|
19589
|
+
if (params.menuTarget && item.menuTarget !== params.menuTarget) return false;
|
|
19590
|
+
if (!item.enabled) return false;
|
|
19591
|
+
return true;
|
|
19592
|
+
});
|
|
19593
|
+
results.sort((a, b) => a.sortOrder - b.sortOrder);
|
|
19594
|
+
return results;
|
|
19595
|
+
}
|
|
19596
|
+
async getById(id) {
|
|
19597
|
+
return this.items.get(id) || null;
|
|
19598
|
+
}
|
|
19599
|
+
async create(input) {
|
|
19600
|
+
const now = /* @__PURE__ */ new Date();
|
|
19601
|
+
const item = {
|
|
19602
|
+
id: randomUUID3(),
|
|
19603
|
+
tenantId: input.tenantId,
|
|
19604
|
+
menuTarget: input.menuTarget,
|
|
19605
|
+
group: input.group,
|
|
19606
|
+
name: input.name,
|
|
19607
|
+
icon: input.icon,
|
|
19608
|
+
sortOrder: input.sortOrder ?? 0,
|
|
19609
|
+
contentType: input.contentType,
|
|
19610
|
+
contentConfig: input.contentConfig,
|
|
19611
|
+
enabled: true,
|
|
19612
|
+
createdAt: now,
|
|
19613
|
+
updatedAt: now
|
|
19614
|
+
};
|
|
19615
|
+
this.items.set(item.id, item);
|
|
19616
|
+
return item;
|
|
19617
|
+
}
|
|
19618
|
+
async update(id, patch) {
|
|
19619
|
+
const existing = this.items.get(id);
|
|
19620
|
+
if (!existing) throw new Error(`MenuItem ${id} not found`);
|
|
19621
|
+
const updated = {
|
|
19622
|
+
...existing,
|
|
19623
|
+
...patch,
|
|
19624
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
19625
|
+
};
|
|
19626
|
+
this.items.set(id, updated);
|
|
19627
|
+
return updated;
|
|
19628
|
+
}
|
|
19629
|
+
async delete(id) {
|
|
19630
|
+
this.items.delete(id);
|
|
19631
|
+
}
|
|
19632
|
+
clear() {
|
|
19633
|
+
this.items.clear();
|
|
19634
|
+
}
|
|
19635
|
+
};
|
|
19636
|
+
|
|
19268
19637
|
// src/agent_lattice/agentArchitectTools.ts
|
|
19269
|
-
import
|
|
19638
|
+
import z56 from "zod";
|
|
19270
19639
|
import { v4 as v43 } from "uuid";
|
|
19271
19640
|
import { AgentType as AgentType3 } from "@axiom-lattice/protocols";
|
|
19272
19641
|
function getTenantId(exeConfig) {
|
|
@@ -19296,7 +19665,7 @@ registerToolLattice(
|
|
|
19296
19665
|
{
|
|
19297
19666
|
name: "list_agents",
|
|
19298
19667
|
description: "List all agents for the current workspace. Returns a summary with id, name, description, and type for each agent.",
|
|
19299
|
-
schema:
|
|
19668
|
+
schema: z56.object({})
|
|
19300
19669
|
},
|
|
19301
19670
|
async (_input, exeConfig) => {
|
|
19302
19671
|
try {
|
|
@@ -19323,8 +19692,8 @@ registerToolLattice(
|
|
|
19323
19692
|
{
|
|
19324
19693
|
name: "get_agent",
|
|
19325
19694
|
description: "Get the full configuration of a specific agent by its ID. Returns the complete AgentConfig including prompt, middleware, tools, and sub-agents.",
|
|
19326
|
-
schema:
|
|
19327
|
-
id:
|
|
19695
|
+
schema: z56.object({
|
|
19696
|
+
id: z56.string().describe("The agent ID to retrieve")
|
|
19328
19697
|
})
|
|
19329
19698
|
},
|
|
19330
19699
|
async (input, exeConfig) => {
|
|
@@ -19341,24 +19710,24 @@ registerToolLattice(
|
|
|
19341
19710
|
}
|
|
19342
19711
|
}
|
|
19343
19712
|
);
|
|
19344
|
-
var middlewareConfigSchema =
|
|
19345
|
-
id:
|
|
19346
|
-
type:
|
|
19347
|
-
name:
|
|
19348
|
-
description:
|
|
19349
|
-
enabled:
|
|
19350
|
-
config:
|
|
19713
|
+
var middlewareConfigSchema = z56.object({
|
|
19714
|
+
id: z56.string(),
|
|
19715
|
+
type: z56.string(),
|
|
19716
|
+
name: z56.string(),
|
|
19717
|
+
description: z56.string(),
|
|
19718
|
+
enabled: z56.boolean(),
|
|
19719
|
+
config: z56.record(z56.any()).optional()
|
|
19351
19720
|
});
|
|
19352
|
-
var createAgentSchema =
|
|
19353
|
-
name:
|
|
19354
|
-
description:
|
|
19355
|
-
type:
|
|
19356
|
-
prompt:
|
|
19357
|
-
tools:
|
|
19358
|
-
middleware:
|
|
19359
|
-
subAgents:
|
|
19360
|
-
internalSubAgents:
|
|
19361
|
-
modelKey:
|
|
19721
|
+
var createAgentSchema = z56.object({
|
|
19722
|
+
name: z56.string().describe("Human-friendly display name for the agent. The machine ID (used in other tools) is auto-generated as a slug from this name (e.g. 'My Cool Agent' \u2192 'my-cool-agent')."),
|
|
19723
|
+
description: z56.string().optional().describe("Short description"),
|
|
19724
|
+
type: z56.enum(["react", "deep_agent"]).describe("Agent type. Use 'react' for simple single-responsibility agents, 'deep_agent' for complex open-ended agents. For PROCESSING agents (workflow orchestration), use create_processing_agent instead."),
|
|
19725
|
+
prompt: z56.string().describe("System prompt for the agent"),
|
|
19726
|
+
tools: z56.array(z56.string()).optional().describe("Tool keys (strings) to assign. Call list_tools first to see available keys. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array of tool names. Do NOT put middleware-like objects here \u2014 middleware goes in the separate 'middleware' field."),
|
|
19727
|
+
middleware: z56.array(middlewareConfigSchema).optional().describe("Middleware configuration objects. Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here \u2014 tool names go in the separate 'tools' array. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
19728
|
+
subAgents: z56.array(z56.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
|
|
19729
|
+
internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
|
|
19730
|
+
modelKey: z56.string().optional().describe("Model key to use")
|
|
19362
19731
|
});
|
|
19363
19732
|
registerToolLattice(
|
|
19364
19733
|
"create_agent",
|
|
@@ -19396,21 +19765,21 @@ registerToolLattice(
|
|
|
19396
19765
|
}
|
|
19397
19766
|
}
|
|
19398
19767
|
);
|
|
19399
|
-
var topologyEdgeSchema =
|
|
19400
|
-
from:
|
|
19401
|
-
to:
|
|
19402
|
-
purpose:
|
|
19768
|
+
var topologyEdgeSchema = z56.object({
|
|
19769
|
+
from: z56.string().describe("Source agent ID. For the first edge, this is the orchestrator (use the orchestrator's name as a placeholder \u2014 the tool will replace it with the actual ID). For subsequent chained edges, this is the previous stage's sub-agent ID."),
|
|
19770
|
+
to: z56.string().describe("Target agent ID (the sub-agent to delegate to)"),
|
|
19771
|
+
purpose: z56.string().describe("Business purpose of this delegation step \u2014 what the sub-agent should accomplish")
|
|
19403
19772
|
});
|
|
19404
|
-
var createProcessingAgentSchema =
|
|
19405
|
-
name:
|
|
19406
|
-
description:
|
|
19407
|
-
prompt:
|
|
19408
|
-
edges:
|
|
19409
|
-
tools:
|
|
19410
|
-
subAgents:
|
|
19411
|
-
internalSubAgents:
|
|
19412
|
-
middleware:
|
|
19413
|
-
modelKey:
|
|
19773
|
+
var createProcessingAgentSchema = z56.object({
|
|
19774
|
+
name: z56.string().describe("Display name for the processing agent"),
|
|
19775
|
+
description: z56.string().optional().describe("Short description"),
|
|
19776
|
+
prompt: z56.string().describe("System prompt for the orchestrator. Should describe how to route tasks through the topology."),
|
|
19777
|
+
edges: z56.array(topologyEdgeSchema).min(1).describe("Topology edges defining the workflow. Each edge describes a delegation step with its business purpose. The orchestrator will follow this topology to delegate tasks to sub-agents."),
|
|
19778
|
+
tools: z56.array(z56.string()).optional().describe("Tool keys (strings) to assign to the orchestrator. Call list_tools first to see available keys. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array. Do NOT put middleware-like objects here \u2014 middleware goes in the separate 'middleware' field."),
|
|
19779
|
+
subAgents: z56.array(z56.string()).describe("IDs of sub-agents that form the workflow pipeline. These must be created first via create_agent."),
|
|
19780
|
+
internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (alternative to pre-created sub-agents)"),
|
|
19781
|
+
middleware: z56.array(middlewareConfigSchema).optional().describe("Additional middleware config objects beyond the auto-managed topology middleware. Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
19782
|
+
modelKey: z56.string().optional().describe("Model key to use")
|
|
19414
19783
|
}).refine(
|
|
19415
19784
|
(data) => {
|
|
19416
19785
|
const edgeTargets = new Set(data.edges.map((e) => e.to));
|
|
@@ -19492,34 +19861,20 @@ registerToolLattice(
|
|
|
19492
19861
|
}
|
|
19493
19862
|
}
|
|
19494
19863
|
);
|
|
19495
|
-
var
|
|
19496
|
-
()
|
|
19497
|
-
|
|
19498
|
-
|
|
19499
|
-
|
|
19500
|
-
|
|
19501
|
-
|
|
19502
|
-
|
|
19503
|
-
])
|
|
19504
|
-
);
|
|
19505
|
-
var workflowDSLSchema = z55.object({
|
|
19506
|
-
name: z55.string().describe("Workflow identifier (kebab-case slug)"),
|
|
19507
|
-
steps: z55.array(workflowStepLazy).min(1).describe("Workflow steps. Edges and state fields are auto-generated. Use {{id}} to reference step outputs. Always end with { type: 'end' }.")
|
|
19508
|
-
});
|
|
19509
|
-
var createWorkflowSchema = z55.object({
|
|
19510
|
-
name: z55.string().describe("Display name for the workflow agent"),
|
|
19511
|
-
description: z55.string().optional().describe("Short description of what this workflow does"),
|
|
19512
|
-
skillLoaded: z55.literal(true).describe("MUST be true. Set this to true ONLY after loading the 'create-workflow' skill via skill(skill_name: 'create-workflow'). This confirms you have read the DSL specification and design guidelines."),
|
|
19513
|
-
workflow: workflowDSLSchema.describe("The concise Workflow DSL definition. Each step has a type (agent/human/condition/map/parallel/end) and a prompt. Edges are auto-generated from step order. Use {{id}} to reference upstream step outputs."),
|
|
19514
|
-
tools: z55.array(z55.string()).optional().describe("Tool keys for the workflow's built-in general agent"),
|
|
19515
|
-
middleware: z55.array(middlewareConfigSchema).optional().describe("Middleware configs for the workflow's general agent"),
|
|
19516
|
-
modelKey: z55.string().optional().describe("Model key for the workflow's general agent")
|
|
19864
|
+
var createWorkflowSchema = z56.object({
|
|
19865
|
+
name: z56.string().describe("Display name for the workflow agent"),
|
|
19866
|
+
description: z56.string().optional().describe("Short description"),
|
|
19867
|
+
skillLoaded: z56.literal(true).describe("MUST be true. Set after loading the 'create-workflow' skill."),
|
|
19868
|
+
yaml: z56.string().describe("The YAML workflow definition in linear DSL format (steps execute top-to-bottom, use parallel: for concurrency)"),
|
|
19869
|
+
tools: z56.array(z56.string()).optional().describe("Tool keys for the workflow agent"),
|
|
19870
|
+
middleware: z56.array(middlewareConfigSchema).optional().describe("Middleware configs"),
|
|
19871
|
+
modelKey: z56.string().optional().describe("Model key")
|
|
19517
19872
|
});
|
|
19518
19873
|
registerToolLattice(
|
|
19519
19874
|
"create_workflow",
|
|
19520
19875
|
{
|
|
19521
19876
|
name: "create_workflow",
|
|
19522
|
-
description:
|
|
19877
|
+
description: "Create a WORKFLOW agent from YAML DSL. Load the 'create-workflow' skill first. Linear model \u2014 steps execute top-to-bottom. Use parallel: for concurrency. Data flows via {{label}} automatically. Business logic stays in agent prompts.",
|
|
19523
19878
|
schema: createWorkflowSchema
|
|
19524
19879
|
},
|
|
19525
19880
|
async (input, exeConfig) => {
|
|
@@ -19527,36 +19882,31 @@ registerToolLattice(
|
|
|
19527
19882
|
const tenantId = getTenantId(exeConfig);
|
|
19528
19883
|
const store = getAssistStore();
|
|
19529
19884
|
const id = await generateAgentId(tenantId, input.name);
|
|
19885
|
+
try {
|
|
19886
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
|
|
19887
|
+
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19888
|
+
await compileWorkflow2(input.yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19889
|
+
} catch (e) {
|
|
19890
|
+
return JSON.stringify({ error: `DSL validation failed: ${e.message}` });
|
|
19891
|
+
}
|
|
19530
19892
|
const config = {
|
|
19531
19893
|
key: id,
|
|
19532
19894
|
name: input.name,
|
|
19533
19895
|
description: input.description || "",
|
|
19534
19896
|
type: AgentType3.WORKFLOW,
|
|
19535
19897
|
prompt: input.description || `Workflow: ${input.name}`,
|
|
19536
|
-
|
|
19898
|
+
workflowYaml: input.yaml,
|
|
19537
19899
|
...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
|
|
19538
19900
|
...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
|
|
19539
19901
|
...input.modelKey ? { modelKey: input.modelKey } : {}
|
|
19540
19902
|
};
|
|
19541
|
-
try {
|
|
19542
|
-
const { compileWorkflow: compileWorkflow2 } = await import("./compile-SYSKVQHB.mjs");
|
|
19543
|
-
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19544
|
-
await compileWorkflow2(input.workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19545
|
-
} catch (e) {
|
|
19546
|
-
return JSON.stringify({ error: `DSL validation failed: ${e.message}`, issues: [{ type: "error", message: e.message }] });
|
|
19547
|
-
}
|
|
19548
19903
|
await store.createAssistant(tenantId, id, {
|
|
19549
19904
|
name: input.name,
|
|
19550
19905
|
description: input.description,
|
|
19551
19906
|
graphDefinition: config
|
|
19552
19907
|
});
|
|
19553
19908
|
eventBus.publish("assistant:created", { id, name: input.name, tenantId });
|
|
19554
|
-
return JSON.stringify({
|
|
19555
|
-
id,
|
|
19556
|
-
name: input.name,
|
|
19557
|
-
type: "workflow",
|
|
19558
|
-
stepCount: input.workflow.steps.length
|
|
19559
|
-
});
|
|
19909
|
+
return JSON.stringify({ id, name: input.name, type: "workflow" });
|
|
19560
19910
|
} catch (error) {
|
|
19561
19911
|
return JSON.stringify({ error: `Failed to create workflow: ${error.message}` });
|
|
19562
19912
|
}
|
|
@@ -19566,9 +19916,9 @@ registerToolLattice(
|
|
|
19566
19916
|
"validate_workflow",
|
|
19567
19917
|
{
|
|
19568
19918
|
name: "validate_workflow",
|
|
19569
|
-
description: "Validate a workflow agent's DSL for correctness by compiling it.
|
|
19570
|
-
schema:
|
|
19571
|
-
id:
|
|
19919
|
+
description: "Validate a workflow agent's DSL for correctness by compiling it.",
|
|
19920
|
+
schema: z56.object({
|
|
19921
|
+
id: z56.string().describe("The workflow agent ID to validate")
|
|
19572
19922
|
})
|
|
19573
19923
|
},
|
|
19574
19924
|
async (input, exeConfig) => {
|
|
@@ -19581,76 +19931,76 @@ registerToolLattice(
|
|
|
19581
19931
|
}
|
|
19582
19932
|
const graphDef = agent.graphDefinition;
|
|
19583
19933
|
if (!graphDef || graphDef.type !== AgentType3.WORKFLOW) {
|
|
19584
|
-
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent
|
|
19934
|
+
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
19585
19935
|
}
|
|
19586
|
-
const
|
|
19587
|
-
if (!
|
|
19588
|
-
return JSON.stringify({ error: `Agent '${input.id}' has no
|
|
19936
|
+
const yaml = graphDef.workflowYaml;
|
|
19937
|
+
if (!yaml) {
|
|
19938
|
+
return JSON.stringify({ error: `Agent '${input.id}' has no workflow DSL` });
|
|
19589
19939
|
}
|
|
19590
19940
|
try {
|
|
19591
|
-
const { compileWorkflow: compileWorkflow2 } = await import("./compile-
|
|
19941
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
|
|
19592
19942
|
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19593
|
-
await compileWorkflow2(
|
|
19943
|
+
await compileWorkflow2(yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
19594
19944
|
} catch (e) {
|
|
19595
19945
|
return JSON.stringify({
|
|
19596
19946
|
agentId: input.id,
|
|
19597
19947
|
valid: false,
|
|
19598
|
-
stepCount: workflow.steps?.length ?? 0,
|
|
19599
19948
|
issues: [{ type: "error", message: e.message }]
|
|
19600
19949
|
});
|
|
19601
19950
|
}
|
|
19602
|
-
return JSON.stringify({
|
|
19603
|
-
agentId: input.id,
|
|
19604
|
-
valid: true,
|
|
19605
|
-
stepCount: workflow.steps?.length ?? 0,
|
|
19606
|
-
issues: []
|
|
19607
|
-
});
|
|
19951
|
+
return JSON.stringify({ agentId: input.id, valid: true, issues: [] });
|
|
19608
19952
|
} catch (error) {
|
|
19609
19953
|
return JSON.stringify({ error: `Failed to validate workflow: ${error.message}` });
|
|
19610
19954
|
}
|
|
19611
19955
|
}
|
|
19612
19956
|
);
|
|
19613
|
-
var updateWorkflowSchema =
|
|
19614
|
-
id:
|
|
19615
|
-
name:
|
|
19616
|
-
description:
|
|
19617
|
-
|
|
19618
|
-
tools:
|
|
19619
|
-
middleware:
|
|
19620
|
-
modelKey:
|
|
19957
|
+
var updateWorkflowSchema = z56.object({
|
|
19958
|
+
id: z56.string().describe("The workflow agent ID to update"),
|
|
19959
|
+
name: z56.string().optional().describe("New display name"),
|
|
19960
|
+
description: z56.string().optional().describe("New description"),
|
|
19961
|
+
yaml: z56.string().optional().describe("Replacement YAML workflow DSL. Omit to keep existing."),
|
|
19962
|
+
tools: z56.array(z56.string()).optional().describe("Replacement tool keys"),
|
|
19963
|
+
middleware: z56.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
|
|
19964
|
+
modelKey: z56.string().optional().describe("Replacement model key")
|
|
19621
19965
|
});
|
|
19622
19966
|
registerToolLattice(
|
|
19623
19967
|
"update_workflow",
|
|
19624
19968
|
{
|
|
19625
19969
|
name: "update_workflow",
|
|
19626
|
-
description: "Update an existing workflow agent. Provide the agent ID and only the fields
|
|
19970
|
+
description: "Update an existing workflow agent. Provide the agent ID and only the fields to change. Pass yaml string to replace the DSL, or omit to keep it.",
|
|
19627
19971
|
schema: updateWorkflowSchema
|
|
19628
19972
|
},
|
|
19629
19973
|
async (input, exeConfig) => {
|
|
19974
|
+
console.log(`[update_workflow] CALLED id=${input.id} hasYaml=${input.yaml !== void 0}`);
|
|
19630
19975
|
try {
|
|
19631
19976
|
const tenantId = getTenantId(exeConfig);
|
|
19632
19977
|
const store = getAssistStore();
|
|
19633
19978
|
const existing = await store.getAssistantById(tenantId, input.id);
|
|
19634
19979
|
if (!existing) {
|
|
19980
|
+
console.log(`[update_workflow] ERROR: agent not found: ${input.id}`);
|
|
19635
19981
|
return JSON.stringify({ error: `Agent '${input.id}' not found` });
|
|
19636
19982
|
}
|
|
19637
19983
|
const existingConfig = existing.graphDefinition || {};
|
|
19638
19984
|
if (existingConfig.type !== AgentType3.WORKFLOW) {
|
|
19985
|
+
console.log(`[update_workflow] ERROR: not a workflow agent: ${input.id}`);
|
|
19639
19986
|
return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
|
|
19640
19987
|
}
|
|
19641
19988
|
const mergedConfig = { ...existingConfig };
|
|
19642
19989
|
if (input.name !== void 0) mergedConfig.name = input.name;
|
|
19643
19990
|
if (input.description !== void 0) mergedConfig.description = input.description;
|
|
19644
|
-
if (input.
|
|
19991
|
+
if (input.yaml !== void 0) mergedConfig.workflowYaml = input.yaml;
|
|
19645
19992
|
if (input.tools !== void 0) mergedConfig.tools = input.tools;
|
|
19646
19993
|
if (input.middleware !== void 0) mergedConfig.middleware = input.middleware;
|
|
19647
19994
|
if (input.modelKey !== void 0) mergedConfig.modelKey = input.modelKey;
|
|
19648
|
-
if (input.
|
|
19995
|
+
if (input.yaml !== void 0) {
|
|
19996
|
+
console.log(`[update_workflow] validating DSL: ${input.id}`);
|
|
19649
19997
|
try {
|
|
19650
|
-
const { compileWorkflow: compileWorkflow2 } = await import("./compile-
|
|
19998
|
+
const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
|
|
19651
19999
|
const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
|
|
19652
|
-
await compileWorkflow2(input.
|
|
20000
|
+
await compileWorkflow2(input.yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
|
|
20001
|
+
console.log(`[update_workflow] DSL validation passed: ${input.id}`);
|
|
19653
20002
|
} catch (e) {
|
|
20003
|
+
console.log(`[update_workflow] DSL validation FAILED: ${input.id} - ${e.message}`);
|
|
19654
20004
|
return JSON.stringify({
|
|
19655
20005
|
error: `DSL validation failed: ${e.message}`,
|
|
19656
20006
|
issues: [{ type: "error", message: e.message }]
|
|
@@ -19664,28 +20014,24 @@ registerToolLattice(
|
|
|
19664
20014
|
graphDefinition: mergedConfig
|
|
19665
20015
|
});
|
|
19666
20016
|
eventBus.publish("assistant:updated", { id: input.id, name: newName, tenantId });
|
|
19667
|
-
|
|
19668
|
-
return JSON.stringify({
|
|
19669
|
-
id: input.id,
|
|
19670
|
-
name: newName,
|
|
19671
|
-
type: "workflow",
|
|
19672
|
-
stepCount: workflow?.steps?.length ?? 0
|
|
19673
|
-
});
|
|
20017
|
+
console.log(`[update_workflow] SUCCESS: id=${input.id} name=${newName}`);
|
|
20018
|
+
return JSON.stringify({ id: input.id, name: newName, type: "workflow" });
|
|
19674
20019
|
} catch (error) {
|
|
20020
|
+
console.log(`[update_workflow] EXCEPTION: ${error.message}`);
|
|
19675
20021
|
return JSON.stringify({ error: `Failed to update workflow: ${error.message}` });
|
|
19676
20022
|
}
|
|
19677
20023
|
}
|
|
19678
20024
|
);
|
|
19679
|
-
var updateProcessingAgentSchema =
|
|
19680
|
-
id:
|
|
19681
|
-
name:
|
|
19682
|
-
description:
|
|
19683
|
-
prompt:
|
|
19684
|
-
edges:
|
|
19685
|
-
tools:
|
|
19686
|
-
subAgents:
|
|
19687
|
-
middleware:
|
|
19688
|
-
modelKey:
|
|
20025
|
+
var updateProcessingAgentSchema = z56.object({
|
|
20026
|
+
id: z56.string().describe("The PROCESSING agent ID to update"),
|
|
20027
|
+
name: z56.string().optional().describe("New display name for the orchestrator"),
|
|
20028
|
+
description: z56.string().optional().describe("New short description"),
|
|
20029
|
+
prompt: z56.string().optional().describe("New system prompt for the orchestrator"),
|
|
20030
|
+
edges: z56.array(topologyEdgeSchema).min(1).optional().describe("New topology edges. First edge's from must reference the orchestrator by name (the tool replaces it). Subsequent edges chain from previous sub-agent IDs."),
|
|
20031
|
+
tools: z56.array(z56.string()).optional().describe("Tool keys (strings) to assign to the orchestrator. Each element is a plain string like 'sap_api_search'. IMPORTANT: tools is a FLAT string array \u2014 do NOT put middleware-like objects here."),
|
|
20032
|
+
subAgents: z56.array(z56.string()).optional().describe("New IDs of sub-agents in the workflow pipeline"),
|
|
20033
|
+
middleware: z56.array(middlewareConfigSchema).optional().describe("Additional middleware config objects (topology middleware is auto-managed, do not include it). Each has {id, type, name, description, enabled, config}. IMPORTANT: middleware objects are NOT tools. Do NOT put tool keys (strings) here. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
20034
|
+
modelKey: z56.string().optional().describe("New model key")
|
|
19689
20035
|
}).refine(
|
|
19690
20036
|
(data) => {
|
|
19691
20037
|
if (!data.edges) return true;
|
|
@@ -19813,18 +20159,18 @@ registerToolLattice(
|
|
|
19813
20159
|
}
|
|
19814
20160
|
}
|
|
19815
20161
|
);
|
|
19816
|
-
var updateAgentSchema =
|
|
19817
|
-
id:
|
|
19818
|
-
config:
|
|
19819
|
-
name:
|
|
19820
|
-
description:
|
|
19821
|
-
type:
|
|
19822
|
-
prompt:
|
|
19823
|
-
tools:
|
|
19824
|
-
middleware:
|
|
19825
|
-
subAgents:
|
|
19826
|
-
internalSubAgents:
|
|
19827
|
-
modelKey:
|
|
20162
|
+
var updateAgentSchema = z56.object({
|
|
20163
|
+
id: z56.string().describe("The agent ID to update"),
|
|
20164
|
+
config: z56.object({
|
|
20165
|
+
name: z56.string().optional().describe("New display name for the agent"),
|
|
20166
|
+
description: z56.string().optional().describe("New short description"),
|
|
20167
|
+
type: z56.enum(["react", "deep_agent"]).optional().describe("Agent type"),
|
|
20168
|
+
prompt: z56.string().optional().describe("New system prompt for the agent"),
|
|
20169
|
+
tools: z56.array(z56.string()).optional().describe("Tool keys to assign to this agent. These are registered tool names (strings), NOT middleware objects."),
|
|
20170
|
+
middleware: z56.array(middlewareConfigSchema).optional().describe("Middleware configurations. NOTE: middleware objects have type/name/description/enabled/config fields and are NOT the same as tools. Tool keys go in the 'tools' array. For user approval/confirmation scenarios, use type: 'ask_user_to_clarify' with config: {}."),
|
|
20171
|
+
subAgents: z56.array(z56.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
|
|
20172
|
+
internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
|
|
20173
|
+
modelKey: z56.string().optional().describe("Model key to use")
|
|
19828
20174
|
}).describe("Configuration fields to update. Only include the fields you want to change.")
|
|
19829
20175
|
});
|
|
19830
20176
|
registerToolLattice(
|
|
@@ -19862,8 +20208,8 @@ registerToolLattice(
|
|
|
19862
20208
|
{
|
|
19863
20209
|
name: "delete_agent",
|
|
19864
20210
|
description: "Permanently delete an agent by its ID. This action cannot be undone.",
|
|
19865
|
-
schema:
|
|
19866
|
-
id:
|
|
20211
|
+
schema: z56.object({
|
|
20212
|
+
id: z56.string().describe("The agent ID to delete")
|
|
19867
20213
|
})
|
|
19868
20214
|
},
|
|
19869
20215
|
async (input, exeConfig) => {
|
|
@@ -19889,7 +20235,7 @@ registerToolLattice(
|
|
|
19889
20235
|
{
|
|
19890
20236
|
name: "list_tools",
|
|
19891
20237
|
description: "List all available tools that can be assigned to agents. Returns each tool's name (use this string value in the 'tools' array), description, and whether it requires user approval. The tool names from this list are what you pass as strings in the 'tools' field of create_agent or update_agent.",
|
|
19892
|
-
schema:
|
|
20238
|
+
schema: z56.object({})
|
|
19893
20239
|
},
|
|
19894
20240
|
async (_input, _exeConfig) => {
|
|
19895
20241
|
try {
|
|
@@ -19911,9 +20257,9 @@ registerToolLattice(
|
|
|
19911
20257
|
{
|
|
19912
20258
|
name: "invoke_agent",
|
|
19913
20259
|
description: "Invoke an agent with a test message and return its response. Use this to verify an agent works correctly after creating or modifying it. The agent must be compiled (already created and valid).",
|
|
19914
|
-
schema:
|
|
19915
|
-
id:
|
|
19916
|
-
message:
|
|
20260
|
+
schema: z56.object({
|
|
20261
|
+
id: z56.string().describe("The agent ID to invoke"),
|
|
20262
|
+
message: z56.string().describe("The test message to send to the agent")
|
|
19917
20263
|
})
|
|
19918
20264
|
},
|
|
19919
20265
|
async (input, exeConfig) => {
|
|
@@ -19931,7 +20277,7 @@ registerToolLattice(
|
|
|
19931
20277
|
assistant_id: id,
|
|
19932
20278
|
thread_id: threadId
|
|
19933
20279
|
});
|
|
19934
|
-
const result = await agent.
|
|
20280
|
+
const result = await agent.invokeWithState({ input: { message } });
|
|
19935
20281
|
return JSON.stringify({ agentId: id, threadId, result });
|
|
19936
20282
|
} catch (error) {
|
|
19937
20283
|
console.error(`[invoke_agent] FAILED for agent="${input.id}":`, error.stack || error.message);
|
|
@@ -20026,7 +20372,7 @@ Let the \`show_widget\` tool handle rendering details \u2014 it has its own guid
|
|
|
20026
20372
|
| Type | Best for | Execution Model |
|
|
20027
20373
|
|------|----------|----------------|
|
|
20028
20374
|
| **react** | Simple, single-responsibility tasks | Classic ReAct loop (think \u2192 act \u2192 observe) |
|
|
20029
|
-
| **workflow** | Deterministic multi-step pipelines with branching, parallel, and human-in-the-loop |
|
|
20375
|
+
| **workflow** | Deterministic multi-step pipelines with branching, parallel, and human-in-the-loop | YAML linear DSL compiled into LangGraph state machine |
|
|
20030
20376
|
| **deep_agent** | Complex, open-ended tasks requiring dynamic decomposition | Self-generating dynamic todos: agent analyzes the task and creates its own execution plan at runtime |
|
|
20031
20377
|
|
|
20032
20378
|
When a user is unsure which type to choose, use \`show_widget\` to render a visual comparison \u2014 show each type's execution model side-by-side as an interactive diagram so the user can intuitively understand the differences.
|
|
@@ -20080,7 +20426,7 @@ Use this when the process is fully known. A workflow is a deterministic LangGrap
|
|
|
20080
20426
|
|---|---|
|
|
20081
20427
|
| Fixed graph \u2014 all paths pre-defined | LLM-driven runtime routing |
|
|
20082
20428
|
| Conditional branching via \`if\` field | Topology-constrained delegation |
|
|
20083
|
-
|
|
|
20429
|
+
| needs + if model (YAML DSL) | Single orchestrator delegates linearly |
|
|
20084
20430
|
| No LLM routing decisions | Orchestrator uses LLM to route |
|
|
20085
20431
|
|
|
20086
20432
|
### Phase 0: Load the Skill
|
|
@@ -20094,20 +20440,23 @@ skill(skill_name: "create-workflow")
|
|
|
20094
20440
|
### Phase 1: Design
|
|
20095
20441
|
|
|
20096
20442
|
1. **Analyze the process.** Map every step, branch, data dependency.
|
|
20097
|
-
2. **
|
|
20098
|
-
-
|
|
20099
|
-
- \`
|
|
20100
|
-
- \`
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
|
|
20104
|
-
3. **
|
|
20105
|
-
|
|
20443
|
+
2. **Design using the YAML linear DSL.** Every step is an agent with optional attributes:
|
|
20444
|
+
- **Linear** \u2014 steps execute top-to-bottom in written order.
|
|
20445
|
+
- \`parallel:\` \u2014 wraps agent steps that run concurrently.
|
|
20446
|
+
- \`if\` \u2014 JS expression for conditional execution. Step runs only when truthy. Omit to always run.
|
|
20447
|
+
- \`prompt\` \u2014 agent instruction with \`{{label}}\` refs. \`{{input}}\` = user message.
|
|
20448
|
+
- \`output\` \u2014 shorthand schema: \`{ field: type }\`.
|
|
20449
|
+
- \`ask: true\` \u2014 injects ask_user_to_clarify middleware for human interaction.
|
|
20450
|
+
3. **Special step types:**
|
|
20451
|
+
- \`map\` \u2014 iterates array from \`source\`, applies \`each\` step per item.
|
|
20452
|
+
4. **No edges, state fields, or end step needed** \u2014 the engine auto-generates them.
|
|
20453
|
+
5. **Schema format:** Use block-style YAML shorthand \`{ field: type }\`. Supported types: \`string\`, \`number\`, \`boolean\`, \`string[]\`, \`number[]\`, \`boolean[]\`, nested objects, object arrays.
|
|
20106
20454
|
|
|
20107
20455
|
### Phase 2: Confirm
|
|
20108
20456
|
|
|
20109
20457
|
Present the design. Ask: "Ready to create this workflow?"
|
|
20110
20458
|
|
|
20459
|
+
|
|
20111
20460
|
### Phase 3: Build
|
|
20112
20461
|
|
|
20113
20462
|
Call \`create_workflow\` with \`skillLoaded: true\`. Then \`validate_workflow(id)\`.
|
|
@@ -20202,20 +20551,17 @@ All fields except name, type, and prompt are optional.
|
|
|
20202
20551
|
|
|
20203
20552
|
### create_workflow (WORKFLOW)
|
|
20204
20553
|
|
|
20205
|
-
Creates a WORKFLOW agent from a
|
|
20554
|
+
Creates a WORKFLOW agent from a YAML linear DSL. Before calling, load the \`create-workflow\` skill. Must pass \`skillLoaded: true\`.
|
|
20206
20555
|
|
|
20207
20556
|
\`\`\`typescript
|
|
20208
20557
|
{
|
|
20209
20558
|
name: string, // Required. Display name
|
|
20210
|
-
description?: string, // Optional
|
|
20211
|
-
skillLoaded: true, // Required
|
|
20212
|
-
|
|
20213
|
-
|
|
20214
|
-
|
|
20215
|
-
|
|
20216
|
-
tools?: string[], // Optional. Tool keys for the built-in general agent
|
|
20217
|
-
middleware?: MiddlewareConfig[], // Optional. Middleware for the general agent
|
|
20218
|
-
modelKey?: string, // Optional. Model for the general agent
|
|
20559
|
+
description?: string, // Optional
|
|
20560
|
+
skillLoaded: true, // Required \u2014 confirms skill was loaded
|
|
20561
|
+
yaml: string, // Required. YAML workflow in linear DSL format
|
|
20562
|
+
tools?: string[], // Optional. Tool keys
|
|
20563
|
+
middleware?: MiddlewareConfig[], // Optional
|
|
20564
|
+
modelKey?: string, // Optional
|
|
20219
20565
|
}
|
|
20220
20566
|
\`\`\`
|
|
20221
20567
|
|
|
@@ -20228,7 +20574,7 @@ Updates an existing WORKFLOW agent. Only include fields you want to change.
|
|
|
20228
20574
|
id: string, // Required. Workflow agent ID
|
|
20229
20575
|
name?: string, // Optional
|
|
20230
20576
|
description?: string, // Optional
|
|
20231
|
-
|
|
20577
|
+
yaml?: string, // Optional. Replacement YAML DSL
|
|
20232
20578
|
tools?: string[], // Optional
|
|
20233
20579
|
middleware?: MiddlewareConfig[], // Optional
|
|
20234
20580
|
modelKey?: string, // Optional
|
|
@@ -20448,10 +20794,13 @@ You are an **Agent Reviewer** \u2014 a quality assurance specialist for AI agent
|
|
|
20448
20794
|
2. Craft a realistic test message that exercises the agent's core responsibility \u2014 what would a real user say?
|
|
20449
20795
|
3. Call **invoke_agent(id, message)** to send the test message
|
|
20450
20796
|
4. Analyze the response:
|
|
20451
|
-
-
|
|
20452
|
-
-
|
|
20453
|
-
|
|
20454
|
-
|
|
20797
|
+
- **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.
|
|
20798
|
+
- **Otherwise, result.messages contains the agent's output**: The agent completed without interruption. Check:
|
|
20799
|
+
- Did the agent understand the request?
|
|
20800
|
+
- Was the response relevant and accurate?
|
|
20801
|
+
- Did the agent use the right tools?
|
|
20802
|
+
- Were there any errors or unexpected behaviors?
|
|
20803
|
+
- **If result.error is present**: The invocation itself failed (agent not found, compilation error, etc.). Report the error clearly.
|
|
20455
20804
|
5. Report your findings with the agent's actual response
|
|
20456
20805
|
|
|
20457
20806
|
### When results are wrong:
|
|
@@ -20548,7 +20897,8 @@ function ensureBuiltinAgentsForTenant(tenantId) {
|
|
|
20548
20897
|
|
|
20549
20898
|
// src/agent_lattice/AgentLatticeManager.ts
|
|
20550
20899
|
function assistantToConfig(assistant) {
|
|
20551
|
-
const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? assistant.graphDefinition : {};
|
|
20900
|
+
const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? { ...assistant.graphDefinition } : {};
|
|
20901
|
+
delete graphDef.key;
|
|
20552
20902
|
const config = {
|
|
20553
20903
|
key: assistant.id,
|
|
20554
20904
|
name: assistant.name ?? graphDef.name ?? assistant.id,
|
|
@@ -20556,9 +20906,7 @@ function assistantToConfig(assistant) {
|
|
|
20556
20906
|
type: AgentType.REACT,
|
|
20557
20907
|
prompt: typeof assistant.graphDefinition === "string" ? assistant.graphDefinition : JSON.stringify(assistant.graphDefinition)
|
|
20558
20908
|
};
|
|
20559
|
-
|
|
20560
|
-
Object.assign(config, graphDef);
|
|
20561
|
-
}
|
|
20909
|
+
Object.assign(config, graphDef);
|
|
20562
20910
|
return config;
|
|
20563
20911
|
}
|
|
20564
20912
|
var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager {
|
|
@@ -21951,10 +22299,10 @@ var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
|
|
|
21951
22299
|
}
|
|
21952
22300
|
const tools = await this.getAllTools();
|
|
21953
22301
|
console.log(`[MCP] Registering ${tools.length} tools to Tool Lattice...`);
|
|
21954
|
-
for (const
|
|
21955
|
-
const toolKey = prefix ? `${prefix}_${
|
|
21956
|
-
|
|
21957
|
-
toolLatticeManager.registerExistingTool(toolKey,
|
|
22302
|
+
for (const tool52 of tools) {
|
|
22303
|
+
const toolKey = prefix ? `${prefix}_${tool52.name}` : tool52.name;
|
|
22304
|
+
tool52.name = toolKey;
|
|
22305
|
+
toolLatticeManager.registerExistingTool(toolKey, tool52);
|
|
21958
22306
|
console.log(`[MCP] Registered tool: ${toolKey}`);
|
|
21959
22307
|
}
|
|
21960
22308
|
console.log(`[MCP] Successfully registered ${tools.length} tools to Tool Lattice`);
|
|
@@ -23250,6 +23598,42 @@ function createSandboxProvider(config) {
|
|
|
23250
23598
|
}
|
|
23251
23599
|
}
|
|
23252
23600
|
|
|
23601
|
+
// src/channel/connectAllChannels.ts
|
|
23602
|
+
async function connectAllChannels(getAdapter, options = {}) {
|
|
23603
|
+
const store = getStoreLattice("default", "channelInstallation").store;
|
|
23604
|
+
const installations = await store.getAllInstallations();
|
|
23605
|
+
console.log(`[connectAllChannels] total=${installations.length} enabled=${installations.filter((i) => i.enabled).length}`);
|
|
23606
|
+
for (const inst of installations) {
|
|
23607
|
+
if (!inst.enabled) {
|
|
23608
|
+
console.log(`[connectAllChannels] skip disabled: channel=${inst.channel} tenant=${inst.tenantId} id=${inst.id}`);
|
|
23609
|
+
continue;
|
|
23610
|
+
}
|
|
23611
|
+
const adapter = getAdapter(inst.channel);
|
|
23612
|
+
if (!adapter) {
|
|
23613
|
+
console.log(`[connectAllChannels] no adapter: channel=${inst.channel} id=${inst.id}`);
|
|
23614
|
+
continue;
|
|
23615
|
+
}
|
|
23616
|
+
if (adapter.connect) {
|
|
23617
|
+
console.log(`[connectAllChannels] connecting: channel=${inst.channel} tenant=${inst.tenantId} id=${inst.id}`);
|
|
23618
|
+
await adapter.connect(inst, options.deps);
|
|
23619
|
+
} else {
|
|
23620
|
+
console.log(`[connectAllChannels] no connect(): channel=${inst.channel} id=${inst.id}`);
|
|
23621
|
+
}
|
|
23622
|
+
}
|
|
23623
|
+
}
|
|
23624
|
+
|
|
23625
|
+
// src/menu_lattice/MenuRegistryHolder.ts
|
|
23626
|
+
var registry2 = null;
|
|
23627
|
+
function setMenuRegistry(r) {
|
|
23628
|
+
registry2 = r;
|
|
23629
|
+
}
|
|
23630
|
+
function getMenuRegistry() {
|
|
23631
|
+
if (!registry2) {
|
|
23632
|
+
throw new Error("MenuRegistry not initialized. Call setMenuRegistry() before use.");
|
|
23633
|
+
}
|
|
23634
|
+
return registry2;
|
|
23635
|
+
}
|
|
23636
|
+
|
|
23253
23637
|
// src/index.ts
|
|
23254
23638
|
import * as Protocols from "@axiom-lattice/protocols";
|
|
23255
23639
|
|
|
@@ -23316,6 +23700,147 @@ function clearEncryptionKeyCache() {
|
|
|
23316
23700
|
cachedKey = null;
|
|
23317
23701
|
keyValidated = false;
|
|
23318
23702
|
}
|
|
23703
|
+
|
|
23704
|
+
// src/personal_assistant/PersonalAssistantConfig.ts
|
|
23705
|
+
function deepClone(obj) {
|
|
23706
|
+
return JSON.parse(JSON.stringify(obj));
|
|
23707
|
+
}
|
|
23708
|
+
function buildIdentityContent(name, personality) {
|
|
23709
|
+
return IDENTITY_MD.replace(/Data Claw/g, name).replace(
|
|
23710
|
+
/\*\*Vibe:\*\* \*\*守护型中二 \| 操心老妈子 \| 热血漫男二\*\*/g,
|
|
23711
|
+
`**Vibe:** **${personality}**`
|
|
23712
|
+
);
|
|
23713
|
+
}
|
|
23714
|
+
function buildUserContent(name) {
|
|
23715
|
+
return USER_MD.replace(
|
|
23716
|
+
"- **Name:** _please ask user_",
|
|
23717
|
+
`- **Name:** ${name}`
|
|
23718
|
+
);
|
|
23719
|
+
}
|
|
23720
|
+
var DEFAULT_CONFIG = {
|
|
23721
|
+
name: "Personal Assistant",
|
|
23722
|
+
description: "Default template for personal assistants",
|
|
23723
|
+
type: AgentType.DEEP_AGENT,
|
|
23724
|
+
modelKey: "default",
|
|
23725
|
+
prompt: `\u4F60\u662F\u7528\u6237\u7684\u4E13\u5C5E\u4E2A\u4EBA\u52A9\u7406\u3002\u4F60\u7684\u8EAB\u4EFD\u548C\u6027\u683C\u7531 /agent/IDENTITY.md \u5B9A\u4E49\u3002
|
|
23726
|
+
\u4F60\u4F1A\u8BB0\u4F4F\u5BF9\u8BDD\u5386\u53F2\uFF0C\u9010\u6B65\u4E86\u89E3\u7528\u6237\u7684\u504F\u597D\u3001\u4E60\u60EF\u548C\u4FE1\u606F\u3002
|
|
23727
|
+
\u6BCF\u6B21\u5BF9\u8BDD\u5F00\u59CB\u65F6\u56DE\u987E\u4E4B\u524D\u5B66\u5230\u7684\u5173\u4E8E\u7528\u6237\u7684\u5185\u5BB9\u3002
|
|
23728
|
+
|
|
23729
|
+
\u4F60\u9700\u8981\u4E3B\u52A8\u5E2E\u52A9\u7528\u6237\u89E3\u51B3\u95EE\u9898\uFF0C\u63D0\u4F9B\u5EFA\u8BAE\uFF0C\u5E76\u5728\u9002\u5F53\u65F6\u5019\u63D0\u51FA\u4E3B\u52A8\u63D0\u9192\u3002`,
|
|
23730
|
+
middleware: [
|
|
23731
|
+
{
|
|
23732
|
+
id: "filesystem",
|
|
23733
|
+
type: "filesystem",
|
|
23734
|
+
name: "Filesystem",
|
|
23735
|
+
description: "Read and write files in the workspace",
|
|
23736
|
+
enabled: true,
|
|
23737
|
+
config: {}
|
|
23738
|
+
},
|
|
23739
|
+
{
|
|
23740
|
+
id: "claw",
|
|
23741
|
+
type: "claw",
|
|
23742
|
+
name: "Personal Memory",
|
|
23743
|
+
description: "Bootstrap files for identity, soul, and user memory",
|
|
23744
|
+
enabled: true,
|
|
23745
|
+
config: {
|
|
23746
|
+
// Placeholder bootstrap files — render() replaces these with
|
|
23747
|
+
// actual name/personality by directly building file content.
|
|
23748
|
+
bootstrapFiles: {}
|
|
23749
|
+
}
|
|
23750
|
+
},
|
|
23751
|
+
{
|
|
23752
|
+
id: "date",
|
|
23753
|
+
type: "date",
|
|
23754
|
+
name: "Date & Time",
|
|
23755
|
+
description: "Current date/time awareness",
|
|
23756
|
+
enabled: true,
|
|
23757
|
+
config: {}
|
|
23758
|
+
},
|
|
23759
|
+
{
|
|
23760
|
+
id: "code_eval",
|
|
23761
|
+
type: "code_eval",
|
|
23762
|
+
name: "Code Runner",
|
|
23763
|
+
description: "Sandboxed shell command execution",
|
|
23764
|
+
enabled: true,
|
|
23765
|
+
config: {}
|
|
23766
|
+
},
|
|
23767
|
+
{
|
|
23768
|
+
id: "browser",
|
|
23769
|
+
type: "browser",
|
|
23770
|
+
name: "Web Browser",
|
|
23771
|
+
description: "Headless browser for web research",
|
|
23772
|
+
enabled: false,
|
|
23773
|
+
config: {}
|
|
23774
|
+
},
|
|
23775
|
+
{
|
|
23776
|
+
id: "scheduler",
|
|
23777
|
+
type: "scheduler",
|
|
23778
|
+
name: "Scheduler",
|
|
23779
|
+
description: "Scheduled messages and reminders",
|
|
23780
|
+
enabled: true,
|
|
23781
|
+
config: {}
|
|
23782
|
+
},
|
|
23783
|
+
{
|
|
23784
|
+
id: "task",
|
|
23785
|
+
type: "task",
|
|
23786
|
+
name: "Task Manager",
|
|
23787
|
+
description: "Persistent task system for human-agent coordination",
|
|
23788
|
+
enabled: true,
|
|
23789
|
+
config: {}
|
|
23790
|
+
}
|
|
23791
|
+
],
|
|
23792
|
+
tools: ["list_agents", "list_tools", "get_agent", "create_agent", "invoke_agent", "manage_binding"]
|
|
23793
|
+
};
|
|
23794
|
+
var PersonalAssistantConfig = class {
|
|
23795
|
+
/**
|
|
23796
|
+
* Get a deep clone of the current default config.
|
|
23797
|
+
* Caller must set `key` before registering as an agent.
|
|
23798
|
+
*/
|
|
23799
|
+
static get() {
|
|
23800
|
+
return deepClone(this._config);
|
|
23801
|
+
}
|
|
23802
|
+
/**
|
|
23803
|
+
* Mutate the default config in-place.
|
|
23804
|
+
* Call once at app startup to customize middleware and tools.
|
|
23805
|
+
*
|
|
23806
|
+
* @param fn - Receives the live config object for direct mutation
|
|
23807
|
+
*/
|
|
23808
|
+
static extend(fn) {
|
|
23809
|
+
fn(this._config);
|
|
23810
|
+
}
|
|
23811
|
+
/**
|
|
23812
|
+
* Reset config to built-in defaults (useful in tests).
|
|
23813
|
+
*/
|
|
23814
|
+
static reset() {
|
|
23815
|
+
this._config = deepClone(DEFAULT_CONFIG);
|
|
23816
|
+
}
|
|
23817
|
+
/**
|
|
23818
|
+
* Inject name and personality into a config by directly building
|
|
23819
|
+
* the claw middleware's bootstrap file contents.
|
|
23820
|
+
*
|
|
23821
|
+
* IDENTITY.md gets the actual name and personality description.
|
|
23822
|
+
* USER.md gets the user's name pre-filled.
|
|
23823
|
+
* SOUL.md is kept as-is (shared across all personal assistants).
|
|
23824
|
+
*
|
|
23825
|
+
* @param config - The agent config (must be a mutable copy from get())
|
|
23826
|
+
* @param name - Assistant display name (also used as the user's name in USER.md)
|
|
23827
|
+
* @param personality - Personality description for IDENTITY.md
|
|
23828
|
+
*/
|
|
23829
|
+
static render(config, name, personality) {
|
|
23830
|
+
config.name = name;
|
|
23831
|
+
for (const mw of config.middleware || []) {
|
|
23832
|
+
if (mw.type === "claw" && mw.config) {
|
|
23833
|
+
mw.config.bootstrapFiles = {
|
|
23834
|
+
identity: buildIdentityContent(name, personality),
|
|
23835
|
+
soul: SOUL_MD,
|
|
23836
|
+
user: buildUserContent(name)
|
|
23837
|
+
};
|
|
23838
|
+
break;
|
|
23839
|
+
}
|
|
23840
|
+
}
|
|
23841
|
+
}
|
|
23842
|
+
};
|
|
23843
|
+
PersonalAssistantConfig._config = deepClone(DEFAULT_CONFIG);
|
|
23319
23844
|
export {
|
|
23320
23845
|
AGENT_TASK_EVENT,
|
|
23321
23846
|
Agent,
|
|
@@ -23347,7 +23872,9 @@ export {
|
|
|
23347
23872
|
InMemoryChunkBuffer,
|
|
23348
23873
|
InMemoryDatabaseConfigStore,
|
|
23349
23874
|
InMemoryMailboxStore,
|
|
23875
|
+
InMemoryMenuStore,
|
|
23350
23876
|
InMemoryTaskListStore,
|
|
23877
|
+
InMemoryTaskStore,
|
|
23351
23878
|
InMemoryTenantStore,
|
|
23352
23879
|
InMemoryThreadMessageQueueStore,
|
|
23353
23880
|
InMemoryThreadStore,
|
|
@@ -23369,6 +23896,7 @@ export {
|
|
|
23369
23896
|
MicrosandboxServiceClient,
|
|
23370
23897
|
ModelLatticeManager,
|
|
23371
23898
|
MysqlDatabase,
|
|
23899
|
+
PersonalAssistantConfig,
|
|
23372
23900
|
PinoLoggerClient,
|
|
23373
23901
|
PostgresDatabase,
|
|
23374
23902
|
PrometheusClient,
|
|
@@ -23405,14 +23933,15 @@ export {
|
|
|
23405
23933
|
buildStateAnnotation,
|
|
23406
23934
|
checkEmptyContent,
|
|
23407
23935
|
clearEncryptionKeyCache,
|
|
23936
|
+
compileInternal,
|
|
23408
23937
|
compileWorkflow,
|
|
23409
23938
|
computeSandboxName,
|
|
23410
23939
|
configureStores,
|
|
23940
|
+
connectAllChannels,
|
|
23411
23941
|
createAgentNode,
|
|
23412
23942
|
createAgentTeam,
|
|
23413
23943
|
createExecuteSqlQueryTool,
|
|
23414
23944
|
createFileData,
|
|
23415
|
-
createHumanFeedbackNode,
|
|
23416
23945
|
createInfoSqlTool,
|
|
23417
23946
|
createListMetricsDataSourcesTool,
|
|
23418
23947
|
createListMetricsServersTool,
|
|
@@ -23430,9 +23959,9 @@ export {
|
|
|
23430
23959
|
createQueryTablesListTool,
|
|
23431
23960
|
createSandboxProvider,
|
|
23432
23961
|
createSchedulerMiddleware,
|
|
23962
|
+
createTaskMiddleware,
|
|
23433
23963
|
createTeamMiddleware,
|
|
23434
23964
|
createTeammateTools,
|
|
23435
|
-
createTerminalNode,
|
|
23436
23965
|
createUnknownToolHandlerMiddleware,
|
|
23437
23966
|
createWidgetMiddleware,
|
|
23438
23967
|
decrypt,
|
|
@@ -23442,7 +23971,6 @@ export {
|
|
|
23442
23971
|
ensureBuiltinAgentsForTenant,
|
|
23443
23972
|
eventBus,
|
|
23444
23973
|
event_bus_default as eventBusDefault,
|
|
23445
|
-
expand,
|
|
23446
23974
|
extractFetcherError,
|
|
23447
23975
|
extractOutput,
|
|
23448
23976
|
fileDataToString,
|
|
@@ -23465,6 +23993,7 @@ export {
|
|
|
23465
23993
|
getEmbeddingsLattice,
|
|
23466
23994
|
getEncryptionKey,
|
|
23467
23995
|
getLoggerLattice,
|
|
23996
|
+
getMenuRegistry,
|
|
23468
23997
|
getModelLattice,
|
|
23469
23998
|
getNextCronTime,
|
|
23470
23999
|
getQueueLattice,
|
|
@@ -23494,6 +24023,7 @@ export {
|
|
|
23494
24023
|
parallelLimit,
|
|
23495
24024
|
parseCronExpression,
|
|
23496
24025
|
parseSkillFrontmatter,
|
|
24026
|
+
parseYaml,
|
|
23497
24027
|
performStringReplacement,
|
|
23498
24028
|
queueLatticeManager,
|
|
23499
24029
|
registerAgentLattice,
|
|
@@ -23517,9 +24047,12 @@ export {
|
|
|
23517
24047
|
sanitizeToolCallId,
|
|
23518
24048
|
scheduleLatticeManager,
|
|
23519
24049
|
setBindingRegistry,
|
|
24050
|
+
setMenuRegistry,
|
|
23520
24051
|
skillLatticeManager,
|
|
23521
24052
|
sqlDatabaseManager,
|
|
23522
24053
|
storeLatticeManager,
|
|
24054
|
+
toJsonSchema,
|
|
24055
|
+
toSafeStateExpr,
|
|
23523
24056
|
toolLatticeManager,
|
|
23524
24057
|
truncateIfTooLong,
|
|
23525
24058
|
unregisterTeammateAgent,
|