replicas-engine 0.1.641 → 0.1.643

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.
@@ -2448,6 +2448,7 @@ Use this when:
2448
2448
  - The user asks to manage Calendly events, invitees, or scheduling links
2449
2449
  - The user asks to read or change Google Ads, Docs, Drive, Search Console, or Sheets data
2450
2450
  - The user asks for ClickHouse analytics or PostHog product data
2451
+ - The user asks to create or control an E2B sandbox
2451
2452
  - The user asks to invoke a connected Modal function
2452
2453
  - The user asks to query or update a connected turbopuffer namespace
2453
2454
  - The user asks for PlanetScale organizations, databases, branches, or Insights data
@@ -2556,6 +2557,18 @@ const plagiarism = await replicas.pangram.plagiarism(text);
2556
2557
  \`\`\`
2557
2558
 
2558
2559
  Do not send private or sensitive text without the user's authorization.
2560
+
2561
+ ## E2B
2562
+
2563
+ E2B is a native integration backed by its official JavaScript SDK. Create a sandbox, run commands, and remove it when finished:
2564
+
2565
+ \`\`\`ts
2566
+ const { sandboxId } = await replicas.e2b.create({ timeoutMs: 300_000 });
2567
+ const result = await replicas.e2b.run(sandboxId, 'python analysis.py', { cwd: '/home/user' });
2568
+ await replicas.e2b.kill(sandboxId);
2569
+ \`\`\`
2570
+
2571
+ Sandbox operations consume the connected account's E2B credits. Kill sandboxes after use unless the user asked to keep one running.
2559
2572
  `;
2560
2573
  var PLUGINS_ABILITY = {
2561
2574
  label: "Plugins",
@@ -5875,7 +5888,7 @@ var DEFAULT_CODEX_ARGS = [
5875
5888
  var MIN_CODEX_CLI_VERSION = "0.144.6";
5876
5889
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
5877
5890
  var codexCliVersionEnsured = null;
5878
- var ENGINE_PACKAGE_VERSION = "0.1.641";
5891
+ var ENGINE_PACKAGE_VERSION = "0.1.643";
5879
5892
  var INITIALIZE_METHOD = "initialize";
5880
5893
  var INITIALIZED_NOTIFICATION = "initialized";
5881
5894
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -7,7 +7,7 @@ import {
7
7
  isUnsafeMemoryOutput,
8
8
  putPresignedFile,
9
9
  recoverCompletedTurn
10
- } from "./chunk-CHX75SYC.js";
10
+ } from "./chunk-NJUUACT2.js";
11
11
 
12
12
  // src/headless-agent.ts
13
13
  import { createHash } from "crypto";
package/dist/src/index.js CHANGED
@@ -172,7 +172,7 @@ import {
172
172
  serializeCanvasContentResponse,
173
173
  shellQuotePosix,
174
174
  stripAgentDiagnosticErrors
175
- } from "./chunk-CHX75SYC.js";
175
+ } from "./chunk-NJUUACT2.js";
176
176
 
177
177
  // src/index.ts
178
178
  import { serve } from "@hono/node-server";
@@ -11365,8 +11365,13 @@ var ChatService = class {
11365
11365
  return;
11366
11366
  }
11367
11367
  if (!chat.hasActiveTurn) {
11368
- await this.publishAgentTurnCompleteWebhook(chat);
11369
- return;
11368
+ const queuedMessageIds = new Set(chat.provider.getQueue().map((message) => message.id));
11369
+ const completedMessageId = chat.pendingMessageIds.find((messageId) => !queuedMessageIds.has(messageId));
11370
+ if (!completedMessageId) {
11371
+ await this.publishAgentTurnCompleteWebhook(chat);
11372
+ return;
11373
+ }
11374
+ chat.pendingMessageIds = chat.pendingMessageIds.filter((messageId) => messageId !== completedMessageId);
11370
11375
  }
11371
11376
  chat.hasActiveTurn = false;
11372
11377
  chat.activeMessageId = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.641",
3
+ "version": "0.1.643",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -123,5 +123,14 @@ const pangram = {
123
123
  plagiarism: (text) => pangramRequest('plagiarism', { text }),
124
124
  };
125
125
 
