@axiom-lattice/core 2.1.100 → 2.1.103

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.js CHANGED
@@ -874,7 +874,7 @@ Output must be valid JSON in exactly this shape. Return ONLY the JSON, no other
874
874
  ${example}`;
875
875
  prompt = prompt + schemaInstruction;
876
876
  }
877
- return { messages: [new import_messages4.HumanMessage(prompt)] };
877
+ return { messages: [new import_messages5.HumanMessage(prompt)] };
878
878
  }
879
879
  function schemaToExample(schema6) {
880
880
  const example = schemaValueToExample(schema6);
@@ -1499,12 +1499,12 @@ function chunk(arr, size) {
1499
1499
  }
1500
1500
  return result;
1501
1501
  }
1502
- var import_langgraph12, import_messages4;
1502
+ var import_langgraph12, import_messages5;
1503
1503
  var init_utils = __esm({
1504
1504
  "src/workflow/utils.ts"() {
1505
1505
  "use strict";
1506
1506
  import_langgraph12 = require("@langchain/langgraph");
1507
- import_messages4 = require("@langchain/core/messages");
1507
+ import_messages5 = require("@langchain/core/messages");
1508
1508
  init_WorkflowAbortRegistry();
1509
1509
  init_parse_yaml();
1510
1510
  }
@@ -1634,7 +1634,7 @@ __export(index_exports, {
1634
1634
  ExportableEntityRegistry: () => ExportableEntityRegistry,
1635
1635
  FileSystemSkillStore: () => FileSystemSkillStore,
1636
1636
  FilesystemBackend: () => FilesystemBackend,
1637
- HumanMessage: () => import_messages6.HumanMessage,
1637
+ HumanMessage: () => import_messages7.HumanMessage,
1638
1638
  IdRemapper: () => IdRemapper,
1639
1639
  InMemoryA2AApiKeyStore: () => InMemoryA2AApiKeyStore,
1640
1640
  InMemoryAssistantStore: () => InMemoryAssistantStore,
@@ -1683,6 +1683,8 @@ __export(index_exports, {
1683
1683
  QueueMode: () => QueueMode,
1684
1684
  RemoteSandboxInstance: () => RemoteSandboxInstance,
1685
1685
  RemoteSandboxProvider: () => RemoteSandboxProvider,
1686
+ STTModelLattice: () => STTModelLattice,
1687
+ STTModelLatticeManager: () => STTModelLatticeManager,
1686
1688
  SandboxFilesystem: () => SandboxFilesystem,
1687
1689
  SandboxLatticeManager: () => SandboxLatticeManager,
1688
1690
  SandboxSkillStore: () => SandboxSkillStore,
@@ -1788,6 +1790,9 @@ __export(index_exports, {
1788
1790
  getNextCronTime: () => getNextCronTime,
1789
1791
  getOrCreateCollectionVectorStore: () => getOrCreateCollectionVectorStore,
1790
1792
  getQueueLattice: () => getQueueLattice,
1793
+ getSTTClient: () => getSTTClient,
1794
+ getSTTClientWithTenant: () => getSTTClientWithTenant,
1795
+ getSTTModelLattice: () => getSTTModelLattice,
1791
1796
  getSandBoxManager: () => getSandBoxManager,
1792
1797
  getScheduleLattice: () => getScheduleLattice,
1793
1798
  getStoreLattice: () => getStoreLattice,
@@ -1831,6 +1836,7 @@ __export(index_exports, {
1831
1836
  registerLoggerLattice: () => registerLoggerLattice,
1832
1837
  registerModelLattice: () => registerModelLattice,
1833
1838
  registerQueueLattice: () => registerQueueLattice,
1839
+ registerSTTModelLattice: () => registerSTTModelLattice,
1834
1840
  registerSandboxProviderType: () => registerSandboxProviderType,
1835
1841
  registerScheduleLattice: () => registerScheduleLattice,
1836
1842
  registerStoreLattice: () => registerStoreLattice,
@@ -1852,6 +1858,7 @@ __export(index_exports, {
1852
1858
  skillLatticeManager: () => skillLatticeManager,
1853
1859
  sqlDatabaseManager: () => sqlDatabaseManager,
1854
1860
  storeLatticeManager: () => storeLatticeManager,
1861
+ sttModelLatticeManager: () => sttModelLatticeManager,
1855
1862
  toJsonSchema: () => toJsonSchema,
1856
1863
  toSafeStateExpr: () => toSafeStateExpr,
1857
1864
  toolLatticeManager: () => toolLatticeManager,
@@ -1911,6 +1918,12 @@ var ModelLattice = class extends import_chat_models.BaseChatModel {
1911
1918
  async _generate(messages, options, runManager) {
1912
1919
  return this.llm._generate(messages, options, runManager);
1913
1920
  }
1921
+ /**
1922
+ * Whether the configured model supports vision/image inputs.
1923
+ */
1924
+ get supportsVision() {
1925
+ return this.config.supportsVision || false;
1926
+ }
1914
1927
  /**
1915
1928
  * 将工具绑定到模型
1916
1929
  * @param tools 工具列表
@@ -4479,11 +4492,17 @@ var InMemoryTaskStore = class {
4479
4492
  description: params.description,
4480
4493
  status: params.status || "pending",
4481
4494
  priority: params.priority || "medium",
4495
+ workspaceId: params.workspaceId,
4496
+ projectId: params.projectId,
4482
4497
  dueDate: params.dueDate,
4483
4498
  metadata: params.metadata,
4484
4499
  parentId: params.parentId,
4485
4500
  sourceId: params.sourceId,
4486
4501
  context: params.context,
4502
+ requireReview: params.requireReview ?? false,
4503
+ dependencies: params.dependencies,
4504
+ result: params.result,
4505
+ failureReason: params.failureReason,
4487
4506
  createdAt: now,
4488
4507
  updatedAt: now
4489
4508
  };
@@ -4509,6 +4528,8 @@ var InMemoryTaskStore = class {
4509
4528
  if (filter2.ownerId) results = results.filter((t) => t.ownerId === filter2.ownerId);
4510
4529
  if (filter2.status) results = results.filter((t) => t.status === filter2.status);
4511
4530
  if (filter2.priority) results = results.filter((t) => t.priority === filter2.priority);
4531
+ if (filter2.workspaceId) results = results.filter((t) => t.workspaceId === filter2.workspaceId);
4532
+ if (filter2.projectId) results = results.filter((t) => t.projectId === filter2.projectId);
4512
4533
  if (filter2.parentId) results = results.filter((t) => t.parentId === filter2.parentId);
4513
4534
  if (filter2.sourceId) results = results.filter((t) => t.sourceId === filter2.sourceId);
4514
4535
  if (filter2.metadata) {
@@ -4557,8 +4578,65 @@ var InMemoryTaskStore = class {
4557
4578
  }
4558
4579
  };
4559
4580
 
4560
- // src/store_lattice/InMemoryCollectionStore.ts
4581
+ // src/store_lattice/InMemoryTaskWorkItemStore.ts
4561
4582
  var import_uuid2 = require("uuid");
4583
+ var InMemoryTaskWorkItemStore = class {
4584
+ constructor() {
4585
+ this.store = /* @__PURE__ */ new Map();
4586
+ }
4587
+ /**
4588
+ * Create a new work item
4589
+ */
4590
+ async create(params) {
4591
+ const id = (0, import_uuid2.v4)();
4592
+ const item = {
4593
+ id,
4594
+ taskId: params.taskId,
4595
+ tenantId: params.tenantId,
4596
+ workspaceId: params.workspaceId,
4597
+ projectId: params.projectId,
4598
+ action: params.action,
4599
+ actor: params.actor,
4600
+ threadId: params.threadId,
4601
+ summary: params.summary,
4602
+ detail: params.detail,
4603
+ attempt: params.attempt,
4604
+ createdAt: /* @__PURE__ */ new Date()
4605
+ };
4606
+ if (!this.store.has(params.tenantId)) {
4607
+ this.store.set(params.tenantId, /* @__PURE__ */ new Map());
4608
+ }
4609
+ const tenantStore = this.store.get(params.tenantId);
4610
+ if (!tenantStore.has(params.taskId)) {
4611
+ tenantStore.set(params.taskId, []);
4612
+ }
4613
+ tenantStore.get(params.taskId).push(item);
4614
+ return item;
4615
+ }
4616
+ /**
4617
+ * List work items matching filter criteria
4618
+ */
4619
+ async list(filter2) {
4620
+ const tenantStore = this.store.get(filter2.tenantId);
4621
+ if (!tenantStore) return [];
4622
+ const items = tenantStore.get(filter2.taskId) || [];
4623
+ let result = [...items];
4624
+ if (filter2.action) {
4625
+ result = result.filter((item) => item.action === filter2.action);
4626
+ }
4627
+ result.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
4628
+ if (filter2.offset) {
4629
+ result = result.slice(filter2.offset);
4630
+ }
4631
+ if (filter2.limit) {
4632
+ result = result.slice(0, filter2.limit);
4633
+ }
4634
+ return result;
4635
+ }
4636
+ };
4637
+
4638
+ // src/store_lattice/InMemoryCollectionStore.ts
4639
+ var import_uuid3 = require("uuid");
4562
4640
  var InMemoryCollectionStore = class {
4563
4641
  constructor() {
4564
4642
  this.collections = /* @__PURE__ */ new Map();
@@ -4592,7 +4670,7 @@ var InMemoryCollectionStore = class {
4592
4670
  }
4593
4671
  const now = /* @__PURE__ */ new Date();
4594
4672
  const collection = {
4595
- id: (0, import_uuid2.v4)(),
4673
+ id: (0, import_uuid3.v4)(),
4596
4674
  tenantId: tenantId2,
4597
4675
  name: data.name,
4598
4676
  label: data.label,
@@ -4828,6 +4906,12 @@ storeLatticeManager.registerLattice(
4828
4906
  "task",
4829
4907
  defaultTaskStore
4830
4908
  );
4909
+ var defaultTaskWorkItemStore = new InMemoryTaskWorkItemStore();
4910
+ storeLatticeManager.registerLattice(
4911
+ "default",
4912
+ "taskWorkItem",
4913
+ defaultTaskWorkItemStore
4914
+ );
4831
4915
  var defaultCollectionStore = new InMemoryCollectionStore();
4832
4916
  storeLatticeManager.registerLattice(
4833
4917
  "default",
@@ -8909,7 +8993,7 @@ var createBrowserGetInfoTool = ({ vmIsolation }) => {
8909
8993
  };
8910
8994
 
8911
8995
  // src/index.ts
8912
- var import_messages6 = require("@langchain/core/messages");
8996
+ var import_messages7 = require("@langchain/core/messages");
8913
8997
 
8914
8998
  // src/agent_lattice/types.ts
8915
8999
  var import_protocols = require("@axiom-lattice/protocols");
@@ -9538,6 +9622,309 @@ var StateBackend = class {
9538
9622
  }
9539
9623
  };
9540
9624
 
9625
+ // src/deep_agent_new/backends/imageUtils.ts
9626
+ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
9627
+ ".png",
9628
+ ".jpg",
9629
+ ".jpeg",
9630
+ ".gif",
9631
+ ".webp",
9632
+ ".bmp",
9633
+ ".svg",
9634
+ ".ico",
9635
+ ".tiff",
9636
+ ".tif"
9637
+ ]);
9638
+ var MIME_MAP = {
9639
+ ".png": "image/png",
9640
+ ".jpg": "image/jpeg",
9641
+ ".jpeg": "image/jpeg",
9642
+ ".gif": "image/gif",
9643
+ ".webp": "image/webp",
9644
+ ".bmp": "image/bmp",
9645
+ ".svg": "image/svg+xml",
9646
+ ".ico": "image/x-icon",
9647
+ ".tiff": "image/tiff",
9648
+ ".tif": "image/tiff"
9649
+ };
9650
+ function isImageFile(filePath) {
9651
+ const ext = filePath.toLowerCase().slice(filePath.lastIndexOf("."));
9652
+ return IMAGE_EXTENSIONS.has(ext);
9653
+ }
9654
+ function detectMimeType(filePath) {
9655
+ const ext = filePath.toLowerCase().slice(filePath.lastIndexOf("."));
9656
+ return MIME_MAP[ext] || "application/octet-stream";
9657
+ }
9658
+ var MAX_IMAGE_SIZE = 50 * 1024 * 1024;
9659
+ function validateImageSize(sizeBytes) {
9660
+ if (sizeBytes > MAX_IMAGE_SIZE) {
9661
+ return `Image too large (${(sizeBytes / 1024 / 1024).toFixed(1)}MB). Maximum is 50MB.`;
9662
+ }
9663
+ return null;
9664
+ }
9665
+
9666
+ // src/deep_agent_new/backends/audioUtils.ts
9667
+ var AUDIO_EXTENSIONS = /* @__PURE__ */ new Set([
9668
+ ".webm",
9669
+ ".wav",
9670
+ ".mp3",
9671
+ ".m4a",
9672
+ ".ogg",
9673
+ ".flac",
9674
+ ".aac",
9675
+ ".wma",
9676
+ ".opus",
9677
+ ".amr"
9678
+ ]);
9679
+ function isAudioFile(filePath) {
9680
+ const ext = filePath.toLowerCase().slice(filePath.lastIndexOf("."));
9681
+ return AUDIO_EXTENSIONS.has(ext);
9682
+ }
9683
+ function detectAudioFormat(filePath) {
9684
+ return filePath.toLowerCase().slice(filePath.lastIndexOf(".") + 1);
9685
+ }
9686
+ var MAX_AUDIO_SIZE = 25 * 1024 * 1024;
9687
+ function validateAudioSize(sizeBytes) {
9688
+ if (sizeBytes > MAX_AUDIO_SIZE) {
9689
+ return `Audio file too large (${(sizeBytes / 1024 / 1024).toFixed(1)}MB). Maximum is 25MB.`;
9690
+ }
9691
+ return null;
9692
+ }
9693
+
9694
+ // src/deep_agent_new/backends/describeImage.ts
9695
+ var import_messages = require("@langchain/core/messages");
9696
+ async function describeImage(options) {
9697
+ const { modelKey, mimeType, base64, prompt } = options;
9698
+ const { client } = modelLatticeManager.getModelLattice(modelKey);
9699
+ if (!client.supportsVision) {
9700
+ throw new Error(`Model "${modelKey}" does not support vision.`);
9701
+ }
9702
+ const result = await client.invoke([
9703
+ new import_messages.HumanMessage({
9704
+ content: [
9705
+ {
9706
+ type: "text",
9707
+ text: prompt || "Please describe this image in detail."
9708
+ },
9709
+ {
9710
+ type: "image_url",
9711
+ image_url: { url: `data:${mimeType};base64,${base64}` }
9712
+ }
9713
+ ]
9714
+ })
9715
+ ]);
9716
+ return result.content || "";
9717
+ }
9718
+
9719
+ // src/stt_model_lattice/STTModelLatticeManager.ts
9720
+ init_BaseLatticeManager();
9721
+
9722
+ // src/stt_model_lattice/STTModelLattice.ts
9723
+ var import_openai2 = require("@langchain/openai");
9724
+ var STTModelLattice = class {
9725
+ constructor(key4, config) {
9726
+ this.key = key4;
9727
+ this.config = config;
9728
+ this.client = this;
9729
+ const apiKey = config.apiKey || (config.apiKeyEnvName ? process.env[config.apiKeyEnvName] : void 0) || process.env.OPENAI_API_KEY || "";
9730
+ if (!apiKey) {
9731
+ throw new Error("No API key configured for STT. Set apiKey, apiKeyEnvName, or OPENAI_API_KEY.");
9732
+ }
9733
+ this.openaiClient = new import_openai2.OpenAIClient({
9734
+ apiKey,
9735
+ baseURL: config.baseURL,
9736
+ timeout: config.timeout || 3e4
9737
+ });
9738
+ }
9739
+ /**
9740
+ * Transcribe audio buffer to text.
9741
+ * Routes to whisper or chat API mode based on config.
9742
+ */
9743
+ async transcribe(audio, format) {
9744
+ const mode = this.config.apiMode || "whisper";
9745
+ if (mode === "chat") {
9746
+ return this.transcribeViaChat(audio, format);
9747
+ }
9748
+ return this.transcribeViaWhisper(audio, format);
9749
+ }
9750
+ /**
9751
+ * Transcribe via OpenAI /v1/audio/transcriptions endpoint (multipart).
9752
+ */
9753
+ async transcribeViaWhisper(audio, format) {
9754
+ const mimeType = formatToMimeType(format);
9755
+ const file = typeof File !== "undefined" ? new File([audio], `audio.${format}`, { type: mimeType }) : await (0, import_openai2.toFile)(audio, `audio.${format}`, { type: mimeType });
9756
+ const extra = this.config.extra || {};
9757
+ const response = await this.openaiClient.audio.transcriptions.create({
9758
+ file,
9759
+ model: this.config.model || "whisper-1",
9760
+ response_format: "verbose_json",
9761
+ ...extra
9762
+ });
9763
+ const result = response;
9764
+ return {
9765
+ text: result.text,
9766
+ segments: result.segments?.map((s) => ({
9767
+ start: s.start,
9768
+ end: s.end,
9769
+ text: s.text
9770
+ })),
9771
+ confidence: result.segments ? result.segments.reduce((sum, s) => sum + Math.exp(s.avg_logprob ?? -Infinity), 0) / result.segments.length : void 0
9772
+ };
9773
+ }
9774
+ /**
9775
+ * Transcribe via OpenAI /v1/chat/completions with input_audio.
9776
+ * Used by Qwen3-ASR-Flash and similar audio-via-chat models.
9777
+ */
9778
+ async transcribeViaChat(audio, format) {
9779
+ const mimeType = formatToMimeType(format);
9780
+ const dataUri = `data:${mimeType};base64,${audio.toString("base64")}`;
9781
+ const extra = this.config.extra || {};
9782
+ const response = await this.openaiClient.chat.completions.create({
9783
+ model: this.config.model || "qwen3-asr-flash",
9784
+ messages: [
9785
+ {
9786
+ role: "user",
9787
+ content: [
9788
+ {
9789
+ type: "input_audio",
9790
+ input_audio: {
9791
+ data: dataUri,
9792
+ format
9793
+ }
9794
+ }
9795
+ ]
9796
+ }
9797
+ ],
9798
+ ...extra
9799
+ });
9800
+ const result = response;
9801
+ const text = result.choices?.[0]?.message?.content || "";
9802
+ return { text };
9803
+ }
9804
+ };
9805
+ function formatToMimeType(format) {
9806
+ const mimeTypes = {
9807
+ webm: "audio/webm",
9808
+ wav: "audio/wav",
9809
+ mp3: "audio/mpeg",
9810
+ m4a: "audio/mp4",
9811
+ ogg: "audio/ogg",
9812
+ flac: "audio/flac",
9813
+ aac: "audio/aac"
9814
+ };
9815
+ const lower = format.toLowerCase();
9816
+ if (!mimeTypes[lower]) {
9817
+ console.warn(`Unknown STT audio format "${format}", falling back to audio/webm`);
9818
+ }
9819
+ return mimeTypes[lower] || "audio/webm";
9820
+ }
9821
+
9822
+ // src/stt_model_lattice/STTModelLatticeManager.ts
9823
+ var STTModelLatticeManager = class _STTModelLatticeManager extends BaseLatticeManager {
9824
+ static getInstance() {
9825
+ if (!_STTModelLatticeManager._instance) {
9826
+ _STTModelLatticeManager._instance = new _STTModelLatticeManager();
9827
+ }
9828
+ return _STTModelLatticeManager._instance;
9829
+ }
9830
+ getLatticeType() {
9831
+ return "stt";
9832
+ }
9833
+ /**
9834
+ * Register an STT model lattice.
9835
+ * @param key - Lattice key name
9836
+ * @param config - STT provider configuration
9837
+ */
9838
+ registerLattice(key4, config) {
9839
+ const client = new STTModelLattice(key4, config);
9840
+ const label = config.model || key4;
9841
+ const sttLattice = {
9842
+ key: key4,
9843
+ client,
9844
+ config,
9845
+ label
9846
+ };
9847
+ this.register(key4, sttLattice);
9848
+ }
9849
+ /**
9850
+ * Get an STT model lattice by key.
9851
+ */
9852
+ getSTTModelLattice(key4) {
9853
+ const lattice = this.get(key4);
9854
+ if (!lattice) {
9855
+ throw new Error(`STTModelLattice "${key4}" not found`);
9856
+ }
9857
+ return lattice;
9858
+ }
9859
+ /**
9860
+ * Get STT client instance by key (default tenant).
9861
+ */
9862
+ getSTTClient(key4) {
9863
+ return this.getSTTModelLattice(key4).client;
9864
+ }
9865
+ /**
9866
+ * Get STT client instance by key and tenant.
9867
+ * @param tenantId - Tenant ID for isolation
9868
+ * @param key - Lattice key name
9869
+ */
9870
+ getSTTClientWithTenant(tenantId2, key4) {
9871
+ let lattice = this.getWithTenant(tenantId2, key4);
9872
+ if (!lattice && tenantId2 !== "default") {
9873
+ lattice = this.getWithTenant("default", key4);
9874
+ }
9875
+ if (!lattice) {
9876
+ throw new Error(`STTModelLattice "${key4}" not found for tenant "${tenantId2}"`);
9877
+ }
9878
+ return lattice.client;
9879
+ }
9880
+ /**
9881
+ * Get all registered STT models as info list.
9882
+ */
9883
+ getAllSTTModelInfo() {
9884
+ return this.getAllLattices().map((l) => ({
9885
+ key: l.key,
9886
+ label: l.label,
9887
+ provider: l.config.provider || "openai-compatible",
9888
+ model: l.config.model || "unknown"
9889
+ }));
9890
+ }
9891
+ getAllLattices() {
9892
+ return this.getAll();
9893
+ }
9894
+ hasLattice(key4) {
9895
+ return this.has(key4);
9896
+ }
9897
+ removeLattice(key4) {
9898
+ return this.remove(key4);
9899
+ }
9900
+ clearLattices() {
9901
+ this.clear();
9902
+ }
9903
+ getLatticeCount() {
9904
+ return this.count();
9905
+ }
9906
+ getLatticeKeys() {
9907
+ return this.keys();
9908
+ }
9909
+ };
9910
+ var sttModelLatticeManager = STTModelLatticeManager.getInstance();
9911
+ var registerSTTModelLattice = (key4, config) => sttModelLatticeManager.registerLattice(key4, config);
9912
+ var getSTTModelLattice = (key4) => sttModelLatticeManager.getSTTModelLattice(key4);
9913
+ var getSTTClient = (key4) => sttModelLatticeManager.getSTTClient(key4);
9914
+ var getSTTClientWithTenant = (tenantId2, key4) => sttModelLatticeManager.getSTTClientWithTenant(tenantId2, key4);
9915
+
9916
+ // src/deep_agent_new/backends/transcribeAudio.ts
9917
+ async function transcribeAudio(options) {
9918
+ const { audioBuffer, format } = options;
9919
+ if (!sttModelLatticeManager.hasLattice("default")) {
9920
+ throw new Error(
9921
+ "No default STT model registered. Use registerSTTModelLattice('default', { ... }) first."
9922
+ );
9923
+ }
9924
+ const client = sttModelLatticeManager.getSTTClient("default");
9925
+ return await client.transcribe(audioBuffer, format);
9926
+ }
9927
+
9541
9928
  // src/deep_agent_new/middleware/fs.ts
9542
9929
  var FileDataSchema = import_v3.z.object({
9543
9930
  content: import_v3.z.array(import_v3.z.string()),
@@ -9596,7 +9983,7 @@ Path conventions:
9596
9983
  - glob: find files matching a pattern (e.g., "/project/**/*.py")
9597
9984
  - grep: search for text within files`;
