zeitlich 0.2.23 → 0.2.24

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 (75) hide show
  1. package/README.md +44 -8
  2. package/dist/adapters/sandbox/bedrock/index.cjs +427 -0
  3. package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -0
  4. package/dist/adapters/sandbox/bedrock/index.d.cts +23 -0
  5. package/dist/adapters/sandbox/bedrock/index.d.ts +23 -0
  6. package/dist/adapters/sandbox/bedrock/index.js +424 -0
  7. package/dist/adapters/sandbox/bedrock/index.js.map +1 -0
  8. package/dist/adapters/sandbox/bedrock/workflow.cjs +33 -0
  9. package/dist/adapters/sandbox/bedrock/workflow.cjs.map +1 -0
  10. package/dist/adapters/sandbox/bedrock/workflow.d.cts +29 -0
  11. package/dist/adapters/sandbox/bedrock/workflow.d.ts +29 -0
  12. package/dist/adapters/sandbox/bedrock/workflow.js +31 -0
  13. package/dist/adapters/sandbox/bedrock/workflow.js.map +1 -0
  14. package/dist/adapters/sandbox/virtual/index.cjs +12 -2
  15. package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
  16. package/dist/adapters/sandbox/virtual/index.d.cts +4 -4
  17. package/dist/adapters/sandbox/virtual/index.d.ts +4 -4
  18. package/dist/adapters/sandbox/virtual/index.js +12 -2
  19. package/dist/adapters/sandbox/virtual/index.js.map +1 -1
  20. package/dist/adapters/sandbox/virtual/workflow.d.cts +2 -2
  21. package/dist/adapters/sandbox/virtual/workflow.d.ts +2 -2
  22. package/dist/adapters/thread/google-genai/index.d.cts +2 -2
  23. package/dist/adapters/thread/google-genai/index.d.ts +2 -2
  24. package/dist/adapters/thread/google-genai/workflow.d.cts +2 -2
  25. package/dist/adapters/thread/google-genai/workflow.d.ts +2 -2
  26. package/dist/adapters/thread/langchain/index.d.cts +2 -2
  27. package/dist/adapters/thread/langchain/index.d.ts +2 -2
  28. package/dist/adapters/thread/langchain/workflow.d.cts +2 -2
  29. package/dist/adapters/thread/langchain/workflow.d.ts +2 -2
  30. package/dist/index.cjs +199 -17
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +63 -10
  33. package/dist/index.d.ts +63 -10
  34. package/dist/index.js +200 -19
  35. package/dist/index.js.map +1 -1
  36. package/dist/{queries-DModcWRy.d.cts → queries-BYGBImeC.d.cts} +1 -1
  37. package/dist/{queries-byD0jr1Y.d.ts → queries-DwBe2CAA.d.ts} +1 -1
  38. package/dist/{types-DQW8l7pY.d.cts → types-7PeMi1bD.d.cts} +9 -2
  39. package/dist/{types-BuXdFhaZ.d.cts → types-Bf8KV0Ci.d.cts} +1 -1
  40. package/dist/{types-Bll19FZJ.d.ts → types-D_igp10o.d.cts} +4 -0
  41. package/dist/{types-Bll19FZJ.d.cts → types-D_igp10o.d.ts} +4 -0
  42. package/dist/types-DhTCEMhr.d.cts +64 -0
  43. package/dist/{types-GZ76HZSj.d.ts → types-LVKmCNds.d.ts} +1 -1
  44. package/dist/types-d9NznUqd.d.ts +64 -0
  45. package/dist/{types-B50pBPEV.d.ts → types-hmferhc2.d.ts} +9 -2
  46. package/dist/workflow.cjs +70 -9
  47. package/dist/workflow.cjs.map +1 -1
  48. package/dist/workflow.d.cts +12 -7
  49. package/dist/workflow.d.ts +12 -7
  50. package/dist/workflow.js +70 -9
  51. package/dist/workflow.js.map +1 -1
  52. package/package.json +26 -1
  53. package/src/adapters/sandbox/bedrock/filesystem.ts +313 -0
  54. package/src/adapters/sandbox/bedrock/index.ts +259 -0
  55. package/src/adapters/sandbox/bedrock/proxy.ts +56 -0
  56. package/src/adapters/sandbox/bedrock/types.ts +24 -0
  57. package/src/adapters/sandbox/virtual/filesystem.ts +5 -3
  58. package/src/adapters/sandbox/virtual/provider.ts +9 -0
  59. package/src/adapters/sandbox/virtual/virtual-sandbox.test.ts +26 -0
  60. package/src/index.ts +2 -1
  61. package/src/lib/lifecycle.ts +1 -1
  62. package/src/lib/sandbox/node-fs.ts +115 -0
  63. package/src/lib/session/session.integration.test.ts +97 -0
  64. package/src/lib/session/session.ts +33 -2
  65. package/src/lib/session/types.ts +1 -1
  66. package/src/lib/skills/fs-provider.ts +65 -4
  67. package/src/lib/skills/handler.ts +43 -1
  68. package/src/lib/skills/index.ts +0 -1
  69. package/src/lib/skills/register.ts +17 -1
  70. package/src/lib/skills/skills.integration.test.ts +308 -24
  71. package/src/lib/skills/types.ts +6 -0
  72. package/src/lib/subagent/handler.ts +5 -1
  73. package/src/lib/tool-router/router.ts +6 -3
  74. package/src/lib/tool-router/types.ts +4 -0
  75. package/tsup.config.ts +3 -0