126
- export const replicas = { integrations, plugins, linear, slack, github, gitlab, sentry, modal, pangram, planetscale, turbopuffer };
126
+ const e2b = {
127
+ create: (input = {}) => request('/v1/engine/e2b', { method: 'POST', body: { ...input, operation: 'create' } }),
128
+ run: (sandboxId, command, options = {}) => request('/v1/engine/e2b', {
129
+ method: 'POST',
130
+ body: { ...options, operation: 'run', sandboxId, command },
131
+ }),
132
+ kill: (sandboxId) => request('/v1/engine/e2b', { method: 'POST', body: { operation: 'kill', sandboxId } }),
133
+ };
134
+
135
+ export const replicas = { integrations, plugins, linear, slack, github, gitlab, sentry, modal, pangram, planetscale, turbopuffer, e2b };
127
136
  export default replicas;
@@ -160,6 +160,29 @@ describe('@replicas/sdk', () => {
160
160
  server.stop(true);
161
161
  }
162
162
  });
163
+
164
+ test('runs E2B commands through the workspace gateway', async () => {
165
+ let observed: { path: string; body: unknown } | null = null;
166
+ const server = Bun.serve({
167
+ port: 0,
168
+ async fetch(request) {
169
+ observed = { path: new URL(request.url).pathname, body: await request.json() };
170
+ return Response.json({ exitCode: 0, stdout: 'ok\n', stderr: '' });
171
+ },
172
+ });
173
+ process.env.REPLICAS_MONOLITH_URL = server.url.toString().replace(/\/$/, '');
174
+ process.env.REPLICAS_ENGINE_SECRET = 'engine-secret';
175
+ process.env.REPLICAS_WORKSPACE_ID = 'workspace-1';
176
+ try {
177
+ await replicas.e2b.run('sandbox-1', 'echo ok', { cwd: '/home/user' });
178
+ expect(observed).toEqual({
179
+ path: '/v1/engine/e2b',
180
+ body: { operation: 'run', sandboxId: 'sandbox-1', command: 'echo ok', cwd: '/home/user' },
181
+ });
182
+ } finally {
183
+ server.stop(true);
184
+ }
185
+ });
163
186
  });
164
187
 
165
188
  test('analyzes text with Pangram through the workspace gateway', async () => {
@@ -28,6 +28,14 @@ export declare const PLUGIN_CATALOG: readonly [{
28
28
  readonly category: "data";
29
29
  readonly name: "Cloudflare";
30
30
  readonly description: "Manage zones, DNS records, analytics, and security settings.";
31
+ }, {
32
+ readonly id: "e2b";
33
+ readonly toolkit: "e2b";
34
+ readonly source: "native";
35
+ readonly authType: "api_key";
36
+ readonly category: "data";
37
+ readonly name: "E2B";
38
+ readonly description: "Create secure cloud sandboxes and run commands in them.";
31
39
  }, {
32
40
  readonly id: "gmail";
33
41
  readonly toolkit: "gmail";
@@ -202,6 +210,30 @@ export interface TurbopufferOperationRequest {
202
210
  namespace?: string;
203
211
  params?: Record<string, unknown>;
204
212
  }
213
+ export interface E2BCreateSandboxRequest {
214
+ template?: string;
215
+ timeoutMs?: number;
216
+ metadata?: Record<string, string>;
217
+ envs?: Record<string, string>;
218
+ }
219
+ export interface E2BRunCommandOptions {
220
+ cwd?: string;
221
+ envs?: Record<string, string>;
222
+ user?: string;
223
+ timeoutMs?: number;
224
+ }
225
+ export interface E2BCreateSandboxResponse {
226
+ sandboxId: string;
227
+ }
228
+ export interface E2BCommandResult {
229
+ exitCode: number;
230
+ error?: string;
231
+ stdout: string;
232
+ stderr: string;
233
+ }
234
+ export interface E2BKillSandboxResponse {
235
+ killed: boolean;
236
+ }
205
237
  export interface PluginConnectResponse {
206
238
  success: true;
207
239
  }
@@ -64,4 +64,9 @@ export interface ReplicasSdk {
64
64
  detect<T = unknown>(input: import('./routes/plugins').PangramAnalyzeRequest): Promise<T>;
65
65
  plagiarism<T = unknown>(text: string): Promise<T>;
66
66
  };
67
+ e2b: {
68
+ create(input?: import('./routes/plugins').E2BCreateSandboxRequest): Promise<import('./routes/plugins').E2BCreateSandboxResponse>;
69
+ run(sandboxId: string, command: string, options?: import('./routes/plugins').E2BRunCommandOptions): Promise<import('./routes/plugins').E2BCommandResult>;
70
+ kill(sandboxId: string): Promise<import('./routes/plugins').E2BKillSandboxResponse>;
71
+ };
67
72
  }