9598
9985
  var LS_TOOL_DESCRIPTION = "List files and directories in a directory";
9599
- var READ_FILE_TOOL_DESCRIPTION = "Read the contents of a file";
9986
+ var READ_FILE_TOOL_DESCRIPTION = "Read the contents of a file. For image files (png, jpg, gif, webp, bmp, svg), returns a visual description when the current model supports vision; otherwise returns an error suggesting a vision-capable model. For audio files (webm, wav, mp3, m4a, ogg, flac, aac, wma, opus, amr), transcribes the content using the default STT model; if none is registered, returns an error with registration instructions.";
9600
9987
  var WRITE_FILE_TOOL_DESCRIPTION = "Write content to a new file. Returns an error if the file already exists";
9601
9988
  var EDIT_FILE_TOOL_DESCRIPTION = "Edit a file by replacing a specific string with a new string";
9602
9989
  var GLOB_TOOL_DESCRIPTION = "Find files matching a glob pattern (e.g., '**/*.py' for all Python files)";
@@ -9649,6 +10036,66 @@ function createReadFileTool(backend, options) {
9649
10036
  };
9650
10037
  const resolvedBackend = await getBackend(backend, stateAndStore);
9651
10038
  const { file_path, offset = 0, limit = 2e3 } = input;
10039
+ if (isImageFile(file_path)) {
10040
+ const modelKey = runConfig?.modelConfig?.modelKey || "default";
10041
+ const { client } = modelLatticeManager.getModelLattice(modelKey);
10042
+ if (!client.supportsVision) {
10043
+ return `[\u56FE\u7247] ${file_path}
10044
+ \u5F53\u524D\u6A21\u578B "${modelKey}" \u4E0D\u652F\u6301\u89C6\u89C9\u80FD\u529B\uFF0C\u65E0\u6CD5\u8BFB\u53D6\u56FE\u7247\u5185\u5BB9\u3002\u8BF7\u5207\u6362\u5230\u652F\u6301\u591A\u6A21\u6001\u7684\u6A21\u578B\uFF08\u5982 GPT-4o\uFF09\u3002`;
10045
+ }
10046
+ if (!resolvedBackend.readBinary) {
10047
+ return `[\u56FE\u7247] ${file_path}
10048
+ \u5F53\u524D\u540E\u7AEF\u4E0D\u652F\u6301\u4E8C\u8FDB\u5236\u8BFB\u53D6\uFF0C\u65E0\u6CD5\u5904\u7406\u56FE\u7247\u3002`;
10049
+ }
10050
+ try {
10051
+ const buffer2 = await resolvedBackend.readBinary(file_path);
10052
+ const sizeWarning = validateImageSize(buffer2.length);
10053
+ if (sizeWarning) {
10054
+ return `[\u56FE\u7247] ${file_path}
10055
+ ${sizeWarning}`;
10056
+ }
10057
+ const mimeType = detectMimeType(file_path);
10058
+ const description = await describeImage({
10059
+ modelKey,
10060
+ mimeType,
10061
+ base64: buffer2.toString("base64")
10062
+ });
10063
+ return `[\u56FE\u7247] ${file_path}\uFF08${mimeType}\uFF0C${(buffer2.length / 1024).toFixed(1)}KB\uFF09
10064
+
10065
+ ${description}`;
10066
+ } catch (error) {
10067
+ return `[\u56FE\u7247] ${file_path}
10068
+ \u8BFB\u53D6\u56FE\u7247\u5931\u8D25\uFF1A${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`;
10069
+ }
10070
+ }
10071
+ if (isAudioFile(file_path)) {
10072
+ if (!resolvedBackend.readBinary) {
10073
+ return `[Audio] ${file_path}
10074
+ The current backend does not support binary reading, unable to process audio.`;
10075
+ }
10076
+ try {
10077
+ const buffer2 = await resolvedBackend.readBinary(file_path);
10078
+ const sizeWarning = validateAudioSize(buffer2.length);
10079
+ if (sizeWarning) {
10080
+ return `[Audio] ${file_path}
10081
+ ${sizeWarning}`;
10082
+ }
10083
+ const format = detectAudioFormat(file_path);
10084
+ const result = await transcribeAudio({ audioBuffer: buffer2, format });
10085
+ let output = `[Audio] ${file_path} (${format}, ${(buffer2.length / 1024).toFixed(1)}KB)`;
10086
+ if (result.confidence !== void 0) {
10087
+ output += `
10088
+ Confidence: ${(result.confidence * 100).toFixed(1)}%`;
10089
+ }
10090
+ output += `
10091
+
10092
+ ${result.text}`;
10093
+ return output;
10094
+ } catch (error) {
10095
+ return `[Audio] ${file_path}
10096
+ Audio transcription failed: ${error instanceof Error ? error.message : "Unknown error"}`;
10097
+ }
10098
+ }
9652
10099
  return await resolvedBackend.read(file_path, offset, limit);
9653
10100
  },
