zeitlich 0.2.9 → 0.2.12

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.
Files changed (53) hide show
  1. package/README.md +313 -126
  2. package/dist/adapters/langchain/index.cjs +270 -0
  3. package/dist/adapters/langchain/index.cjs.map +1 -0
  4. package/dist/adapters/langchain/index.d.cts +132 -0
  5. package/dist/adapters/langchain/index.d.ts +132 -0
  6. package/dist/adapters/langchain/index.js +265 -0
  7. package/dist/adapters/langchain/index.js.map +1 -0
  8. package/dist/index.cjs +406 -301
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +88 -45
  11. package/dist/index.d.ts +88 -45
  12. package/dist/index.js +375 -274
  13. package/dist/index.js.map +1 -1
  14. package/dist/{workflow-C2ShwjC7.d.cts → model-invoker-C5-N-5TC.d.cts} +92 -435
  15. package/dist/{workflow-C2ShwjC7.d.ts → model-invoker-C5-N-5TC.d.ts} +92 -435
  16. package/dist/thread-manager-qc0g5Rvd.d.cts +39 -0
  17. package/dist/thread-manager-qc0g5Rvd.d.ts +39 -0
  18. package/dist/workflow.cjs +294 -126
  19. package/dist/workflow.cjs.map +1 -1
  20. package/dist/workflow.d.cts +459 -5
  21. package/dist/workflow.d.ts +459 -5
  22. package/dist/workflow.js +266 -103
  23. package/dist/workflow.js.map +1 -1
  24. package/package.json +30 -15
  25. package/src/adapters/langchain/activities.ts +120 -0
  26. package/src/adapters/langchain/index.ts +38 -0
  27. package/src/adapters/langchain/model-invoker.ts +102 -0
  28. package/src/adapters/langchain/thread-manager.ts +142 -0
  29. package/src/index.ts +26 -22
  30. package/src/lib/fs.ts +25 -0
  31. package/src/lib/model-invoker.ts +14 -74
  32. package/src/lib/session.ts +60 -23
  33. package/src/lib/skills/fs-provider.ts +84 -0
  34. package/src/lib/skills/index.ts +3 -0
  35. package/src/lib/skills/parse.ts +117 -0
  36. package/src/lib/skills/types.ts +41 -0
  37. package/src/lib/state-manager.ts +65 -31
  38. package/src/lib/thread-id.ts +25 -0
  39. package/src/lib/thread-manager.ts +63 -128
  40. package/src/lib/tool-router.ts +33 -23
  41. package/src/lib/types.ts +48 -15
  42. package/src/lib/workflow-helpers.ts +50 -0
  43. package/src/tools/ask-user-question/handler.ts +25 -1
  44. package/src/tools/bash/handler.ts +13 -0
  45. package/src/tools/read-skill/handler.ts +31 -0
  46. package/src/tools/read-skill/tool.ts +47 -0
  47. package/src/tools/subagent/handler.ts +37 -9
  48. package/src/tools/subagent/tool.ts +38 -34
  49. package/src/tools/task-create/tool.ts +1 -1
  50. package/src/workflow.ts +39 -11
  51. package/tsup.config.ts +1 -0
  52. package/src/activities.ts +0 -91
  53. package/src/plugin.ts +0 -28
package/dist/index.cjs CHANGED
@@ -1,58 +1,67 @@
1
1
  'use strict';
2
2
 
3
3
  var workflow = require('@temporalio/workflow');
4
- var z13 = require('zod');
5
- var plugin = require('@temporalio/plugin');
6
- var messages = require('@langchain/core/messages');
7
- var crypto = require('crypto');
4
+ var z14 = require('zod');
8
5
  var activity = require('@temporalio/activity');
9
6
  var justBash = require('just-bash');
7
+ var promises = require('fs/promises');
8
+ var path = require('path');
10
9
 
11
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
11
 
13
- var z13__default = /*#__PURE__*/_interopDefault(z13);
14
- var crypto__default = /*#__PURE__*/_interopDefault(crypto);
12
+ var z14__default = /*#__PURE__*/_interopDefault(z14);
15
13
 
16
14
  // src/lib/session.ts
17
15
  var SUBAGENT_TOOL_NAME = "Subagent";
18
16
  function buildSubagentDescription(subagents) {
19
- const subagentList = subagents.map((s) => `- **${s.agentName}**: ${s.description}`).join("\n");
20
- return `Launch a new agent to handle complex tasks autonomously.
21
-
22
- The ${SUBAGENT_TOOL_NAME} tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
23
-
24
- Available agent types:
17
+ const subagentList = subagents.map((s) => {
18
+ const continuation = s.allowThreadContinuation ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
19
+ return `## ${s.agentName}
20
+ ${s.description}${continuation}`;
21
+ }).join("\n\n");
22
+ return `The ${SUBAGENT_TOOL_NAME} tool launches specialized agents (subagents) that autonomously handle complex work. Each agent type has specific capabilities and tools available to it.
25
23
 
24
+ # Available subagents:
26
25
  ${subagentList}
27
-
28
- When using the ${SUBAGENT_TOOL_NAME} tool, you must specify a subagent parameter to select which agent type to use.
29
-
30
- Usage notes:
31
-
32
- - Always include a short description (3-5 words) summarizing what the agent will do
33
- - Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
34
- - When the agent is done, it will return a single message back to you.
35
- - Each invocation starts fresh - provide a detailed task description with all necessary context.
36
- - Provide clear, detailed prompts so the agent can work autonomously and return exactly the information you need.
37
- - The agent's outputs should generally be trusted
38
- - Clearly tell the agent what type of work you expect since it is not aware of the user's intent
39
- - 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.`;
26
+ `;
40
27
  }