package/dist/index.cjs CHANGED
@@ -6,6 +6,7 @@ var crypto = require('crypto');
6
6
  var common = require('@temporalio/common');
7
7
  var path = require('path');
8
8
  var activity = require('@temporalio/activity');
9
+ var fs = require('fs');
9
10
 
10
11
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
12
 
@@ -18,8 +19,8 @@ function createToolRouter(options) {
18
19
  for (const [_key, tool] of Object.entries(options.tools)) {
19
20
  toolMap.set(tool.name, tool);
20
21
  }
21
- const resolve = (v) => typeof v === "function" ? v() : v;
22
- const isEnabled = (tool) => resolve(tool.enabled) ?? true;
22
+ const resolve2 = (v) => typeof v === "function" ? v() : v;
23
+ const isEnabled = (tool) => resolve2(tool.enabled) ?? true;
23
24
  if (options.plugins) {
24
25
  for (const plugin of options.plugins) {
25
26
  toolMap.set(plugin.name, plugin);
@@ -116,7 +117,7 @@ function createToolRouter(options) {
116
117
  });
117
118
  }
118
119
  }
119
- async function processToolCall(toolCall, turn, sandboxId) {
120
+ async function processToolCall(toolCall, turn, sandboxId, sandboxStateUpdate) {
120
121
  const startTime = Date.now();
121
122
  const tool = toolMap.get(toolCall.name);
122
123
  const preResult = await runPreHooks(toolCall, tool, turn);
@@ -143,7 +144,8 @@ function createToolRouter(options) {
143
144
  threadId: options.threadId,
144
145
  toolCallId: toolCall.id,
145
146
  toolName: toolCall.name,
146
- ...sandboxId !== void 0 && { sandboxId }
147
+ ...sandboxId !== void 0 && { sandboxId },
148
+ ...sandboxStateUpdate && { sandboxStateUpdate }
147
149
  };
148
150
  const response = await tool.handler(
149
151
  effectiveArgs,
@@ -207,7 +209,7 @@ function createToolRouter(options) {
207
209
  if (!tool || !isEnabled(tool)) {
208
210
  throw new Error(`Tool ${toolCall.name} not found`);
209
211
  }
210
- const parsedArgs = resolve(tool.schema).parse(toolCall.args);
212
+ const parsedArgs = resolve2(tool.schema).parse(toolCall.args);
211
213
  return {
212
214
  id: toolCall.id ?? "",
213
215
  name: toolCall.name,
@@ -224,8 +226,8 @@ function createToolRouter(options) {
224
226
  getToolDefinitions() {
225
227
  return Array.from(toolMap).filter(([, tool]) => isEnabled(tool)).map(([name, tool]) => ({
226
228
  name,
227
- description: resolve(tool.description),
228
- schema: resolve(tool.schema),
229
+ description: resolve2(tool.description),
230
+ schema: resolve2(tool.schema),
229
231
  strict: tool.strict,
230
232
  max_uses: tool.max_uses
231
233
  }));
@@ -236,9 +238,10 @@ function createToolRouter(options) {
236
238
  }
237
239
  const turn = context?.turn ?? 0;
238
240
  const sandboxId = context?.sandboxId;
241
+ const sandboxStateUpdate = context?.sandboxStateUpdate;
239
242
  if (options.parallel) {
240
243
  const results2 = await Promise.all(
241
- toolCalls.map((tc) => processToolCall(tc, turn, sandboxId))
244
+ toolCalls.map((tc) => processToolCall(tc, turn, sandboxId, sandboxStateUpdate))
242
245
  );
243
246
  return results2.filter(
244
247
  (r) => r !== null
@@ -246,7 +249,7 @@ function createToolRouter(options) {
246
249
  }
247
250
  const results = [];
248
251
  for (const toolCall of toolCalls) {
249
- const result = await processToolCall(toolCall, turn, sandboxId);
252
+ const result = await processToolCall(toolCall, turn, sandboxId, sandboxStateUpdate);
250
253
  if (result !== null) {
251
254
  results.push(result);
252
255
  }
@@ -412,7 +415,11 @@ function createSubagentHandler(subagents) {
412
415
  }
413
416
  let sandbox;
414
417
  if (sandboxCfg.source === "inherit" && parentSandboxId) {
415
- sandbox = { mode: "inherit", sandboxId: parentSandboxId };
418
+ sandbox = {
419
+ mode: "inherit",
420
+ sandboxId: parentSandboxId,
421
+ ...context.sandboxStateUpdate && { stateUpdate: context.sandboxStateUpdate }
422
+ };
416
423
  } else if (sandboxCfg.source === "own") {
417
424
  const prevSbId = continuationThreadId ? threadSandboxes.get(continuationThreadId) : void 0;
418
425
  if (prevSbId) {
@@ -568,6 +575,29 @@ function createReadSkillTool(skills) {
568
575
  }
569
576
 
570
577
  // src/lib/skills/handler.ts
578
+ function formatSkillResponse(skill) {
579
+ const parts = [];
580
+ parts.push(`<skill_content name="${skill.name}">`);
581
+ parts.push(skill.instructions);
582
+ if (skill.location) {
583
+ parts.push(`
584
+ Skill directory: ${skill.location}`);
585
+ parts.push(
586
+ "Relative paths in this skill resolve against the skill directory above."
587
+ );
588
+ }
589
+ const resources = skill.resourceContents ? Object.keys(skill.resourceContents) : [];
590
+ if (resources.length > 0) {
591
+ parts.push("");
592
+ parts.push("<skill_resources>");
593
+ for (const r of resources) {
594
+ parts.push(` <file>${r}</file>`);
595
+ }
596
+ parts.push("</skill_resources>");
597
+ }
598
+ parts.push("</skill_content>");
599
+ return parts.join("\n");
600
+ }
571
601
  function createReadSkillHandler(skills) {
572
602
  const skillMap = new Map(skills.map((s) => [s.name, s]));
573
603
  return (args) => {
@@ -581,20 +611,41 @@ function createReadSkillHandler(skills) {
581
611
  };
582
612
  }
583
613
  return {
584
- toolResponse: skill.instructions,
614
+ toolResponse: formatSkillResponse(skill),
585
615
  data: null
586
616
  };
587
617
  };
588
618
  }
589
619
 
590
620
  // src/lib/skills/register.ts
621
+ function validateSkillNames(skills) {
622
+ const names = skills.map((s) => s.name);
623
+ const dupes = names.filter((n, i) => names.indexOf(n) !== i);
624
+ if (dupes.length > 0) {
625
+ throw new Error(
626
+ `Duplicate skill names: ${[...new Set(dupes)].join(", ")}`
627
+ );
628
+ }
629
+ }
591
630
  function buildSkillRegistration(skills) {
592
631
  if (skills.length === 0) return null;
632
+ validateSkillNames(skills);
593
633
  return {
594
634
  ...createReadSkillTool(skills),
595
635
  handler: createReadSkillHandler(skills)
596
636
  };
597
637
  }
638
+ function collectSkillFiles(skills) {
639
+ let files;
640
+ for (const skill of skills) {
641
+ if (!skill.resourceContents || !skill.location) continue;
642
+ for (const [relPath, content] of Object.entries(skill.resourceContents)) {
643
+ files ??= {};
644
+ files[`${skill.location}/${relPath}`] = content;
645
+ }
646
+ }
647
+ return files;
648
+ }
598
649
  async function createSession({
599
650
  agentName,
600
651
  maxTurns = 50,
@@ -694,8 +745,14 @@ async function createSession({
694
745
  const sandboxMode = sandboxInit?.mode;
695
746
  let sandboxId;
696
747
  let sandboxOwned = false;
748
+ let sandboxStateUpdate;
697
749
  if (sandboxMode === "inherit") {
698
- sandboxId = sandboxInit.sandboxId;
750
+ const inheritInit = sandboxInit;
751
+ sandboxId = inheritInit.sandboxId;
752
+ if (inheritInit.stateUpdate) {
753
+ sandboxStateUpdate = inheritInit.stateUpdate;
754
+ stateManager.mergeUpdate(inheritInit.stateUpdate);
755
+ }
699
756
  if (!sandboxOps) {
700
757
  throw workflow.ApplicationFailure.create({
701
758
  message: "sandboxId provided but no sandboxOps \u2014 cannot manage sandbox lifecycle",
@@ -723,10 +780,14 @@ async function createSession({
723
780
  );
724
781
  sandboxOwned = true;
725
782
  } else if (sandboxOps) {
726
- const result = await sandboxOps.createSandbox();
783
+ const skillFiles = skills ? collectSkillFiles(skills) : void 0;
784
+ const result = await sandboxOps.createSandbox(
785
+ skillFiles ? { initialFiles: skillFiles } : void 0
786
+ );
727
787
  sandboxId = result.sandboxId;
728
788
  sandboxOwned = true;
729
789
  if (result.stateUpdate) {
790
+ sandboxStateUpdate = result.stateUpdate;
730
791
  stateManager.mergeUpdate(result.stateUpdate);
731
792
  }
732
793
  }
@@ -798,7 +859,8 @@ async function createSession({
798
859
  parsedToolCalls,
799
860
  {
800
861
  turn: currentTurn,
801
- ...sandboxId !== void 0 && { sandboxId }
862
+ ...sandboxId !== void 0 && { sandboxId },
863
+ ...sandboxStateUpdate && { sandboxStateUpdate }
802
864
  }
803
865
  );
804
866
  for (const result of toolCallResults) {
@@ -1739,7 +1801,11 @@ var FileSystemSkillProvider = class {
1739
1801
  for (const dir of dirs) {
1740
1802
  const raw = await this.fs.readFile(path.join(this.baseDir, dir, "SKILL.md"));
1741
1803
  const { frontmatter } = parseSkillFile(raw);
1742
- skills.push(frontmatter);
1804
+ const location = path.join(this.baseDir, dir);
1805
+ skills.push({
1806
+ ...frontmatter,
1807
+ location
1808
+ });
1743
1809
  }
1744
1810
  return skills;
1745
1811
  }
@@ -1753,7 +1819,15 @@ var FileSystemSkillProvider = class {
1753
1819
  `Skill directory "${name}" contains SKILL.md with mismatched name "${frontmatter.name}"`
1754
1820
  );
1755
1821
  }
1756
- return { ...frontmatter, instructions: body };
1822
+ const location = path.join(this.baseDir, name);
1823
+ const resourcePaths = await this.discoverResources(name);
1824
+ const resourceContents = await this.readResourceContents(location, resourcePaths);
1825
+ return {
1826
+ ...frontmatter,
1827
+ instructions: body,
1828
+ location,
1829
+ ...resourceContents && { resourceContents }
1830
+ };
1757
1831
  }
1758
1832
  /**
1759
1833
  * Convenience method to load all skills with full instructions.
@@ -1765,10 +1839,48 @@ var FileSystemSkillProvider = class {
1765
1839
  for (const dir of dirs) {
1766
1840
  const raw = await this.fs.readFile(path.join(this.baseDir, dir, "SKILL.md"));
1767
1841
  const { frontmatter, body } = parseSkillFile(raw);
1768
- skills.push({ ...frontmatter, instructions: body });
1842
+ const location = path.join(this.baseDir, dir);
1843
+ const resourcePaths = await this.discoverResources(dir);
1844
+ const resourceContents = await this.readResourceContents(location, resourcePaths);
1845
+ skills.push({
1846
+ ...frontmatter,
1847
+ instructions: body,
1848
+ location,
1849
+ ...resourceContents && { resourceContents }
1850
+ });
1769
1851
  }
1770
1852
  return skills;
1771
1853
  }
1854
+ /**
1855
+ * Recursively discovers all non-SKILL.md files inside the skill directory
1856
+ * and returns their paths relative to the skill root.
1857
+ */
1858
+ async discoverResources(skillDir) {
1859
+ const skillRoot = path.join(this.baseDir, skillDir);
1860
+ const resources = [];
1861
+ const walk2 = async (dir, prefix) => {
1862
+ const entries = await this.fs.readdirWithFileTypes(dir);
1863
+ for (const e of entries) {
1864
+ if (e.name.startsWith(".")) continue;
1865
+ const relPath = prefix ? `${prefix}/${e.name}` : e.name;
1866
+ if (e.isDirectory) {
1867
+ await walk2(path.join(dir, e.name), relPath);
1868
+ } else if (e.isFile && e.name !== "SKILL.md") {
1869
+ resources.push(relPath);
1870
+ }
1871
+ }
1872
+ };
1873
+ await walk2(skillRoot, "");
1874
+ return resources;
1875
+ }
1876
+ async readResourceContents(location, resources) {
1877
+ if (resources.length === 0) return void 0;
1878
+ const contents = {};
1879
+ for (const r of resources) {
1880
+ contents[r] = await this.fs.readFile(path.join(location, r));
1881
+ }
1882
+ return contents;
1883
+ }
1772
1884
  async discoverSkillDirs() {
1773
1885
  const entries = await this.fs.readdirWithFileTypes(this.baseDir);
1774
1886
  const dirs = [];
@@ -1960,6 +2072,75 @@ var SandboxManager = class {
1960
2072
  );
1961
2073
  }
1962
2074
  };
2075
+ var NodeFsSandboxFileSystem = class {
2076
+ workspaceBase;
2077
+ constructor(workspaceBase) {
2078
+ this.workspaceBase = workspaceBase;
2079
+ }
2080
+ abs(path$1) {
2081
+ return path.resolve(this.workspaceBase, path$1);
2082
+ }
2083
+ async readFile(path) {
2084
+ return fs.promises.readFile(this.abs(path), "utf-8");
2085
+ }
2086
+ async readFileBuffer(path) {
2087
+ return fs.promises.readFile(this.abs(path));
2088
+ }
2089
+ async writeFile(path, content) {
2090
+ await fs.promises.writeFile(this.abs(path), content);
2091
+ }
2092
+ async appendFile(path, content) {
2093
+ await fs.promises.appendFile(this.abs(path), content);
2094
+ }
2095
+ async exists(path) {
2096
+ try {
2097
+ await fs.promises.access(this.abs(path));
2098
+ return true;
2099
+ } catch {
2100
+ return false;
2101
+ }
2102
+ }
2103
+ async stat(path) {
2104
+ const s = await fs.promises.stat(this.abs(path));
2105
+ return {
2106
+ isFile: s.isFile(),
2107
+ isDirectory: s.isDirectory(),
2108
+ isSymbolicLink: s.isSymbolicLink(),
2109
+ size: s.size,
2110
+ mtime: s.mtime
2111
+ };
2112
+ }
2113
+ async mkdir(path, options) {
2114
+ await fs.promises.mkdir(this.abs(path), options);
2115
+ }
2116
+ async readdir(path) {
2117
+ return fs.promises.readdir(this.abs(path));
2118
+ }
2119
+ async readdirWithFileTypes(path) {
2120
+ const entries = await fs.promises.readdir(this.abs(path), { withFileTypes: true });
2121
+ return entries.map((e) => ({
2122
+ name: e.name,
2123
+ isFile: e.isFile(),
2124
+ isDirectory: e.isDirectory(),
2125
+ isSymbolicLink: e.isSymbolicLink()
2126
+ }));
2127
+ }
2128
+ async rm(path, options) {
2129
+ await fs.promises.rm(this.abs(path), options);
2130
+ }
2131
+ async cp(src, dest, options) {
2132
+ await fs.promises.cp(this.abs(src), this.abs(dest), options);
2133
+ }
2134
+ async mv(src, dest) {
2135
+ await fs.promises.rename(this.abs(src), this.abs(dest));
2136
+ }
2137
+ async readlink(path) {
2138
+ return fs.promises.readlink(this.abs(path));
2139
+ }
2140
+ resolvePath(base, path$1) {
2141
+ return path.posix.resolve(base, path$1);
2142
+ }
2143
+ };
1963
2144
 
1964
2145
  // src/tools/bash/handler.ts
1965
2146
  var bashHandler = async (args, { sandbox }) => {
@@ -2216,6 +2397,7 @@ var toTree = async (fs, opts = {}) => {
2216
2397
  };
2217
2398
 
2218
2399
  exports.FileSystemSkillProvider = FileSystemSkillProvider;
2400
+ exports.NodeFsSandboxFileSystem = NodeFsSandboxFileSystem;
2219
2401
  exports.SandboxManager = SandboxManager;
2220
2402
  exports.SandboxNotFoundError = SandboxNotFoundError;
2221
2403
  exports.SandboxNotSupportedError = SandboxNotSupportedError;