9654
10101
  {
@@ -10697,7 +11144,7 @@ var clawPlugin = {
10697
11144
 
10698
11145
  // src/middlewares/unknownToolHandlerMiddleware.ts
10699
11146
  var import_langchain44 = require("langchain");
10700
- var import_messages = require("@langchain/core/messages");
11147
+ var import_messages2 = require("@langchain/core/messages");
10701
11148
  function createUnknownToolHandlerMiddleware(config = {}) {
10702
11149
  const {
10703
11150
  strategy = "error",
@@ -10747,7 +11194,7 @@ Please select a valid tool from the list above.`
10747
11194
  toolCallId: toolCall.id,
10748
11195
  errorMessage: errorMessageTemplate(toolCall.name, availableToolNames)
10749
11196
  }));
10750
- const modifiedResponse = new import_messages.AIMessage({
11197
+ const modifiedResponse = new import_messages2.AIMessage({
10751
11198
  content: aiResponse.content,
10752
11199
  tool_calls: aiResponse.tool_calls,
10753
11200
  // Key: preserve all tool_calls, don't delete unknown
@@ -10778,7 +11225,7 @@ Please select a valid tool from the list above.`
10778
11225
  return;
10779
11226
  }
10780
11227
  const lastMessage = messages[messages.length - 1];
10781
- if (!import_messages.AIMessage.isInstance(lastMessage)) {
11228
+ if (!import_messages2.AIMessage.isInstance(lastMessage)) {
10782
11229
  return;
10783
11230
  }
10784
11231
  const unknownToolErrors = lastMessage.response_metadata?._unknownToolErrors;
@@ -10786,7 +11233,7 @@ Please select a valid tool from the list above.`
10786
11233
  return;
10787
11234
  }
10788
11235
  const errorToolMessages = unknownToolErrors.map(
10789
- (error) => new import_messages.ToolMessage({
11236
+ (error) => new import_messages2.ToolMessage({
10790
11237
  content: error.errorMessage,
10791
11238
  name: error.toolName,
10792
11239
  tool_call_id: error.toolCallId,
@@ -11242,19 +11689,13 @@ var SandboxFilesystem = class {
11242
11689
  throw new Error(`Error reading file '${filePath}': ${e.message}`);
11243
11690
  }
11244
11691
  }
11692
+ async readBinary(filePath) {
11693
+ return this.sandbox.file.downloadFile({ file: filePath });
11694
+ }
11245
11695
  async write(filePath, content) {
11246
11696
  try {
11247
11697
  await this.sandbox.file.writeFile(filePath, content);
11248
- return {
11249
- path: filePath,
11250
- filesUpdate: {
11251
- [filePath]: {
11252
- content: content.split("\n"),
11253
- created_at: (/* @__PURE__ */ new Date()).toISOString(),
11254
- modified_at: (/* @__PURE__ */ new Date()).toISOString()
11255
- }
11256
- }
11257
- };
11698
+ return { path: filePath, filesUpdate: null };
11258
11699
  } catch (e) {
11259
11700
  throw new Error(`Error writing file '${filePath}': ${e.message}`);
11260
11701
  }
@@ -11268,10 +11709,7 @@ var SandboxFilesystem = class {
11268
11709
  new_str: newString,
11269
11710
  replace_mode: replaceAll ? "ALL" : "FIRST"
11270
11711
  });
11271
- return {
11272
- path: filePath,
11273
- filesUpdate: null
11274
- };
11712
+ return { path: filePath, filesUpdate: null };
11275
11713
  } catch (e) {
11276
11714
  throw new Error(`Error editing file '${filePath}': ${e.message}`);
11277
11715
  }
@@ -11368,13 +11806,13 @@ var ReActAgentGraphBuilder = class {
11368
11806
  };
11369
11807
 
11370
11808
  // src/deep_agent_new/agent.ts
11371
- var import_langchain52 = require("langchain");
11809
+ var import_langchain53 = require("langchain");
11372
11810
 
11373
11811
  // src/deep_agent_new/middleware/subagents.ts
11374
11812
  var import_v32 = require("zod/v3");
11375
- var import_langchain47 = require("langchain");
11813
+ var import_langchain48 = require("langchain");
11376
11814
  var import_langgraph7 = require("@langchain/langgraph");
11377
- var import_messages2 = require("@langchain/core/messages");
11815
+ var import_messages3 = require("@langchain/core/messages");
11378
11816
 
11379
11817
  // src/agent_worker/agent_worker_graph.ts
11380
11818
  var import_langgraph5 = require("@langchain/langgraph");
@@ -12101,7 +12539,7 @@ var buffer = new InMemoryChunkBuffer({
12101
12539
  registerChunkBuffer("default", buffer);
12102
12540
 
12103
12541
  // src/services/Agent.ts
12104
- var import_uuid3 = require("uuid");
12542
+ var import_uuid4 = require("uuid");
12105
12543
  var ThreadStatus2 = /* @__PURE__ */ ((ThreadStatus3) => {
12106
12544
  ThreadStatus3["IDLE"] = "idle";
12107
12545
  ThreadStatus3["BUSY"] = "busy";
@@ -12147,7 +12585,7 @@ var Agent = class {
12147
12585
  runConfig
12148
12586
  },
12149
12587
  configurable: {
12150
- run_id: (0, import_uuid3.v4)(),
12588
+ run_id: (0, import_uuid4.v4)(),
12151
12589
  ...runConfig,
12152
12590
  runConfig
12153
12591
  },
@@ -12220,7 +12658,7 @@ var Agent = class {
12220
12658
  runConfig
12221
12659
  },
12222
12660
  configurable: {
12223
- run_id: (0, import_uuid3.v4)(),
12661
+ run_id: (0, import_uuid4.v4)(),
12224
12662
  ...runConfig,
12225
12663
  runConfig
12226
12664
  // Inject runConfig for tools to access
@@ -12606,7 +13044,7 @@ var Agent = class {
12606
13044
  };
12607
13045
  }
12608
13046
  async invoke(queueMessage, signal) {
12609
- const messageId = (0, import_uuid3.v4)();
13047
+ const messageId = (0, import_uuid4.v4)();
12610
13048
  const input = {
12611
13049
  ...queueMessage.input,
12612
13050
  messages: [new import_langchain46.HumanMessage({ id: messageId, content: queueMessage.input.message })]
@@ -12625,7 +13063,7 @@ var Agent = class {
12625
13063
  * to avoid exposing internal annotation data.
12626
13064
  */
12627
13065
  async invokeWithState(queueMessage, signal) {
12628
- const messageId = (0, import_uuid3.v4)();
13066
+ const messageId = (0, import_uuid4.v4)();
12629
13067
  const input = {
12630
13068
  ...queueMessage.input,
12631
13069
  messages: [new import_langchain46.HumanMessage({ id: messageId, content: queueMessage.input.message })]
@@ -12641,7 +13079,7 @@ var Agent = class {
12641
13079
  {
12642
13080
  context: { runConfig },
12643
13081
  configurable: {
12644
- run_id: (0, import_uuid3.v4)(),
13082
+ run_id: (0, import_uuid4.v4)(),
12645
13083
  ...runConfig,
12646
13084
  runConfig
12647
13085
  },
@@ -12817,7 +13255,7 @@ var Agent = class {
12817
13255
  */
12818
13256
  async addMessage(queueMessage, mode) {
12819
13257
  const useMode = mode ?? this.queueMode.mode;
12820
- const messageId = queueMessage.input.id || (0, import_uuid3.v4)();
13258
+ const messageId = queueMessage.input.id || (0, import_uuid4.v4)();
12821
13259
  const messages = queueMessage.input.messages;
12822
13260
  const legacyMessage = queueMessage.input.message;
12823
13261
  if (!messages && !legacyMessage) {
@@ -13309,74 +13747,416 @@ var AgentInstanceManager = class _AgentInstanceManager {
13309
13747
  };
13310
13748
  var agentInstanceManager = AgentInstanceManager.getInstance();
13311
13749
 
13312
- // src/deep_agent_new/middleware/subagents.ts
13313
- var DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools.";
13314
- var EXCLUDED_STATE_KEYS = ["messages", "todos", "jumpTo"];
13315
- var DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.";
13316
- function getTaskToolDescription(subagentDescriptions) {
13317
- return subagentDescriptions.length > 0 ? `
13318
- Launch an ephemeral subagent to handle complex, multi-step independent tasks with isolated context windows.
13319
-
13320
- Available agent types and the tools they have access to:
13321
- ${subagentDescriptions.join("\n")}
13322
-
13323
- When using the Task tool, you must specify a subagent_type parameter to select which agent type to use.
13324
-
13325
- ## Usage notes:
13326
- 1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
13327
- 2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
13328
- 3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.
13329
- 4. The agent's outputs should generally be trusted
13330
- 5. Clearly tell the agent whether you expect it to create content, perform analysis, or just do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent
13331
- 6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
13332
- 7. When only the general-purpose agent is provided, you should use it for all tasks. It is great for isolating context and token usage, and completing specific, complex tasks, as it has all the same capabilities as the main agent.
13333
-
13334
- ### Example usage of the general-purpose agent:
13335
-
13336
- <example_agent_descriptions>
13337
- "general-purpose": use this agent for general purpose tasks, it has access to all tools as the main agent.
13338
- </example_agent_descriptions>
13339
-
13340
- <example>
13341
- User: "I want to conduct research on the accomplishments of Lebron James, Michael Jordan, and Kobe Bryant, and then compare them."
13342
- Assistant: *Uses the task tool in parallel to conduct isolated research on each of the three players*
13343
- Assistant: *Synthesizes the results of the three isolated research tasks and responds to the User*
13344
- <commentary>
13345
- Research is a complex, multi-step task in it of itself.
13346
- The research of each individual player is not dependent on the research of the other players.
13347
- The assistant uses the task tool to break down the complex objective into three isolated tasks.
13348
- Each research task only needs to worry about context and tokens about one player, then returns synthesized information about each player as the Tool Result.
13349
- This means each research task can dive deep and spend tokens and context deeply researching each player, but the final result is synthesized information, and saves us tokens in the long run when comparing the players to each other.
13350
- </commentary>
13351
- </example>
13352
-
13353
- <example>
13354
- User: "Analyze a single large code repository for security vulnerabilities and generate a report."
13355
- Assistant: *Launches a single \`task\` subagent for the repository analysis*
13356
- Assistant: *Receives report and integrates results into final summary*
13357
- <commentary>
13358
- Subagent is used to isolate a large, context-heavy task, even though there is only one. This prevents the main thread from being overloaded with details.
13359
- If the user then asks followup questions, we have a concise report to reference instead of the entire history of analysis and tool calls, which is good and saves us time and money.
13360
- </commentary>
13361
- </example>
13362
-
13363
- <example>
13364
- User: "Schedule two meetings for me and prepare agendas for each."
13365
- Assistant: *Calls the task tool in parallel to launch two \`task\` subagents (one per meeting) to prepare agendas*
13366
- Assistant: *Returns final schedules and agendas*
13367
- <commentary>
13368
- Tasks are simple individually, but subagents help silo agenda preparation.
13369
- Each subagent only needs to worry about the agenda for one meeting.
13370
- </commentary>
13371
- </example>
13372
-
13373
- <example>
13374
- User: "I want to order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway."
13375
- Assistant: *Calls tools directly in parallel to order a pizza from Dominos, a burger from McDonald's, and a salad from Subway*
13376
- <commentary>
13377
- The assistant did not use the task tool because the objective is super simple and clear and only requires a few trivial tool calls.
13378
- It is better to just complete the task directly and NOT use the \`task\`tool.
13379
- </commentary>
13750
+ // src/middlewares/taskMiddleware.ts
13751
+ var import_langchain47 = require("langchain");
13752
+ var import_zod44 = require("zod");
13753
+ function getRunConfig(config) {
13754
+ const c = config;
13755
+ return c?.configurable?.runConfig ?? {};
13756
+ }
13757
+ function getTaskStore() {
13758
+ return getStoreLattice("default", "task").store;
13759
+ }
13760
+ var VALID_TRANSITIONS = {
13761
+ pending: ["in_progress", "cancelled"],
13762
+ in_progress: ["completed", "review", "failed", "interrupted", "cancelled"],
13763
+ review: ["completed", "in_progress", "cancelled"],
13764
+ failed: ["in_progress", "cancelled"],
13765
+ interrupted: ["in_progress", "cancelled"],
13766
+ completed: [],
13767
+ cancelled: []
13768
+ };
13769
+ function isValidTransition(from, to) {
13770
+ const allowed = VALID_TRANSITIONS[from];
13771
+ if (!allowed) return false;
13772
+ return allowed.includes(to);
13773
+ }
13774
+ function getTaskWorkItemStore() {
13775
+ return getStoreLattice("default", "taskWorkItem").store;
13776
+ }
13777
+ var manageTaskSchema = import_zod44.z.object({
13778
+ action: import_zod44.z.enum(["create", "list", "update", "delete"]).describe("Action to perform. Available: create, list, update, delete. To mark a task complete, use update with status='completed'"),
13779
+ id: import_zod44.z.string().optional().describe("Task ID (required for update and delete)"),
13780
+ title: import_zod44.z.string().optional().describe("Task title (required for create)"),
13781
+ description: import_zod44.z.string().optional().describe("Task description in Markdown"),
13782
+ priority: import_zod44.z.enum(["low", "medium", "high"]).optional().describe("Priority level"),
13783
+ status: import_zod44.z.enum(["pending", "in_progress", "review", "failed", "interrupted", "completed", "cancelled"]).optional().describe("Task status"),
13784
+ dueDate: import_zod44.z.string().optional().describe("Due date (ISO 8601 format)"),
13785
+ metadata: import_zod44.z.record(import_zod44.z.unknown()).optional().describe("Structured metadata (e.g. projectId, module)"),
13786
+ parentId: import_zod44.z.string().optional().describe("Parent task ID for grouping subtasks"),
13787
+ sourceId: import_zod44.z.string().optional().describe("Source session/thread ID"),
13788
+ context: import_zod44.z.record(import_zod44.z.unknown()).optional().describe("Additional context data"),
13789
+ ownerType: import_zod44.z.enum(["user", "agent"]).optional().describe("Owner type. Defaults to 'user' if omitted"),
13790
+ ownerId: import_zod44.z.string().optional().describe("Owner ID. Auto-filled from current user/agent if omitted"),
13791
+ requireReview: import_zod44.z.boolean().optional().describe("If true, completing sends task to 'review' status instead of 'completed'"),
13792
+ dependencies: import_zod44.z.array(import_zod44.z.string()).optional().describe("List of task IDs that must be completed before this task can start"),
13793
+ result: import_zod44.z.string().optional().describe("Result summary when task is completed"),
13794
+ failureReason: import_zod44.z.string().optional().describe("Reason for failure (use when status='failed')"),
13795
+ summary: import_zod44.z.string().optional().describe("Brief summary of the operation")
13796
+ });
13797
+ function createTaskMiddleware() {
13798
+ const handleManageTask = async (input, config) => {
13799
+ const rc = getRunConfig(config);
13800
+ const tenantId2 = rc.tenantId || "default";
13801
+ const workspaceId = rc.workspaceId;
13802
+ const projectId = rc.projectId;
13803
+ const ownerId = input.ownerId || (input.ownerType === "agent" ? rc.assistant_id : null) || rc.user_id;
13804
+ const store = getTaskStore();
13805
+ switch (input.action) {
13806
+ case "create": {
13807
+ if (!input.title) {
13808
+ return JSON.stringify({
13809
+ success: false,
13810
+ error: "title is required for create action",
13811
+ hint: "Provide a short, descriptive title for the task"
13812
+ });
13813
+ }
13814
+ const task = await store.create({
13815
+ tenantId: tenantId2,
13816
+ ownerType: input.ownerType || "user",
13817
+ ownerId,
13818
+ title: input.title,
13819
+ description: input.description,
13820
+ priority: input.priority || "medium",
13821
+ status: input.status || "pending",
13822
+ dueDate: input.dueDate,
13823
+ metadata: input.metadata,
13824
+ parentId: input.parentId,
13825
+ sourceId: input.sourceId,
13826
+ context: input.context,
13827
+ requireReview: input.requireReview,
13828
+ dependencies: input.dependencies,
13829
+ workspaceId,
13830
+ projectId
13831
+ });
13832
+ return JSON.stringify({ success: true, data: task });
13833
+ }
13834
+ case "list": {
13835
+ const filter2 = {
13836
+ tenantId: tenantId2,
13837
+ ownerType: input.ownerType,
13838
+ ownerId: input.ownerId,
13839
+ status: input.status,
13840
+ priority: input.priority,
13841
+ projectId
13842
+ };
13843
+ const tasks = await store.list(filter2);
13844
+ return JSON.stringify({ success: true, data: tasks, count: tasks.length });
13845
+ }
13846
+ case "update": {
13847
+ if (!input.id) {
13848
+ return JSON.stringify({
13849
+ success: false,
13850
+ error: "id is required for update action",
13851
+ hint: "Pass the task ID you want to update"
13852
+ });
13853
+ }
13854
+ const existing = await store.getById(tenantId2, input.id);
13855
+ if (!existing) {
13856
+ return JSON.stringify({
13857
+ success: false,
13858
+ error: `Task '${input.id}' not found`,
13859
+ hint: "Use list to see available tasks and their IDs"
13860
+ });
13861
+ }
13862
+ if (input.status) {
13863
+ if (!isValidTransition(existing.status, input.status)) {
13864
+ const allowed = VALID_TRANSITIONS[existing.status] || [];
13865
+ return JSON.stringify({
13866
+ success: false,
13867
+ error: `Cannot transition task from '${existing.status}' to '${input.status}'`,
13868
+ allowedTransitions: allowed,
13869
+ hint: `From '${existing.status}', valid transitions are: ${allowed.join(", ")}`
13870
+ });
13871
+ }
13872
+ }
13873
+ if (input.status === "in_progress" && existing.dependencies && existing.dependencies.length > 0) {
13874
+ const incompleteDeps = [];
13875
+ for (const depId of existing.dependencies) {
13876
+ const depTask = await store.getById(tenantId2, depId);
13877
+ if (!depTask || depTask.status !== "completed") {
13878
+ incompleteDeps.push(depId);
13879
+ }
13880
+ }
13881
+ if (incompleteDeps.length > 0) {
13882
+ return JSON.stringify({
13883
+ success: false,
13884
+ error: `Cannot start task '${input.id}': ${incompleteDeps.length} dependencies not completed`,
13885
+ blockedBy: incompleteDeps,
13886
+ hint: `These tasks must be completed first: ${incompleteDeps.join(", ")}`
13887
+ });
13888
+ }
13889
+ }
13890
+ let effectiveStatus = input.status;
13891
+ if (existing.requireReview && input.status === "completed" && existing.status === "in_progress") {
13892
+ effectiveStatus = "review";
13893
+ }
13894
+ const updates = {};
13895
+ const settableFields = [
13896
+ "title",
13897
+ "description",
13898
+ "priority",
13899
+ "dueDate",
13900
+ "metadata",
13901
+ "parentId",
13902
+ "sourceId",
13903
+ "context",
13904
+ "ownerType",
13905
+ "ownerId",
13906
+ "result",
13907
+ "failureReason",
13908
+ "requireReview",
13909
+ "dependencies"
13910
+ ];
13911
+ for (const field of settableFields) {
13912
+ if (input[field] !== void 0) {
13913
+ updates[field] = input[field];
13914
+ }
13915
+ }
13916
+ if (effectiveStatus !== void 0) {
13917
+ updates.status = effectiveStatus;
13918
+ }
13919
+ const updated = await store.update(tenantId2, input.id, updates);
13920
+ if (!updated) {
13921
+ return JSON.stringify({
13922
+ success: false,
13923
+ error: `Failed to update task '${input.id}'`,
13924
+ hint: "The task may have been deleted or the ID is incorrect"
13925
+ });
13926
+ }
13927
+ const actionMap = {
13928
+ pending: "pending",
13929
+ in_progress: "started",
13930
+ review: "submitted",
13931
+ failed: "failed",
13932
+ interrupted: "interrupted",
13933
+ completed: "completed",
13934
+ cancelled: "cancelled"
13935
+ };
13936
+ const workItemAction = effectiveStatus ? actionMap[effectiveStatus] || "updated" : "updated";
13937
+ const workItemSummary = input.summary || (effectiveStatus ? `Status changed to ${effectiveStatus}` : void 0);
13938
+ const workItemStore = getTaskWorkItemStore();
13939
+ await workItemStore.create({
13940
+ taskId: input.id,
13941
+ tenantId: tenantId2,
13942
+ action: workItemAction,
13943
+ actor: input.ownerType === "agent" ? `agent:${ownerId}` : `user:${ownerId}`,
13944
+ threadId: input.sourceId,
13945
+ summary: workItemSummary,
13946
+ detail: {
13947
+ ...input.result !== void 0 && { result: input.result },
13948
+ ...input.failureReason !== void 0 && { failureReason: input.failureReason }
13949
+ },
13950
+ workspaceId,
13951
+ projectId
13952
+ });
13953
+ return JSON.stringify({ success: true, data: updated });
13954
+ }
13955
+ case "delete": {
13956
+ if (!input.id) {
13957
+ return JSON.stringify({
13958
+ success: false,
13959
+ error: "id is required for delete action",
13960
+ hint: "Pass the task ID you want to delete"
13961
+ });
13962
+ }
13963
+ const deleted = await store.delete(tenantId2, input.id);
13964
+ if (!deleted) {
13965
+ return JSON.stringify({
13966
+ success: false,
13967
+ error: `Task '${input.id}' not found or could not be deleted`,
13968
+ hint: "Use list to verify the task exists"
13969
+ });
13970
+ }
13971
+ return JSON.stringify({ success: true, message: `Task '${input.id}' deleted` });
13972
+ }
13973
+ default:
13974
+ return JSON.stringify({
13975
+ success: false,
13976
+ error: `Unknown action '${input.action}'`,
13977
+ availableActions: ["create", "list", "update", "delete"],
13978
+ hint: "To mark a task complete, use action='update' with status='completed'"
13979
+ });
13980
+ }
13981
+ };
13982
+ return (0, import_langchain47.createMiddleware)({
13983
+ name: "TaskMiddleware",
13984
+ contextSchema,
13985
+ wrapModelCall: async (request, handler) => {
13986
+ const taskPrompt = `## Task Management
13987
+
13988
+ You can use the \`manage_task\` tool to create persistent tasks for user-visible work tracking.
13989
+
13990
+ ### When to create a task
13991
+ - The user explicitly asks you to track, manage, or follow up on work
13992
+ - The work spans multiple sessions or might need resumption later
13993
+ - The user needs to review or approve output before it is considered done
13994
+ - There are multiple independent work items the user wants visibility into
13995
+
13996
+ ### When NOT to create a task
13997
+ - One-shot lookups or simple Q&A ("what is X?", "search for Y")
13998
+ - Internal exploration steps you take to understand the problem (use \`write_todos\` for your execution plan instead)
13999
+ - Trivial single-step actions that complete in the same turn
14000
+ - Conversational or informational requests with no deliverable
14001
+
14002
+ ### Ownership defaults
14003
+ - No params: ownerType defaults to "user" with current user's ID
14004
+ - ownerType="agent": auto-fills ownerId from current agent (subtask for yourself)
14005
+ - Explicit ownerId: assign to a specific agent or user`;
14006
+ return handler({
14007
+ ...request,
14008
+ systemPrompt: taskPrompt + "\n\n" + (request.systemPrompt ?? "")
14009
+ });
14010
+ },
14011
+ tools: [
14012
+ (0, import_langchain47.tool)(
14013
+ handleManageTask,
14014
+ {
14015
+ name: "manage_task",
14016
+ description: `Manage persistent tasks. CRUD operations for user and agent tasks.
14017
+
14018
+ ## Owner defaults
14019
+ - No ownerType/ownerId: auto-assigned to current user
14020
+ - ownerType="agent" without ownerId: auto-assigned to current agent
14021
+ - Explicit ownerId: assign to a specific agent (cross-agent delegation)
14022
+
14023
+ ## Actions
14024
+ - create: Create a task (title required; priority/description/dueDate/metadata/parentId/context optional)
14025
+ - list: List tasks, filterable by ownerType/status/priority
14026
+ - update: Update a task (id required; pass only the fields to change)
14027
+ To mark complete: update with status='completed'
14028
+ To mark failed: update with status='failed', failureReason='...'
14029
+ Status transitions are validated \u2014 only allowed transitions will succeed.
14030
+ - delete: Delete a task (id required)`,
14031
+ schema: manageTaskSchema
14032
+ }
14033
+ )
14034
+ ]
14035
+ });
14036
+ }
14037
+ var taskPlugin = {
14038
+ meta: {
14039
+ type: "task",
14040
+ name: "Task Management",
14041
+ description: "Enables persistent task management with delegation and tracking",
14042
+ configSchema: {
14043
+ type: "object",
14044
+ title: "Task Management Configuration",
14045
+ description: "Zero-configuration task management",
14046
+ properties: {}
14047
+ },
14048
+ defaultConfig: {}
14049
+ },
14050
+ middleware: () => createTaskMiddleware(),
14051
+ skills: {
14052
+ "task-definition": `## Using manage_task
14053
+
14054
+ ### Task description format
14055
+
14056
+ When creating a task with manage_task, write the description in this Markdown structure:
14057
+
14058
+ ## Objective
14059
+ [One sentence \u2014 what result to achieve, as measurable as possible]
14060
+
14061
+ ## Acceptance Criteria
14062
+ - [ ] Criterion 1
14063
+ - [ ] Criterion 2
14064
+
14065
+ ## Deliverables
14066
+ - Deliverable description
14067
+
14068
+ Update the checklist as you work: change \`[ ]\` to \`[x]\` when a criterion is met.
14069
+
14070
+ ### Subtasks (parentId)
14071
+
14072
+ Use \`parentId\` to group related tasks under a parent. Create the parent task first, then create each subtask with \`parentId\` pointing to the parent.
14073
+
14074
+ ### Dependencies
14075
+
14076
+ Use the \`dependencies\` field to declare prerequisites. A task cannot be started (\`in_progress\`) until all its dependencies are \`completed\`. The validation happens automatically \u2014 no manual checking needed.
14077
+
14078
+ ### requireReview
14079
+
14080
+ Set \`requireReview: true\` if the user should approve output before the task is considered done. When enabled, completing the task sends it to \`review\` status instead of \`completed\`.
14081
+
14082
+ ### Reporting results
14083
+
14084
+ When a task is finished:
14085
+ - \`update(status: "completed", result: "summary of what was done")\`
14086
+ - If unable to complete: \`update(status: "failed", failureReason: "specific reason")\`
14087
+ - If blocked waiting for user input: \`update(status: "interrupted", summary: "what you need")\`
14088
+ - Use description updates to append progress notes between status changes.`
14089
+ }
14090
+ };
14091
+
14092
+ // src/deep_agent_new/middleware/subagents.ts
14093
+ var DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools.";
14094
+ var EXCLUDED_STATE_KEYS = ["messages", "todos", "jumpTo"];
14095
+ var DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.";
14096
+ function getTaskToolDescription(subagentDescriptions) {
14097
+ return subagentDescriptions.length > 0 ? `
14098
+ Launch an ephemeral subagent to handle complex, multi-step independent tasks with isolated context windows.
14099
+
14100
+ Available agent types and the tools they have access to:
14101
+ ${subagentDescriptions.join("\n")}
14102
+
14103
+ When using the Task tool, you must specify a subagent_type parameter to select which agent type to use.
14104
+
14105
+ ## Usage notes:
14106
+ 1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
14107
+ 2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
14108
+ 3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.
14109
+ 4. The agent's outputs should generally be trusted
14110
+ 5. Clearly tell the agent whether you expect it to create content, perform analysis, or just do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent
14111
+ 6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
14112
+ 7. When only the general-purpose agent is provided, you should use it for all tasks. It is great for isolating context and token usage, and completing specific, complex tasks, as it has all the same capabilities as the main agent.
14113
+
14114
+ ### Example usage of the general-purpose agent:
14115
+
14116
+ <example_agent_descriptions>
14117
+ "general-purpose": use this agent for general purpose tasks, it has access to all tools as the main agent.
14118
+ </example_agent_descriptions>
14119
+
14120
+ <example>
14121
+ User: "I want to conduct research on the accomplishments of Lebron James, Michael Jordan, and Kobe Bryant, and then compare them."
14122
+ Assistant: *Uses the task tool in parallel to conduct isolated research on each of the three players*
14123
+ Assistant: *Synthesizes the results of the three isolated research tasks and responds to the User*
14124
+ <commentary>
14125
+ Research is a complex, multi-step task in it of itself.
14126
+ The research of each individual player is not dependent on the research of the other players.
14127
+ The assistant uses the task tool to break down the complex objective into three isolated tasks.
14128
+ Each research task only needs to worry about context and tokens about one player, then returns synthesized information about each player as the Tool Result.
14129
+ This means each research task can dive deep and spend tokens and context deeply researching each player, but the final result is synthesized information, and saves us tokens in the long run when comparing the players to each other.
14130
+ </commentary>
14131
+ </example>
14132
+
14133
+ <example>
14134
+ User: "Analyze a single large code repository for security vulnerabilities and generate a report."
14135
+ Assistant: *Launches a single \`task\` subagent for the repository analysis*
14136
+ Assistant: *Receives report and integrates results into final summary*
14137
+ <commentary>
14138
+ Subagent is used to isolate a large, context-heavy task, even though there is only one. This prevents the main thread from being overloaded with details.
14139
+ If the user then asks followup questions, we have a concise report to reference instead of the entire history of analysis and tool calls, which is good and saves us time and money.
14140
+ </commentary>
14141
+ </example>
14142
+
14143
+ <example>
14144
+ User: "Schedule two meetings for me and prepare agendas for each."
14145
+ Assistant: *Calls the task tool in parallel to launch two \`task\` subagents (one per meeting) to prepare agendas*
14146
+ Assistant: *Returns final schedules and agendas*
14147
+ <commentary>
14148
+ Tasks are simple individually, but subagents help silo agenda preparation.
14149
+ Each subagent only needs to worry about the agenda for one meeting.
14150
+ </commentary>
14151
+ </example>
14152
+
14153
+ <example>
14154
+ User: "I want to order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway."
14155
+ Assistant: *Calls tools directly in parallel to order a pizza from Dominos, a burger from McDonald's, and a salad from Subway*
14156
+ <commentary>
14157
+ The assistant did not use the task tool because the objective is super simple and clear and only requires a few trivial tool calls.
14158
+ It is better to just complete the task directly and NOT use the \`task\`tool.
14159
+ </commentary>
13380
14160
  </example>
13381
14161
 
13382
14162
  ### Example usage with custom agents:
@@ -13470,7 +14250,7 @@ function returnCommandWithStateUpdate(result, toolCallId) {
13470
14250
  update: {
13471
14251
  ...stateUpdate,
13472
14252
  messages: [
13473
- new import_langchain47.ToolMessage({
14253
+ new import_langchain48.ToolMessage({
13474
14254
  content: lastMessage?.content || "Task Failed to complete",
13475
14255
  tool_call_id: toolCallId,
13476
14256
  name: "task"
@@ -13491,14 +14271,18 @@ function getSubagents(options) {
13491
14271
  const defaultSubagentMiddleware = defaultMiddleware || [];
13492
14272
  const agents = {};
13493
14273
  const subagentDescriptions = [];
14274
+ const hasTaskMiddleware = defaultSubagentMiddleware.some(
14275
+ (m) => m?.name === "TaskMiddleware"
14276
+ );
14277
+ const taskMiddleware = hasTaskMiddleware ? [] : [createTaskMiddleware()];
13494
14278
  if (generalPurposeAgent) {
13495
- const generalPurposeMiddleware = [...defaultSubagentMiddleware];
14279
+ const generalPurposeMiddleware = [...defaultSubagentMiddleware, ...taskMiddleware];
13496
14280
  if (defaultInterruptOn) {
13497
14281
  generalPurposeMiddleware.push(
13498
- (0, import_langchain47.humanInTheLoopMiddleware)({ interruptOn: defaultInterruptOn })
14282
+ (0, import_langchain48.humanInTheLoopMiddleware)({ interruptOn: defaultInterruptOn })
13499
14283
  );
13500
14284
  }
13501
- const generalPurposeSubagent = (0, import_langchain47.createAgent)({
14285
+ const generalPurposeSubagent = (0, import_langchain48.createAgent)({
13502
14286
  model: defaultModel,
13503
14287
  systemPrompt: DEFAULT_SUBAGENT_PROMPT,
13504
14288
  tools: defaultTools,
@@ -13518,11 +14302,11 @@ function getSubagents(options) {
13518
14302
  if ("runnable" in agentParams) {
13519
14303
  agents[agentParams.key] = agentParams.runnable;
13520
14304
  } else {
13521
- const middleware = agentParams.middleware ? [...defaultSubagentMiddleware, ...agentParams.middleware] : [...defaultSubagentMiddleware];
14305
+ const middleware = agentParams.middleware ? [...defaultSubagentMiddleware, ...taskMiddleware, ...agentParams.middleware] : [...defaultSubagentMiddleware, ...taskMiddleware];
13522
14306
  const interruptOn = agentParams.interruptOn || defaultInterruptOn;
13523
14307
  if (interruptOn)
13524
- middleware.push((0, import_langchain47.humanInTheLoopMiddleware)({ interruptOn }));
13525
- agents[agentParams.key] = (0, import_langchain47.createAgent)({
14308
+ middleware.push((0, import_langchain48.humanInTheLoopMiddleware)({ interruptOn }));
14309
+ agents[agentParams.key] = (0, import_langchain48.createAgent)({
13526
14310
  model: agentParams.model ?? defaultModel,
13527
14311
  systemPrompt: agentParams.systemPrompt,
13528
14312
  tools: agentParams.tools ?? defaultTools,
@@ -13572,7 +14356,7 @@ function createTaskTool(options) {
13572
14356
  generalPurposeAgent
13573
14357
  });
13574
14358
  const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
13575
- return (0, import_langchain47.tool)(
14359
+ return (0, import_langchain48.tool)(
13576
14360
  async (input, config) => {
13577
14361
  const { description, subagent_type, async } = input;
13578
14362
  let assistant_id = subagent_type;
@@ -13602,7 +14386,17 @@ function createTaskTool(options) {
13602
14386
  }
13603
14387
  const currentState = (0, import_langgraph7.getCurrentTaskInput)();
13604
14388
  const subagentState = filterStateForSubagent(currentState);
13605
- subagentState.messages = [new import_messages2.HumanMessage({ content: description })];
14389
+ subagentState.messages = input.taskId ? [
14390
+ new import_messages3.HumanMessage({
14391
+ content: `${description}
14392
+
14393
+ ---
14394
+ You are executing a persistent task (ID: ${input.taskId}). Use manage_task.update to report your progress:
14395
+ - Set status to 'in_progress' when you start working
14396
+ - Set status to 'completed' when done (or 'review' if requireReview is true, or 'failed' if you cannot complete, or 'interrupted' if you need more information)
14397
+ - You can also update the description to append progress notes or update the acceptance criteria checklist.`
14398
+ })
14399
+ ] : [new import_messages3.HumanMessage({ content: description })];
13606
14400
  const subagent_thread_id = config.configurable?.thread_id + "____" + assistant_id + "_" + config.toolCall.id;
13607
14401
  if (async) {
13608
14402
  const tenantId2 = config.configurable?.runConfig?.tenantId;
@@ -13634,11 +14428,12 @@ function createTaskTool(options) {
13634
14428
  runConfig: {
13635
14429
  ...config.configurable?.runConfig,
13636
14430
  assistant_id,
13637
- thread_id: subagent_thread_id
14431
+ thread_id: subagent_thread_id,
14432
+ taskId: input.taskId
13638
14433
  },
13639
- main_thread_id: mainThreadId,
13640
14434
  main_tenant_id: tenantId2,
13641
- main_assistant_id: mainAssistantId
14435
+ main_assistant_id: mainAssistantId,
14436
+ main_thread_id: mainThreadId
13642
14437
  }, false).catch((err) => {
13643
14438
  console.error(`Failed to start async subagent ${subagent_thread_id}:`, err);
13644
14439
  });
@@ -13648,7 +14443,7 @@ function createTaskTool(options) {
13648
14443
  return new import_langgraph7.Command({
13649
14444
  update: {
13650
14445
  messages: [
13651
- new import_langchain47.ToolMessage({
14446
+ new import_langchain48.ToolMessage({
13652
14447
  content: `Async task started: ${subagent_thread_id}
13653
14448
  ${description}
13654
14449
  The result will be delivered as a notification when complete. Do not poll.`,
@@ -13666,7 +14461,8 @@ The result will be delivered as a notification when complete. Do not poll.`,
13666
14461
  runConfig: {
13667
14462
  ...config.configurable?.runConfig,
13668
14463
  assistant_id,
13669
- thread_id: subagent_thread_id
14464
+ thread_id: subagent_thread_id,
14465
+ taskId: input.taskId
13670
14466
  }
13671
14467
  });
13672
14468
  const result = workerResult.finalState?.values;
@@ -13681,7 +14477,7 @@ The result will be delivered as a notification when complete. Do not poll.`,
13681
14477
  return new import_langgraph7.Command({
13682
14478
  update: {
13683
14479
  messages: [
13684
- new import_langchain47.ToolMessage({
14480
+ new import_langchain48.ToolMessage({
13685
14481
  content: error instanceof Error ? error.message : "Task Failed to complete",
13686
14482
  tool_call_id: config.toolCall.id,
13687
14483
  name: "task"
@@ -13705,7 +14501,10 @@ The result will be delivered as a notification when complete. Do not poll.`,
13705
14501
  async: import_v32.z.boolean().default(false).describe(
13706
14502
  "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."
13707
14503
  )
13708
- } : {}
14504
+ } : {},
14505
+ taskId: import_v32.z.string().optional().describe(
14506
+ "Optional: ID of a TaskItem created via manage_task. When set, the subagent will update this task's status as it works. Use this when executing a persistent task from the task board."
14507
+ )
13709
14508
  })
13710
14509
  }
13711
14510
  );
@@ -13721,7 +14520,7 @@ function getMainAgentFromConfig(config) {
13721
14520
  });
13722
14521
  }
