@roj-ai/sandbox-runtime 0.1.3 → 0.1.4
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/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/main.js +33 -0
- package/dist/main.js.map +1 -0
- package/dist/server.js +146 -0
- package/dist/server.js.map +1 -0
- package/dist/user-config-loader.js +66 -0
- package/dist/user-config-loader.js.map +1 -0
- package/package.json +10 -10
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @roj-ai/sandbox-runtime — Bun runtime that hosts the agent inside an E2B sandbox.
|
|
3
|
+
*
|
|
4
|
+
* Connects back to the Cloudflare Worker Durable Object over WebSocket
|
|
5
|
+
* (worker mode). Not for standalone use — see @roj-ai/standalone-server
|
|
6
|
+
* for running the SDK locally.
|
|
7
|
+
*/
|
|
8
|
+
export { createBunFileSystem, createBunPlatform, createBunProcessRunner } from '@roj-ai/sdk/bun-platform';
|
|
9
|
+
export { startServer } from './server.js';
|
|
10
|
+
export { loadUserConfig } from './user-config-loader.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACzG,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Entry Point for Agent Server
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* bun src/main.ts [config-path]
|
|
6
|
+
*
|
|
7
|
+
* Arguments:
|
|
8
|
+
* config-path Path to roj.config.ts (default: roj.config.ts in CWD)
|
|
9
|
+
*/
|
|
10
|
+
import { resolve } from 'node:path';
|
|
11
|
+
import { startServer } from './server.js';
|
|
12
|
+
import { loadUserConfig } from './user-config-loader.js';
|
|
13
|
+
async function main() {
|
|
14
|
+
const configPath = process.argv[2] ?? 'roj.config.ts';
|
|
15
|
+
const absoluteConfigPath = resolve(process.cwd(), configPath);
|
|
16
|
+
let userConfig;
|
|
17
|
+
try {
|
|
18
|
+
userConfig = await loadUserConfig(absoluteConfigPath);
|
|
19
|
+
console.log(`Loaded config from: ${absoluteConfigPath}`);
|
|
20
|
+
console.log(` Presets: ${userConfig.presets.map((p) => p.id).join(', ')}`);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error(`Failed to load user config from ${absoluteConfigPath}:`);
|
|
24
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
await startServer({ presets: userConfig.presets });
|
|
28
|
+
}
|
|
29
|
+
main().catch((error) => {
|
|
30
|
+
console.error('Fatal error:', error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAExD,KAAK,UAAU,IAAI;IAClB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,eAAe,CAAA;IACrD,MAAM,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAA;IAE7D,IAAI,UAAsD,CAAA;IAC1D,IAAI,CAAC;QACJ,UAAU,GAAG,MAAM,cAAc,CAAC,kBAAkB,CAAC,CAAA;QACrD,OAAO,CAAC,GAAG,CAAC,uBAAuB,kBAAkB,EAAE,CAAC,CAAA;QACxD,OAAO,CAAC,GAAG,CAAC,cAAc,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC5E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,mCAAmC,kBAAkB,GAAG,CAAC,CAAA;QACvE,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC;IAED,MAAM,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,CAAA;AACnD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACtB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC,CAAC,CAAA"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level API for starting the Agent Server.
|
|
3
|
+
*
|
|
4
|
+
* Handles: config loading, bootstrap, transport, session manager,
|
|
5
|
+
* HTTP app, Bun.serve, session loading, and shutdown.
|
|
6
|
+
*/
|
|
7
|
+
import { bootstrap, createSystemFromServices, loadConfig, validateConfig } from '@roj-ai/sdk';
|
|
8
|
+
import { createApp } from '@roj-ai/sdk/transport/http/app';
|
|
9
|
+
import { createAgentTransport, ServerAdapter } from '@roj-ai/sdk/transport/adapter';
|
|
10
|
+
import { bunWebSocketFactory, createBunWebSocketHandlers } from '@roj-ai/transport/bun';
|
|
11
|
+
import { createBunPlatform } from '@roj-ai/sdk/bun-platform';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// startServer
|
|
14
|
+
// ============================================================================
|
|
15
|
+
export async function startServer(options) {
|
|
16
|
+
// Load config from env and merge overrides
|
|
17
|
+
const envConfig = loadConfig();
|
|
18
|
+
const config = options.config ? { ...envConfig, ...options.config } : envConfig;
|
|
19
|
+
const errors = validateConfig(config);
|
|
20
|
+
if (errors.length > 0) {
|
|
21
|
+
throw new Error(`Configuration errors:\n${errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
22
|
+
}
|
|
23
|
+
// Apply global LLM middleware to all presets (prepended before preset-level middleware)
|
|
24
|
+
const presets = options.llmMiddleware?.length
|
|
25
|
+
? options.presets.map(p => ({
|
|
26
|
+
...p,
|
|
27
|
+
llmMiddleware: [...options.llmMiddleware, ...(p.llmMiddleware ?? [])],
|
|
28
|
+
}))
|
|
29
|
+
: options.presets;
|
|
30
|
+
const services = bootstrap(config, { presets }, createBunPlatform());
|
|
31
|
+
const { logger } = services;
|
|
32
|
+
if (options.onBeforeStart) {
|
|
33
|
+
await options.onBeforeStart({ config, logger });
|
|
34
|
+
}
|
|
35
|
+
// Auto-detect mode from config
|
|
36
|
+
const isWorkerMode = !!(config.workerUrl && config.agentToken);
|
|
37
|
+
const transport = createTransport(config, logger, isWorkerMode);
|
|
38
|
+
const system = createSystemFromServices(services, {
|
|
39
|
+
onUserOutput: (message) => transport.broadcast(message),
|
|
40
|
+
});
|
|
41
|
+
const sessionManager = system.sessionManager;
|
|
42
|
+
const app = createApp({
|
|
43
|
+
...services,
|
|
44
|
+
sessionRuntime: sessionManager,
|
|
45
|
+
agentToken: config.agentToken,
|
|
46
|
+
});
|
|
47
|
+
const server = startBunServer(config, app, transport);
|
|
48
|
+
// Load persisted sessions after HTTP server is up (health checks pass during loading)
|
|
49
|
+
try {
|
|
50
|
+
await sessionManager.loadAllSessions();
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
logger.error('Failed to load persisted sessions', error instanceof Error ? error : new Error(String(error)));
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
await transport.start();
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
logger.error('Transport connection failed (will retry via reconnect)', error instanceof Error ? error : new Error(String(error)));
|
|
60
|
+
}
|
|
61
|
+
logger.info('Agent server started', {
|
|
62
|
+
host: config.host,
|
|
63
|
+
port: config.port,
|
|
64
|
+
persistence: config.persistence,
|
|
65
|
+
mode: isWorkerMode ? 'worker' : 'standalone',
|
|
66
|
+
});
|
|
67
|
+
const shutdown = async () => {
|
|
68
|
+
logger.info('Shutting down...');
|
|
69
|
+
if (options.onShutdown) {
|
|
70
|
+
await options.onShutdown();
|
|
71
|
+
}
|
|
72
|
+
await sessionManager.shutdown();
|
|
73
|
+
await transport.stop();
|
|
74
|
+
server.stop();
|
|
75
|
+
};
|
|
76
|
+
process.on('SIGINT', () => {
|
|
77
|
+
void shutdown().then(() => process.exit(0));
|
|
78
|
+
});
|
|
79
|
+
process.on('SIGTERM', () => {
|
|
80
|
+
void shutdown().then(() => process.exit(0));
|
|
81
|
+
});
|
|
82
|
+
return { config, logger, shutdown };
|
|
83
|
+
}
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// Internal helpers
|
|
86
|
+
// ============================================================================
|
|
87
|
+
function createTransport(config, logger, isWorkerMode) {
|
|
88
|
+
if (isWorkerMode) {
|
|
89
|
+
const sandboxId = process.env.SANDBOX_ID;
|
|
90
|
+
if (!sandboxId) {
|
|
91
|
+
throw new Error('SANDBOX_ID is required in worker mode');
|
|
92
|
+
}
|
|
93
|
+
const url = new URL('/ws/agent', config.workerUrl);
|
|
94
|
+
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
95
|
+
url.searchParams.set('sandboxId', sandboxId);
|
|
96
|
+
url.searchParams.set('token', config.agentToken);
|
|
97
|
+
return createAgentTransport({
|
|
98
|
+
mode: 'worker',
|
|
99
|
+
url: url.toString(),
|
|
100
|
+
wsFactory: bunWebSocketFactory,
|
|
101
|
+
reconnect: {
|
|
102
|
+
baseDelayMs: config.wsReconnectBaseDelayMs ?? 1000,
|
|
103
|
+
maxDelayMs: config.wsReconnectMaxDelayMs ?? 30000,
|
|
104
|
+
maxAttempts: Infinity,
|
|
105
|
+
jitterFactor: 0.3,
|
|
106
|
+
},
|
|
107
|
+
logger,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return createAgentTransport({ mode: 'standalone', logger });
|
|
111
|
+
}
|
|
112
|
+
function createWSData(sessionId = null) {
|
|
113
|
+
return {
|
|
114
|
+
clientId: crypto.randomUUID(),
|
|
115
|
+
clientType: 'spa',
|
|
116
|
+
sessionId,
|
|
117
|
+
subscribedSessions: new Set(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function startBunServer(config, app, transport) {
|
|
121
|
+
const serverAdapter = transport instanceof ServerAdapter ? transport : null;
|
|
122
|
+
const wsHandlers = serverAdapter
|
|
123
|
+
? createBunWebSocketHandlers({
|
|
124
|
+
onOpen: (ws) => serverAdapter.handleOpen(ws, ws.data.sessionId ?? undefined),
|
|
125
|
+
onClose: (ws, code, reason) => serverAdapter.handleClose(ws, code, reason),
|
|
126
|
+
onMessage: (ws, message) => serverAdapter.handleMessage(ws, message),
|
|
127
|
+
onError: (ws, error) => serverAdapter.handleError(ws, error),
|
|
128
|
+
getData: (ws) => ws.data,
|
|
129
|
+
})
|
|
130
|
+
: null;
|
|
131
|
+
return Bun.serve({
|
|
132
|
+
port: config.port,
|
|
133
|
+
hostname: config.host,
|
|
134
|
+
fetch(req, server) {
|
|
135
|
+
const url = new URL(req.url);
|
|
136
|
+
if (url.pathname === '/ws/spa' && serverAdapter) {
|
|
137
|
+
const sessionId = url.searchParams.get('sessionId');
|
|
138
|
+
const upgraded = server.upgrade(req, { data: createWSData(sessionId) });
|
|
139
|
+
return upgraded ? undefined : new Response('WebSocket upgrade failed', { status: 400 });
|
|
140
|
+
}
|
|
141
|
+
return app.fetch(req);
|
|
142
|
+
},
|
|
143
|
+
websocket: wsHandlers ?? { open() { }, close() { }, message() { } },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime loader for the user `roj.config.ts` file.
|
|
3
|
+
*
|
|
4
|
+
* Uses dynamic `import()` — this is why it lives in the runtime package
|
|
5
|
+
* rather than in `@roj-ai/sdk` (which stays pure and platform-agnostic).
|
|
6
|
+
*/
|
|
7
|
+
import { validatePreset } from '@roj-ai/sdk';
|
|
8
|
+
import { existsSync } from 'node:fs';
|
|
9
|
+
import { resolve } from 'node:path';
|
|
10
|
+
/**
|
|
11
|
+
* Load user configuration from a TypeScript file.
|
|
12
|
+
*
|
|
13
|
+
* @param configPath - Absolute or relative path to the config file
|
|
14
|
+
* @returns Validated RojConfig
|
|
15
|
+
* @throws Error if config file not found, invalid format, or preset validation fails
|
|
16
|
+
*/
|
|
17
|
+
export async function loadUserConfig(configPath) {
|
|
18
|
+
const absolutePath = resolve(process.cwd(), configPath);
|
|
19
|
+
if (!existsSync(absolutePath)) {
|
|
20
|
+
throw new Error(`Configuration file not found: ${absolutePath}`);
|
|
21
|
+
}
|
|
22
|
+
let module;
|
|
23
|
+
try {
|
|
24
|
+
module = await import(absolutePath);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw new Error(`Failed to load configuration file: ${absolutePath}\n${error instanceof Error ? error.message : String(error)}`);
|
|
28
|
+
}
|
|
29
|
+
const config = module.default;
|
|
30
|
+
if (!config) {
|
|
31
|
+
throw new Error(`Configuration file must have a default export: ${absolutePath}`);
|
|
32
|
+
}
|
|
33
|
+
if (typeof config !== 'object' || config === null) {
|
|
34
|
+
throw new Error(`Configuration must be an object: ${absolutePath}`);
|
|
35
|
+
}
|
|
36
|
+
const typedConfig = config;
|
|
37
|
+
if (!Array.isArray(typedConfig.presets)) {
|
|
38
|
+
throw new Error(`Configuration must have a 'presets' array: ${absolutePath}`);
|
|
39
|
+
}
|
|
40
|
+
const presets = typedConfig.presets;
|
|
41
|
+
const allErrors = [];
|
|
42
|
+
for (const preset of presets) {
|
|
43
|
+
if (!preset.id || typeof preset.id !== 'string') {
|
|
44
|
+
allErrors.push(`Preset missing required 'id' field`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const errors = validatePreset(preset);
|
|
48
|
+
if (errors.length > 0) {
|
|
49
|
+
allErrors.push(`Preset '${preset.id}': ${errors.join(', ')}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (allErrors.length > 0) {
|
|
53
|
+
throw new Error(`Preset validation errors:\n${allErrors.map((e) => ` - ${e}`).join('\n')}`);
|
|
54
|
+
}
|
|
55
|
+
const ids = presets.map((p) => p.id);
|
|
56
|
+
const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
|
|
57
|
+
if (duplicates.length > 0) {
|
|
58
|
+
throw new Error(`Duplicate preset IDs: ${[...new Set(duplicates)].join(', ')}`);
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
presets,
|
|
62
|
+
sandboxed: typedConfig.sandboxed,
|
|
63
|
+
snapshotter: typedConfig.snapshotter,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=user-config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-config-loader.js","sourceRoot":"","sources":["../src/user-config-loader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roj-ai/sandbox-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "./
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
|
-
"import": "./
|
|
10
|
-
"default": "./
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
11
|
},
|
|
12
12
|
"./server": {
|
|
13
13
|
"types": "./dist/server.d.ts",
|
|
14
|
-
"import": "./
|
|
15
|
-
"default": "./
|
|
14
|
+
"import": "./dist/server.js",
|
|
15
|
+
"default": "./dist/server.js"
|
|
16
16
|
},
|
|
17
17
|
"./user-config": {
|
|
18
18
|
"types": "./dist/user-config-loader.d.ts",
|
|
19
|
-
"import": "./
|
|
20
|
-
"default": "./
|
|
19
|
+
"import": "./dist/user-config-loader.js",
|
|
20
|
+
"default": "./dist/user-config-loader.js"
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"type-check": "tsc --noEmit"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@roj-ai/sdk": "^0.1.
|
|
47
|
-
"@roj-ai/transport": "^0.1.
|
|
46
|
+
"@roj-ai/sdk": "^0.1.4",
|
|
47
|
+
"@roj-ai/transport": "^0.1.4",
|
|
48
48
|
"hono": "4.12.5"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|