41
28
  function createSubagentTool(subagents) {
42
29
  if (subagents.length === 0) {
43
30
  throw new Error("createTaskTool requires at least one subagent");
44
31
  }
45
32
  const names = subagents.map((s) => s.agentName);
33
+ const hasThreadContinuation = subagents.some(
34
+ (s) => s.allowThreadContinuation
35
+ );
36
+ const baseFields = {
37
+ subagent: z14__default.default.enum(names).describe("The type of subagent to launch"),
38
+ description: z14__default.default.string().describe("A short (3-5 word) description of the task"),
39
+ prompt: z14__default.default.string().describe("The task for the agent to perform")
40
+ };
41
+ const schema = hasThreadContinuation ? z14__default.default.object({
42
+ ...baseFields,
43
+ threadId: z14__default.default.string().nullable().describe(
44
+ "Thread ID to continue an existing conversation, or null to start a new one"
45
+ )
46
+ }) : z14__default.default.object(baseFields);
46
47
  return {
47
48
  name: SUBAGENT_TOOL_NAME,
48
49
  description: buildSubagentDescription(subagents),
49
- schema: z13__default.default.object({
50
- subagent: z13__default.default.enum(names).describe("The type of subagent to launch"),
51
- description: z13__default.default.string().describe("A short (3-5 word) description of the task"),
52
- prompt: z13__default.default.string().describe("The task for the agent to perform")
53
- })
50
+ schema
54
51
  };
55
52
  }