13723
14522
  function createCheckAsyncTaskTool() {
13724
- return (0, import_langchain47.tool)(
14523
+ return (0, import_langchain48.tool)(
13725
14524
  async (input, config) => {
13726
14525
  const { task_id } = input;
13727
14526
  const mainAgent = getMainAgentFromConfig(config);
@@ -13788,7 +14587,7 @@ Description: ${cached.description}`;
13788
14587
  );
13789
14588
  }
13790
14589
  function createListAsyncTasksTool() {
13791
- return (0, import_langchain47.tool)(
14590
+ return (0, import_langchain48.tool)(
13792
14591
  async (_input, config) => {
13793
14592
  const mainAgent = getMainAgentFromConfig(config);
13794
14593
  if (!mainAgent) {
@@ -13839,7 +14638,7 @@ function createListAsyncTasksTool() {
13839
14638
  );
13840
14639
  }
13841
14640
  function createCancelAsyncTaskTool() {
13842
- return (0, import_langchain47.tool)(
14641
+ return (0, import_langchain48.tool)(
13843
14642
  async (input, config) => {
13844
14643
  const { task_id } = input;
13845
14644
  const mainAgent = getMainAgentFromConfig(config);
@@ -13915,7 +14714,7 @@ function createSubAgentMiddleware(options) {
13915
14714
  );
13916
14715
  }
13917
14716
  const effectiveSystemPrompt = allowAsync ? systemPrompt + getAsyncPromptText() : systemPrompt;
13918
- return (0, import_langchain47.createMiddleware)({
14717
+ return (0, import_langchain48.createMiddleware)({
13919
14718
  name: "subAgentMiddleware",
13920
14719
  tools: allTools,
13921
14720
  wrapModelCall: async (request, handler) => {
@@ -13935,9 +14734,9 @@ ${effectiveSystemPrompt}` : effectiveSystemPrompt;
13935
14734
  }
13936
14735
 
13937
14736
  // src/deep_agent_new/middleware/patch_tool_calls.ts
13938
- var import_langchain48 = require("langchain");
14737
+ var import_langchain49 = require("langchain");
13939
14738
  function createPatchToolCallsMiddleware() {
13940
- return (0, import_langchain48.createMiddleware)({
14739
+ return (0, import_langchain49.createMiddleware)({
13941
14740
  name: "patchToolCallsMiddleware",
13942
14741
  beforeAgent: async (state) => {
13943
14742
  const messages = state.messages;
@@ -13948,15 +14747,15 @@ function createPatchToolCallsMiddleware() {
13948
14747
  for (let i = 0; i < messages.length; i++) {
13949
14748
  const msg = messages[i];
13950
14749
  patchedMessages.push(msg);
13951
- if (import_langchain48.AIMessage.isInstance(msg) && msg.tool_calls != null) {
14750
+ if (import_langchain49.AIMessage.isInstance(msg) && msg.tool_calls != null) {
13952
14751
  for (const toolCall of msg.tool_calls) {
13953
14752
  const correspondingToolMsg = messages.slice(i).find(
13954
- (m) => import_langchain48.ToolMessage.isInstance(m) && m.tool_call_id === toolCall.id
14753
+ (m) => import_langchain49.ToolMessage.isInstance(m) && m.tool_call_id === toolCall.id
13955
14754
  );
13956
14755
  if (!correspondingToolMsg) {
13957
14756
  const toolMsg = `Tool call ${toolCall.name} with id ${toolCall.id} was cancelled - another message came in before it could be completed.`;
13958
14757
  patchedMessages.push(
13959
- new import_langchain48.ToolMessage({
14758
+ new import_langchain49.ToolMessage({
13960
14759
  content: toolMsg,
13961
14760
  name: toolCall.name,
13962
14761
  tool_call_id: toolCall.id
@@ -13978,8 +14777,8 @@ function createPatchToolCallsMiddleware() {
13978
14777
  }
13979
14778
 
13980
14779
  // src/deep_agent_new/middleware/date.ts
13981
- var import_langchain49 = require("langchain");
13982
- var import_zod44 = require("zod");
14780
+ var import_langchain50 = require("langchain");
14781
+ var import_zod45 = require("zod");
13983
14782
  function formatCurrentDate(timezone = "UTC") {
13984
14783
  const now = /* @__PURE__ */ new Date();
13985
14784
  let validTimezone = timezone;
@@ -14007,10 +14806,10 @@ function generateDateContext(timezone = "UTC") {
14007
14806
  function createDateMiddleware(options = {}) {
14008
14807
  const timezone = options.timezone || "UTC";
14009
14808
  const dateContext = generateDateContext(timezone);
14010
- return (0, import_langchain49.createMiddleware)({
14809
+ return (0, import_langchain50.createMiddleware)({
14011
14810
  name: "DateMiddleware",
14012
14811
  tools: [
14013
- (0, import_langchain49.tool)(
14812
+ (0, import_langchain50.tool)(
14014
14813
  async () => {
14015
14814
  const now = /* @__PURE__ */ new Date();
14016
14815
  let validTimezone = timezone;
@@ -14040,7 +14839,7 @@ function createDateMiddleware(options = {}) {
14040
14839
  {
14041
14840
  name: "get_current_date_time",
14042
14841
  description: "Get the exact current date and time at the moment of invocation. Use this when the user asks about the current time (e.g., 'what time is it', '\u51E0\u70B9\u4E86', '\u73B0\u5728\u51E0\u70B9'), or when you need to know the precise time for scheduling, deadlines, or time-sensitive operations.",
14043
- schema: import_zod44.z.object({})
14842
+ schema: import_zod45.z.object({})
14044
14843
  }
14045
14844
  )
14046
14845
  ],
@@ -14105,9 +14904,9 @@ var datePlugin = {
14105
14904
  };
14106
14905
 
14107
14906
  // src/deep_agent_new/middleware/scheduler.ts
14108
- var import_langchain50 = require("langchain");
14109
- var import_zod45 = require("zod");
14110
- var import_uuid4 = require("uuid");
14907
+ var import_langchain51 = require("langchain");
14908
+ var import_zod46 = require("zod");
14909
+ var import_uuid5 = require("uuid");
14111
14910
  var import_protocols8 = require("@axiom-lattice/protocols");
14112
14911
 
14113
14912
  // src/schedule_lattice/ScheduleLatticeManager.ts
@@ -15102,7 +15901,7 @@ var getScheduleLattice = (key4) => scheduleLatticeManager.getScheduleLattice(key
15102
15901
  // src/deep_agent_new/middleware/scheduler.ts
15103
15902
  var SCHEDULE_LATTICE_KEY = "default";
15104
15903
  var AGENT_ADD_MESSAGE_TASK_TYPE = "agent.add_message";
15105
- function getRunConfig(config) {
15904
+ function getRunConfig2(config) {
15106
15905
  const configurable = config;
15107
15906
  return configurable?.configurable?.runConfig ?? {};
15108
15907
  }
@@ -15174,14 +15973,14 @@ function registerAgentAddMessageHandler() {
15174
15973
  function createSchedulerMiddleware(options = {}) {
15175
15974
  const defaultMaxRetries = options.defaultMaxRetries ?? 0;
15176
15975
  registerAgentAddMessageHandler();
15177
- return (0, import_langchain50.createMiddleware)({
15976
+ return (0, import_langchain51.createMiddleware)({
15178
15977
  name: "SchedulerMiddleware",
15179
15978
  tools: [
15180
- (0, import_langchain50.tool)(
15979
+ (0, import_langchain51.tool)(
15181
15980
  async (input, config) => {
15182
- const runConfig = getRunConfig(config);
15981
+ const runConfig = getRunConfig2(config);
15183
15982
  const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
15184
- const taskId = (0, import_uuid4.v4)();
15983
+ const taskId = (0, import_uuid5.v4)();
15185
15984
  const executeAt = input.executeAt;
15186
15985
  const success = await scheduleLattice.client.scheduleOnce(
15187
15986
  taskId,
@@ -15205,18 +16004,18 @@ function createSchedulerMiddleware(options = {}) {
15205
16004
  {
15206
16005
  name: "schedule_at",
15207
16006
  description: "Schedule a system message for an absolute future timestamp",
15208
- schema: import_zod45.z.object({
15209
- executeAt: import_zod45.z.number(),
15210
- maxRetries: import_zod45.z.number().int().min(0).optional(),
15211
- message: import_zod45.z.string()
16007
+ schema: import_zod46.z.object({
16008
+ executeAt: import_zod46.z.number(),
16009
+ maxRetries: import_zod46.z.number().int().min(0).optional(),
16010
+ message: import_zod46.z.string()
15212
16011
  })
15213
16012
  }
15214
16013
  ),
15215
- (0, import_langchain50.tool)(
16014
+ (0, import_langchain51.tool)(
15216
16015
  async (input, config) => {
15217
- const runConfig = getRunConfig(config);
16016
+ const runConfig = getRunConfig2(config);
15218
16017
  const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
15219
- const taskId = (0, import_uuid4.v4)();
16018
+ const taskId = (0, import_uuid5.v4)();
15220
16019
  const executeAt = Date.now() + input.delayMs;
15221
16020
  const success = await scheduleLattice.client.scheduleOnce(
15222
16021
  taskId,
@@ -15240,18 +16039,18 @@ function createSchedulerMiddleware(options = {}) {
15240
16039
  {
15241
16040
  name: "schedule_after",
15242
16041
  description: "Schedule a system message after a relative delay",
15243
- schema: import_zod45.z.object({
15244
- delayMs: import_zod45.z.number().positive(),
15245
- maxRetries: import_zod45.z.number().int().min(0).optional(),
15246
- message: import_zod45.z.string()
16042
+ schema: import_zod46.z.object({
16043
+ delayMs: import_zod46.z.number().positive(),
16044
+ maxRetries: import_zod46.z.number().int().min(0).optional(),
16045
+ message: import_zod46.z.string()
15247
16046
  })
15248
16047
  }
15249
16048
  ),
15250
- (0, import_langchain50.tool)(
16049
+ (0, import_langchain51.tool)(
15251
16050
  async (input, config) => {
15252
- const runConfig = getRunConfig(config);
16051
+ const runConfig = getRunConfig2(config);
15253
16052
  const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
15254
- const taskId = (0, import_uuid4.v4)();
16053
+ const taskId = (0, import_uuid5.v4)();
15255
16054
  const success = await scheduleLattice.client.scheduleCron(
15256
16055
  taskId,
15257
16056
  AGENT_ADD_MESSAGE_TASK_TYPE,
@@ -15282,16 +16081,16 @@ function createSchedulerMiddleware(options = {}) {
15282
16081
  {
15283
16082
  name: "schedule_recurring",
15284
16083
  description: "Schedule a recurring system message with a cron expression",
15285
- schema: import_zod45.z.object({
15286
- cronExpression: import_zod45.z.string(),
15287
- maxRuns: import_zod45.z.number().int().positive().optional(),
15288
- expiresAt: import_zod45.z.number().optional(),
15289
- maxRetries: import_zod45.z.number().int().min(0).optional(),
15290
- message: import_zod45.z.string()
16084
+ schema: import_zod46.z.object({
16085
+ cronExpression: import_zod46.z.string(),
16086
+ maxRuns: import_zod46.z.number().int().positive().optional(),
16087
+ expiresAt: import_zod46.z.number().optional(),
16088
+ maxRetries: import_zod46.z.number().int().min(0).optional(),
16089
+ message: import_zod46.z.string()
15291
16090
  })
15292
16091
  }
15293
16092
  ),
15294
- (0, import_langchain50.tool)(
16093
+ (0, import_langchain51.tool)(
15295
16094
  async (input) => {
15296
16095
  const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
15297
16096
  const success = await scheduleLattice.client.cancel(input.taskId);
@@ -15300,14 +16099,14 @@ function createSchedulerMiddleware(options = {}) {
15300
16099
  {
15301
16100
  name: "cancel_scheduled_task",
15302
16101
  description: "Cancel a scheduled task by task id",
15303
- schema: import_zod45.z.object({
15304
- taskId: import_zod45.z.string()
16102
+ schema: import_zod46.z.object({
16103
+ taskId: import_zod46.z.string()
15305
16104
  })
15306
16105
  }
15307
16106
  ),
15308
- (0, import_langchain50.tool)(
16107
+ (0, import_langchain51.tool)(
15309
16108
  async (input, config) => {
15310
- const runConfig = getRunConfig(config);
16109
+ const runConfig = getRunConfig2(config);
15311
16110
  const scheduleLattice = getScheduleLattice(SCHEDULE_LATTICE_KEY);
15312
16111
  const storage = scheduleLattice.client.getStorage();
15313
16112
  if (!storage) {
@@ -15327,11 +16126,11 @@ function createSchedulerMiddleware(options = {}) {
15327
16126
  {
15328
16127
  name: "list_scheduled_tasks",
15329
16128
  description: "List scheduled tasks for the current agent context",
15330
- schema: import_zod45.z.object({
15331
- status: import_zod45.z.enum(["pending", "running", "completed", "failed", "cancelled", "paused"]).optional(),
15332
- executionType: import_zod45.z.enum(["once", "cron"]).optional(),
15333
- limit: import_zod45.z.number().int().positive().optional(),
15334
- offset: import_zod45.z.number().int().min(0).optional()
16129
+ schema: import_zod46.z.object({
16130
+ status: import_zod46.z.enum(["pending", "running", "completed", "failed", "cancelled", "paused"]).optional(),
16131
+ executionType: import_zod46.z.enum(["once", "cron"]).optional(),
16132
+ limit: import_zod46.z.number().int().positive().optional(),
16133
+ offset: import_zod46.z.number().int().min(0).optional()
15335
16134
  })
15336
16135
  }
15337
16136
  )
@@ -16472,8 +17271,8 @@ var MemoryBackend = class {
16472
17271
 
16473
17272
  // src/deep_agent_new/middleware/todos.ts
16474
17273
  var import_langgraph8 = require("@langchain/langgraph");
16475
- var import_zod46 = require("zod");
16476
- var import_langchain51 = require("langchain");
17274
+ var import_zod47 = require("zod");
17275
+ var import_langchain52 = require("langchain");
16477
17276
  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.
16478
17277
  It also helps the user understand the progress of the task and overall progress of their requests.
16479
17278
  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.
@@ -16700,20 +17499,20 @@ Writing todos takes time and tokens, use it when it is helpful for managing comp
16700
17499
  ## Important To-Do List Usage Notes to Remember
16701
17500
  - The \`write_todos\` tool should never be called multiple times in parallel.
16702
17501
  - 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.`;
16703
- var TodoStatus = import_zod46.z.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
16704
- var TodoSchema = import_zod46.z.object({
16705
- content: import_zod46.z.string().describe("Content of the todo item"),
17502
+ var TodoStatus = import_zod47.z.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
17503
+ var TodoSchema = import_zod47.z.object({
17504
+ content: import_zod47.z.string().describe("Content of the todo item"),
16706
17505
  status: TodoStatus
16707
17506
  });
16708
- var stateSchema = import_zod46.z.object({ todos: import_zod46.z.array(TodoSchema).default([]) });
17507
+ var stateSchema = import_zod47.z.object({ todos: import_zod47.z.array(TodoSchema).default([]) });
16709
17508
  function todoListMiddleware(options) {
16710
- const writeTodos = (0, import_langchain51.tool)(
17509
+ const writeTodos = (0, import_langchain52.tool)(
16711
17510
  ({ todos }, config) => {
16712
17511
  return new import_langgraph8.Command({
16713
17512
  update: {
16714
17513
  todos,
16715
17514
  messages: [
16716
- new import_langchain51.ToolMessage({
17515
+ new import_langchain52.ToolMessage({
16717
17516
  content: genUIMarkdown("todo_list", todos),
16718
17517
  tool_call_id: config.toolCall?.id
16719
17518
  })
@@ -16724,12 +17523,12 @@ function todoListMiddleware(options) {
16724
17523
  {
16725
17524
  name: "write_todos",
16726
17525
  description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,
16727
- schema: import_zod46.z.object({
16728
- todos: import_zod46.z.array(TodoSchema).describe("List of todo items to update")
17526
+ schema: import_zod47.z.object({
17527
+ todos: import_zod47.z.array(TodoSchema).describe("List of todo items to update")
16729
17528
  })
16730
17529
  }
16731
17530
  );
16732
- return (0, import_langchain51.createMiddleware)({
17531
+ return (0, import_langchain52.createMiddleware)({
16733
17532
  name: "todoListMiddleware",
16734
17533
  stateSchema,
16735
17534
  tools: [writeTodos],
@@ -16781,13 +17580,13 @@ ${BASE_PROMPT}` : BASE_PROMPT;
16781
17580
  backend: filesystemBackend
16782
17581
  }),
16783
17582
  // Subagent middleware: Automatic conversation summarization when token limits are approached
16784
- (0, import_langchain52.summarizationMiddleware)({
17583
+ (0, import_langchain53.summarizationMiddleware)({
16785
17584
  model,
16786
17585
  trigger: { tokens: 17e4 },
16787
17586
  keep: { messages: 6 }
16788
17587
  }),
16789
17588
  // Subagent middleware: Anthropic prompt caching for improved performance
16790
- (0, import_langchain52.anthropicPromptCachingMiddleware)({
17589
+ (0, import_langchain53.anthropicPromptCachingMiddleware)({
16791
17590
  unsupportedModelBehavior: "ignore"
16792
17591
  }),
16793
17592
  // Subagent middleware: Patches tool calls for compatibility
@@ -16799,23 +17598,23 @@ ${BASE_PROMPT}` : BASE_PROMPT;
16799
17598
  generalPurposeAgent: true
16800
17599
  }),
16801
17600
  // Automatically summarizes conversation history when token limits are approached
16802
- (0, import_langchain52.summarizationMiddleware)({
17601
+ (0, import_langchain53.summarizationMiddleware)({
16803
17602
  model,
16804
17603
  trigger: { tokens: 17e4 },
16805
17604
  keep: { messages: 6 }
16806
17605
  }),
16807
17606
  // Enables Anthropic prompt caching for improved performance and reduced costs
16808
- (0, import_langchain52.anthropicPromptCachingMiddleware)({
17607
+ (0, import_langchain53.anthropicPromptCachingMiddleware)({
16809
17608
  unsupportedModelBehavior: "ignore"
16810
17609
  }),
16811
17610
  // Patches tool calls to ensure compatibility across different model providers
16812
17611
  createPatchToolCallsMiddleware()
16813
17612
  ];
16814
17613
  if (interruptOn) {
16815
- middleware.push((0, import_langchain52.humanInTheLoopMiddleware)({ interruptOn }));
17614
+ middleware.push((0, import_langchain53.humanInTheLoopMiddleware)({ interruptOn }));
16816
17615
  }
16817
17616
  middleware.push(...customMiddleware);
16818
- return (0, import_langchain52.createAgent)({
17617
+ return (0, import_langchain53.createAgent)({
16819
17618
  model,
16820
17619
  systemPrompt: finalSystemPrompt,
16821
17620
  tools,
@@ -16887,7 +17686,7 @@ init_MemoryLatticeManager();
16887
17686
 
16888
17687
  // src/agent_team/agent_team.ts
16889
17688
  var import_v35 = require("zod/v3");
16890
- var import_langchain55 = require("langchain");
17689
+ var import_langchain56 = require("langchain");
16891
17690
 
16892
17691
  // src/agent_team/types.ts
16893
17692
  var TaskStatus = /* @__PURE__ */ ((TaskStatus3) => {
@@ -17323,13 +18122,13 @@ var InMemoryMailboxStore = class {
17323
18122
 
17324
18123
  // src/agent_team/middleware/team.ts
17325
18124
  var import_v34 = require("zod/v3");
17326
- var import_langchain54 = require("langchain");
18125
+ var import_langchain55 = require("langchain");
17327
18126
  var import_langgraph10 = require("@langchain/langgraph");
17328
- var import_uuid5 = require("uuid");
18127
+ var import_uuid6 = require("uuid");
17329
18128
 
17330
18129
  // src/agent_team/middleware/teammate_tools.ts
17331
18130
  var import_v33 = require("zod/v3");
17332
- var import_langchain53 = require("langchain");
18131
+ var import_langchain54 = require("langchain");
17333
18132
  var import_langgraph9 = require("@langchain/langgraph");
17334
18133
 
17335
18134
  // src/agent_team/middleware/formatMessages.ts
@@ -17354,7 +18153,7 @@ ${meta}${body}`;
17354
18153
  // src/agent_team/middleware/teammate_tools.ts
17355
18154
  function createTeammateTools(options) {
17356
18155
  const { teamId, agentId, taskListStore, mailboxStore } = options;
17357
- const claimTaskTool = (0, import_langchain53.tool)(
18156
+ const claimTaskTool = (0, import_langchain54.tool)(
17358
18157
  async (input) => {
17359
18158
  const task = await taskListStore.claimTaskById(
17360
18159
  teamId,
@@ -17384,7 +18183,7 @@ function createTeammateTools(options) {
17384
18183
  })
17385
18184
  }
17386
18185
  );
17387
- const completeTaskTool = (0, import_langchain53.tool)(
18186
+ const completeTaskTool = (0, import_langchain54.tool)(
17388
18187
  async (input) => {
17389
18188
  const task = await taskListStore.completeTask(
17390
18189
  teamId,
@@ -17411,7 +18210,7 @@ function createTeammateTools(options) {
17411
18210
  })
17412
18211
  }
17413
18212
  );
17414
- const failTaskTool = (0, import_langchain53.tool)(
18213
+ const failTaskTool = (0, import_langchain54.tool)(
17415
18214
  async (input) => {
17416
18215
  const task = await taskListStore.failTask(
17417
18216
  teamId,
@@ -17438,7 +18237,7 @@ function createTeammateTools(options) {
17438
18237
  })
17439
18238
  }
17440
18239
  );
17441
- const sendMessageTool = (0, import_langchain53.tool)(
18240
+ const sendMessageTool = (0, import_langchain54.tool)(
17442
18241
  async (input) => {
17443
18242
  await mailboxStore.sendMessage(
17444
18243
  teamId,
@@ -17476,7 +18275,7 @@ function createTeammateTools(options) {
17476
18275
  read: msg.read
17477
18276
  }));
17478
18277
  };
17479
- const readMessagesTool = (0, import_langchain53.tool)(
18278
+ const readMessagesTool = (0, import_langchain54.tool)(
17480
18279
  async (input, config) => {
17481
18280
  const formatAndMarkAsRead = async (msgs2) => {
17482
18281
  for (const msg of msgs2) {
@@ -17488,7 +18287,7 @@ function createTeammateTools(options) {
17488
18287
  if (msgs.length > 0) {
17489
18288
  const formatted2 = await formatAndMarkAsRead(msgs);
17490
18289
  const relevantMsgs2 = await getRelevantMessagesForState();
17491
- const toolMessage2 = new import_langchain53.ToolMessage({
18290
+ const toolMessage2 = new import_langchain54.ToolMessage({
17492
18291
  content: formatted2,
17493
18292
  tool_call_id: config.toolCall?.id,
17494
18293
  name: "read_messages"
@@ -17513,7 +18312,7 @@ function createTeammateTools(options) {
17513
18312
  });
17514
18313
  const relevantMsgs = await getRelevantMessagesForState();
17515
18314
  if (msgs.length === 0) {
17516
- const toolMessage2 = new import_langchain53.ToolMessage({
18315
+ const toolMessage2 = new import_langchain54.ToolMessage({
17517
18316
  content: "No unread messages.",
17518
18317
  tool_call_id: config.toolCall?.id,
17519
18318
  name: "read_messages"
@@ -17523,7 +18322,7 @@ function createTeammateTools(options) {
17523
18322
  });
17524
18323
  }
17525
18324
  const formatted = await formatAndMarkAsRead(msgs);
17526
- const toolMessage = new import_langchain53.ToolMessage({
18325
+ const toolMessage = new import_langchain54.ToolMessage({
17527
18326
  content: formatted,
17528
18327
  tool_call_id: config.toolCall?.id,
17529
18328
  name: "read_messages"
@@ -17538,7 +18337,7 @@ function createTeammateTools(options) {
17538
18337
  schema: import_v33.z.object({})
17539
18338
  }
17540
18339
  );
17541
- const checkTasksTool = (0, import_langchain53.tool)(
18340
+ const checkTasksTool = (0, import_langchain54.tool)(
17542
18341
  async () => {
17543
18342
  const tasks = await taskListStore.getAllTasks(teamId);
17544
18343
  return formatTaskSummary(tasks);
@@ -17549,7 +18348,7 @@ function createTeammateTools(options) {
17549
18348
  schema: import_v33.z.object({})
17550
18349
  }
17551
18350
  );
17552
- const broadcastMessageTool = (0, import_langchain53.tool)(
18351
+ const broadcastMessageTool = (0, import_langchain54.tool)(
17553
18352
  async (input) => {
17554
18353
  const allAgents = await mailboxStore.getRegisteredAgents(teamId);
17555
18354
  const recipients = allAgents.filter((a) => a !== agentId);
@@ -17735,7 +18534,7 @@ You have access to these tools:
17735
18534
  - \`read_messages\`: Read messages from team_lead or teammates
17736
18535
  - \`check_tasks\`: Get current status of all tasks in the team`;
17737
18536
  const assistantId = getTeammateAssistantId(ctx.teamId, spec.name);
17738
- agent = (0, import_langchain54.createAgent)({
18537
+ agent = (0, import_langchain55.createAgent)({
17739
18538
  model: spec.model ?? ctx.defaultModel,
17740
18539
  systemPrompt: teammatePrompt,
17741
18540
  tools: allTools,
@@ -17804,19 +18603,19 @@ async function spawnTeammate(options) {
17804
18603
  function createTeamMiddleware(options) {
17805
18604
  const { teamConfig, taskListStore, mailboxStore, tenantId: tenantId2 } = options;
17806
18605
  const defaultModel = teamConfig.model ?? "claude-sonnet-4-5-20250929";
17807
- const createTeamTool = (0, import_langchain54.tool)(
18606
+ const createTeamTool = (0, import_langchain55.tool)(
17808
18607
  async (input, config) => {
17809
18608
  const state = (0, import_langgraph10.getCurrentTaskInput)();
17810
18609
  if (state?.team?.teamId) {
17811
18610
  const existingId = state.team.teamId;
17812
- const msg = new import_langchain54.ToolMessage({
18611
+ const msg = new import_langchain55.ToolMessage({
17813
18612
  content: `A team is already active (id: ${existingId}). Use this team_id for \`check_tasks\`, \`read_messages\`, \`add_tasks\`, \`send_message\`, \`assign_task\`, \`set_task_status\`, and \`set_task_dependencies\`. Do not call \`create_team\` again unless you need a fresh team for a new objective.`,
17814
18613
  tool_call_id: config.toolCall?.id,
17815
18614
  name: "create_team"
17816
18615
  });
17817
18616
  return msg;
17818
18617
  }
17819
- const teamId = (0, import_uuid5.v4)();
18618
+ const teamId = (0, import_uuid6.v4)();
17820
18619
  const createdTasks = await taskListStore.addTasks(
17821
18620
  teamId,
17822
18621
  input.tasks.map((t) => ({
@@ -17898,7 +18697,7 @@ Teammates are now working in the background. Keep calling \`check_tasks\` and \`
17898
18697
  \`\`\`json
17899
18698
  ${teamJson}
17900
18699
  \`\`\``;
17901
- const toolMessage = new import_langchain54.ToolMessage({
18700
+ const toolMessage = new import_langchain55.ToolMessage({
17902
18701
  content: summary,
17903
18702
  tool_call_id: config.toolCall?.id,
17904
18703
  name: "create_team"
@@ -17983,7 +18782,7 @@ After calling create_team, you MUST:
17983
18782
  if (state?.team?.teamId) return state.team.teamId;
17984
18783
  throw new Error("No team_id provided and no team in state. Call create_team first.");
17985
18784
  };
17986
- const addTasksTool = (0, import_langchain54.tool)(
18785
+ const addTasksTool = (0, import_langchain55.tool)(
17987
18786
  async (input, config) => {
17988
18787
  const teamId = resolveTeamId();
17989
18788
  const created = await taskListStore.addTasks(
@@ -17997,7 +18796,7 @@ After calling create_team, you MUST:
17997
18796
  }))
17998
18797
  );
17999
18798
  const summary = created.map((t) => `- ${t.id}: "${t.title}"`).join("\n");
18000
- return new import_langchain54.ToolMessage({
18799
+ return new import_langchain55.ToolMessage({
18001
18800
  content: `Added ${created.length} task(s) to team ${teamId}:
18002
18801
  ${summary}
18003
18802
  Sleeping teammates will wake up and claim these.`,
@@ -18048,20 +18847,20 @@ IMPORTANT: Assigning to a specific teammate
18048
18847
  })
18049
18848
  }
18050
18849
  );
18051
- const assignTaskTool = (0, import_langchain54.tool)(
18850
+ const assignTaskTool = (0, import_langchain55.tool)(
18052
18851
  async (input, config) => {
18053
18852
  const teamId = resolveTeamId();
18054
18853
  const task = await taskListStore.updateTask(teamId, input.task_id, {
18055
18854
  assignee: input.assignee
18056
18855
  });
18057
18856
  if (!task) {
18058
- return new import_langchain54.ToolMessage({
18857
+ return new import_langchain55.ToolMessage({
18059
18858
  content: `Task ${input.task_id} not found in team ${teamId}.`,
18060
18859
  tool_call_id: config.toolCall?.id,
18061
18860
  name: "assign_task"
18062
18861
  });
18063
18862
  }
18064
- return new import_langchain54.ToolMessage({
18863
+ return new import_langchain55.ToolMessage({
18065
18864
  content: `Task "${task.title}" (${task.id}) assigned to ${input.assignee}.`,
18066
18865
  tool_call_id: config.toolCall?.id,
18067
18866
  name: "assign_task"
@@ -18076,20 +18875,20 @@ IMPORTANT: Assigning to a specific teammate
18076
18875
  })
18077
18876
  }
18078
18877
  );
18079
- const setTaskStatusTool = (0, import_langchain54.tool)(
18878
+ const setTaskStatusTool = (0, import_langchain55.tool)(
18080
18879
  async (input, config) => {
18081
18880
  const teamId = resolveTeamId();
18082
18881
  const task = await taskListStore.updateTask(teamId, input.task_id, {
18083
18882
  status: input.status
18084
18883
  });
18085
18884
  if (!task) {
18086
- return new import_langchain54.ToolMessage({
18885
+ return new import_langchain55.ToolMessage({
18087
18886
  content: `Task ${input.task_id} not found in team ${teamId}.`,
18088
18887
  tool_call_id: config.toolCall?.id,
18089
18888
  name: "set_task_status"
18090
18889
  });
18091
18890
  }
18092
- return new import_langchain54.ToolMessage({
18891
+ return new import_langchain55.ToolMessage({
18093
18892
  content: `Task "${task.title}" (${task.id}) status set to ${input.status}.`,
18094
18893
  tool_call_id: config.toolCall?.id,
18095
18894
  name: "set_task_status"
@@ -18104,20 +18903,20 @@ IMPORTANT: Assigning to a specific teammate
18104
18903
  })
18105
18904
  }
18106
18905
  );
18107
- const setTaskDependenciesTool = (0, import_langchain54.tool)(
18906
+ const setTaskDependenciesTool = (0, import_langchain55.tool)(
18108
18907
  async (input, config) => {
18109
18908
  const teamId = resolveTeamId();
18110
18909
  const task = await taskListStore.updateTask(teamId, input.task_id, {
18111
18910
  dependencies: input.dependencies
18112
18911
  });
18113
18912
  if (!task) {
18114
- return new import_langchain54.ToolMessage({
18913
+ return new import_langchain55.ToolMessage({
18115
18914
  content: `Task ${input.task_id} not found in team ${teamId}.`,
18116
18915
  tool_call_id: config.toolCall?.id,
18117
18916
  name: "set_task_dependencies"
18118
18917
  });
18119
18918
  }
18120
- return new import_langchain54.ToolMessage({
18919
+ return new import_langchain55.ToolMessage({
18121
18920
  content: `Task "${task.title}" (${task.id}) dependencies set to [${input.dependencies.join(", ")}].`,
18122
18921
  tool_call_id: config.toolCall?.id,
18123
18922
  name: "set_task_dependencies"
@@ -18132,7 +18931,7 @@ IMPORTANT: Assigning to a specific teammate
18132
18931
  })
18133
18932
  }
18134
18933
  );
18135
- const checkTasksTool = (0, import_langchain54.tool)(
18934
+ const checkTasksTool = (0, import_langchain55.tool)(
18136
18935
  async (input, config) => {
18137
18936
  const teamId = resolveTeamId();
18138
18937
  const tasks = await taskListStore.getAllTasks(teamId);
@@ -18141,7 +18940,7 @@ IMPORTANT: Assigning to a specific teammate
18141
18940
  update: {
18142
18941
  tasks: tasksSnapshot,
18143
18942
  messages: [
18144
- new import_langchain54.ToolMessage({
18943
+ new import_langchain55.ToolMessage({
18145
18944
  content: formatTaskSummary(tasks),
18146
18945
  tool_call_id: config.toolCall?.id,
18147
18946
  name: "check_tasks"
@@ -18177,7 +18976,7 @@ Task Status Values:
18177
18976
  })
18178
18977
  }
18179
18978
  );
18180
- const sendMessageTool = (0, import_langchain54.tool)(
18979
+ const sendMessageTool = (0, import_langchain55.tool)(
18181
18980
  async (input, config) => {
18182
18981
  const teamId = resolveTeamId();
18183
18982
  await mailboxStore.sendMessage(
@@ -18187,7 +18986,7 @@ Task Status Values:
18187
18986
  input.content,
18188
18987
  "direct_message" /* DIRECT_MESSAGE */
18189
18988
  );
18190
- return new import_langchain54.ToolMessage({
18989
+ return new import_langchain55.ToolMessage({
18191
18990
  content: `Message sent to ${input.to}.`,
18192
18991
  tool_call_id: config.toolCall?.id,
18193
18992
  name: "send_message"
@@ -18202,7 +19001,7 @@ Task Status Values:
18202
19001
  })
18203
19002
  }
18204
19003
  );
18205
- const readMessagesTool = (0, import_langchain54.tool)(
19004
+ const readMessagesTool = (0, import_langchain55.tool)(
18206
19005
  async (input, config) => {
18207
19006
  const teamId = resolveTeamId();
18208
19007
  const formatAndMarkAsRead = async (msgs2) => {
@@ -18230,7 +19029,7 @@ Task Status Values:
18230
19029
  if (msgs.length > 0) {
18231
19030
  const formatted2 = await formatAndMarkAsRead(msgs);
18232
19031
  const allTeamMessages2 = await getAllTeamMessagesForState();
18233
- const toolMessage2 = new import_langchain54.ToolMessage({
19032
+ const toolMessage2 = new import_langchain55.ToolMessage({
18234
19033
  content: formatted2,
18235
19034
  tool_call_id: config.toolCall?.id,
18236
19035
  name: "read_messages"
@@ -18262,7 +19061,7 @@ Task Status Values:
18262
19061
  );
18263
19062
  const allTeamMessages = await getAllTeamMessagesForState();
18264
19063
  if (msgs.length === 0) {
18265
- const toolMessage2 = new import_langchain54.ToolMessage({
19064
+ const toolMessage2 = new import_langchain55.ToolMessage({
18266
19065
  content: "No unread messages from teammates.",
18267
19066
  tool_call_id: config.toolCall?.id,
18268
19067
  name: "read_messages"
@@ -18272,7 +19071,7 @@ Task Status Values:
18272
19071
  });
18273
19072
  }
18274
19073
  const formatted = await formatAndMarkAsRead(msgs);
18275
- const toolMessage = new import_langchain54.ToolMessage({
19074
+ const toolMessage = new import_langchain55.ToolMessage({
18276
19075
  content: formatted,
18277
19076
  tool_call_id: config.toolCall?.id,
18278
19077
  name: "read_messages"
@@ -18289,7 +19088,7 @@ Task Status Values:
18289
19088
  })
18290
19089
  }
18291
19090
  );
18292
- const disbandTeamTool = (0, import_langchain54.tool)(
19091
+ const disbandTeamTool = (0, import_langchain55.tool)(
18293
19092
  async (input, config) => {
18294
19093
  const teamId = resolveTeamId();
18295
19094
  await mailboxStore.broadcastMessage(
@@ -18299,7 +19098,7 @@ Task Status Values:
18299
19098
  "shutdown_request" /* SHUTDOWN_REQUEST */
18300
19099
  );
18301
19100
  await new Promise((r) => setTimeout(r, 2e3));
18302
- return new import_langchain54.ToolMessage({
19101
+ return new import_langchain55.ToolMessage({
18303
19102
  content: `Team ${teamId} has been disbanded. All teammates notified and resources cleaned up.`,
18304
19103
  tool_call_id: config.toolCall?.id,
18305
19104
  name: "disband_team"
@@ -18310,7 +19109,7 @@ Task Status Values:
18310
19109
  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."
18311
19110
  }
18312
19111
  );
18313
- const broadcastMessageTool = (0, import_langchain54.tool)(
19112
+ const broadcastMessageTool = (0, import_langchain55.tool)(
18314
19113
  async (input, config) => {
18315
19114
  const teamId = resolveTeamId();
18316
19115
  await mailboxStore.broadcastMessage(
@@ -18319,7 +19118,7 @@ Task Status Values:
18319
19118
  input.content,
18320
19119
  "broadcast" /* BROADCAST */
18321
19120
  );
18322
- return new import_langchain54.ToolMessage({
19121
+ return new import_langchain55.ToolMessage({
18323
19122
  content: `Broadcast message sent to all teammates.`,
18324
19123
  tool_call_id: config.toolCall?.id,
18325
19124
  name: "broadcast_message"
@@ -18333,7 +19132,7 @@ Task Status Values:
18333
19132
  })
18334
19133
  }
18335
19134
  );
18336
- return (0, import_langchain54.createMiddleware)({
19135
+ return (0, import_langchain55.createMiddleware)({
18337
19136
  name: "teamMiddleware",
18338
19137
  tools: [
18339
19138
  createTeamTool,
@@ -18442,7 +19241,7 @@ function createAgentTeam(config) {
18442
19241
  ];
18443
19242
  const systemPrompt = config.systemPrompt + "\n\n" + TEAM_LEAD_BASE_PROMPT;
18444
19243
  const stateSchema2 = createReactAgentSchema(TEAM_STATE_SCHEMA);
18445
- return (0, import_langchain55.createAgent)({
19244
+ return (0, import_langchain56.createAgent)({
18446
19245
  model: config.model ?? "claude-sonnet-4-5-20250929",
18447
19246
  systemPrompt,
18448
19247
  tools: [],
@@ -18511,10 +19310,10 @@ var TeamAgentGraphBuilder = class {
18511
19310
 
18512
19311
  // src/agent_lattice/builders/RemoteAgentGraphBuilder.ts
18513
19312
  var import_langgraph11 = require("@langchain/langgraph");
18514
- var import_messages3 = require("@langchain/core/messages");
19313
+ var import_messages4 = require("@langchain/core/messages");
18515
19314
 
18516
19315
  // src/services/a2a-client.ts
18517
- var import_uuid6 = require("uuid");
19316
+ var import_uuid7 = require("uuid");
18518
19317
  var A2ARemoteError = class extends Error {
18519
19318
  constructor(message, statusCode, body) {
18520
19319
  super(message);
@@ -18561,7 +19360,7 @@ var A2ARemoteClient = class {
18561
19360
  */
18562
19361
  async sendMessage(text) {
18563
19362
  await this.resolve();
18564
- const taskId = (0, import_uuid6.v4)();
19363
+ const taskId = (0, import_uuid7.v4)();
18565
19364
  const body = JSON.stringify({
18566
19365
  jsonrpc: "2.0",
18567
19366
  method: "tasks/send",
@@ -18687,7 +19486,7 @@ var RemoteAgentGraphBuilder = class {
18687
19486
  if (!text) {
18688
19487
  return {
18689
19488
  messages: [
18690
- new import_messages3.AIMessage("No text input provided to remote agent.")
19489
+ new import_messages4.AIMessage("No text input provided to remote agent.")
18691
19490
  ]
18692
19491
  };
18693
19492
  }
@@ -18698,13 +19497,13 @@ User request:
18698
19497
  ${text}` : text;
18699
19498
  const response = await client.sendMessage(fullPrompt);
18700
19499
  return {
18701
- messages: [new import_messages3.AIMessage(response)]
19500
+ messages: [new import_messages4.AIMessage(response)]
18702
19501
  };
18703
19502
  } catch (error) {
18704
19503
  const msg = error.message ?? String(error);
18705
19504
  return {
18706
19505
  messages: [
18707
- new import_messages3.AIMessage(`Remote A2A agent error: ${msg}`)
19506
+ new import_messages4.AIMessage(`Remote A2A agent error: ${msg}`)
18708
19507
  ]
18709
19508
  };
18710
19509
  }
@@ -18731,7 +19530,7 @@ function extractLastHumanMessage(messages) {
18731
19530
  }
18732
19531
 
18733
19532
  // src/agent_lattice/builders/WorkflowAgentGraphBuilder.ts
18734
- var import_langchain56 = require("langchain");
19533
+ var import_langchain57 = require("langchain");
18735
19534
  init_MemoryLatticeManager();
18736
19535
  var import_protocols10 = require("@axiom-lattice/protocols");
18737
19536
  init_compile();
@@ -18796,7 +19595,7 @@ var WorkflowAgentGraphBuilder = class {
18796
19595
  const noWrapMiddlewares = stripWrapModelCallHook(middlewares);
18797
19596
  const noWrapAskMiddlewares = stripWrapModelCallHook(askMiddlewares);
18798
19597
  console.log(`[WF BUILDER] building default agent | toolCount=${tools.length} | middlewareCount=${middlewares.length}`);
18799
- const defaultAgent = (0, import_langchain56.createAgent)({
19598
+ const defaultAgent = (0, import_langchain57.createAgent)({
18800
19599
  model: params.model,
18801
19600
  tools,
18802
19601
  systemPrompt: buildStepSystemPrompt(false, params.prompt),
@@ -18816,7 +19615,7 @@ var WorkflowAgentGraphBuilder = class {
18816
19615
  console.log(`[WF BUILDER] resolveAgent: cacheKey=${key4.slice(0, 80)}... | cached=${agentCache.has(key4)}`);
18817
19616
  if (!agentCache.has(key4)) {
18818
19617
  console.log(`[WF BUILDER] creating ${isAsk ? "ask" : "agent"} with responseFormat`);
18819
- const agent = (0, import_langchain56.createAgent)({
19618
+ const agent = (0, import_langchain57.createAgent)({
18820
19619
  model: params.model,
18821
19620
  tools,
18822
19621
  systemPrompt: buildStepSystemPrompt(isAsk, params.prompt),
@@ -18832,7 +19631,7 @@ var WorkflowAgentGraphBuilder = class {
18832
19631
  const key4 = "ask:default";
18833
19632
  if (!agentCache.has(key4)) {
18834
19633
  console.log(`[WF BUILDER] creating ask default agent`);
18835
- const agent = (0, import_langchain56.createAgent)({
19634
+ const agent = (0, import_langchain57.createAgent)({
18836
19635
  model: params.model,
18837
19636
  tools,
18838
19637
  systemPrompt: buildStepSystemPrompt(true, params.prompt),
@@ -19351,6 +20150,22 @@ async function configureStores(stores, options = {}) {
19351
20150
  storeLatticeManager.registerLattice("default", t, store);
19352
20151
  }
19353
20152
  }
20153
+ if (options.discoverPlugins) {
20154
+ const pluginTypes = PluginRegistry.list();
20155
+ for (const pluginType of pluginTypes) {
20156
+ const plugin = PluginRegistry.get(pluginType);
20157
+ if (!plugin?.stores) continue;
20158
+ for (const [storeType, storeOrFactory] of Object.entries(plugin.stores)) {
20159
+ const store = typeof storeOrFactory === "function" ? storeOrFactory() : storeOrFactory;
20160
+ await initAndRegister(store, localDisposables);
20161
+ const t = storeType;
20162
+ if (storeLatticeManager.hasLattice("default", t)) {
20163
+ storeLatticeManager.removeLattice("default", t);
20164
+ }
20165
+ storeLatticeManager.registerLattice("default", t, store);
20166
+ }
20167
+ }
20168
+ }
19354
20169
  if (options.autoDisposeStores) {
19355
20170
  registerSignalCleanup();
19356
20171
  _disposables.push(...localDisposables);
@@ -19495,7 +20310,7 @@ description: Create new skills, modify and improve existing skills. Use this ski
19495
20310
  license: MIT
19496
20311
  metadata:
19497
20312
  category: meta
19498
- version: "2.0"
20313
+ version: "3.0"
19499
20314
  ---
19500
20315
 
19501
20316
  # Skill Creator
@@ -19594,6 +20409,160 @@ Instructional content for the agent.
19594
20409
 
19595
20410
  ---
19596
20411
 
20412
+ ## subSkills: Building the Skill Graph
20413
+
20414
+ \`subSkills\` is how skills reference each other. It forms a graph \u2014
20415
+ visualized in the Skills view as connected nodes.
20416
+
20417
+ ### What subSkills Means
20418
+
20419
+ It declares: "this skill is conceptually composed of these sub-skills."
20420
+ It does NOT mean the agent automatically loads them. The agent reads the
20421
+ body and decides what to load next.
20422
+
20423
+ ### When to Use subSkills
20424
+
20425
+ **YES \u2014 split into subSkills when another task would independently
20426
+ reference that piece.** The test:
20427
+
20428
+ > "Will a future learning task about a DIFFERENT document type
20429
+ > need to reference this?"
20430
+
20431
+ For example:
20432
+ - \`engine-selection\` \u2192 YES, PO extraction AND invoice extraction both need it
20433
+ - \`sap-bp-validation\` \u2192 YES, multiple tasks validate BP through SAP
20434
+ - \`po-bp-extraction\` \u2192 NO, nobody extracts BP without extracting the whole PO
20435
+
20436
+ **NO \u2014 keep in one file when the steps are a single pipeline that's
20437
+ always used together.** Field extraction, validation, and formatting
20438
+ for one document type belong in one skill file.
20439
+
20440
+ ### Examples
20441
+
20442
+ Good (shared skills split out):
20443
+ \`\`\`yaml
20444
+ ---
20445
+ name: po-extraction
20446
+ description: Extract BP, items, notes from PO PDFs with SAP validation
20447
+ subSkills:
20448
+ - engine-selection # Shared \u2014 also used by invoice-extraction
20449
+ ---
20450
+ # Body describes the full PO extraction flow:
20451
+ # 1. Use [[engine-selection]] to pick best parser
20452
+ # 2. Find BP in document header
20453
+ # 3. Parse items table
20454
+ # ...
20455
+
20456
+ ---
20457
+ name: engine-selection
20458
+ description: Choose the best parsing engine based on document type
20459
+ ---
20460
+ # Body describes decision logic with confidence scores
20461
+ \`\`\`
20462
+
20463
+ Bad (over-split \u2014 these are never used independently):
20464
+ \`\`\`yaml
20465
+ ---
20466
+ name: po-bp-extraction
20467
+ description: Extract BP field from PO
20468
+ subSkills: []
20469
+ ---
20470
+ # This is always used with items-extraction and notes-extraction.
20471
+ # They should be one skill: po-extraction
20472
+ \`\`\`
20473
+
20474
+ ### Growing the Graph
20475
+
20476
+ Skills are discovered incrementally. When a learning task produces
20477
+ new knowledge:
20478
+
20479
+ 1. \`ls /root/.agents/knowledge/\` to see what already exists
20480
+ 2. If a reusable piece already exists \u2192 reference it via subSkills
20481
+ 3. If a reusable piece doesn't exist \u2192 create it, then reference it
20482
+ 4. If it's not reusable \u2192 keep it in the parent skill's body
20483
+
20484
+ The graph grows naturally \u2014 each new learning task adds nodes
20485
+ and edges by creating skills and declaring subSkills.
20486
+
20487
+ ---
20488
+
20489
+ ## Verifying subSkills Are Correct
20490
+
20491
+ After writing the body, check consistency between frontmatter and content.
20492
+ You MUST run these checks before finalizing the skill.
20493
+
20494
+ ### Self-Check Rules
20495
+
20496
+ **For each entry in subSkills:**
20497
+ Find where in the body it's actually referenced. If you can't find it \u2014
20498
+ either the body is missing the reference, or the subSkill shouldn't
20499
+ be there.
20500
+
20501
+ **For each skill referenced in the body:**
20502
+ Check that it appears in subSkills. If the body references a skill
20503
+ but subSkills doesn't list it \u2014 add it.
20504
+
20505
+ ### Automated Consistency Check
20506
+
20507
+ Since body references use \`[[skill-name]]\` format, you can verify
20508
+ automatically:
20509
+
20510
+ \`\`\`bash
20511
+ # Extract all skill references from body
20512
+ grep -oE '\\[\\[[^]]+\\]\\]' /root/.agents/skills/{skill-name}/SKILL.md \\
20513
+ | sed 's/\\[\\[//;s/\\]\\]//' | sort -u
20514
+
20515
+ # Then compare with the subSkills list in frontmatter.
20516
+ # Every [[ref]] in body should have a corresponding subSkills entry.
20517
+ # Every subSkills entry should appear as [[ref]] somewhere in body.
20518
+ \`\`\`
20519
+
20520
+ ### Quick Checklist Before Writing
20521
+
20522
+ 1. List all subSkills in frontmatter
20523
+ 2. grep the body for each name using \`[[name]]\` format \u2014 does it appear?
20524
+ 3. grep the body for \`[[...]]\` patterns \u2014 are they all in subSkills?
20525
+ 4. Mismatches \u2192 fix either the body or the frontmatter
20526
+ 5. Remove any subSkills entry that's never referenced in the body
20527
+
20528
+ ---
20529
+
20530
+ ## Referencing Other Skills in the Body
20531
+
20532
+ When the body instructs the agent to consult another skill,
20533
+ use the \`[[skill-name]]\` format:
20534
+
20535
+ \`\`\`markdown
20536
+ ## Procedure
20537
+
20538
+ 1. First, use [[engine-selection]] to pick the best parsing engine
20539
+ 2. Load [[sap-bp-validation]] to verify the extracted Business Partner
20540
+ 3. For edge cases, refer to [[ocr-fallback]]
20541
+
20542
+ ## Dependencies
20543
+
20544
+ This skill depends on:
20545
+ - [[engine-selection]] \u2014 chooses the parsing engine
20546
+ - [[sap-bp-validation]] \u2014 validates BP codes against SAP
20547
+ \`\`\`
20548
+
20549
+ ### Why [[wiki-links]]
20550
+
20551
+ - **Visually distinct** \u2014 clearly not regular text
20552
+ - **Grepable** \u2014 \`grep -o '\\[\\[.*?\\]\\]'\` extracts all references
20553
+ - **Verifiable** \u2014 the consistency check against subSkills can be automated
20554
+ - **Human-readable** \u2014 anyone reading the SKILL.md knows this is a skill reference
20555
+
20556
+ ### Rules
20557
+ - Always use the exact skill name (kebab-case) inside \`[[]]\`
20558
+ - Before writing, check each referenced skill:
20559
+ - If it exists \u2014 reference it directly
20560
+ - If it doesn't exist \u2014 create it first, then reference it in the parent
20561
+ - Every \`[[ref]]\` in the body must have a corresponding \`subSkills\` entry
20562
+ - Every \`subSkills\` entry must appear as \`[[ref]]\` somewhere in the body
20563
+
20564
+ ---
20565
+
19597
20566
  ## Writing Guide
19598
20567
 
19599
20568
  ### The Description Field
@@ -19644,6 +20613,7 @@ A well-written skill body typically includes:
19644
20613
  - **Guidelines**: Rules, constraints, quality standards, and the WHY behind them
19645
20614
  - **Scenarios**: 2-3 common scenarios with concrete examples of inputs and expected outputs
19646
20615
  - **Edge cases**: What to do when things go wrong, when data is missing, etc.
20616
+ - **Skill references**: Use \`[[skill-name]]\` to reference other skills \u2014 see the subSkills section above
19647
20617
 
19648
20618
  ---
19649
20619
 
@@ -19651,10 +20621,11 @@ A well-written skill body typically includes:
19651
20621
 
19652
20622
  After writing the draft, test it:
19653
20623
 
19654
- 1. **Create 2-3 test prompts** \u2014 the kind of thing a real user would actually say. Share them with the user: "Here are a few test cases I'd like to try. Do these look right?"
19655
- 2. **Run the skill** against each test prompt to see what the agent produces
19656
- 3. **Review outputs with the user**: evaluate both qualitatively (does the output look right?) and quantitatively (did it follow the workflow? use the right tools?)
19657
- 4. **Collect feedback**: What worked? What didn't? What surprised the user?
20624
+ 1. **Run the consistency check** from the Verifying subSkills section \u2014 fix any mismatches
20625
+ 2. **Create 2-3 test prompts** \u2014 the kind of thing a real user would actually say. Share them with the user: "Here are a few test cases I'd like to try. Do these look right?"
20626
+ 3. **Run the skill** against each test prompt to see what the agent produces
20627
+ 4. **Review outputs with the user**: evaluate both qualitatively (does the output look right?) and quantitatively (did it follow the workflow? use the right tools?)
20628
+ 5. **Collect feedback**: What worked? What didn't? What surprised the user?
19658
20629
 
19659
20630
  ### Improving the Skill
19660
20631
 
@@ -19690,10 +20661,11 @@ The agent sees skills as a list of name + description pairs. It decides whether
19690
20661
  ## Step 6: Package and Present
19691
20662
 
19692
20663
  When the skill is ready:
19693
- 1. Verify the SKILL.md is at \`/root/.agents/skills/{skill-name}/SKILL.md\` with correct frontmatter
19694
- 2. Confirm all resource files are in place under \`resources/\`
19695
- 3. Tell the user the skill is ready and available at its path
19696
- 4. Remind them that the skill will now appear in the available skills list for any agent using the skill system
20664
+ 1. Run the subSkills consistency check one final time
20665
+ 2. Verify the SKILL.md is at \`/root/.agents/skills/{skill-name}/SKILL.md\` with correct frontmatter
20666
+ 3. Confirm all resource files are in place under \`resources/\`
20667
+ 4. Tell the user the skill is ready and available at its path
20668
+ 5. Remind them that the skill will now appear in the available skills list for any agent using the skill system
19697
20669
 
19698
20670
  ## Updating Existing Skills
19699
20671
 
@@ -19702,7 +20674,8 @@ When the user wants to improve an existing skill:
19702
20674
  2. Understand what it currently does and where it falls short
19703
20675
  3. Follow the same interview \u2192 draft \u2192 test \u2192 iterate loop
19704
20676
  4. **Preserve the original name** \u2014 the directory name and \`name\` frontmatter field should stay the same
19705
- 5. Write the updated version back to the same path
20677
+ 5. Run the subSkills consistency check after making changes
20678
+ 6. Write the updated version back to the same path
19706
20679
 
19707
20680
  ---
19708
20681
 
@@ -19736,6 +20709,8 @@ metadata:
19736
20709
 
19737
20710
  **You** (write): Create \`/root/.agents/skills/csv-analyzer/SKILL.md\`
19738
20711
 
20712
+ **You** (verify): Run the subSkills consistency check \u2014 no subSkills, no \`[[refs]]\`, all good.
20713
+
19739
20714
  **You** (test): "Here are 3 test cases \u2014 'summarize this sales CSV', 'filter rows where region is West', 'show monthly revenue trends'. Let me run these and we'll review."
19740
20715
 
19741
20716
  Then iterate based on what the user says.
@@ -20795,8 +21770,8 @@ var InMemoryMenuStore = class {
20795
21770
  };
20796
21771
 
20797
21772
  // src/agent_lattice/agentArchitectTools.ts
20798
- var import_zod47 = __toESM(require("zod"));
20799
- var import_uuid7 = require("uuid");
21773
+ var import_zod48 = __toESM(require("zod"));
21774
+ var import_uuid8 = require("uuid");
20800
21775
  var import_protocols12 = require("@axiom-lattice/protocols");
20801
21776
  function getTenantId(exeConfig) {
20802
21777
  const runConfig = exeConfig?.configurable?.runConfig || {};
@@ -20825,7 +21800,7 @@ registerToolLattice(
20825
21800
  {
20826
21801
  name: "list_agents",
20827
21802
  description: "List all agents for the current workspace. Returns a summary with id, name, description, and type for each agent.",
20828
- schema: import_zod47.default.object({})
21803
+ schema: import_zod48.default.object({})
20829
21804
  },
20830
21805
  async (_input, exeConfig) => {
20831
21806
  try {
@@ -20852,8 +21827,8 @@ registerToolLattice(
20852
21827
  {
20853
21828
  name: "get_agent",
20854
21829
  description: "Get the full configuration of a specific agent by its ID. Returns the complete AgentConfig including prompt, middleware, tools, and sub-agents.",
20855
- schema: import_zod47.default.object({
20856
- id: import_zod47.default.string().describe("The agent ID to retrieve")
21830
+ schema: import_zod48.default.object({
21831
+ id: import_zod48.default.string().describe("The agent ID to retrieve")
20857
21832
  })
20858
21833
  },
20859
21834
  async (input, exeConfig) => {
@@ -20870,24 +21845,24 @@ registerToolLattice(
20870
21845
  }
20871
21846
  }
20872
21847
  );
20873
- var middlewareConfigSchema = import_zod47.default.object({
20874
- id: import_zod47.default.string(),
20875
- type: import_zod47.default.string(),
20876
- name: import_zod47.default.string(),
20877
- description: import_zod47.default.string(),
20878
- enabled: import_zod47.default.boolean(),
20879
- config: import_zod47.default.record(import_zod47.default.any()).optional()
21848
+ var middlewareConfigSchema = import_zod48.default.object({
21849
+ id: import_zod48.default.string(),
21850
+ type: import_zod48.default.string(),
21851
+ name: import_zod48.default.string(),
21852
+ description: import_zod48.default.string(),
21853
+ enabled: import_zod48.default.boolean(),
21854
+ config: import_zod48.default.record(import_zod48.default.any()).optional()
20880
21855
  });
20881
- var createAgentSchema = import_zod47.default.object({
20882
- name: import_zod47.default.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')."),
20883
- description: import_zod47.default.string().optional().describe("Short description"),
20884
- type: import_zod47.default.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."),
20885
- prompt: import_zod47.default.string().describe("System prompt for the agent"),
20886
- tools: import_zod47.default.array(import_zod47.default.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."),
20887
- middleware: import_zod47.default.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: {}."),
20888
- subAgents: import_zod47.default.array(import_zod47.default.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
20889
- internalSubAgents: import_zod47.default.array(import_zod47.default.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
20890
- modelKey: import_zod47.default.string().optional().describe("Model key to use")
21856
+ var createAgentSchema = import_zod48.default.object({
21857
+ name: import_zod48.default.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')."),
21858
+ description: import_zod48.default.string().optional().describe("Short description"),
21859
+ type: import_zod48.default.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."),
21860
+ prompt: import_zod48.default.string().describe("System prompt for the agent"),
21861
+ tools: import_zod48.default.array(import_zod48.default.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."),
21862
+ middleware: import_zod48.default.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: {}."),
21863
+ subAgents: import_zod48.default.array(import_zod48.default.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
21864
+ internalSubAgents: import_zod48.default.array(import_zod48.default.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
21865
+ modelKey: import_zod48.default.string().optional().describe("Model key to use")
20891
21866
  });
20892
21867
  registerToolLattice(
20893
21868
  "create_agent",
@@ -20925,14 +21900,14 @@ registerToolLattice(
20925
21900
  }
20926
21901
  }
20927
21902
  );
20928
- var createWorkflowSchema = import_zod47.default.object({
20929
- name: import_zod47.default.string().describe("Display name for the workflow agent"),
20930
- description: import_zod47.default.string().optional().describe("Short description"),
20931
- skillLoaded: import_zod47.default.literal(true).describe("MUST be true. Set after loading the 'create-workflow' skill."),
20932
- yaml: import_zod47.default.string().describe("The YAML workflow definition in linear DSL format (steps execute top-to-bottom, use parallel: for concurrency)"),
20933
- tools: import_zod47.default.array(import_zod47.default.string()).optional().describe("Tool keys for the workflow agent"),
20934
- middleware: import_zod47.default.array(middlewareConfigSchema).optional().describe("Middleware configs"),
20935
- modelKey: import_zod47.default.string().optional().describe("Model key")
21903
+ var createWorkflowSchema = import_zod48.default.object({
21904
+ name: import_zod48.default.string().describe("Display name for the workflow agent"),
21905
+ description: import_zod48.default.string().optional().describe("Short description"),
21906
+ skillLoaded: import_zod48.default.literal(true).describe("MUST be true. Set after loading the 'create-workflow' skill."),
21907
+ yaml: import_zod48.default.string().describe("The YAML workflow definition in linear DSL format (steps execute top-to-bottom, use parallel: for concurrency)"),
21908
+ tools: import_zod48.default.array(import_zod48.default.string()).optional().describe("Tool keys for the workflow agent"),
21909
+ middleware: import_zod48.default.array(middlewareConfigSchema).optional().describe("Middleware configs"),
21910
+ modelKey: import_zod48.default.string().optional().describe("Model key")
20936
21911
  });
20937
21912
  registerToolLattice(
20938
21913
  "create_workflow",
@@ -20981,8 +21956,8 @@ registerToolLattice(
20981
21956
  {
20982
21957
  name: "validate_workflow",
20983
21958
  description: "Validate a workflow agent's DSL for correctness by compiling it.",
20984
- schema: import_zod47.default.object({
20985
- id: import_zod47.default.string().describe("The workflow agent ID to validate")
21959
+ schema: import_zod48.default.object({
21960
+ id: import_zod48.default.string().describe("The workflow agent ID to validate")
20986
21961
  })
20987
21962
  },
20988
21963
  async (input, exeConfig) => {
@@ -21079,14 +22054,14 @@ registerToolLattice(
21079
22054
  }
21080
22055
  }
21081
22056
  );
21082
- var updateWorkflowSchema = import_zod47.default.object({
21083
- id: import_zod47.default.string().describe("The workflow agent ID to update"),
21084
- name: import_zod47.default.string().optional().describe("New display name"),
21085
- description: import_zod47.default.string().optional().describe("New description"),
21086
- yaml: import_zod47.default.string().optional().describe("Replacement YAML workflow DSL. Omit to keep existing."),
21087
- tools: import_zod47.default.array(import_zod47.default.string()).optional().describe("Replacement tool keys"),
21088
- middleware: import_zod47.default.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
21089
- modelKey: import_zod47.default.string().optional().describe("Replacement model key")
22057
+ var updateWorkflowSchema = import_zod48.default.object({
22058
+ id: import_zod48.default.string().describe("The workflow agent ID to update"),
22059
+ name: import_zod48.default.string().optional().describe("New display name"),
22060
+ description: import_zod48.default.string().optional().describe("New description"),
22061
+ yaml: import_zod48.default.string().optional().describe("Replacement YAML workflow DSL. Omit to keep existing."),
22062
+ tools: import_zod48.default.array(import_zod48.default.string()).optional().describe("Replacement tool keys"),
22063
+ middleware: import_zod48.default.array(middlewareConfigSchema).optional().describe("Replacement middleware configs"),
22064
+ modelKey: import_zod48.default.string().optional().describe("Replacement model key")
21090
22065
  });
21091
22066
  registerToolLattice(
21092
22067
  "update_workflow",
@@ -21147,18 +22122,18 @@ registerToolLattice(
21147
22122
  }
21148
22123
  }
21149
22124
  );
21150
- var updateAgentSchema = import_zod47.default.object({
21151
- id: import_zod47.default.string().describe("The agent ID to update"),
21152
- config: import_zod47.default.object({
21153
- name: import_zod47.default.string().optional().describe("New display name for the agent"),
21154
- description: import_zod47.default.string().optional().describe("New short description"),
21155
- type: import_zod47.default.enum(["react", "deep_agent"]).optional().describe("Agent type"),
21156
- prompt: import_zod47.default.string().optional().describe("New system prompt for the agent"),
21157
- tools: import_zod47.default.array(import_zod47.default.string()).optional().describe("Tool keys to assign to this agent. These are registered tool names (strings), NOT middleware objects."),
21158
- middleware: import_zod47.default.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: {}."),
21159
- subAgents: import_zod47.default.array(import_zod47.default.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
21160
- internalSubAgents: import_zod47.default.array(import_zod47.default.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
21161
- modelKey: import_zod47.default.string().optional().describe("Model key to use")
22125
+ var updateAgentSchema = import_zod48.default.object({
22126
+ id: import_zod48.default.string().describe("The agent ID to update"),
22127
+ config: import_zod48.default.object({
22128
+ name: import_zod48.default.string().optional().describe("New display name for the agent"),
22129
+ description: import_zod48.default.string().optional().describe("New short description"),
22130
+ type: import_zod48.default.enum(["react", "deep_agent"]).optional().describe("Agent type"),
22131
+ prompt: import_zod48.default.string().optional().describe("New system prompt for the agent"),
22132
+ tools: import_zod48.default.array(import_zod48.default.string()).optional().describe("Tool keys to assign to this agent. These are registered tool names (strings), NOT middleware objects."),
22133
+ middleware: import_zod48.default.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: {}."),
22134
+ subAgents: import_zod48.default.array(import_zod48.default.string()).optional().describe("Sub-agent IDs (deep_agent only)"),
22135
+ internalSubAgents: import_zod48.default.array(import_zod48.default.any()).optional().describe("Inline sub-agent configs (deep_agent only)"),
22136
+ modelKey: import_zod48.default.string().optional().describe("Model key to use")
21162
22137
  }).describe("Configuration fields to update. Only include the fields you want to change.")
21163
22138
  });
21164
22139
  registerToolLattice(
@@ -21196,8 +22171,8 @@ registerToolLattice(
21196
22171
  {
21197
22172
  name: "delete_agent",
21198
22173
  description: "Permanently delete an agent by its ID. This action cannot be undone.",
21199
- schema: import_zod47.default.object({
21200
- id: import_zod47.default.string().describe("The agent ID to delete")
22174
+ schema: import_zod48.default.object({
22175
+ id: import_zod48.default.string().describe("The agent ID to delete")
21201
22176
  })
21202
22177
  },
21203
22178
  async (input, exeConfig) => {
@@ -21223,7 +22198,7 @@ registerToolLattice(
21223
22198
  {
21224
22199
  name: "list_tools",
21225
22200
  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.",
21226
- schema: import_zod47.default.object({})
22201
+ schema: import_zod48.default.object({})
21227
22202
  },
21228
22203
  async (_input, _exeConfig) => {
21229
22204
  try {
@@ -21245,9 +22220,9 @@ registerToolLattice(
21245
22220
  {
21246
22221
  name: "invoke_agent",
21247
22222
  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).",
21248
- schema: import_zod47.default.object({
21249
- id: import_zod47.default.string().describe("The agent ID to invoke"),
21250
- message: import_zod47.default.string().describe("The test message to send to the agent")
22223
+ schema: import_zod48.default.object({
22224
+ id: import_zod48.default.string().describe("The agent ID to invoke"),
22225
+ message: import_zod48.default.string().describe("The test message to send to the agent")
21251
22226
  })
21252
22227
  },
21253
22228
  async (input, exeConfig) => {
@@ -21262,7 +22237,7 @@ registerToolLattice(
21262
22237
  if (!existing) {
21263
22238
  return JSON.stringify({ error: `Agent '${id}' not found` });
21264
22239
  }
21265
- const threadId = (0, import_uuid7.v4)();
22240
+ const threadId = (0, import_uuid8.v4)();
21266
22241
  const agent = new Agent({
21267
22242
  tenant_id: tenantId2,
21268
22243
  assistant_id: id,
@@ -21283,7 +22258,7 @@ registerToolLattice(
21283
22258
  {
21284
22259
  name: "list_middleware_types",
21285
22260
  description: "\u5217\u51FA\u5F53\u524D\u7CFB\u7EDF\u4E2D\u6240\u6709\u53EF\u7528\u7684\u4E2D\u95F4\u4EF6\u7C7B\u578B\uFF08Middlewares\uFF09\uFF0C\u5305\u62EC\u5185\u7F6E\u548C\u81EA\u5B9A\u4E49\u63D2\u4EF6\u3002\u8FD4\u56DE\u6BCF\u4E2A\u4E2D\u95F4\u4EF6\u7684 type\u3001name\u3001description\u3001tools \u6E05\u5355\uFF08\u652F\u6301 allowedTools \u8FC7\u6EE4\uFF09\u3001configSchema\uFF08\u914D\u7F6E\u9762\u677F\u9700\u8981\u54EA\u4E9B\u5B57\u6BB5\uFF09\u548C connectionSchema\uFF08\u662F\u5426\u652F\u6301\u8FDE\u63A5\u6D4B\u8BD5\u548C\u8D44\u6E90\u53D1\u73B0\uFF09\u3002\n\n\u4F7F\u7528\u573A\u666F\uFF1A\n1. \u5728\u521B\u5EFA agent \u524D\uFF0C\u5148\u8C03\u6B64\u5DE5\u5177\u4E86\u89E3\u6709\u54EA\u4E9B\u4E2D\u95F4\u4EF6\u53EF\u914D\u7F6E\n2. \u6839\u636E configSchema \u51B3\u5B9A\u9700\u8981\u63D0\u4F9B\u54EA\u4E9B\u914D\u7F6E\u5B57\u6BB5\uFF08\u5982 databaseKeys\u3001connections \u7B49\uFF09\n3. \u5982\u679C\u67D0\u4E2A\u4E2D\u95F4\u4EF6\u7684 connectionSchema \u5B58\u5728\uFF0C\u8BF4\u660E\u5B83\u662F\u8FDE\u63A5\u578B\u4E2D\u95F4\u4EF6\uFF0C\u9700\u8981\u518D\u8C03 list_connections \u83B7\u53D6\u53EF\u7528\u8FDE\u63A5\n4. \u7528\u8FD4\u56DE\u7684 type \u5B57\u6BB5\u6784\u5EFA middleware \u6570\u7EC4\u4F20\u7ED9 create_agent / update_agent",
21286
- schema: import_zod47.default.object({})
22261
+ schema: import_zod48.default.object({})
21287
22262
  },
21288
22263
  async () => {
21289
22264
  const metas = PluginRegistry.listMeta();
@@ -21295,8 +22270,8 @@ registerToolLattice(
21295
22270
  {
21296
22271
  name: "list_connections",
21297
22272
  description: "\u5217\u51FA\u6307\u5B9A\u63D2\u4EF6\u7C7B\u578B\u7684\u6240\u6709\u5DF2\u914D\u7F6E\u8FDE\u63A5\u3002\u7528\u4E8E\u67E5\u8BE2\u6709\u54EA\u4E9B\u53EF\u7528\u7684\u8FDE\u63A5\u5B9E\u4F8B\uFF08\u5982 'sap-prod', 'sap-dev'\uFF09\uFF0C\u65B9\u4FBF\u5728 agent \u914D\u7F6E\u4E2D\u9009\u62E9\u5177\u4F53\u8FDE\u63A5\u3002\n\n\u4F7F\u7528\u573A\u666F\uFF1A\n1. \u5148\u8C03 list_middleware_types \u786E\u5B9A\u67D0\u4E2A\u4E2D\u95F4\u4EF6\u662F\u8FDE\u63A5\u578B\uFF08\u6709 connectionSchema\uFF09\n2. \u8C03\u6B64\u5DE5\u5177\u4F20\u5165 type\uFF08\u5982 'erp'\uFF09\uFF0C\u83B7\u53D6\u8BE5\u7C7B\u578B\u4E0B\u5DF2\u914D\u597D\u7684\u8FDE\u63A5\u5217\u8868\n3. \u5728 create_agent \u7684 middleware[i].config.connections \u4E2D\u586B\u5165\u5BF9\u5E94\u7684 key \u503C\n\n\u8FD4\u56DE\u683C\u5F0F\uFF1A{ success: true, data: { records: [{ key, name, ... }] } }",
21298
- schema: import_zod47.default.object({
21299
- type: import_zod47.default.string().describe("\u63D2\u4EF6\u7C7B\u578B\u6807\u8BC6\uFF0C\u5982 'erp'\u3002\u4ECE list_middleware_types \u7684\u8FD4\u56DE\u4E2D\u83B7\u53D6")
22273
+ schema: import_zod48.default.object({
22274
+ type: import_zod48.default.string().describe("\u63D2\u4EF6\u7C7B\u578B\u6807\u8BC6\uFF0C\u5982 'erp'\u3002\u4ECE list_middleware_types \u7684\u8FD4\u56DE\u4E2D\u83B7\u53D6")
21300
22275
  }),
21301
22276
  needUserApprove: false
21302
22277
  },
@@ -21877,6 +22852,20 @@ function ensureBuiltinAgentsForTenant(tenantId2) {
21877
22852
  }
21878
22853
  }
21879
22854
 
22855
+ // src/agent_lattice/pluginAgents.ts
22856
+ function ensurePluginAgentsForTenant(tenantId2) {
22857
+ const pluginTypes = PluginRegistry.list();
22858
+ for (const pluginType of pluginTypes) {
22859
+ const plugin = PluginRegistry.get(pluginType);
22860
+ if (!plugin?.agents) continue;
22861
+ for (const [key4, config] of Object.entries(plugin.agents)) {
22862
+ if (!agentLatticeManager.hasWithTenant(tenantId2, key4)) {
22863
+ agentLatticeManager.registerLatticeWithTenant(tenantId2, config);
22864
+ }
22865
+ }
22866
+ }
22867
+ }
22868
+
21880
22869
  // src/agent_lattice/AgentLatticeManager.ts
21881
22870
  function assistantToConfig(assistant) {
21882
22871
  const graphDef = typeof assistant.graphDefinition === "object" && assistant.graphDefinition !== null ? { ...assistant.graphDefinition } : {};
@@ -22075,6 +23064,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
22075
23064
  */
22076
23065
  async initializeStoredAssistantsForTenant(tenantId2) {
22077
23066
  ensureBuiltinAgentsForTenant(tenantId2);
23067
+ ensurePluginAgentsForTenant(tenantId2);
22078
23068
  try {
22079
23069
  const storeLattice = getStoreLattice("default", "assistant");
22080
23070
  const assistants = await storeLattice.store.getAllAssistants(tenantId2);
@@ -25254,8 +26244,8 @@ function clearEvalRunService() {
25254
26244
  }
25255
26245
 
25256
26246
  // src/eval_lattice/LatticeEval.ts
25257
- var import_messages5 = require("@langchain/core/messages");
25258
- var import_uuid8 = require("uuid");
26247
+ var import_messages6 = require("@langchain/core/messages");
26248
+ var import_uuid9 = require("uuid");
25259
26249
  var _LatticeEval = class _LatticeEval {
25260
26250
  constructor(config = {}) {
25261
26251
  this.inMemoryLogs = [];
@@ -25395,7 +26385,7 @@ var _LatticeEval = class _LatticeEval {
25395
26385
  }
25396
26386
  async evaluateCase(evalCase) {
25397
26387
  const startedAt = Date.now();
25398
- const threadId = `${evalCase.caseId}||${(0, import_uuid8.v4)()}`;
26388
+ const threadId = `${evalCase.caseId}||${(0, import_uuid9.v4)()}`;
25399
26389
  this.inMemoryLogs = [];
25400
26390
  this.lastThreadId = threadId;
25401
26391
  this.lastJudgeThreadId = void 0;
@@ -25537,7 +26527,7 @@ ${rubricsSection}
25537
26527
 
25538
26528
  \u6CE8\u610F\uFF1A\u5982\u679C final_score >= 80 \u4E14\u6CA1\u6709\u81F4\u547D\u6027\u9519\u8BEF\uFF0Cpass \u5E94\u4E3A true\uFF1B\u5426\u5219\u4E3A false\u3002`;
25539
26529
  this.lastTestPrompt = testPrompt;
25540
- const judgeThreadId = (0, import_uuid8.v4)();
26530
+ const judgeThreadId = (0, import_uuid9.v4)();
25541
26531
  this.lastJudgeThreadId = judgeThreadId;
25542
26532
  const judgeAgentKey = this.config.judge_agent_key || "LatticeTest";
25543
26533
  const judgeTenantId = this.config.tenant_id || "default";
@@ -25545,7 +26535,7 @@ ${rubricsSection}
25545
26535
  const judgeAgent = await getAgentClient(judgeTenantId, judgeAgentKey);
25546
26536
  const testResponse = await judgeAgent.invoke(
25547
26537
  {
25548
- messages: [new import_messages5.HumanMessage(testPrompt)]
26538
+ messages: [new import_messages6.HumanMessage(testPrompt)]
25549
26539
  },
25550
26540
  {
25551
26541
  configurable: {
@@ -26137,15 +27127,15 @@ function clearEncryptionKeyCache() {
26137
27127
  }
26138
27128
 
26139
27129
  // src/middlewares/skillMiddleware.ts
26140
- var import_langchain59 = require("langchain");
27130
+ var import_langchain60 = require("langchain");
26141
27131
 
26142
27132
  // src/tool_lattice/skill/load_skills.ts
26143
- var import_zod48 = __toESM(require("zod"));
26144
- var import_langchain57 = require("langchain");
26145
-
26146
- // src/tool_lattice/skill/load_skill_content.ts
26147
27133
  var import_zod49 = __toESM(require("zod"));
26148
27134
  var import_langchain58 = require("langchain");
27135
+
27136
+ // src/tool_lattice/skill/load_skill_content.ts
27137
+ var import_zod50 = __toESM(require("zod"));
27138
+ var import_langchain59 = require("langchain");
26149
27139
  var LOAD_SKILL_CONTENT_DESCRIPTION = `
26150
27140
  Execute a skill within the main conversation
26151
27141
 
@@ -26183,7 +27173,7 @@ function getSandboxFromExeConfig(_exe_config) {
26183
27173
  });
26184
27174
  }
26185
27175
  var createLoadSkillContentTool = (pluginSkillContents) => {
26186
- return (0, import_langchain58.tool)(
27176
+ return (0, import_langchain59.tool)(
26187
27177
  async (input, _exe_config) => {
26188
27178
  try {
26189
27179
  if (pluginSkillContents?.[input.skill_name]) {
@@ -26232,8 +27222,8 @@ var createLoadSkillContentTool = (pluginSkillContents) => {
26232
27222
  {
26233
27223
  name: "skill",
26234
27224
  description: LOAD_SKILL_CONTENT_DESCRIPTION,
26235
- schema: import_zod49.default.object({
26236
- skill_name: import_zod49.default.string().describe("The name of the skill to load")
27225
+ schema: import_zod50.default.object({
27226
+ skill_name: import_zod50.default.string().describe("The name of the skill to load")
26237
27227
  })
26238
27228
  }
26239
27229
  );
@@ -26247,7 +27237,7 @@ function createSkillMiddleware(params = {}) {
26247
27237
  } = params;
26248
27238
  const skills = params.skills;
26249
27239
  let latestSkills = [];
26250
- return (0, import_langchain59.createMiddleware)({
27240
+ return (0, import_langchain60.createMiddleware)({
26251
27241
  name: "skillMiddleware",
26252
27242
  contextSchema,
26253
27243
  tools: [
@@ -26379,17 +27369,17 @@ var skillPlugin = {
26379
27369
  };
26380
27370
 
26381
27371
  // src/middlewares/collectionMiddleware.ts
26382
- var import_langchain70 = require("langchain");
27372
+ var import_langchain71 = require("langchain");
26383
27373
 
26384
27374
  // src/tool_lattice/collection/list_collections.ts
26385
- var import_zod50 = __toESM(require("zod"));
26386
- var import_langchain60 = require("langchain");
27375
+ var import_zod51 = __toESM(require("zod"));
27376
+ var import_langchain61 = require("langchain");
26387
27377
  var LIST_COLLECTIONS_DESCRIPTION = `List all available collections for the current tenant. Returns collection names, labels, and field definitions (including field types and enum values). Use this tool to discover what collections are available before searching.`;
26388
27378
  var createListCollectionsTool = ({
26389
27379
  collectionKeys,
26390
27380
  connectAll
26391
27381
  }) => {
26392
- return (0, import_langchain60.tool)(
27382
+ return (0, import_langchain61.tool)(
26393
27383
  async (_input, _exeConfig) => {
26394
27384
  try {
26395
27385
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
@@ -26423,23 +27413,23 @@ var createListCollectionsTool = ({
26423
27413
  {
26424
27414
  name: "list_collections",
26425
27415
  description: LIST_COLLECTIONS_DESCRIPTION,
26426
- schema: import_zod50.default.object({})
27416
+ schema: import_zod51.default.object({})
26427
27417
  }
26428
27418
  );
26429
27419
  };
26430
27420
 
26431
27421
  // src/tool_lattice/collection/search_collection.ts
26432
- var import_zod51 = __toESM(require("zod"));
26433
- var import_langchain61 = require("langchain");
27422
+ var import_zod52 = __toESM(require("zod"));
27423
+ var import_langchain62 = require("langchain");
26434
27424
  var SEARCH_COLLECTION_DESCRIPTION = `Search for content within a specific collection using semantic (vector) similarity. Use the 'filter' parameter to narrow results by metadata fields (e.g., {"category": "cardiovascular"}). Returns the most relevant content entries with similarity scores.`;
26435
- var searchSchema = import_zod51.default.object({
26436
- collection: import_zod51.default.string().describe("The collection name to search in"),
26437
- query: import_zod51.default.string().describe("The search query text"),
26438
- filter: import_zod51.default.record(import_zod51.default.unknown()).optional().describe("Metadata filter conditions"),
26439
- top_k: import_zod51.default.number().optional().default(5).describe("Number of results to return")
27425
+ var searchSchema = import_zod52.default.object({
27426
+ collection: import_zod52.default.string().describe("The collection name to search in"),
27427
+ query: import_zod52.default.string().describe("The search query text"),
27428
+ filter: import_zod52.default.record(import_zod52.default.unknown()).optional().describe("Metadata filter conditions"),
27429
+ top_k: import_zod52.default.number().optional().default(5).describe("Number of results to return")
26440
27430
  });
26441
27431
  var createSearchCollectionTool = () => {
26442
- return (0, import_langchain61.tool)(
27432
+ return (0, import_langchain62.tool)(
26443
27433
  async (input, _exeConfig) => {
26444
27434
  try {
26445
27435
  const { collection, query, filter: filter2, top_k } = input;
@@ -26489,10 +27479,10 @@ var createSearchCollectionTool = () => {
26489
27479
  };
26490
27480
 
26491
27481
  // src/tool_lattice/collection/get_collection.ts
26492
- var import_zod52 = __toESM(require("zod"));
26493
- var import_langchain62 = require("langchain");
27482
+ var import_zod53 = __toESM(require("zod"));
27483
+ var import_langchain63 = require("langchain");
26494
27484
  var GET_COLLECTION_DESCRIPTION = `Get a collection's full definition including its custom fields schema. Use this to discover what metadata fields are available before adding entries.`;
26495
- var createGetCollectionTool = () => (0, import_langchain62.tool)(
27485
+ var createGetCollectionTool = () => (0, import_langchain63.tool)(
26496
27486
  async (input, _exeConfig) => {
26497
27487
  try {
26498
27488
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
@@ -26515,24 +27505,24 @@ Embedding: ${c.embeddingKey}${fieldsDesc}`;
26515
27505
  return `Error: ${error.message}`;
26516
27506
  }
26517
27507
  },
26518
- { name: "get_collection", description: GET_COLLECTION_DESCRIPTION, schema: import_zod52.default.object({ name: import_zod52.default.string().describe("Collection name") }) }
27508
+ { name: "get_collection", description: GET_COLLECTION_DESCRIPTION, schema: import_zod53.default.object({ name: import_zod53.default.string().describe("Collection name") }) }
26519
27509
  );
26520
27510
 
26521
27511
  // src/tool_lattice/collection/create_collection.ts
26522
- var import_zod53 = __toESM(require("zod"));
26523
- var import_langchain63 = require("langchain");
26524
- var createSchema = import_zod53.default.object({
26525
- name: import_zod53.default.string().describe("Collection name (lowercase, underscores only)"),
26526
- label: import_zod53.default.string().describe("Display name"),
26527
- embeddingKey: import_zod53.default.string().describe("Embedding model key"),
26528
- fields: import_zod53.default.array(import_zod53.default.object({
26529
- key: import_zod53.default.string().describe("Field key name"),
26530
- type: import_zod53.default.enum(["string", "number", "enum"]).describe("Field data type"),
26531
- enumValues: import_zod53.default.array(import_zod53.default.string()).optional().describe("Valid values for enum type"),
26532
- required: import_zod53.default.boolean().optional().default(false).describe("Whether field is required")
27512
+ var import_zod54 = __toESM(require("zod"));
27513
+ var import_langchain64 = require("langchain");
27514
+ var createSchema = import_zod54.default.object({
27515
+ name: import_zod54.default.string().describe("Collection name (lowercase, underscores only)"),
27516
+ label: import_zod54.default.string().describe("Display name"),
27517
+ embeddingKey: import_zod54.default.string().describe("Embedding model key"),
27518
+ fields: import_zod54.default.array(import_zod54.default.object({
27519
+ key: import_zod54.default.string().describe("Field key name"),
27520
+ type: import_zod54.default.enum(["string", "number", "enum"]).describe("Field data type"),
27521
+ enumValues: import_zod54.default.array(import_zod54.default.string()).optional().describe("Valid values for enum type"),
27522
+ required: import_zod54.default.boolean().optional().default(false).describe("Whether field is required")
26533
27523
  })).optional().describe("Custom field definitions for entries in this collection")
26534
27524
  });
26535
- var createCreateCollectionTool = () => (0, import_langchain63.tool)(
27525
+ var createCreateCollectionTool = () => (0, import_langchain64.tool)(
26536
27526
  async (input, _exeConfig) => {
26537
27527
  try {
26538
27528
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
@@ -26557,20 +27547,20 @@ var createCreateCollectionTool = () => (0, import_langchain63.tool)(
26557
27547
  );
26558
27548
 
26559
27549
  // src/tool_lattice/collection/update_collection.ts
26560
- var import_zod54 = __toESM(require("zod"));
26561
- var import_langchain64 = require("langchain");
26562
- var schema = import_zod54.default.object({
26563
- name: import_zod54.default.string().describe("Collection name"),
26564
- label: import_zod54.default.string().optional().describe("New display name"),
26565
- embeddingKey: import_zod54.default.string().optional().describe("New embedding model key"),
26566
- fields: import_zod54.default.array(import_zod54.default.object({
26567
- key: import_zod54.default.string().describe("Field key name"),
26568
- type: import_zod54.default.enum(["string", "number", "enum"]).describe("Field data type"),
26569
- enumValues: import_zod54.default.array(import_zod54.default.string()).optional().describe("Valid values for enum type"),
26570
- required: import_zod54.default.boolean().optional().default(false).describe("Whether field is required")
27550
+ var import_zod55 = __toESM(require("zod"));
27551
+ var import_langchain65 = require("langchain");
27552
+ var schema = import_zod55.default.object({
27553
+ name: import_zod55.default.string().describe("Collection name"),
27554
+ label: import_zod55.default.string().optional().describe("New display name"),
27555
+ embeddingKey: import_zod55.default.string().optional().describe("New embedding model key"),
27556
+ fields: import_zod55.default.array(import_zod55.default.object({
27557
+ key: import_zod55.default.string().describe("Field key name"),
27558
+ type: import_zod55.default.enum(["string", "number", "enum"]).describe("Field data type"),
27559
+ enumValues: import_zod55.default.array(import_zod55.default.string()).optional().describe("Valid values for enum type"),
27560
+ required: import_zod55.default.boolean().optional().default(false).describe("Whether field is required")
26571
27561
  })).optional().describe("Custom field definitions for entries (replaces existing schema)")
26572
27562
  });
26573
- var createUpdateCollectionTool = () => (0, import_langchain64.tool)(
27563
+ var createUpdateCollectionTool = () => (0, import_langchain65.tool)(
26574
27564
  async (input, _exeConfig) => {
26575
27565
  try {
26576
27566
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
@@ -26589,9 +27579,9 @@ var createUpdateCollectionTool = () => (0, import_langchain64.tool)(
26589
27579
  );
26590
27580
 
26591
27581
  // src/tool_lattice/collection/delete_collection.ts
26592
- var import_zod55 = __toESM(require("zod"));
26593
- var import_langchain65 = require("langchain");
26594
- var createDeleteCollectionTool = () => (0, import_langchain65.tool)(
27582
+ var import_zod56 = __toESM(require("zod"));
27583
+ var import_langchain66 = require("langchain");
27584
+ var createDeleteCollectionTool = () => (0, import_langchain66.tool)(
26595
27585
  async (input, _exeConfig) => {
26596
27586
  try {
26597
27587
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
@@ -26601,19 +27591,19 @@ var createDeleteCollectionTool = () => (0, import_langchain65.tool)(
26601
27591
  return `Error: ${e.message}`;
26602
27592
  }
26603
27593
  },
26604
- { name: "delete_collection", description: `Delete a collection and all its entries. This cannot be undone.`, schema: import_zod55.default.object({ name: import_zod55.default.string().describe("Collection name") }) }
27594
+ { name: "delete_collection", description: `Delete a collection and all its entries. This cannot be undone.`, schema: import_zod56.default.object({ name: import_zod56.default.string().describe("Collection name") }) }
26605
27595
  );
26606
27596
 
26607
27597
  // src/tool_lattice/collection/list_entries.ts
26608
- var import_zod56 = __toESM(require("zod"));
26609
- var import_langchain66 = require("langchain");
26610
- var schema2 = import_zod56.default.object({
26611
- collection: import_zod56.default.string().describe("Collection name")
27598
+ var import_zod57 = __toESM(require("zod"));
27599
+ var import_langchain67 = require("langchain");
27600
+ var schema2 = import_zod57.default.object({
27601
+ collection: import_zod57.default.string().describe("Collection name")
26612
27602
  });
26613
27603
  function buildKey2(tenantId2, name) {
26614
27604
  return `${tenantId2}:${name}`;
26615
27605
  }
26616
- var createListEntriesTool = () => (0, import_langchain66.tool)(
27606
+ var createListEntriesTool = () => (0, import_langchain67.tool)(
26617
27607
  async (input, _exeConfig) => {
26618
27608
  try {
26619
27609
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
@@ -26640,24 +27630,24 @@ var createListEntriesTool = () => (0, import_langchain66.tool)(
26640
27630
  );
26641
27631
 
26642
27632
  // src/tool_lattice/collection/add_entry.ts
26643
- var import_zod57 = __toESM(require("zod"));
26644
- var import_langchain67 = require("langchain");
27633
+ var import_zod58 = __toESM(require("zod"));
27634
+ var import_langchain68 = require("langchain");
26645
27635
  var import_documents = require("@langchain/core/documents");
26646
- var import_uuid9 = require("uuid");
26647
- var schema3 = import_zod57.default.object({
26648
- collection: import_zod57.default.string().describe("Collection name"),
26649
- content: import_zod57.default.string().describe("Entry content text"),
26650
- metadata: import_zod57.default.record(import_zod57.default.unknown()).optional().describe("Metadata fields matching the collection schema")
27636
+ var import_uuid10 = require("uuid");
27637
+ var schema3 = import_zod58.default.object({
27638
+ collection: import_zod58.default.string().describe("Collection name"),
27639
+ content: import_zod58.default.string().describe("Entry content text"),
27640
+ metadata: import_zod58.default.record(import_zod58.default.unknown()).optional().describe("Metadata fields matching the collection schema")
26651
27641
  });
26652
27642
  function key(t, n) {
26653
27643
  return `${t}:${n}`;
26654
27644
  }
26655
- var createAddEntryTool = () => (0, import_langchain67.tool)(
27645
+ var createAddEntryTool = () => (0, import_langchain68.tool)(
26656
27646
  async (input, _exeConfig) => {
26657
27647
  try {
26658
27648
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
26659
27649
  const vs = vectorStoreLatticeManager.getVectorStoreClient(key(tenantId2, input.collection));
26660
- const id = (0, import_uuid9.v4)();
27650
+ const id = (0, import_uuid10.v4)();
26661
27651
  await vs.addDocuments([new import_documents.Document({
26662
27652
  pageContent: input.content,
26663
27653
  metadata: { _id: id, _created_at: (/* @__PURE__ */ new Date()).toISOString(), ...input.metadata || {} }
@@ -26671,18 +27661,18 @@ var createAddEntryTool = () => (0, import_langchain67.tool)(
26671
27661
  );
26672
27662
 
26673
27663
  // src/tool_lattice/collection/update_entry.ts
26674
- var import_zod58 = __toESM(require("zod"));
26675
- var import_langchain68 = require("langchain");
26676
- var schema4 = import_zod58.default.object({
26677
- collection: import_zod58.default.string().describe("Collection name"),
26678
- entryId: import_zod58.default.string().describe("Entry ID to update"),
26679
- content: import_zod58.default.string().optional().describe("New content"),
26680
- metadata: import_zod58.default.record(import_zod58.default.unknown()).optional().describe("New metadata")
27664
+ var import_zod59 = __toESM(require("zod"));
27665
+ var import_langchain69 = require("langchain");
27666
+ var schema4 = import_zod59.default.object({
27667
+ collection: import_zod59.default.string().describe("Collection name"),
27668
+ entryId: import_zod59.default.string().describe("Entry ID to update"),
27669
+ content: import_zod59.default.string().optional().describe("New content"),
27670
+ metadata: import_zod59.default.record(import_zod59.default.unknown()).optional().describe("New metadata")
26681
27671
  });
26682
27672
  function key2(t, n) {
26683
27673
  return `${t}:${n}`;
26684
27674
  }
26685
- var createUpdateEntryTool = () => (0, import_langchain68.tool)(
27675
+ var createUpdateEntryTool = () => (0, import_langchain69.tool)(
26686
27676
  async (input, _exeConfig) => {
26687
27677
  try {
26688
27678
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
@@ -26701,16 +27691,16 @@ var createUpdateEntryTool = () => (0, import_langchain68.tool)(
26701
27691
  );
26702
27692
 
26703
27693
  // src/tool_lattice/collection/delete_entry.ts
26704
- var import_zod59 = __toESM(require("zod"));
26705
- var import_langchain69 = require("langchain");
26706
- var schema5 = import_zod59.default.object({
26707
- collection: import_zod59.default.string().describe("Collection name"),
26708
- entryId: import_zod59.default.string().describe("Entry ID to delete")
27694
+ var import_zod60 = __toESM(require("zod"));
27695
+ var import_langchain70 = require("langchain");
27696
+ var schema5 = import_zod60.default.object({
27697
+ collection: import_zod60.default.string().describe("Collection name"),
27698
+ entryId: import_zod60.default.string().describe("Entry ID to delete")
26709
27699
  });
26710
27700
  function key3(t, n) {
26711
27701
  return `${t}:${n}`;
26712
27702
  }
26713
- var createDeleteEntryTool = () => (0, import_langchain69.tool)(
27703
+ var createDeleteEntryTool = () => (0, import_langchain70.tool)(
26714
27704
  async (input, _exeConfig) => {
26715
27705
  try {
26716
27706
  const tenantId2 = _exeConfig?.configurable?.runConfig?.tenantId || "default";
@@ -26728,7 +27718,7 @@ var createDeleteEntryTool = () => (0, import_langchain69.tool)(
26728
27718
  function createCollectionMiddleware(params) {
26729
27719
  const { collectionKeys, connectAll } = params;
26730
27720
  if (!connectAll && (!collectionKeys || collectionKeys.length === 0)) {
26731
- return (0, import_langchain70.createMiddleware)({
27721
+ return (0, import_langchain71.createMiddleware)({
26732
27722
  name: "collectionMiddleware",
26733
27723
  contextSchema,
26734
27724
  tools: [
@@ -26738,7 +27728,7 @@ function createCollectionMiddleware(params) {
26738
27728
  });
26739
27729
  }
26740
27730
  const listToolParams = { collectionKeys, connectAll };
26741
- return (0, import_langchain70.createMiddleware)({
27731
+ return (0, import_langchain71.createMiddleware)({
26742
27732
  name: "collectionMiddleware",
26743
27733
  contextSchema,
26744
27734
  tools: [
@@ -26799,24 +27789,24 @@ var collectionPlugin = {
26799
27789
  };
26800
27790
 
26801
27791
  // src/middlewares/askUserClarifyMiddleware.ts
26802
- var import_langchain72 = require("langchain");
27792
+ var import_langchain73 = require("langchain");
26803
27793
  var import_langgraph14 = require("@langchain/langgraph");
26804
27794
 
26805
27795
  // src/tool_lattice/ask_user_to_clarify/index.ts
26806
- var import_langchain71 = require("langchain");
26807
- var import_zod60 = __toESM(require("zod"));
26808
- var questionSchema = import_zod60.default.object({
26809
- question: import_zod60.default.string().describe("The question text to ask the user"),
26810
- options: import_zod60.default.array(import_zod60.default.string()).optional().default([]).describe("List of EXACT, selectable values. Maximum 3 options allowed. DO NOT include placeholder values like 'Other' or 'Enter manually'. For free-text with predefined choices, use allowOther=true (works with 'single' and 'multiple'). For pure free-text without choices, use type='input' instead. For file_upload and input, pass an empty array."),
26811
- type: import_zod60.default.enum(["single", "multiple", "file_upload", "input"]).describe("The question format. 'single' = pick one from options (default, see tool description for guidance). 'multiple' = pick several from options. 'input' = free-text field (only when options cannot express the answer). 'file_upload' = file picker."),
26812
- required: import_zod60.default.boolean().optional().default(false).describe("Whether this question must be answered"),
26813
- allowOther: import_zod60.default.boolean().optional().default(true).describe("Set to true to append an 'Other' checkbox with a free-text input field. Works with 'single' and 'multiple' types. Use for open-ended answers or when the options cannot cover all possibilities. Not applicable for 'input' or 'file_upload' types.")
27796
+ var import_langchain72 = require("langchain");
27797
+ var import_zod61 = __toESM(require("zod"));
27798
+ var questionSchema = import_zod61.default.object({
27799
+ question: import_zod61.default.string().describe("The question text to ask the user"),
27800
+ options: import_zod61.default.array(import_zod61.default.string()).optional().default([]).describe("List of EXACT, selectable values. Maximum 3 options allowed. DO NOT include placeholder values like 'Other' or 'Enter manually'. For free-text with predefined choices, use allowOther=true (works with 'single' and 'multiple'). For pure free-text without choices, use type='input' instead. For file_upload and input, pass an empty array."),
27801
+ type: import_zod61.default.enum(["single", "multiple", "file_upload", "input"]).describe("The question format. 'single' = pick one from options (default, see tool description for guidance). 'multiple' = pick several from options. 'input' = free-text field (only when options cannot express the answer). 'file_upload' = file picker."),
27802
+ required: import_zod61.default.boolean().optional().default(false).describe("Whether this question must be answered"),
27803
+ allowOther: import_zod61.default.boolean().optional().default(true).describe("Set to true to append an 'Other' checkbox with a free-text input field. Works with 'single' and 'multiple' types. Use for open-ended answers or when the options cannot cover all possibilities. Not applicable for 'input' or 'file_upload' types.")
26814
27804
  });
26815
- var inputSchema = import_zod60.default.object({
26816
- questions: import_zod60.default.array(questionSchema).min(1, "At least one question is required").describe("A structured sequence of clarification questions. Use these to gather missing parameters or disambiguate user intent before proceeding.")
27805
+ var inputSchema = import_zod61.default.object({
27806
+ questions: import_zod61.default.array(questionSchema).min(1, "At least one question is required").describe("A structured sequence of clarification questions. Use these to gather missing parameters or disambiguate user intent before proceeding.")
26817
27807
  });
26818
27808
  function createAskUserToClarifyTool() {
26819
- return (0, import_langchain71.tool)(
27809
+ return (0, import_langchain72.tool)(
26820
27810
  async (input) => {
26821
27811
  return JSON.stringify(input);
26822
27812
  },
@@ -26830,7 +27820,7 @@ function createAskUserToClarifyTool() {
26830
27820
 
26831
27821
  // src/middlewares/askUserClarifyMiddleware.ts
26832
27822
  function createAskUserClarifyMiddleware() {
26833
- return (0, import_langchain72.createMiddleware)({
27823
+ return (0, import_langchain73.createMiddleware)({
26834
27824
  name: "AskUserClarifyMiddleware",
26835
27825
  tools: [createAskUserToClarifyTool()],
26836
27826
  wrapToolCall: async (request, handler) => {
@@ -26844,7 +27834,7 @@ function createAskUserClarifyMiddleware() {
26844
27834
  throw error;
26845
27835
  }
26846
27836
  console.error(`Error executing tool "${toolName}":`, error);
26847
- return new import_langchain72.ToolMessage({
27837
+ return new import_langchain73.ToolMessage({
26848
27838
  content: `Error executing tool: ${error instanceof Error ? error.message : "Unknown error"}`,
26849
27839
  tool_call_id: toolCall?.id,
26850
27840
  name: toolName
@@ -26853,7 +27843,7 @@ function createAskUserClarifyMiddleware() {
26853
27843
  }
26854
27844
  const parsed = inputSchema.safeParse(toolCall?.args);
26855
27845
  if (!parsed.success) {
26856
- return new import_langchain72.ToolMessage({
27846
+ return new import_langchain73.ToolMessage({
26857
27847
  content: `Invalid clarify tool arguments: ${parsed.error.message}`,
26858
27848
  tool_call_id: toolCall?.id,
26859
27849
  name: toolName
@@ -26873,7 +27863,7 @@ function createAskUserClarifyMiddleware() {
26873
27863
  const result = await (0, import_langgraph14.interrupt)(md);
26874
27864
  const response = result.data;
26875
27865
  if (!response?.answers || response.answers.length === 0) {
26876
- return new import_langchain72.ToolMessage({
27866
+ return new import_langchain73.ToolMessage({
26877
27867
  content: "No clarification questions were answered.",
26878
27868
  tool_call_id: toolCall?.id,
26879
27869
  name: toolName
@@ -26883,7 +27873,7 @@ function createAskUserClarifyMiddleware() {
26883
27873
  (answer) => (answer.selectedOptions?.length ?? 0) > 0 || answer.otherText && answer.otherText.trim() !== "" || answer.filePath && answer.filePath.trim() !== ""
26884
27874
  );
26885
27875
  if (answeredQuestions.length === 0) {
26886
- return new import_langchain72.ToolMessage({
27876
+ return new import_langchain73.ToolMessage({
26887
27877
  content: "No clarification questions were answered.",
26888
27878
  tool_call_id: toolCall?.id,
26889
27879
  name: toolName
@@ -26913,7 +27903,7 @@ function createAskUserClarifyMiddleware() {
26913
27903
  }
26914
27904
  lines.push("");
26915
27905
  }
26916
- return new import_langchain72.ToolMessage({
27906
+ return new import_langchain73.ToolMessage({
26917
27907
  content: lines.join("\n"),
26918
27908
  tool_call_id: toolCall?.id,
26919
27909
  name: toolName
@@ -26938,11 +27928,11 @@ var askUserClarifyPlugin = {
26938
27928
  };
26939
27929
 
26940
27930
  // src/middlewares/widgetMiddleware.ts
26941
- var import_langchain75 = require("langchain");
27931
+ var import_langchain76 = require("langchain");
26942
27932
 
26943
27933
  // src/tool_lattice/widget/loadGuidelines.ts
26944
- var import_langchain73 = require("langchain");
26945
- var import_zod61 = require("zod");
27934
+ var import_langchain74 = require("langchain");
27935
+ var import_zod62 = require("zod");
26946
27936
 
26947
27937
  // src/middlewares/guidelines/index.ts
26948
27938
  var CORE = `# Imagine \u2014 Visual Creation Suite
@@ -27733,13 +28723,13 @@ function getGuidelines(modules) {
27733
28723
  var AVAILABLE_MODULES = Object.keys(MODULE_SECTIONS);
27734
28724
 
27735
28725
  // src/tool_lattice/widget/loadGuidelines.ts
27736
- var LoadGuidelinesInputSchema = import_zod61.z.object({
27737
- modules: import_zod61.z.array(import_zod61.z.string()).describe(
28726
+ var LoadGuidelinesInputSchema = import_zod62.z.object({
28727
+ modules: import_zod62.z.array(import_zod62.z.string()).describe(
27738
28728
  "Which design modules to load. Choose all that apply. Available modules: [" + AVAILABLE_MODULES.join(",") + "]"
27739
28729
  )
27740
28730
  });
27741
28731
  function createLoadGuidelinesTool() {
27742
- return (0, import_langchain73.tool)(
28732
+ return (0, import_langchain74.tool)(
27743
28733
  async (input) => {
27744
28734
  const result = getGuidelines(input.modules);
27745
28735
  return result;
@@ -27753,8 +28743,8 @@ function createLoadGuidelinesTool() {
27753
28743
  }
27754
28744
 
27755
28745
  // src/tool_lattice/widget/showWidget.ts
27756
- var import_langchain74 = require("langchain");
27757
- var import_zod62 = require("zod");
28746
+ var import_langchain75 = require("langchain");
28747
+ var import_zod63 = require("zod");
27758
28748
  function containsForbiddenTags(code) {
27759
28749
  const forbiddenPatterns = [
27760
28750
  /<!DOCTYPE/i,
@@ -27776,20 +28766,20 @@ function validateWidgetCode(code) {
27776
28766
  }
27777
28767
  return { valid: true };
27778
28768
  }
27779
- var ShowWidgetInputSchema = import_zod62.z.object({
27780
- i_have_seen_guidelines: import_zod62.z.boolean().describe(
28769
+ var ShowWidgetInputSchema = import_zod63.z.object({
28770
+ i_have_seen_guidelines: import_zod63.z.boolean().describe(
27781
28771
  "Must be true. Confirm you have called load_guidelines first."
27782
28772
  ),
27783
- title: import_zod62.z.string().describe("Title displayed above the widget"),
27784
- loading_messages: import_zod62.z.array(import_zod62.z.string()).optional().describe(
28773
+ title: import_zod63.z.string().describe("Title displayed above the widget"),
28774
+ loading_messages: import_zod63.z.array(import_zod63.z.string()).optional().describe(
27785
28775
  "1-4 short strings shown while the widget renders"
27786
28776
  ),
27787
- widget_code: import_zod62.z.string().describe(
28777
+ widget_code: import_zod63.z.string().describe(
27788
28778
  "HTML fragment to render. Rules: 1. No DOCTYPE, <html>, <head>, or <body> tags. 2. Order: <style> block first, then HTML content, then <script> last. 3. Use only CSS variables for colors (e.g. var(--color-accent)). 4. No gradients, shadows, or blur effects. For SVG: start directly with <svg> tag."
27789
28779
  )
27790
28780
  });
27791
28781
  function createShowWidgetTool() {
27792
- return (0, import_langchain74.tool)(
28782
+ return (0, import_langchain75.tool)(
27793
28783
  async (input) => {
27794
28784
  if (!input.i_have_seen_guidelines) {
27795
28785
  return "Error: You must call load_guidelines before using show_widget. Set i_have_seen_guidelines to true only after loading guidelines.";
@@ -27820,7 +28810,7 @@ function createWidgetMiddleware() {
27820
28810
  createLoadGuidelinesTool(),
27821
28811
  createShowWidgetTool()
27822
28812
  ];
27823
- return (0, import_langchain75.createMiddleware)({
28813
+ return (0, import_langchain76.createMiddleware)({
27824
28814
  name: "widgetMiddleware",
27825
28815
  contextSchema,
27826
28816
  tools
@@ -27842,157 +28832,10 @@ var widgetPlugin = {
27842
28832
  middleware: () => createWidgetMiddleware()
27843
28833
  };
27844
28834
 
27845
- // src/middlewares/taskMiddleware.ts
27846
- var import_langchain76 = require("langchain");
27847
- var import_zod63 = require("zod");
27848
- function getRunConfig2(config) {
27849
- const c = config;
27850
- return c?.configurable?.runConfig ?? {};
27851
- }
27852
- function getTaskStore() {
27853
- return getStoreLattice("default", "task").store;
27854
- }
27855
- var manageTaskSchema = import_zod63.z.object({
27856
- action: import_zod63.z.enum(["create", "list", "update", "delete", "complete"]).describe("\u64CD\u4F5C\u7C7B\u578B"),
27857
- id: import_zod63.z.string().optional().describe("\u4EFB\u52A1 ID (update/delete/complete \u5FC5\u586B)"),
27858
- title: import_zod63.z.string().optional().describe("\u4EFB\u52A1\u6807\u9898 (create \u5FC5\u586B)"),
27859
- description: import_zod63.z.string().optional().describe("\u4EFB\u52A1\u63CF\u8FF0"),
27860
- priority: import_zod63.z.enum(["low", "medium", "high"]).optional().describe("\u4F18\u5148\u7EA7"),
27861
- status: import_zod63.z.enum(["pending", "in_progress", "completed", "cancelled"]).optional().describe("\u72B6\u6001"),
27862
- dueDate: import_zod63.z.string().optional().describe("\u622A\u6B62\u65E5\u671F (ISO 8601)"),
27863
- metadata: import_zod63.z.record(import_zod63.z.unknown()).optional().describe("\u7ED3\u6784\u5316\u5143\u6570\u636E (projectId, module \u7B49)"),
27864
- parentId: import_zod63.z.string().optional().describe("\u7236\u4EFB\u52A1 ID (\u5B50\u4EFB\u52A1\u5173\u8054)"),
27865
- sourceId: import_zod63.z.string().optional().describe("\u6765\u6E90\u4F1A\u8BDD/thread ID"),
27866
- context: import_zod63.z.record(import_zod63.z.unknown()).optional().describe("\u9644\u52A0\u4E0A\u4E0B\u6587"),
27867
- ownerType: import_zod63.z.enum(["user", "agent"]).optional().describe("\u6240\u6709\u8005\u7C7B\u578B\uFF0C\u4E0D\u4F20\u9ED8\u8BA4\u4E3A user"),
27868
- ownerId: import_zod63.z.string().optional().describe("\u6240\u6709\u8005 ID\uFF0C\u4E0D\u4F20\u81EA\u52A8\u53D6\u5F53\u524D\u7528\u6237/Agent")
27869
- });
27870
- function createTaskMiddleware() {
27871
- return (0, import_langchain76.createMiddleware)({
27872
- name: "TaskMiddleware",
27873
- contextSchema,
27874
- wrapModelCall: async (request, handler) => {
27875
- const taskPrompt = `## \u4EFB\u52A1\u7BA1\u7406\u80FD\u529B
27876
- \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
27877
- - \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)
27878
- - ownerType="agent": \u4E3A\u81EA\u5DF1\u521B\u5EFA\u6267\u884C\u5B50\u4EFB\u52A1 (ownerId \u81EA\u52A8\u53D6\u5F53\u524D Agent)
27879
- - \u663E\u5F0F\u4F20 ownerId: \u4E3A\u6307\u5B9A agent/user \u521B\u5EFA\u4EFB\u52A1\uFF08\u62D3\u6251\u573A\u666F\uFF09`;
27880
- return handler({
27881
- ...request,
27882
- systemPrompt: taskPrompt + "\n\n" + (request.systemPrompt ?? "")
27883
- });
27884
- },
27885
- tools: [
27886
- (0, import_langchain76.tool)(
27887
- async (input, config) => {
27888
- const rc = getRunConfig2(config);
27889
- const tenantId2 = rc.tenantId || "default";
27890
- const ownerId = input.ownerId || (input.ownerType === "agent" ? rc.assistant_id : null) || rc.user_id;
27891
- const store = getTaskStore();
27892
- switch (input.action) {
27893
- case "create": {
27894
- if (!input.title) {
27895
- return JSON.stringify({ success: false, error: "create requires title" });
27896
- }
27897
- const task = await store.create({
27898
- tenantId: tenantId2,
27899
- ownerType: input.ownerType || "user",
27900
- ownerId,
27901
- title: input.title,
27902
- description: input.description,
27903
- priority: input.priority || "medium",
27904
- status: input.status || "pending",
27905
- dueDate: input.dueDate,
27906
- metadata: input.metadata,
27907
- parentId: input.parentId,
27908
- sourceId: input.sourceId,
27909
- context: input.context
27910
- });
27911
- return JSON.stringify({ success: true, data: task });
27912
- }
27913
- case "list": {
27914
- const tasks = await store.list({
27915
- tenantId: tenantId2,
27916
- ownerType: input.ownerType,
27917
- ownerId: input.ownerId,
27918
- status: input.status,
27919
- priority: input.priority
27920
- });
27921
- return JSON.stringify({ success: true, data: tasks, count: tasks.length });
27922
- }
27923
- case "update": {
27924
- if (!input.id) {
27925
- return JSON.stringify({ success: false, error: "update requires id" });
27926
- }
27927
- const { action, ...updates } = input;
27928
- const updated = await store.update(tenantId2, input.id, updates);
27929
- if (!updated) {
27930
- return JSON.stringify({ success: false, error: "Task not found" });
27931
- }
27932
- return JSON.stringify({ success: true, data: updated });
27933
- }
27934
- case "delete": {
27935
- if (!input.id) {
27936
- return JSON.stringify({ success: false, error: "delete requires id" });
27937
- }
27938
- const deleted = await store.delete(tenantId2, input.id);
27939
- return JSON.stringify({ success: deleted, message: deleted ? "Task deleted" : "Task not found" });
27940
- }
27941
- case "complete": {
27942
- if (!input.id) {
27943
- return JSON.stringify({ success: false, error: "complete requires id" });
27944
- }
27945
- const updated = await store.update(tenantId2, input.id, { status: "completed" });
27946
- if (!updated) {
27947
- return JSON.stringify({ success: false, error: "Task not found" });
27948
- }
27949
- return JSON.stringify({ success: true, data: updated });
27950
- }
27951
- default:
27952
- return JSON.stringify({ success: false, error: `Unknown action: ${input.action}` });
27953
- }
27954
- },
27955
- {
27956
- name: "manage_task",
27957
- description: `\u7BA1\u7406\u6301\u4E45\u5316\u4EFB\u52A1\u7CFB\u7EDF\u3002CRUD \u64CD\u4F5C\u7528\u6237\u548C Agent \u7684\u4EFB\u52A1\u3002
27958
-
27959
- ## ownerType \u548C ownerId \u7684\u9ED8\u8BA4\u903B\u8F91
27960
- - \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)
27961
- - \u4F20 ownerType="agent" \u4E0D\u4F20 ownerId: \u7CFB\u7EDF\u81EA\u52A8\u4E3A\u5F53\u524D Agent \u521B\u5EFA\u5B50\u4EFB\u52A1
27962
- - \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
27963
-
27964
- ## Actions
27965
- - create: \u521B\u5EFA\u4EFB\u52A1 (title \u5FC5\u586B, priority/description/dueDate/metadata/parentId/context \u53EF\u9009)
27966
- - list: \u5217\u51FA\u4EFB\u52A1\uFF0C\u53EF\u6309 ownerType/status/priority \u8FC7\u6EE4
27967
- - update: \u66F4\u65B0\u4EFB\u52A1 (id \u5FC5\u586B\uFF0C\u53EA\u4F20\u8981\u6539\u7684\u5B57\u6BB5)
27968
- - delete: \u5220\u9664\u4EFB\u52A1 (id \u5FC5\u586B)
27969
- - complete: \u5FEB\u901F\u6807\u8BB0\u5B8C\u6210 (id \u5FC5\u586B)`,
27970
- schema: manageTaskSchema
27971
- }
27972
- )
27973
- ]
27974
- });
27975
- }
27976
- var taskPlugin = {
27977
- meta: {
27978
- type: "task",
27979
- name: "Task Management",
27980
- description: "Enables persistent task management with delegation and tracking",
27981
- configSchema: {
27982
- type: "object",
27983
- title: "Task Management Configuration",
27984
- description: "Zero-configuration task management",
27985
- properties: {}
27986
- },
27987
- defaultConfig: {}
27988
- },
27989
- middleware: () => createTaskMiddleware()
27990
- };
27991
-
27992
28835
  // src/middlewares/evalMiddleware.ts
27993
28836
  var import_langchain77 = require("langchain");
27994
28837
  var import_zod64 = require("zod");
27995
- var import_uuid10 = require("uuid");
28838
+ var import_uuid11 = require("uuid");
27996
28839
 
27997
28840
  // src/middlewares/evalSkills.ts
27998
28841
  var EVAL_SKILLS = {
@@ -28206,7 +29049,7 @@ function createManageEvalTool() {
28206
29049
  let data;
28207
29050
  switch (input.action) {
28208
29051
  case "create_project":
28209
- data = await store.createProject(tid, (0, import_uuid10.v4)(), {
29052
+ data = await store.createProject(tid, (0, import_uuid11.v4)(), {
28210
29053
  name: input.name,
28211
29054
  description: input.description,
28212
29055
  judgeModelConfig: { modelKey: input.judgeModelKey },
@@ -28230,7 +29073,7 @@ function createManageEvalTool() {
28230
29073
  break;
28231
29074
  }
28232
29075
  case "create_suite":
28233
- data = await store.createSuite(tid, input.projectId, (0, import_uuid10.v4)(), { name: input.name });
29076
+ data = await store.createSuite(tid, input.projectId, (0, import_uuid11.v4)(), { name: input.name });
28234
29077
  break;
28235
29078
  case "update_suite":
28236
29079
  data = await store.updateSuite(tid, input.suiteId, { name: input.name });
@@ -28240,7 +29083,7 @@ function createManageEvalTool() {
28240
29083
  data = true;
28241
29084
  break;
28242
29085
  case "create_case":
28243
- data = await store.createCase(tid, input.suiteId, (0, import_uuid10.v4)(), {
29086
+ data = await store.createCase(tid, input.suiteId, (0, import_uuid11.v4)(), {
28244
29087
  inputMessage: input.inputMessage,
28245
29088
  inputFiles: input.inputFiles,
28246
29089
  steps: input.steps,
@@ -28859,6 +29702,8 @@ registerBuiltinPlugins();
28859
29702
  QueueMode,
28860
29703
  RemoteSandboxInstance,
28861
29704
  RemoteSandboxProvider,
29705
+ STTModelLattice,
29706
+ STTModelLatticeManager,
28862
29707
  SandboxFilesystem,
28863
29708
  SandboxLatticeManager,
28864
29709
  SandboxSkillStore,
@@ -28964,6 +29809,9 @@ registerBuiltinPlugins();
28964
29809
  getNextCronTime,
28965
29810
  getOrCreateCollectionVectorStore,
28966
29811
  getQueueLattice,
29812
+ getSTTClient,
29813
+ getSTTClientWithTenant,
29814
+ getSTTModelLattice,
28967
29815
  getSandBoxManager,
28968
29816
  getScheduleLattice,
28969
29817
  getStoreLattice,
@@ -29007,6 +29855,7 @@ registerBuiltinPlugins();
29007
29855
  registerLoggerLattice,
29008
29856
  registerModelLattice,
29009
29857
  registerQueueLattice,
29858
+ registerSTTModelLattice,
29010
29859
  registerSandboxProviderType,
29011
29860
  registerScheduleLattice,
29012
29861
  registerStoreLattice,
@@ -29028,6 +29877,7 @@ registerBuiltinPlugins();
29028
29877
  skillLatticeManager,
29029
29878
  sqlDatabaseManager,
29030
29879
  storeLatticeManager,
29880
+ sttModelLatticeManager,
29031
29881
  toJsonSchema,
29032
29882
  toSafeStateExpr,
29033
29883
  toolLatticeManager,