zeitlich 0.2.13 → 0.2.14
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/README.md +49 -38
- package/dist/adapters/sandbox/daytona/index.cjs +205 -0
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -0
- package/dist/adapters/sandbox/daytona/index.d.cts +86 -0
- package/dist/adapters/sandbox/daytona/index.d.ts +86 -0
- package/dist/adapters/sandbox/daytona/index.js +202 -0
- package/dist/adapters/sandbox/daytona/index.js.map +1 -0
- package/dist/adapters/sandbox/inmemory/index.cjs +174 -0
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -0
- package/dist/adapters/sandbox/inmemory/index.d.cts +28 -0
- package/dist/adapters/sandbox/inmemory/index.d.ts +28 -0
- package/dist/adapters/sandbox/inmemory/index.js +172 -0
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -0
- package/dist/adapters/sandbox/virtual/index.cjs +405 -0
- package/dist/adapters/sandbox/virtual/index.cjs.map +1 -0
- package/dist/adapters/sandbox/virtual/index.d.cts +85 -0
- package/dist/adapters/sandbox/virtual/index.d.ts +85 -0
- package/dist/adapters/sandbox/virtual/index.js +400 -0
- package/dist/adapters/sandbox/virtual/index.js.map +1 -0
- package/dist/adapters/thread/google-genai/index.cjs +284 -0
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -0
- package/dist/adapters/thread/google-genai/index.d.cts +145 -0
- package/dist/adapters/thread/google-genai/index.d.ts +145 -0
- package/dist/adapters/thread/google-genai/index.js +278 -0
- package/dist/adapters/thread/google-genai/index.js.map +1 -0
- package/dist/adapters/{langchain → thread/langchain}/index.cjs +7 -9
- package/dist/adapters/thread/langchain/index.cjs.map +1 -0
- package/dist/adapters/{langchain → thread/langchain}/index.d.cts +17 -21
- package/dist/adapters/{langchain → thread/langchain}/index.d.ts +17 -21
- package/dist/adapters/{langchain → thread/langchain}/index.js +7 -9
- package/dist/adapters/thread/langchain/index.js.map +1 -0
- package/dist/index.cjs +816 -545
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +235 -74
- package/dist/index.d.ts +235 -74
- package/dist/index.js +804 -540
- package/dist/index.js.map +1 -1
- package/dist/types-B4C9txdq.d.ts +389 -0
- package/dist/{thread-manager-qc0g5Rvd.d.cts → types-B9ljZewB.d.cts} +1 -6
- package/dist/{thread-manager-qc0g5Rvd.d.ts → types-B9ljZewB.d.ts} +1 -6
- package/dist/types-BMXzv7TN.d.cts +476 -0
- package/dist/types-BMXzv7TN.d.ts +476 -0
- package/dist/types-BVP87m_W.d.cts +121 -0
- package/dist/types-CDubRtad.d.cts +115 -0
- package/dist/types-CDubRtad.d.ts +115 -0
- package/dist/types-CwwgQ_9H.d.ts +121 -0
- package/dist/types-GpMU4b0w.d.cts +389 -0
- package/dist/workflow.cjs +444 -318
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +271 -222
- package/dist/workflow.d.ts +271 -222
- package/dist/workflow.js +440 -316
- package/dist/workflow.js.map +1 -1
- package/package.json +59 -6
- package/src/adapters/sandbox/daytona/filesystem.ts +136 -0
- package/src/adapters/sandbox/daytona/index.ts +149 -0
- package/src/adapters/sandbox/daytona/types.ts +34 -0
- package/src/adapters/sandbox/inmemory/index.ts +213 -0
- package/src/adapters/sandbox/virtual/filesystem.ts +345 -0
- package/src/adapters/sandbox/virtual/index.ts +88 -0
- package/src/adapters/sandbox/virtual/mutations.ts +38 -0
- package/src/adapters/sandbox/virtual/provider.ts +101 -0
- package/src/adapters/sandbox/virtual/tree.ts +82 -0
- package/src/adapters/sandbox/virtual/types.ts +127 -0
- package/src/adapters/sandbox/virtual/virtual-sandbox.test.ts +523 -0
- package/src/adapters/sandbox/virtual/with-virtual-sandbox.ts +91 -0
- package/src/adapters/thread/google-genai/activities.ts +121 -0
- package/src/adapters/thread/google-genai/index.ts +41 -0
- package/src/adapters/thread/google-genai/model-invoker.ts +154 -0
- package/src/adapters/thread/google-genai/thread-manager.ts +169 -0
- package/src/adapters/{langchain → thread/langchain}/activities.ts +11 -15
- package/src/adapters/{langchain → thread/langchain}/index.ts +1 -1
- package/src/adapters/{langchain → thread/langchain}/model-invoker.ts +15 -18
- package/src/adapters/{langchain → thread/langchain}/thread-manager.ts +1 -1
- package/src/index.ts +32 -24
- package/src/lib/activity.ts +87 -0
- package/src/lib/hooks/index.ts +11 -0
- package/src/lib/hooks/types.ts +98 -0
- package/src/lib/model/helpers.ts +6 -0
- package/src/lib/model/index.ts +13 -0
- package/src/lib/{model-invoker.ts → model/types.ts} +18 -1
- package/src/lib/sandbox/index.ts +19 -0
- package/src/lib/sandbox/manager.ts +76 -0
- package/src/lib/sandbox/sandbox.test.ts +158 -0
- package/src/lib/{fs.ts → sandbox/tree.ts} +6 -6
- package/src/lib/sandbox/types.ts +164 -0
- package/src/lib/session/index.ts +11 -0
- package/src/lib/{session.ts → session/session.ts} +76 -48
- package/src/lib/session/types.ts +93 -0
- package/src/lib/skills/fs-provider.ts +16 -15
- package/src/lib/skills/handler.ts +31 -0
- package/src/lib/skills/index.ts +5 -1
- package/src/lib/skills/register.ts +20 -0
- package/src/lib/skills/tool.ts +47 -0
- package/src/lib/state/index.ts +9 -0
- package/src/lib/{state-manager.ts → state/manager.ts} +10 -147
- package/src/lib/state/types.ts +134 -0
- package/src/lib/subagent/define.ts +71 -0
- package/src/lib/subagent/handler.ts +99 -0
- package/src/lib/subagent/index.ts +13 -0
- package/src/lib/subagent/register.ts +53 -0
- package/src/lib/subagent/tool.ts +80 -0
- package/src/lib/subagent/types.ts +92 -0
- package/src/lib/thread/index.ts +7 -0
- package/src/lib/{thread-manager.ts → thread/manager.ts} +1 -33
- package/src/lib/thread/types.ts +33 -0
- package/src/lib/tool-router/auto-append.ts +55 -0
- package/src/lib/tool-router/index.ts +41 -0
- package/src/lib/tool-router/router.ts +462 -0
- package/src/lib/tool-router/types.ts +478 -0
- package/src/lib/tool-router/with-sandbox.ts +70 -0
- package/src/lib/types.ts +5 -382
- package/src/tools/bash/bash.test.ts +53 -55
- package/src/tools/bash/handler.ts +23 -51
- package/src/tools/edit/handler.ts +67 -81
- package/src/tools/glob/handler.ts +60 -17
- package/src/tools/read-file/handler.ts +67 -0
- package/src/tools/read-skill/handler.ts +1 -31
- package/src/tools/read-skill/tool.ts +5 -47
- package/src/tools/subagent/handler.ts +1 -100
- package/src/tools/subagent/tool.ts +5 -93
- package/src/tools/task-create/handler.ts +1 -1
- package/src/tools/task-get/handler.ts +1 -1
- package/src/tools/task-list/handler.ts +1 -1
- package/src/tools/task-update/handler.ts +1 -1
- package/src/tools/write-file/handler.ts +47 -0
- package/src/workflow.ts +88 -47
- package/tsup.config.ts +8 -1
- package/dist/adapters/langchain/index.cjs.map +0 -1
- package/dist/adapters/langchain/index.js.map +0 -1
- package/dist/model-invoker-y_zlyMqu.d.cts +0 -892
- package/dist/model-invoker-y_zlyMqu.d.ts +0 -892
- package/src/lib/tool-router.ts +0 -977
- package/src/lib/workflow-helpers.ts +0 -50
- /package/src/lib/{thread-id.ts → thread/id.ts} +0 -0
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Temporal solves these problems for workflows. Zeitlich brings these guarantees t
|
|
|
35
35
|
|
|
36
36
|
Zeitlich's core is framework-agnostic — it defines generic interfaces (`ModelInvoker`, `ThreadOps`, `MessageContent`) that work with any LLM SDK. Concrete implementations are provided via adapter packages.
|
|
37
37
|
|
|
38
|
-
### LangChain Adapter (`zeitlich/adapters/langchain`)
|
|
38
|
+
### LangChain Adapter (`zeitlich/adapters/thread/langchain`)
|
|
39
39
|
|
|
40
40
|
The built-in LangChain adapter gives you:
|
|
41
41
|
|
|
@@ -45,7 +45,7 @@ The built-in LangChain adapter gives you:
|
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
47
|
import { ChatAnthropic } from "@langchain/anthropic";
|
|
48
|
-
import { createLangChainAdapter } from "zeitlich/adapters/langchain";
|
|
48
|
+
import { createLangChainAdapter } from "zeitlich/adapters/thread/langchain";
|
|
49
49
|
import { createRunAgentActivity } from "zeitlich";
|
|
50
50
|
|
|
51
51
|
const adapter = createLangChainAdapter({
|
|
@@ -78,7 +78,7 @@ npm install zeitlich ioredis
|
|
|
78
78
|
**Peer dependencies:**
|
|
79
79
|
|
|
80
80
|
- `ioredis` >= 5.0.0
|
|
81
|
-
- `@langchain/core` >= 1.0.0 (optional — only needed when using `zeitlich/adapters/langchain`)
|
|
81
|
+
- `@langchain/core` >= 1.0.0 (optional — only needed when using `zeitlich/adapters/thread/langchain`)
|
|
82
82
|
|
|
83
83
|
**Required infrastructure:**
|
|
84
84
|
|
|
@@ -104,20 +104,22 @@ import {
|
|
|
104
104
|
// In activity files and worker setup — framework-agnostic core
|
|
105
105
|
import {
|
|
106
106
|
createRunAgentActivity,
|
|
107
|
-
|
|
107
|
+
withParentWorkflowState,
|
|
108
|
+
withSandbox,
|
|
109
|
+
bashHandler,
|
|
108
110
|
createAskUserQuestionHandler,
|
|
109
111
|
toTree,
|
|
110
112
|
} from "zeitlich";
|
|
111
113
|
|
|
112
114
|
// LangChain adapter — unified adapter for LLM invocation and thread management
|
|
113
|
-
import { createLangChainAdapter } from "zeitlich/adapters/langchain";
|
|
115
|
+
import { createLangChainAdapter } from "zeitlich/adapters/thread/langchain";
|
|
114
116
|
```
|
|
115
117
|
|
|
116
118
|
**Why three entry points?**
|
|
117
119
|
|
|
118
120
|
- `zeitlich/workflow` — Pure TypeScript, safe for Temporal's V8 sandbox
|
|
119
121
|
- `zeitlich` — Activity-side utilities (Redis, filesystem), framework-agnostic
|
|
120
|
-
- `zeitlich/adapters/langchain` — LangChain-specific adapter (model invocation + thread management)
|
|
122
|
+
- `zeitlich/adapters/thread/langchain` — LangChain-specific adapter (model invocation + thread management)
|
|
121
123
|
|
|
122
124
|
## Examples
|
|
123
125
|
|
|
@@ -223,11 +225,12 @@ import type Redis from "ioredis";
|
|
|
223
225
|
import type { WorkflowClient } from "@temporalio/client";
|
|
224
226
|
import { ChatAnthropic } from "@langchain/anthropic";
|
|
225
227
|
import {
|
|
226
|
-
|
|
228
|
+
withSandbox,
|
|
229
|
+
bashHandler,
|
|
227
230
|
createAskUserQuestionHandler,
|
|
228
231
|
createRunAgentActivity,
|
|
229
232
|
} from "zeitlich";
|
|
230
|
-
import { createLangChainAdapter } from "zeitlich/adapters/langchain";
|
|
233
|
+
import { createLangChainAdapter } from "zeitlich/adapters/thread/langchain";
|
|
231
234
|
|
|
232
235
|
export const createActivities = ({
|
|
233
236
|
redis,
|
|
@@ -251,7 +254,7 @@ export const createActivities = ({
|
|
|
251
254
|
toolResponse: JSON.stringify(await performSearch(args.query)),
|
|
252
255
|
data: null,
|
|
253
256
|
}),
|
|
254
|
-
bashHandlerActivity:
|
|
257
|
+
bashHandlerActivity: withSandbox(sandboxManager, bashHandler),
|
|
255
258
|
askUserQuestionHandlerActivity: createAskUserQuestionHandler(),
|
|
256
259
|
};
|
|
257
260
|
};
|
|
@@ -521,20 +524,24 @@ const session = await createSession({
|
|
|
521
524
|
});
|
|
522
525
|
```
|
|
523
526
|
|
|
524
|
-
For file operations, use the built-in tool
|
|
527
|
+
For file operations, use the built-in tool handlers wrapped with `withSandbox`:
|
|
525
528
|
|
|
526
529
|
```typescript
|
|
527
530
|
import {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
+
SandboxManager,
|
|
532
|
+
withSandbox,
|
|
533
|
+
globHandler,
|
|
534
|
+
editHandler,
|
|
535
|
+
bashHandler,
|
|
531
536
|
} from "zeitlich";
|
|
532
537
|
|
|
538
|
+
const sandboxManager = new SandboxManager(provider);
|
|
539
|
+
|
|
533
540
|
export const createActivities = ({ redis, client }) => ({
|
|
534
|
-
|
|
535
|
-
globHandlerActivity:
|
|
536
|
-
editHandlerActivity:
|
|
537
|
-
bashHandlerActivity:
|
|
541
|
+
...sandboxManager.createActivities(),
|
|
542
|
+
globHandlerActivity: withSandbox(sandboxManager, globHandler),
|
|
543
|
+
editHandlerActivity: withSandbox(sandboxManager, editHandler),
|
|
544
|
+
bashHandlerActivity: withSandbox(sandboxManager, bashHandler),
|
|
538
545
|
});
|
|
539
546
|
```
|
|
540
547
|
|
|
@@ -565,11 +572,12 @@ import {
|
|
|
565
572
|
askUserQuestionTool,
|
|
566
573
|
} from "zeitlich/workflow";
|
|
567
574
|
|
|
568
|
-
// Import
|
|
575
|
+
// Import handlers + wrapper in activities
|
|
569
576
|
import {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
577
|
+
withSandbox,
|
|
578
|
+
editHandler,
|
|
579
|
+
globHandler,
|
|
580
|
+
bashHandler,
|
|
573
581
|
createAskUserQuestionHandler,
|
|
574
582
|
} from "zeitlich";
|
|
575
583
|
```
|
|
@@ -598,18 +606,17 @@ const session = await createSession({
|
|
|
598
606
|
|
|
599
607
|
Safe for use in Temporal workflow files:
|
|
600
608
|
|
|
601
|
-
| Export
|
|
602
|
-
|
|
|
603
|
-
| `createSession`
|
|
604
|
-
| `createAgentStateManager`
|
|
605
|
-
| `createToolRouter`
|
|
606
|
-
| `defineTool`
|
|
607
|
-
| `defineSubagent`
|
|
608
|
-
| `getShortId`
|
|
609
|
-
|
|
|
610
|
-
|
|
|
611
|
-
|
|
|
612
|
-
| Types | `SubagentWorkflow`, `ToolDefinition`, `ToolWithHandler`, `AgentConfig`, `SessionConfig`, etc. |
|
|
609
|
+
| Export | Description |
|
|
610
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
611
|
+
| `createSession` | Creates an agent session with tools, prompts, subagents, and hooks |
|
|
612
|
+
| `createAgentStateManager` | Creates a state manager for workflow state with query/update handlers |
|
|
613
|
+
| `createToolRouter` | Creates a tool router (used internally by session, or for advanced use) |
|
|
614
|
+
| `defineTool` | Identity function for type-safe tool definition with handler and hooks |
|
|
615
|
+
| `defineSubagent` | Identity function for type-safe subagent configuration |
|
|
616
|
+
| `getShortId` | Generate a compact, workflow-deterministic identifier (base-62, 12 chars) |
|
|
617
|
+
| Tool definitions | `askUserQuestionTool`, `globTool`, `grepTool`, `readFileTool`, `writeFileTool`, `editTool`, `bashTool` |
|
|
618
|
+
| Task tools | `taskCreateTool`, `taskGetTool`, `taskListTool`, `taskUpdateTool` for workflow task management |
|
|
619
|
+
| Types | `SubagentWorkflow`, `ToolDefinition`, `ToolWithHandler`, `RouterContext`, `SessionConfig`, etc. |
|
|
613
620
|
|
|
614
621
|
### Activity Entry Point (`zeitlich`)
|
|
615
622
|
|
|
@@ -617,12 +624,14 @@ Framework-agnostic utilities for activities, worker setup, and Node.js code:
|
|
|
617
624
|
|
|
618
625
|
| Export | Description |
|
|
619
626
|
| ------------------------- | --------------------------------------------------------------------------------------------- |
|
|
620
|
-
| `createRunAgentActivity` | Wraps a
|
|
627
|
+
| `createRunAgentActivity` | Wraps a handler into a `RunAgentActivity` with auto-fetched parent workflow state |
|
|
628
|
+
| `withParentWorkflowState` | Wraps a tool handler into an `ActivityToolHandler` with auto-fetched parent workflow state |
|
|
621
629
|
| `createThreadManager` | Generic Redis-backed thread manager factory |
|
|
622
630
|
| `toTree` | Generate file tree string from an `IFileSystem` instance |
|
|
623
|
-
|
|
|
631
|
+
| `withSandbox` | Wraps a handler to auto-resolve sandbox from context (pairs with `withAutoAppend`) |
|
|
632
|
+
| Tool handlers | `bashHandler`, `editHandler`, `globHandler`, `readFileHandler`, `writeFileHandler`, `createAskUserQuestionHandler` |
|
|
624
633
|
|
|
625
|
-
### LangChain Adapter Entry Point (`zeitlich/adapters/langchain`)
|
|
634
|
+
### LangChain Adapter Entry Point (`zeitlich/adapters/thread/langchain`)
|
|
626
635
|
|
|
627
636
|
LangChain-specific implementations:
|
|
628
637
|
|
|
@@ -644,8 +653,10 @@ LangChain-specific implementations:
|
|
|
644
653
|
| `ModelInvokerConfig` | Configuration passed to a model invoker |
|
|
645
654
|
| `ToolDefinition` | Tool definition with name, description, and Zod schema |
|
|
646
655
|
| `ToolWithHandler` | Tool definition combined with its handler |
|
|
656
|
+
| `RouterContext` | Base context every tool handler receives (`threadId`, `toolCallId`, `toolName`, `sandboxId?`) |
|
|
657
|
+
| `Hooks` | Combined session lifecycle + tool execution hooks |
|
|
658
|
+
| `ToolRouterHooks` | Narrowed hook interface for tool execution only (pre/post/failure) |
|
|
647
659
|
| `SubagentConfig` | Configuration for subagent workflows |
|
|
648
|
-
| `SessionLifecycleHooks` | Lifecycle hooks interface |
|
|
649
660
|
| `AgentState` | Generic agent state type |
|
|
650
661
|
|
|
651
662
|
## Architecture
|
|
@@ -671,7 +682,7 @@ LangChain-specific implementations:
|
|
|
671
682
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
672
683
|
│ │ │
|
|
673
684
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
674
|
-
│ │ LLM Adapter (zeitlich/adapters/langchain) │ │
|
|
685
|
+
│ │ LLM Adapter (zeitlich/adapters/thread/langchain) │ │
|
|
675
686
|
│ │ • createLangChainAdapter (thread ops + model invoker) │ │
|
|
676
687
|
│ │ • createLangChainThreadManager (message helpers) │ │
|
|
677
688
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sdk = require('@daytonaio/sdk');
|
|
4
|
+
var common = require('@temporalio/common');
|
|
5
|
+
var path = require('path');
|
|
6
|
+
|
|
7
|
+
// src/adapters/sandbox/daytona/index.ts
|
|
8
|
+
var SandboxNotSupportedError = class extends common.ApplicationFailure {
|
|
9
|
+
constructor(operation) {
|
|
10
|
+
super(
|
|
11
|
+
`Sandbox does not support: ${operation}`,
|
|
12
|
+
"SandboxNotSupportedError",
|
|
13
|
+
true
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var SandboxNotFoundError = class extends common.ApplicationFailure {
|
|
18
|
+
constructor(sandboxId) {
|
|
19
|
+
super(`Sandbox not found: ${sandboxId}`, "SandboxNotFoundError", true);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var DaytonaSandboxFileSystem = class {
|
|
23
|
+
constructor(sandbox) {
|
|
24
|
+
this.sandbox = sandbox;
|
|
25
|
+
}
|
|
26
|
+
async readFile(path) {
|
|
27
|
+
const buf = await this.sandbox.fs.downloadFile(path);
|
|
28
|
+
return buf.toString("utf-8");
|
|
29
|
+
}
|
|
30
|
+
async readFileBuffer(path) {
|
|
31
|
+
const buf = await this.sandbox.fs.downloadFile(path);
|
|
32
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
33
|
+
}
|
|
34
|
+
async writeFile(path, content) {
|
|
35
|
+
const buf = typeof content === "string" ? Buffer.from(content, "utf-8") : Buffer.from(content);
|
|
36
|
+
await this.sandbox.fs.uploadFile(buf, path);
|
|
37
|
+
}
|
|
38
|
+
async appendFile(path, content) {
|
|
39
|
+
let existing;
|
|
40
|
+
try {
|
|
41
|
+
existing = await this.sandbox.fs.downloadFile(path);
|
|
42
|
+
} catch {
|
|
43
|
+
return this.writeFile(path, content);
|
|
44
|
+
}
|
|
45
|
+
const addition = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
46
|
+
const merged = Buffer.concat([existing, Buffer.from(addition)]);
|
|
47
|
+
await this.sandbox.fs.uploadFile(merged, path);
|
|
48
|
+
}
|
|
49
|
+
async exists(path) {
|
|
50
|
+
try {
|
|
51
|
+
await this.sandbox.fs.getFileDetails(path);
|
|
52
|
+
return true;
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async stat(path) {
|
|
58
|
+
const info = await this.sandbox.fs.getFileDetails(path);
|
|
59
|
+
return {
|
|
60
|
+
isFile: !info.isDir,
|
|
61
|
+
isDirectory: info.isDir,
|
|
62
|
+
isSymbolicLink: false,
|
|
63
|
+
size: info.size,
|
|
64
|
+
mtime: new Date(info.modTime)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async mkdir(path, _options) {
|
|
68
|
+
await this.sandbox.fs.createFolder(path, "755");
|
|
69
|
+
}
|
|
70
|
+
async readdir(path) {
|
|
71
|
+
const entries = await this.sandbox.fs.listFiles(path);
|
|
72
|
+
return entries.map((e) => e.name);
|
|
73
|
+
}
|
|
74
|
+
async readdirWithFileTypes(path) {
|
|
75
|
+
const entries = await this.sandbox.fs.listFiles(path);
|
|
76
|
+
return entries.map((e) => ({
|
|
77
|
+
name: e.name,
|
|
78
|
+
isFile: !e.isDir,
|
|
79
|
+
isDirectory: e.isDir,
|
|
80
|
+
isSymbolicLink: false
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
async rm(path, options) {
|
|
84
|
+
try {
|
|
85
|
+
await this.sandbox.fs.deleteFile(path, options?.recursive);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
if (!options?.force) throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async cp(src, dest, options) {
|
|
91
|
+
const info = await this.sandbox.fs.getFileDetails(src);
|
|
92
|
+
if (info.isDir) {
|
|
93
|
+
if (!options?.recursive) {
|
|
94
|
+
throw new Error(`EISDIR: is a directory (use recursive): ${src}`);
|
|
95
|
+
}
|
|
96
|
+
await this.sandbox.process.executeCommand(`cp -r "${src}" "${dest}"`);
|
|
97
|
+
} else {
|
|
98
|
+
await this.sandbox.process.executeCommand(`cp "${src}" "${dest}"`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async mv(src, dest) {
|
|
102
|
+
await this.sandbox.fs.moveFiles(src, dest);
|
|
103
|
+
}
|
|
104
|
+
async readlink(_path) {
|
|
105
|
+
throw new SandboxNotSupportedError("readlink");
|
|
106
|
+
}
|
|
107
|
+
resolvePath(base, path$1) {
|
|
108
|
+
if (path.posix.isAbsolute(path$1)) return path.posix.normalize(path$1);
|
|
109
|
+
return path.posix.resolve(base, path$1);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// src/adapters/sandbox/daytona/index.ts
|
|
114
|
+
var DaytonaSandboxImpl = class {
|
|
115
|
+
constructor(id, sdkSandbox) {
|
|
116
|
+
this.id = id;
|
|
117
|
+
this.sdkSandbox = sdkSandbox;
|
|
118
|
+
this.fs = new DaytonaSandboxFileSystem(sdkSandbox);
|
|
119
|
+
}
|
|
120
|
+
capabilities = {
|
|
121
|
+
filesystem: true,
|
|
122
|
+
execution: true,
|
|
123
|
+
persistence: false
|
|
124
|
+
};
|
|
125
|
+
fs;
|
|
126
|
+
async exec(command, options) {
|
|
127
|
+
const response = await this.sdkSandbox.process.executeCommand(
|
|
128
|
+
command,
|
|
129
|
+
options?.cwd,
|
|
130
|
+
options?.env,
|
|
131
|
+
options?.timeout
|
|
132
|
+
);
|
|
133
|
+
return {
|
|
134
|
+
exitCode: response.exitCode ?? 0,
|
|
135
|
+
stdout: response.result ?? "",
|
|
136
|
+
stderr: ""
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
async destroy() {
|
|
140
|
+
await this.sdkSandbox.delete(60);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var DaytonaSandboxProvider = class {
|
|
144
|
+
id = "daytona";
|
|
145
|
+
capabilities = {
|
|
146
|
+
filesystem: true,
|
|
147
|
+
execution: true,
|
|
148
|
+
persistence: false
|
|
149
|
+
};
|
|
150
|
+
client;
|
|
151
|
+
constructor(config) {
|
|
152
|
+
this.client = new sdk.Daytona(config);
|
|
153
|
+
}
|
|
154
|
+
async create(options) {
|
|
155
|
+
const sdkSandbox = await this.client.create(
|
|
156
|
+
{
|
|
157
|
+
language: options?.language,
|
|
158
|
+
snapshot: options?.snapshot,
|
|
159
|
+
envVars: options?.env,
|
|
160
|
+
labels: options?.labels,
|
|
161
|
+
autoStopInterval: options?.autoStopInterval,
|
|
162
|
+
autoArchiveInterval: options?.autoArchiveInterval,
|
|
163
|
+
autoDeleteInterval: options?.autoDeleteInterval
|
|
164
|
+
},
|
|
165
|
+
{ timeout: options?.timeout ?? 60 }
|
|
166
|
+
);
|
|
167
|
+
const sandbox = new DaytonaSandboxImpl(sdkSandbox.id, sdkSandbox);
|
|
168
|
+
if (options?.initialFiles) {
|
|
169
|
+
for (const [path, content] of Object.entries(options.initialFiles)) {
|
|
170
|
+
await sandbox.fs.writeFile(path, content);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return { sandbox };
|
|
174
|
+
}
|
|
175
|
+
async get(sandboxId) {
|
|
176
|
+
try {
|
|
177
|
+
const sdkSandbox = await this.client.get(sandboxId);
|
|
178
|
+
return new DaytonaSandboxImpl(sdkSandbox.id, sdkSandbox);
|
|
179
|
+
} catch {
|
|
180
|
+
throw new SandboxNotFoundError(sandboxId);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async destroy(sandboxId) {
|
|
184
|
+
try {
|
|
185
|
+
const sdkSandbox = await this.client.get(sandboxId);
|
|
186
|
+
await this.client.delete(sdkSandbox);
|
|
187
|
+
} catch {
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async snapshot(_sandboxId) {
|
|
191
|
+
throw new SandboxNotSupportedError(
|
|
192
|
+
"snapshot (use Daytona's native snapshot API directly)"
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
async restore(_snapshot) {
|
|
196
|
+
throw new SandboxNotSupportedError(
|
|
197
|
+
"restore (use Daytona's native snapshot API directly)"
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
exports.DaytonaSandboxFileSystem = DaytonaSandboxFileSystem;
|
|
203
|
+
exports.DaytonaSandboxProvider = DaytonaSandboxProvider;
|
|
204
|
+
//# sourceMappingURL=index.cjs.map
|
|
205
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/adapters/sandbox/daytona/filesystem.ts","../../../../src/adapters/sandbox/daytona/index.ts"],"names":["ApplicationFailure","path","posix","Daytona"],"mappings":"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","file":"index.cjs","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import type { Sandbox as DaytonaSdkSandbox } from \"@daytonaio/sdk\";\nimport type {\n SandboxFileSystem,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotSupportedError } from \"../../../lib/sandbox/types\";\nimport { posix } from \"node:path\";\n\n/**\n * {@link SandboxFileSystem} backed by a Daytona SDK sandbox.\n *\n * Maps zeitlich's filesystem interface to Daytona's `sandbox.fs` and\n * `sandbox.process` APIs. Operations that have no direct Daytona equivalent\n * (e.g. `appendFile`, `cp`) are composed from primitives.\n */\nexport class DaytonaSandboxFileSystem implements SandboxFileSystem {\n constructor(private sandbox: DaytonaSdkSandbox) {}\n\n async readFile(path: string): Promise<string> {\n const buf = await this.sandbox.fs.downloadFile(path);\n return buf.toString(\"utf-8\");\n }\n\n async readFileBuffer(path: string): Promise<Uint8Array> {\n const buf = await this.sandbox.fs.downloadFile(path);\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n }\n\n async writeFile(path: string, content: string | Uint8Array): Promise<void> {\n const buf =\n typeof content === \"string\"\n ? Buffer.from(content, \"utf-8\")\n : Buffer.from(content);\n await this.sandbox.fs.uploadFile(buf, path);\n }\n\n async appendFile(\n path: string,\n content: string | Uint8Array,\n ): Promise<void> {\n let existing: Buffer;\n try {\n existing = await this.sandbox.fs.downloadFile(path);\n } catch {\n return this.writeFile(path, content);\n }\n\n const addition =\n typeof content === \"string\" ? Buffer.from(content, \"utf-8\") : content;\n const merged = Buffer.concat([existing, Buffer.from(addition)]);\n await this.sandbox.fs.uploadFile(merged, path);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await this.sandbox.fs.getFileDetails(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async stat(path: string): Promise<FileStat> {\n const info = await this.sandbox.fs.getFileDetails(path);\n return {\n isFile: !info.isDir,\n isDirectory: info.isDir,\n isSymbolicLink: false,\n size: info.size,\n mtime: new Date(info.modTime),\n };\n }\n\n async mkdir(\n path: string,\n _options?: { recursive?: boolean },\n ): Promise<void> {\n await this.sandbox.fs.createFolder(path, \"755\");\n }\n\n async readdir(path: string): Promise<string[]> {\n const entries = await this.sandbox.fs.listFiles(path);\n return entries.map((e) => e.name);\n }\n\n async readdirWithFileTypes(path: string): Promise<DirentEntry[]> {\n const entries = await this.sandbox.fs.listFiles(path);\n return entries.map((e) => ({\n name: e.name,\n isFile: !e.isDir,\n isDirectory: e.isDir,\n isSymbolicLink: false,\n }));\n }\n\n async rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean },\n ): Promise<void> {\n try {\n await this.sandbox.fs.deleteFile(path, options?.recursive);\n } catch (err) {\n if (!options?.force) throw err;\n }\n }\n\n async cp(\n src: string,\n dest: string,\n options?: { recursive?: boolean },\n ): Promise<void> {\n const info = await this.sandbox.fs.getFileDetails(src);\n if (info.isDir) {\n if (!options?.recursive) {\n throw new Error(`EISDIR: is a directory (use recursive): ${src}`);\n }\n await this.sandbox.process.executeCommand(`cp -r \"${src}\" \"${dest}\"`);\n } else {\n await this.sandbox.process.executeCommand(`cp \"${src}\" \"${dest}\"`);\n }\n }\n\n async mv(src: string, dest: string): Promise<void> {\n await this.sandbox.fs.moveFiles(src, dest);\n }\n\n async readlink(_path: string): Promise<string> {\n throw new SandboxNotSupportedError(\"readlink\");\n }\n\n resolvePath(base: string, path: string): string {\n if (posix.isAbsolute(path)) return posix.normalize(path);\n return posix.resolve(base, path);\n }\n}\n","import {\n Daytona,\n type Sandbox as DaytonaSdkSandbox,\n} from \"@daytonaio/sdk\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateResult,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n} from \"../../../lib/sandbox/types\";\nimport {\n SandboxNotFoundError,\n SandboxNotSupportedError,\n} from \"../../../lib/sandbox/types\";\nimport { DaytonaSandboxFileSystem } from \"./filesystem\";\nimport type {\n DaytonaSandbox,\n DaytonaSandboxConfig,\n DaytonaSandboxCreateOptions,\n} from \"./types\";\n\n// ============================================================================\n// DaytonaSandbox\n// ============================================================================\n\nclass DaytonaSandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: false,\n };\n\n readonly fs: DaytonaSandboxFileSystem;\n\n constructor(\n readonly id: string,\n private sdkSandbox: DaytonaSdkSandbox,\n ) {\n this.fs = new DaytonaSandboxFileSystem(sdkSandbox);\n }\n\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n const response = await this.sdkSandbox.process.executeCommand(\n command,\n options?.cwd,\n options?.env,\n options?.timeout,\n );\n\n return {\n exitCode: response.exitCode ?? 0,\n stdout: response.result ?? \"\",\n stderr: \"\",\n };\n }\n\n async destroy(): Promise<void> {\n await this.sdkSandbox.delete(60);\n }\n}\n\n// ============================================================================\n// DaytonaSandboxProvider\n// ============================================================================\n\nexport class DaytonaSandboxProvider\n implements SandboxProvider<DaytonaSandboxCreateOptions, DaytonaSandbox>\n{\n readonly id = \"daytona\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: false,\n };\n\n private client: Daytona;\n\n constructor(config?: DaytonaSandboxConfig) {\n this.client = new Daytona(config);\n }\n\n async create(\n options?: DaytonaSandboxCreateOptions,\n ): Promise<SandboxCreateResult> {\n const sdkSandbox = await this.client.create(\n {\n language: options?.language,\n snapshot: options?.snapshot,\n envVars: options?.env,\n labels: options?.labels,\n autoStopInterval: options?.autoStopInterval,\n autoArchiveInterval: options?.autoArchiveInterval,\n autoDeleteInterval: options?.autoDeleteInterval,\n },\n { timeout: options?.timeout ?? 60 },\n );\n\n const sandbox = new DaytonaSandboxImpl(sdkSandbox.id, sdkSandbox);\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n await sandbox.fs.writeFile(path, content);\n }\n }\n\n return { sandbox };\n }\n\n async get(sandboxId: string): Promise<DaytonaSandbox> {\n try {\n const sdkSandbox = await this.client.get(sandboxId);\n return new DaytonaSandboxImpl(sdkSandbox.id, sdkSandbox);\n } catch {\n throw new SandboxNotFoundError(sandboxId);\n }\n }\n\n async destroy(sandboxId: string): Promise<void> {\n try {\n const sdkSandbox = await this.client.get(sandboxId);\n await this.client.delete(sdkSandbox);\n } catch {\n // Already gone\n }\n }\n\n async snapshot(_sandboxId: string): Promise<SandboxSnapshot> {\n throw new SandboxNotSupportedError(\n \"snapshot (use Daytona's native snapshot API directly)\",\n );\n }\n\n async restore(_snapshot: SandboxSnapshot): Promise<never> {\n throw new SandboxNotSupportedError(\n \"restore (use Daytona's native snapshot API directly)\",\n );\n }\n}\n\n// Re-exports\nexport { DaytonaSandboxFileSystem } from \"./filesystem\";\nexport type {\n DaytonaSandbox,\n DaytonaSandboxConfig,\n DaytonaSandboxCreateOptions,\n} from \"./types\";\n"]}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox$1, d as SandboxCreateOptions, b as SandboxProvider, c as SandboxCapabilities, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-CDubRtad.cjs';
|
|
2
|
+
import { Sandbox } from '@daytonaio/sdk';
|
|
3
|
+
import '@temporalio/common';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* {@link SandboxFileSystem} backed by a Daytona SDK sandbox.
|
|
7
|
+
*
|
|
8
|
+
* Maps zeitlich's filesystem interface to Daytona's `sandbox.fs` and
|
|
9
|
+
* `sandbox.process` APIs. Operations that have no direct Daytona equivalent
|
|
10
|
+
* (e.g. `appendFile`, `cp`) are composed from primitives.
|
|
11
|
+
*/
|
|
12
|
+
declare class DaytonaSandboxFileSystem implements SandboxFileSystem {
|
|
13
|
+
private sandbox;
|
|
14
|
+
constructor(sandbox: Sandbox);
|
|
15
|
+
readFile(path: string): Promise<string>;
|
|
16
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
17
|
+
writeFile(path: string, content: string | Uint8Array): Promise<void>;
|
|
18
|
+
appendFile(path: string, content: string | Uint8Array): Promise<void>;
|
|
19
|
+
exists(path: string): Promise<boolean>;
|
|
20
|
+
stat(path: string): Promise<FileStat>;
|
|
21
|
+
mkdir(path: string, _options?: {
|
|
22
|
+
recursive?: boolean;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
readdir(path: string): Promise<string[]>;
|
|
25
|
+
readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
|
|
26
|
+
rm(path: string, options?: {
|
|
27
|
+
recursive?: boolean;
|
|
28
|
+
force?: boolean;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
cp(src: string, dest: string, options?: {
|
|
31
|
+
recursive?: boolean;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
mv(src: string, dest: string): Promise<void>;
|
|
34
|
+
readlink(_path: string): Promise<string>;
|
|
35
|
+
resolvePath(base: string, path: string): string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A Daytona-backed {@link Sandbox} with its typed filesystem.
|
|
40
|
+
*/
|
|
41
|
+
type DaytonaSandbox = Sandbox$1 & {
|
|
42
|
+
fs: DaytonaSandboxFileSystem;
|
|
43
|
+
};
|
|
44
|
+
interface DaytonaSandboxConfig {
|
|
45
|
+
apiKey?: string;
|
|
46
|
+
apiUrl?: string;
|
|
47
|
+
target?: string;
|
|
48
|
+
}
|
|
49
|
+
interface DaytonaSandboxCreateOptions extends SandboxCreateOptions {
|
|
50
|
+
/** Programming language runtime. Defaults to "python". */
|
|
51
|
+
language?: string;
|
|
52
|
+
/** Daytona snapshot name to create the sandbox from. */
|
|
53
|
+
snapshot?: string;
|
|
54
|
+
/** Custom Docker image to use. */
|
|
55
|
+
image?: string;
|
|
56
|
+
/** Resource allocation. */
|
|
57
|
+
resources?: {
|
|
58
|
+
cpu?: number;
|
|
59
|
+
memory?: number;
|
|
60
|
+
disk?: number;
|
|
61
|
+
};
|
|
62
|
+
/** Auto-stop interval in minutes (0 = disabled). Default 15. */
|
|
63
|
+
autoStopInterval?: number;
|
|
64
|
+
/** Auto-archive interval in minutes (0 = max interval). Default 7 days. */
|
|
65
|
+
autoArchiveInterval?: number;
|
|
66
|
+
/** Auto-delete interval in minutes (negative = disabled). */
|
|
67
|
+
autoDeleteInterval?: number;
|
|
68
|
+
/** Custom labels for the sandbox. */
|
|
69
|
+
labels?: Record<string, string>;
|
|
70
|
+
/** Timeout in seconds for sandbox creation. Default 60. */
|
|
71
|
+
timeout?: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
declare class DaytonaSandboxProvider implements SandboxProvider<DaytonaSandboxCreateOptions, DaytonaSandbox> {
|
|
75
|
+
readonly id = "daytona";
|
|
76
|
+
readonly capabilities: SandboxCapabilities;
|
|
77
|
+
private client;
|
|
78
|
+
constructor(config?: DaytonaSandboxConfig);
|
|
79
|
+
create(options?: DaytonaSandboxCreateOptions): Promise<SandboxCreateResult>;
|
|
80
|
+
get(sandboxId: string): Promise<DaytonaSandbox>;
|
|
81
|
+
destroy(sandboxId: string): Promise<void>;
|
|
82
|
+
snapshot(_sandboxId: string): Promise<SandboxSnapshot>;
|
|
83
|
+
restore(_snapshot: SandboxSnapshot): Promise<never>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { type DaytonaSandbox, type DaytonaSandboxConfig, type DaytonaSandboxCreateOptions, DaytonaSandboxFileSystem, DaytonaSandboxProvider };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, S as Sandbox$1, d as SandboxCreateOptions, b as SandboxProvider, c as SandboxCapabilities, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-CDubRtad.js';
|
|
2
|
+
import { Sandbox } from '@daytonaio/sdk';
|
|
3
|
+
import '@temporalio/common';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* {@link SandboxFileSystem} backed by a Daytona SDK sandbox.
|
|
7
|
+
*
|
|
8
|
+
* Maps zeitlich's filesystem interface to Daytona's `sandbox.fs` and
|
|
9
|
+
* `sandbox.process` APIs. Operations that have no direct Daytona equivalent
|
|
10
|
+
* (e.g. `appendFile`, `cp`) are composed from primitives.
|
|
11
|
+
*/
|
|
12
|
+
declare class DaytonaSandboxFileSystem implements SandboxFileSystem {
|
|
13
|
+
private sandbox;
|
|
14
|
+
constructor(sandbox: Sandbox);
|
|
15
|
+
readFile(path: string): Promise<string>;
|
|
16
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
17
|
+
writeFile(path: string, content: string | Uint8Array): Promise<void>;
|
|
18
|
+
appendFile(path: string, content: string | Uint8Array): Promise<void>;
|
|
19
|
+
exists(path: string): Promise<boolean>;
|
|
20
|
+
stat(path: string): Promise<FileStat>;
|
|
21
|
+
mkdir(path: string, _options?: {
|
|
22
|
+
recursive?: boolean;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
readdir(path: string): Promise<string[]>;
|
|
25
|
+
readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
|
|
26
|
+
rm(path: string, options?: {
|
|
27
|
+
recursive?: boolean;
|
|
28
|
+
force?: boolean;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
cp(src: string, dest: string, options?: {
|
|
31
|
+
recursive?: boolean;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
mv(src: string, dest: string): Promise<void>;
|
|
34
|
+
readlink(_path: string): Promise<string>;
|
|
35
|
+
resolvePath(base: string, path: string): string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A Daytona-backed {@link Sandbox} with its typed filesystem.
|
|
40
|
+
*/
|
|
41
|
+
type DaytonaSandbox = Sandbox$1 & {
|
|
42
|
+
fs: DaytonaSandboxFileSystem;
|
|
43
|
+
};
|
|
44
|
+
interface DaytonaSandboxConfig {
|
|
45
|
+
apiKey?: string;
|
|
46
|
+
apiUrl?: string;
|
|
47
|
+
target?: string;
|
|
48
|
+
}
|
|
49
|
+
interface DaytonaSandboxCreateOptions extends SandboxCreateOptions {
|
|
50
|
+
/** Programming language runtime. Defaults to "python". */
|
|
51
|
+
language?: string;
|
|
52
|
+
/** Daytona snapshot name to create the sandbox from. */
|
|
53
|
+
snapshot?: string;
|
|
54
|
+
/** Custom Docker image to use. */
|
|
55
|
+
image?: string;
|
|
56
|
+
/** Resource allocation. */
|
|
57
|
+
resources?: {
|
|
58
|
+
cpu?: number;
|
|
59
|
+
memory?: number;
|
|
60
|
+
disk?: number;
|
|
61
|
+
};
|
|
62
|
+
/** Auto-stop interval in minutes (0 = disabled). Default 15. */
|
|
63
|
+
autoStopInterval?: number;
|
|
64
|
+
/** Auto-archive interval in minutes (0 = max interval). Default 7 days. */
|
|
65
|
+
autoArchiveInterval?: number;
|
|
66
|
+
/** Auto-delete interval in minutes (negative = disabled). */
|
|
67
|
+
autoDeleteInterval?: number;
|
|
68
|
+
/** Custom labels for the sandbox. */
|
|
69
|
+
labels?: Record<string, string>;
|
|
70
|
+
/** Timeout in seconds for sandbox creation. Default 60. */
|
|
71
|
+
timeout?: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
declare class DaytonaSandboxProvider implements SandboxProvider<DaytonaSandboxCreateOptions, DaytonaSandbox> {
|
|
75
|
+
readonly id = "daytona";
|
|
76
|
+
readonly capabilities: SandboxCapabilities;
|
|
77
|
+
private client;
|
|
78
|
+
constructor(config?: DaytonaSandboxConfig);
|
|
79
|
+
create(options?: DaytonaSandboxCreateOptions): Promise<SandboxCreateResult>;
|
|
80
|
+
get(sandboxId: string): Promise<DaytonaSandbox>;
|
|
81
|
+
destroy(sandboxId: string): Promise<void>;
|
|
82
|
+
snapshot(_sandboxId: string): Promise<SandboxSnapshot>;
|
|
83
|
+
restore(_snapshot: SandboxSnapshot): Promise<never>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { type DaytonaSandbox, type DaytonaSandboxConfig, type DaytonaSandboxCreateOptions, DaytonaSandboxFileSystem, DaytonaSandboxProvider };
|