53
+ var BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
54
+ function getShortId(length = 12) {
55
+ const hex = workflow.uuid4().replace(/-/g, "");
56
+ let result = "";
57
+ for (let i = 0; i < length; i++) {
58
+ const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
59
+ result += BASE62[byte % BASE62.length];
60
+ }
61
+ return result;
62
+ }
63
+
64
+ // src/tools/subagent/handler.ts
56
65
  function createSubagentHandler(subagents) {
57
66
  const { taskQueue: parentTaskQueue } = workflow.workflowInfo();
58
67
  return async (args) => {
@@ -62,34 +71,95 @@ function createSubagentHandler(subagents) {
62
71
  `Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.agentName).join(", ")}`
63
72
  );
64
73
  }
65
- const childWorkflowId = `${args.subagent}-${workflow.uuid4()}`;
74
+ const childWorkflowId = `${args.subagent}-${getShortId()}`;
66
75
  const input = {
67
76
  prompt: args.prompt,
68
- ...config.context && { context: config.context }
77
+ ...config.context && { context: config.context },
78
+ ...args.threadId && config.allowThreadContinuation && { threadId: args.threadId }
69
79
  };
70
80
  const childOpts = {
71
81
  workflowId: childWorkflowId,
72
82
  args: [input],
73
83
  taskQueue: config.taskQueue ?? parentTaskQueue
74
84
  };
75
- const { toolResponse, data, usage } = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
76
- const validated = config.resultSchema ? config.resultSchema.parse(data) : null;
85
+ const { toolResponse, data, usage, threadId: childThreadId } = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
86
+ if (!toolResponse) {
87
+ return {
88
+ toolResponse: "Subagent workflow returned no response",
89
+ data: null,
90
+ ...usage && { usage }
91
+ };
92
+ }
93
+ const validated = config.resultSchema ? config.resultSchema.safeParse(data) : null;
94
+ if (validated && !validated.success) {
95
+ return {
96
+ toolResponse: `Subagent workflow returned invalid data: ${validated.error.message}`,
97
+ data: null,
98
+ ...usage && { usage }
99
+ };
100
+ }
101
+ let finalToolResponse = toolResponse;
102
+ if (config.allowThreadContinuation && childThreadId) {
103
+ finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
104
+
105
+ [Thread ID: ${childThreadId}]` : toolResponse;
106
+ }
77
107
  return {
78
- toolResponse,
79
- data: validated,
108
+ toolResponse: finalToolResponse,
109
+ data: validated ? validated.data : data,
80
110
  ...usage && { usage }
81
111
  };
82
112
  };
83
113
  }
114
+ var READ_SKILL_TOOL_NAME = "ReadSkill";
115
+ function buildReadSkillDescription(skills) {
116
+ const skillList = skills.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
117
+ return `Load the full instructions for a skill. Read the skill before following its instructions.
84
118
 
85
- // src/lib/tool-router.ts
119
+ # Available skills:
120
+ ${skillList}
121
+ `;
122
+ }
123
+ function createReadSkillTool(skills) {
124
+ if (skills.length === 0) {
125
+ throw new Error("createReadSkillTool requires at least one skill");
126
+ }
127
+ const names = skills.map((s) => s.name);
128
+ return {
129
+ name: READ_SKILL_TOOL_NAME,
130
+ description: buildReadSkillDescription(skills),
131
+ schema: z14__default.default.object({
132
+ skill_name: z14__default.default.enum(names).describe("The name of the skill to load")
133
+ })
134
+ };
135
+ }
136
+
137
+ // src/tools/read-skill/handler.ts
138
+ function createReadSkillHandler(skills) {
139
+ const skillMap = new Map(skills.map((s) => [s.name, s]));
140
+ return (args) => {
141
+ const skill = skillMap.get(args.skill_name);
142
+ if (!skill) {
143
+ return {
144
+ toolResponse: JSON.stringify({
145
+ error: `Skill "${args.skill_name}" not found`
146
+ }),
147
+ data: null
148
+ };
149
+ }
150
+ return {
151
+ toolResponse: skill.instructions,
152
+ data: null
153
+ };
154
+ };
155
+ }
86
156
  function createToolRouter(options) {
87
157
  const { appendToolResult } = options;
88
158
  const toolMap = /* @__PURE__ */ new Map();
89
159
  for (const [_key, tool] of Object.entries(options.tools)) {
90
160
  toolMap.set(tool.name, tool);
91
161
  }
92
- const isEnabled = (tool) => tool.enabled?.() ?? true;
162
+ const isEnabled = (tool) => tool.enabled ?? true;
93
163
  if (options.subagents) {
94
164
  if (options.subagents.length > 0) {
95
165
  const subagentHooksMap = /* @__PURE__ */ new Map();
@@ -119,6 +189,12 @@ function createToolRouter(options) {
119
189
  });
120
190
  }
121
191
  }
192
+ if (options.skills && options.skills.length > 0) {
193
+ toolMap.set(READ_SKILL_TOOL_NAME, {
194
+ ...createReadSkillTool(options.skills),
195
+ handler: createReadSkillHandler(options.skills)
196
+ });
197
+ }
122
198
  async function processToolCall(toolCall, turn, handlerContext) {
123
199
  const startTime = Date.now();
124
200
  const tool = toolMap.get(toolCall.name);
@@ -228,7 +304,9 @@ function createToolRouter(options) {
228
304
  }
229
305
  }
230
306
  if (!recovered) {
231
- throw error;
307
+ throw workflow.ApplicationFailure.fromError(error, {
308
+ nonRetryable: true
309
+ });
232
310
  }
233
311
  }
234
312
  if (!resultAppended) {
@@ -291,9 +369,10 @@ function createToolRouter(options) {
291
369
  },
292
370
  getToolDefinitions() {
293
371
  const activeSubagents = options.subagents?.filter((subagent) => isEnabled(subagent)) ?? [];
372
+ const activeSkills = options.skills ?? [];
294
373
  return [
295
374
  ...Array.from(toolMap).filter(
296
- ([, tool]) => isEnabled(tool) && tool.name !== SUBAGENT_TOOL_NAME
375
+ ([, tool]) => isEnabled(tool) && tool.name !== SUBAGENT_TOOL_NAME && tool.name !== READ_SKILL_TOOL_NAME
297
376
  ).map(([name, tool]) => ({
298
377
  name,
299
378
  description: tool.description,
@@ -301,7 +380,8 @@ function createToolRouter(options) {
301
380
  strict: tool.strict,
302
381
  max_uses: tool.max_uses
303
382
  })),
304
- ...activeSubagents.length > 0 ? [createSubagentTool(activeSubagents)] : []
383
+ ...activeSubagents.length > 0 ? [createSubagentTool(activeSubagents)] : [],
384
+ ...activeSkills.length > 0 ? [createReadSkillTool(activeSkills)] : []
305
385
  ];
306
386
  },
307
387
  // --- Methods for processing tool calls ---
@@ -413,22 +493,23 @@ function hasNoOtherToolCalls(toolCalls, excludeName) {
413
493
 
414
494
  // src/lib/session.ts
415
495
  var createSession = async ({
416
- threadId,
496
+ threadId: providedThreadId,
417
497
  agentName,
418
- description,
419
498
  maxTurns = 50,
420
499
  metadata = {},
421
500
  runAgent,
422
501
  threadOps,
423
502
  buildContextMessage,
424
503
  subagents,
504
+ skills,
425
505
  tools = {},
426
506
  processToolsInParallel = true,
427
507
  hooks = {},
428
508
  appendSystemPrompt = true,
429
- systemPrompt,
509
+ continueThread = false,
430
510
  waitForInputTimeout = "48h"
431
511
  }) => {
512
+ const threadId = providedThreadId ?? getShortId();
432
513
  const {
433
514
  appendToolResult,
434
515
  appendHumanMessage,
@@ -441,6 +522,7 @@ var createSession = async ({
441
522
  threadId,
442
523
  hooks,
443
524
  subagents,
525
+ skills,
444
526
  parallel: processToolsInParallel
445
527
  });
446
528
  const callSessionEnd = async (exitReason, turns) => {
@@ -484,9 +566,19 @@ var createSession = async ({
484
566
  metadata
485
567
  });
486
568
  }
487
- await initializeThread(threadId);
488
- if (appendSystemPrompt && systemPrompt && systemPrompt.trim() !== "") {
489
- await appendSystemMessage(threadId, systemPrompt);
569
+ const systemPrompt = stateManager.getSystemPrompt();
570
+ if (!continueThread) {
571
+ if (appendSystemPrompt) {
572
+ if (!systemPrompt || systemPrompt.trim() === "") {
573
+ throw workflow.ApplicationFailure.create({
574
+ message: "No system prompt in state",
575
+ nonRetryable: true
576
+ });
577
+ }
578
+ await appendSystemMessage(threadId, systemPrompt);
579
+ } else {
580
+ await initializeThread(threadId);
581
+ }
490
582
  }
491
583
  await appendHumanMessage(threadId, await buildContextMessage());
492
584
  let exitReason = "completed";
@@ -498,9 +590,7 @@ var createSession = async ({
498
590
  const { message, rawToolCalls, usage } = await runAgent({
499
591
  threadId,
500
592
  agentName,
501
- metadata,
502
- systemPrompt,
503
- description
593
+ metadata
504
594
  });
505
595
  if (usage) {
506
596
  stateManager.updateUsage(usage);
@@ -557,7 +647,7 @@ var createSession = async ({
557
647
  }
558
648
  } catch (error) {
559
649
  exitReason = "failed";
560
- throw error;
650
+ throw workflow.ApplicationFailure.fromError(error);
561
651
  } finally {
562
652
  await callSessionEnd(exitReason, stateManager.getTurns());
563
653
  }
@@ -570,33 +660,28 @@ var createSession = async ({
570
660
  };
571
661
  };
572
662
  function proxyDefaultThreadOps(options) {
573
- const activities = workflow.proxyActivities(
663
+ return workflow.proxyActivities(
574
664
  options ?? {
575
- startToCloseTimeout: "30m",
665
+ startToCloseTimeout: "10s",
576
666
  retry: {
577
667
  maximumAttempts: 6,
578
668
  initialInterval: "5s",
579
669
  maximumInterval: "15m",
580
670
  backoffCoefficient: 4
581
- },
582
- heartbeatTimeout: "5m"
671
+ }
583
672
  }
584
673
  );
585
- return {
586
- initializeThread: activities.initializeThread,
587
- appendHumanMessage: activities.appendHumanMessage,
588
- appendToolResult: activities.appendToolResult,
589
- appendSystemMessage: activities.appendSystemMessage
590
- };
591
674
  }
592
675
 
593
676
  // src/lib/types.ts
677
+ var agentQueryName = (agentName) => `get${agentName}State`;
678
+ var agentStateChangeUpdateName = (agentName) => `waitFor${agentName}StateChange`;
594
679
  function isTerminalStatus(status) {
595
680
  return status === "COMPLETED" || status === "FAILED" || status === "CANCELLED";
596
681
  }
597
682
  function createAgentStateManager({
598
683
  initialState,
599
- agentConfig
684
+ agentName
600
685
  }) {
601
686
  let status = initialState?.status ?? "RUNNING";
602
687
  let version = initialState?.version ?? 0;
@@ -607,6 +692,7 @@ function createAgentStateManager({
607
692
  let totalCachedWriteTokens = 0;
608
693
  let totalCachedReadTokens = 0;
609
694
  let totalReasonTokens = 0;
695
+ let systemPrompt = initialState?.systemPrompt;
610
696
  const tasks = new Map(initialState?.tasks);
611
697
  const {
612
698
  status: _,
@@ -626,28 +712,32 @@ function createAgentStateManager({
626
712
  ...customState
627
713
  };
628
714
  }
629
- workflow.setHandler(workflow.defineQuery(`get${agentConfig.agentName}State`), () => {
715
+ const stateQuery = workflow.defineQuery(
716
+ agentQueryName(agentName)
717
+ );
718
+ const stateChangeUpdate = workflow.defineUpdate(
719
+ agentStateChangeUpdateName(agentName)
720
+ );
721
+ workflow.setHandler(stateQuery, () => buildState());
722
+ workflow.setHandler(stateChangeUpdate, async (lastKnownVersion) => {
723
+ await workflow.condition(
724
+ () => version > lastKnownVersion || isTerminalStatus(status),
725
+ "55s"
726
+ );
630
727
  return buildState();
631
728
  });
632
- workflow.setHandler(
633
- workflow.defineUpdate(
634
- `waitFor${agentConfig.agentName}StateChange`
635
- ),
636
- async (lastKnownVersion) => {
637
- await workflow.condition(
638
- () => version > lastKnownVersion || isTerminalStatus(status),
639
- "55s"
640
- );
641
- return buildState();
642
- }
643
- );
644
729
  return {
730
+ stateQuery,
731
+ stateChangeUpdate,
645
732
  getStatus() {
646
733
  return status;
647
734
  },
648
735
  isRunning() {
649
736
  return status === "RUNNING";
650
737
  },
738
+ getSystemPrompt() {
739
+ return systemPrompt;
740
+ },
651
741
  isTerminal() {
652
742
  return isTerminalStatus(status);
653
743
  },
@@ -710,11 +800,14 @@ function createAgentStateManager({
710
800
  tools = newTools.map((tool) => ({
711
801
  name: tool.name,
712
802
  description: tool.description,
713
- schema: z13.z.toJSONSchema(tool.schema),
803
+ schema: z14.z.toJSONSchema(tool.schema),
714
804
  strict: tool.strict,
715
805
  max_uses: tool.max_uses
716
806
  }));
717
807
  },
808
+ setSystemPrompt(newSystemPrompt) {
809
+ systemPrompt = newSystemPrompt;
810
+ },
718
811
  deleteTask(id) {
719
812
  const deleted = tasks.delete(id);
720
813
  if (deleted) {
@@ -741,11 +834,79 @@ function createAgentStateManager({
741
834
  }
742
835
  };
743
836
  }
744
- var AGENT_HANDLER_NAMES = {
745
- getAgentState: "getAgentState",
746
- waitForStateChange: "waitForStateChange",
747
- addMessage: "addMessage"
748
- };
837
+
838
+ // src/lib/skills/parse.ts
839
+ function parseSkillFile(raw) {
840
+ const trimmed = raw.replace(/^\uFEFF/, "");
841
+ const match = trimmed.match(/^---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*\r?\n?([\s\S]*)$/);
842
+ if (!match) {
843
+ throw new Error(
844
+ "SKILL.md must start with YAML frontmatter delimited by ---"
845
+ );
846
+ }
847
+ const [, yamlBlock, body] = match;
848
+ const frontmatter = parseSimpleYaml(yamlBlock);
849
+ if (!frontmatter.name || typeof frontmatter.name !== "string") {
850
+ throw new Error("SKILL.md frontmatter must include a 'name' field");
851
+ }
852
+ if (!frontmatter.description || typeof frontmatter.description !== "string") {
853
+ throw new Error("SKILL.md frontmatter must include a 'description' field");
854
+ }
855
+ const result = {
856
+ name: frontmatter.name,
857
+ description: frontmatter.description
858
+ };
859
+ if (frontmatter.license) result.license = String(frontmatter.license);
860
+ if (frontmatter.compatibility)
861
+ result.compatibility = String(frontmatter.compatibility);
862
+ if (frontmatter["allowed-tools"]) {
863
+ result.allowedTools = String(frontmatter["allowed-tools"]).split(/\s+/).filter(Boolean);
864
+ }
865
+ if (frontmatter.metadata && typeof frontmatter.metadata === "object" && !Array.isArray(frontmatter.metadata)) {
866
+ result.metadata = frontmatter.metadata;
867
+ }
868
+ return { frontmatter: result, body: body.trim() };
869
+ }
870
+ function parseSimpleYaml(yaml) {
871
+ const result = {};
872
+ const lines = yaml.split(/\r?\n/);
873
+ let currentMapKey = null;
874
+ let currentMap = null;
875
+ for (const line of lines) {
876
+ if (line.trim() === "" || line.trim().startsWith("#")) continue;
877
+ const nestedMatch = line.match(/^(\s{2,}|\t+)(\S+)\s*:\s*(.*)$/);
878
+ if (nestedMatch && currentMapKey && currentMap) {
879
+ const [, , key2, rawVal2] = nestedMatch;
880
+ currentMap[key2] = unquote(rawVal2.trim());
881
+ continue;
882
+ }
883
+ if (currentMapKey && currentMap) {
884
+ result[currentMapKey] = currentMap;
885
+ currentMapKey = null;
886
+ currentMap = null;
887
+ }
888
+ const topMatch = line.match(/^(\S+)\s*:\s*(.*)$/);
889
+ if (!topMatch) continue;
890
+ const [, key, rawVal] = topMatch;
891
+ const val = rawVal.trim();
892
+ if (val === "" || val === "|" || val === ">") {
893
+ currentMapKey = key;
894
+ currentMap = {};
895
+ } else {
896
+ result[key] = unquote(val);
897
+ }
898
+ }
899
+ if (currentMapKey && currentMap) {
900
+ result[currentMapKey] = currentMap;
901
+ }
902
+ return result;
903
+ }
904
+ function unquote(s) {
905
+ if (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'")) {
906
+ return s.slice(1, -1);
907
+ }
908
+ return s;
909
+ }
749
910
  var globTool = {
750
911
  name: "Glob",
751
912
  description: `Search for files matching a glob pattern within the available file system.
@@ -760,9 +921,9 @@ Examples:
760
921
  - "**/*.test.ts" - Find all test files recursively
761
922
  - "src/**/*.ts" - Find all TypeScript files in src directory
762
923
  `,
763
- schema: z13.z.object({
764
- pattern: z13.z.string().describe("Glob pattern to match files against"),
765
- root: z13.z.string().optional().describe("Optional root directory to search from")
924
+ schema: z14.z.object({
925
+ pattern: z14.z.string().describe("Glob pattern to match files against"),
926
+ root: z14.z.string().optional().describe("Optional root directory to search from")
766
927
  }),
767
928
  strict: true
768
929
  };
@@ -780,13 +941,13 @@ Examples:
780
941
  - Search for function definitions with "function.*handleClick"
781
942
  - Search case-insensitively with ignoreCase: true
782
943
  `,
783
- schema: z13.z.object({
784
- pattern: z13.z.string().describe("Regex pattern to search for in file contents"),
785
- ignoreCase: z13.z.boolean().optional().describe("Case-insensitive search (default: false)"),
786
- maxMatches: z13.z.number().optional().describe("Maximum number of matches to return (default: 50)"),
787
- includePatterns: z13.z.array(z13.z.string()).optional().describe("Glob patterns to include (e.g., ['*.ts', '*.js'])"),
788
- excludePatterns: z13.z.array(z13.z.string()).optional().describe("Glob patterns to exclude (e.g., ['*.test.ts'])"),
789
- contextLines: z13.z.number().optional().describe("Number of context lines to show around matches")
944
+ schema: z14.z.object({
945
+ pattern: z14.z.string().describe("Regex pattern to search for in file contents"),
946
+ ignoreCase: z14.z.boolean().optional().describe("Case-insensitive search (default: false)"),
947
+ maxMatches: z14.z.number().optional().describe("Maximum number of matches to return (default: 50)"),
948
+ includePatterns: z14.z.array(z14.z.string()).optional().describe("Glob patterns to include (e.g., ['*.ts', '*.js'])"),
949
+ excludePatterns: z14.z.array(z14.z.string()).optional().describe("Glob patterns to exclude (e.g., ['*.test.ts'])"),
950
+ contextLines: z14.z.number().optional().describe("Number of context lines to show around matches")
790
951
  }),
791
952
  strict: true
792
953
  };
@@ -804,12 +965,12 @@ The tool returns the file content in an appropriate format:
804
965
  - Images: Base64-encoded image data
805
966
  - PDFs: Extracted text content
806
967
  `,
807
- schema: z13.z.object({
808
- path: z13.z.string().describe("Virtual path to the file to read"),
809
- offset: z13.z.number().optional().describe(
968
+ schema: z14.z.object({
969
+ path: z14.z.string().describe("Virtual path to the file to read"),
970
+ offset: z14.z.number().optional().describe(
810
971
  "Line number to start reading from (1-indexed, for text files)"
811
972
  ),
812
- limit: z13.z.number().optional().describe("Maximum number of lines to read (for text files)")
973
+ limit: z14.z.number().optional().describe("Maximum number of lines to read (for text files)")
813
974
  }),
814
975
  strict: true
815
976
  };
@@ -826,9 +987,9 @@ IMPORTANT:
826
987
  - This is an atomic write operation - the entire file is replaced
827
988
  - Path must be relative to the root of the file system (e.g., "docs/readme.md", not "/docs/readme.md")
828
989
  `,
829
- schema: z13.z.object({
830
- file_path: z13.z.string().describe("The path to the file to write"),
831
- content: z13.z.string().describe("The content to write to the file")
990
+ schema: z14.z.object({
991
+ file_path: z14.z.string().describe("The path to the file to write"),
992
+ content: z14.z.string().describe("The content to write to the file")
832
993
  }),
833
994
  strict: true
834
995
  };
@@ -848,13 +1009,13 @@ IMPORTANT:
848
1009
  - The operation fails if old_string is not found
849
1010
  - old_string and new_string must be different
850
1011
  `,
851
- schema: z13.z.object({
852
- file_path: z13.z.string().describe("The absolute virtual path to the file to modify"),
853
- old_string: z13.z.string().describe("The exact text to replace"),
854
- new_string: z13.z.string().describe(
1012
+ schema: z14.z.object({
1013
+ file_path: z14.z.string().describe("The absolute virtual path to the file to modify"),
1014
+ old_string: z14.z.string().describe("The exact text to replace"),
1015
+ new_string: z14.z.string().describe(
855
1016
  "The text to replace it with (must be different from old_string)"
856
1017
  ),
857
- replace_all: z13.z.boolean().optional().describe(
1018
+ replace_all: z14.z.boolean().optional().describe(
858
1019
  "If true, replace all occurrences of old_string (default: false)"
859
1020
  )
860
1021
  }),
@@ -862,7 +1023,7 @@ IMPORTANT:
862
1023
  };
863
1024
  var taskCreateTool = {
864
1025
  name: "TaskCreate",
865
- description: `Use this tool to create a structured task list for the control test. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
1026
+ description: `Use this tool to create a structured task list. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
866
1027
  It also helps the user understand the progress of the task and overall progress of their requests.
867
1028
 
868
1029
  ## When to Use This Tool
@@ -901,17 +1062,17 @@ var taskCreateTool = {
901
1062
  - Include enough detail in the description for another agent to understand and complete the task
902
1063
  - After creating tasks, use TaskUpdate to set up dependencies (blocks/blockedBy) if needed
903
1064
  - Check TaskList first to avoid creating duplicate tasks`,
904
- schema: z13__default.default.object({
905
- subject: z13__default.default.string().describe(
1065
+ schema: z14__default.default.object({
1066
+ subject: z14__default.default.string().describe(
906
1067
  'A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")'
907
1068
  ),
908
- description: z13__default.default.string().describe(
1069
+ description: z14__default.default.string().describe(
909
1070
  "Detailed description of what needs to be done, including context and acceptance criteria"
910
1071
  ),
911
- activeForm: z13__default.default.string().describe(
1072
+ activeForm: z14__default.default.string().describe(
912
1073
  'Present continuous form shown in spinner when task is in_progress (e.g., "Fixing authentication bug"). This is displayed to the user while you work on the task.'
913
1074
  ),
914
- metadata: z13__default.default.record(z13__default.default.string(), z13__default.default.string()).describe("Arbitrary key-value pairs for tracking")
1075
+ metadata: z14__default.default.record(z14__default.default.string(), z14__default.default.string()).describe("Arbitrary key-value pairs for tracking")
915
1076
  })
916
1077
  };
917
1078
  function createTaskCreateHandler(stateManager) {
@@ -936,8 +1097,8 @@ function createTaskCreateHandler(stateManager) {
936
1097
  var taskGetTool = {
937
1098
  name: "TaskGet",
938
1099
  description: `Retrieve full task details including dependencies.`,
939
- schema: z13__default.default.object({
940
- taskId: z13__default.default.string().describe("The ID of the task to get")
1100
+ schema: z14__default.default.object({
1101
+ taskId: z14__default.default.string().describe("The ID of the task to get")
941
1102
  })
942
1103
  };
943
1104
 
@@ -960,7 +1121,7 @@ function createTaskGetHandler(stateManager) {
960
1121
  var taskListTool = {
961
1122
  name: "TaskList",
962
1123
  description: `List all tasks with current state.`,
963
- schema: z13__default.default.object({})
1124
+ schema: z14__default.default.object({})
964
1125
  };
965
1126
 
966
1127
  // src/tools/task-list/handler.ts
@@ -976,11 +1137,11 @@ function createTaskListHandler(stateManager) {
976
1137
  var taskUpdateTool = {
977
1138
  name: "TaskUpdate",
978
1139
  description: `Update status, add blockers, modify details.`,
979
- schema: z13__default.default.object({
980
- taskId: z13__default.default.string().describe("The ID of the task to get"),
981
- status: z13__default.default.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
982
- addBlockedBy: z13__default.default.array(z13__default.default.string()).describe("The IDs of the tasks that are blocking this task"),
983
- addBlocks: z13__default.default.array(z13__default.default.string()).describe("The IDs of the tasks that this task is blocking")
1140
+ schema: z14__default.default.object({
1141
+ taskId: z14__default.default.string().describe("The ID of the task to get"),
1142
+ status: z14__default.default.enum(["pending", "in_progress", "completed"]).describe("The status of the task"),
1143
+ addBlockedBy: z14__default.default.array(z14__default.default.string()).describe("The IDs of the tasks that are blocking this task"),
1144
+ addBlocks: z14__default.default.array(z14__default.default.string()).describe("The IDs of the tasks that this task is blocking")
984
1145
  })
985
1146
  };
986
1147
 
@@ -1048,8 +1209,8 @@ Use this tool to:
1048
1209
  - Execute scripts and chain commands with pipes (|) or logical operators (&&, ||)
1049
1210
  - Inspect files and directories
1050
1211
  `,
1051
- schema: z13__default.default.object({
1052
- command: z13__default.default.string().describe(
1212
+ schema: z14__default.default.object({
1213
+ command: z14__default.default.string().describe(
1053
1214
  "The bash command to execute. Can include pipes (|), redirects (>, >>), logical operators (&&, ||), and shell features like command substitution $(...)."
1054
1215
  )
1055
1216
  }),
@@ -1070,18 +1231,18 @@ Usage notes:
1070
1231
  * Use multiSelect: true to allow multiple answers to be selected for a question
1071
1232
  * If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
1072
1233
  `,
1073
- schema: z13__default.default.object({
1074
- questions: z13__default.default.array(
1075
- z13__default.default.object({
1076
- question: z13__default.default.string().describe("The full question text to display"),
1077
- header: z13__default.default.string().describe("Short label for the question (max 12 characters)"),
1078
- options: z13__default.default.array(
1079
- z13__default.default.object({
1080
- label: z13__default.default.string(),
1081
- description: z13__default.default.string()
1234
+ schema: z14__default.default.object({
1235
+ questions: z14__default.default.array(
1236
+ z14__default.default.object({
1237
+ question: z14__default.default.string().describe("The full question text to display"),
1238
+ header: z14__default.default.string().describe("Short label for the question (max 12 characters)"),
1239
+ options: z14__default.default.array(
1240
+ z14__default.default.object({
1241
+ label: z14__default.default.string(),
1242
+ description: z14__default.default.string()
1082
1243
  })
1083
1244
  ).min(0).max(4).describe("Array of 0-4 choices, each with label and description"),
1084
- multiSelect: z13__default.default.boolean().describe("If true, users can select multiple options")
1245
+ multiSelect: z14__default.default.boolean().describe("If true, users can select multiple options")
1085
1246
  })
1086
1247
  )
1087
1248
  }),
@@ -1096,49 +1257,19 @@ var createAskUserQuestionHandler = () => async (args) => {
1096
1257
  };
1097
1258
  };
1098
1259
 
1099
- // node_modules/uuid/dist/esm-node/stringify.js
1100
- var byteToHex = [];
1101
- for (let i = 0; i < 256; ++i) {
1102
- byteToHex.push((i + 256).toString(16).slice(1));
1103
- }
1104
- function unsafeStringify(arr, offset = 0) {
1105
- return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
1106
- }
1107
- var rnds8Pool = new Uint8Array(256);
1108
- var poolPtr = rnds8Pool.length;
1109
- function rng() {
1110
- if (poolPtr > rnds8Pool.length - 16) {
1111
- crypto__default.default.randomFillSync(rnds8Pool);
1112
- poolPtr = 0;
1113
- }
1114
- return rnds8Pool.slice(poolPtr, poolPtr += 16);
1115
- }
1116
- var native_default = {
1117
- randomUUID: crypto__default.default.randomUUID
1118
- };
1119
-
1120
- // node_modules/uuid/dist/esm-node/v4.js
1121
- function v4(options, buf, offset) {
1122
- if (native_default.randomUUID && !buf && !options) {
1123
- return native_default.randomUUID();
1124
- }
1125
- options = options || {};
1126
- const rnds = options.random || (options.rng || rng)();
1127
- rnds[6] = rnds[6] & 15 | 64;
1128
- rnds[8] = rnds[8] & 63 | 128;
1129
- if (buf) {
1130
- offset = offset || 0;
1131
- for (let i = 0; i < 16; ++i) {
1132
- buf[offset + i] = rnds[i];
1133
- }
1134
- return buf;
1135
- }
1136
- return unsafeStringify(rnds);
1137
- }
1138
- var v4_default = v4;
1139
-
1140
1260
  // src/lib/thread-manager.ts
1141
1261
  var THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;
1262
+ var APPEND_IDEMPOTENT_SCRIPT = `
1263
+ if redis.call('EXISTS', KEYS[1]) == 1 then
1264
+ return 0
1265
+ end
1266
+ for i = 2, #ARGV do
1267
+ redis.call('RPUSH', KEYS[2], ARGV[i])
1268
+ end
1269
+ redis.call('EXPIRE', KEYS[2], tonumber(ARGV[1]))
1270
+ redis.call('SET', KEYS[1], '1', 'EX', tonumber(ARGV[1]))
1271
+ return 1
1272
+ `;
1142
1273
  function getThreadKey(threadId, key) {
1143
1274
  return `thread:${threadId}:${key}`;
1144
1275
  }
@@ -1148,152 +1279,66 @@ function createThreadManager(config) {
1148
1279
  threadId,
1149
1280
  key = "messages",
1150
1281
  serialize = (m) => JSON.stringify(m),
1151
- deserialize = (raw) => JSON.parse(raw)
1282
+ deserialize = (raw) => JSON.parse(raw),
1283
+ idOf
1152
1284
  } = config;
1153
1285
  const redisKey = getThreadKey(threadId, key);
1154
- const base = {
1286
+ const metaKey = getThreadKey(threadId, `${key}:meta`);
1287
+ async function assertThreadExists() {
1288
+ const exists = await redis.exists(metaKey);
1289
+ if (!exists) {
1290
+ throw new Error(`Thread "${threadId}" (key: ${key}) does not exist`);
1291
+ }
1292
+ }
1293
+ return {
1155
1294
  async initialize() {
1156
1295
  await redis.del(redisKey);
1296
+ await redis.set(metaKey, "1", "EX", THREAD_TTL_SECONDS);
1157
1297
  },
1158
1298
  async load() {
1299
+ await assertThreadExists();
1159
1300
  const data = await redis.lrange(redisKey, 0, -1);
1160
1301
  return data.map(deserialize);
1161
1302
  },
1162
1303
  async append(messages) {
1163
- if (messages.length > 0) {
1304
+ if (messages.length === 0) return;
1305
+ await assertThreadExists();
1306
+ if (idOf) {
1307
+ const dedupId = messages.map(idOf).join(":");
1308
+ const dedupKey = getThreadKey(threadId, `dedup:${dedupId}`);
1309
+ await redis.eval(
1310
+ APPEND_IDEMPOTENT_SCRIPT,
1311
+ 2,
1312
+ dedupKey,
1313
+ redisKey,
1314
+ String(THREAD_TTL_SECONDS),
1315
+ ...messages.map(serialize)
1316
+ );
1317
+ } else {
1164
1318
  await redis.rpush(redisKey, ...messages.map(serialize));
1165
1319
  await redis.expire(redisKey, THREAD_TTL_SECONDS);
1166
1320
  }
1167
1321
  },
1168
1322
  async delete() {
1169
- await redis.del(redisKey);
1170
- }
1171
- };
1172
- const helpers = {
1173
- createHumanMessage(content) {
1174
- return new messages.HumanMessage({
1175
- id: v4_default(),
1176
- content
1177
- }).toDict();
1178
- },
1179
- createSystemMessage(content) {
1180
- return new messages.SystemMessage({
1181
- id: v4_default(),
1182
- content
1183
- }).toDict();
1184
- },
1185
- createAIMessage(content, kwargs) {
1186
- return new messages.AIMessage({
1187
- id: v4_default(),
1188
- content,
1189
- additional_kwargs: kwargs ? {
1190
- header: kwargs.header,
1191
- options: kwargs.options,
1192
- multiSelect: kwargs.multiSelect
1193
- } : void 0
1194
- }).toDict();
1195
- },
1196
- createToolMessage(content, toolCallId) {
1197
- return new messages.ToolMessage({
1198
- content,
1199
- tool_call_id: toolCallId
1200
- }).toDict();
1201
- },
1202
- async appendHumanMessage(content) {
1203
- const message = helpers.createHumanMessage(content);
1204
- await base.append([message]);
1205
- },
1206
- async appendToolMessage(content, toolCallId) {
1207
- const message = helpers.createToolMessage(content, toolCallId);
1208
- await base.append([message]);
1209
- },
1210
- async appendAIMessage(content) {
1211
- const message = helpers.createAIMessage(content);
1212
- await base.append([message]);
1213
- },
1214
- async appendSystemMessage(content) {
1215
- const message = helpers.createSystemMessage(content);
1216
- await base.append([message]);
1323
+ await redis.del(redisKey, metaKey);
1217
1324
  }
1218
1325
  };
1219
- return Object.assign(base, helpers);
1220
1326
  }
1221
-
1222
- // src/activities.ts
1223
- function createSharedActivities(redis) {
1224
- return {
1225
- async appendToolResult(config) {
1226
- const { threadId, toolCallId, content } = config;
1227
- const thread = createThreadManager({ redis, threadId });
1228
- await thread.appendToolMessage(content, toolCallId);
1229
- },
1230
- async initializeThread(threadId) {
1231
- const thread = createThreadManager({ redis, threadId });
1232
- await thread.initialize();
1233
- },
1234
- async appendThreadMessages(threadId, messages) {
1235
- const thread = createThreadManager({ redis, threadId });
1236
- await thread.append(messages);
1237
- },
1238
- async appendHumanMessage(threadId, content) {
1239
- const thread = createThreadManager({ redis, threadId });
1240
- await thread.appendHumanMessage(content);
1241
- },
1242
- async appendSystemMessage(threadId, content) {
1243
- const thread = createThreadManager({ redis, threadId });
1244
- await thread.appendSystemMessage(content);
1245
- }
1246
- };
1247
- }
1248
-
1249
- // src/plugin.ts
1250
- var ZeitlichPlugin = class extends plugin.SimplePlugin {
1251
- constructor(options) {
1252
- super({
1253
- name: "ZeitlichPlugin",
1254
- activities: createSharedActivities(options.redis)
1255
- });
1256
- }
1257
- };
1258
- async function invokeModel({
1259
- redis,
1260
- model,
1261
- client,
1262
- config: { threadId, agentName }
1263
- }) {
1264
- const thread = createThreadManager({ redis, threadId });
1265
- const runId = v4_default();
1266
- const info = activity.Context.current().info;
1267
- const parentWorkflowId = info.workflowExecution.workflowId;
1268
- const parentRunId = info.workflowExecution.runId;
1269
- const handle = client.getHandle(parentWorkflowId, parentRunId);
1270
- const { tools } = await handle.query(`get${agentName}State`);
1271
- const messages$1 = await thread.load();
1272
- const response = await model.invoke(
1273
- [...messages.mapStoredMessagesToChatMessages(messages$1)],
1274
- {
1275
- runName: agentName,
1276
- runId,
1277
- metadata: { thread_id: threadId },
1278
- tools
1279
- }
1327
+ async function queryParentWorkflowState(client, queryName) {
1328
+ const { workflowExecution } = activity.Context.current().info;
1329
+ const handle = client.getHandle(
1330
+ workflowExecution.workflowId,
1331
+ workflowExecution.runId
1280
1332
  );
1281
- await thread.append([response.toDict()]);
1282
- const toolCalls = response.tool_calls ?? [];
1283
- return {
1284
- message: response.toDict(),
1285
- rawToolCalls: toolCalls.map((tc) => ({
1286
- id: tc.id,
1287
- name: tc.name,
1288
- args: tc.args
1289
- })),
1290
- usage: {
1291
- inputTokens: response.usage_metadata?.input_tokens,
1292
- outputTokens: response.usage_metadata?.output_tokens,
1293
- reasonTokens: response.usage_metadata?.output_token_details?.reasoning,
1294
- cachedWriteTokens: response.usage_metadata?.input_token_details?.cache_creation,
1295
- cachedReadTokens: response.usage_metadata?.input_token_details?.cache_read
1296
- }
1333
+ return handle.query(queryName);
1334
+ }
1335
+ function createRunAgentActivity(client, invoker) {
1336
+ return async (config) => {
1337
+ const state = await queryParentWorkflowState(
1338
+ client,
1339
+ agentQueryName(config.agentName)
1340
+ );
1341
+ return invoker({ ...config, state });
1297
1342
  };
1298
1343
  }
1299
1344
  function createGlobHandler(fs) {
@@ -1464,9 +1509,65 @@ var toTree = async (fs, opts = {}) => {
1464
1509
  const base = basename(dir, separator) + separator;
1465
1510
  return base + subtree;
1466
1511
  };
1512
+ var FileSystemSkillProvider = class {
1513
+ constructor(baseDir) {
1514
+ this.baseDir = baseDir;
1515
+ }
1516
+ async listSkills() {
1517
+ const dirs = await this.discoverSkillDirs();
1518
+ const skills = [];
1519
+ for (const dir of dirs) {
1520
+ const raw = await promises.readFile(path.join(this.baseDir, dir, "SKILL.md"), "utf-8");
1521
+ const { frontmatter } = parseSkillFile(raw);
1522
+ skills.push(frontmatter);
1523
+ }
1524
+ return skills;
1525
+ }
1526
+ async getSkill(name) {
1527
+ const raw = await promises.readFile(
1528
+ path.join(this.baseDir, name, "SKILL.md"),
1529
+ "utf-8"
1530
+ );
1531
+ const { frontmatter, body } = parseSkillFile(raw);
1532
+ if (frontmatter.name !== name) {
1533
+ throw new Error(
1534
+ `Skill directory "${name}" contains SKILL.md with mismatched name "${frontmatter.name}"`
1535
+ );
1536
+ }
1537
+ return { ...frontmatter, instructions: body };
1538
+ }
1539
+ /**
1540
+ * Convenience method to load all skills with full instructions.
1541
+ * Returns `Skill[]` ready to pass into a workflow.
1542
+ */
1543
+ async loadAll() {
1544
+ const dirs = await this.discoverSkillDirs();
1545
+ const skills = [];
1546
+ for (const dir of dirs) {
1547
+ const raw = await promises.readFile(path.join(this.baseDir, dir, "SKILL.md"), "utf-8");
1548
+ const { frontmatter, body } = parseSkillFile(raw);
1549
+ skills.push({ ...frontmatter, instructions: body });
1550
+ }
1551
+ return skills;
1552
+ }
1553
+ async discoverSkillDirs() {
1554
+ const entries = await promises.readdir(this.baseDir, { withFileTypes: true });
1555
+ const dirs = [];
1556
+ for (const entry of entries) {
1557
+ if (!entry.isDirectory()) continue;
1558
+ try {
1559
+ await promises.readFile(path.join(this.baseDir, entry.name, "SKILL.md"), "utf-8");
1560
+ dirs.push(entry.name);
1561
+ } catch {
1562
+ }
1563
+ }
1564
+ return dirs;
1565
+ }
1566
+ };
1467
1567
 
1468
- exports.AGENT_HANDLER_NAMES = AGENT_HANDLER_NAMES;
1469
- exports.ZeitlichPlugin = ZeitlichPlugin;
1568
+ exports.FileSystemSkillProvider = FileSystemSkillProvider;
1569
+ exports.agentQueryName = agentQueryName;
1570
+ exports.agentStateChangeUpdateName = agentStateChangeUpdateName;
1470
1571
  exports.askUserQuestionTool = askUserQuestionTool;
1471
1572
  exports.bashTool = bashTool;
1472
1573
  exports.createAgentStateManager = createAgentStateManager;
@@ -1475,8 +1576,10 @@ exports.createBashHandler = createBashHandler;
1475
1576
  exports.createBashToolDescription = createBashToolDescription;
1476
1577
  exports.createEditHandler = createEditHandler;
1477
1578
  exports.createGlobHandler = createGlobHandler;
1579
+ exports.createReadSkillHandler = createReadSkillHandler;
1580
+ exports.createReadSkillTool = createReadSkillTool;
1581
+ exports.createRunAgentActivity = createRunAgentActivity;
1478
1582
  exports.createSession = createSession;
1479
- exports.createSharedActivities = createSharedActivities;
1480
1583
  exports.createSubagentTool = createSubagentTool;
1481
1584
  exports.createTaskCreateHandler = createTaskCreateHandler;
1482
1585
  exports.createTaskGetHandler = createTaskGetHandler;
@@ -1487,12 +1590,14 @@ exports.createToolRouter = createToolRouter;
1487
1590
  exports.defineSubagent = defineSubagent;
1488
1591
  exports.defineTool = defineTool;
1489
1592
  exports.editTool = editTool;
1593
+ exports.getShortId = getShortId;
1490
1594
  exports.globTool = globTool;
1491
1595
  exports.grepTool = grepTool;
1492
1596
  exports.hasNoOtherToolCalls = hasNoOtherToolCalls;
1493
- exports.invokeModel = invokeModel;
1494
1597
  exports.isTerminalStatus = isTerminalStatus;
1598
+ exports.parseSkillFile = parseSkillFile;
1495
1599
  exports.proxyDefaultThreadOps = proxyDefaultThreadOps;
1600
+ exports.queryParentWorkflowState = queryParentWorkflowState;
1496
1601
  exports.readFileTool = readFileTool;
1497
1602
  exports.taskCreateTool = taskCreateTool;
1498
1603
  exports.taskGetTool = taskGetTool;