cloudflare-openhands-sdk 0.1.0
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/Dockerfile +19 -0
- package/README.md +134 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +312 -0
- package/dist/index.js.map +13 -0
- package/dist/openhands/index.d.ts +3 -0
- package/dist/openhands/index.d.ts.map +1 -0
- package/dist/openhands/index.js +178 -0
- package/dist/openhands/index.js.map +12 -0
- package/dist/openhands/openhands.d.ts +64 -0
- package/dist/openhands/openhands.d.ts.map +1 -0
- package/dist/openhands/types.d.ts +50 -0
- package/dist/openhands/types.d.ts.map +1 -0
- package/dist/routes/handler.d.ts +51 -0
- package/dist/routes/handler.d.ts.map +1 -0
- package/dist/routes/handler.js +302 -0
- package/dist/routes/handler.js.map +13 -0
- package/dist/utils/agent-server.d.ts +30 -0
- package/dist/utils/agent-server.d.ts.map +1 -0
- package/dist/utils/agent-server.js +52 -0
- package/dist/utils/agent-server.js.map +10 -0
- package/package.json +55 -0
package/Dockerfile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
FROM docker.io/cloudflare/sandbox:0.6.7
|
|
2
|
+
|
|
3
|
+
# Install build tools
|
|
4
|
+
RUN apt-get update && \
|
|
5
|
+
apt-get install -y make build-essential && \
|
|
6
|
+
rm -rf /var/lib/apt/lists/*
|
|
7
|
+
|
|
8
|
+
# Install uv and add to PATH
|
|
9
|
+
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
10
|
+
ENV PATH="/root/.local/bin:$PATH"
|
|
11
|
+
|
|
12
|
+
# Clone the repository and build
|
|
13
|
+
RUN git clone https://github.com/OpenHands/software-agent-sdk.git && \
|
|
14
|
+
cd software-agent-sdk && \
|
|
15
|
+
make build
|
|
16
|
+
|
|
17
|
+
# Required during local development to access exposed ports
|
|
18
|
+
EXPOSE 8080
|
|
19
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Cloudflare OpenHands SDK
|
|
2
|
+
|
|
3
|
+
SDK for integrating OpenHands agent-server with Cloudflare Workers Sandbox.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install cloudflare-openhands-sdk
|
|
9
|
+
# or
|
|
10
|
+
pnpm add cloudflare-openhands-sdk
|
|
11
|
+
# or
|
|
12
|
+
bun add cloudflare-openhands-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- `@cloudflare/sandbox` (peer dependency) - Install in your Worker project
|
|
18
|
+
- Cloudflare Workers account with Sandbox support
|
|
19
|
+
- Custom domain (required for preview URLs)
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Configure Wrangler
|
|
24
|
+
|
|
25
|
+
Add the Dockerfile to your `wrangler.jsonc`:
|
|
26
|
+
|
|
27
|
+
```jsonc
|
|
28
|
+
{
|
|
29
|
+
"containers": [
|
|
30
|
+
{
|
|
31
|
+
"class_name": "Sandbox",
|
|
32
|
+
"image": "./node_modules/cloudflare-openhands-sdk/Dockerfile",
|
|
33
|
+
"instance_type": "basic",
|
|
34
|
+
"max_instances": 1
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"durable_objects": {
|
|
38
|
+
"bindings": [
|
|
39
|
+
{
|
|
40
|
+
"class_name": "Sandbox",
|
|
41
|
+
"name": "Sandbox"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"routes": [
|
|
46
|
+
{
|
|
47
|
+
"pattern": "*.yourdomain.com/*",
|
|
48
|
+
"zone_name": "yourdomain.com"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Use the SDK in Your Worker
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { attachOpenhandsRoutes } from 'cloudflare-openhands-sdk/routes';
|
|
58
|
+
|
|
59
|
+
export default attachOpenhandsRoutes(async (request, env) => {
|
|
60
|
+
// Your custom routes here
|
|
61
|
+
return new Response('Not found', { status: 404 });
|
|
62
|
+
}, {
|
|
63
|
+
port: 8001,
|
|
64
|
+
exposePort: true,
|
|
65
|
+
hostname: 'yourdomain.com'
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## API Reference
|
|
70
|
+
|
|
71
|
+
### `createOpenhandsServer(sandbox, options?)`
|
|
72
|
+
|
|
73
|
+
Creates and manages an OpenHands agent-server instance.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { getSandbox } from '@cloudflare/sandbox';
|
|
77
|
+
import { createOpenhandsServer } from 'cloudflare-openhands-sdk/openhands';
|
|
78
|
+
|
|
79
|
+
const sandbox = getSandbox(env.Sandbox, 'my-sandbox');
|
|
80
|
+
const server = await createOpenhandsServer(sandbox, {
|
|
81
|
+
port: 8001,
|
|
82
|
+
exposePort: true,
|
|
83
|
+
hostname: 'yourdomain.com'
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### `proxyToOpenhands(request, sandbox, server)`
|
|
88
|
+
|
|
89
|
+
Proxies requests to the agent-server.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { proxyToOpenhands } from 'cloudflare-openhands-sdk/openhands';
|
|
93
|
+
|
|
94
|
+
return proxyToOpenhands(request, sandbox, server);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### `attachOpenhandsRoutes(fetchHandler, options?)`
|
|
98
|
+
|
|
99
|
+
Attaches OpenHands routes to your Worker handler.
|
|
100
|
+
|
|
101
|
+
**Routes:**
|
|
102
|
+
- `GET /start-openhands` - Start the agent-server
|
|
103
|
+
- `GET /stop-openhands` - Stop the agent-server
|
|
104
|
+
- `GET /openhands-status` - Get server status
|
|
105
|
+
|
|
106
|
+
## Dockerfile
|
|
107
|
+
|
|
108
|
+
The package includes a pre-configured Dockerfile that:
|
|
109
|
+
- Installs build tools (make, build-essential)
|
|
110
|
+
- Installs `uv` package manager
|
|
111
|
+
- Clones and builds the OpenHands software-agent-sdk
|
|
112
|
+
- Sets up the agent-server environment
|
|
113
|
+
|
|
114
|
+
Reference it in your `wrangler.jsonc`:
|
|
115
|
+
```jsonc
|
|
116
|
+
"image": "./node_modules/cloudflare-openhands-sdk/Dockerfile"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Configuration Options
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
interface OpenhandsOptions {
|
|
123
|
+
port?: number; // Default: 8001
|
|
124
|
+
directory?: string; // Default: /container-server/software-agent-sdk
|
|
125
|
+
hostname?: string; // Required if exposePort is true
|
|
126
|
+
exposePort?: boolean; // Default: false
|
|
127
|
+
env?: Record<string, string>; // Environment variables for agent-server
|
|
128
|
+
sandboxName?: string; // Default: 'my-sandbox'
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAG5B,cAAc,kBAAkB,CAAC;AAGjC,cAAc,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
// src/utils/agent-server.ts
|
|
2
|
+
var DEFAULT_AGENT_SERVER_PATH = "/container-server/software-agent-sdk/.venv/bin/agent-server";
|
|
3
|
+
var DEFAULT_AGENT_SERVER_DIR = "/container-server/software-agent-sdk";
|
|
4
|
+
function getDefaultAgentServerPath() {
|
|
5
|
+
return DEFAULT_AGENT_SERVER_PATH;
|
|
6
|
+
}
|
|
7
|
+
function getDefaultAgentServerDir() {
|
|
8
|
+
return DEFAULT_AGENT_SERVER_DIR;
|
|
9
|
+
}
|
|
10
|
+
async function checkAgentServerExists(sandbox, path = DEFAULT_AGENT_SERVER_PATH) {
|
|
11
|
+
try {
|
|
12
|
+
const result = await sandbox.exec(`test -f ${path} && echo "EXISTS" || echo "NOT_FOUND"`);
|
|
13
|
+
return result.stdout.trim() === "EXISTS";
|
|
14
|
+
} catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function findAgentServerPath(sandbox) {
|
|
19
|
+
const locations = [
|
|
20
|
+
DEFAULT_AGENT_SERVER_PATH,
|
|
21
|
+
"/software-agent-sdk/.venv/bin/agent-server",
|
|
22
|
+
"/root/software-agent-sdk/.venv/bin/agent-server"
|
|
23
|
+
];
|
|
24
|
+
for (const location of locations) {
|
|
25
|
+
if (await checkAgentServerExists(sandbox, location)) {
|
|
26
|
+
return location;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const result = await sandbox.exec("which agent-server");
|
|
31
|
+
const path = result.stdout.trim();
|
|
32
|
+
if (path && !path.includes("not found")) {
|
|
33
|
+
return path;
|
|
34
|
+
}
|
|
35
|
+
} catch {}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
function buildAgentServerCommand(port, directory) {
|
|
39
|
+
const command = `${DEFAULT_AGENT_SERVER_PATH} --host 0.0.0.0 --port ${port}`;
|
|
40
|
+
return directory && directory !== DEFAULT_AGENT_SERVER_DIR ? `cd ${directory} && ${command}` : command;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/openhands/types.ts
|
|
44
|
+
class OpenhandsStartupError extends Error {
|
|
45
|
+
code = "OPENHANDS_STARTUP_FAILED";
|
|
46
|
+
context;
|
|
47
|
+
constructor(message, context, options) {
|
|
48
|
+
super(message, options);
|
|
49
|
+
this.name = "OpenhandsStartupError";
|
|
50
|
+
this.context = context;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// src/openhands/openhands.ts
|
|
54
|
+
var DEFAULT_PORT = 8001;
|
|
55
|
+
async function findExistingAgentServer(sandbox, port) {
|
|
56
|
+
const processes = await sandbox.listProcesses();
|
|
57
|
+
const commandPattern = DEFAULT_AGENT_SERVER_PATH;
|
|
58
|
+
for (const proc of processes) {
|
|
59
|
+
if (proc.command.includes(commandPattern)) {
|
|
60
|
+
if (proc.command.includes(`--port ${port}`) || proc.command.includes(`--port=${port}`)) {
|
|
61
|
+
if (proc.status === "starting" || proc.status === "running") {
|
|
62
|
+
return proc;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
async function startAgentServer(sandbox, port, options) {
|
|
70
|
+
const directory = options.directory || DEFAULT_AGENT_SERVER_DIR;
|
|
71
|
+
const command = buildAgentServerCommand(port, directory);
|
|
72
|
+
const process = await sandbox.startProcess(command, {
|
|
73
|
+
cwd: directory,
|
|
74
|
+
env: options.env
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
await process.waitForPort(port, {
|
|
78
|
+
mode: "http",
|
|
79
|
+
path: "/",
|
|
80
|
+
timeout: 60000
|
|
81
|
+
});
|
|
82
|
+
} catch (e) {
|
|
83
|
+
const logs = await process.getLogs();
|
|
84
|
+
throw new OpenhandsStartupError(`agent-server failed to start on port ${port}. Stderr: ${logs.stderr || "(empty)"}`, {
|
|
85
|
+
port,
|
|
86
|
+
stderr: logs.stderr,
|
|
87
|
+
command: process.command,
|
|
88
|
+
processId: process.id
|
|
89
|
+
}, { cause: e });
|
|
90
|
+
}
|
|
91
|
+
return process;
|
|
92
|
+
}
|
|
93
|
+
async function ensureAgentServer(sandbox, port, options) {
|
|
94
|
+
const existingProcess = await findExistingAgentServer(sandbox, port);
|
|
95
|
+
if (existingProcess) {
|
|
96
|
+
if (existingProcess.status === "starting") {
|
|
97
|
+
try {
|
|
98
|
+
await existingProcess.waitForPort(port, {
|
|
99
|
+
mode: "http",
|
|
100
|
+
path: "/",
|
|
101
|
+
timeout: 60000
|
|
102
|
+
});
|
|
103
|
+
} catch (e) {
|
|
104
|
+
const logs = await existingProcess.getLogs();
|
|
105
|
+
throw new OpenhandsStartupError(`agent-server failed to start. Stderr: ${logs.stderr || "(empty)"}`, {
|
|
106
|
+
port,
|
|
107
|
+
stderr: logs.stderr,
|
|
108
|
+
command: existingProcess.command,
|
|
109
|
+
processId: existingProcess.id
|
|
110
|
+
}, { cause: e });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return existingProcess;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
return await startAgentServer(sandbox, port, options);
|
|
117
|
+
} catch (startupError) {
|
|
118
|
+
const retryProcess = await findExistingAgentServer(sandbox, port);
|
|
119
|
+
if (retryProcess) {
|
|
120
|
+
if (retryProcess.status === "starting") {
|
|
121
|
+
try {
|
|
122
|
+
await retryProcess.waitForPort(port, {
|
|
123
|
+
mode: "http",
|
|
124
|
+
path: "/",
|
|
125
|
+
timeout: 60000
|
|
126
|
+
});
|
|
127
|
+
} catch (e) {
|
|
128
|
+
const logs = await retryProcess.getLogs();
|
|
129
|
+
throw new OpenhandsStartupError(`agent-server failed to start. Stderr: ${logs.stderr || "(empty)"}`, {
|
|
130
|
+
port,
|
|
131
|
+
stderr: logs.stderr,
|
|
132
|
+
command: retryProcess.command,
|
|
133
|
+
processId: retryProcess.id
|
|
134
|
+
}, { cause: e });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return retryProcess;
|
|
138
|
+
}
|
|
139
|
+
throw startupError;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async function createOpenhandsServer(sandbox, options = {}) {
|
|
143
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
144
|
+
const process = await ensureAgentServer(sandbox, port, options);
|
|
145
|
+
let previewUrl;
|
|
146
|
+
if (options.exposePort) {
|
|
147
|
+
if (!options.hostname) {
|
|
148
|
+
throw new Error("hostname is required when exposePort is true. Provide hostname in options or extract from request URL.");
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
const exposed = await sandbox.exposePort(port, {
|
|
152
|
+
hostname: options.hostname
|
|
153
|
+
});
|
|
154
|
+
previewUrl = typeof exposed === "string" ? exposed : exposed.url;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.warn("Failed to expose port:", error);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
port,
|
|
161
|
+
url: `http://localhost:${port}`,
|
|
162
|
+
previewUrl,
|
|
163
|
+
processId: process.id,
|
|
164
|
+
async close() {
|
|
165
|
+
await process.kill("SIGTERM");
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function proxyToOpenhands(request, sandbox, server) {
|
|
170
|
+
return sandbox.containerFetch(request, server.port);
|
|
171
|
+
}
|
|
172
|
+
// src/routes/handler.ts
|
|
173
|
+
import { getSandbox, proxyToSandbox } from "@cloudflare/sandbox";
|
|
174
|
+
async function findOpenhandsServer(sandbox, port) {
|
|
175
|
+
const processes = await sandbox.listProcesses();
|
|
176
|
+
for (const process of processes) {
|
|
177
|
+
if (process.command.includes(DEFAULT_AGENT_SERVER_PATH) && (process.command.includes(`--port ${port}`) || process.command.includes(`--port=${port}`)) && (process.status === "running" || process.status === "starting")) {
|
|
178
|
+
let previewUrl;
|
|
179
|
+
try {
|
|
180
|
+
const exposedPorts = await sandbox.getExposedPorts("");
|
|
181
|
+
const exposed = exposedPorts.find((p) => p.port === port);
|
|
182
|
+
if (exposed) {
|
|
183
|
+
previewUrl = exposed.url;
|
|
184
|
+
}
|
|
185
|
+
} catch {}
|
|
186
|
+
return {
|
|
187
|
+
port,
|
|
188
|
+
url: `http://localhost:${port}`,
|
|
189
|
+
previewUrl,
|
|
190
|
+
processId: process.id,
|
|
191
|
+
async close() {
|
|
192
|
+
await process.kill("SIGTERM");
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
function createOpenhandsHandler(options = {}) {
|
|
200
|
+
const basePath = options.basePath || "";
|
|
201
|
+
const getSandboxName = options.getSandboxName || ((req) => {
|
|
202
|
+
const url = new URL(req.url);
|
|
203
|
+
return url.searchParams.get("sandbox");
|
|
204
|
+
});
|
|
205
|
+
return async (request, env) => {
|
|
206
|
+
const url = new URL(request.url);
|
|
207
|
+
const pathname = url.pathname;
|
|
208
|
+
const sandboxName = getSandboxName(request) || options.sandboxName || "my-sandbox";
|
|
209
|
+
const sandbox = getSandbox(env.Sandbox, sandboxName);
|
|
210
|
+
const proxyResponse = await proxyToSandbox(request, env);
|
|
211
|
+
if (proxyResponse) {
|
|
212
|
+
return proxyResponse;
|
|
213
|
+
}
|
|
214
|
+
if (pathname === `${basePath}/start-openhands`) {
|
|
215
|
+
try {
|
|
216
|
+
const hostname = options.hostname || url.hostname;
|
|
217
|
+
const server = await createOpenhandsServer(sandbox, {
|
|
218
|
+
...options,
|
|
219
|
+
hostname: options.exposePort ? hostname : undefined
|
|
220
|
+
});
|
|
221
|
+
return Response.json({
|
|
222
|
+
process: {
|
|
223
|
+
id: server.processId,
|
|
224
|
+
port: server.port,
|
|
225
|
+
status: "running"
|
|
226
|
+
},
|
|
227
|
+
previewUrl: server.previewUrl ? { url: server.previewUrl, port: server.port } : undefined,
|
|
228
|
+
success: true
|
|
229
|
+
});
|
|
230
|
+
} catch (error) {
|
|
231
|
+
return Response.json({
|
|
232
|
+
error: error instanceof Error ? error.message : String(error),
|
|
233
|
+
errorStack: error instanceof Error ? error.stack : undefined,
|
|
234
|
+
success: false
|
|
235
|
+
}, { status: 500 });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (pathname === `${basePath}/stop-openhands`) {
|
|
239
|
+
try {
|
|
240
|
+
const port = options.port ?? 8001;
|
|
241
|
+
const server = await findOpenhandsServer(sandbox, port);
|
|
242
|
+
if (server) {
|
|
243
|
+
await server.close();
|
|
244
|
+
return Response.json({ success: true, message: "Server stopped" });
|
|
245
|
+
}
|
|
246
|
+
return Response.json({ success: false, message: "No server running" }, { status: 404 });
|
|
247
|
+
} catch (error) {
|
|
248
|
+
return Response.json({
|
|
249
|
+
error: error instanceof Error ? error.message : String(error),
|
|
250
|
+
success: false
|
|
251
|
+
}, { status: 500 });
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (pathname === `${basePath}/openhands-status`) {
|
|
255
|
+
try {
|
|
256
|
+
const port = options.port ?? 8001;
|
|
257
|
+
const server = await findOpenhandsServer(sandbox, port);
|
|
258
|
+
if (!server) {
|
|
259
|
+
return Response.json({
|
|
260
|
+
running: false,
|
|
261
|
+
success: true
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
const processes = await sandbox.listProcesses();
|
|
265
|
+
const process = processes.find((p) => p.id === server.processId);
|
|
266
|
+
return Response.json({
|
|
267
|
+
running: process?.status === "running",
|
|
268
|
+
port: server.port,
|
|
269
|
+
previewUrl: server.previewUrl,
|
|
270
|
+
process: process ? {
|
|
271
|
+
id: process.id,
|
|
272
|
+
status: process.status,
|
|
273
|
+
command: process.command
|
|
274
|
+
} : null,
|
|
275
|
+
success: true
|
|
276
|
+
});
|
|
277
|
+
} catch (error) {
|
|
278
|
+
return Response.json({
|
|
279
|
+
error: error instanceof Error ? error.message : String(error),
|
|
280
|
+
success: false
|
|
281
|
+
}, { status: 500 });
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return null;
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function attachOpenhandsRoutes(fetchHandler, options = {}) {
|
|
288
|
+
const openhandsHandler = createOpenhandsHandler(options);
|
|
289
|
+
return async (request, env) => {
|
|
290
|
+
const openhandsResponse = await openhandsHandler(request, env);
|
|
291
|
+
if (openhandsResponse !== null) {
|
|
292
|
+
return openhandsResponse;
|
|
293
|
+
}
|
|
294
|
+
return fetchHandler(request, env);
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
export {
|
|
298
|
+
proxyToOpenhands,
|
|
299
|
+
getDefaultAgentServerPath,
|
|
300
|
+
getDefaultAgentServerDir,
|
|
301
|
+
findAgentServerPath,
|
|
302
|
+
createOpenhandsServer,
|
|
303
|
+
createOpenhandsHandler,
|
|
304
|
+
checkAgentServerExists,
|
|
305
|
+
buildAgentServerCommand,
|
|
306
|
+
attachOpenhandsRoutes,
|
|
307
|
+
OpenhandsStartupError,
|
|
308
|
+
DEFAULT_AGENT_SERVER_PATH,
|
|
309
|
+
DEFAULT_AGENT_SERVER_DIR
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
//# debugId=B9FBDAC5E93D00D564756E2164756E21
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/utils/agent-server.ts", "../src/openhands/types.ts", "../src/openhands/openhands.ts", "../src/routes/handler.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Sandbox } from '@cloudflare/sandbox';\n\n/**\n * Default path to agent-server executable\n */\nexport const DEFAULT_AGENT_SERVER_PATH =\n '/container-server/software-agent-sdk/.venv/bin/agent-server';\n\n/**\n * Default working directory for agent-server\n */\nexport const DEFAULT_AGENT_SERVER_DIR =\n '/container-server/software-agent-sdk';\n\n/**\n * Get the default agent-server executable path\n */\nexport function getDefaultAgentServerPath(): string {\n return DEFAULT_AGENT_SERVER_PATH;\n}\n\n/**\n * Get the default agent-server working directory\n */\nexport function getDefaultAgentServerDir(): string {\n return DEFAULT_AGENT_SERVER_DIR;\n}\n\n/**\n * Check if agent-server exists at the given path\n */\nexport async function checkAgentServerExists(\n sandbox: Sandbox<unknown>,\n path: string = DEFAULT_AGENT_SERVER_PATH\n): Promise<boolean> {\n try {\n const result = await sandbox.exec(\n `test -f ${path} && echo \"EXISTS\" || echo \"NOT_FOUND\"`\n );\n return result.stdout.trim() === 'EXISTS';\n } catch {\n return false;\n }\n}\n\n/**\n * Find agent-server executable by checking common locations\n */\nexport async function findAgentServerPath(\n sandbox: Sandbox<unknown>\n): Promise<string | null> {\n const locations = [\n DEFAULT_AGENT_SERVER_PATH,\n '/software-agent-sdk/.venv/bin/agent-server',\n '/root/software-agent-sdk/.venv/bin/agent-server',\n ];\n\n for (const location of locations) {\n if (await checkAgentServerExists(sandbox, location)) {\n return location;\n }\n }\n\n // Try which as fallback\n try {\n const result = await sandbox.exec('which agent-server');\n const path = result.stdout.trim();\n if (path && !path.includes('not found')) {\n return path;\n }\n } catch {\n // Ignore errors\n }\n\n return null;\n}\n\n/**\n * Build the agent-server command\n */\nexport function buildAgentServerCommand(\n port: number,\n directory?: string\n): string {\n const command = `${DEFAULT_AGENT_SERVER_PATH} --host 0.0.0.0 --port ${port}`;\n return directory && directory !== DEFAULT_AGENT_SERVER_DIR\n ? `cd ${directory} && ${command}`\n : command;\n}\n\n",
|
|
6
|
+
"import type { Process } from '@cloudflare/sandbox';\n\n/**\n * Configuration options for starting OpenHands agent-server\n */\nexport interface OpenhandsOptions {\n /** Port for agent-server (default: 8001) */\n port?: number;\n /** Working directory for agent-server (default: /container-server/software-agent-sdk) */\n directory?: string;\n /** Hostname for preview URL exposure (required if exposePort is true) */\n hostname?: string;\n /** Enable preview URL exposure (default: false) */\n exposePort?: boolean;\n /** Environment variables for agent-server */\n env?: Record<string, string>;\n /** Sandbox name/session ID (default: 'my-sandbox') */\n sandboxName?: string;\n}\n\n/**\n * Server lifecycle management\n */\nexport interface OpenhandsServer {\n /** Port the server is running on */\n port: number;\n /** Base URL for server (http://localhost:{port}) */\n url: string;\n /** Preview URL if port was exposed (optional) */\n previewUrl?: string;\n /** Process ID */\n processId: string;\n /** Close the server gracefully */\n close(): Promise<void>;\n}\n\n/**\n * Context information for startup errors\n */\nexport interface OpenhandsStartupContext {\n port: number;\n stderr?: string;\n command?: string;\n processId?: string;\n}\n\n/**\n * Error thrown when agent-server fails to start\n */\nexport class OpenhandsStartupError extends Error {\n readonly code = 'OPENHANDS_STARTUP_FAILED' as const;\n readonly context: OpenhandsStartupContext;\n\n constructor(\n message: string,\n context: OpenhandsStartupContext,\n options?: ErrorOptions\n ) {\n super(message, options);\n this.name = 'OpenhandsStartupError';\n this.context = context;\n }\n}\n\n",
|
|
7
|
+
"import type { Sandbox, Process } from '@cloudflare/sandbox';\nimport type {\n OpenhandsOptions,\n OpenhandsServer,\n OpenhandsStartupContext,\n} from './types';\nimport { OpenhandsStartupError } from './types';\nimport {\n buildAgentServerCommand,\n DEFAULT_AGENT_SERVER_DIR,\n DEFAULT_AGENT_SERVER_PATH,\n} from '../utils/agent-server';\n\nconst DEFAULT_PORT = 8001;\n\n/**\n * Find an existing agent-server process running on the specified port.\n * Returns the process if found and still active, null otherwise.\n */\nasync function findExistingAgentServer(\n sandbox: Sandbox<unknown>,\n port: number\n): Promise<Process | null> {\n const processes = await sandbox.listProcesses();\n const commandPattern = DEFAULT_AGENT_SERVER_PATH;\n\n for (const proc of processes) {\n // Match commands that contain the agent-server path\n if (proc.command.includes(commandPattern)) {\n // Check if the command includes the port\n if (\n proc.command.includes(`--port ${port}`) ||\n proc.command.includes(`--port=${port}`)\n ) {\n if (proc.status === 'starting' || proc.status === 'running') {\n return proc;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Start a new agent-server process\n */\nasync function startAgentServer(\n sandbox: Sandbox<unknown>,\n port: number,\n options: OpenhandsOptions\n): Promise<Process> {\n const directory = options.directory || DEFAULT_AGENT_SERVER_DIR;\n const command = buildAgentServerCommand(port, directory);\n\n const process = await sandbox.startProcess(command, {\n cwd: directory,\n env: options.env,\n });\n\n // Wait for the server to be ready\n try {\n await process.waitForPort(port, {\n mode: 'http',\n path: '/',\n timeout: 60_000, // 60 seconds\n });\n } catch (e) {\n const logs = await process.getLogs();\n throw new OpenhandsStartupError(\n `agent-server failed to start on port ${port}. Stderr: ${logs.stderr || '(empty)'}`,\n {\n port,\n stderr: logs.stderr,\n command: process.command,\n processId: process.id,\n },\n { cause: e }\n );\n }\n\n return process;\n}\n\n/**\n * Ensures agent-server is running in the container.\n * Reuses existing process if one is already running on the specified port.\n * Handles concurrent startup attempts gracefully by retrying on failure.\n */\nasync function ensureAgentServer(\n sandbox: Sandbox<unknown>,\n port: number,\n options: OpenhandsOptions\n): Promise<Process> {\n // Check if agent-server is already running on this port\n const existingProcess = await findExistingAgentServer(sandbox, port);\n if (existingProcess) {\n // Reuse existing process - wait for it to be ready if still starting\n if (existingProcess.status === 'starting') {\n try {\n await existingProcess.waitForPort(port, {\n mode: 'http',\n path: '/',\n timeout: 60_000,\n });\n } catch (e) {\n const logs = await existingProcess.getLogs();\n throw new OpenhandsStartupError(\n `agent-server failed to start. Stderr: ${logs.stderr || '(empty)'}`,\n {\n port,\n stderr: logs.stderr,\n command: existingProcess.command,\n processId: existingProcess.id,\n },\n { cause: e }\n );\n }\n }\n return existingProcess;\n }\n\n // Try to start a new agent-server\n try {\n return await startAgentServer(sandbox, port, options);\n } catch (startupError) {\n // Startup failed - check if another concurrent request started the server\n // This handles the race condition where multiple requests try to start simultaneously\n const retryProcess = await findExistingAgentServer(sandbox, port);\n if (retryProcess) {\n // Wait for the concurrent server to be ready\n if (retryProcess.status === 'starting') {\n try {\n await retryProcess.waitForPort(port, {\n mode: 'http',\n path: '/',\n timeout: 60_000,\n });\n } catch (e) {\n const logs = await retryProcess.getLogs();\n throw new OpenhandsStartupError(\n `agent-server failed to start. Stderr: ${logs.stderr || '(empty)'}`,\n {\n port,\n stderr: logs.stderr,\n command: retryProcess.command,\n processId: retryProcess.id,\n },\n { cause: e }\n );\n }\n }\n return retryProcess;\n }\n\n // No concurrent process found, rethrow the original error\n throw startupError;\n }\n}\n\n/**\n * Starts an agent-server inside a Sandbox container.\n *\n * This function manages the server lifecycle only. If an agent-server is already\n * running on the specified port, this function will reuse it instead of starting\n * a new one.\n *\n * @param sandbox - The Sandbox instance to run agent-server in\n * @param options - Configuration options\n * @returns Promise resolving to server handle { port, url, previewUrl?, close() }\n *\n * @example\n * ```typescript\n * import { getSandbox } from '@cloudflare/sandbox'\n * import { createOpenhandsServer } from 'openhands-sdk/openhands'\n *\n * const sandbox = getSandbox(env.Sandbox, 'my-sandbox')\n * const server = await createOpenhandsServer(sandbox, {\n * port: 8001,\n * exposePort: true,\n * hostname: 'yourdomain.com'\n * })\n *\n * // Proxy requests to the server\n * return sandbox.containerFetch(request, server.port)\n *\n * // When done\n * await server.close()\n * ```\n */\nexport async function createOpenhandsServer(\n sandbox: Sandbox<unknown>,\n options: OpenhandsOptions = {}\n): Promise<OpenhandsServer> {\n const port = options.port ?? DEFAULT_PORT;\n const process = await ensureAgentServer(sandbox, port, options);\n\n let previewUrl: string | undefined;\n\n // Optionally expose port for preview URL\n if (options.exposePort) {\n if (!options.hostname) {\n throw new Error(\n 'hostname is required when exposePort is true. Provide hostname in options or extract from request URL.'\n );\n }\n\n try {\n const exposed = await sandbox.exposePort(port, {\n hostname: options.hostname,\n });\n previewUrl = typeof exposed === 'string' ? exposed : exposed.url;\n } catch (error) {\n // Log but don't fail - server is still running\n console.warn('Failed to expose port:', error);\n }\n }\n\n return {\n port,\n url: `http://localhost:${port}`,\n previewUrl,\n processId: process.id,\n async close() {\n await process.kill('SIGTERM');\n },\n };\n}\n\n/**\n * Proxy a request to the agent-server.\n *\n * This function handles proxying only - you must start the server separately\n * using `createOpenhandsServer()`.\n *\n * @param request - The incoming HTTP request\n * @param sandbox - The Sandbox instance running agent-server\n * @param server - The agent-server handle from createOpenhandsServer()\n * @returns Response from agent-server\n *\n * @example\n * ```typescript\n * import { getSandbox } from '@cloudflare/sandbox'\n * import { createOpenhandsServer, proxyToOpenhands } from 'openhands-sdk/openhands'\n *\n * export default {\n * async fetch(request: Request, env: Env) {\n * const sandbox = getSandbox(env.Sandbox, 'my-sandbox')\n * const server = await createOpenhandsServer(sandbox, {\n * port: 8001,\n * exposePort: true,\n * hostname: 'yourdomain.com'\n * })\n * return proxyToOpenhands(request, sandbox, server)\n * }\n * }\n * ```\n */\nexport function proxyToOpenhands(\n request: Request,\n sandbox: Sandbox<unknown>,\n server: OpenhandsServer\n): Response | Promise<Response> {\n return sandbox.containerFetch(request, server.port);\n}\n\n",
|
|
8
|
+
"import { getSandbox, proxyToSandbox } from '@cloudflare/sandbox';\nimport type { Sandbox } from '@cloudflare/sandbox';\nimport {\n createOpenhandsServer,\n proxyToOpenhands,\n type OpenhandsOptions,\n type OpenhandsServer,\n} from '../openhands';\nimport { DEFAULT_AGENT_SERVER_PATH } from '../utils/agent-server';\n\n// Cloudflare Workers environment type constraint\n// Accepts any Env type that has a Sandbox property compatible with DurableObjectNamespace\n// This is a minimal structural type that matches what getSandbox and proxyToSandbox need\n// Using a more permissive type that accepts any object with the required structure\nexport type OpenhandsEnv = {\n Sandbox: {\n get(id: { toString(): string }): {\n fetch(input: string | Request, init?: RequestInit): Promise<Response>;\n };\n };\n};\n\n/**\n * Options for OpenHands route handler\n */\nexport interface OpenhandsHandlerOptions extends OpenhandsOptions {\n /** Base path for OpenHands routes (default: '') */\n basePath?: string;\n /** Custom sandbox name resolver */\n getSandboxName?: (request: Request) => string | null;\n}\n\n/**\n * Find existing OpenHands server by port\n */\nasync function findOpenhandsServer(\n sandbox: Sandbox<unknown>,\n port: number\n): Promise<OpenhandsServer | null> {\n const processes = await sandbox.listProcesses();\n\n for (const process of processes) {\n // Match agent-server processes on the specified port\n if (\n process.command.includes(DEFAULT_AGENT_SERVER_PATH) &&\n (process.command.includes(`--port ${port}`) ||\n process.command.includes(`--port=${port}`)) &&\n (process.status === 'running' || process.status === 'starting')\n ) {\n // Try to get exposed ports to find preview URL\n let previewUrl: string | undefined;\n try {\n // Try to get exposed ports - hostname is optional\n const exposedPorts = await sandbox.getExposedPorts('');\n const exposed = exposedPorts.find((p) => p.port === port);\n if (exposed) {\n previewUrl = exposed.url;\n }\n } catch {\n // Ignore errors getting exposed ports\n }\n\n return {\n port,\n url: `http://localhost:${port}`,\n previewUrl,\n processId: process.id,\n async close() {\n await process.kill('SIGTERM');\n },\n };\n }\n }\n\n return null;\n}\n\n/**\n * Creates a middleware function that handles OpenHands routes.\n * Returns null if the request doesn't match OpenHands routes (allows chaining).\n *\n * @param options - Configuration options\n * @returns Middleware function\n */\nexport function createOpenhandsHandler<Env extends OpenhandsEnv = OpenhandsEnv>(\n options: OpenhandsHandlerOptions = {}\n) {\n const basePath = options.basePath || '';\n const getSandboxName = options.getSandboxName || ((req) => {\n const url = new URL(req.url);\n return url.searchParams.get('sandbox');\n });\n\n return async (\n request: Request,\n env: Env\n ): Promise<Response | null> => {\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n // Extract sandbox name\n const sandboxName = getSandboxName(request) || options.sandboxName || 'my-sandbox';\n const sandbox = getSandbox(env.Sandbox, sandboxName);\n\n // Handle preview URL proxying (must be first)\n const proxyResponse = await proxyToSandbox(request, env);\n if (proxyResponse) {\n return proxyResponse;\n }\n\n // Handle OpenHands routes\n if (pathname === `${basePath}/start-openhands`) {\n try {\n // Extract hostname from request if not provided\n const hostname = options.hostname || url.hostname;\n\n const server = await createOpenhandsServer(sandbox, {\n ...options,\n hostname: options.exposePort ? hostname : undefined,\n });\n\n return Response.json({\n process: {\n id: server.processId,\n port: server.port,\n status: 'running',\n },\n previewUrl: server.previewUrl\n ? { url: server.previewUrl, port: server.port }\n : undefined,\n success: true,\n });\n } catch (error) {\n return Response.json(\n {\n error: error instanceof Error ? error.message : String(error),\n errorStack: error instanceof Error ? error.stack : undefined,\n success: false,\n },\n { status: 500 }\n );\n }\n }\n\n if (pathname === `${basePath}/stop-openhands`) {\n try {\n const port = options.port ?? 8001;\n const server = await findOpenhandsServer(sandbox, port);\n if (server) {\n await server.close();\n return Response.json({ success: true, message: 'Server stopped' });\n }\n return Response.json(\n { success: false, message: 'No server running' },\n { status: 404 }\n );\n } catch (error) {\n return Response.json(\n {\n error: error instanceof Error ? error.message : String(error),\n success: false,\n },\n { status: 500 }\n );\n }\n }\n\n if (pathname === `${basePath}/openhands-status`) {\n try {\n const port = options.port ?? 8001;\n const server = await findOpenhandsServer(sandbox, port);\n if (!server) {\n return Response.json({\n running: false,\n success: true,\n });\n }\n\n // Verify process is still running\n const processes = await sandbox.listProcesses();\n const process = processes.find((p) => p.id === server.processId);\n\n return Response.json({\n running: process?.status === 'running',\n port: server.port,\n previewUrl: server.previewUrl,\n process: process\n ? {\n id: process.id,\n status: process.status,\n command: process.command,\n }\n : null,\n success: true,\n });\n } catch (error) {\n return Response.json(\n {\n error: error instanceof Error ? error.message : String(error),\n success: false,\n },\n { status: 500 }\n );\n }\n }\n\n // Request doesn't match OpenHands routes\n return null;\n };\n}\n\n/**\n * Attaches OpenHands routes to an existing fetch handler.\n * This wraps your handler with OpenHands route handling and preview URL proxying.\n *\n * @param fetchHandler - Your existing fetch handler\n * @param options - Configuration options\n * @returns Wrapped fetch handler\n *\n * @example\n * ```typescript\n * import { attachOpenhandsRoutes } from 'openhands-sdk/routes';\n *\n * export default attachOpenhandsRoutes(async (request, env) => {\n * // Your custom routes here\n * return new Response('Not found', { status: 404 });\n * }, {\n * port: 8001,\n * exposePort: true,\n * hostname: 'yourdomain.com'\n * });\n * ```\n */\nexport function attachOpenhandsRoutes<Env extends OpenhandsEnv = OpenhandsEnv>(\n fetchHandler: (\n request: Request,\n env: Env\n ) => Response | Promise<Response>,\n options: OpenhandsHandlerOptions = {}\n): (\n request: Request,\n env: Env\n) => Promise<Response> {\n const openhandsHandler = createOpenhandsHandler<Env>(options);\n\n return async (\n request: Request,\n env: Env\n ): Promise<Response> => {\n // First, try OpenHands handler\n const openhandsResponse = await openhandsHandler(request, env);\n if (openhandsResponse !== null) {\n return openhandsResponse;\n }\n\n // Fall through to user's handler\n return fetchHandler(request, env);\n };\n}\n\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "B9FBDAC5E93D00D564756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/openhands/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC"}
|