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.
- package/README.md +44 -8
- package/dist/adapters/sandbox/bedrock/index.cjs +427 -0
- package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -0
- package/dist/adapters/sandbox/bedrock/index.d.cts +23 -0
- package/dist/adapters/sandbox/bedrock/index.d.ts +23 -0
- package/dist/adapters/sandbox/bedrock/index.js +424 -0
- package/dist/adapters/sandbox/bedrock/index.js.map +1 -0
- package/dist/adapters/sandbox/bedrock/workflow.cjs +33 -0
- package/dist/adapters/sandbox/bedrock/workflow.cjs.map +1 -0
- package/dist/adapters/sandbox/bedrock/workflow.d.cts +29 -0
- package/dist/adapters/sandbox/bedrock/workflow.d.ts +29 -0
- package/dist/adapters/sandbox/bedrock/workflow.js +31 -0
- package/dist/adapters/sandbox/bedrock/workflow.js.map +1 -0
- package/dist/adapters/sandbox/virtual/index.cjs +12 -2
- package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
- package/dist/adapters/sandbox/virtual/index.d.cts +4 -4
- package/dist/adapters/sandbox/virtual/index.d.ts +4 -4
- package/dist/adapters/sandbox/virtual/index.js +12 -2
- package/dist/adapters/sandbox/virtual/index.js.map +1 -1
- package/dist/adapters/sandbox/virtual/workflow.d.cts +2 -2
- package/dist/adapters/sandbox/virtual/workflow.d.ts +2 -2
- package/dist/adapters/thread/google-genai/index.d.cts +2 -2
- package/dist/adapters/thread/google-genai/index.d.ts +2 -2
- package/dist/adapters/thread/google-genai/workflow.d.cts +2 -2
- package/dist/adapters/thread/google-genai/workflow.d.ts +2 -2
- package/dist/adapters/thread/langchain/index.d.cts +2 -2
- package/dist/adapters/thread/langchain/index.d.ts +2 -2
- package/dist/adapters/thread/langchain/workflow.d.cts +2 -2
- package/dist/adapters/thread/langchain/workflow.d.ts +2 -2
- package/dist/index.cjs +199 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -10
- package/dist/index.d.ts +63 -10
- package/dist/index.js +200 -19
- package/dist/index.js.map +1 -1
- package/dist/{queries-DModcWRy.d.cts → queries-BYGBImeC.d.cts} +1 -1
- package/dist/{queries-byD0jr1Y.d.ts → queries-DwBe2CAA.d.ts} +1 -1
- package/dist/{types-DQW8l7pY.d.cts → types-7PeMi1bD.d.cts} +9 -2
- package/dist/{types-BuXdFhaZ.d.cts → types-Bf8KV0Ci.d.cts} +1 -1
- package/dist/{types-Bll19FZJ.d.ts → types-D_igp10o.d.cts} +4 -0
- package/dist/{types-Bll19FZJ.d.cts → types-D_igp10o.d.ts} +4 -0
- package/dist/types-DhTCEMhr.d.cts +64 -0
- package/dist/{types-GZ76HZSj.d.ts → types-LVKmCNds.d.ts} +1 -1
- package/dist/types-d9NznUqd.d.ts +64 -0
- package/dist/{types-B50pBPEV.d.ts → types-hmferhc2.d.ts} +9 -2
- package/dist/workflow.cjs +70 -9
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +12 -7
- package/dist/workflow.d.ts +12 -7
- package/dist/workflow.js +70 -9
- package/dist/workflow.js.map +1 -1
- package/package.json +26 -1
- package/src/adapters/sandbox/bedrock/filesystem.ts +313 -0
- package/src/adapters/sandbox/bedrock/index.ts +259 -0
- package/src/adapters/sandbox/bedrock/proxy.ts +56 -0
- package/src/adapters/sandbox/bedrock/types.ts +24 -0
- package/src/adapters/sandbox/virtual/filesystem.ts +5 -3
- package/src/adapters/sandbox/virtual/provider.ts +9 -0
- package/src/adapters/sandbox/virtual/virtual-sandbox.test.ts +26 -0
- package/src/index.ts +2 -1
- package/src/lib/lifecycle.ts +1 -1
- package/src/lib/sandbox/node-fs.ts +115 -0
- package/src/lib/session/session.integration.test.ts +97 -0
- package/src/lib/session/session.ts +33 -2
- package/src/lib/session/types.ts +1 -1
- package/src/lib/skills/fs-provider.ts +65 -4
- package/src/lib/skills/handler.ts +43 -1
- package/src/lib/skills/index.ts +0 -1
- package/src/lib/skills/register.ts +17 -1
- package/src/lib/skills/skills.integration.test.ts +308 -24
- package/src/lib/skills/types.ts +6 -0
- package/src/lib/subagent/handler.ts +5 -1
- package/src/lib/tool-router/router.ts +6 -3
- package/src/lib/tool-router/types.ts +4 -0
- package/tsup.config.ts +3 -0
package/README.md
CHANGED
|
@@ -61,6 +61,7 @@ A sandbox adapter provides filesystem access for tools like `Bash`, `Read`, `Wri
|
|
|
61
61
|
| Virtual | `zeitlich/adapters/sandbox/virtual` | Custom resolvers with path-only ops |
|
|
62
62
|
| Daytona | `zeitlich/adapters/sandbox/daytona` | Remote Daytona workspaces |
|
|
63
63
|
| E2B | `zeitlich/adapters/sandbox/e2b` | E2B cloud sandboxes |
|
|
64
|
+
| Bedrock | `zeitlich/adapters/sandbox/bedrock` | AWS Bedrock AgentCore Code Interpreter |
|
|
64
65
|
|
|
65
66
|
### Example: LangChain Adapter
|
|
66
67
|
|
|
@@ -95,6 +96,7 @@ npm install zeitlich ioredis
|
|
|
95
96
|
- `ioredis` >= 5.0.0
|
|
96
97
|
- `@langchain/core` >= 1.0.0 (optional — only when using the LangChain adapter)
|
|
97
98
|
- `@google/genai` >= 1.0.0 (optional — only when using the Google GenAI adapter)
|
|
99
|
+
- `@aws-sdk/client-bedrock-agentcore` >= 3.900.0 (optional — only when using the Bedrock adapter)
|
|
98
100
|
|
|
99
101
|
**Required infrastructure:**
|
|
100
102
|
|
|
@@ -483,14 +485,18 @@ Zeitlich has first-class support for the [agentskills.io](https://agentskills.io
|
|
|
483
485
|
|
|
484
486
|
#### Defining a Skill
|
|
485
487
|
|
|
486
|
-
Each skill lives in its own directory as a `SKILL.md` file with YAML frontmatter:
|
|
488
|
+
Each skill lives in its own directory as a `SKILL.md` file with YAML frontmatter. A skill directory can also contain **resource files** — supporting documents, templates, or data that the agent can read from the sandbox filesystem:
|
|
487
489
|
|
|
488
490
|
```
|
|
489
491
|
skills/
|
|
490
492
|
├── code-review/
|
|
491
|
-
│
|
|
493
|
+
│ ├── SKILL.md
|
|
494
|
+
│ └── resources/
|
|
495
|
+
│ └── checklist.md
|
|
492
496
|
├── pdf-processing/
|
|
493
|
-
│
|
|
497
|
+
│ ├── SKILL.md
|
|
498
|
+
│ └── templates/
|
|
499
|
+
│ └── extraction-prompt.txt
|
|
494
500
|
```
|
|
495
501
|
|
|
496
502
|
```markdown
|
|
@@ -506,14 +512,17 @@ license: MIT
|
|
|
506
512
|
When reviewing code, follow these steps:
|
|
507
513
|
1. Read the diff with `Bash`
|
|
508
514
|
2. Search for related tests with `Grep`
|
|
509
|
-
3.
|
|
515
|
+
3. Read the checklist from `resources/checklist.md`
|
|
516
|
+
4. ...
|
|
510
517
|
```
|
|
511
518
|
|
|
512
519
|
Required fields: `name` and `description`. Optional: `license`, `compatibility`, `allowed-tools` (space-delimited), `metadata` (key-value map).
|
|
513
520
|
|
|
521
|
+
Resource files are any non-`SKILL.md` files inside the skill directory (discovered recursively). When loaded via `FileSystemSkillProvider`, their contents are stored in `skill.resourceContents` — a `Record<string, string>` keyed by relative path (e.g. `"resources/checklist.md"`).
|
|
522
|
+
|
|
514
523
|
#### Loading Skills
|
|
515
524
|
|
|
516
|
-
Use `FileSystemSkillProvider` to load skills from a directory
|
|
525
|
+
Use `FileSystemSkillProvider` to load skills from a directory. It accepts any `SandboxFileSystem` implementation. `loadAll()` eagerly reads `SKILL.md` instructions **and** all resource file contents into each `Skill` object:
|
|
517
526
|
|
|
518
527
|
```typescript
|
|
519
528
|
import { FileSystemSkillProvider } from "zeitlich";
|
|
@@ -524,6 +533,28 @@ const { sandbox } = await provider.create({});
|
|
|
524
533
|
|
|
525
534
|
const skillProvider = new FileSystemSkillProvider(sandbox.fs, "/skills");
|
|
526
535
|
const skills = await skillProvider.loadAll();
|
|
536
|
+
// Each skill has: { name, description, instructions, resourceContents }
|
|
537
|
+
// resourceContents: { "resources/checklist.md": "...", ... }
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
**Loading from the local filesystem (activity-side):** Use `NodeFsSandboxFileSystem` to read skills from the worker's disk. This is the simplest option when skill files are bundled alongside your application code:
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
import { NodeFsSandboxFileSystem, FileSystemSkillProvider } from "zeitlich";
|
|
544
|
+
import { fileURLToPath } from "node:url";
|
|
545
|
+
import { dirname, join } from "node:path";
|
|
546
|
+
|
|
547
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
548
|
+
const fs = new NodeFsSandboxFileSystem(join(__dirname, "skills"));
|
|
549
|
+
const skillProvider = new FileSystemSkillProvider(fs, "/");
|
|
550
|
+
const skills = await skillProvider.loadAll();
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
For lightweight discovery without reading file contents, use `listSkills()`:
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
const metadata = await skillProvider.listSkills();
|
|
557
|
+
// SkillMetadata[] — name, description, location only
|
|
527
558
|
```
|
|
528
559
|
|
|
529
560
|
Or parse a single file directly:
|
|
@@ -537,7 +568,10 @@ const { frontmatter, body } = parseSkillFile(rawMarkdown);
|
|
|
537
568
|
|
|
538
569
|
#### Passing Skills to a Session
|
|
539
570
|
|
|
540
|
-
Pass loaded skills to `createSession`. Zeitlich automatically
|
|
571
|
+
Pass loaded skills to `createSession`. Zeitlich automatically:
|
|
572
|
+
|
|
573
|
+
1. Registers a `ReadSkill` tool whose description lists all available skills — the agent discovers them through the tool definition and loads instructions on demand.
|
|
574
|
+
2. Seeds `resourceContents` into the sandbox as `initialFiles` (when `sandboxOps` is configured), so the agent can read resource files with its `Read` tool without any extra setup.
|
|
541
575
|
|
|
542
576
|
```typescript
|
|
543
577
|
import { createSession } from "zeitlich/workflow";
|
|
@@ -548,7 +582,7 @@ const session = await createSession({
|
|
|
548
582
|
});
|
|
549
583
|
```
|
|
550
584
|
|
|
551
|
-
The `ReadSkill` tool accepts a `skill_name` parameter (constrained to an enum of available names) and returns the full instruction body. The handler runs directly in the workflow — no activity needed.
|
|
585
|
+
The `ReadSkill` tool accepts a `skill_name` parameter (constrained to an enum of available names) and returns the full instruction body plus a list of available resource file paths. The handler runs directly in the workflow — no activity needed. Resource file contents are not included in the `ReadSkill` response (progressive disclosure); the agent reads them from the sandbox filesystem on demand.
|
|
552
586
|
|
|
553
587
|
#### Building Skills Manually
|
|
554
588
|
|
|
@@ -867,6 +901,7 @@ Framework-agnostic utilities for activities, worker setup, and Node.js code:
|
|
|
867
901
|
| `createThreadManager` | Generic Redis-backed thread manager factory |
|
|
868
902
|
| `toTree` | Generate file tree string from an `IFileSystem` instance |
|
|
869
903
|
| `withSandbox` | Wraps a handler to auto-resolve sandbox from context (pairs with `withAutoAppend`) |
|
|
904
|
+
| `NodeFsSandboxFileSystem` | `node:fs` adapter for `SandboxFileSystem` — read skills from the worker's local disk |
|
|
870
905
|
| `FileSystemSkillProvider` | Load skills from a directory following the agentskills.io layout |
|
|
871
906
|
| Tool handlers | `bashHandler`, `editHandler`, `globHandler`, `readFileHandler`, `writeFileHandler`, `createAskUserQuestionHandler` |
|
|
872
907
|
|
|
@@ -926,6 +961,7 @@ Framework-agnostic utilities for activities, worker setup, and Node.js code:
|
|
|
926
961
|
│ │ │ • Turns │ │ • Tool routing & hooks │ │ │
|
|
927
962
|
│ │ │ • Custom state │ │ • Prompts (system, context) │ │ │
|
|
928
963
|
│ │ └────────────────┘ │ • Subagent coordination │ │ │
|
|
964
|
+
│ │ │ • Skills (progressive load) │ │ │
|
|
929
965
|
│ │ └───────────────────────────────┘ │ │
|
|
930
966
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
931
967
|
│ │ │
|
|
@@ -942,7 +978,7 @@ Framework-agnostic utilities for activities, worker setup, and Node.js code:
|
|
|
942
978
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
943
979
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
944
980
|
│ │ Sandbox Adapter (zeitlich/adapters/sandbox/*) │ │
|
|
945
|
-
│ │ • In-memory, Virtual, Daytona, E2B, or custom
|
|
981
|
+
│ │ • In-memory, Virtual, Daytona, E2B, Bedrock, or custom │ │
|
|
946
982
|
│ │ • Filesystem ops for agent tools │ │
|
|
947
983
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
948
984
|
└─────────────────────────────────────────────────────────────────┘
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var clientBedrockAgentcore = require('@aws-sdk/client-bedrock-agentcore');
|
|
4
|
+
var common = require('@temporalio/common');
|
|
5
|
+
var path = require('path');
|
|
6
|
+
|
|
7
|
+
// src/adapters/sandbox/bedrock/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
|
+
async function consumeStream(stream) {
|
|
23
|
+
for await (const event of stream) {
|
|
24
|
+
if ("result" in event && event.result) return event.result;
|
|
25
|
+
if ("accessDeniedException" in event && event.accessDeniedException)
|
|
26
|
+
throw new Error(event.accessDeniedException.message ?? "Access denied");
|
|
27
|
+
if ("resourceNotFoundException" in event && event.resourceNotFoundException)
|
|
28
|
+
throw new Error(
|
|
29
|
+
event.resourceNotFoundException.message ?? "Resource not found"
|
|
30
|
+
);
|
|
31
|
+
if ("validationException" in event && event.validationException)
|
|
32
|
+
throw new Error(
|
|
33
|
+
event.validationException.message ?? "Validation error"
|
|
34
|
+
);
|
|
35
|
+
if ("internalServerException" in event && event.internalServerException)
|
|
36
|
+
throw new Error(
|
|
37
|
+
event.internalServerException.message ?? "Internal server error"
|
|
38
|
+
);
|
|
39
|
+
if ("throttlingException" in event && event.throttlingException)
|
|
40
|
+
throw new Error(event.throttlingException.message ?? "Throttled");
|
|
41
|
+
if ("serviceQuotaExceededException" in event && event.serviceQuotaExceededException)
|
|
42
|
+
throw new Error(
|
|
43
|
+
event.serviceQuotaExceededException.message ?? "Quota exceeded"
|
|
44
|
+
);
|
|
45
|
+
if ("conflictException" in event && event.conflictException)
|
|
46
|
+
throw new Error(event.conflictException.message ?? "Conflict");
|
|
47
|
+
}
|
|
48
|
+
throw new Error("No result received from code interpreter stream");
|
|
49
|
+
}
|
|
50
|
+
var BedrockSandboxFileSystem = class {
|
|
51
|
+
constructor(client, codeInterpreterIdentifier, sessionId, workspaceBase = "/home/user") {
|
|
52
|
+
this.client = client;
|
|
53
|
+
this.codeInterpreterIdentifier = codeInterpreterIdentifier;
|
|
54
|
+
this.sessionId = sessionId;
|
|
55
|
+
this.workspaceBase = path.posix.resolve("/", workspaceBase);
|
|
56
|
+
}
|
|
57
|
+
workspaceBase;
|
|
58
|
+
normalisePath(path$1) {
|
|
59
|
+
return path.posix.resolve(this.workspaceBase, path$1);
|
|
60
|
+
}
|
|
61
|
+
async invoke(name, args) {
|
|
62
|
+
const resp = await this.client.send(
|
|
63
|
+
new clientBedrockAgentcore.InvokeCodeInterpreterCommand({
|
|
64
|
+
codeInterpreterIdentifier: this.codeInterpreterIdentifier,
|
|
65
|
+
sessionId: this.sessionId,
|
|
66
|
+
name,
|
|
67
|
+
arguments: args
|
|
68
|
+
})
|
|
69
|
+
);
|
|
70
|
+
if (!resp.stream) throw new Error("No stream in code interpreter response");
|
|
71
|
+
return consumeStream(resp.stream);
|
|
72
|
+
}
|
|
73
|
+
async execShell(command) {
|
|
74
|
+
const result = await this.invoke("executeCommand", {
|
|
75
|
+
command
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
stdout: result.structuredContent?.stdout ?? "",
|
|
79
|
+
stderr: result.structuredContent?.stderr ?? "",
|
|
80
|
+
exitCode: result.structuredContent?.exitCode ?? 0
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async readFile(path) {
|
|
84
|
+
const norm = this.normalisePath(path);
|
|
85
|
+
const result = await this.invoke("readFiles", {
|
|
86
|
+
paths: [norm]
|
|
87
|
+
});
|
|
88
|
+
for (const block of result.content ?? []) {
|
|
89
|
+
if (block.resource?.text != null) return block.resource.text;
|
|
90
|
+
if (block.text != null) return block.text;
|
|
91
|
+
}
|
|
92
|
+
return "";
|
|
93
|
+
}
|
|
94
|
+
async readFileBuffer(path) {
|
|
95
|
+
const norm = this.normalisePath(path);
|
|
96
|
+
const result = await this.invoke("readFiles", {
|
|
97
|
+
paths: [norm]
|
|
98
|
+
});
|
|
99
|
+
for (const block of result.content ?? []) {
|
|
100
|
+
if (block.resource?.blob) return block.resource.blob;
|
|
101
|
+
if (block.data) return block.data;
|
|
102
|
+
if (block.resource?.text != null)
|
|
103
|
+
return new TextEncoder().encode(block.resource.text);
|
|
104
|
+
if (block.text != null) return new TextEncoder().encode(block.text);
|
|
105
|
+
}
|
|
106
|
+
return new Uint8Array(0);
|
|
107
|
+
}
|
|
108
|
+
async writeFile(path, content) {
|
|
109
|
+
const norm = this.normalisePath(path);
|
|
110
|
+
const isText = typeof content === "string";
|
|
111
|
+
const result = await this.invoke("writeFiles", {
|
|
112
|
+
content: [
|
|
113
|
+
{
|
|
114
|
+
path: norm,
|
|
115
|
+
...isText ? { text: content } : { blob: content }
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
});
|
|
119
|
+
if (result.isError) {
|
|
120
|
+
const msg = result.content?.map((b) => b.text).join("") ?? "writeFile failed";
|
|
121
|
+
throw new Error(msg);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async appendFile(path, content) {
|
|
125
|
+
const norm = this.normalisePath(path);
|
|
126
|
+
const addition = typeof content === "string" ? content : new TextDecoder().decode(content);
|
|
127
|
+
const escaped = addition.replace(/'/g, "'\\''");
|
|
128
|
+
const { exitCode, stderr } = await this.execShell(
|
|
129
|
+
`printf '%s' '${escaped}' >> "${norm}"`
|
|
130
|
+
);
|
|
131
|
+
if (exitCode !== 0) throw new Error(`appendFile failed: ${stderr}`);
|
|
132
|
+
}
|
|
133
|
+
async exists(path) {
|
|
134
|
+
const norm = this.normalisePath(path);
|
|
135
|
+
const { exitCode } = await this.execShell(`test -e "${norm}"`);
|
|
136
|
+
return exitCode === 0;
|
|
137
|
+
}
|
|
138
|
+
async stat(path) {
|
|
139
|
+
const norm = this.normalisePath(path);
|
|
140
|
+
const { stdout, exitCode, stderr } = await this.execShell(
|
|
141
|
+
`stat -c '%F %s %Y' "${norm}" 2>&1`
|
|
142
|
+
);
|
|
143
|
+
if (exitCode !== 0) throw new Error(`stat failed: ${stderr || stdout}`);
|
|
144
|
+
const parts = stdout.trim().split(" ");
|
|
145
|
+
const fileType = parts.slice(0, -2).join(" ");
|
|
146
|
+
const sizeStr = parts[parts.length - 2] ?? "0";
|
|
147
|
+
const mtimeStr = parts[parts.length - 1] ?? "0";
|
|
148
|
+
const size = parseInt(sizeStr, 10);
|
|
149
|
+
const mtimeEpoch = parseInt(mtimeStr, 10);
|
|
150
|
+
return {
|
|
151
|
+
isFile: fileType === "regular file" || fileType === "regular empty file",
|
|
152
|
+
isDirectory: fileType === "directory",
|
|
153
|
+
isSymbolicLink: fileType === "symbolic link",
|
|
154
|
+
size: isNaN(size) ? 0 : size,
|
|
155
|
+
mtime: new Date(isNaN(mtimeEpoch) ? 0 : mtimeEpoch * 1e3)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async mkdir(path, options) {
|
|
159
|
+
const norm = this.normalisePath(path);
|
|
160
|
+
const flag = options?.recursive ? "-p " : "";
|
|
161
|
+
const { exitCode, stderr } = await this.execShell(
|
|
162
|
+
`mkdir ${flag}"${norm}"`
|
|
163
|
+
);
|
|
164
|
+
if (exitCode !== 0) throw new Error(`mkdir failed: ${stderr}`);
|
|
165
|
+
}
|
|
166
|
+
async readdir(path) {
|
|
167
|
+
const norm = this.normalisePath(path);
|
|
168
|
+
const result = await this.invoke("listFiles", {
|
|
169
|
+
directoryPath: norm
|
|
170
|
+
});
|
|
171
|
+
const names = [];
|
|
172
|
+
for (const block of result.content ?? []) {
|
|
173
|
+
if (block.name) names.push(block.name);
|
|
174
|
+
}
|
|
175
|
+
if (names.length > 0) return names;
|
|
176
|
+
const { stdout, exitCode, stderr } = await this.execShell(
|
|
177
|
+
`ls -1A "${norm}"`
|
|
178
|
+
);
|
|
179
|
+
if (exitCode !== 0) throw new Error(`readdir failed: ${stderr}`);
|
|
180
|
+
return stdout.trim().split("\n").filter((l) => l.length > 0);
|
|
181
|
+
}
|
|
182
|
+
async readdirWithFileTypes(path) {
|
|
183
|
+
const norm = this.normalisePath(path);
|
|
184
|
+
const { stdout, exitCode, stderr } = await this.execShell(
|
|
185
|
+
`find "${norm}" -maxdepth 1 -mindepth 1 -printf '%y %f\\n'`
|
|
186
|
+
);
|
|
187
|
+
if (exitCode !== 0)
|
|
188
|
+
throw new Error(`readdirWithFileTypes failed: ${stderr}`);
|
|
189
|
+
return stdout.trim().split("\n").filter((l) => l.length > 0).map((line) => {
|
|
190
|
+
const type = line.charAt(0);
|
|
191
|
+
const name = line.slice(2);
|
|
192
|
+
return {
|
|
193
|
+
name,
|
|
194
|
+
isFile: type === "f",
|
|
195
|
+
isDirectory: type === "d",
|
|
196
|
+
isSymbolicLink: type === "l"
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
async rm(path, options) {
|
|
201
|
+
const norm = this.normalisePath(path);
|
|
202
|
+
if (options?.recursive || options?.force) {
|
|
203
|
+
const flags = `${options?.recursive ? "-r" : ""} ${options?.force ? "-f" : ""}`.trim();
|
|
204
|
+
const { exitCode, stderr } = await this.execShell(
|
|
205
|
+
`rm ${flags} "${norm}"`
|
|
206
|
+
);
|
|
207
|
+
if (exitCode !== 0 && !options?.force)
|
|
208
|
+
throw new Error(`rm failed: ${stderr}`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const result = await this.invoke("removeFiles", {
|
|
212
|
+
paths: [norm]
|
|
213
|
+
});
|
|
214
|
+
if (result.isError) {
|
|
215
|
+
const msg = result.content?.map((b) => b.text).join("") ?? "rm failed";
|
|
216
|
+
throw new Error(msg);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async cp(src, dest, options) {
|
|
220
|
+
const normSrc = this.normalisePath(src);
|
|
221
|
+
const normDest = this.normalisePath(dest);
|
|
222
|
+
const flag = options?.recursive ? "-r " : "";
|
|
223
|
+
const { exitCode, stderr } = await this.execShell(
|
|
224
|
+
`cp ${flag}"${normSrc}" "${normDest}"`
|
|
225
|
+
);
|
|
226
|
+
if (exitCode !== 0) throw new Error(`cp failed: ${stderr}`);
|
|
227
|
+
}
|
|
228
|
+
async mv(src, dest) {
|
|
229
|
+
const normSrc = this.normalisePath(src);
|
|
230
|
+
const normDest = this.normalisePath(dest);
|
|
231
|
+
const { exitCode, stderr } = await this.execShell(
|
|
232
|
+
`mv "${normSrc}" "${normDest}"`
|
|
233
|
+
);
|
|
234
|
+
if (exitCode !== 0) throw new Error(`mv failed: ${stderr}`);
|
|
235
|
+
}
|
|
236
|
+
async readlink(path) {
|
|
237
|
+
const norm = this.normalisePath(path);
|
|
238
|
+
const { stdout, exitCode, stderr } = await this.execShell(
|
|
239
|
+
`readlink "${norm}"`
|
|
240
|
+
);
|
|
241
|
+
if (exitCode !== 0)
|
|
242
|
+
throw new SandboxNotSupportedError(`readlink: ${stderr}`);
|
|
243
|
+
return stdout.trim();
|
|
244
|
+
}
|
|
245
|
+
resolvePath(base, path$1) {
|
|
246
|
+
return path.posix.resolve(this.normalisePath(base), path$1);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// src/adapters/sandbox/bedrock/index.ts
|
|
251
|
+
async function consumeExecStream(stream) {
|
|
252
|
+
for await (const event of stream) {
|
|
253
|
+
if ("result" in event && event.result) {
|
|
254
|
+
const sc = event.result.structuredContent;
|
|
255
|
+
return {
|
|
256
|
+
exitCode: sc?.exitCode ?? 0,
|
|
257
|
+
stdout: sc?.stdout ?? "",
|
|
258
|
+
stderr: sc?.stderr ?? ""
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
if ("accessDeniedException" in event && event.accessDeniedException)
|
|
262
|
+
throw new Error(event.accessDeniedException.message ?? "Access denied");
|
|
263
|
+
if ("resourceNotFoundException" in event && event.resourceNotFoundException)
|
|
264
|
+
throw new Error(
|
|
265
|
+
event.resourceNotFoundException.message ?? "Resource not found"
|
|
266
|
+
);
|
|
267
|
+
if ("validationException" in event && event.validationException)
|
|
268
|
+
throw new Error(
|
|
269
|
+
event.validationException.message ?? "Validation error"
|
|
270
|
+
);
|
|
271
|
+
if ("internalServerException" in event && event.internalServerException)
|
|
272
|
+
throw new Error(
|
|
273
|
+
event.internalServerException.message ?? "Internal server error"
|
|
274
|
+
);
|
|
275
|
+
if ("throttlingException" in event && event.throttlingException)
|
|
276
|
+
throw new Error(event.throttlingException.message ?? "Throttled");
|
|
277
|
+
if ("serviceQuotaExceededException" in event && event.serviceQuotaExceededException)
|
|
278
|
+
throw new Error(
|
|
279
|
+
event.serviceQuotaExceededException.message ?? "Quota exceeded"
|
|
280
|
+
);
|
|
281
|
+
if ("conflictException" in event && event.conflictException)
|
|
282
|
+
throw new Error(event.conflictException.message ?? "Conflict");
|
|
283
|
+
}
|
|
284
|
+
return { exitCode: 0, stdout: "", stderr: "" };
|
|
285
|
+
}
|
|
286
|
+
var BedrockSandboxImpl = class {
|
|
287
|
+
constructor(id, client, codeInterpreterIdentifier, sessionId, workspaceBase = "/home/user") {
|
|
288
|
+
this.id = id;
|
|
289
|
+
this.client = client;
|
|
290
|
+
this.codeInterpreterIdentifier = codeInterpreterIdentifier;
|
|
291
|
+
this.sessionId = sessionId;
|
|
292
|
+
this.fs = new BedrockSandboxFileSystem(
|
|
293
|
+
client,
|
|
294
|
+
codeInterpreterIdentifier,
|
|
295
|
+
sessionId,
|
|
296
|
+
workspaceBase
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
capabilities = {
|
|
300
|
+
filesystem: true,
|
|
301
|
+
execution: true,
|
|
302
|
+
persistence: false
|
|
303
|
+
};
|
|
304
|
+
fs;
|
|
305
|
+
async exec(command, options) {
|
|
306
|
+
let cmd = command;
|
|
307
|
+
if (options?.cwd) cmd = `cd "${options.cwd}" && ${cmd}`;
|
|
308
|
+
if (options?.env) {
|
|
309
|
+
const exports$1 = Object.entries(options.env).map(([k, v]) => `export ${k}="${v.replace(/"/g, '\\"')}"`).join(" && ");
|
|
310
|
+
cmd = `${exports$1} && ${cmd}`;
|
|
311
|
+
}
|
|
312
|
+
const resp = await this.client.send(
|
|
313
|
+
new clientBedrockAgentcore.InvokeCodeInterpreterCommand({
|
|
314
|
+
codeInterpreterIdentifier: this.codeInterpreterIdentifier,
|
|
315
|
+
sessionId: this.sessionId,
|
|
316
|
+
name: "executeCommand",
|
|
317
|
+
arguments: { command: cmd }
|
|
318
|
+
})
|
|
319
|
+
);
|
|
320
|
+
if (!resp.stream)
|
|
321
|
+
throw new Error("No stream in code interpreter response");
|
|
322
|
+
return consumeExecStream(resp.stream);
|
|
323
|
+
}
|
|
324
|
+
async destroy() {
|
|
325
|
+
await this.client.send(
|
|
326
|
+
new clientBedrockAgentcore.StopCodeInterpreterSessionCommand({
|
|
327
|
+
codeInterpreterIdentifier: this.codeInterpreterIdentifier,
|
|
328
|
+
sessionId: this.sessionId
|
|
329
|
+
})
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
var BedrockSandboxProvider = class {
|
|
334
|
+
id = "bedrock";
|
|
335
|
+
capabilities = {
|
|
336
|
+
filesystem: true,
|
|
337
|
+
execution: true,
|
|
338
|
+
persistence: false
|
|
339
|
+
};
|
|
340
|
+
client;
|
|
341
|
+
codeInterpreterIdentifier;
|
|
342
|
+
defaultWorkspaceBase;
|
|
343
|
+
constructor(config) {
|
|
344
|
+
this.client = new clientBedrockAgentcore.BedrockAgentCoreClient(config.clientConfig ?? {});
|
|
345
|
+
this.codeInterpreterIdentifier = config.codeInterpreterIdentifier;
|
|
346
|
+
this.defaultWorkspaceBase = config.workspaceBase ?? "/home/user";
|
|
347
|
+
}
|
|
348
|
+
async create(options) {
|
|
349
|
+
const resp = await this.client.send(
|
|
350
|
+
new clientBedrockAgentcore.StartCodeInterpreterSessionCommand({
|
|
351
|
+
codeInterpreterIdentifier: this.codeInterpreterIdentifier,
|
|
352
|
+
name: options?.name,
|
|
353
|
+
sessionTimeoutSeconds: options?.sessionTimeoutSeconds
|
|
354
|
+
})
|
|
355
|
+
);
|
|
356
|
+
const sessionId = resp.sessionId ?? "";
|
|
357
|
+
if (!sessionId) throw new Error("No sessionId returned from Bedrock");
|
|
358
|
+
const sandbox = new BedrockSandboxImpl(
|
|
359
|
+
sessionId,
|
|
360
|
+
this.client,
|
|
361
|
+
this.codeInterpreterIdentifier,
|
|
362
|
+
sessionId,
|
|
363
|
+
this.defaultWorkspaceBase
|
|
364
|
+
);
|
|
365
|
+
if (options?.initialFiles) {
|
|
366
|
+
for (const [path, content] of Object.entries(options.initialFiles)) {
|
|
367
|
+
await sandbox.fs.writeFile(path, content);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (options?.env) {
|
|
371
|
+
const exports$1 = Object.entries(options.env).map(([k, v]) => `${k}="${v.replace(/"/g, '\\"')}"`).join(" ");
|
|
372
|
+
await sandbox.exec(`echo '${exports$1}' >> ~/.bashrc`);
|
|
373
|
+
}
|
|
374
|
+
return { sandbox };
|
|
375
|
+
}
|
|
376
|
+
async get(sandboxId) {
|
|
377
|
+
try {
|
|
378
|
+
const resp = await this.client.send(
|
|
379
|
+
new clientBedrockAgentcore.GetCodeInterpreterSessionCommand({
|
|
380
|
+
codeInterpreterIdentifier: this.codeInterpreterIdentifier,
|
|
381
|
+
sessionId: sandboxId
|
|
382
|
+
})
|
|
383
|
+
);
|
|
384
|
+
if (resp.status === "TERMINATED") {
|
|
385
|
+
throw new SandboxNotFoundError(sandboxId);
|
|
386
|
+
}
|
|
387
|
+
return new BedrockSandboxImpl(
|
|
388
|
+
sandboxId,
|
|
389
|
+
this.client,
|
|
390
|
+
this.codeInterpreterIdentifier,
|
|
391
|
+
sandboxId,
|
|
392
|
+
this.defaultWorkspaceBase
|
|
393
|
+
);
|
|
394
|
+
} catch (err) {
|
|
395
|
+
if (err instanceof SandboxNotFoundError) throw err;
|
|
396
|
+
throw new SandboxNotFoundError(sandboxId);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
async destroy(sandboxId) {
|
|
400
|
+
try {
|
|
401
|
+
await this.client.send(
|
|
402
|
+
new clientBedrockAgentcore.StopCodeInterpreterSessionCommand({
|
|
403
|
+
codeInterpreterIdentifier: this.codeInterpreterIdentifier,
|
|
404
|
+
sessionId: sandboxId
|
|
405
|
+
})
|
|
406
|
+
);
|
|
407
|
+
} catch {
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
async pause(_sandboxId, _ttlSeconds) {
|
|
411
|
+
throw new SandboxNotSupportedError("pause");
|
|
412
|
+
}
|
|
413
|
+
async snapshot(_sandboxId) {
|
|
414
|
+
throw new SandboxNotSupportedError("snapshot");
|
|
415
|
+
}
|
|
416
|
+
async restore(_snapshot) {
|
|
417
|
+
throw new SandboxNotSupportedError("restore");
|
|
418
|
+
}
|
|
419
|
+
async fork(_sandboxId) {
|
|
420
|
+
throw new SandboxNotSupportedError("fork");
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
exports.BedrockSandboxFileSystem = BedrockSandboxFileSystem;
|
|
425
|
+
exports.BedrockSandboxProvider = BedrockSandboxProvider;
|
|
426
|
+
//# sourceMappingURL=index.cjs.map
|
|
427
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/adapters/sandbox/bedrock/filesystem.ts","../../../../src/adapters/sandbox/bedrock/index.ts"],"names":["ApplicationFailure","posix","path","InvokeCodeInterpreterCommand","exports","StopCodeInterpreterSessionCommand","BedrockAgentCoreClient","StartCodeInterpreterSessionCommand","GetCodeInterpreterSessionCommand"],"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 /** Base directory used when resolving relative paths. */\n readonly workspaceBase: string;\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(\n path: string,\n options?: { recursive?: boolean; force?: boolean }\n ): Promise<void>;\n cp(\n src: string,\n dest: string,\n options?: { recursive?: boolean }\n ): 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 pause(sandboxId: string, ttlSeconds?: number): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n fork(sandboxId: string): 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 pauseSandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n forkSandbox(sandboxId: string): Promise<string>;\n}\n\n/**\n * Maps generic {@link SandboxOps} method names to adapter-prefixed names.\n *\n * @example\n * ```typescript\n * type InMemOps = PrefixedSandboxOps<\"inMemory\">;\n * // → { inMemoryCreateSandbox, inMemoryDestroySandbox, inMemorySnapshotSandbox }\n * ```\n */\nexport type PrefixedSandboxOps<\n TPrefix extends string,\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> = {\n [K in keyof SandboxOps<TOptions> as `${TPrefix}${Capitalize<K & string>}`]: SandboxOps<TOptions>[K];\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 {\n BedrockAgentCoreClient,\n CodeInterpreterStreamOutput,\n CodeInterpreterResult,\n ToolName as ToolNameType,\n ToolArguments,\n} from \"@aws-sdk/client-bedrock-agentcore\";\nimport { InvokeCodeInterpreterCommand } from \"@aws-sdk/client-bedrock-agentcore\";\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\nasync function consumeStream(\n stream: AsyncIterable<CodeInterpreterStreamOutput>\n): Promise<CodeInterpreterResult> {\n for await (const event of stream) {\n if (\"result\" in event && event.result) return event.result;\n if (\"accessDeniedException\" in event && event.accessDeniedException)\n throw new Error(event.accessDeniedException.message ?? \"Access denied\");\n if (\"resourceNotFoundException\" in event && event.resourceNotFoundException)\n throw new Error(\n event.resourceNotFoundException.message ?? \"Resource not found\"\n );\n if (\"validationException\" in event && event.validationException)\n throw new Error(\n event.validationException.message ?? \"Validation error\"\n );\n if (\"internalServerException\" in event && event.internalServerException)\n throw new Error(\n event.internalServerException.message ?? \"Internal server error\"\n );\n if (\"throttlingException\" in event && event.throttlingException)\n throw new Error(event.throttlingException.message ?? \"Throttled\");\n if (\n \"serviceQuotaExceededException\" in event &&\n event.serviceQuotaExceededException\n )\n throw new Error(\n event.serviceQuotaExceededException.message ?? \"Quota exceeded\"\n );\n if (\"conflictException\" in event && event.conflictException)\n throw new Error(event.conflictException.message ?? \"Conflict\");\n }\n throw new Error(\"No result received from code interpreter stream\");\n}\n\n/**\n * {@link SandboxFileSystem} backed by AWS Bedrock AgentCore Code Interpreter.\n *\n * Maps zeitlich's filesystem interface to Code Interpreter's\n * `readFiles` / `writeFiles` / `listFiles` / `removeFiles` / `executeCommand`\n * tool invocations.\n */\nexport class BedrockSandboxFileSystem implements SandboxFileSystem {\n readonly workspaceBase: string;\n\n constructor(\n private client: BedrockAgentCoreClient,\n private codeInterpreterIdentifier: string,\n private sessionId: string,\n workspaceBase = \"/home/user\"\n ) {\n this.workspaceBase = posix.resolve(\"/\", workspaceBase);\n }\n\n private normalisePath(path: string): string {\n return posix.resolve(this.workspaceBase, path);\n }\n\n private async invoke(\n name: ToolNameType,\n args: ToolArguments\n ): Promise<CodeInterpreterResult> {\n const resp = await this.client.send(\n new InvokeCodeInterpreterCommand({\n codeInterpreterIdentifier: this.codeInterpreterIdentifier,\n sessionId: this.sessionId,\n name,\n arguments: args,\n })\n );\n if (!resp.stream) throw new Error(\"No stream in code interpreter response\");\n return consumeStream(resp.stream);\n }\n\n private async execShell(command: string): Promise<{\n stdout: string;\n stderr: string;\n exitCode: number;\n }> {\n const result = await this.invoke(\"executeCommand\" as ToolNameType, {\n command,\n });\n return {\n stdout: result.structuredContent?.stdout ?? \"\",\n stderr: result.structuredContent?.stderr ?? \"\",\n exitCode: result.structuredContent?.exitCode ?? 0,\n };\n }\n\n async readFile(path: string): Promise<string> {\n const norm = this.normalisePath(path);\n const result = await this.invoke(\"readFiles\" as ToolNameType, {\n paths: [norm],\n });\n\n for (const block of result.content ?? []) {\n if (block.resource?.text != null) return block.resource.text;\n if (block.text != null) return block.text;\n }\n return \"\";\n }\n\n async readFileBuffer(path: string): Promise<Uint8Array> {\n const norm = this.normalisePath(path);\n const result = await this.invoke(\"readFiles\" as ToolNameType, {\n paths: [norm],\n });\n\n for (const block of result.content ?? []) {\n if (block.resource?.blob) return block.resource.blob;\n if (block.data) return block.data;\n if (block.resource?.text != null)\n return new TextEncoder().encode(block.resource.text);\n if (block.text != null) return new TextEncoder().encode(block.text);\n }\n return new Uint8Array(0);\n }\n\n async writeFile(path: string, content: string | Uint8Array): Promise<void> {\n const norm = this.normalisePath(path);\n const isText = typeof content === \"string\";\n const result = await this.invoke(\"writeFiles\" as ToolNameType, {\n content: [\n {\n path: norm,\n ...(isText\n ? { text: content as string }\n : { blob: content as Uint8Array }),\n },\n ],\n });\n if (result.isError) {\n const msg =\n result.content?.map((b) => b.text).join(\"\") ?? \"writeFile failed\";\n throw new Error(msg);\n }\n }\n\n async appendFile(path: string, content: string | Uint8Array): Promise<void> {\n const norm = this.normalisePath(path);\n const addition =\n typeof content === \"string\"\n ? content\n : new TextDecoder().decode(content);\n const escaped = addition.replace(/'/g, \"'\\\\''\");\n const { exitCode, stderr } = await this.execShell(\n `printf '%s' '${escaped}' >> \"${norm}\"`\n );\n if (exitCode !== 0) throw new Error(`appendFile failed: ${stderr}`);\n }\n\n async exists(path: string): Promise<boolean> {\n const norm = this.normalisePath(path);\n const { exitCode } = await this.execShell(`test -e \"${norm}\"`);\n return exitCode === 0;\n }\n\n async stat(path: string): Promise<FileStat> {\n const norm = this.normalisePath(path);\n const { stdout, exitCode, stderr } = await this.execShell(\n `stat -c '%F %s %Y' \"${norm}\" 2>&1`\n );\n if (exitCode !== 0) throw new Error(`stat failed: ${stderr || stdout}`);\n\n const parts = stdout.trim().split(\" \");\n const fileType = parts.slice(0, -2).join(\" \");\n const sizeStr = parts[parts.length - 2] ?? \"0\";\n const mtimeStr = parts[parts.length - 1] ?? \"0\";\n const size = parseInt(sizeStr, 10);\n const mtimeEpoch = parseInt(mtimeStr, 10);\n\n return {\n isFile: fileType === \"regular file\" || fileType === \"regular empty file\",\n isDirectory: fileType === \"directory\",\n isSymbolicLink: fileType === \"symbolic link\",\n size: isNaN(size) ? 0 : size,\n mtime: new Date(isNaN(mtimeEpoch) ? 0 : mtimeEpoch * 1000),\n };\n }\n\n async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {\n const norm = this.normalisePath(path);\n const flag = options?.recursive ? \"-p \" : \"\";\n const { exitCode, stderr } = await this.execShell(\n `mkdir ${flag}\"${norm}\"`\n );\n if (exitCode !== 0) throw new Error(`mkdir failed: ${stderr}`);\n }\n\n async readdir(path: string): Promise<string[]> {\n const norm = this.normalisePath(path);\n const result = await this.invoke(\"listFiles\" as ToolNameType, {\n directoryPath: norm,\n });\n\n const names: string[] = [];\n for (const block of result.content ?? []) {\n if (block.name) names.push(block.name);\n }\n\n if (names.length > 0) return names;\n\n const { stdout, exitCode, stderr } = await this.execShell(\n `ls -1A \"${norm}\"`\n );\n if (exitCode !== 0) throw new Error(`readdir failed: ${stderr}`);\n return stdout\n .trim()\n .split(\"\\n\")\n .filter((l) => l.length > 0);\n }\n\n async readdirWithFileTypes(path: string): Promise<DirentEntry[]> {\n const norm = this.normalisePath(path);\n const { stdout, exitCode, stderr } = await this.execShell(\n `find \"${norm}\" -maxdepth 1 -mindepth 1 -printf '%y %f\\\\n'`\n );\n if (exitCode !== 0)\n throw new Error(`readdirWithFileTypes failed: ${stderr}`);\n\n return stdout\n .trim()\n .split(\"\\n\")\n .filter((l) => l.length > 0)\n .map((line) => {\n const type = line.charAt(0);\n const name = line.slice(2);\n return {\n name,\n isFile: type === \"f\",\n isDirectory: type === \"d\",\n isSymbolicLink: type === \"l\",\n };\n });\n }\n\n async rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean }\n ): Promise<void> {\n const norm = this.normalisePath(path);\n if (options?.recursive || options?.force) {\n const flags = `${options?.recursive ? \"-r\" : \"\"} ${options?.force ? \"-f\" : \"\"}`.trim();\n const { exitCode, stderr } = await this.execShell(\n `rm ${flags} \"${norm}\"`\n );\n if (exitCode !== 0 && !options?.force)\n throw new Error(`rm failed: ${stderr}`);\n return;\n }\n\n const result = await this.invoke(\"removeFiles\" as ToolNameType, {\n paths: [norm],\n });\n if (result.isError) {\n const msg =\n result.content?.map((b) => b.text).join(\"\") ?? \"rm failed\";\n throw new Error(msg);\n }\n }\n\n async cp(\n src: string,\n dest: string,\n options?: { recursive?: boolean }\n ): Promise<void> {\n const normSrc = this.normalisePath(src);\n const normDest = this.normalisePath(dest);\n const flag = options?.recursive ? \"-r \" : \"\";\n const { exitCode, stderr } = await this.execShell(\n `cp ${flag}\"${normSrc}\" \"${normDest}\"`\n );\n if (exitCode !== 0) throw new Error(`cp failed: ${stderr}`);\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const normSrc = this.normalisePath(src);\n const normDest = this.normalisePath(dest);\n const { exitCode, stderr } = await this.execShell(\n `mv \"${normSrc}\" \"${normDest}\"`\n );\n if (exitCode !== 0) throw new Error(`mv failed: ${stderr}`);\n }\n\n async readlink(path: string): Promise<string> {\n const norm = this.normalisePath(path);\n const { stdout, exitCode, stderr } = await this.execShell(\n `readlink \"${norm}\"`\n );\n if (exitCode !== 0)\n throw new SandboxNotSupportedError(`readlink: ${stderr}`);\n return stdout.trim();\n }\n\n resolvePath(base: string, path: string): string {\n return posix.resolve(this.normalisePath(base), path);\n }\n}\n","import {\n BedrockAgentCoreClient,\n StartCodeInterpreterSessionCommand,\n GetCodeInterpreterSessionCommand,\n StopCodeInterpreterSessionCommand,\n InvokeCodeInterpreterCommand,\n} from \"@aws-sdk/client-bedrock-agentcore\";\nimport type { CodeInterpreterStreamOutput } from \"@aws-sdk/client-bedrock-agentcore\";\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 { BedrockSandboxFileSystem } from \"./filesystem\";\nimport type {\n BedrockSandbox,\n BedrockSandboxConfig,\n BedrockSandboxCreateOptions,\n} from \"./types\";\n\n// ============================================================================\n// Stream helpers\n// ============================================================================\n\nasync function consumeExecStream(\n stream: AsyncIterable<CodeInterpreterStreamOutput>\n): Promise<ExecResult> {\n for await (const event of stream) {\n if (\"result\" in event && event.result) {\n const sc = event.result.structuredContent;\n return {\n exitCode: sc?.exitCode ?? 0,\n stdout: sc?.stdout ?? \"\",\n stderr: sc?.stderr ?? \"\",\n };\n }\n if (\"accessDeniedException\" in event && event.accessDeniedException)\n throw new Error(event.accessDeniedException.message ?? \"Access denied\");\n if (\"resourceNotFoundException\" in event && event.resourceNotFoundException)\n throw new Error(\n event.resourceNotFoundException.message ?? \"Resource not found\"\n );\n if (\"validationException\" in event && event.validationException)\n throw new Error(\n event.validationException.message ?? \"Validation error\"\n );\n if (\"internalServerException\" in event && event.internalServerException)\n throw new Error(\n event.internalServerException.message ?? \"Internal server error\"\n );\n if (\"throttlingException\" in event && event.throttlingException)\n throw new Error(event.throttlingException.message ?? \"Throttled\");\n if (\n \"serviceQuotaExceededException\" in event &&\n event.serviceQuotaExceededException\n )\n throw new Error(\n event.serviceQuotaExceededException.message ?? \"Quota exceeded\"\n );\n if (\"conflictException\" in event && event.conflictException)\n throw new Error(event.conflictException.message ?? \"Conflict\");\n }\n return { exitCode: 0, stdout: \"\", stderr: \"\" };\n}\n\n// ============================================================================\n// BedrockSandboxImpl\n// ============================================================================\n\nclass BedrockSandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: false,\n };\n\n readonly fs: BedrockSandboxFileSystem;\n\n constructor(\n readonly id: string,\n private client: BedrockAgentCoreClient,\n private codeInterpreterIdentifier: string,\n private sessionId: string,\n workspaceBase = \"/home/user\"\n ) {\n this.fs = new BedrockSandboxFileSystem(\n client,\n codeInterpreterIdentifier,\n sessionId,\n workspaceBase\n );\n }\n\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n let cmd = command;\n if (options?.cwd) cmd = `cd \"${options.cwd}\" && ${cmd}`;\n if (options?.env) {\n const exports = Object.entries(options.env)\n .map(([k, v]) => `export ${k}=\"${v.replace(/\"/g, '\\\\\"')}\"`)\n .join(\" && \");\n cmd = `${exports} && ${cmd}`;\n }\n\n const resp = await this.client.send(\n new InvokeCodeInterpreterCommand({\n codeInterpreterIdentifier: this.codeInterpreterIdentifier,\n sessionId: this.sessionId,\n name: \"executeCommand\",\n arguments: { command: cmd },\n })\n );\n\n if (!resp.stream)\n throw new Error(\"No stream in code interpreter response\");\n return consumeExecStream(resp.stream);\n }\n\n async destroy(): Promise<void> {\n await this.client.send(\n new StopCodeInterpreterSessionCommand({\n codeInterpreterIdentifier: this.codeInterpreterIdentifier,\n sessionId: this.sessionId,\n })\n );\n }\n}\n\n// ============================================================================\n// BedrockSandboxProvider\n// ============================================================================\n\nexport class BedrockSandboxProvider\n implements SandboxProvider<BedrockSandboxCreateOptions, BedrockSandbox>\n{\n readonly id = \"bedrock\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: false,\n };\n\n private client: BedrockAgentCoreClient;\n private readonly codeInterpreterIdentifier: string;\n private readonly defaultWorkspaceBase: string;\n\n constructor(config: BedrockSandboxConfig) {\n this.client = new BedrockAgentCoreClient(config.clientConfig ?? {});\n this.codeInterpreterIdentifier = config.codeInterpreterIdentifier;\n this.defaultWorkspaceBase = config.workspaceBase ?? \"/home/user\";\n }\n\n async create(\n options?: BedrockSandboxCreateOptions\n ): Promise<SandboxCreateResult> {\n const resp = await this.client.send(\n new StartCodeInterpreterSessionCommand({\n codeInterpreterIdentifier: this.codeInterpreterIdentifier,\n name: options?.name,\n sessionTimeoutSeconds: options?.sessionTimeoutSeconds,\n })\n );\n\n const sessionId = resp.sessionId ?? \"\";\n if (!sessionId) throw new Error(\"No sessionId returned from Bedrock\");\n const sandbox = new BedrockSandboxImpl(\n sessionId,\n this.client,\n this.codeInterpreterIdentifier,\n sessionId,\n this.defaultWorkspaceBase\n );\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 if (options?.env) {\n const exports = Object.entries(options.env)\n .map(([k, v]) => `${k}=\"${v.replace(/\"/g, '\\\\\"')}\"`)\n .join(\" \");\n await sandbox.exec(`echo '${exports}' >> ~/.bashrc`);\n }\n\n return { sandbox };\n }\n\n async get(sandboxId: string): Promise<BedrockSandbox> {\n try {\n const resp = await this.client.send(\n new GetCodeInterpreterSessionCommand({\n codeInterpreterIdentifier: this.codeInterpreterIdentifier,\n sessionId: sandboxId,\n })\n );\n\n if (resp.status === \"TERMINATED\") {\n throw new SandboxNotFoundError(sandboxId);\n }\n\n return new BedrockSandboxImpl(\n sandboxId,\n this.client,\n this.codeInterpreterIdentifier,\n sandboxId,\n this.defaultWorkspaceBase\n );\n } catch (err) {\n if (err instanceof SandboxNotFoundError) throw err;\n throw new SandboxNotFoundError(sandboxId);\n }\n }\n\n async destroy(sandboxId: string): Promise<void> {\n try {\n await this.client.send(\n new StopCodeInterpreterSessionCommand({\n codeInterpreterIdentifier: this.codeInterpreterIdentifier,\n sessionId: sandboxId,\n })\n );\n } catch {\n // Already stopped or not found\n }\n }\n\n async pause(_sandboxId: string, _ttlSeconds?: number): Promise<void> {\n throw new SandboxNotSupportedError(\"pause\");\n }\n\n async snapshot(_sandboxId: string): Promise<SandboxSnapshot> {\n throw new SandboxNotSupportedError(\"snapshot\");\n }\n\n async restore(_snapshot: SandboxSnapshot): Promise<never> {\n throw new SandboxNotSupportedError(\"restore\");\n }\n\n async fork(_sandboxId: string): Promise<Sandbox> {\n throw new SandboxNotSupportedError(\"fork\");\n }\n}\n\n// Re-exports\nexport { BedrockSandboxFileSystem } from \"./filesystem\";\nexport type {\n BedrockSandbox,\n BedrockSandboxConfig,\n BedrockSandboxCreateOptions,\n} from \"./types\";\n"]}
|