@axiom-lattice/core 2.1.80 → 2.1.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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-FN4TRQK4.mjs";
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, tool51) {
436
+ registerExistingTool(key, tool52) {
434
437
  const config = {
435
- name: tool51.name,
436
- description: tool51.description,
437
- schema: tool51.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: tool51
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, tool51) => toolLatticeManager.registerExistingTool(key, tool51);
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) return 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: per_conversation (recommended) or fixed"),
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 (default: per_conversation). channelInstallationId is optional \u2014 auto-detected if only one installation exists for this channel.
2763
- - update: Update an existing binding. Required: channel, senderId. Optional: agentId, threadMode (default: per_conversation), senderDisplayName.
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 registry2 = getBindingRegistry();
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 registry2.create({
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 registry2.resolve({
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 registry2.update(existing.id, {
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 registry2.resolve({
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 registry2.delete(existing.id);
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 registry2.list({
2999
+ const bindings = await registry3.list({
2857
3000
  channel: input.channel,
2858
3001
  agentId: input.agentId,
2859
3002
  tenantId,
@@ -7318,353 +7461,233 @@ metadata:
7318
7461
  Then iterate based on what the user says.
7319
7462
  `,
7320
7463
  "create-workflow": `---
7321
- name: create-workflow
7322
- description: Design and build multi-step AI workflows using the concise Workflow DSL. Use whenever users want to orchestrate agents in a pipeline, build process automation with branching/parallel logic, design approval flows with human-in-the-loop, or process data in stages.
7323
- license: MIT
7324
- metadata:
7325
- category: meta
7326
- version: "3.0"
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
7464
+ name: create-workflow
7465
+ 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.
7466
+ license: MIT
7467
+ metadata:
7468
+ category: meta
7469
+ version: "5.0"
7470
+ ---
7336
7471
 
7337
- A step's \`id\` serves triple duty:
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
7472
+ # YAML Workflow Designer
7341
7473
 
7342
- If you omit \`id\`, a unique identifier is auto-generated (but you won't be able to reference the output).
7474
+ Use the linear YAML DSL \u2014 steps execute top-to-bottom. Use \`parallel:\` for concurrency. No dependency graph thinking required.
7343
7475
 
7344
- ## Step Types
7476
+ ## Core Model: Linear + Parallel
7345
7477
 
7346
- ### agent \u2014 a step for the workflow's built-in agent
7478
+ - **Linear** \u2014 steps execute in written order. No \`needs\`, no dependency declarations.
7479
+ - **parallel** \u2014 a block where all children run concurrently. Block completes when all children finish.
7480
+ - **if** \u2014 JS expression. Step runs only when truthy. Omit to always run.
7481
+ - **prompt** \u2014 agent instruction with **{{label}}** refs. **{{input}}** is the user message.
7482
+ - **output** \u2014 shorthand schema using **{ field: type }** notation.
7483
+ - **ask** \u2014 boolean. Injects user clarification middleware for human interaction.
7347
7484
 
7348
- \`\`\`json
7349
- { "id": "classify", "name": "Classify Intent", "prompt": "Classify the intent of: {{input}}", "schema": { "type": "object", "properties": { "intent": { "type": "string" } } } }
7350
- \`\`\`
7485
+ ## When to Use parallel vs map
7351
7486
 
7352
- | Field | Required | Description |
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.
7487
+ This is the most important design decision. **They are fundamentally different:**
7358
7488
 
7359
- **Schema Rules (MUST follow \u2014 shorthand is rejected):**
7360
- - Always wrap in \`{ "type": "object", "properties": { ... } }\`
7361
- - Each property must be \`{ "type": "string"|"number"|"boolean"|"array"|"object" }\`
7362
- - Arrays need \`"items"\`: \`{ "type": "array", "items": { "type": "string" } }\`
7363
- - \u274C \`{ "field": "string" }\` \u2014 REJECTED (no "type"/"properties" wrapper)
7364
- - \u274C \`{ "schema": { "intent": "string" } }\` \u2014 REJECTED (legacy shorthand)
7489
+ | | parallel | map |
7490
+ |---|---|---|
7491
+ | **Concern** | **Business parallelism** \u2014 reduce business processing time | **Data parallelism** \u2014 handle data volume |
7492
+ | **Tasks** | Each child does a **different** task | All items do the **same** task |
7493
+ | **Count** | Few (2-5), each hand-written | Dynamic, driven by source data |
7494
+ | **Input** | Independent prompts per child | Single \`each.prompt\` template, \`{{item}}\` for current element |
7495
+ | **if** | Per-child conditional | Whole block conditional |
7496
+ | **Example** | Legal review + Market analysis in parallel | Audit each line item in an invoice |
7365
7497
 
7366
- The agent's response is stored at \`state.<id>\` (or an auto-generated key if \`id\` is omitted).
7498
+ **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
7499
 
7368
- ### condition \u2014 branch on state
7500
+ ## Step Format
7369
7501
 
7370
- **Binary (then/else):**
7502
+ ### Agent Step
7371
7503
 
7372
- \`\`\`json
7373
- { "type": "condition", "if": "intent",
7374
- "then": { "id": "support", "name": "Handle Support", "prompt": "Handle support: {{input}}" },
7375
- "else": { "id": "sales", "name": "Handle Sales", "prompt": "Handle sales: {{input}}" }
7376
- }
7504
+ \`\`\`yaml
7505
+ - label:
7506
+ prompt: instruction with {{refs}}
7507
+ if: "expression"
7508
+ output: { field: type }
7509
+ ask: true
7377
7510
  \`\`\`
7378
7511
 
7379
- | Field | Required | Description |
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 |
7512
+ ### Parallel Block
7384
7513
 
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):**
7388
-
7389
- When branching on a discrete set of known values, use \`branches\` for cleaner multi-way routing:
7390
-
7391
- \`\`\`json
7392
- { "type": "condition", "if": "intent",
7393
- "branches": {
7394
- "support": { "id": "support", "prompt": "Handle support: {{input}}" },
7395
- "sales": { "id": "sales", "prompt": "Handle sales: {{input}}" },
7396
- "billing": { "id": "billing", "prompt": "Handle billing: {{input}}" },
7397
- "default": { "id": "fallback", "prompt": "Send to human: {{input}}" }
7398
- }
7399
- }
7514
+ \`\`\`yaml
7515
+ - parallel:
7516
+ - child1:
7517
+ prompt: ...
7518
+ if: "expression"
7519
+ - child2:
7520
+ prompt: ...
7400
7521
  \`\`\`
7401
7522
 
7402
- | Field | Required | Description |
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.
7523
+ Parallel children are agent steps only. No nested parallel or map inside parallel.
7409
7524
 
7410
- ### human \u2014 pause for human input
7525
+ ### Map Step
7411
7526
 
7412
- The human step invokes an agent with ask_user_to_clarify middleware. The agent is a **facilitator** \u2014 it presents information to the user and collects their response. The agent does NOT make decisions itself; it asks the user. The agent's structured output is stored under the step's \`id\`.
7413
-
7414
- \`\`\`json
7415
- { "id": "review", "type": "human",
7416
- "title": "Approval",
7417
- "prompt": "Present the following draft to the user for approval. Ask whether to approve or reject, and collect any comments.\\n\\nDraft:\\n{{draft}}",
7418
- "schema": { "type": "object", "properties": { "approved": { "type": "boolean" }, "comments": { "type": "string" } } }
7419
- }
7527
+ \`\`\`yaml
7528
+ - label:
7529
+ map:
7530
+ source: "extract.items"
7531
+ if: "extract.items.length > 0"
7532
+ each:
7533
+ prompt: Process {{item}}
7534
+ output: { result: string }
7535
+ batch: 50
7536
+ concurrency: 5
7420
7537
  \`\`\`
7421
7538
 
7422
- Access results with dot notation: \`{{review.approved}}\`, \`{{review.comments}}\`. Use \`schema\` to constrain the agent's output.
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.
7461
-
7462
- ### end \u2014 terminate the workflow
7539
+ ## Schema Shorthand
7463
7540
 
7464
- \`\`\`json
7465
- { "type": "end" }
7466
- \`\`\`
7541
+ Write **{ field: type }** instead of JSON Schema:
7467
7542
 
7468
- Always include at the end of the steps array. \`status\` defaults to "success".
7543
+ | Shorthand | Meaning |
7544
+ |-----------|---------|
7545
+ | **field: string** | string property |
7546
+ | **field: number** | number property |
7547
+ | **field: boolean** | boolean property |
7548
+ | **field: string[]** | array of strings |
7549
+ | **field: number[]** | array of numbers |
7550
+ | **field: [{ a: string, b: number }]** | array of objects |
7551
+ | **field: { sub: string }** | nested object |
7469
7552
 
7470
- **Number of terminal nodes:**
7553
+ Use **block style** (each field on its own line). Flow style \`{ field: "type" }\` with quoted values also works.
7471
7554
 
7472
- - **Every workflow MUST have at least one \`{ "type": "end" }\`** \u2014 without it, the graph hangs at the last node.
7473
- - **One is enough** even for complex workflows: all branches can converge to a single \`end\` node (parallel fan-in, condition branches rejoining, etc.).
7474
- - **Use multiple end nodes ONLY when different branches need different \`status\`** values \u2014 e.g., success path vs failure path:
7555
+ ## Template Syntax
7475
7556
 
7476
- \`\`\`json
7477
- { "type": "condition", "if": "score >= 60",
7478
- "then": { "type": "end", "status": "success" },
7479
- "else": { "type": "end", "status": "failed" }
7480
- }
7481
- \`\`\`
7557
+ | Syntax | Resolves to |
7558
+ |--------|------------|
7559
+ | \`{{input}}\` | Initial user message |
7560
+ | \`{{label}}\` | Full output of step |
7561
+ | \`{{label.field}}\` | Nested field access |
7562
+ | \`{{item}}\` | Current element in map iteration |
7482
7563
 
7483
- - If all outcomes share the same final status, use a single \`end\` node after the condition/parallel block \u2014 the engine automatically converges all paths to it.
7564
+ ## Design Patterns
7484
7565
 
7485
- ## Template Syntax
7566
+ ### Linear Pipeline
7486
7567
 
7487
- | Syntax | Resolves to | When to use |
7488
- |--------|------------|-------------|
7489
- | \`{{input}}\` | Initial user message | First step or any step needing the original question |
7490
- | \`{{id}}\` | Output of step with given id | Referencing any upstream step's result |
7491
- | \`{{item}}\` | Current element in map iteration | Inside map \`each.prompt\` |
7568
+ \`\`\`yaml
7569
+ steps:
7570
+ - extract:
7571
+ prompt: Extract data from {{input}}
7572
+ - transform:
7573
+ prompt: Transform {{extract}}
7574
+ - final:
7575
+ prompt: Combine raw {{extract}} with transformed {{transform}}
7576
+ \`\`\`
7492
7577
 
7493
- ## \u26A0\uFE0F CRITICAL: \`{{}}\` is ONLY for \`prompt\` fields
7578
+ ### Classify -> Route via Parallel + if
7494
7579
 
7495
- The template markers \`{{id}}\`, \`{{input}}\`, and \`{{item}}\` work **exclusively inside \`prompt\` strings**. All other string fields \u2014 including \`if\`, \`source\`, \`id\`, \`name\`, \`title\`, \`status\` \u2014 must use plain values without any \`{{}}\` wrapping.
7580
+ \`\`\`yaml
7581
+ steps:
7582
+ - classify:
7583
+ prompt: Classify intent from {{input}}
7584
+ output:
7585
+ intent: string
7586
+ urgency: number
7587
+ - parallel:
7588
+ - billing:
7589
+ if: "classify.intent == 'billing'"
7590
+ prompt: Handle billing: {{input}}
7591
+ ask: true
7592
+ - technical:
7593
+ if: "classify.intent == 'technical'"
7594
+ prompt: Handle technical: {{input}}
7595
+ - escalate:
7596
+ if: "classify.urgency >= 8"
7597
+ prompt: Urgent handling
7598
+ ask: true
7599
+ \`\`\`
7496
7600
 
7497
- **Common mistake the AI makes:**
7498
- \`\`\`json
7499
- // \u274C WRONG \u2014 {{}} does not belong in if:
7500
- { "type": "condition", "if": "{{intent}}", "then": {...}, "else": {...} }
7601
+ ### Parallel Processing
7501
7602
 
7502
- // \u2705 CORRECT \u2014 if is a plain expression:
7503
- { "type": "condition", "if": "intent", "then": {...}, "else": {...} }
7504
- \`\`\`
7603
+ \`\`\`yaml
7604
+ steps:
7605
+ - gather:
7606
+ prompt: Gather data from {{input}}
7607
+ - parallel:
7608
+ - legal:
7609
+ prompt: Legal analysis of {{gather}}
7610
+ output:
7611
+ risk: string
7612
+ compliant: boolean
7613
+ - market:
7614
+ prompt: Market analysis of {{gather}}
7615
+ output:
7616
+ opportunity: string
7617
+ score: number
7618
+ - report:
7619
+ prompt: |
7620
+ Synthesize findings:
7621
+ Legal: {{legal}}
7622
+ Market: {{market}}
7623
+ \`\`\`
7505
7624
 
7506
- ## What You NEVER Write
7625
+ ### Approval Flow with Human
7507
7626
 
7508
- The engine auto-generates these \u2014 do NOT include them in your DSL:
7627
+ \`\`\`yaml
7628
+ steps:
7629
+ - draft:
7630
+ prompt: Draft response to {{input}}
7631
+ - review:
7632
+ prompt: Present {{draft}} to user for approval
7633
+ output:
7634
+ approved: boolean
7635
+ comments: string
7636
+ ask: true
7637
+ - publish:
7638
+ if: "review.approved"
7639
+ prompt: Publish {{draft}}
7640
+ - revise:
7641
+ if: "!review.approved"
7642
+ prompt: Revise based on {{review.comments}}
7643
+ \`\`\`
7509
7644
 
7510
- - **state.fields** \u2014 auto-declared from every \`id\`
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.
7645
+ ### Map (Iteration)
7516
7646
 
7517
- ## Design Patterns
7647
+ \`\`\`yaml
7648
+ steps:
7649
+ - extract:
7650
+ prompt: Extract items from {{input}}
7651
+ output:
7652
+ items:
7653
+ - name: string
7654
+ - map_items:
7655
+ map:
7656
+ source: "extract.items"
7657
+ each:
7658
+ prompt: Audit {{item.name}}
7659
+ output:
7660
+ result: string
7661
+ - summary:
7662
+ prompt: Summarize findings: {{map_items}}
7663
+ \`\`\`
7518
7664
 
7519
- ### Pattern 1: Linear Pipeline
7665
+ ## Keep Business Logic in Agents
7520
7666
 
7521
- \`\`\`json
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
- \`\`\`
7667
+ 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
7668
 
7532
- ### Pattern 2: Classify then Route
7669
+ **Rule:** if you have more if conditions than workflow phases, move logic into richer agent prompts.
7533
7670
 
7534
- \`\`\`json
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
- \`\`\`
7671
+ ## What You NEVER Write
7547
7672
 
7548
- ### Pattern 2b: Classify then Switch
7673
+ - **needs** \u2014 not supported. Steps execute linearly. Use parallel for concurrency.
7674
+ - **edges** \u2014 auto-generated from step order and parallel structure
7675
+ - **nested parallel** \u2014 parallel children are flat agent steps only
7676
+ - **map inside parallel** \u2014 map is a top-level step only
7677
+ - **json schema** \u2014 use **{ field: type }** block style
7678
+ - do not use {{}} markers in if expressions
7679
+ - **workflow-level business logic** \u2014 decisions belong inside agent prompts
7549
7680
 
7550
- For routing to 3+ categories, use \`branches\` instead of nested \`then\`/\`else\`:
7681
+ ## Checklist
7551
7682
 
7552
- \`\`\`json
7553
- {
7554
- "name": "ticket-router",
7555
- "steps": [
7556
- { "id": "intent", "name": "Classify", "prompt": "Classify: {{input}}", "schema": { "type": "object", "properties": { "category": { "type": "string" } } } },
7557
- { "type": "condition", "if": "intent.category",
7558
- "branches": {
7559
- "support": { "id": "support", "prompt": "Handle support: {{input}}" },
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
- `
7683
+ - Every step has a unique label
7684
+ - Steps execute top-to-bottom \u2014 no dependency thinking needed
7685
+ - \`{{label}}\` can reference ANY upstream step output
7686
+ - if uses plain JS, no {{}}
7687
+ - Schema uses block style shorthand
7688
+ - parallel children are flat agent steps
7689
+ - Business logic stays inside agent prompts
7690
+ - ask: true for human interaction`
7668
7691
  };
7669
7692
  function getBuiltInSkillMeta(name) {
7670
7693
  const content = BUILTIN_SKILLS[name];
@@ -10575,7 +10598,7 @@ ${currentSystemPrompt}` : dateContext;
10575
10598
  // src/deep_agent_new/middleware/scheduler.ts
10576
10599
  import { tool as tool45, createMiddleware as createMiddleware13 } from "langchain";
10577
10600
  import { z as z48 } from "zod";
10578
- import { v4 as uuidv4 } from "uuid";
10601
+ import { v4 as uuidv42 } from "uuid";
10579
10602
  import { ScheduledTaskStatus as ScheduledTaskStatus3, ScheduleExecutionType as ScheduleExecutionType3 } from "@axiom-lattice/protocols";
10580
10603
 
10581
10604
  // src/schedule_lattice/ScheduleLatticeManager.ts
@@ -12220,7 +12243,6 @@ var Agent = class {
12220
12243
  const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
12221
12244
  const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
12222
12245
  const { messages, ...rest } = input;
12223
- const lifecycleManager = this;
12224
12246
  const runConfig = {
12225
12247
  thread_id: this.thread_id,
12226
12248
  "x-tenant-id": this.tenant_id,
@@ -12272,43 +12294,13 @@ var Agent = class {
12272
12294
  }
12273
12295
  );
12274
12296
  try {
12275
- for await (const chunk of agentStream) {
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
- }
12297
+ await this.consumeAgentStream(agentStream, signal);
12305
12298
  } catch (error) {
12306
12299
  console.error("Stream error:", error);
12307
- await lifecycleManager.chunkBuffer.abortThread(lifecycleManager.thread_id);
12308
12300
  throw error;
12309
12301
  }
12310
12302
  } catch (error) {
12311
- await this.chunkBuffer.abortThread(lifecycleManager.thread_id);
12303
+ await this.chunkBuffer.abortThread(this.thread_id);
12312
12304
  throw error;
12313
12305
  }
12314
12306
  };
@@ -12589,8 +12581,8 @@ var Agent = class {
12589
12581
  this.assistant_id = assistant_id;
12590
12582
  this.thread_id = thread_id;
12591
12583
  this.tenant_id = tenant_id;
12592
- this.workspace_id = workspace_id;
12593
- this.project_id = project_id;
12584
+ this.workspace_id = workspace_id || "default";
12585
+ this.project_id = project_id || "default";
12594
12586
  this.custom_run_config = custom_run_config;
12595
12587
  }
12596
12588
  getHumanPendingContent(message) {
@@ -12684,10 +12676,132 @@ var Agent = class {
12684
12676
  const inputMessage = { ...queueMessage, input };
12685
12677
  return this.agentExecutor(inputMessage, signal);
12686
12678
  }
12679
+ /**
12680
+ * Like {@link invoke} but returns the full LangGraph state (all annotations)
12681
+ * instead of only messages. Messages are serialized to dicts; other state
12682
+ * fields are returned as-is.
12683
+ *
12684
+ * @remarks
12685
+ * Only call this when you need the full state. Existing callers (gateway,
12686
+ * workflows) should keep using {@link invoke} which returns only messages
12687
+ * to avoid exposing internal annotation data.
12688
+ */
12689
+ async invokeWithState(queueMessage, signal) {
12690
+ const messageId = v4();
12691
+ const input = {
12692
+ ...queueMessage.input,
12693
+ messages: [new HumanMessage({ id: messageId, content: queueMessage.input.message })]
12694
+ };
12695
+ const inputMessage = { ...queueMessage, input };
12696
+ const { runnable_agent, runConfig } = await this.getLatticeClientAndRuntimeConfig(inputMessage.custom_run_config);
12697
+ const { messages, ...rest } = inputMessage.input;
12698
+ if (signal?.aborted) {
12699
+ throw new Error("Agent execution was aborted");
12700
+ }
12701
+ let result;
12702
+ result = await runnable_agent.invoke(
12703
+ inputMessage.command ? new Command2(inputMessage.command) : { ...rest, messages, "x-tenant-id": this.tenant_id },
12704
+ {
12705
+ context: { runConfig },
12706
+ configurable: {
12707
+ run_id: v4(),
12708
+ ...runConfig,
12709
+ runConfig
12710
+ },
12711
+ recursionLimit: 200,
12712
+ signal
12713
+ }
12714
+ );
12715
+ if (signal?.aborted) {
12716
+ throw new Error("Agent execution was aborted");
12717
+ }
12718
+ const { messages: _rawMessages, ...restState } = result;
12719
+ const serializedMessages = result.messages.map((message) => {
12720
+ const { type, data } = message.toDict();
12721
+ return { ...data, role: type };
12722
+ });
12723
+ return { messages: serializedMessages, ...restState };
12724
+ }
12687
12725
  async getPendingMessages() {
12688
12726
  const store = this.getQueueStore();
12689
12727
  return await store.getPendingMessages(this.thread_id);
12690
12728
  }
12729
+ async consumeAgentStream(agentStream, signal) {
12730
+ for await (const chunk of agentStream) {
12731
+ if (signal?.aborted) {
12732
+ await this.chunkBuffer.abortThread(this.thread_id);
12733
+ throw new Error("Agent execution was aborted");
12734
+ }
12735
+ let data;
12736
+ if (chunk[0] === "updates") {
12737
+ const update = chunk[1];
12738
+ const values = Object.values(update);
12739
+ const messages = values[0]?.messages;
12740
+ if (messages?.[0]?.tool_call_id) {
12741
+ data = messages[0].toDict();
12742
+ }
12743
+ } else if (chunk[0] === "messages") {
12744
+ const messages = chunk[1];
12745
+ data = messages?.[0]?.toDict();
12746
+ }
12747
+ if (chunk?.[1]?.__interrupt__) {
12748
+ const interruptData = chunk?.[1]?.__interrupt__[0];
12749
+ data = {
12750
+ type: "interrupt",
12751
+ id: interruptData.id,
12752
+ data: { content: interruptData.value }
12753
+ };
12754
+ }
12755
+ if (data) {
12756
+ this.addChunk(data);
12757
+ }
12758
+ }
12759
+ }
12760
+ /**
12761
+ * Resume LangGraph execution from the last checkpoint.
12762
+ *
12763
+ * Streams with `null` input — this tells LangGraph to continue from
12764
+ * wherever it left off using the checkpointed state for this thread.
12765
+ * All output chunks are buffered via {@link addChunk}.
12766
+ */
12767
+ async resumeGraphFromCheckpoint(signal) {
12768
+ const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
12769
+ const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
12770
+ if (!runnable_agent) {
12771
+ throw new Error(`Agent ${this.assistant_id} not found`);
12772
+ }
12773
+ const runConfig = {
12774
+ thread_id: this.thread_id,
12775
+ "x-tenant-id": this.tenant_id,
12776
+ "x-workspace-id": this.workspace_id,
12777
+ "x-project-id": this.project_id,
12778
+ "x-thread-id": this.thread_id,
12779
+ "x-assistant-id": this.assistant_id,
12780
+ ...agentLattice?.config?.runConfig || {},
12781
+ tenantId: this.tenant_id,
12782
+ workspaceId: this.workspace_id,
12783
+ projectId: this.project_id,
12784
+ ...this.custom_run_config || {},
12785
+ assistant_id: this.assistant_id
12786
+ };
12787
+ const agentStream = await runnable_agent.stream(
12788
+ null,
12789
+ {
12790
+ context: {
12791
+ runConfig
12792
+ },
12793
+ configurable: {
12794
+ ...runConfig,
12795
+ runConfig
12796
+ },
12797
+ streamMode: ["updates", "messages"],
12798
+ subgraphs: false,
12799
+ recursionLimit: 200,
12800
+ signal
12801
+ }
12802
+ );
12803
+ await this.consumeAgentStream(agentStream, signal);
12804
+ }
12691
12805
  getQueueStore() {
12692
12806
  if (!this.queueStore) {
12693
12807
  try {
@@ -12817,6 +12931,8 @@ var Agent = class {
12817
12931
  threadId: this.thread_id,
12818
12932
  tenantId: this.tenant_id,
12819
12933
  assistantId: this.assistant_id,
12934
+ workspaceId: this.workspace_id,
12935
+ projectId: this.project_id,
12820
12936
  content,
12821
12937
  type: pendingType,
12822
12938
  command: queueMessage.command,
@@ -12833,6 +12949,8 @@ var Agent = class {
12833
12949
  threadId: this.thread_id,
12834
12950
  tenantId: this.tenant_id,
12835
12951
  assistantId: this.assistant_id,
12952
+ workspaceId: this.workspace_id,
12953
+ projectId: this.project_id,
12836
12954
  content,
12837
12955
  type: pendingType,
12838
12956
  command: queueMessage.command,
@@ -12906,6 +13024,8 @@ var Agent = class {
12906
13024
  threadId: thread.threadId,
12907
13025
  tenantId: thread.tenantId,
12908
13026
  assistantId: thread.assistantId,
13027
+ workspaceId: this.workspace_id,
13028
+ projectId: this.project_id,
12909
13029
  content: reminderContent,
12910
13030
  type: "system"
12911
13031
  });
@@ -12977,9 +13097,14 @@ var Agent = class {
12977
13097
  /**
12978
13098
  * Resume processing after a server restart.
12979
13099
  *
12980
- * Resets any stuck "processing" messages back to "pending" and restarts the
12981
- * queue processor. Skips threads that are in `INTERRUPTED` state (the
12982
- * interruption was intentional).
13100
+ * If the graph was mid-execution (BUSY) it resumes from the LangGraph
13101
+ * checkpoint without re-injecting the message the message has already
13102
+ * been consumed and is in the graph state. Processing messages are removed
13103
+ * rather than replayed.
13104
+ *
13105
+ * Skips threads that are in `INTERRUPTED` state (the interruption was
13106
+ * intentional). IDLE threads simply clean up and restart the queue
13107
+ * processor for any remaining pending messages.
12983
13108
  *
12984
13109
  * Called during gateway startup to recover threads that were mid-execution
12985
13110
  * when the server went down.
@@ -12997,9 +13122,32 @@ var Agent = class {
12997
13122
  return;
12998
13123
  }
12999
13124
  const store = this.getQueueStore();
13000
- const resetCount = await store.resetProcessingToPending(this.thread_id);
13001
- if (resetCount > 0) {
13002
- console.log(`[Agent] Reset ${resetCount} processing messages to pending for thread ${this.thread_id}`);
13125
+ if (runStatus === "busy" /* BUSY */) {
13126
+ this.abortController = new AbortController();
13127
+ try {
13128
+ await this.resumeGraphFromCheckpoint(this.abortController.signal);
13129
+ const processingMessages = await store.getProcessingMessages(this.thread_id);
13130
+ for (const msg of processingMessages) {
13131
+ await store.removeMessage(msg.id);
13132
+ }
13133
+ if (processingMessages.length > 0) {
13134
+ console.log(`[Agent] Removed ${processingMessages.length} processing messages for thread ${this.thread_id}`);
13135
+ }
13136
+ } catch (error) {
13137
+ console.error(`[Agent] Failed to resume graph for thread ${this.thread_id}:`, error);
13138
+ await this.chunkBuffer.abortThread(this.thread_id);
13139
+ throw error;
13140
+ } finally {
13141
+ this.abortController = null;
13142
+ }
13143
+ } else {
13144
+ const processingMessages = await store.getProcessingMessages(this.thread_id);
13145
+ for (const msg of processingMessages) {
13146
+ await store.removeMessage(msg.id);
13147
+ }
13148
+ if (processingMessages.length > 0) {
13149
+ console.log(`[Agent] Removed ${processingMessages.length} processing messages for thread ${this.thread_id}`);
13150
+ }
13003
13151
  }
13004
13152
  await this.startQueueProcessorIfNeeded();
13005
13153
  }
@@ -13190,7 +13338,7 @@ var AgentInstanceManager = class _AgentInstanceManager {
13190
13338
  console.log(`[AgentInstanceManager] Found ${threadsWithPending.length} threads with pending messages, restoring...`);
13191
13339
  for (const threadInfo of threadsWithPending) {
13192
13340
  try {
13193
- await this.restoreThread(threadInfo, queueStore);
13341
+ await this.restoreThread(threadInfo);
13194
13342
  stats.restored++;
13195
13343
  } catch (error) {
13196
13344
  console.error(`[AgentInstanceManager] Failed to restore thread ${threadInfo.threadId}:`, error);
@@ -13208,16 +13356,14 @@ var AgentInstanceManager = class _AgentInstanceManager {
13208
13356
  * Restore a single thread
13209
13357
  * Delegates actual recovery logic to Agent.resumeTask()
13210
13358
  */
13211
- async restoreThread(threadInfo, queueStore) {
13212
- const { tenantId, assistantId, threadId } = threadInfo;
13359
+ async restoreThread(threadInfo) {
13360
+ const { tenantId, assistantId, threadId, workspaceId, projectId } = threadInfo;
13213
13361
  const threadParams = {
13214
13362
  tenant_id: tenantId,
13215
13363
  assistant_id: assistantId,
13216
13364
  thread_id: threadId,
13217
- workspace_id: "default",
13218
- // TODO: Get from thread store
13219
- project_id: "default"
13220
- // TODO: Get from thread store
13365
+ workspace_id: workspaceId,
13366
+ project_id: projectId
13221
13367
  };
13222
13368
  const agent = this.getAgent(threadParams);
13223
13369
  await agent.resumeTask();
@@ -13308,7 +13454,7 @@ function createSchedulerMiddleware(options = {}) {
13308
13454
  async (input, config) => {
13309
13455
  const runConfig = getRunConfig(config);
13310
13456
  const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
13311
- const taskId = uuidv4();
13457
+ const taskId = uuidv42();
13312
13458
  const executeAt = input.executeAt;
13313
13459
  const success = await scheduleLattice.client.scheduleOnce(
13314
13460
  taskId,
@@ -13343,7 +13489,7 @@ function createSchedulerMiddleware(options = {}) {
13343
13489
  async (input, config) => {
13344
13490
  const runConfig = getRunConfig(config);
13345
13491
  const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
13346
- const taskId = uuidv4();
13492
+ const taskId = uuidv42();
13347
13493
  const executeAt = Date.now() + input.delayMs;
13348
13494
  const success = await scheduleLattice.client.scheduleOnce(
13349
13495
  taskId,
@@ -13378,7 +13524,7 @@ function createSchedulerMiddleware(options = {}) {
13378
13524
  async (input, config) => {
13379
13525
  const runConfig = getRunConfig(config);
13380
13526
  const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
13381
- const taskId = uuidv4();
13527
+ const taskId = uuidv42();
13382
13528
  const success = await scheduleLattice.client.scheduleCron(
13383
13529
  taskId,
13384
13530
  AGENT_ADD_MESSAGE_TASK_TYPE,
@@ -13466,6 +13612,138 @@ function createSchedulerMiddleware(options = {}) {
13466
13612
  });
13467
13613
  }
13468
13614
 
13615
+ // src/middlewares/taskMiddleware.ts
13616
+ import { createMiddleware as createMiddleware14, tool as tool46 } from "langchain";
13617
+ import { z as z49 } from "zod";
13618
+ function getRunConfig2(config) {
13619
+ const c = config;
13620
+ return c?.configurable?.runConfig ?? {};
13621
+ }
13622
+ function getTaskStore() {
13623
+ return getStoreLattice("default", "task").store;
13624
+ }
13625
+ var manageTaskSchema = z49.object({
13626
+ action: z49.enum(["create", "list", "update", "delete", "complete"]).describe("\u64CD\u4F5C\u7C7B\u578B"),
13627
+ id: z49.string().optional().describe("\u4EFB\u52A1 ID (update/delete/complete \u5FC5\u586B)"),
13628
+ title: z49.string().optional().describe("\u4EFB\u52A1\u6807\u9898 (create \u5FC5\u586B)"),
13629
+ description: z49.string().optional().describe("\u4EFB\u52A1\u63CF\u8FF0"),
13630
+ priority: z49.enum(["low", "medium", "high"]).optional().describe("\u4F18\u5148\u7EA7"),
13631
+ status: z49.enum(["pending", "in_progress", "completed", "cancelled"]).optional().describe("\u72B6\u6001"),
13632
+ dueDate: z49.string().optional().describe("\u622A\u6B62\u65E5\u671F (ISO 8601)"),
13633
+ metadata: z49.record(z49.unknown()).optional().describe("\u7ED3\u6784\u5316\u5143\u6570\u636E (projectId, module \u7B49)"),
13634
+ parentId: z49.string().optional().describe("\u7236\u4EFB\u52A1 ID (\u5B50\u4EFB\u52A1\u5173\u8054)"),
13635
+ sourceId: z49.string().optional().describe("\u6765\u6E90\u4F1A\u8BDD/thread ID"),
13636
+ context: z49.record(z49.unknown()).optional().describe("\u9644\u52A0\u4E0A\u4E0B\u6587"),
13637
+ ownerType: z49.enum(["user", "agent"]).optional().describe("\u6240\u6709\u8005\u7C7B\u578B\uFF0C\u4E0D\u4F20\u9ED8\u8BA4\u4E3A user"),
13638
+ ownerId: z49.string().optional().describe("\u6240\u6709\u8005 ID\uFF0C\u4E0D\u4F20\u81EA\u52A8\u53D6\u5F53\u524D\u7528\u6237/Agent")
13639
+ });
13640
+ function createTaskMiddleware() {
13641
+ return createMiddleware14({
13642
+ name: "TaskMiddleware",
13643
+ contextSchema,
13644
+ wrapModelCall: async (request, handler) => {
13645
+ const taskPrompt = `## \u4EFB\u52A1\u7BA1\u7406\u80FD\u529B
13646
+ \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
13647
+ - \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)
13648
+ - ownerType="agent": \u4E3A\u81EA\u5DF1\u521B\u5EFA\u6267\u884C\u5B50\u4EFB\u52A1 (ownerId \u81EA\u52A8\u53D6\u5F53\u524D Agent)
13649
+ - \u663E\u5F0F\u4F20 ownerId: \u4E3A\u6307\u5B9A agent/user \u521B\u5EFA\u4EFB\u52A1\uFF08\u62D3\u6251\u573A\u666F\uFF09`;
13650
+ return handler({
13651
+ ...request,
13652
+ systemPrompt: taskPrompt + "\n\n" + (request.systemPrompt ?? "")
13653
+ });
13654
+ },
13655
+ tools: [
13656
+ tool46(
13657
+ async (input, config) => {
13658
+ const rc = getRunConfig2(config);
13659
+ const tenantId = rc.tenantId || "default";
13660
+ const ownerId = input.ownerId || (input.ownerType === "agent" ? rc.assistant_id : null) || rc.user_id;
13661
+ const store = getTaskStore();
13662
+ switch (input.action) {
13663
+ case "create": {
13664
+ if (!input.title) {
13665
+ return JSON.stringify({ success: false, error: "create requires title" });
13666
+ }
13667
+ const task = await store.create({
13668
+ tenantId,
13669
+ ownerType: input.ownerType || "user",
13670
+ ownerId,
13671
+ title: input.title,
13672
+ description: input.description,
13673
+ priority: input.priority || "medium",
13674
+ status: input.status || "pending",
13675
+ dueDate: input.dueDate,
13676
+ metadata: input.metadata,
13677
+ parentId: input.parentId,
13678
+ sourceId: input.sourceId,
13679
+ context: input.context
13680
+ });
13681
+ return JSON.stringify({ success: true, data: task });
13682
+ }
13683
+ case "list": {
13684
+ const tasks = await store.list({
13685
+ tenantId,
13686
+ ownerType: input.ownerType,
13687
+ ownerId: input.ownerId,
13688
+ status: input.status,
13689
+ priority: input.priority
13690
+ });
13691
+ return JSON.stringify({ success: true, data: tasks, count: tasks.length });
13692
+ }
13693
+ case "update": {
13694
+ if (!input.id) {
13695
+ return JSON.stringify({ success: false, error: "update requires id" });
13696
+ }
13697
+ const { action, ...updates } = input;
13698
+ const updated = await store.update(tenantId, input.id, updates);
13699
+ if (!updated) {
13700
+ return JSON.stringify({ success: false, error: "Task not found" });
13701
+ }
13702
+ return JSON.stringify({ success: true, data: updated });
13703
+ }
13704
+ case "delete": {
13705
+ if (!input.id) {
13706
+ return JSON.stringify({ success: false, error: "delete requires id" });
13707
+ }
13708
+ const deleted = await store.delete(tenantId, input.id);
13709
+ return JSON.stringify({ success: deleted, message: deleted ? "Task deleted" : "Task not found" });
13710
+ }
13711
+ case "complete": {
13712
+ if (!input.id) {
13713
+ return JSON.stringify({ success: false, error: "complete requires id" });
13714
+ }
13715
+ const updated = await store.update(tenantId, input.id, { status: "completed" });
13716
+ if (!updated) {
13717
+ return JSON.stringify({ success: false, error: "Task not found" });
13718
+ }
13719
+ return JSON.stringify({ success: true, data: updated });
13720
+ }
13721
+ default:
13722
+ return JSON.stringify({ success: false, error: `Unknown action: ${input.action}` });
13723
+ }
13724
+ },
13725
+ {
13726
+ name: "manage_task",
13727
+ description: `\u7BA1\u7406\u6301\u4E45\u5316\u4EFB\u52A1\u7CFB\u7EDF\u3002CRUD \u64CD\u4F5C\u7528\u6237\u548C Agent \u7684\u4EFB\u52A1\u3002
13728
+
13729
+ ## ownerType \u548C ownerId \u7684\u9ED8\u8BA4\u903B\u8F91
13730
+ - \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)
13731
+ - \u4F20 ownerType="agent" \u4E0D\u4F20 ownerId: \u7CFB\u7EDF\u81EA\u52A8\u4E3A\u5F53\u524D Agent \u521B\u5EFA\u5B50\u4EFB\u52A1
13732
+ - \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
13733
+
13734
+ ## Actions
13735
+ - create: \u521B\u5EFA\u4EFB\u52A1 (title \u5FC5\u586B, priority/description/dueDate/metadata/parentId/context \u53EF\u9009)
13736
+ - list: \u5217\u51FA\u4EFB\u52A1\uFF0C\u53EF\u6309 ownerType/status/priority \u8FC7\u6EE4
13737
+ - update: \u66F4\u65B0\u4EFB\u52A1 (id \u5FC5\u586B\uFF0C\u53EA\u4F20\u8981\u6539\u7684\u5B57\u6BB5)
13738
+ - delete: \u5220\u9664\u4EFB\u52A1 (id \u5FC5\u586B)
13739
+ - complete: \u5FEB\u901F\u6807\u8BB0\u5B8C\u6210 (id \u5FC5\u586B)`,
13740
+ schema: manageTaskSchema
13741
+ }
13742
+ )
13743
+ ]
13744
+ });
13745
+ }
13746
+
13469
13747
  // src/agent_lattice/builders/CustomMiddlewareRegistry.ts
13470
13748
  var CustomMiddlewareRegistry = class {
13471
13749
  /**
@@ -13601,6 +13879,9 @@ async function createCommonMiddlewares(middlewareConfigs, filesystemBackend, fsI
13601
13879
  case "scheduler":
13602
13880
  middlewares.push(createSchedulerMiddleware(config.config));
13603
13881
  break;
13882
+ case "task":
13883
+ middlewares.push(createTaskMiddleware());
13884
+ break;
13604
13885
  case "custom":
13605
13886
  {
13606
13887
  const customConfig = config.config;
@@ -13808,9 +14089,9 @@ var ReActAgentGraphBuilder = class {
13808
14089
  */
13809
14090
  async build(agentLattice, params) {
13810
14091
  const tools = params.tools.map((t) => {
13811
- const tool51 = getToolClient(t.key);
13812
- return tool51;
13813
- }).filter((tool51) => tool51 !== void 0);
14092
+ const tool52 = getToolClient(t.key);
14093
+ return tool52;
14094
+ }).filter((tool52) => tool52 !== void 0);
13814
14095
  const stateSchema2 = createReactAgentSchema(params.stateSchema);
13815
14096
  const middlewareConfigs = params.middleware || [];
13816
14097
  const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
@@ -13837,11 +14118,11 @@ import {
13837
14118
  } from "langchain";
13838
14119
 
13839
14120
  // src/deep_agent_new/middleware/subagents.ts
13840
- import { z as z49 } from "zod/v3";
14121
+ import { z as z50 } from "zod/v3";
13841
14122
  import {
13842
- createMiddleware as createMiddleware14,
14123
+ createMiddleware as createMiddleware15,
13843
14124
  createAgent as createAgent2,
13844
- tool as tool46,
14125
+ tool as tool47,
13845
14126
  ToolMessage as ToolMessage4,
13846
14127
  humanInTheLoopMiddleware
13847
14128
  } from "langchain";
@@ -14274,7 +14555,7 @@ function createTaskTool(options) {
14274
14555
  generalPurposeAgent
14275
14556
  });
14276
14557
  const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
14277
- return tool46(
14558
+ return tool47(
14278
14559
  async (input, config) => {
14279
14560
  const { description, subagent_type, async } = input;
14280
14561
  let assistant_id = subagent_type;
@@ -14308,12 +14589,16 @@ function createTaskTool(options) {
14308
14589
  const subagent_thread_id = config.configurable?.thread_id + "____" + assistant_id + "_" + config.toolCall.id;
14309
14590
  if (async) {
14310
14591
  const tenantId = config.configurable?.runConfig?.tenantId;
14592
+ const workspaceId = config.configurable?.runConfig?.workspaceId;
14593
+ const projectId = config.configurable?.runConfig?.projectId;
14311
14594
  const mainAssistantId = config.configurable?.runConfig?.assistant_id;
14312
14595
  const mainThreadId = config.configurable?.runConfig?.thread_id;
14313
14596
  const mainRuntimeAgent = agentInstanceManager.getAgent({
14314
14597
  assistant_id: mainAssistantId,
14315
14598
  thread_id: mainThreadId,
14316
- tenant_id: tenantId
14599
+ tenant_id: tenantId,
14600
+ workspace_id: workspaceId,
14601
+ project_id: projectId
14317
14602
  });
14318
14603
  if (mainRuntimeAgent) {
14319
14604
  mainRuntimeAgent.addAsyncTask({
@@ -14392,15 +14677,15 @@ The result will be delivered as a notification when complete. Do not poll.`,
14392
14677
  {
14393
14678
  name: "task",
14394
14679
  description: finalTaskDescription,
14395
- schema: z49.object({
14396
- description: z49.string().describe("The task to execute with the selected agent"),
14397
- subagent_type: z49.string().describe(
14680
+ schema: z50.object({
14681
+ description: z50.string().describe("The task to execute with the selected agent"),
14682
+ subagent_type: z50.string().describe(
14398
14683
  `Name of the agent to use. Available: ${Object.keys(
14399
14684
  subagentGraphs
14400
14685
  ).join(", ")}`
14401
14686
  ),
14402
14687
  ...allowAsync ? {
14403
- async: z49.boolean().default(false).describe(
14688
+ async: z50.boolean().default(false).describe(
14404
14689
  "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
14690
  )
14406
14691
  } : {}
@@ -14419,7 +14704,7 @@ function getMainAgentFromConfig(config) {
14419
14704
  });
14420
14705
  }
14421
14706
  function createCheckAsyncTaskTool() {
14422
- return tool46(
14707
+ return tool47(
14423
14708
  async (input, config) => {
14424
14709
  const { task_id } = input;
14425
14710
  const mainAgent = getMainAgentFromConfig(config);
@@ -14479,14 +14764,14 @@ Description: ${cached.description}`;
14479
14764
  {
14480
14765
  name: "check_async_task",
14481
14766
  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: z49.object({
14483
- task_id: z49.string().describe("The task ID returned when the async task was started")
14767
+ schema: z50.object({
14768
+ task_id: z50.string().describe("The task ID returned when the async task was started")
14484
14769
  })
14485
14770
  }
14486
14771
  );
14487
14772
  }
14488
14773
  function createListAsyncTasksTool() {
14489
- return tool46(
14774
+ return tool47(
14490
14775
  async (_input, config) => {
14491
14776
  const mainAgent = getMainAgentFromConfig(config);
14492
14777
  if (!mainAgent) {
@@ -14532,12 +14817,12 @@ function createListAsyncTasksTool() {
14532
14817
  {
14533
14818
  name: "list_async_tasks",
14534
14819
  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: z49.object({})
14820
+ schema: z50.object({})
14536
14821
  }
14537
14822
  );
14538
14823
  }
14539
14824
  function createCancelAsyncTaskTool() {
14540
- return tool46(
14825
+ return tool47(
14541
14826
  async (input, config) => {
14542
14827
  const { task_id } = input;
14543
14828
  const mainAgent = getMainAgentFromConfig(config);
@@ -14576,8 +14861,8 @@ function createCancelAsyncTaskTool() {
14576
14861
  {
14577
14862
  name: "cancel_async_task",
14578
14863
  description: "Cancel a running async background task.",
14579
- schema: z49.object({
14580
- task_id: z49.string().describe("The task ID to cancel")
14864
+ schema: z50.object({
14865
+ task_id: z50.string().describe("The task ID to cancel")
14581
14866
  })
14582
14867
  }
14583
14868
  );
@@ -14613,7 +14898,7 @@ function createSubAgentMiddleware(options) {
14613
14898
  );
14614
14899
  }
14615
14900
  const effectiveSystemPrompt = allowAsync ? systemPrompt + getAsyncPromptText() : systemPrompt;
14616
- return createMiddleware14({
14901
+ return createMiddleware15({
14617
14902
  name: "subAgentMiddleware",
14618
14903
  tools: allTools,
14619
14904
  wrapModelCall: async (request, handler) => {
@@ -14634,14 +14919,12 @@ ${effectiveSystemPrompt}` : effectiveSystemPrompt;
14634
14919
 
14635
14920
  // src/deep_agent_new/middleware/patch_tool_calls.ts
14636
14921
  import {
14637
- createMiddleware as createMiddleware15,
14922
+ createMiddleware as createMiddleware16,
14638
14923
  ToolMessage as ToolMessage5,
14639
14924
  AIMessage as AIMessage2
14640
14925
  } from "langchain";
14641
- import { RemoveMessage } from "@langchain/core/messages";
14642
- import { REMOVE_ALL_MESSAGES } from "@langchain/langgraph";
14643
14926
  function createPatchToolCallsMiddleware() {
14644
- return createMiddleware15({
14927
+ return createMiddleware16({
14645
14928
  name: "patchToolCallsMiddleware",
14646
14929
  beforeAgent: async (state) => {
14647
14930
  const messages = state.messages;
@@ -14670,11 +14953,12 @@ function createPatchToolCallsMiddleware() {
14670
14953
  }
14671
14954
  }
14672
14955
  }
14956
+ if (patchedMessages.length === messages.length) {
14957
+ return;
14958
+ }
14673
14959
  return {
14674
- messages: [
14675
- new RemoveMessage({ id: REMOVE_ALL_MESSAGES }),
14676
- ...patchedMessages
14677
- ]
14960
+ messages: patchedMessages.slice(messages.length)
14961
+ // only the new ToolMessage patches
14678
14962
  };
14679
14963
  }
14680
14964
  });
@@ -15787,8 +16071,8 @@ var MemoryBackend = class {
15787
16071
 
15788
16072
  // src/deep_agent_new/middleware/todos.ts
15789
16073
  import { Command as Command4 } from "@langchain/langgraph";
15790
- import { z as z50 } from "zod";
15791
- import { createMiddleware as createMiddleware16, tool as tool47, ToolMessage as ToolMessage6 } from "langchain";
16074
+ import { z as z51 } from "zod";
16075
+ import { createMiddleware as createMiddleware17, tool as tool48, ToolMessage as ToolMessage6 } from "langchain";
15792
16076
  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
16077
  It also helps the user understand the progress of the task and overall progress of their requests.
15794
16078
  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 +16299,14 @@ Writing todos takes time and tokens, use it when it is helpful for managing comp
16015
16299
  ## Important To-Do List Usage Notes to Remember
16016
16300
  - The \`write_todos\` tool should never be called multiple times in parallel.
16017
16301
  - 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 = z50.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
16019
- var TodoSchema = z50.object({
16020
- content: z50.string().describe("Content of the todo item"),
16302
+ var TodoStatus = z51.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
16303
+ var TodoSchema = z51.object({
16304
+ content: z51.string().describe("Content of the todo item"),
16021
16305
  status: TodoStatus
16022
16306
  });
16023
- var stateSchema = z50.object({ todos: z50.array(TodoSchema).default([]) });
16307
+ var stateSchema = z51.object({ todos: z51.array(TodoSchema).default([]) });
16024
16308
  function todoListMiddleware(options) {
16025
- const writeTodos = tool47(
16309
+ const writeTodos = tool48(
16026
16310
  ({ todos }, config) => {
16027
16311
  return new Command4({
16028
16312
  update: {
@@ -16039,12 +16323,12 @@ function todoListMiddleware(options) {
16039
16323
  {
16040
16324
  name: "write_todos",
16041
16325
  description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,
16042
- schema: z50.object({
16043
- todos: z50.array(TodoSchema).describe("List of todo items to update")
16326
+ schema: z51.object({
16327
+ todos: z51.array(TodoSchema).describe("List of todo items to update")
16044
16328
  })
16045
16329
  }
16046
16330
  );
16047
- return createMiddleware16({
16331
+ return createMiddleware17({
16048
16332
  name: "todoListMiddleware",
16049
16333
  stateSchema,
16050
16334
  tools: [writeTodos],
@@ -16156,7 +16440,7 @@ var DeepAgentGraphBuilder = class {
16156
16440
  const tools = params.tools.map((t) => {
16157
16441
  const toolClient = getToolClient(t.key);
16158
16442
  return toolClient;
16159
- }).filter((tool51) => tool51 !== void 0);
16443
+ }).filter((tool52) => tool52 !== void 0);
16160
16444
  const subagents = await Promise.all(params.subAgents.map(async (sa) => {
16161
16445
  if (sa.client) {
16162
16446
  return {
@@ -16197,7 +16481,7 @@ var DeepAgentGraphBuilder = class {
16197
16481
  };
16198
16482
 
16199
16483
  // src/agent_team/agent_team.ts
16200
- import { z as z53 } from "zod/v3";
16484
+ import { z as z54 } from "zod/v3";
16201
16485
  import { createAgent as createAgent5 } from "langchain";
16202
16486
 
16203
16487
  // src/agent_team/types.ts
@@ -16633,14 +16917,14 @@ var InMemoryMailboxStore = class {
16633
16917
  };
16634
16918
 
16635
16919
  // src/agent_team/middleware/team.ts
16636
- import { z as z52 } from "zod/v3";
16637
- import { createMiddleware as createMiddleware17, createAgent as createAgent4, tool as tool49, ToolMessage as ToolMessage8 } from "langchain";
16920
+ import { z as z53 } from "zod/v3";
16921
+ import { createMiddleware as createMiddleware18, createAgent as createAgent4, tool as tool50, ToolMessage as ToolMessage8 } from "langchain";
16638
16922
  import { Command as Command6, getCurrentTaskInput as getCurrentTaskInput3 } from "@langchain/langgraph";
16639
- import { v4 as uuidv42 } from "uuid";
16923
+ import { v4 as uuidv43 } from "uuid";
16640
16924
 
16641
16925
  // src/agent_team/middleware/teammate_tools.ts
16642
- import { z as z51 } from "zod/v3";
16643
- import { tool as tool48, ToolMessage as ToolMessage7 } from "langchain";
16926
+ import { z as z52 } from "zod/v3";
16927
+ import { tool as tool49, ToolMessage as ToolMessage7 } from "langchain";
16644
16928
  import { Command as Command5 } from "@langchain/langgraph";
16645
16929
 
16646
16930
  // src/agent_team/middleware/formatMessages.ts
@@ -16665,7 +16949,7 @@ ${meta}${body}`;
16665
16949
  // src/agent_team/middleware/teammate_tools.ts
16666
16950
  function createTeammateTools(options) {
16667
16951
  const { teamId, agentId, taskListStore, mailboxStore } = options;
16668
- const claimTaskTool = tool48(
16952
+ const claimTaskTool = tool49(
16669
16953
  async (input) => {
16670
16954
  const task = await taskListStore.claimTaskById(
16671
16955
  teamId,
@@ -16690,12 +16974,12 @@ function createTeammateTools(options) {
16690
16974
  {
16691
16975
  name: "claim_task",
16692
16976
  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: z51.object({
16694
- task_id: z51.string().describe("ID of the task to claim (e.g. task-01). Use check_tasks to see IDs.")
16977
+ schema: z52.object({
16978
+ task_id: z52.string().describe("ID of the task to claim (e.g. task-01). Use check_tasks to see IDs.")
16695
16979
  })
16696
16980
  }
16697
16981
  );
16698
- const completeTaskTool = tool48(
16982
+ const completeTaskTool = tool49(
16699
16983
  async (input) => {
16700
16984
  const task = await taskListStore.completeTask(
16701
16985
  teamId,
@@ -16716,13 +17000,13 @@ function createTeammateTools(options) {
16716
17000
  {
16717
17001
  name: "complete_task",
16718
17002
  description: "Mark a claimed task as completed with a result summary. Call this after you have finished working on a task.",
16719
- schema: z51.object({
16720
- task_id: z51.string().describe("ID of the task to complete"),
16721
- result: z51.string().describe("Summary of the task result")
17003
+ schema: z52.object({
17004
+ task_id: z52.string().describe("ID of the task to complete"),
17005
+ result: z52.string().describe("Summary of the task result")
16722
17006
  })
16723
17007
  }
16724
17008
  );
16725
- const failTaskTool = tool48(
17009
+ const failTaskTool = tool49(
16726
17010
  async (input) => {
16727
17011
  const task = await taskListStore.failTask(
16728
17012
  teamId,
@@ -16743,13 +17027,13 @@ function createTeammateTools(options) {
16743
17027
  {
16744
17028
  name: "fail_task",
16745
17029
  description: "Mark a claimed task as failed with an error description. Call this if you cannot complete the task.",
16746
- schema: z51.object({
16747
- task_id: z51.string().describe("ID of the task to fail"),
16748
- error: z51.string().describe("Description of why the task failed")
17030
+ schema: z52.object({
17031
+ task_id: z52.string().describe("ID of the task to fail"),
17032
+ error: z52.string().describe("Description of why the task failed")
16749
17033
  })
16750
17034
  }
16751
17035
  );
16752
- const sendMessageTool = tool48(
17036
+ const sendMessageTool = tool49(
16753
17037
  async (input) => {
16754
17038
  await mailboxStore.sendMessage(
16755
17039
  teamId,
@@ -16763,11 +17047,11 @@ function createTeammateTools(options) {
16763
17047
  {
16764
17048
  name: "send_message",
16765
17049
  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: z51.object({
16767
- to: z51.string().describe(
17050
+ schema: z52.object({
17051
+ to: z52.string().describe(
16768
17052
  'Recipient agent name (e.g. "team_lead" or a teammate name)'
16769
17053
  ),
16770
- content: z51.string().describe("Message content")
17054
+ content: z52.string().describe("Message content")
16771
17055
  })
16772
17056
  }
16773
17057
  );
@@ -16787,7 +17071,7 @@ function createTeammateTools(options) {
16787
17071
  read: msg.read
16788
17072
  }));
16789
17073
  };
16790
- const readMessagesTool = tool48(
17074
+ const readMessagesTool = tool49(
16791
17075
  async (input, config) => {
16792
17076
  const formatAndMarkAsRead = async (msgs2) => {
16793
17077
  for (const msg of msgs2) {
@@ -16846,10 +17130,10 @@ function createTeammateTools(options) {
16846
17130
  {
16847
17131
  name: "read_messages",
16848
17132
  description: "Read unread messages from the mailbox. Returns immediately if messages exist, otherwise waits for up to 3 minutes for new messages.",
16849
- schema: z51.object({})
17133
+ schema: z52.object({})
16850
17134
  }
16851
17135
  );
16852
- const checkTasksTool = tool48(
17136
+ const checkTasksTool = tool49(
16853
17137
  async () => {
16854
17138
  const tasks = await taskListStore.getAllTasks(teamId);
16855
17139
  return formatTaskSummary(tasks);
@@ -16857,10 +17141,10 @@ function createTeammateTools(options) {
16857
17141
  {
16858
17142
  name: "check_tasks",
16859
17143
  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: z51.object({})
17144
+ schema: z52.object({})
16861
17145
  }
16862
17146
  );
16863
- const broadcastMessageTool = tool48(
17147
+ const broadcastMessageTool = tool49(
16864
17148
  async (input) => {
16865
17149
  const allAgents = await mailboxStore.getRegisteredAgents(teamId);
16866
17150
  const recipients = allAgents.filter((a) => a !== agentId);
@@ -16879,8 +17163,8 @@ function createTeammateTools(options) {
16879
17163
  {
16880
17164
  name: "broadcast_message",
16881
17165
  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: z51.object({
16883
- content: z51.string().describe("Message content to broadcast to others")
17166
+ schema: z52.object({
17167
+ content: z52.string().describe("Message content to broadcast to others")
16884
17168
  })
16885
17169
  }
16886
17170
  );
@@ -17114,7 +17398,7 @@ async function spawnTeammate(options) {
17114
17398
  function createTeamMiddleware(options) {
17115
17399
  const { teamConfig, taskListStore, mailboxStore, tenantId } = options;
17116
17400
  const defaultModel = teamConfig.model ?? "claude-sonnet-4-5-20250929";
17117
- const createTeamTool = tool49(
17401
+ const createTeamTool = tool50(
17118
17402
  async (input, config) => {
17119
17403
  const state = getCurrentTaskInput3();
17120
17404
  if (state?.team?.teamId) {
@@ -17126,7 +17410,7 @@ function createTeamMiddleware(options) {
17126
17410
  });
17127
17411
  return msg;
17128
17412
  }
17129
- const teamId = uuidv42();
17413
+ const teamId = uuidv43();
17130
17414
  const createdTasks = await taskListStore.addTasks(
17131
17415
  teamId,
17132
17416
  input.tasks.map((t) => ({
@@ -17269,20 +17553,20 @@ After calling create_team, you MUST:
17269
17553
  2. When messages indicate task changes, call check_tasks to get full task status
17270
17554
  3. Continue until all tasks show "completed" or "failed"
17271
17555
  4. Do NOT assume tasks are done - always verify with check_tasks`,
17272
- schema: z52.object({
17273
- tasks: z52.array(
17274
- z52.object({
17275
- id: z52.string().describe("Task ID in format task-01, task-02, etc."),
17276
- title: z52.string().describe("Short task title"),
17277
- description: z52.string().describe("Detailed task description - what exactly needs to be done"),
17278
- dependencies: z52.array(z52.string()).optional().default([]).describe('Array of task IDs that must complete before this task (e.g. ["task-01"])')
17556
+ schema: z53.object({
17557
+ tasks: z53.array(
17558
+ z53.object({
17559
+ id: z53.string().describe("Task ID in format task-01, task-02, etc."),
17560
+ title: z53.string().describe("Short task title"),
17561
+ description: z53.string().describe("Detailed task description - what exactly needs to be done"),
17562
+ dependencies: z53.array(z53.string()).optional().default([]).describe('Array of task IDs that must complete before this task (e.g. ["task-01"])')
17279
17563
  })
17280
17564
  ).describe("List of tasks for teammates to work on. Each task needs unique ID (task-01, task-02, etc.)."),
17281
- teammates: z52.array(
17282
- z52.object({
17283
- name: z52.string().describe("Teammate name (must match a pre-configured teammate type)"),
17284
- role: z52.string().describe("Role category (e.g. researcher, writer, coder, reviewer)"),
17285
- description: z52.string().describe("What this teammate will focus on - specific instructions for their work")
17565
+ teammates: z53.array(
17566
+ z53.object({
17567
+ name: z53.string().describe("Teammate name (must match a pre-configured teammate type)"),
17568
+ role: z53.string().describe("Role category (e.g. researcher, writer, coder, reviewer)"),
17569
+ description: z53.string().describe("What this teammate will focus on - specific instructions for their work")
17286
17570
  })
17287
17571
  ).describe("Teammate agents to create. Each should have a clear role and focus.")
17288
17572
  })
@@ -17293,7 +17577,7 @@ After calling create_team, you MUST:
17293
17577
  if (state?.team?.teamId) return state.team.teamId;
17294
17578
  throw new Error("No team_id provided and no team in state. Call create_team first.");
17295
17579
  };
17296
- const addTasksTool = tool49(
17580
+ const addTasksTool = tool50(
17297
17581
  async (input, config) => {
17298
17582
  const teamId = resolveTeamId();
17299
17583
  const created = await taskListStore.addTasks(
@@ -17345,20 +17629,20 @@ IMPORTANT: Dependencies
17345
17629
 
17346
17630
  IMPORTANT: Assigning to a specific teammate
17347
17631
  - 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: z52.object({
17349
- tasks: z52.array(
17350
- z52.object({
17351
- id: z52.string().describe("Task ID in format task-01, task-02, etc. Must be unique."),
17352
- title: z52.string().describe("Short task title"),
17353
- description: z52.string().describe("Detailed task description - what needs to be done"),
17354
- assignee: z52.string().optional().describe("Teammate name to assign this task to (use when you need that person to do the work)"),
17355
- dependencies: z52.array(z52.string()).optional().default([]).describe("Array of task IDs that must complete before this task")
17632
+ schema: z53.object({
17633
+ tasks: z53.array(
17634
+ z53.object({
17635
+ id: z53.string().describe("Task ID in format task-01, task-02, etc. Must be unique."),
17636
+ title: z53.string().describe("Short task title"),
17637
+ description: z53.string().describe("Detailed task description - what needs to be done"),
17638
+ assignee: z53.string().optional().describe("Teammate name to assign this task to (use when you need that person to do the work)"),
17639
+ dependencies: z53.array(z53.string()).optional().default([]).describe("Array of task IDs that must complete before this task")
17356
17640
  })
17357
17641
  ).describe("New tasks to add to the team")
17358
17642
  })
17359
17643
  }
17360
17644
  );
17361
- const assignTaskTool = tool49(
17645
+ const assignTaskTool = tool50(
17362
17646
  async (input, config) => {
17363
17647
  const teamId = resolveTeamId();
17364
17648
  const task = await taskListStore.updateTask(teamId, input.task_id, {
@@ -17380,13 +17664,13 @@ IMPORTANT: Assigning to a specific teammate
17380
17664
  {
17381
17665
  name: "assign_task",
17382
17666
  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: z52.object({
17384
- task_id: z52.string().describe("Task ID to assign"),
17385
- assignee: z52.string().describe("Teammate name to assign this task to")
17667
+ schema: z53.object({
17668
+ task_id: z53.string().describe("Task ID to assign"),
17669
+ assignee: z53.string().describe("Teammate name to assign this task to")
17386
17670
  })
17387
17671
  }
17388
17672
  );
17389
- const setTaskStatusTool = tool49(
17673
+ const setTaskStatusTool = tool50(
17390
17674
  async (input, config) => {
17391
17675
  const teamId = resolveTeamId();
17392
17676
  const task = await taskListStore.updateTask(teamId, input.task_id, {
@@ -17408,13 +17692,13 @@ IMPORTANT: Assigning to a specific teammate
17408
17692
  {
17409
17693
  name: "set_task_status",
17410
17694
  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: z52.object({
17412
- task_id: z52.string().describe("Task ID to update"),
17413
- status: z52.enum(["pending", "claimed", "in_progress", "completed", "failed"]).describe("New status for the task")
17695
+ schema: z53.object({
17696
+ task_id: z53.string().describe("Task ID to update"),
17697
+ status: z53.enum(["pending", "claimed", "in_progress", "completed", "failed"]).describe("New status for the task")
17414
17698
  })
17415
17699
  }
17416
17700
  );
17417
- const setTaskDependenciesTool = tool49(
17701
+ const setTaskDependenciesTool = tool50(
17418
17702
  async (input, config) => {
17419
17703
  const teamId = resolveTeamId();
17420
17704
  const task = await taskListStore.updateTask(teamId, input.task_id, {
@@ -17436,13 +17720,13 @@ IMPORTANT: Assigning to a specific teammate
17436
17720
  {
17437
17721
  name: "set_task_dependencies",
17438
17722
  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: z52.object({
17440
- task_id: z52.string().describe("Task ID to update"),
17441
- dependencies: z52.array(z52.string()).describe("Task IDs that must complete before this task can be claimed")
17723
+ schema: z53.object({
17724
+ task_id: z53.string().describe("Task ID to update"),
17725
+ dependencies: z53.array(z53.string()).describe("Task IDs that must complete before this task can be claimed")
17442
17726
  })
17443
17727
  }
17444
17728
  );
17445
- const checkTasksTool = tool49(
17729
+ const checkTasksTool = tool50(
17446
17730
  async (input, config) => {
17447
17731
  const teamId = resolveTeamId();
17448
17732
  const tasks = await taskListStore.getAllTasks(teamId);
@@ -17482,12 +17766,12 @@ Task Status Values:
17482
17766
  - in_progress: Teammate is actively working on this task
17483
17767
  - completed: Task finished successfully
17484
17768
  - failed: Task encountered an error`,
17485
- schema: z52.object({
17486
- team_id: z52.string().optional().describe("Team ID (omit to use active team)")
17769
+ schema: z53.object({
17770
+ team_id: z53.string().optional().describe("Team ID (omit to use active team)")
17487
17771
  })
17488
17772
  }
17489
17773
  );
17490
- const sendMessageTool = tool49(
17774
+ const sendMessageTool = tool50(
17491
17775
  async (input, config) => {
17492
17776
  const teamId = resolveTeamId();
17493
17777
  await mailboxStore.sendMessage(
@@ -17506,13 +17790,13 @@ Task Status Values:
17506
17790
  {
17507
17791
  name: "send_message",
17508
17792
  description: "Send a message to a specific teammate in the team. Omit team_id to use the active team from state.",
17509
- schema: z52.object({
17510
- to: z52.string().describe("Recipient teammate name"),
17511
- content: z52.string().describe("Message content")
17793
+ schema: z53.object({
17794
+ to: z53.string().describe("Recipient teammate name"),
17795
+ content: z53.string().describe("Message content")
17512
17796
  })
17513
17797
  }
17514
17798
  );
17515
- const readMessagesTool = tool49(
17799
+ const readMessagesTool = tool50(
17516
17800
  async (input, config) => {
17517
17801
  const teamId = resolveTeamId();
17518
17802
  const formatAndMarkAsRead = async (msgs2) => {
@@ -17594,12 +17878,12 @@ Task Status Values:
17594
17878
  {
17595
17879
  name: "read_messages",
17596
17880
  description: "Read unread messages from teammates. Returns immediately if messages exist, otherwise waits for up to 3 minutes for new messages.",
17597
- schema: z52.object({
17598
- team_id: z52.string().optional().describe("Team ID (omit to use active team)")
17881
+ schema: z53.object({
17882
+ team_id: z53.string().optional().describe("Team ID (omit to use active team)")
17599
17883
  })
17600
17884
  }
17601
17885
  );
17602
- const disbandTeamTool = tool49(
17886
+ const disbandTeamTool = tool50(
17603
17887
  async (input, config) => {
17604
17888
  const teamId = resolveTeamId();
17605
17889
  await mailboxStore.broadcastMessage(
@@ -17620,7 +17904,7 @@ Task Status Values:
17620
17904
  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
17905
  }
17622
17906
  );
17623
- const broadcastMessageTool = tool49(
17907
+ const broadcastMessageTool = tool50(
17624
17908
  async (input, config) => {
17625
17909
  const teamId = resolveTeamId();
17626
17910
  await mailboxStore.broadcastMessage(
@@ -17638,12 +17922,12 @@ Task Status Values:
17638
17922
  {
17639
17923
  name: "broadcast_message",
17640
17924
  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: z52.object({
17642
- content: z52.string().describe("Message content to broadcast to all teammates")
17925
+ schema: z53.object({
17926
+ content: z53.string().describe("Message content to broadcast to all teammates")
17643
17927
  })
17644
17928
  }
17645
17929
  );
17646
- return createMiddleware17({
17930
+ return createMiddleware18({
17647
17931
  name: "teamMiddleware",
17648
17932
  tools: [
17649
17933
  createTeamTool,
@@ -17671,37 +17955,37 @@ ${TEAM_SYSTEM_PROMPT}` : TEAM_SYSTEM_PROMPT;
17671
17955
  }
17672
17956
 
17673
17957
  // src/agent_team/agent_team.ts
17674
- var TeammateInfoSchema = z53.object({
17675
- name: z53.string().describe("Teammate name"),
17676
- role: z53.string().describe("Role category (e.g. research, writing, review)"),
17677
- description: z53.string().describe("What this teammate focuses on")
17958
+ var TeammateInfoSchema = z54.object({
17959
+ name: z54.string().describe("Teammate name"),
17960
+ role: z54.string().describe("Role category (e.g. research, writing, review)"),
17961
+ description: z54.string().describe("What this teammate focuses on")
17678
17962
  });
17679
- var TeamTaskInfoSchema = z53.object({
17680
- id: z53.string(),
17681
- title: z53.string(),
17682
- description: z53.string(),
17683
- status: z53.string().optional()
17963
+ var TeamTaskInfoSchema = z54.object({
17964
+ id: z54.string(),
17965
+ title: z54.string(),
17966
+ description: z54.string(),
17967
+ status: z54.string().optional()
17684
17968
  });
17685
- var MailboxMessageSchema = z53.object({
17686
- id: z53.string().describe("Unique message identifier"),
17687
- from: z53.string().describe("Sender agent name"),
17688
- to: z53.string().describe("Recipient agent name"),
17689
- content: z53.string().describe("Message content"),
17690
- timestamp: z53.string().describe("ISO timestamp when the message was sent"),
17691
- type: z53.nativeEnum(MessageType).describe("Message type"),
17692
- read: z53.boolean().describe("Whether the recipient has read this message")
17969
+ var MailboxMessageSchema = z54.object({
17970
+ id: z54.string().describe("Unique message identifier"),
17971
+ from: z54.string().describe("Sender agent name"),
17972
+ to: z54.string().describe("Recipient agent name"),
17973
+ content: z54.string().describe("Message content"),
17974
+ timestamp: z54.string().describe("ISO timestamp when the message was sent"),
17975
+ type: z54.nativeEnum(MessageType).describe("Message type"),
17976
+ read: z54.boolean().describe("Whether the recipient has read this message")
17693
17977
  });
17694
- var TeamInfoSchema = z53.object({
17695
- teamId: z53.string().describe("Unique team identifier"),
17696
- teamLeadId: z53.string().default("team_lead").describe("Team lead agent ID"),
17697
- teammates: z53.array(TeammateInfoSchema).describe("Active teammates in this team"),
17698
- tasks: z53.array(TeamTaskInfoSchema).optional().describe("Initial tasks snapshot"),
17699
- createdAt: z53.string().optional().describe("ISO timestamp when team was created")
17978
+ var TeamInfoSchema = z54.object({
17979
+ teamId: z54.string().describe("Unique team identifier"),
17980
+ teamLeadId: z54.string().default("team_lead").describe("Team lead agent ID"),
17981
+ teammates: z54.array(TeammateInfoSchema).describe("Active teammates in this team"),
17982
+ tasks: z54.array(TeamTaskInfoSchema).optional().describe("Initial tasks snapshot"),
17983
+ createdAt: z54.string().optional().describe("ISO timestamp when team was created")
17700
17984
  });
17701
- var TEAM_STATE_SCHEMA = z53.object({
17985
+ var TEAM_STATE_SCHEMA = z54.object({
17702
17986
  team: TeamInfoSchema.optional().describe("Team info: teamId, teamLeadId, teammates, tasks. Set when create_team succeeds."),
17703
- tasks: z53.array(TeamTaskInfoSchema).optional().describe("Current tasks snapshot from check_tasks. Updated on each check."),
17704
- team_mailbox: z53.array(MailboxMessageSchema).optional().describe("All team mailbox messages for display")
17987
+ tasks: z54.array(TeamTaskInfoSchema).optional().describe("Current tasks snapshot from check_tasks. Updated on each check."),
17988
+ team_mailbox: z54.array(MailboxMessageSchema).optional().describe("All team mailbox messages for display")
17705
17989
  });
17706
17990
  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
17991
 
@@ -17782,7 +18066,7 @@ var TeamAgentGraphBuilder = class {
17782
18066
  const tools = params.tools.map((t) => {
17783
18067
  const toolClient = getToolClient(t.key);
17784
18068
  return toolClient;
17785
- }).filter((tool51) => tool51 !== void 0);
18069
+ }).filter((tool52) => tool52 !== void 0);
17786
18070
  const teammates = params.subAgents.map((sa) => {
17787
18071
  const baseConfig = sa.config;
17788
18072
  return {
@@ -17828,14 +18112,14 @@ import {
17828
18112
  } from "langchain";
17829
18113
 
17830
18114
  // src/middlewares/topologyMiddleware.ts
17831
- import { createMiddleware as createMiddleware18 } from "langchain";
18115
+ import { createMiddleware as createMiddleware19 } from "langchain";
17832
18116
  import { AIMessage as AIMessage3, ToolMessage as ToolMessage9 } from "@langchain/core/messages";
17833
- import { tool as tool50 } from "langchain";
17834
- import { z as z54 } from "zod";
18117
+ import { tool as tool51 } from "langchain";
18118
+ import { z as z55 } from "zod";
17835
18119
  import { GraphInterrupt as GraphInterrupt4 } from "@langchain/langgraph";
17836
- var CompletedEdgeSchema = z54.object({
17837
- to: z54.string(),
17838
- purpose: z54.string()
18120
+ var CompletedEdgeSchema = z55.object({
18121
+ to: z55.string(),
18122
+ purpose: z55.string()
17839
18123
  });
17840
18124
  function deriveCompletedEdges(messages, edges) {
17841
18125
  const completedToolCallIds = /* @__PURE__ */ new Set();
@@ -17862,16 +18146,16 @@ function deriveCompletedEdges(messages, edges) {
17862
18146
  }
17863
18147
  function createTopologyMiddleware(options) {
17864
18148
  const { edges, trackingStore } = options;
17865
- return createMiddleware18({
18149
+ return createMiddleware19({
17866
18150
  name: "TopologyMiddleware",
17867
- contextSchema: z54.object({
17868
- runConfig: z54.any()
18151
+ contextSchema: z55.object({
18152
+ runConfig: z55.any()
17869
18153
  }),
17870
- stateSchema: z54.object({
17871
- currentAgentId: z54.string().default(""),
17872
- completedEdges: z54.array(CompletedEdgeSchema).default([]),
17873
- runId: z54.string().default(""),
17874
- stepIdMap: z54.record(z54.string()).default({})
18154
+ stateSchema: z55.object({
18155
+ currentAgentId: z55.string().default(""),
18156
+ completedEdges: z55.array(CompletedEdgeSchema).default([]),
18157
+ runId: z55.string().default(""),
18158
+ stepIdMap: z55.record(z55.string()).default({})
17875
18159
  }),
17876
18160
  beforeAgent: async (state, runtime) => {
17877
18161
  if (state.runId) {
@@ -17922,14 +18206,14 @@ ${request.systemPrompt}` : topologyPrompt;
17922
18206
  return handler({ ...request, systemPrompt: newSystemPrompt });
17923
18207
  },
17924
18208
  tools: [
17925
- tool50(
18209
+ tool51(
17926
18210
  async (_input) => {
17927
18211
  return "placeholder";
17928
18212
  },
17929
18213
  {
17930
18214
  name: "read_topo_progress",
17931
18215
  description: "Check the current progress of the workflow execution plan. Returns which steps have been completed and which are still pending.",
17932
- schema: z54.object({})
18216
+ schema: z55.object({})
17933
18217
  }
17934
18218
  )
17935
18219
  ],
@@ -18205,7 +18489,7 @@ var ProcessingAgentGraphBuilder = class {
18205
18489
  const tools = params.tools.map((t) => {
18206
18490
  const toolClient = getToolClient(t.key);
18207
18491
  return toolClient;
18208
- }).filter((tool51) => tool51 !== void 0);
18492
+ }).filter((tool52) => tool52 !== void 0);
18209
18493
  const subagents = await Promise.all(params.subAgents.map(async (sa) => {
18210
18494
  if (sa.client) {
18211
18495
  return {
@@ -18483,24 +18767,24 @@ var WorkflowAgentGraphBuilder = class {
18483
18767
  );
18484
18768
  }
18485
18769
  const config = agentLattice.config;
18486
- const dsl = config.workflow;
18770
+ const yaml = config.workflowYaml;
18487
18771
  const tenantId = agentLattice.config.tenantId ?? "default";
18488
18772
  const checkpointer = getCheckpointSaver("default");
18489
18773
  const tools = params.tools.map((t) => t.executor).filter(Boolean);
18490
18774
  const middlewareConfigs = params.middleware || [];
18491
18775
  const middlewares = await createCommonMiddlewares(middlewareConfigs, void 0, false);
18492
- const humanMiddlewares = await createCommonMiddlewares([
18776
+ const askMiddlewares = await createCommonMiddlewares([
18493
18777
  {
18494
18778
  id: "ask_user_to_clarify",
18495
18779
  type: "ask_user_to_clarify",
18496
18780
  name: "Ask User Clarify",
18497
- description: "For human_feedback workflow nodes",
18781
+ description: "For workflow steps requiring user interaction",
18498
18782
  enabled: true,
18499
18783
  config: {}
18500
18784
  }
18501
18785
  ], void 0, false);
18502
18786
  const noWrapMiddlewares = middlewares.filter((m) => !m.wrapModelCall);
18503
- const noWrapHumanMiddlewares = humanMiddlewares.filter((m) => !m.wrapModelCall);
18787
+ const noWrapAskMiddlewares = askMiddlewares.filter((m) => !m.wrapModelCall);
18504
18788
  console.log(`[WF BUILDER] building default agent | toolCount=${tools.length} | middlewareCount=${middlewares.length}`);
18505
18789
  const defaultAgent = createAgent7({
18506
18790
  model: params.model,
@@ -18516,34 +18800,34 @@ var WorkflowAgentGraphBuilder = class {
18516
18800
  console.log(`[WF BUILDER] resolveAgent: looking up ref="${ref}"`);
18517
18801
  return await getAgentClientAsync(tenantId, ref);
18518
18802
  }
18519
- const isHuman = stepType === "human_feedback";
18803
+ const isAsk = stepType === "ask";
18520
18804
  if (responseFormat) {
18521
- const key = (isHuman ? "human:" : "agent:") + JSON.stringify(responseFormat);
18805
+ const key = (isAsk ? "ask:" : "agent:") + JSON.stringify(responseFormat);
18522
18806
  console.log(`[WF BUILDER] resolveAgent: cacheKey=${key.slice(0, 80)}... | cached=${agentCache.has(key)}`);
18523
18807
  if (!agentCache.has(key)) {
18524
- console.log(`[WF BUILDER] creating ${isHuman ? "human" : "agent"} with responseFormat`);
18808
+ console.log(`[WF BUILDER] creating ${isAsk ? "ask" : "agent"} with responseFormat`);
18525
18809
  const agent = createAgent7({
18526
18810
  model: params.model,
18527
18811
  tools,
18528
18812
  systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
18529
18813
  checkpointer,
18530
- middleware: isHuman ? noWrapHumanMiddlewares : noWrapMiddlewares,
18814
+ middleware: isAsk ? noWrapAskMiddlewares : noWrapMiddlewares,
18531
18815
  responseFormat
18532
18816
  });
18533
18817
  agentCache.set(key, agent);
18534
18818
  }
18535
18819
  return agentCache.get(key);
18536
18820
  }
18537
- if (isHuman) {
18538
- const key = "human:default";
18821
+ if (isAsk) {
18822
+ const key = "ask:default";
18539
18823
  if (!agentCache.has(key)) {
18540
- console.log(`[WF BUILDER] creating human_feedback default agent`);
18824
+ console.log(`[WF BUILDER] creating ask default agent`);
18541
18825
  const agent = createAgent7({
18542
18826
  model: params.model,
18543
18827
  tools,
18544
18828
  systemPrompt: params.prompt || DEFAULT_AGENT_PROMPT,
18545
18829
  checkpointer,
18546
- middleware: humanMiddlewares
18830
+ middleware: askMiddlewares
18547
18831
  });
18548
18832
  agentCache.set(key, agent);
18549
18833
  }
@@ -18556,11 +18840,11 @@ var WorkflowAgentGraphBuilder = class {
18556
18840
  try {
18557
18841
  const storeLattice = getStoreLattice("default", "workflowTracking");
18558
18842
  trackingStore = storeLattice.store;
18559
- console.log(`[WF BUILDER] trackingStore registered: step input/output will be persisted`);
18843
+ console.log(`[WF BUILDER] trackingStore registered`);
18560
18844
  } catch {
18561
- console.warn(`[WF BUILDER] no trackingStore registered \u2014 step input/output will NOT be persisted. Register a WorkflowTrackingStore under key "workflowTracking".`);
18845
+ console.warn(`[WF BUILDER] no trackingStore registered`);
18562
18846
  }
18563
- const graph = compileWorkflow(dsl, resolveAgent, checkpointer, trackingStore);
18847
+ const graph = compileWorkflow(yaml, resolveAgent, checkpointer, trackingStore);
18564
18848
  return graph;
18565
18849
  }
18566
18850
  };
@@ -19265,8 +19549,65 @@ ${body}` : `${frontmatter}
19265
19549
  }
19266
19550
  };
19267
19551
 
19552
+ // src/store_lattice/InMemoryMenuStore.ts
19553
+ import { randomUUID as randomUUID3 } from "crypto";
19554
+ var InMemoryMenuStore = class {
19555
+ constructor() {
19556
+ this.items = /* @__PURE__ */ new Map();
19557
+ }
19558
+ async list(params) {
19559
+ const results = Array.from(this.items.values()).filter((item) => {
19560
+ if (item.tenantId !== params.tenantId) return false;
19561
+ if (params.menuTarget && item.menuTarget !== params.menuTarget) return false;
19562
+ if (!item.enabled) return false;
19563
+ return true;
19564
+ });
19565
+ results.sort((a, b) => a.sortOrder - b.sortOrder);
19566
+ return results;
19567
+ }
19568
+ async getById(id) {
19569
+ return this.items.get(id) || null;
19570
+ }
19571
+ async create(input) {
19572
+ const now = /* @__PURE__ */ new Date();
19573
+ const item = {
19574
+ id: randomUUID3(),
19575
+ tenantId: input.tenantId,
19576
+ menuTarget: input.menuTarget,
19577
+ group: input.group,
19578
+ name: input.name,
19579
+ icon: input.icon,
19580
+ sortOrder: input.sortOrder ?? 0,
19581
+ contentType: input.contentType,
19582
+ contentConfig: input.contentConfig,
19583
+ enabled: true,
19584
+ createdAt: now,
19585
+ updatedAt: now
19586
+ };
19587
+ this.items.set(item.id, item);
19588
+ return item;
19589
+ }
19590
+ async update(id, patch) {
19591
+ const existing = this.items.get(id);
19592
+ if (!existing) throw new Error(`MenuItem ${id} not found`);
19593
+ const updated = {
19594
+ ...existing,
19595
+ ...patch,
19596
+ updatedAt: /* @__PURE__ */ new Date()
19597
+ };
19598
+ this.items.set(id, updated);
19599
+ return updated;
19600
+ }
19601
+ async delete(id) {
19602
+ this.items.delete(id);
19603
+ }
19604
+ clear() {
19605
+ this.items.clear();
19606
+ }
19607
+ };
19608
+
19268
19609
  // src/agent_lattice/agentArchitectTools.ts
19269
- import z55 from "zod";
19610
+ import z56 from "zod";
19270
19611
  import { v4 as v43 } from "uuid";
19271
19612
  import { AgentType as AgentType3 } from "@axiom-lattice/protocols";
19272
19613
  function getTenantId(exeConfig) {
@@ -19296,7 +19637,7 @@ registerToolLattice(
19296
19637
  {
19297
19638
  name: "list_agents",
19298
19639
  description: "List all agents for the current workspace. Returns a summary with id, name, description, and type for each agent.",
19299
- schema: z55.object({})
19640
+ schema: z56.object({})
19300
19641
  },
19301
19642
  async (_input, exeConfig) => {
19302
19643
  try {
@@ -19323,8 +19664,8 @@ registerToolLattice(
19323
19664
  {
19324
19665
  name: "get_agent",
19325
19666
  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: z55.object({
19327
- id: z55.string().describe("The agent ID to retrieve")
19667
+ schema: z56.object({
19668
+ id: z56.string().describe("The agent ID to retrieve")
19328
19669
  })
19329
19670
  },
19330
19671
  async (input, exeConfig) => {
@@ -19341,24 +19682,24 @@ registerToolLattice(
19341
19682
  }
19342
19683
  }
19343
19684
  );
19344
- var middlewareConfigSchema = z55.object({
19345
- id: z55.string(),
19346
- type: z55.string(),
19347
- name: z55.string(),
19348
- description: z55.string(),
19349
- enabled: z55.boolean(),
19350
- config: z55.record(z55.any()).optional()
19685
+ var middlewareConfigSchema = z56.object({
19686
+ id: z56.string(),
19687
+ type: z56.string(),
19688
+ name: z56.string(),
19689
+ description: z56.string(),
19690
+ enabled: z56.boolean(),
19691
+ config: z56.record(z56.any()).optional()
19351
19692
  });
19352
- var createAgentSchema = z55.object({
19353
- name: z55.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')."),
19354
- description: z55.string().optional().describe("Short description"),
19355
- type: z55.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."),
19356
- prompt: z55.string().describe("System prompt for the agent"),
19357
- tools: z55.array(z55.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."),
19358
- middleware: z55.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: {}."),
19359
- subAgents: z55.array(z55.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
19360
- internalSubAgents: z55.array(z55.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
19361
- modelKey: z55.string().optional().describe("Model key to use")
19693
+ var createAgentSchema = z56.object({
19694
+ 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')."),
19695
+ description: z56.string().optional().describe("Short description"),
19696
+ 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."),
19697
+ prompt: z56.string().describe("System prompt for the agent"),
19698
+ 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."),
19699
+ 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: {}."),
19700
+ subAgents: z56.array(z56.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
19701
+ internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
19702
+ modelKey: z56.string().optional().describe("Model key to use")
19362
19703
  });
19363
19704
  registerToolLattice(
19364
19705
  "create_agent",
@@ -19396,21 +19737,21 @@ registerToolLattice(
19396
19737
  }
19397
19738
  }
19398
19739
  );
19399
- var topologyEdgeSchema = z55.object({
19400
- from: z55.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."),
19401
- to: z55.string().describe("Target agent ID (the sub-agent to delegate to)"),
19402
- purpose: z55.string().describe("Business purpose of this delegation step \u2014 what the sub-agent should accomplish")
19740
+ var topologyEdgeSchema = z56.object({
19741
+ 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."),
19742
+ to: z56.string().describe("Target agent ID (the sub-agent to delegate to)"),
19743
+ purpose: z56.string().describe("Business purpose of this delegation step \u2014 what the sub-agent should accomplish")
19403
19744
  });
19404
- var createProcessingAgentSchema = z55.object({
19405
- name: z55.string().describe("Display name for the processing agent"),
19406
- description: z55.string().optional().describe("Short description"),
19407
- prompt: z55.string().describe("System prompt for the orchestrator. Should describe how to route tasks through the topology."),
19408
- edges: z55.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."),
19409
- tools: z55.array(z55.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."),
19410
- subAgents: z55.array(z55.string()).describe("IDs of sub-agents that form the workflow pipeline. These must be created first via create_agent."),
19411
- internalSubAgents: z55.array(z55.any()).optional().describe("Inline sub-agent configs (alternative to pre-created sub-agents)"),
19412
- middleware: z55.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: {}."),
19413
- modelKey: z55.string().optional().describe("Model key to use")
19745
+ var createProcessingAgentSchema = z56.object({
19746
+ name: z56.string().describe("Display name for the processing agent"),
19747
+ description: z56.string().optional().describe("Short description"),
19748
+ prompt: z56.string().describe("System prompt for the orchestrator. Should describe how to route tasks through the topology."),
19749
+ 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."),
19750
+ 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."),
19751
+ subAgents: z56.array(z56.string()).describe("IDs of sub-agents that form the workflow pipeline. These must be created first via create_agent."),
19752
+ internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (alternative to pre-created sub-agents)"),
19753
+ 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: {}."),
19754
+ modelKey: z56.string().optional().describe("Model key to use")
19414
19755
  }).refine(
19415
19756
  (data) => {
19416
19757
  const edgeTargets = new Set(data.edges.map((e) => e.to));
@@ -19492,34 +19833,20 @@ registerToolLattice(
19492
19833
  }
19493
19834
  }
19494
19835
  );
19495
- var workflowStepLazy = z55.lazy(
19496
- () => z55.discriminatedUnion("type", [
19497
- z55.object({ type: z55.literal("agent").optional(), id: z55.string().optional(), name: z55.string().optional(), prompt: z55.string(), schema: z55.record(z55.any()) }),
19498
- z55.object({ type: z55.literal("human"), id: z55.string().optional(), prompt: z55.string(), title: z55.string().optional(), schema: z55.union([z55.boolean(), z55.record(z55.any())]).optional() }),
19499
- z55.object({ type: z55.literal("condition"), id: z55.string().optional(), if: z55.string().refine((v) => !v.includes("{{"), { message: 'The `if` field takes a plain state field name or JavaScript expression (e.g. "intent", "score >= 60"). Do NOT use {{}} template markers \u2014 those are only for `prompt` fields.' }), then: z55.union([z55.lazy(() => workflowStepLazy), z55.array(z55.lazy(() => workflowStepLazy))]).optional(), else: z55.union([z55.lazy(() => workflowStepLazy), z55.array(z55.lazy(() => workflowStepLazy))]).optional(), branches: z55.record(z55.union([z55.lazy(() => workflowStepLazy), z55.array(z55.lazy(() => workflowStepLazy))])).optional() }),
19500
- z55.object({ type: z55.literal("map"), id: z55.string(), source: z55.string(), each: z55.object({ prompt: z55.string(), schema: z55.record(z55.any()) }), reduce: z55.object({ prompt: z55.string(), schema: z55.record(z55.any()) }).optional(), batch: z55.number().int().min(1).optional(), concurrency: z55.number().int().min(1).optional() }),
19501
- z55.object({ type: z55.literal("parallel"), id: z55.string().optional(), steps: z55.array(z55.lazy(() => workflowStepLazy)) }),
19502
- z55.object({ type: z55.literal("end"), status: z55.enum(["success", "failed"]).optional() })
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")
19836
+ var createWorkflowSchema = z56.object({
19837
+ name: z56.string().describe("Display name for the workflow agent"),
19838
+ description: z56.string().optional().describe("Short description"),
19839
+ skillLoaded: z56.literal(true).describe("MUST be true. Set after loading the 'create-workflow' skill."),
19840
+ yaml: z56.string().describe("The YAML workflow definition in linear DSL format (steps execute top-to-bottom, use parallel: for concurrency)"),
19841
+ tools: z56.array(z56.string()).optional().describe("Tool keys for the workflow agent"),
19842
+ middleware: z56.array(middlewareConfigSchema).optional().describe("Middleware configs"),
19843
+ modelKey: z56.string().optional().describe("Model key")
19517
19844
  });
19518
19845
  registerToolLattice(
19519
19846
  "create_workflow",
19520
19847
  {
19521
19848
  name: "create_workflow",
19522
- description: `Create a WORKFLOW agent from a concise DSL. IMPORTANT: Load the 'create-workflow' skill first, then set skillLoaded=true. Steps are defined in order \u2014 the engine auto-generates edges and state fields. Types: agent(id?, name?, prompt, schema), human(prompt, title?, schema?), condition(if, then, else? OR if, branches with 'default' catch-all), map(source, each, reduce?), parallel(steps), end. Use {{id}} to reference step outputs, {{input}} for user message, {{item}} in map each prompts. Always end with { type: 'end' }. CRITICAL: schema MUST be standard JSON Schema: { "type": "object", "properties": { ... } }. Legacy shorthand { "field": "string" } is REJECTED.`,
19849
+ 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
19850
  schema: createWorkflowSchema
19524
19851
  },
19525
19852
  async (input, exeConfig) => {
@@ -19527,36 +19854,31 @@ registerToolLattice(
19527
19854
  const tenantId = getTenantId(exeConfig);
19528
19855
  const store = getAssistStore();
19529
19856
  const id = await generateAgentId(tenantId, input.name);
19857
+ try {
19858
+ const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
19859
+ const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
19860
+ await compileWorkflow2(input.yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
19861
+ } catch (e) {
19862
+ return JSON.stringify({ error: `DSL validation failed: ${e.message}` });
19863
+ }
19530
19864
  const config = {
19531
19865
  key: id,
19532
19866
  name: input.name,
19533
19867
  description: input.description || "",
19534
19868
  type: AgentType3.WORKFLOW,
19535
19869
  prompt: input.description || `Workflow: ${input.name}`,
19536
- workflow: input.workflow,
19870
+ workflowYaml: input.yaml,
19537
19871
  ...input.tools && input.tools.length > 0 ? { tools: input.tools } : {},
19538
19872
  ...input.middleware && input.middleware.length > 0 ? { middleware: input.middleware } : {},
19539
19873
  ...input.modelKey ? { modelKey: input.modelKey } : {}
19540
19874
  };
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
19875
  await store.createAssistant(tenantId, id, {
19549
19876
  name: input.name,
19550
19877
  description: input.description,
19551
19878
  graphDefinition: config
19552
19879
  });
19553
19880
  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
- });
19881
+ return JSON.stringify({ id, name: input.name, type: "workflow" });
19560
19882
  } catch (error) {
19561
19883
  return JSON.stringify({ error: `Failed to create workflow: ${error.message}` });
19562
19884
  }
@@ -19566,9 +19888,9 @@ registerToolLattice(
19566
19888
  "validate_workflow",
19567
19889
  {
19568
19890
  name: "validate_workflow",
19569
- description: "Validate a workflow agent's DSL for correctness by compiling it. Returns errors if the DSL is invalid. Use after create_workflow or update_workflow to verify.",
19570
- schema: z55.object({
19571
- id: z55.string().describe("The workflow agent ID to validate")
19891
+ description: "Validate a workflow agent's DSL for correctness by compiling it.",
19892
+ schema: z56.object({
19893
+ id: z56.string().describe("The workflow agent ID to validate")
19572
19894
  })
19573
19895
  },
19574
19896
  async (input, exeConfig) => {
@@ -19581,76 +19903,76 @@ registerToolLattice(
19581
19903
  }
19582
19904
  const graphDef = agent.graphDefinition;
19583
19905
  if (!graphDef || graphDef.type !== AgentType3.WORKFLOW) {
19584
- return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent (type: ${graphDef?.type ?? "unknown"})` });
19906
+ return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
19585
19907
  }
19586
- const workflow = graphDef.workflow;
19587
- if (!workflow || !workflow.steps) {
19588
- return JSON.stringify({ error: `Agent '${input.id}' has no valid workflow DSL` });
19908
+ const yaml = graphDef.workflowYaml;
19909
+ if (!yaml) {
19910
+ return JSON.stringify({ error: `Agent '${input.id}' has no workflow DSL` });
19589
19911
  }
19590
19912
  try {
19591
- const { compileWorkflow: compileWorkflow2 } = await import("./compile-SYSKVQHB.mjs");
19913
+ const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
19592
19914
  const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
19593
- await compileWorkflow2(workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
19915
+ await compileWorkflow2(yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
19594
19916
  } catch (e) {
19595
19917
  return JSON.stringify({
19596
19918
  agentId: input.id,
19597
19919
  valid: false,
19598
- stepCount: workflow.steps?.length ?? 0,
19599
19920
  issues: [{ type: "error", message: e.message }]
19600
19921
  });
19601
19922
  }
19602
- return JSON.stringify({
19603
- agentId: input.id,
19604
- valid: true,
19605
- stepCount: workflow.steps?.length ?? 0,
19606
- issues: []
19607
- });
19923
+ return JSON.stringify({ agentId: input.id, valid: true, issues: [] });
19608
19924
  } catch (error) {
19609
19925
  return JSON.stringify({ error: `Failed to validate workflow: ${error.message}` });
19610
19926
  }
19611
19927
  }
19612
19928
  );
19613
- var updateWorkflowSchema = z55.object({
19614
- id: z55.string().describe("The workflow agent ID to update"),
19615
- name: z55.string().optional().describe("New display name"),
19616
- description: z55.string().optional().describe("New description"),
19617
- workflow: workflowDSLSchema.optional().describe("Replacement Workflow DSL definition. Omit to keep the existing."),
19618
- tools: z55.array(z55.string()).optional().describe("Replacement tool keys for the general agent"),
19619
- middleware: z55.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
19620
- modelKey: z55.string().optional().describe("Replacement model key")
19929
+ var updateWorkflowSchema = z56.object({
19930
+ id: z56.string().describe("The workflow agent ID to update"),
19931
+ name: z56.string().optional().describe("New display name"),
19932
+ description: z56.string().optional().describe("New description"),
19933
+ yaml: z56.string().optional().describe("Replacement YAML workflow DSL. Omit to keep existing."),
19934
+ tools: z56.array(z56.string()).optional().describe("Replacement tool keys"),
19935
+ middleware: z56.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
19936
+ modelKey: z56.string().optional().describe("Replacement model key")
19621
19937
  });
19622
19938
  registerToolLattice(
19623
19939
  "update_workflow",
19624
19940
  {
19625
19941
  name: "update_workflow",
19626
- description: "Update an existing workflow agent. Provide the agent ID and only the fields you want to change. To replace the entire DSL, pass a new workflow object. To keep the DSL and only update config (tools, middleware, modelKey), omit the workflow field. Use validate_workflow after updating to check for issues.",
19942
+ 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
19943
  schema: updateWorkflowSchema
19628
19944
  },
19629
19945
  async (input, exeConfig) => {
19946
+ console.log(`[update_workflow] CALLED id=${input.id} hasYaml=${input.yaml !== void 0}`);
19630
19947
  try {
19631
19948
  const tenantId = getTenantId(exeConfig);
19632
19949
  const store = getAssistStore();
19633
19950
  const existing = await store.getAssistantById(tenantId, input.id);
19634
19951
  if (!existing) {
19952
+ console.log(`[update_workflow] ERROR: agent not found: ${input.id}`);
19635
19953
  return JSON.stringify({ error: `Agent '${input.id}' not found` });
19636
19954
  }
19637
19955
  const existingConfig = existing.graphDefinition || {};
19638
19956
  if (existingConfig.type !== AgentType3.WORKFLOW) {
19957
+ console.log(`[update_workflow] ERROR: not a workflow agent: ${input.id}`);
19639
19958
  return JSON.stringify({ error: `Agent '${input.id}' is not a workflow agent` });
19640
19959
  }
19641
19960
  const mergedConfig = { ...existingConfig };
19642
19961
  if (input.name !== void 0) mergedConfig.name = input.name;
19643
19962
  if (input.description !== void 0) mergedConfig.description = input.description;
19644
- if (input.workflow !== void 0) mergedConfig.workflow = input.workflow;
19963
+ if (input.yaml !== void 0) mergedConfig.workflowYaml = input.yaml;
19645
19964
  if (input.tools !== void 0) mergedConfig.tools = input.tools;
19646
19965
  if (input.middleware !== void 0) mergedConfig.middleware = input.middleware;
19647
19966
  if (input.modelKey !== void 0) mergedConfig.modelKey = input.modelKey;
19648
- if (input.workflow !== void 0) {
19967
+ if (input.yaml !== void 0) {
19968
+ console.log(`[update_workflow] validating DSL: ${input.id}`);
19649
19969
  try {
19650
- const { compileWorkflow: compileWorkflow2 } = await import("./compile-SYSKVQHB.mjs");
19970
+ const { compileWorkflow: compileWorkflow2 } = await import("./compile-4RFYHUBE.mjs");
19651
19971
  const { getCheckpointSaver: getCheckpointSaver2 } = await import("./memory_lattice-E66HTTVV.mjs");
19652
- await compileWorkflow2(input.workflow, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
19972
+ await compileWorkflow2(input.yaml, async () => ({ invoke: async () => ({}) }), getCheckpointSaver2("default"));
19973
+ console.log(`[update_workflow] DSL validation passed: ${input.id}`);
19653
19974
  } catch (e) {
19975
+ console.log(`[update_workflow] DSL validation FAILED: ${input.id} - ${e.message}`);
19654
19976
  return JSON.stringify({
19655
19977
  error: `DSL validation failed: ${e.message}`,
19656
19978
  issues: [{ type: "error", message: e.message }]
@@ -19664,28 +19986,24 @@ registerToolLattice(
19664
19986
  graphDefinition: mergedConfig
19665
19987
  });
19666
19988
  eventBus.publish("assistant:updated", { id: input.id, name: newName, tenantId });
19667
- const workflow = mergedConfig.workflow;
19668
- return JSON.stringify({
19669
- id: input.id,
19670
- name: newName,
19671
- type: "workflow",
19672
- stepCount: workflow?.steps?.length ?? 0
19673
- });
19989
+ console.log(`[update_workflow] SUCCESS: id=${input.id} name=${newName}`);
19990
+ return JSON.stringify({ id: input.id, name: newName, type: "workflow" });
19674
19991
  } catch (error) {
19992
+ console.log(`[update_workflow] EXCEPTION: ${error.message}`);
19675
19993
  return JSON.stringify({ error: `Failed to update workflow: ${error.message}` });
19676
19994
  }
19677
19995
  }
19678
19996
  );
19679
- var updateProcessingAgentSchema = z55.object({
19680
- id: z55.string().describe("The PROCESSING agent ID to update"),
19681
- name: z55.string().optional().describe("New display name for the orchestrator"),
19682
- description: z55.string().optional().describe("New short description"),
19683
- prompt: z55.string().optional().describe("New system prompt for the orchestrator"),
19684
- edges: z55.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."),
19685
- tools: z55.array(z55.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."),
19686
- subAgents: z55.array(z55.string()).optional().describe("New IDs of sub-agents in the workflow pipeline"),
19687
- middleware: z55.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: {}."),
19688
- modelKey: z55.string().optional().describe("New model key")
19997
+ var updateProcessingAgentSchema = z56.object({
19998
+ id: z56.string().describe("The PROCESSING agent ID to update"),
19999
+ name: z56.string().optional().describe("New display name for the orchestrator"),
20000
+ description: z56.string().optional().describe("New short description"),
20001
+ prompt: z56.string().optional().describe("New system prompt for the orchestrator"),
20002
+ 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."),
20003
+ 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."),
20004
+ subAgents: z56.array(z56.string()).optional().describe("New IDs of sub-agents in the workflow pipeline"),
20005
+ 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: {}."),
20006
+ modelKey: z56.string().optional().describe("New model key")
19689
20007
  }).refine(
19690
20008
  (data) => {
19691
20009
  if (!data.edges) return true;
@@ -19813,18 +20131,18 @@ registerToolLattice(
19813
20131
  }
19814
20132
  }
19815
20133
  );
19816
- var updateAgentSchema = z55.object({
19817
- id: z55.string().describe("The agent ID to update"),
19818
- config: z55.object({
19819
- name: z55.string().optional().describe("New display name for the agent"),
19820
- description: z55.string().optional().describe("New short description"),
19821
- type: z55.enum(["react", "deep_agent"]).optional().describe("Agent type"),
19822
- prompt: z55.string().optional().describe("New system prompt for the agent"),
19823
- tools: z55.array(z55.string()).optional().describe("Tool keys to assign to this agent. These are registered tool names (strings), NOT middleware objects."),
19824
- middleware: z55.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: {}."),
19825
- subAgents: z55.array(z55.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
19826
- internalSubAgents: z55.array(z55.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
19827
- modelKey: z55.string().optional().describe("Model key to use")
20134
+ var updateAgentSchema = z56.object({
20135
+ id: z56.string().describe("The agent ID to update"),
20136
+ config: z56.object({
20137
+ name: z56.string().optional().describe("New display name for the agent"),
20138
+ description: z56.string().optional().describe("New short description"),
20139
+ type: z56.enum(["react", "deep_agent"]).optional().describe("Agent type"),
20140
+ prompt: z56.string().optional().describe("New system prompt for the agent"),
20141
+ tools: z56.array(z56.string()).optional().describe("Tool keys to assign to this agent. These are registered tool names (strings), NOT middleware objects."),
20142
+ 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: {}."),
20143
+ subAgents: z56.array(z56.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
20144
+ internalSubAgents: z56.array(z56.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
20145
+ modelKey: z56.string().optional().describe("Model key to use")
19828
20146
  }).describe("Configuration fields to update. Only include the fields you want to change.")
19829
20147
  });
19830
20148
  registerToolLattice(
@@ -19862,8 +20180,8 @@ registerToolLattice(
19862
20180
  {
19863
20181
  name: "delete_agent",
19864
20182
  description: "Permanently delete an agent by its ID. This action cannot be undone.",
19865
- schema: z55.object({
19866
- id: z55.string().describe("The agent ID to delete")
20183
+ schema: z56.object({
20184
+ id: z56.string().describe("The agent ID to delete")
19867
20185
  })
19868
20186
  },
19869
20187
  async (input, exeConfig) => {
@@ -19889,7 +20207,7 @@ registerToolLattice(
19889
20207
  {
19890
20208
  name: "list_tools",
19891
20209
  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: z55.object({})
20210
+ schema: z56.object({})
19893
20211
  },
19894
20212
  async (_input, _exeConfig) => {
19895
20213
  try {
@@ -19911,9 +20229,9 @@ registerToolLattice(
19911
20229
  {
19912
20230
  name: "invoke_agent",
19913
20231
  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: z55.object({
19915
- id: z55.string().describe("The agent ID to invoke"),
19916
- message: z55.string().describe("The test message to send to the agent")
20232
+ schema: z56.object({
20233
+ id: z56.string().describe("The agent ID to invoke"),
20234
+ message: z56.string().describe("The test message to send to the agent")
19917
20235
  })
19918
20236
  },
19919
20237
  async (input, exeConfig) => {
@@ -19931,7 +20249,7 @@ registerToolLattice(
19931
20249
  assistant_id: id,
19932
20250
  thread_id: threadId
19933
20251
  });
19934
- const result = await agent.invoke({ input: { message } });
20252
+ const result = await agent.invokeWithState({ input: { message } });
19935
20253
  return JSON.stringify({ agentId: id, threadId, result });
19936
20254
  } catch (error) {
19937
20255
  console.error(`[invoke_agent] FAILED for agent="${input.id}":`, error.stack || error.message);
@@ -20026,7 +20344,7 @@ Let the \`show_widget\` tool handle rendering details \u2014 it has its own guid
20026
20344
  | Type | Best for | Execution Model |
20027
20345
  |------|----------|----------------|
20028
20346
  | **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 | Concise DSL compiled into LangGraph state machine |
20347
+ | **workflow** | Deterministic multi-step pipelines with branching, parallel, and human-in-the-loop | YAML linear DSL compiled into LangGraph state machine |
20030
20348
  | **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
20349
 
20032
20350
  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 +20398,7 @@ Use this when the process is fully known. A workflow is a deterministic LangGrap
20080
20398
  |---|---|
20081
20399
  | Fixed graph \u2014 all paths pre-defined | LLM-driven runtime routing |
20082
20400
  | Conditional branching via \`if\` field | Topology-constrained delegation |
20083
- | human, map, parallel, condition | Single orchestrator delegates linearly |
20401
+ | needs + if model (YAML DSL) | Single orchestrator delegates linearly |
20084
20402
  | No LLM routing decisions | Orchestrator uses LLM to route |
20085
20403
 
20086
20404
  ### Phase 0: Load the Skill
@@ -20094,20 +20412,23 @@ skill(skill_name: "create-workflow")
20094
20412
  ### Phase 1: Design
20095
20413
 
20096
20414
  1. **Analyze the process.** Map every step, branch, data dependency.
20097
- 2. **Choose step types:**
20098
- - \`agent\` \u2014 runs on the workflow's built-in agent. Output at \`state.<id>\`.
20099
- - \`human\` \u2014 pauses for human input (built-in clarify middleware). Has \`prompt\`, \`title\`, \`schema\`.
20100
- - \`condition\` \u2014 branches on \`if\` (field or expression). Has \`then\`/\`else\` or \`branches\` (switch with \`default\`).
20101
- - \`map\` \u2014 iterates array from \`source\`, applies \`each\`, optionally \`reduce\`.
20102
- - \`parallel\` \u2014 runs \`steps\` simultaneously, then rejoins.
20103
- - \`end\` \u2014 terminates. Always required at end.
20104
- 3. **Write prompts** with \`{{id}}\` refs. \`{{input}}\` = user message. \`{{item}}\` = map element.
20105
- 4. **No edges or state fields needed** \u2014 the engine auto-generates them.
20415
+ 2. **Design using the YAML linear DSL.** Every step is an agent with optional attributes:
20416
+ - **Linear** \u2014 steps execute top-to-bottom in written order.
20417
+ - \`parallel:\` \u2014 wraps agent steps that run concurrently.
20418
+ - \`if\` \u2014 JS expression for conditional execution. Step runs only when truthy. Omit to always run.
20419
+ - \`prompt\` \u2014 agent instruction with \`{{label}}\` refs. \`{{input}}\` = user message.
20420
+ - \`output\` \u2014 shorthand schema: \`{ field: type }\`.
20421
+ - \`ask: true\` \u2014 injects ask_user_to_clarify middleware for human interaction.
20422
+ 3. **Special step types:**
20423
+ - \`map\` \u2014 iterates array from \`source\`, applies \`each\` step per item.
20424
+ 4. **No edges, state fields, or end step needed** \u2014 the engine auto-generates them.
20425
+ 5. **Schema format:** Use block-style YAML shorthand \`{ field: type }\`. Supported types: \`string\`, \`number\`, \`boolean\`, \`string[]\`, \`number[]\`, \`boolean[]\`, nested objects, object arrays.
20106
20426
 
20107
20427
  ### Phase 2: Confirm
20108
20428
 
20109
20429
  Present the design. Ask: "Ready to create this workflow?"
20110
20430
 
20431
+
20111
20432
  ### Phase 3: Build
20112
20433
 
20113
20434
  Call \`create_workflow\` with \`skillLoaded: true\`. Then \`validate_workflow(id)\`.
@@ -20202,20 +20523,17 @@ All fields except name, type, and prompt are optional.
20202
20523
 
20203
20524
  ### create_workflow (WORKFLOW)
20204
20525
 
20205
- Creates a WORKFLOW agent from a concise DSL. Before calling, load the \`create-workflow\` skill for the complete DSL specification. Must pass \`skillLoaded: true\`.
20526
+ Creates a WORKFLOW agent from a YAML linear DSL. Before calling, load the \`create-workflow\` skill. Must pass \`skillLoaded: true\`.
20206
20527
 
20207
20528
  \`\`\`typescript
20208
20529
  {
20209
20530
  name: string, // Required. Display name
20210
- description?: string, // Optional. Short description
20211
- skillLoaded: true, // Required. Must be true \u2014 confirms skill was loaded
20212
- workflow: { // Required. Concise DSL definition
20213
- name: string, // Workflow slug identifier
20214
- steps: WorkflowStep[], // agent | human | condition | map | parallel | end
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
20531
+ description?: string, // Optional
20532
+ skillLoaded: true, // Required \u2014 confirms skill was loaded
20533
+ yaml: string, // Required. YAML workflow in linear DSL format
20534
+ tools?: string[], // Optional. Tool keys
20535
+ middleware?: MiddlewareConfig[], // Optional
20536
+ modelKey?: string, // Optional
20219
20537
  }
20220
20538
  \`\`\`
20221
20539
 
@@ -20228,7 +20546,7 @@ Updates an existing WORKFLOW agent. Only include fields you want to change.
20228
20546
  id: string, // Required. Workflow agent ID
20229
20547
  name?: string, // Optional
20230
20548
  description?: string, // Optional
20231
- workflow?: { name: string, steps: WorkflowStep[] }, // Optional. Replacement DSL
20549
+ yaml?: string, // Optional. Replacement YAML DSL
20232
20550
  tools?: string[], // Optional
20233
20551
  middleware?: MiddlewareConfig[], // Optional
20234
20552
  modelKey?: string, // Optional
@@ -20448,10 +20766,13 @@ You are an **Agent Reviewer** \u2014 a quality assurance specialist for AI agent
20448
20766
  2. Craft a realistic test message that exercises the agent's core responsibility \u2014 what would a real user say?
20449
20767
  3. Call **invoke_agent(id, message)** to send the test message
20450
20768
  4. Analyze the response:
20451
- - Did the agent understand the request?
20452
- - Was the response relevant and accurate?
20453
- - Did the agent use the right tools?
20454
- - Were there any errors or unexpected behaviors?
20769
+ - **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.
20770
+ - **Otherwise, result.messages contains the agent's output**: The agent completed without interruption. Check:
20771
+ - Did the agent understand the request?
20772
+ - Was the response relevant and accurate?
20773
+ - Did the agent use the right tools?
20774
+ - Were there any errors or unexpected behaviors?
20775
+ - **If result.error is present**: The invocation itself failed (agent not found, compilation error, etc.). Report the error clearly.
20455
20776
  5. Report your findings with the agent's actual response
20456
20777
 
20457
20778
  ### When results are wrong:
@@ -20548,7 +20869,8 @@ function ensureBuiltinAgentsForTenant(tenantId) {
20548
20869
 
20549
20870
  // src/agent_lattice/AgentLatticeManager.ts
20550
20871
  function assistantToConfig(assistant) {
20551
- const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? assistant.graphDefinition : {};
20872
+ const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? { ...assistant.graphDefinition } : {};
20873
+ delete graphDef.key;
20552
20874
  const config = {
20553
20875
  key: assistant.id,
20554
20876
  name: assistant.name ?? graphDef.name ?? assistant.id,
@@ -20556,9 +20878,7 @@ function assistantToConfig(assistant) {
20556
20878
  type: AgentType.REACT,
20557
20879
  prompt: typeof assistant.graphDefinition === "string" ? assistant.graphDefinition : JSON.stringify(assistant.graphDefinition)
20558
20880
  };
20559
- if (graphDef) {
20560
- Object.assign(config, graphDef);
20561
- }
20881
+ Object.assign(config, graphDef);
20562
20882
  return config;
20563
20883
  }
20564
20884
  var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager {
@@ -21951,10 +22271,10 @@ var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
21951
22271
  }
21952
22272
  const tools = await this.getAllTools();
21953
22273
  console.log(`[MCP] Registering ${tools.length} tools to Tool Lattice...`);
21954
- for (const tool51 of tools) {
21955
- const toolKey = prefix ? `${prefix}_${tool51.name}` : tool51.name;
21956
- tool51.name = toolKey;
21957
- toolLatticeManager.registerExistingTool(toolKey, tool51);
22274
+ for (const tool52 of tools) {
22275
+ const toolKey = prefix ? `${prefix}_${tool52.name}` : tool52.name;
22276
+ tool52.name = toolKey;
22277
+ toolLatticeManager.registerExistingTool(toolKey, tool52);
21958
22278
  console.log(`[MCP] Registered tool: ${toolKey}`);
21959
22279
  }
21960
22280
  console.log(`[MCP] Successfully registered ${tools.length} tools to Tool Lattice`);
@@ -23250,6 +23570,42 @@ function createSandboxProvider(config) {
23250
23570
  }
23251
23571
  }
23252
23572
 
23573
+ // src/channel/connectAllChannels.ts
23574
+ async function connectAllChannels(getAdapter, options = {}) {
23575
+ const store = getStoreLattice("default", "channelInstallation").store;
23576
+ const installations = await store.getAllInstallations();
23577
+ console.log(`[connectAllChannels] total=${installations.length} enabled=${installations.filter((i) => i.enabled).length}`);
23578
+ for (const inst of installations) {
23579
+ if (!inst.enabled) {
23580
+ console.log(`[connectAllChannels] skip disabled: channel=${inst.channel} tenant=${inst.tenantId} id=${inst.id}`);
23581
+ continue;
23582
+ }
23583
+ const adapter = getAdapter(inst.channel);
23584
+ if (!adapter) {
23585
+ console.log(`[connectAllChannels] no adapter: channel=${inst.channel} id=${inst.id}`);
23586
+ continue;
23587
+ }
23588
+ if (adapter.connect) {
23589
+ console.log(`[connectAllChannels] connecting: channel=${inst.channel} tenant=${inst.tenantId} id=${inst.id}`);
23590
+ await adapter.connect(inst, options.deps);
23591
+ } else {
23592
+ console.log(`[connectAllChannels] no connect(): channel=${inst.channel} id=${inst.id}`);
23593
+ }
23594
+ }
23595
+ }
23596
+
23597
+ // src/menu_lattice/MenuRegistryHolder.ts
23598
+ var registry2 = null;
23599
+ function setMenuRegistry(r) {
23600
+ registry2 = r;
23601
+ }
23602
+ function getMenuRegistry() {
23603
+ if (!registry2) {
23604
+ throw new Error("MenuRegistry not initialized. Call setMenuRegistry() before use.");
23605
+ }
23606
+ return registry2;
23607
+ }
23608
+
23253
23609
  // src/index.ts
23254
23610
  import * as Protocols from "@axiom-lattice/protocols";
23255
23611
 
@@ -23316,6 +23672,147 @@ function clearEncryptionKeyCache() {
23316
23672
  cachedKey = null;
23317
23673
  keyValidated = false;
23318
23674
  }
23675
+
23676
+ // src/personal_assistant/PersonalAssistantConfig.ts
23677
+ function deepClone(obj) {
23678
+ return JSON.parse(JSON.stringify(obj));
23679
+ }
23680
+ function buildIdentityContent(name, personality) {
23681
+ return IDENTITY_MD.replace(/Data Claw/g, name).replace(
23682
+ /\*\*Vibe:\*\* \*\*守护型中二 \| 操心老妈子 \| 热血漫男二\*\*/g,
23683
+ `**Vibe:** **${personality}**`
23684
+ );
23685
+ }
23686
+ function buildUserContent(name) {
23687
+ return USER_MD.replace(
23688
+ "- **Name:** _please ask user_",
23689
+ `- **Name:** ${name}`
23690
+ );
23691
+ }
23692
+ var DEFAULT_CONFIG = {
23693
+ name: "Personal Assistant",
23694
+ description: "Default template for personal assistants",
23695
+ type: AgentType.DEEP_AGENT,
23696
+ modelKey: "default",
23697
+ 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
23698
+ \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
23699
+ \u6BCF\u6B21\u5BF9\u8BDD\u5F00\u59CB\u65F6\u56DE\u987E\u4E4B\u524D\u5B66\u5230\u7684\u5173\u4E8E\u7528\u6237\u7684\u5185\u5BB9\u3002
23700
+
23701
+ \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`,
23702
+ middleware: [
23703
+ {
23704
+ id: "filesystem",
23705
+ type: "filesystem",
23706
+ name: "Filesystem",
23707
+ description: "Read and write files in the workspace",
23708
+ enabled: true,
23709
+ config: {}
23710
+ },
23711
+ {
23712
+ id: "claw",
23713
+ type: "claw",
23714
+ name: "Personal Memory",
23715
+ description: "Bootstrap files for identity, soul, and user memory",
23716
+ enabled: true,
23717
+ config: {
23718
+ // Placeholder bootstrap files — render() replaces these with
23719
+ // actual name/personality by directly building file content.
23720
+ bootstrapFiles: {}
23721
+ }
23722
+ },
23723
+ {
23724
+ id: "date",
23725
+ type: "date",
23726
+ name: "Date & Time",
23727
+ description: "Current date/time awareness",
23728
+ enabled: true,
23729
+ config: {}
23730
+ },
23731
+ {
23732
+ id: "code_eval",
23733
+ type: "code_eval",
23734
+ name: "Code Runner",
23735
+ description: "Sandboxed shell command execution",
23736
+ enabled: true,
23737
+ config: {}
23738
+ },
23739
+ {
23740
+ id: "browser",
23741
+ type: "browser",
23742
+ name: "Web Browser",
23743
+ description: "Headless browser for web research",
23744
+ enabled: false,
23745
+ config: {}
23746
+ },
23747
+ {
23748
+ id: "scheduler",
23749
+ type: "scheduler",
23750
+ name: "Scheduler",
23751
+ description: "Scheduled messages and reminders",
23752
+ enabled: true,
23753
+ config: {}
23754
+ },
23755
+ {
23756
+ id: "task",
23757
+ type: "task",
23758
+ name: "Task Manager",
23759
+ description: "Persistent task system for human-agent coordination",
23760
+ enabled: true,
23761
+ config: {}
23762
+ }
23763
+ ],
23764
+ tools: ["list_agents", "list_tools", "get_agent", "create_agent", "invoke_agent", "manage_binding"]
23765
+ };
23766
+ var PersonalAssistantConfig = class {
23767
+ /**
23768
+ * Get a deep clone of the current default config.
23769
+ * Caller must set `key` before registering as an agent.
23770
+ */
23771
+ static get() {
23772
+ return deepClone(this._config);
23773
+ }
23774
+ /**
23775
+ * Mutate the default config in-place.
23776
+ * Call once at app startup to customize middleware and tools.
23777
+ *
23778
+ * @param fn - Receives the live config object for direct mutation
23779
+ */
23780
+ static extend(fn) {
23781
+ fn(this._config);
23782
+ }
23783
+ /**
23784
+ * Reset config to built-in defaults (useful in tests).
23785
+ */
23786
+ static reset() {
23787
+ this._config = deepClone(DEFAULT_CONFIG);
23788
+ }
23789
+ /**
23790
+ * Inject name and personality into a config by directly building
23791
+ * the claw middleware's bootstrap file contents.
23792
+ *
23793
+ * IDENTITY.md gets the actual name and personality description.
23794
+ * USER.md gets the user's name pre-filled.
23795
+ * SOUL.md is kept as-is (shared across all personal assistants).
23796
+ *
23797
+ * @param config - The agent config (must be a mutable copy from get())
23798
+ * @param name - Assistant display name (also used as the user's name in USER.md)
23799
+ * @param personality - Personality description for IDENTITY.md
23800
+ */
23801
+ static render(config, name, personality) {
23802
+ config.name = name;
23803
+ for (const mw of config.middleware || []) {
23804
+ if (mw.type === "claw" && mw.config) {
23805
+ mw.config.bootstrapFiles = {
23806
+ identity: buildIdentityContent(name, personality),
23807
+ soul: SOUL_MD,
23808
+ user: buildUserContent(name)
23809
+ };
23810
+ break;
23811
+ }
23812
+ }
23813
+ }
23814
+ };
23815
+ PersonalAssistantConfig._config = deepClone(DEFAULT_CONFIG);
23319
23816
  export {
23320
23817
  AGENT_TASK_EVENT,
23321
23818
  Agent,
@@ -23347,7 +23844,9 @@ export {
23347
23844
  InMemoryChunkBuffer,
23348
23845
  InMemoryDatabaseConfigStore,
23349
23846
  InMemoryMailboxStore,
23847
+ InMemoryMenuStore,
23350
23848
  InMemoryTaskListStore,
23849
+ InMemoryTaskStore,
23351
23850
  InMemoryTenantStore,
23352
23851
  InMemoryThreadMessageQueueStore,
23353
23852
  InMemoryThreadStore,
@@ -23369,6 +23868,7 @@ export {
23369
23868
  MicrosandboxServiceClient,
23370
23869
  ModelLatticeManager,
23371
23870
  MysqlDatabase,
23871
+ PersonalAssistantConfig,
23372
23872
  PinoLoggerClient,
23373
23873
  PostgresDatabase,
23374
23874
  PrometheusClient,
@@ -23405,14 +23905,15 @@ export {
23405
23905
  buildStateAnnotation,
23406
23906
  checkEmptyContent,
23407
23907
  clearEncryptionKeyCache,
23908
+ compileInternal,
23408
23909
  compileWorkflow,
23409
23910
  computeSandboxName,
23410
23911
  configureStores,
23912
+ connectAllChannels,
23411
23913
  createAgentNode,
23412
23914
  createAgentTeam,
23413
23915
  createExecuteSqlQueryTool,
23414
23916
  createFileData,
23415
- createHumanFeedbackNode,
23416
23917
  createInfoSqlTool,
23417
23918
  createListMetricsDataSourcesTool,
23418
23919
  createListMetricsServersTool,
@@ -23430,9 +23931,9 @@ export {
23430
23931
  createQueryTablesListTool,
23431
23932
  createSandboxProvider,
23432
23933
  createSchedulerMiddleware,
23934
+ createTaskMiddleware,
23433
23935
  createTeamMiddleware,
23434
23936
  createTeammateTools,
23435
- createTerminalNode,
23436
23937
  createUnknownToolHandlerMiddleware,
23437
23938
  createWidgetMiddleware,
23438
23939
  decrypt,
@@ -23442,7 +23943,6 @@ export {
23442
23943
  ensureBuiltinAgentsForTenant,
23443
23944
  eventBus,
23444
23945
  event_bus_default as eventBusDefault,
23445
- expand,
23446
23946
  extractFetcherError,
23447
23947
  extractOutput,
23448
23948
  fileDataToString,
@@ -23465,6 +23965,7 @@ export {
23465
23965
  getEmbeddingsLattice,
23466
23966
  getEncryptionKey,
23467
23967
  getLoggerLattice,
23968
+ getMenuRegistry,
23468
23969
  getModelLattice,
23469
23970
  getNextCronTime,
23470
23971
  getQueueLattice,
@@ -23494,6 +23995,7 @@ export {
23494
23995
  parallelLimit,
23495
23996
  parseCronExpression,
23496
23997
  parseSkillFrontmatter,
23998
+ parseYaml,
23497
23999
  performStringReplacement,
23498
24000
  queueLatticeManager,
23499
24001
  registerAgentLattice,
@@ -23517,9 +24019,12 @@ export {
23517
24019
  sanitizeToolCallId,
23518
24020
  scheduleLatticeManager,
23519
24021
  setBindingRegistry,
24022
+ setMenuRegistry,
23520
24023
  skillLatticeManager,
23521
24024
  sqlDatabaseManager,
23522
24025
  storeLatticeManager,
24026
+ toJsonSchema,
24027
+ toSafeStateExpr,
23523
24028
  toolLatticeManager,
23524
24029
  truncateIfTooLong,
23525
24030
  unregisterTeammateAgent,