@better-agent/plugins 0.1.0-beta.2 → 0.1.0-beta.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.d.mts CHANGED
@@ -191,12 +191,19 @@ declare const rateLimitPlugin: (config: RateLimitPluginConfig) => Plugin;
191
191
  interface SandboxCreateParams {
192
192
  /** Template, snapshot, or image to create the sandbox from. */
193
193
  template?: string;
194
- /** Timeout in milliseconds. */
195
- timeoutMs?: number;
194
+ /** Maximum time to wait for the sandbox to become ready. */
195
+ startupTimeoutMs?: number;
196
196
  /** Environment variables for the sandbox. */
197
197
  envs?: Record<string, string>;
198
198
  /** Metadata or labels for the sandbox. */
199
199
  metadata?: Record<string, string>;
200
+ /** Shared lifecycle controls for the created sandbox. */
201
+ lifecycle?: {
202
+ /** Maximum lifetime for the sandbox. */ttlMs?: number; /** Stop the sandbox after this much inactivity. */
203
+ idleStopMs?: number; /** Archive the sandbox this long after it stops. */
204
+ archiveAfterMs?: number; /** Delete the sandbox this long after it stops. */
205
+ deleteAfterMs?: number;
206
+ };
200
207
  }
201
208
  /** Sandbox returned after creation. */
202
209
  interface SandboxInstance {
@@ -457,13 +464,15 @@ interface SandboxPluginConfig {
457
464
  * Return `null` or `undefined` to disable reuse for that call.
458
465
  */
459
466
  sessionKey?: (ctx: SandboxSessionKeyContext) => string | null | undefined;
460
- /** Default sandbox creation options. */
461
- defaults?: SandboxCreateParams;
467
+ /** Authoritative sandbox creation options that model overrides cannot overwrite. */
468
+ createConfig?: SandboxCreateParams;
469
+ /** Fallback sandbox creation options used only when createConfig and model overrides omit a field. */
470
+ createDefaults?: SandboxCreateParams;
462
471
  /** Approval settings for risky sandbox tools. */
463
472
  approvals?: SandboxToolApprovals;
464
473
  }
465
474
  /** Configuration for the built-in E2B sandbox client. */
466
- interface E2BSandboxClientConfig extends SandboxCreateParams {
475
+ interface E2BSandboxClientConfig {
467
476
  /** API key used to authenticate with E2B. */
468
477
  apiKey?: string;
469
478
  /** Access token used instead of an API key. */
@@ -474,7 +483,7 @@ interface E2BSandboxClientConfig extends SandboxCreateParams {
474
483
  requestTimeoutMs?: number;
475
484
  }
476
485
  /** Configuration for the Daytona sandbox client. */
477
- interface DaytonaSandboxClientConfig extends SandboxCreateParams {
486
+ interface DaytonaSandboxClientConfig {
478
487
  /** API key used to authenticate with Daytona. */
479
488
  apiKey?: string;
480
489
  /** Custom Daytona API base URL. */
@@ -483,28 +492,22 @@ interface DaytonaSandboxClientConfig extends SandboxCreateParams {
483
492
  target?: string;
484
493
  /** Default language or runtime. */
485
494
  language?: string;
486
- /** Explicit snapshot to create from. */
487
- snapshot?: string;
488
- /** Explicit image to create from. */
489
- image?: string;
490
495
  /** Whether previews should be public. */
491
496
  public?: boolean;
492
- /** Auto-stop interval in provider-defined units. */
493
- autoStopInterval?: number;
494
- /** Auto-archive interval in provider-defined units. */
495
- autoArchiveInterval?: number;
496
- /** Auto-delete interval in provider-defined units. */
497
- autoDeleteInterval?: number;
498
- /** For Daytona, whether `template` should be treated as a `snapshot` or `image`. */
497
+ /** For Daytona, how the shared sandbox template should be mapped. */
499
498
  templateKind?: "snapshot" | "image";
500
499
  }
501
500
  //#endregion
502
501
  //#region src/sandbox/daytona.d.ts
503
- /** Creates a sandbox client backed by the Daytona SDK. */
502
+ /**
503
+ * Creates a sandbox client backed by the Daytona SDK.
504
+ */
504
505
  declare function createDaytonaSandboxClient(config?: DaytonaSandboxClientConfig): SandboxClient;
505
506
  //#endregion
506
507
  //#region src/sandbox/e2b.d.ts
507
- /** Creates a sandbox client backed by the E2B SDK. */
508
+ /**
509
+ * Creates a sandbox client backed by the E2B SDK.
510
+ */
508
511
  declare function createE2BSandboxClient(config?: E2BSandboxClientConfig): SandboxClient;
509
512
  //#endregion
510
513
  //#region src/sandbox/memory-store.d.ts
@@ -529,14 +532,16 @@ declare function createMemorySandboxSessionStore(): SandboxSessionStore;
529
532
  * client: createE2BSandboxClient({
530
533
  * apiKey: process.env.E2B_API_KEY,
531
534
  * }),
532
- * defaults: {
535
+ * createConfig: {
533
536
  * template: "base",
534
- * timeoutMs: 10 * 60_000,
537
+ * },
538
+ * createDefaults: {
539
+ * startupTimeoutMs: 90_000,
535
540
  * },
536
541
  * });
537
542
  * ```
538
543
  */
539
- declare const sandboxPlugin: (config: SandboxPluginConfig) => Plugin;
544
+ declare const sandboxPlugin: (pluginConfig: SandboxPluginConfig) => Plugin;
540
545
  //#endregion
541
546
  export { AuthPluginConfig, type DaytonaSandboxClientConfig, type E2BSandboxClientConfig, IpAllowlistPluginConfig, LogEntry, LoggingPluginConfig, RateLimitBucket, RateLimitPluginConfig, RateLimitRequestContext, RateLimitStorageState, type SandboxCapabilities, type SandboxClient, type SandboxCommandParams, type SandboxCommandResult, type SandboxCreateParams, type SandboxDesktopClient, type SandboxFileEntry, type SandboxGetHostParams, type SandboxInstance, type SandboxKillParams, type SandboxLifecycleClient, type SandboxListFilesParams, type SandboxMakeDirParams, type SandboxPTYClient, type SandboxPluginConfig, type SandboxPreviewInfo, type SandboxReadFileParams, type SandboxRemovePathParams, type SandboxSessionKeyContext, type SandboxSessionStore, type SandboxToolApprovals, type SandboxWriteFileParams, authPlugin, createDaytonaSandboxClient, createE2BSandboxClient, createMemorySandboxSessionStore, ipAllowlistPlugin, loggingPlugin, rateLimitPlugin, sandboxPlugin };
542
547
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/auth/types.ts","../src/auth/plugin.ts","../src/ip-allowlist/types.ts","../src/ip-allowlist/plugin.ts","../src/logging/types.ts","../src/logging/plugin.ts","../src/rate-limit/types.ts","../src/rate-limit/plugin.ts","../src/sandbox/types.ts","../src/sandbox/daytona.ts","../src/sandbox/e2b.ts","../src/sandbox/memory-store.ts","../src/sandbox/plugin.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/auth/types.ts","../src/auth/plugin.ts","../src/ip-allowlist/types.ts","../src/ip-allowlist/plugin.ts","../src/logging/types.ts","../src/logging/plugin.ts","../src/rate-limit/types.ts","../src/rate-limit/plugin.ts","../src/sandbox/types.ts","../src/sandbox/daytona.ts","../src/sandbox/e2b.ts","../src/sandbox/memory-store.ts","../src/sandbox/plugin.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -722,27 +722,28 @@ const normalizeFileEntries = (files) => files.map((entry) => ({
722
722
  path: entry.path ?? entry.name ?? "",
723
723
  type: entry.type ?? (entry.isDir ? "directory" : "file")
724
724
  }));
725
- /** Creates a sandbox client backed by the Daytona SDK. */
725
+ /**
726
+ * Creates a sandbox client backed by the Daytona SDK.
727
+ */
726
728
  function createDaytonaSandboxClient(config = {}) {
727
729
  const clientConfig = removeUndefined$1({
728
730
  apiKey: config.apiKey,
729
731
  apiUrl: config.apiUrl,
730
732
  target: config.target
731
733
  });
734
+ const toProviderMinutes = (value) => value !== void 0 ? Math.max(1, Math.ceil(value / 6e4)) : void 0;
732
735
  const buildCreateParams = (overrides) => {
733
- const template = overrides?.template ?? config.template;
736
+ const template = overrides?.template;
734
737
  const templateKind = config.templateKind ?? "snapshot";
735
738
  return removeUndefined$1({
736
739
  language: config.language,
737
- envVars: overrides?.envs ?? config.envs,
738
- labels: overrides?.metadata ?? config.metadata,
740
+ envVars: overrides?.envs,
741
+ labels: overrides?.metadata,
739
742
  public: config.public,
740
- autoStopInterval: config.autoStopInterval,
741
- autoArchiveInterval: config.autoArchiveInterval,
742
- autoDeleteInterval: config.autoDeleteInterval,
743
- ...template !== void 0 ? templateKind === "image" ? { image: template } : { snapshot: template } : {},
744
- ...config.snapshot !== void 0 ? { snapshot: config.snapshot } : {},
745
- ...config.image !== void 0 ? { image: config.image } : {}
743
+ autoStopInterval: toProviderMinutes(overrides?.lifecycle?.idleStopMs),
744
+ autoArchiveInterval: toProviderMinutes(overrides?.lifecycle?.archiveAfterMs),
745
+ autoDeleteInterval: toProviderMinutes(overrides?.lifecycle?.deleteAfterMs),
746
+ ...template !== void 0 ? templateKind === "image" ? { image: template } : { snapshot: template } : {}
746
747
  });
747
748
  };
748
749
  const getClient = async () => {
@@ -780,7 +781,7 @@ function createDaytonaSandboxClient(config = {}) {
780
781
  },
781
782
  async createSandbox(params) {
782
783
  const client = await getClient();
783
- const timeout = toSeconds(params?.timeoutMs ?? config.timeoutMs);
784
+ const timeout = toSeconds(params?.startupTimeoutMs);
784
785
  return { sandboxId: (await client.create(buildCreateParams(params), { ...timeout !== void 0 ? { timeout } : {} })).id };
785
786
  },
786
787
  async runCommand(params) {
@@ -874,7 +875,9 @@ const loadE2B = async () => {
874
875
  });
875
876
  }
876
877
  };
877
- /** Creates a sandbox client backed by the E2B SDK. */
878
+ /**
879
+ * Creates a sandbox client backed by the E2B SDK.
880
+ */
878
881
  function createE2BSandboxClient(config = {}) {
879
882
  const connectionOptions = removeUndefined({
880
883
  apiKey: config.apiKey,
@@ -882,11 +885,11 @@ function createE2BSandboxClient(config = {}) {
882
885
  domain: config.domain,
883
886
  requestTimeoutMs: config.requestTimeoutMs
884
887
  });
885
- const toCreateOptions = (overrides) => removeUndefined({
888
+ const toCreateOptions = (params) => removeUndefined({
886
889
  ...connectionOptions,
887
- timeoutMs: overrides?.timeoutMs ?? config.timeoutMs,
888
- envs: overrides?.envs ?? config.envs,
889
- metadata: overrides?.metadata ?? config.metadata
890
+ timeoutMs: params?.lifecycle?.ttlMs,
891
+ envs: params?.envs,
892
+ metadata: params?.metadata
890
893
  });
891
894
  const connectSandbox = async (sandboxId) => {
892
895
  const { Sandbox } = await loadE2B();
@@ -910,7 +913,7 @@ function createE2BSandboxClient(config = {}) {
910
913
  },
911
914
  async createSandbox(params) {
912
915
  const { Sandbox } = await loadE2B();
913
- const template = params?.template ?? config.template;
916
+ const template = params?.template;
914
917
  const options = toCreateOptions(params);
915
918
  return { sandboxId: (template !== void 0 ? await Sandbox.create(template, options) : await Sandbox.create(options)).sandboxId };
916
919
  },
@@ -965,11 +968,28 @@ function createMemorySandboxSessionStore() {
965
968
 
966
969
  //#endregion
967
970
  //#region src/sandbox/validate.ts
971
+ const hasLifecycleValues = (lifecycle) => Boolean(lifecycle?.ttlMs !== void 0 || lifecycle?.idleStopMs !== void 0 || lifecycle?.archiveAfterMs !== void 0 || lifecycle?.deleteAfterMs !== void 0);
972
+ function validateSandboxCreateParams(clientProvider, params) {
973
+ const provider = clientProvider?.trim().toLowerCase();
974
+ if (!provider) return;
975
+ if (provider === "daytona") {
976
+ if (params.lifecycle?.ttlMs !== void 0) throw createValidationError$1("`lifecycle.ttlMs` is not supported by the Daytona sandbox client. Use `startupTimeoutMs` for creation readiness and Daytona lifecycle fields like `idleStopMs`, `archiveAfterMs`, or `deleteAfterMs` instead.", "plugins.sandboxPlugin.createConfig.lifecycle.ttlMs");
977
+ return;
978
+ }
979
+ if (provider === "e2b") {
980
+ if (params.startupTimeoutMs !== void 0) throw createValidationError$1("`startupTimeoutMs` is not supported by the E2B sandbox client. Use `lifecycle.ttlMs` to control sandbox lifetime.", "plugins.sandboxPlugin.createConfig.startupTimeoutMs");
981
+ if (params.lifecycle?.idleStopMs !== void 0 || params.lifecycle?.archiveAfterMs !== void 0 || params.lifecycle?.deleteAfterMs !== void 0) throw createValidationError$1("`lifecycle.idleStopMs`, `lifecycle.archiveAfterMs`, and `lifecycle.deleteAfterMs` are not supported by the E2B sandbox client.", "plugins.sandboxPlugin.createConfig.lifecycle");
982
+ return;
983
+ }
984
+ if (hasLifecycleValues(params.lifecycle) || params.startupTimeoutMs !== void 0) return;
985
+ }
968
986
  /** Validates `sandboxPlugin` configuration. */
969
987
  function validateSandboxPluginConfig(config) {
970
988
  const client = config.client;
971
989
  if (!client || typeof client !== "object") throw createValidationError$1("`sandboxPlugin` requires a `client`.", "plugins.sandboxPlugin");
972
990
  if (config.prefix !== void 0 && config.prefix.trim().length === 0) throw createValidationError$1("`sandboxPlugin` requires `prefix` to be a non-empty string when provided.", "plugins.sandboxPlugin");
991
+ if (config.createConfig) validateSandboxCreateParams(config.client.provider, config.createConfig);
992
+ if (config.createDefaults) validateSandboxCreateParams(config.client.provider, config.createDefaults);
973
993
  }
974
994
 
975
995
  //#endregion
@@ -983,6 +1003,25 @@ const createValidationError = (message, at, context) => BetterAgentError.fromCod
983
1003
  ...context !== void 0 ? { context } : {},
984
1004
  trace: [{ at }]
985
1005
  });
1006
+ const resolveCreateParams = (overrides, createConfig, createDefaults) => ({
1007
+ template: createConfig?.template ?? overrides?.template ?? createDefaults?.template,
1008
+ startupTimeoutMs: createConfig?.startupTimeoutMs ?? overrides?.startupTimeoutMs ?? createDefaults?.startupTimeoutMs,
1009
+ envs: createDefaults?.envs || overrides?.envs || createConfig?.envs ? {
1010
+ ...createDefaults?.envs ?? {},
1011
+ ...overrides?.envs ?? {},
1012
+ ...createConfig?.envs ?? {}
1013
+ } : void 0,
1014
+ metadata: createDefaults?.metadata || overrides?.metadata || createConfig?.metadata ? {
1015
+ ...createDefaults?.metadata ?? {},
1016
+ ...overrides?.metadata ?? {},
1017
+ ...createConfig?.metadata ?? {}
1018
+ } : void 0,
1019
+ lifecycle: createDefaults?.lifecycle || overrides?.lifecycle || createConfig?.lifecycle ? {
1020
+ ...createDefaults?.lifecycle ?? {},
1021
+ ...overrides?.lifecycle ?? {},
1022
+ ...createConfig?.lifecycle ?? {}
1023
+ } : void 0
1024
+ });
986
1025
  /**
987
1026
  * Adds sandbox tools.
988
1027
  *
@@ -1000,22 +1039,24 @@ const createValidationError = (message, at, context) => BetterAgentError.fromCod
1000
1039
  * client: createE2BSandboxClient({
1001
1040
  * apiKey: process.env.E2B_API_KEY,
1002
1041
  * }),
1003
- * defaults: {
1042
+ * createConfig: {
1004
1043
  * template: "base",
1005
- * timeoutMs: 10 * 60_000,
1044
+ * },
1045
+ * createDefaults: {
1046
+ * startupTimeoutMs: 90_000,
1006
1047
  * },
1007
1048
  * });
1008
1049
  * ```
1009
1050
  */
1010
- const sandboxPlugin = (config) => {
1011
- validateSandboxPluginConfig(config);
1012
- const sandboxClient = config.client;
1013
- const store = config.store ?? createMemorySandboxSessionStore();
1014
- const prefix = trimToUndefined(config.prefix) ?? "sandbox";
1051
+ const sandboxPlugin = (pluginConfig) => {
1052
+ validateSandboxPluginConfig(pluginConfig);
1053
+ const sandboxClient = pluginConfig.client;
1054
+ const store = pluginConfig.store ?? createMemorySandboxSessionStore();
1055
+ const prefix = trimToUndefined(pluginConfig.prefix) ?? "sandbox";
1015
1056
  const nameFor = (suffix) => `${prefix}_${suffix}`;
1016
1057
  const getSessionPolicy = (ctx, toolName) => {
1017
- if (config.sessionKey) {
1018
- const custom = trimToUndefined(config.sessionKey({
1058
+ if (pluginConfig.sessionKey) {
1059
+ const custom = trimToUndefined(pluginConfig.sessionKey({
1019
1060
  runId: ctx.runId,
1020
1061
  agentName: ctx.agentName,
1021
1062
  ...ctx.conversationId !== void 0 ? { conversationId: ctx.conversationId } : {},
@@ -1039,12 +1080,9 @@ const sandboxPlugin = (config) => {
1039
1080
  };
1040
1081
  const createSandbox = async (params, ctx, toolName) => {
1041
1082
  const sessionPolicy = getSessionPolicy(ctx, toolName);
1042
- const created = await sandboxClient.createSandbox({
1043
- template: params?.template ?? config.defaults?.template,
1044
- timeoutMs: params?.timeoutMs ?? config.defaults?.timeoutMs,
1045
- envs: params?.envs ?? config.defaults?.envs,
1046
- metadata: params?.metadata ?? config.defaults?.metadata
1047
- });
1083
+ const resolvedParams = resolveCreateParams(params, pluginConfig.createConfig, pluginConfig.createDefaults);
1084
+ validateSandboxCreateParams(sandboxClient.provider, resolvedParams);
1085
+ const created = await sandboxClient.createSandbox(resolvedParams);
1048
1086
  if (sessionPolicy.kind === "managed") await store.set(sessionPolicy.sessionKey, created.sandboxId);
1049
1087
  return {
1050
1088
  sandboxId: created.sandboxId,
@@ -1088,7 +1126,7 @@ const sandboxPlugin = (config) => {
1088
1126
  properties: {
1089
1127
  forceNew: { type: "boolean" },
1090
1128
  template: { type: "string" },
1091
- timeoutMs: {
1129
+ startupTimeoutMs: {
1092
1130
  type: "number",
1093
1131
  exclusiveMinimum: 0
1094
1132
  },
@@ -1099,6 +1137,28 @@ const sandboxPlugin = (config) => {
1099
1137
  metadata: {
1100
1138
  type: "object",
1101
1139
  additionalProperties: { type: "string" }
1140
+ },
1141
+ lifecycle: {
1142
+ type: "object",
1143
+ properties: {
1144
+ ttlMs: {
1145
+ type: "number",
1146
+ exclusiveMinimum: 0
1147
+ },
1148
+ idleStopMs: {
1149
+ type: "number",
1150
+ exclusiveMinimum: 0
1151
+ },
1152
+ archiveAfterMs: {
1153
+ type: "number",
1154
+ exclusiveMinimum: 0
1155
+ },
1156
+ deleteAfterMs: {
1157
+ type: "number",
1158
+ exclusiveMinimum: 0
1159
+ }
1160
+ },
1161
+ additionalProperties: false
1102
1162
  }
1103
1163
  },
1104
1164
  additionalProperties: false
@@ -1128,9 +1188,10 @@ const sandboxPlugin = (config) => {
1128
1188
  }
1129
1189
  const resolved = await createSandbox({
1130
1190
  template: input.template,
1131
- timeoutMs: input.timeoutMs,
1191
+ startupTimeoutMs: input.startupTimeoutMs,
1132
1192
  envs: input.envs,
1133
- metadata: input.metadata
1193
+ metadata: input.metadata,
1194
+ lifecycle: input.lifecycle
1134
1195
  }, ctx, nameFor("create"));
1135
1196
  return {
1136
1197
  sandboxId: resolved.sandboxId,
@@ -1163,7 +1224,7 @@ const sandboxPlugin = (config) => {
1163
1224
  required: ["cmd"],
1164
1225
  additionalProperties: false
1165
1226
  },
1166
- approval: config.approvals?.exec
1227
+ approval: pluginConfig.approvals?.exec
1167
1228
  }).server(async (input, ctx) => {
1168
1229
  const resolved = await resolveSandbox({
1169
1230
  sandboxId: input.sandboxId,
@@ -1225,7 +1286,7 @@ const sandboxPlugin = (config) => {
1225
1286
  required: ["path", "content"],
1226
1287
  additionalProperties: false
1227
1288
  },
1228
- approval: config.approvals?.writeFile
1289
+ approval: pluginConfig.approvals?.writeFile
1229
1290
  }).server(async (input, ctx) => {
1230
1291
  const resolved = await resolveSandbox({
1231
1292
  sandboxId: input.sandboxId,
@@ -1313,7 +1374,7 @@ const sandboxPlugin = (config) => {
1313
1374
  required: ["path"],
1314
1375
  additionalProperties: false
1315
1376
  },
1316
- approval: config.approvals?.removePath
1377
+ approval: pluginConfig.approvals?.removePath
1317
1378
  }).server(async (input, ctx) => {
1318
1379
  const resolved = await resolveSandbox({
1319
1380
  sandboxId: input.sandboxId,
@@ -1375,7 +1436,7 @@ const sandboxPlugin = (config) => {
1375
1436
  properties: { sandboxId: sandboxIdSchema },
1376
1437
  additionalProperties: false
1377
1438
  },
1378
- approval: config.approvals?.killSandbox
1439
+ approval: pluginConfig.approvals?.killSandbox
1379
1440
  }).server(async (input, ctx) => {
1380
1441
  const resolved = await resolveSandbox({
1381
1442
  sandboxId: input.sandboxId,
@@ -1393,7 +1454,7 @@ const sandboxPlugin = (config) => {
1393
1454
  })
1394
1455
  ];
1395
1456
  return {
1396
- id: config.id ?? "sandbox",
1457
+ id: pluginConfig.id ?? "sandbox",
1397
1458
  tools
1398
1459
  };
1399
1460
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["createValidationError","createValidationError","createValidationError","removeUndefined","createValidationError"],"sources":["../src/shared/json.ts","../src/auth/responses.ts","../src/shared/validation.ts","../src/auth/validate.ts","../src/auth/plugin.ts","../src/ip-allowlist/ip.ts","../src/ip-allowlist/cidr.ts","../src/ip-allowlist/responses.ts","../src/ip-allowlist/validate.ts","../src/ip-allowlist/plugin.ts","../src/logging/format.ts","../src/logging/redact.ts","../src/logging/validate.ts","../src/logging/plugin.ts","../src/rate-limit/bucket.ts","../src/rate-limit/memory-store.ts","../src/rate-limit/responses.ts","../src/rate-limit/validate.ts","../src/rate-limit/plugin.ts","../src/sandbox/daytona.ts","../src/sandbox/e2b.ts","../src/sandbox/memory-store.ts","../src/sandbox/validate.ts","../src/sandbox/plugin.ts"],"sourcesContent":["/** Creates a JSON response with a default content type. */\nexport function jsonResponse(body: unknown, init?: ResponseInit): Response {\n const headers = new Headers(init?.headers);\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n","import { jsonResponse } from \"../shared/json\";\n\n/** Creates the default unauthorized response. */\nexport function createUnauthorizedResponse(): Response {\n return jsonResponse(\n {\n error: \"unauthorized\",\n message: \"Invalid API key.\",\n },\n { status: 401 },\n );\n}\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\n\n/** Creates a plugin validation error. */\nexport function createValidationError(message: string, at: string): BetterAgentError {\n return BetterAgentError.fromCode(\"VALIDATION_FAILED\", message, {\n trace: [{ at }],\n });\n}\n\n/** Requires a positive finite number. */\nexport function requirePositiveNumber(value: number, name: string, at: string): void {\n if (!Number.isFinite(value) || value <= 0) {\n throw createValidationError(`\\`${name}\\` must be a positive number.`, at);\n }\n}\n\n/** Requires a non-empty array. */\nexport function requireNonEmptyArray<T>(\n value: readonly T[] | undefined,\n name: string,\n at: string,\n): asserts value is readonly T[] {\n if (!value || value.length === 0) {\n throw createValidationError(`\\`${name}\\` must contain at least one value.`, at);\n }\n}\n","import { createValidationError } from \"../shared/validation\";\nimport type { AuthPluginConfig } from \"./types\";\n\n/** Validates `authPlugin` configuration. */\nexport function validateAuthPluginConfig(config: AuthPluginConfig): void {\n if (!config.validate && (!config.apiKeys || config.apiKeys.length === 0)) {\n throw createValidationError(\n \"`authPlugin` requires either `apiKeys` or `validate`.\",\n \"plugins.authPlugin\",\n );\n }\n\n if (config.header !== undefined && config.header.trim().length === 0) {\n throw createValidationError(\n \"`authPlugin` requires `header` to be a non-empty string when provided.\",\n \"plugins.authPlugin\",\n );\n }\n\n if (config.apiKeys) {\n const normalized = config.apiKeys\n .filter((key): key is string => typeof key === \"string\")\n .map((key) => key.trim())\n .filter((key) => key.length > 0);\n\n if (normalized.length === 0 && !config.validate) {\n throw createValidationError(\n \"`authPlugin` requires `apiKeys` to contain at least one non-empty key.\",\n \"plugins.authPlugin\",\n );\n }\n }\n}\n","import type { Plugin } from \"@better-agent/core\";\nimport { createUnauthorizedResponse } from \"./responses\";\nimport type { AuthPluginConfig } from \"./types\";\nimport { validateAuthPluginConfig } from \"./validate\";\n\n/**\n * Creates an API-key auth plugin.\n *\n * Provide either `apiKeys` or `validate`.\n *\n * @example\n * ```ts\n * const plugin = authPlugin({\n * apiKeys: [\"dev-key\"],\n * });\n * ```\n */\nexport const authPlugin = (config: AuthPluginConfig): Plugin => {\n validateAuthPluginConfig(config);\n\n const header = config.header?.trim() || \"x-api-key\";\n const apiKeys = new Set((config.apiKeys ?? []).map((key) => key.trim()).filter(Boolean));\n\n return {\n id: config.id ?? \"auth\",\n guards: [\n async (ctx) => {\n const keyValue = config.getKey\n ? await config.getKey({\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : ctx.request.headers.get(header);\n\n const key =\n typeof keyValue === \"string\" && keyValue.trim().length > 0 ? keyValue : null;\n\n const valid = config.validate\n ? await config.validate({\n key,\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : key !== null && apiKeys.has(key);\n\n if (valid) {\n return null;\n }\n\n return config.onUnauthorized\n ? await config.onUnauthorized({\n key,\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : createUnauthorizedResponse();\n },\n ],\n };\n};\n","/** Parsed IP value. */\ntype ParsedIp = {\n /** IP family. */\n kind: \"ipv4\" | \"ipv6\";\n /** Numeric IP value. */\n value: bigint;\n /** Bit width for the IP family. */\n bits: number;\n /** Normalized string form. */\n normalized: string;\n};\n\n/** Parses an IPv4 string. */\nfunction parseIpv4(input: string): ParsedIp | null {\n const parts = input.split(\".\");\n if (parts.length !== 4) return null;\n\n let value = 0n;\n for (const part of parts) {\n if (!/^\\d+$/.test(part)) return null;\n const octet = Number(part);\n if (octet < 0 || octet > 255) return null;\n value = (value << 8n) | BigInt(octet);\n }\n\n return {\n kind: \"ipv4\",\n value,\n bits: 32,\n normalized: parts.join(\".\"),\n };\n}\n\n/** Expands an IPv6 string into eight normalized segments. */\nfunction expandIpv6Segments(input: string): string[] | null {\n const zoneIndex = input.indexOf(\"%\");\n const value = zoneIndex >= 0 ? input.slice(0, zoneIndex) : input;\n if (value.length === 0) return null;\n\n const doubleColonCount = value.split(\"::\").length - 1;\n if (doubleColonCount > 1) return null;\n\n const [leftRaw = \"\", rightRaw = \"\"] = value.split(\"::\");\n const left = leftRaw.length > 0 ? leftRaw.split(\":\") : [];\n const right = rightRaw.length > 0 ? rightRaw.split(\":\") : [];\n\n const normalizedRight = [...right];\n if (normalizedRight.length > 0) {\n const last = normalizedRight[normalizedRight.length - 1];\n if (last?.includes(\".\")) {\n const ipv4 = parseIpv4(last);\n if (!ipv4) return null;\n normalizedRight.splice(\n normalizedRight.length - 1,\n 1,\n Number((ipv4.value >> 16n) & 0xffffn).toString(16),\n Number(ipv4.value & 0xffffn).toString(16),\n );\n }\n }\n\n const normalizedLeft = [...left];\n if (normalizedLeft.length > 0) {\n const last = normalizedLeft[normalizedLeft.length - 1];\n if (last?.includes(\".\")) {\n const ipv4 = parseIpv4(last);\n if (!ipv4) return null;\n normalizedLeft.splice(\n normalizedLeft.length - 1,\n 1,\n Number((ipv4.value >> 16n) & 0xffffn).toString(16),\n Number(ipv4.value & 0xffffn).toString(16),\n );\n }\n }\n\n const totalSegments = normalizedLeft.length + normalizedRight.length;\n if (doubleColonCount === 0 && totalSegments !== 8) return null;\n if (doubleColonCount === 1 && totalSegments >= 8) return null;\n\n const missing = doubleColonCount === 1 ? 8 - totalSegments : 0;\n const segments = [\n ...normalizedLeft,\n ...Array.from({ length: missing }, () => \"0\"),\n ...normalizedRight,\n ];\n\n if (segments.length !== 8) return null;\n if (segments.some((segment) => !/^[0-9a-fA-F]{1,4}$/.test(segment))) return null;\n\n return segments.map((segment) => segment.toLowerCase());\n}\n\n/** Parses an IPv6 string. */\nfunction parseIpv6(input: string): ParsedIp | null {\n const segments = expandIpv6Segments(input);\n if (!segments) return null;\n\n let value = 0n;\n for (const segment of segments) {\n value = (value << 16n) | BigInt(Number.parseInt(segment, 16));\n }\n\n return {\n kind: \"ipv6\",\n value,\n bits: 128,\n normalized: segments.join(\":\"),\n };\n}\n\n/** Parses an IPv4 or IPv6 string. */\nexport function parseIp(input: string): ParsedIp | null {\n const value = input.trim();\n if (value.length === 0) return null;\n return parseIpv4(value) ?? parseIpv6(value);\n}\n\n/** Normalizes an IP string. */\nexport function normalizeIp(input: string): string | null {\n return parseIp(input)?.normalized ?? null;\n}\n\nexport type { ParsedIp };\n","import { type ParsedIp, parseIp } from \"./ip\";\n\n/** Matcher for one allowed IP entry. */\nexport type IpMatcher = {\n /** Original allowlist entry. */\n raw: string;\n /** Returns true when the IP matches this entry. */\n matches: (ip: ParsedIp) => boolean;\n};\n\n/** Creates a network mask for the given prefix. */\nfunction createMask(bits: number, prefix: number): bigint {\n if (prefix === 0) return 0n;\n return ((1n << BigInt(prefix)) - 1n) << BigInt(bits - prefix);\n}\n\n/** Parses one allowlist IP or CIDR entry. */\nexport function parseAllowEntry(input: string): IpMatcher | null {\n const raw = input.trim();\n if (raw.length === 0) return null;\n\n const slashIndex = raw.indexOf(\"/\");\n if (slashIndex === -1) {\n const parsed = parseIp(raw);\n if (!parsed) return null;\n return {\n raw,\n matches: (ip) => ip.kind === parsed.kind && ip.value === parsed.value,\n };\n }\n\n const addressPart = raw.slice(0, slashIndex).trim();\n const prefixPart = raw.slice(slashIndex + 1).trim();\n if (!/^\\d+$/.test(prefixPart)) return null;\n\n const parsed = parseIp(addressPart);\n if (!parsed) return null;\n\n const prefix = Number(prefixPart);\n if (prefix < 0 || prefix > parsed.bits) return null;\n\n const mask = createMask(parsed.bits, prefix);\n const network = parsed.value & mask;\n\n return {\n raw,\n matches: (ip) => ip.kind === parsed.kind && (ip.value & mask) === network,\n };\n}\n","import { jsonResponse } from \"../shared/json\";\n\n/** Creates the default IP denied response. */\nexport function createIpDeniedResponse(): Response {\n return jsonResponse(\n {\n error: \"forbidden\",\n message: \"IP address is not allowed.\",\n },\n { status: 403 },\n );\n}\n","import { createValidationError, requireNonEmptyArray } from \"../shared/validation\";\nimport { parseAllowEntry } from \"./cidr\";\nimport type { IpAllowlistPluginConfig } from \"./types\";\n\n/** Validates `ipAllowlistPlugin` configuration. */\nexport function validateIpAllowlistPluginConfig(config: IpAllowlistPluginConfig): void {\n requireNonEmptyArray(config.allow, \"allow\", \"plugins.ipAllowlistPlugin\");\n\n for (const entry of config.allow) {\n if (typeof entry !== \"string\" || !parseAllowEntry(entry)) {\n throw createValidationError(\n `\\`ipAllowlistPlugin\\` received an invalid allow entry: '${String(entry)}'.`,\n \"plugins.ipAllowlistPlugin\",\n );\n }\n }\n}\n","import type { Plugin } from \"@better-agent/core\";\nimport { parseAllowEntry } from \"./cidr\";\nimport { normalizeIp, parseIp } from \"./ip\";\nimport { createIpDeniedResponse } from \"./responses\";\nimport type { IpAllowlistPluginConfig } from \"./types\";\nimport { validateIpAllowlistPluginConfig } from \"./validate\";\n\n/** Reads the first valid forwarded IP. */\nfunction getProxyIp(request: Request): string | null {\n const forwardedFor = request.headers.get(\"x-forwarded-for\");\n if (!forwardedFor) return null;\n\n for (const part of forwardedFor.split(\",\")) {\n const normalized = normalizeIp(part.trim());\n if (normalized) {\n return normalized;\n }\n }\n\n return null;\n}\n\n/** Reads a direct client IP from common proxy headers. */\nfunction getDirectIp(request: Request): string | null {\n const candidates = [\n request.headers.get(\"x-real-ip\"),\n request.headers.get(\"cf-connecting-ip\"),\n request.headers.get(\"fly-client-ip\"),\n request.headers.get(\"fastly-client-ip\"),\n request.headers.get(\"x-client-ip\"),\n ];\n\n for (const candidate of candidates) {\n if (!candidate) continue;\n const normalized = normalizeIp(candidate);\n if (normalized) {\n return normalized;\n }\n }\n\n return null;\n}\n\n/**\n * Creates an IP allowlist plugin.\n *\n * @example\n * ```ts\n * const plugin = ipAllowlistPlugin({\n * allow: [\"127.0.0.1\", \"10.0.0.0/8\"],\n * });\n * ```\n */\nexport const ipAllowlistPlugin = (config: IpAllowlistPluginConfig): Plugin => {\n validateIpAllowlistPluginConfig(config);\n\n const matchers = config.allow.map((entry) => {\n const matcher = parseAllowEntry(entry);\n if (!matcher) {\n throw new Error(`Invalid allowlist entry: ${entry}`);\n }\n return matcher;\n });\n\n return {\n id: config.id ?? \"ip-allowlist\",\n guards: [\n async (ctx) => {\n const resolvedIp = config.getIp\n ? await config.getIp({\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : config.trustProxy\n ? getProxyIp(ctx.request)\n : getDirectIp(ctx.request);\n\n const normalizedIp =\n typeof resolvedIp === \"string\" && resolvedIp.trim().length > 0\n ? normalizeIp(resolvedIp)\n : null;\n const parsedIp = normalizedIp ? parseIp(normalizedIp) : null;\n\n if (parsedIp && matchers.some((matcher) => matcher.matches(parsedIp))) {\n return null;\n }\n\n return config.onDenied\n ? await config.onDenied({\n ip: normalizedIp,\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : createIpDeniedResponse();\n },\n ],\n };\n};\n","import type { LogEntry, LoggingPluginConfig } from \"./types\";\n\nconst order: Record<LogEntry[\"level\"], number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\n/** Returns true when the entry should be logged at the current level. */\nexport function shouldLog(\n currentLevel: NonNullable<LoggingPluginConfig[\"level\"]>,\n entry: LogEntry,\n): boolean {\n return order[entry.level] >= order[currentLevel];\n}\n","const DEFAULT_REDACT_HEADERS = [\"authorization\", \"cookie\", \"set-cookie\", \"x-api-key\"] as const;\n\n/** Redacts sensitive headers. */\nexport function redactHeaders(\n headers: Headers,\n extraHeaders?: readonly string[],\n): Record<string, string> {\n const redactSet = new Set(\n [...DEFAULT_REDACT_HEADERS, ...(extraHeaders ?? [])].map((value) => value.toLowerCase()),\n );\n const result: Record<string, string> = {};\n\n headers.forEach((value, key) => {\n result[key] = redactSet.has(key.toLowerCase()) ? \"[REDACTED]\" : value;\n });\n\n return result;\n}\n","import type { LoggingPluginConfig } from \"./types\";\n\n/** Validates `loggingPlugin` configuration. */\nexport function validateLoggingPluginConfig(_config: LoggingPluginConfig): void {}\n","import type { Plugin } from \"@better-agent/core\";\nimport type { PluginOnStepContext, PluginSaveContext } from \"@better-agent/core\";\nimport type { Event } from \"@better-agent/core/events\";\nimport { shouldLog } from \"./format\";\nimport { redactHeaders } from \"./redact\";\nimport type { LogEntry, LoggingPluginConfig } from \"./types\";\nimport { validateLoggingPluginConfig } from \"./validate\";\n\nfunction safeInvoke(fn: ((...args: unknown[]) => void) | undefined, payload: unknown): void {\n if (!fn) return;\n try {\n fn(payload);\n } catch {\n // Logging must never affect runtime execution.\n }\n}\n\n/** Resolves the logger methods for the configured sink. */\nfunction getLoggerMethods(config: LoggingPluginConfig) {\n return {\n debug: config.logger?.debug ?? console.debug,\n info: config.logger?.info ?? console.info,\n warn: config.logger?.warn ?? console.warn,\n error: config.logger?.error ?? console.error,\n };\n}\n\n/** Emits one log entry. */\nfunction emitLog(config: LoggingPluginConfig, entry: LogEntry): void {\n const level = config.level ?? \"info\";\n if (!shouldLog(level, entry)) return;\n\n const output = config.format ? config.format(entry) : entry;\n const logger = getLoggerMethods(config);\n safeInvoke(logger[entry.level], output);\n}\n\n/** Maps one runtime event to a log level. */\nfunction getEventLevel(event: Event): LogEntry[\"level\"] {\n if (event.type.endsWith(\"_ERROR\")) return \"error\";\n return \"info\";\n}\n\n/** Creates request log data. */\nfunction createRequestData(ctx: Parameters<NonNullable<Plugin[\"guards\"]>[number]>[0]) {\n return {\n mode: ctx.mode,\n url: ctx.request.url,\n method: ctx.request.method,\n headers: redactHeaders(ctx.request.headers),\n input: ctx.input,\n };\n}\n\n/** Creates step log data. */\nfunction createStepData(ctx: PluginOnStepContext) {\n return {\n stepIndex: ctx.stepIndex,\n maxSteps: ctx.maxSteps,\n messageCount: ctx.messages.length,\n };\n}\n\n/** Creates save log data. */\nfunction createSaveData(ctx: PluginSaveContext) {\n const messageCount = ctx.items.filter((item) => item.type === \"message\").length;\n\n return {\n itemCount: ctx.items.length,\n messageCount,\n };\n}\n\n/**\n * Creates a logging plugin.\n *\n * @example\n * ```ts\n * const plugin = loggingPlugin({\n * level: \"info\",\n * include: { requests: true, toolCalls: true },\n * });\n * ```\n */\nexport const loggingPlugin = (config: LoggingPluginConfig = {}): Plugin => {\n validateLoggingPluginConfig(config);\n\n const include = {\n requests: config.include?.requests ?? true,\n events: config.include?.events ?? true,\n steps: config.include?.steps ?? true,\n modelCalls: config.include?.modelCalls ?? true,\n toolCalls: config.include?.toolCalls ?? true,\n saves: config.include?.saves ?? false,\n errors: config.include?.errors ?? true,\n };\n\n const plugin: Plugin = {\n id: config.id ?? \"logging\",\n };\n\n if (include.requests) {\n plugin.guards = [\n async (ctx) => {\n const body = config.redactBody\n ? config.redactBody({ body: ctx.input, phase: \"request\" })\n : ctx.input;\n\n emitLog(config, {\n level: \"info\",\n event: \"request.received\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n data: {\n ...createRequestData(ctx),\n input: body,\n },\n });\n\n return null;\n },\n ];\n }\n\n if (include.events) {\n plugin.onEvent = async (event, ctx) => {\n const level = getEventLevel(event);\n if (level === \"error\" && !include.errors) return;\n\n emitLog(config, {\n level,\n event: \"run.event\",\n timestamp: new Date(event.timestamp).toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n type: event.type,\n },\n });\n };\n }\n\n if (include.steps) {\n plugin.onStep = async (ctx) => {\n emitLog(config, {\n level: \"info\",\n event: \"step.start\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: createStepData(ctx),\n });\n };\n }\n\n if (include.modelCalls) {\n plugin.onBeforeModelCall = async (ctx) => {\n emitLog(config, {\n level: \"debug\",\n event: \"model.before\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n stepIndex: ctx.stepIndex,\n inputCount: ctx.input.length,\n toolCount: ctx.tools.length,\n toolChoice: ctx.toolChoice,\n },\n });\n };\n\n plugin.onAfterModelCall = async (ctx) => {\n emitLog(config, {\n level: \"debug\",\n event: \"model.after\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n stepIndex: ctx.stepIndex,\n response: config.redactBody\n ? config.redactBody({ body: ctx.response, phase: \"response\" })\n : ctx.response,\n },\n });\n };\n }\n\n if (include.toolCalls) {\n plugin.onBeforeToolCall = async (ctx) => {\n emitLog(config, {\n level: \"info\",\n event: \"tool.before\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n toolName: ctx.toolName,\n toolCallId: ctx.toolCallId,\n args: config.redactBody\n ? config.redactBody({ body: ctx.args, phase: \"tool_args\" })\n : ctx.args,\n },\n });\n return undefined;\n };\n\n plugin.onAfterToolCall = async (ctx) => {\n emitLog(config, {\n level: ctx.error ? \"error\" : \"info\",\n event: \"tool.after\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n toolName: ctx.toolName,\n toolCallId: ctx.toolCallId,\n error: ctx.error,\n result: config.redactBody\n ? config.redactBody({ body: ctx.result, phase: \"tool_result\" })\n : ctx.result,\n },\n });\n };\n }\n\n if (include.saves) {\n plugin.onBeforeSave = async (ctx) => {\n emitLog(config, {\n level: \"debug\",\n event: \"save.before\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n ...createSaveData(ctx),\n items: config.redactBody\n ? config.redactBody({ body: ctx.items, phase: \"save\" })\n : ctx.items,\n },\n });\n };\n }\n\n return plugin;\n};\n","import type { RateLimitBucket } from \"./types\";\n\n/** Creates a rate-limit bucket for the current window. */\nexport function createBucket(params: {\n key: string;\n now: Date;\n windowMs: number;\n}): RateLimitBucket {\n const nowMs = params.now.getTime();\n const windowStartMs = Math.floor(nowMs / params.windowMs) * params.windowMs;\n\n return {\n id: `${windowStartMs}:${params.key}`,\n key: params.key,\n now: params.now,\n windowStart: new Date(windowStartMs),\n windowEnd: new Date(windowStartMs + params.windowMs),\n };\n}\n","import type { RateLimitPluginConfig, RateLimitStorageState } from \"./types\";\n\n/** Creates an in-memory CAS store for rate limiting. */\nexport function createMemoryStore(): NonNullable<RateLimitPluginConfig[\"storage\"]> {\n const rows = new Map<string, RateLimitStorageState>();\n\n return {\n read: async ({ bucket }) => rows.get(bucket.id) ?? null,\n write: async ({ bucket, prevVersion, next }) => {\n const current = rows.get(bucket.id) ?? null;\n if (prevVersion === null) {\n if (current) return false;\n rows.set(bucket.id, next);\n return true;\n }\n\n if (!current || current.version !== prevVersion) {\n return false;\n }\n\n rows.set(bucket.id, next);\n return true;\n },\n };\n}\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { jsonResponse } from \"../shared/json\";\nimport type { RateLimitBucket } from \"./types\";\n\n/** Creates the default rate-limited response. */\nexport function createRateLimitedResponse(params: {\n bucket: RateLimitBucket;\n nowMs: number;\n key: string;\n max: number;\n}): Response {\n const retryAfter = Math.max(\n 1,\n Math.ceil((params.bucket.windowEnd.getTime() - params.nowMs) / 1000),\n );\n\n return jsonResponse(\n {\n error: \"rate_limited\",\n message: \"Too many requests.\",\n key: params.key,\n limit: params.max,\n remaining: 0,\n resetAt: params.bucket.windowEnd.toISOString(),\n },\n {\n status: 429,\n headers: {\n \"retry-after\": String(retryAfter),\n \"x-ratelimit-limit\": String(params.max),\n \"x-ratelimit-remaining\": \"0\",\n \"x-ratelimit-reset\": String(Math.floor(params.bucket.windowEnd.getTime() / 1000)),\n },\n },\n );\n}\n\n/** Creates the default storage unavailable response. */\nexport function createRateLimitStorageUnavailableResponse(): Response {\n return jsonResponse(\n {\n error: \"service_unavailable\",\n message: \"Rate limit storage is unavailable.\",\n },\n { status: 503 },\n );\n}\n\n/** Creates the CAS retries exceeded error. */\nexport function createCasRetriesExceededError(): BetterAgentError {\n return BetterAgentError.fromCode(\"INTERNAL\", \"Rate limit write failed after CAS retries.\", {\n trace: [{ at: \"plugins.rateLimitPlugin\" }],\n });\n}\n","import { requirePositiveNumber } from \"../shared/validation\";\nimport type { RateLimitPluginConfig } from \"./types\";\n\n/** Validates `rateLimitPlugin` configuration. */\nexport function validateRateLimitPluginConfig(config: RateLimitPluginConfig): void {\n requirePositiveNumber(config.windowMs, \"windowMs\", \"plugins.rateLimitPlugin\");\n requirePositiveNumber(config.max, \"max\", \"plugins.rateLimitPlugin\");\n requirePositiveNumber(config.casRetries ?? 8, \"casRetries\", \"plugins.rateLimitPlugin\");\n}\n","import type { Plugin } from \"@better-agent/core\";\nimport { createBucket } from \"./bucket\";\nimport { createMemoryStore } from \"./memory-store\";\nimport {\n createCasRetriesExceededError,\n createRateLimitStorageUnavailableResponse,\n createRateLimitedResponse,\n} from \"./responses\";\nimport type { RateLimitPluginConfig, RateLimitStorageState } from \"./types\";\nimport { validateRateLimitPluginConfig } from \"./validate\";\n\n/**\n * Creates a rate-limit plugin.\n *\n * Uses an in-memory store by default.\n *\n * @example\n * ```ts\n * const plugin = rateLimitPlugin({\n * windowMs: 60_000,\n * max: 30,\n * });\n * ```\n */\nexport const rateLimitPlugin = (config: RateLimitPluginConfig): Plugin => {\n validateRateLimitPluginConfig(config);\n\n const casRetries = config.casRetries ?? 8;\n const storage = config.storage ?? createMemoryStore();\n\n return {\n id: config.id ?? \"rate-limit\",\n guards: [\n async (ctx) => {\n const request = {\n mode: ctx.mode,\n agentName: ctx.agentName,\n request: ctx.request,\n };\n\n const now = new Date();\n const nowMs = now.getTime();\n const keyFromConfig = config.key\n ? await config.key(request)\n : `${ctx.agentName}:global`;\n const key =\n typeof keyFromConfig === \"string\" && keyFromConfig.trim().length > 0\n ? keyFromConfig.trim()\n : `${ctx.agentName}:global`;\n const bucket = createBucket({\n key,\n now,\n windowMs: config.windowMs,\n });\n\n const handleStoreError = async (error: unknown): Promise<Response | null> => {\n const action = config.onStoreError\n ? await config.onStoreError({ error, bucket, request })\n : \"allow\";\n\n if (action instanceof Response) return action;\n if (action === \"deny\") {\n return createRateLimitStorageUnavailableResponse();\n }\n\n return null;\n };\n\n for (let attempt = 0; attempt < casRetries; attempt += 1) {\n let state: RateLimitStorageState | null = null;\n try {\n state = await storage.read({ bucket, request });\n } catch (error) {\n return handleStoreError(error);\n }\n\n if (state && state.count >= config.max) {\n return createRateLimitedResponse({\n bucket,\n nowMs,\n key,\n max: config.max,\n });\n }\n\n try {\n const written = await storage.write({\n bucket,\n request,\n prevVersion: state?.version ?? null,\n next: {\n count: (state?.count ?? 0) + 1,\n version: (state?.version ?? 0) + 1,\n },\n });\n\n if (written) return null;\n } catch (error) {\n return handleStoreError(error);\n }\n }\n\n return handleStoreError(createCasRetriesExceededError());\n },\n ],\n };\n};\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type {\n DaytonaSandboxClientConfig,\n SandboxClient,\n SandboxCommandResult,\n SandboxFileEntry,\n SandboxPreviewInfo,\n} from \"./types\";\n\ntype DaytonaModule = {\n Daytona: new (config?: Record<string, unknown>) => DaytonaClientInstance;\n};\n\ntype DaytonaClientInstance = {\n create: (\n params?: Record<string, unknown>,\n options?: {\n timeout?: number;\n onSnapshotCreateLogs?: (chunk: string) => void;\n },\n ) => Promise<DaytonaSandboxInstance>;\n get: (sandboxIdOrName: string) => Promise<DaytonaSandboxInstance>;\n start?: (sandbox: DaytonaSandboxInstance, timeout?: number) => Promise<void>;\n stop?: (sandbox: DaytonaSandboxInstance) => Promise<void>;\n delete?: (sandbox: DaytonaSandboxInstance, timeout?: number) => Promise<void>;\n};\n\ntype DaytonaSandboxInstance = {\n id: string;\n process: {\n executeCommand: (\n command: string,\n cwd?: string,\n envVars?: Record<string, string>,\n timeout?: number,\n ) => Promise<{\n result?: string;\n exitCode?: number;\n }>;\n };\n fs: {\n downloadFile: (remotePath: string, timeout?: number) => Promise<Uint8Array | string>;\n uploadFile: (\n file: Uint8Array | string,\n remotePath: string,\n timeout?: number,\n ) => Promise<void>;\n listFiles: (path: string) => Promise<DaytonaFileInfo[]>;\n createFolder: (path: string, mode: string) => Promise<void>;\n deleteFile: (path: string, recursive?: boolean) => Promise<void>;\n };\n getPreviewLink: (port: number) => Promise<SandboxPreviewInfo>;\n start?: (timeout?: number) => Promise<void>;\n stop?: (timeout?: number) => Promise<void>;\n archive?: () => Promise<void>;\n delete?: (timeout?: number) => Promise<void>;\n};\n\ntype DaytonaFileInfo = {\n name?: string;\n path?: string;\n isDir?: boolean;\n type?: string;\n};\n\nconst loadDaytona = async (): Promise<DaytonaModule> => {\n try {\n const moduleName = \"@daytonaio/sdk\";\n return (await import(moduleName)) as DaytonaModule;\n } catch (error) {\n throw BetterAgentError.fromCode(\n \"INTERNAL\",\n \"The Daytona sandbox client requires the `@daytonaio/sdk` package to be installed in the host app.\",\n {\n cause: error,\n trace: [{ at: \"plugins.sandbox.createDaytonaSandboxClient.loadDaytona\" }],\n },\n );\n }\n};\n\nconst removeUndefined = (value: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));\n\nconst toSeconds = (value: number | undefined): number | undefined =>\n value === undefined ? undefined : Math.max(1, Math.ceil(value / 1000));\n\nconst toUtf8 = (value: Uint8Array | string): string =>\n typeof value === \"string\" ? value : new TextDecoder().decode(value);\n\nconst normalizeFileEntries = (files: DaytonaFileInfo[]): SandboxFileEntry[] =>\n files.map((entry) => ({\n name: entry.name ?? entry.path?.split(\"/\").filter(Boolean).at(-1) ?? \"\",\n path: entry.path ?? entry.name ?? \"\",\n type: entry.type ?? (entry.isDir ? \"directory\" : \"file\"),\n }));\n\n/** Creates a sandbox client backed by the Daytona SDK. */\nexport function createDaytonaSandboxClient(config: DaytonaSandboxClientConfig = {}): SandboxClient {\n const clientConfig = removeUndefined({\n apiKey: config.apiKey,\n apiUrl: config.apiUrl,\n target: config.target,\n });\n\n const buildCreateParams = (overrides?: {\n template?: string;\n envs?: Record<string, string>;\n metadata?: Record<string, string>;\n }) => {\n const template = overrides?.template ?? config.template;\n const templateKind = config.templateKind ?? \"snapshot\";\n\n return removeUndefined({\n language: config.language,\n envVars: overrides?.envs ?? config.envs,\n labels: overrides?.metadata ?? config.metadata,\n public: config.public,\n autoStopInterval: config.autoStopInterval,\n autoArchiveInterval: config.autoArchiveInterval,\n autoDeleteInterval: config.autoDeleteInterval,\n ...(template !== undefined\n ? templateKind === \"image\"\n ? { image: template }\n : { snapshot: template }\n : {}),\n ...(config.snapshot !== undefined ? { snapshot: config.snapshot } : {}),\n ...(config.image !== undefined ? { image: config.image } : {}),\n });\n };\n\n const getClient = async (): Promise<DaytonaClientInstance> => {\n const { Daytona } = await loadDaytona();\n return new Daytona(clientConfig);\n };\n\n const getSandbox = async (\n sandboxId: string,\n ): Promise<{\n client: DaytonaClientInstance;\n sandbox: DaytonaSandboxInstance;\n }> => {\n const client = await getClient();\n return {\n sandbox: await client.get(sandboxId),\n client,\n };\n };\n\n const toCommandResult = (response: {\n result?: string;\n exitCode?: number;\n }): SandboxCommandResult => ({\n exitCode: response.exitCode,\n stdout: response.result,\n });\n\n return {\n provider: \"daytona\",\n capabilities: {\n commands: true,\n filesystem: true,\n preview: true,\n pty: true,\n desktop: true,\n git: true,\n snapshots: true,\n volumes: true,\n lifecycle: {\n start: true,\n stop: true,\n archive: true,\n resume: true,\n },\n },\n\n async createSandbox(params) {\n const client = await getClient();\n const timeout = toSeconds(params?.timeoutMs ?? config.timeoutMs);\n const sandbox = await client.create(buildCreateParams(params), {\n ...(timeout !== undefined ? { timeout } : {}),\n });\n\n return { sandboxId: sandbox.id };\n },\n\n async runCommand(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n return toCommandResult(\n await sandbox.process.executeCommand(\n params.cmd,\n params.cwd,\n params.envs,\n toSeconds(params.timeoutMs),\n ),\n );\n },\n\n async readFile(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n return toUtf8(await sandbox.fs.downloadFile(params.path));\n },\n\n async writeFile(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n await sandbox.fs.uploadFile(Buffer.from(params.content), params.path);\n return { path: params.path };\n },\n\n async listFiles(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n return normalizeFileEntries(await sandbox.fs.listFiles(params.path));\n },\n\n async makeDir(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n await sandbox.fs.createFolder(params.path, \"755\");\n return { created: true };\n },\n\n async removePath(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n await sandbox.fs.deleteFile(params.path, true);\n },\n\n async getHost(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n return await sandbox.getPreviewLink(params.port);\n },\n\n async killSandbox(params) {\n const { client, sandbox } = await getSandbox(params.sandboxId);\n if (typeof sandbox.delete === \"function\") {\n await sandbox.delete(60);\n return;\n }\n\n if (typeof client.delete === \"function\") {\n await client.delete(sandbox, 60);\n return;\n }\n\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n \"The active Daytona SDK instance does not expose sandbox deletion.\",\n {\n context: { sandboxId: params.sandboxId },\n trace: [{ at: \"plugins.sandbox.createDaytonaSandboxClient.killSandbox\" }],\n },\n );\n },\n\n lifecycle: {\n async startSandbox(params) {\n const { client, sandbox } = await getSandbox(params.sandboxId);\n const timeout = toSeconds(params.timeoutMs);\n\n if (typeof sandbox.start === \"function\") {\n await sandbox.start(timeout);\n return;\n }\n\n if (typeof client.start === \"function\") {\n await client.start(sandbox, timeout);\n }\n },\n\n async stopSandbox(params) {\n const { client, sandbox } = await getSandbox(params.sandboxId);\n\n if (typeof sandbox.stop === \"function\") {\n await sandbox.stop(toSeconds(params.timeoutMs));\n return;\n }\n\n if (typeof client.stop === \"function\") {\n await client.stop(sandbox);\n }\n },\n\n async archiveSandbox(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n if (typeof sandbox.archive === \"function\") {\n await sandbox.archive();\n return;\n }\n\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n \"The active Daytona SDK instance does not expose sandbox archiving.\",\n {\n context: { sandboxId: params.sandboxId },\n trace: [\n { at: \"plugins.sandbox.createDaytonaSandboxClient.archiveSandbox\" },\n ],\n },\n );\n },\n },\n };\n}\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type {\n E2BSandboxClientConfig,\n SandboxClient,\n SandboxCommandParams,\n SandboxCommandResult,\n SandboxFileEntry,\n} from \"./types\";\n\ntype E2BSandboxModule = {\n Sandbox: {\n create: (\n templateOrOptions?: string | Record<string, unknown>,\n options?: Record<string, unknown>,\n ) => Promise<E2BSandboxInstance>;\n connect: (\n sandboxId: string,\n options?: Record<string, unknown>,\n ) => Promise<E2BSandboxInstance>;\n };\n};\n\ntype E2BSandboxInstance = {\n sandboxId: string;\n commands: {\n run: (\n cmd: string,\n options?: Record<string, unknown>,\n ) => Promise<{\n exitCode?: number;\n stdout?: string;\n stderr?: string;\n pid?: number;\n }>;\n };\n files: {\n read: (path: string, options?: Record<string, unknown>) => Promise<string>;\n write: (\n path: string,\n data: string,\n options?: Record<string, unknown>,\n ) => Promise<{ path?: string }>;\n list: (path: string, options?: Record<string, unknown>) => Promise<SandboxFileEntry[]>;\n makeDir: (path: string, options?: Record<string, unknown>) => Promise<boolean>;\n remove: (path: string, options?: Record<string, unknown>) => Promise<void>;\n };\n getHost: (port: number) => string;\n kill: (options?: Record<string, unknown>) => Promise<void>;\n};\n\nconst removeUndefined = (value: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));\n\nconst loadE2B = async (): Promise<E2BSandboxModule> => {\n try {\n const moduleName = \"e2b\";\n return (await import(moduleName)) as E2BSandboxModule;\n } catch (error) {\n throw BetterAgentError.fromCode(\n \"INTERNAL\",\n \"The built-in E2B sandbox client requires the `e2b` package to be installed in the host app.\",\n {\n cause: error,\n trace: [{ at: \"plugins.sandbox.createE2BSandboxClient.loadE2B\" }],\n },\n );\n }\n};\n\n/** Creates a sandbox client backed by the E2B SDK. */\nexport function createE2BSandboxClient(config: E2BSandboxClientConfig = {}): SandboxClient {\n const connectionOptions = removeUndefined({\n apiKey: config.apiKey,\n accessToken: config.accessToken,\n domain: config.domain,\n requestTimeoutMs: config.requestTimeoutMs,\n });\n\n const toCreateOptions = (overrides?: {\n template?: string;\n timeoutMs?: number;\n envs?: Record<string, string>;\n metadata?: Record<string, string>;\n }) =>\n removeUndefined({\n ...connectionOptions,\n timeoutMs: overrides?.timeoutMs ?? config.timeoutMs,\n envs: overrides?.envs ?? config.envs,\n metadata: overrides?.metadata ?? config.metadata,\n });\n\n const connectSandbox = async (sandboxId: string): Promise<E2BSandboxInstance> => {\n const { Sandbox } = await loadE2B();\n return await Sandbox.connect(sandboxId, connectionOptions);\n };\n\n const mapCommandResult = (\n result: Awaited<ReturnType<E2BSandboxInstance[\"commands\"][\"run\"]>>,\n ): SandboxCommandResult => ({\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n pid: result.pid,\n });\n\n return {\n provider: \"e2b\",\n capabilities: {\n commands: true,\n filesystem: true,\n preview: true,\n mcp: true,\n pty: true,\n desktop: true,\n },\n async createSandbox(params) {\n const { Sandbox } = await loadE2B();\n const template = params?.template ?? config.template;\n const options = toCreateOptions(params);\n\n const sandbox =\n template !== undefined\n ? await Sandbox.create(template, options)\n : await Sandbox.create(options);\n\n return { sandboxId: sandbox.sandboxId };\n },\n\n async runCommand(params: SandboxCommandParams) {\n const sandbox = await connectSandbox(params.sandboxId);\n return mapCommandResult(\n await sandbox.commands.run(\n params.cmd,\n removeUndefined({\n cwd: params.cwd,\n envs: params.envs,\n timeoutMs: params.timeoutMs,\n }),\n ),\n );\n },\n\n async readFile(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n return await sandbox.files.read(params.path);\n },\n\n async writeFile(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n const result = await sandbox.files.write(params.path, params.content);\n return { path: result.path ?? params.path };\n },\n\n async listFiles(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n return await sandbox.files.list(params.path);\n },\n\n async makeDir(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n return {\n created: await sandbox.files.makeDir(params.path),\n };\n },\n\n async removePath(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n await sandbox.files.remove(params.path);\n },\n\n async getHost(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n return sandbox.getHost(params.port);\n },\n\n async killSandbox(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n await sandbox.kill();\n },\n };\n}\n","import type { SandboxSessionStore } from \"./types\";\n\n/** Creates an in-memory sandbox session store. */\nexport function createMemorySandboxSessionStore(): SandboxSessionStore {\n const sessions = new Map<string, string>();\n\n return {\n async get(key) {\n return sessions.get(key) ?? null;\n },\n async set(key, sandboxId) {\n sessions.set(key, sandboxId);\n },\n async delete(key) {\n sessions.delete(key);\n },\n };\n}\n","import { createValidationError } from \"../shared/validation\";\nimport type { SandboxPluginConfig } from \"./types\";\n\n/** Validates `sandboxPlugin` configuration. */\nexport function validateSandboxPluginConfig(config: SandboxPluginConfig): void {\n const client = config.client;\n\n if (!client || typeof client !== \"object\") {\n throw createValidationError(\n \"`sandboxPlugin` requires a `client`.\",\n \"plugins.sandboxPlugin\",\n );\n }\n\n if (config.prefix !== undefined && config.prefix.trim().length === 0) {\n throw createValidationError(\n \"`sandboxPlugin` requires `prefix` to be a non-empty string when provided.\",\n \"plugins.sandboxPlugin\",\n );\n }\n}\n","import { type Plugin, type ToolRunContext, defineTool } from \"@better-agent/core\";\nimport { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { createMemorySandboxSessionStore } from \"./memory-store\";\nimport type { SandboxCreateParams, SandboxPluginConfig } from \"./types\";\nimport { validateSandboxPluginConfig } from \"./validate\";\n\nconst trimToUndefined = (value: string | undefined): string | undefined => {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n};\n\nconst normalizeHostUrl = (value: string): string =>\n /^[a-z][a-z0-9+.-]*:\\/\\//i.test(value) ? value : `https://${value}`;\n\nconst createValidationError = (message: string, at: string, context?: Record<string, unknown>) =>\n BetterAgentError.fromCode(\"VALIDATION_FAILED\", message, {\n ...(context !== undefined ? { context } : {}),\n trace: [{ at }],\n });\n\ntype ResolvedSandboxRef = {\n sandboxId: string;\n sessionKey?: string;\n created: boolean;\n};\n\ntype SessionPolicy =\n | {\n kind: \"managed\";\n sessionKey: string;\n }\n | {\n kind: \"disabled\";\n };\n\n/**\n * Adds sandbox tools.\n *\n * By default, the plugin reuses one sandbox per `conversationId`.\n * Use `sessionKey` to customize reuse, or return `null`/`undefined`\n * to disable reuse for a specific tool call.\n *\n * Uses an in-memory store by default.\n *\n * @example\n * ```ts\n * import { sandboxPlugin, createE2BSandboxClient } from \"@better-agent/plugins\";\n *\n * const plugin = sandboxPlugin({\n * client: createE2BSandboxClient({\n * apiKey: process.env.E2B_API_KEY,\n * }),\n * defaults: {\n * template: \"base\",\n * timeoutMs: 10 * 60_000,\n * },\n * });\n * ```\n */\nexport const sandboxPlugin = (config: SandboxPluginConfig): Plugin => {\n validateSandboxPluginConfig(config);\n\n const sandboxClient = config.client;\n const store = config.store ?? createMemorySandboxSessionStore();\n const prefix = trimToUndefined(config.prefix) ?? \"sandbox\";\n const nameFor = (suffix: string) => `${prefix}_${suffix}`;\n\n const getSessionPolicy = (ctx: ToolRunContext, toolName: string): SessionPolicy => {\n if (config.sessionKey) {\n const custom = trimToUndefined(\n config.sessionKey({\n runId: ctx.runId,\n agentName: ctx.agentName,\n ...(ctx.conversationId !== undefined\n ? { conversationId: ctx.conversationId }\n : {}),\n toolName,\n }) ?? undefined,\n );\n\n return custom !== undefined\n ? { kind: \"managed\", sessionKey: custom }\n : { kind: \"disabled\" };\n }\n\n return ctx.conversationId\n ? { kind: \"managed\", sessionKey: `conversation:${ctx.conversationId}` }\n : { kind: \"disabled\" };\n };\n\n const getExplicitSandboxId = (value: string | undefined): string | undefined => {\n if (value === undefined) {\n return undefined;\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n throw createValidationError(\n \"`sandboxId` must be a non-empty string when provided.\",\n \"plugins.sandboxPlugin.sandboxId\",\n );\n }\n\n return trimmed;\n };\n\n const createSandbox = async (\n params: SandboxCreateParams | undefined,\n ctx: ToolRunContext,\n toolName: string,\n ): Promise<ResolvedSandboxRef> => {\n const sessionPolicy = getSessionPolicy(ctx, toolName);\n const created = await sandboxClient.createSandbox({\n template: params?.template ?? config.defaults?.template,\n timeoutMs: params?.timeoutMs ?? config.defaults?.timeoutMs,\n envs: params?.envs ?? config.defaults?.envs,\n metadata: params?.metadata ?? config.defaults?.metadata,\n });\n\n if (sessionPolicy.kind === \"managed\") {\n await store.set(sessionPolicy.sessionKey, created.sandboxId);\n }\n\n return {\n sandboxId: created.sandboxId,\n ...(sessionPolicy.kind === \"managed\" ? { sessionKey: sessionPolicy.sessionKey } : {}),\n created: true,\n };\n };\n\n const resolveSandbox = async (params: {\n sandboxId?: string;\n createIfMissing: boolean;\n createParams?: SandboxCreateParams;\n ctx: ToolRunContext;\n toolName: string;\n }): Promise<ResolvedSandboxRef> => {\n const explicitSandboxId = getExplicitSandboxId(params.sandboxId);\n if (explicitSandboxId) {\n return { sandboxId: explicitSandboxId, created: false };\n }\n\n const sessionPolicy = getSessionPolicy(params.ctx, params.toolName);\n if (sessionPolicy.kind === \"managed\") {\n const existing = trimToUndefined(\n (await store.get(sessionPolicy.sessionKey)) ?? undefined,\n );\n if (existing) {\n return {\n sandboxId: existing,\n sessionKey: sessionPolicy.sessionKey,\n created: false,\n };\n }\n }\n\n if (!params.createIfMissing) {\n throw createValidationError(\n `No sandbox is available for this ${params.ctx.conversationId ? \"conversation\" : \"run\"}. Create one first with '${nameFor(\"create\")}' or pass a sandboxId explicitly.`,\n \"plugins.sandboxPlugin.resolveSandbox.missing\",\n {\n runId: params.ctx.runId,\n agentName: params.ctx.agentName,\n conversationId: params.ctx.conversationId,\n toolName: params.toolName,\n },\n );\n }\n\n return await createSandbox(params.createParams, params.ctx, params.toolName);\n };\n\n const clearManagedSessionIfMatches = async (\n ctx: ToolRunContext,\n toolName: string,\n sandboxId: string,\n ): Promise<string | undefined> => {\n const sessionPolicy = getSessionPolicy(ctx, toolName);\n if (sessionPolicy.kind !== \"managed\") {\n return undefined;\n }\n\n const current = await store.get(sessionPolicy.sessionKey);\n if (current === sandboxId) {\n await store.delete(sessionPolicy.sessionKey);\n return sessionPolicy.sessionKey;\n }\n\n return undefined;\n };\n\n const createSchema = {\n type: \"object\",\n properties: {\n forceNew: { type: \"boolean\" },\n template: { type: \"string\" },\n timeoutMs: { type: \"number\", exclusiveMinimum: 0 },\n envs: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n },\n metadata: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n },\n },\n additionalProperties: false,\n } as const;\n\n const sandboxIdSchema = {\n type: \"string\",\n } as const;\n\n const pathSchema = {\n type: \"string\",\n minLength: 1,\n } as const;\n\n const envsSchema = {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n } as const;\n\n const createTool = defineTool({\n name: nameFor(\"create\"),\n description:\n \"Create a sandbox, or reuse the current conversation sandbox unless forceNew is true.\",\n schema: createSchema,\n }).server(async (input, ctx) => {\n if (!input.forceNew) {\n const sessionPolicy = getSessionPolicy(ctx, nameFor(\"create\"));\n if (sessionPolicy.kind === \"managed\") {\n const existing = trimToUndefined(\n (await store.get(sessionPolicy.sessionKey)) ?? undefined,\n );\n if (existing) {\n return {\n sandboxId: existing,\n reused: true,\n created: false,\n sessionKey: sessionPolicy.sessionKey,\n };\n }\n }\n }\n\n const resolved = await createSandbox(\n {\n template: input.template,\n timeoutMs: input.timeoutMs,\n envs: input.envs,\n metadata: input.metadata,\n },\n ctx,\n nameFor(\"create\"),\n );\n\n return {\n sandboxId: resolved.sandboxId,\n reused: false,\n created: true,\n ...(resolved.sessionKey !== undefined ? { sessionKey: resolved.sessionKey } : {}),\n };\n });\n\n const execTool = defineTool({\n name: nameFor(\"exec\"),\n description:\n \"Run one shell command inside a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n cmd: { type: \"string\", minLength: 1 },\n cwd: { type: \"string\" },\n timeoutMs: { type: \"number\", exclusiveMinimum: 0 },\n envs: envsSchema,\n },\n required: [\"cmd\"],\n additionalProperties: false,\n } as const,\n approval: config.approvals?.exec,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"exec\"),\n });\n const result = await sandboxClient.runCommand({\n sandboxId: resolved.sandboxId,\n cmd: input.cmd,\n cwd: input.cwd,\n timeoutMs: input.timeoutMs,\n envs: input.envs,\n });\n\n return {\n sandboxId: resolved.sandboxId,\n createdSandbox: resolved.created,\n ...result,\n };\n });\n\n const readFileTool = defineTool({\n name: nameFor(\"read_file\"),\n description:\n \"Read one text file from a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n },\n required: [\"path\"],\n additionalProperties: false,\n } as const,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"read_file\"),\n });\n\n return {\n sandboxId: resolved.sandboxId,\n path: input.path,\n content: await sandboxClient.readFile({\n sandboxId: resolved.sandboxId,\n path: input.path,\n }),\n };\n });\n\n const writeFileTool = defineTool({\n name: nameFor(\"write_file\"),\n description:\n \"Write one text file into a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n content: { type: \"string\" },\n },\n required: [\"path\", \"content\"],\n additionalProperties: false,\n } as const,\n approval: config.approvals?.writeFile,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"write_file\"),\n });\n const result = await sandboxClient.writeFile({\n sandboxId: resolved.sandboxId,\n path: input.path,\n content: input.content,\n });\n\n return {\n sandboxId: resolved.sandboxId,\n createdSandbox: resolved.created,\n path: result.path,\n };\n });\n\n const listFilesTool = defineTool({\n name: nameFor(\"list_files\"),\n description:\n \"List directory entries inside a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n },\n required: [\"path\"],\n additionalProperties: false,\n } as const,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"list_files\"),\n });\n\n return {\n sandboxId: resolved.sandboxId,\n path: input.path,\n entries: await sandboxClient.listFiles({\n sandboxId: resolved.sandboxId,\n path: input.path,\n }),\n };\n });\n\n const makeDirTool = defineTool({\n name: nameFor(\"make_dir\"),\n description:\n \"Create a directory inside a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n },\n required: [\"path\"],\n additionalProperties: false,\n } as const,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"make_dir\"),\n });\n const result = await sandboxClient.makeDir({\n sandboxId: resolved.sandboxId,\n path: input.path,\n });\n\n return {\n sandboxId: resolved.sandboxId,\n path: input.path,\n created: result.created,\n };\n });\n\n const removePathTool = defineTool({\n name: nameFor(\"remove_path\"),\n description: \"Remove a file or directory from a sandbox.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n },\n required: [\"path\"],\n additionalProperties: false,\n } as const,\n approval: config.approvals?.removePath,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: false,\n ctx,\n toolName: nameFor(\"remove_path\"),\n });\n await sandboxClient.removePath({\n sandboxId: resolved.sandboxId,\n path: input.path,\n });\n\n return {\n sandboxId: resolved.sandboxId,\n removed: true,\n path: input.path,\n };\n });\n\n const getHostTool = defineTool({\n name: nameFor(\"get_host\"),\n description:\n \"Expose one sandbox port as a host URL so callers can reach an app running inside the sandbox.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n port: { type: \"number\", minimum: 1, maximum: 65535 },\n },\n required: [\"port\"],\n additionalProperties: false,\n } as const,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: false,\n ctx,\n toolName: nameFor(\"get_host\"),\n });\n const hostResult = await sandboxClient.getHost({\n sandboxId: resolved.sandboxId,\n port: input.port,\n });\n const preview = typeof hostResult === \"string\" ? undefined : hostResult;\n const host = normalizeHostUrl(typeof hostResult === \"string\" ? hostResult : hostResult.url);\n\n return {\n sandboxId: resolved.sandboxId,\n port: input.port,\n host,\n ...(preview?.token !== undefined ? { token: preview.token } : {}),\n };\n });\n\n const killTool = defineTool({\n name: nameFor(\"kill\"),\n description:\n \"Terminate a sandbox and clear the current conversation sandbox when applicable.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n },\n additionalProperties: false,\n } as const,\n approval: config.approvals?.killSandbox,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: false,\n ctx,\n toolName: nameFor(\"kill\"),\n });\n\n await sandboxClient.killSandbox({\n sandboxId: resolved.sandboxId,\n });\n\n const clearedSessionKey = await clearManagedSessionIfMatches(\n ctx,\n nameFor(\"kill\"),\n resolved.sandboxId,\n );\n\n return {\n sandboxId: resolved.sandboxId,\n killed: true,\n ...(clearedSessionKey !== undefined ? { clearedSessionKey } : {}),\n };\n });\n\n // @ts-ignore\n const tools = [\n createTool,\n execTool,\n readFileTool,\n writeFileTool,\n listFilesTool,\n makeDirTool,\n removePathTool,\n getHostTool,\n killTool,\n ];\n\n const plugin: Plugin = {\n id: config.id ?? \"sandbox\",\n tools,\n };\n\n return plugin;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["createValidationError","createValidationError","createValidationError","removeUndefined","createValidationError"],"sources":["../src/shared/json.ts","../src/auth/responses.ts","../src/shared/validation.ts","../src/auth/validate.ts","../src/auth/plugin.ts","../src/ip-allowlist/ip.ts","../src/ip-allowlist/cidr.ts","../src/ip-allowlist/responses.ts","../src/ip-allowlist/validate.ts","../src/ip-allowlist/plugin.ts","../src/logging/format.ts","../src/logging/redact.ts","../src/logging/validate.ts","../src/logging/plugin.ts","../src/rate-limit/bucket.ts","../src/rate-limit/memory-store.ts","../src/rate-limit/responses.ts","../src/rate-limit/validate.ts","../src/rate-limit/plugin.ts","../src/sandbox/daytona.ts","../src/sandbox/e2b.ts","../src/sandbox/memory-store.ts","../src/sandbox/validate.ts","../src/sandbox/plugin.ts"],"sourcesContent":["/** Creates a JSON response with a default content type. */\nexport function jsonResponse(body: unknown, init?: ResponseInit): Response {\n const headers = new Headers(init?.headers);\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n","import { jsonResponse } from \"../shared/json\";\n\n/** Creates the default unauthorized response. */\nexport function createUnauthorizedResponse(): Response {\n return jsonResponse(\n {\n error: \"unauthorized\",\n message: \"Invalid API key.\",\n },\n { status: 401 },\n );\n}\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\n\n/** Creates a plugin validation error. */\nexport function createValidationError(message: string, at: string): BetterAgentError {\n return BetterAgentError.fromCode(\"VALIDATION_FAILED\", message, {\n trace: [{ at }],\n });\n}\n\n/** Requires a positive finite number. */\nexport function requirePositiveNumber(value: number, name: string, at: string): void {\n if (!Number.isFinite(value) || value <= 0) {\n throw createValidationError(`\\`${name}\\` must be a positive number.`, at);\n }\n}\n\n/** Requires a non-empty array. */\nexport function requireNonEmptyArray<T>(\n value: readonly T[] | undefined,\n name: string,\n at: string,\n): asserts value is readonly T[] {\n if (!value || value.length === 0) {\n throw createValidationError(`\\`${name}\\` must contain at least one value.`, at);\n }\n}\n","import { createValidationError } from \"../shared/validation\";\nimport type { AuthPluginConfig } from \"./types\";\n\n/** Validates `authPlugin` configuration. */\nexport function validateAuthPluginConfig(config: AuthPluginConfig): void {\n if (!config.validate && (!config.apiKeys || config.apiKeys.length === 0)) {\n throw createValidationError(\n \"`authPlugin` requires either `apiKeys` or `validate`.\",\n \"plugins.authPlugin\",\n );\n }\n\n if (config.header !== undefined && config.header.trim().length === 0) {\n throw createValidationError(\n \"`authPlugin` requires `header` to be a non-empty string when provided.\",\n \"plugins.authPlugin\",\n );\n }\n\n if (config.apiKeys) {\n const normalized = config.apiKeys\n .filter((key): key is string => typeof key === \"string\")\n .map((key) => key.trim())\n .filter((key) => key.length > 0);\n\n if (normalized.length === 0 && !config.validate) {\n throw createValidationError(\n \"`authPlugin` requires `apiKeys` to contain at least one non-empty key.\",\n \"plugins.authPlugin\",\n );\n }\n }\n}\n","import type { Plugin } from \"@better-agent/core\";\nimport { createUnauthorizedResponse } from \"./responses\";\nimport type { AuthPluginConfig } from \"./types\";\nimport { validateAuthPluginConfig } from \"./validate\";\n\n/**\n * Creates an API-key auth plugin.\n *\n * Provide either `apiKeys` or `validate`.\n *\n * @example\n * ```ts\n * const plugin = authPlugin({\n * apiKeys: [\"dev-key\"],\n * });\n * ```\n */\nexport const authPlugin = (config: AuthPluginConfig): Plugin => {\n validateAuthPluginConfig(config);\n\n const header = config.header?.trim() || \"x-api-key\";\n const apiKeys = new Set((config.apiKeys ?? []).map((key) => key.trim()).filter(Boolean));\n\n return {\n id: config.id ?? \"auth\",\n guards: [\n async (ctx) => {\n const keyValue = config.getKey\n ? await config.getKey({\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : ctx.request.headers.get(header);\n\n const key =\n typeof keyValue === \"string\" && keyValue.trim().length > 0 ? keyValue : null;\n\n const valid = config.validate\n ? await config.validate({\n key,\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : key !== null && apiKeys.has(key);\n\n if (valid) {\n return null;\n }\n\n return config.onUnauthorized\n ? await config.onUnauthorized({\n key,\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : createUnauthorizedResponse();\n },\n ],\n };\n};\n","/** Parsed IP value. */\ntype ParsedIp = {\n /** IP family. */\n kind: \"ipv4\" | \"ipv6\";\n /** Numeric IP value. */\n value: bigint;\n /** Bit width for the IP family. */\n bits: number;\n /** Normalized string form. */\n normalized: string;\n};\n\n/** Parses an IPv4 string. */\nfunction parseIpv4(input: string): ParsedIp | null {\n const parts = input.split(\".\");\n if (parts.length !== 4) return null;\n\n let value = 0n;\n for (const part of parts) {\n if (!/^\\d+$/.test(part)) return null;\n const octet = Number(part);\n if (octet < 0 || octet > 255) return null;\n value = (value << 8n) | BigInt(octet);\n }\n\n return {\n kind: \"ipv4\",\n value,\n bits: 32,\n normalized: parts.join(\".\"),\n };\n}\n\n/** Expands an IPv6 string into eight normalized segments. */\nfunction expandIpv6Segments(input: string): string[] | null {\n const zoneIndex = input.indexOf(\"%\");\n const value = zoneIndex >= 0 ? input.slice(0, zoneIndex) : input;\n if (value.length === 0) return null;\n\n const doubleColonCount = value.split(\"::\").length - 1;\n if (doubleColonCount > 1) return null;\n\n const [leftRaw = \"\", rightRaw = \"\"] = value.split(\"::\");\n const left = leftRaw.length > 0 ? leftRaw.split(\":\") : [];\n const right = rightRaw.length > 0 ? rightRaw.split(\":\") : [];\n\n const normalizedRight = [...right];\n if (normalizedRight.length > 0) {\n const last = normalizedRight[normalizedRight.length - 1];\n if (last?.includes(\".\")) {\n const ipv4 = parseIpv4(last);\n if (!ipv4) return null;\n normalizedRight.splice(\n normalizedRight.length - 1,\n 1,\n Number((ipv4.value >> 16n) & 0xffffn).toString(16),\n Number(ipv4.value & 0xffffn).toString(16),\n );\n }\n }\n\n const normalizedLeft = [...left];\n if (normalizedLeft.length > 0) {\n const last = normalizedLeft[normalizedLeft.length - 1];\n if (last?.includes(\".\")) {\n const ipv4 = parseIpv4(last);\n if (!ipv4) return null;\n normalizedLeft.splice(\n normalizedLeft.length - 1,\n 1,\n Number((ipv4.value >> 16n) & 0xffffn).toString(16),\n Number(ipv4.value & 0xffffn).toString(16),\n );\n }\n }\n\n const totalSegments = normalizedLeft.length + normalizedRight.length;\n if (doubleColonCount === 0 && totalSegments !== 8) return null;\n if (doubleColonCount === 1 && totalSegments >= 8) return null;\n\n const missing = doubleColonCount === 1 ? 8 - totalSegments : 0;\n const segments = [\n ...normalizedLeft,\n ...Array.from({ length: missing }, () => \"0\"),\n ...normalizedRight,\n ];\n\n if (segments.length !== 8) return null;\n if (segments.some((segment) => !/^[0-9a-fA-F]{1,4}$/.test(segment))) return null;\n\n return segments.map((segment) => segment.toLowerCase());\n}\n\n/** Parses an IPv6 string. */\nfunction parseIpv6(input: string): ParsedIp | null {\n const segments = expandIpv6Segments(input);\n if (!segments) return null;\n\n let value = 0n;\n for (const segment of segments) {\n value = (value << 16n) | BigInt(Number.parseInt(segment, 16));\n }\n\n return {\n kind: \"ipv6\",\n value,\n bits: 128,\n normalized: segments.join(\":\"),\n };\n}\n\n/** Parses an IPv4 or IPv6 string. */\nexport function parseIp(input: string): ParsedIp | null {\n const value = input.trim();\n if (value.length === 0) return null;\n return parseIpv4(value) ?? parseIpv6(value);\n}\n\n/** Normalizes an IP string. */\nexport function normalizeIp(input: string): string | null {\n return parseIp(input)?.normalized ?? null;\n}\n\nexport type { ParsedIp };\n","import { type ParsedIp, parseIp } from \"./ip\";\n\n/** Matcher for one allowed IP entry. */\nexport type IpMatcher = {\n /** Original allowlist entry. */\n raw: string;\n /** Returns true when the IP matches this entry. */\n matches: (ip: ParsedIp) => boolean;\n};\n\n/** Creates a network mask for the given prefix. */\nfunction createMask(bits: number, prefix: number): bigint {\n if (prefix === 0) return 0n;\n return ((1n << BigInt(prefix)) - 1n) << BigInt(bits - prefix);\n}\n\n/** Parses one allowlist IP or CIDR entry. */\nexport function parseAllowEntry(input: string): IpMatcher | null {\n const raw = input.trim();\n if (raw.length === 0) return null;\n\n const slashIndex = raw.indexOf(\"/\");\n if (slashIndex === -1) {\n const parsed = parseIp(raw);\n if (!parsed) return null;\n return {\n raw,\n matches: (ip) => ip.kind === parsed.kind && ip.value === parsed.value,\n };\n }\n\n const addressPart = raw.slice(0, slashIndex).trim();\n const prefixPart = raw.slice(slashIndex + 1).trim();\n if (!/^\\d+$/.test(prefixPart)) return null;\n\n const parsed = parseIp(addressPart);\n if (!parsed) return null;\n\n const prefix = Number(prefixPart);\n if (prefix < 0 || prefix > parsed.bits) return null;\n\n const mask = createMask(parsed.bits, prefix);\n const network = parsed.value & mask;\n\n return {\n raw,\n matches: (ip) => ip.kind === parsed.kind && (ip.value & mask) === network,\n };\n}\n","import { jsonResponse } from \"../shared/json\";\n\n/** Creates the default IP denied response. */\nexport function createIpDeniedResponse(): Response {\n return jsonResponse(\n {\n error: \"forbidden\",\n message: \"IP address is not allowed.\",\n },\n { status: 403 },\n );\n}\n","import { createValidationError, requireNonEmptyArray } from \"../shared/validation\";\nimport { parseAllowEntry } from \"./cidr\";\nimport type { IpAllowlistPluginConfig } from \"./types\";\n\n/** Validates `ipAllowlistPlugin` configuration. */\nexport function validateIpAllowlistPluginConfig(config: IpAllowlistPluginConfig): void {\n requireNonEmptyArray(config.allow, \"allow\", \"plugins.ipAllowlistPlugin\");\n\n for (const entry of config.allow) {\n if (typeof entry !== \"string\" || !parseAllowEntry(entry)) {\n throw createValidationError(\n `\\`ipAllowlistPlugin\\` received an invalid allow entry: '${String(entry)}'.`,\n \"plugins.ipAllowlistPlugin\",\n );\n }\n }\n}\n","import type { Plugin } from \"@better-agent/core\";\nimport { parseAllowEntry } from \"./cidr\";\nimport { normalizeIp, parseIp } from \"./ip\";\nimport { createIpDeniedResponse } from \"./responses\";\nimport type { IpAllowlistPluginConfig } from \"./types\";\nimport { validateIpAllowlistPluginConfig } from \"./validate\";\n\n/** Reads the first valid forwarded IP. */\nfunction getProxyIp(request: Request): string | null {\n const forwardedFor = request.headers.get(\"x-forwarded-for\");\n if (!forwardedFor) return null;\n\n for (const part of forwardedFor.split(\",\")) {\n const normalized = normalizeIp(part.trim());\n if (normalized) {\n return normalized;\n }\n }\n\n return null;\n}\n\n/** Reads a direct client IP from common proxy headers. */\nfunction getDirectIp(request: Request): string | null {\n const candidates = [\n request.headers.get(\"x-real-ip\"),\n request.headers.get(\"cf-connecting-ip\"),\n request.headers.get(\"fly-client-ip\"),\n request.headers.get(\"fastly-client-ip\"),\n request.headers.get(\"x-client-ip\"),\n ];\n\n for (const candidate of candidates) {\n if (!candidate) continue;\n const normalized = normalizeIp(candidate);\n if (normalized) {\n return normalized;\n }\n }\n\n return null;\n}\n\n/**\n * Creates an IP allowlist plugin.\n *\n * @example\n * ```ts\n * const plugin = ipAllowlistPlugin({\n * allow: [\"127.0.0.1\", \"10.0.0.0/8\"],\n * });\n * ```\n */\nexport const ipAllowlistPlugin = (config: IpAllowlistPluginConfig): Plugin => {\n validateIpAllowlistPluginConfig(config);\n\n const matchers = config.allow.map((entry) => {\n const matcher = parseAllowEntry(entry);\n if (!matcher) {\n throw new Error(`Invalid allowlist entry: ${entry}`);\n }\n return matcher;\n });\n\n return {\n id: config.id ?? \"ip-allowlist\",\n guards: [\n async (ctx) => {\n const resolvedIp = config.getIp\n ? await config.getIp({\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : config.trustProxy\n ? getProxyIp(ctx.request)\n : getDirectIp(ctx.request);\n\n const normalizedIp =\n typeof resolvedIp === \"string\" && resolvedIp.trim().length > 0\n ? normalizeIp(resolvedIp)\n : null;\n const parsedIp = normalizedIp ? parseIp(normalizedIp) : null;\n\n if (parsedIp && matchers.some((matcher) => matcher.matches(parsedIp))) {\n return null;\n }\n\n return config.onDenied\n ? await config.onDenied({\n ip: normalizedIp,\n agentName: ctx.agentName,\n mode: ctx.mode,\n request: ctx.request,\n })\n : createIpDeniedResponse();\n },\n ],\n };\n};\n","import type { LogEntry, LoggingPluginConfig } from \"./types\";\n\nconst order: Record<LogEntry[\"level\"], number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\n/** Returns true when the entry should be logged at the current level. */\nexport function shouldLog(\n currentLevel: NonNullable<LoggingPluginConfig[\"level\"]>,\n entry: LogEntry,\n): boolean {\n return order[entry.level] >= order[currentLevel];\n}\n","const DEFAULT_REDACT_HEADERS = [\"authorization\", \"cookie\", \"set-cookie\", \"x-api-key\"] as const;\n\n/** Redacts sensitive headers. */\nexport function redactHeaders(\n headers: Headers,\n extraHeaders?: readonly string[],\n): Record<string, string> {\n const redactSet = new Set(\n [...DEFAULT_REDACT_HEADERS, ...(extraHeaders ?? [])].map((value) => value.toLowerCase()),\n );\n const result: Record<string, string> = {};\n\n headers.forEach((value, key) => {\n result[key] = redactSet.has(key.toLowerCase()) ? \"[REDACTED]\" : value;\n });\n\n return result;\n}\n","import type { LoggingPluginConfig } from \"./types\";\n\n/** Validates `loggingPlugin` configuration. */\nexport function validateLoggingPluginConfig(_config: LoggingPluginConfig): void {}\n","import type { Plugin } from \"@better-agent/core\";\nimport type { PluginOnStepContext, PluginSaveContext } from \"@better-agent/core\";\nimport type { Event } from \"@better-agent/core/events\";\nimport { shouldLog } from \"./format\";\nimport { redactHeaders } from \"./redact\";\nimport type { LogEntry, LoggingPluginConfig } from \"./types\";\nimport { validateLoggingPluginConfig } from \"./validate\";\n\nfunction safeInvoke(fn: ((...args: unknown[]) => void) | undefined, payload: unknown): void {\n if (!fn) return;\n try {\n fn(payload);\n } catch {\n // Logging must never affect runtime execution.\n }\n}\n\n/** Resolves the logger methods for the configured sink. */\nfunction getLoggerMethods(config: LoggingPluginConfig) {\n return {\n debug: config.logger?.debug ?? console.debug,\n info: config.logger?.info ?? console.info,\n warn: config.logger?.warn ?? console.warn,\n error: config.logger?.error ?? console.error,\n };\n}\n\n/** Emits one log entry. */\nfunction emitLog(config: LoggingPluginConfig, entry: LogEntry): void {\n const level = config.level ?? \"info\";\n if (!shouldLog(level, entry)) return;\n\n const output = config.format ? config.format(entry) : entry;\n const logger = getLoggerMethods(config);\n safeInvoke(logger[entry.level], output);\n}\n\n/** Maps one runtime event to a log level. */\nfunction getEventLevel(event: Event): LogEntry[\"level\"] {\n if (event.type.endsWith(\"_ERROR\")) return \"error\";\n return \"info\";\n}\n\n/** Creates request log data. */\nfunction createRequestData(ctx: Parameters<NonNullable<Plugin[\"guards\"]>[number]>[0]) {\n return {\n mode: ctx.mode,\n url: ctx.request.url,\n method: ctx.request.method,\n headers: redactHeaders(ctx.request.headers),\n input: ctx.input,\n };\n}\n\n/** Creates step log data. */\nfunction createStepData(ctx: PluginOnStepContext) {\n return {\n stepIndex: ctx.stepIndex,\n maxSteps: ctx.maxSteps,\n messageCount: ctx.messages.length,\n };\n}\n\n/** Creates save log data. */\nfunction createSaveData(ctx: PluginSaveContext) {\n const messageCount = ctx.items.filter((item) => item.type === \"message\").length;\n\n return {\n itemCount: ctx.items.length,\n messageCount,\n };\n}\n\n/**\n * Creates a logging plugin.\n *\n * @example\n * ```ts\n * const plugin = loggingPlugin({\n * level: \"info\",\n * include: { requests: true, toolCalls: true },\n * });\n * ```\n */\nexport const loggingPlugin = (config: LoggingPluginConfig = {}): Plugin => {\n validateLoggingPluginConfig(config);\n\n const include = {\n requests: config.include?.requests ?? true,\n events: config.include?.events ?? true,\n steps: config.include?.steps ?? true,\n modelCalls: config.include?.modelCalls ?? true,\n toolCalls: config.include?.toolCalls ?? true,\n saves: config.include?.saves ?? false,\n errors: config.include?.errors ?? true,\n };\n\n const plugin: Plugin = {\n id: config.id ?? \"logging\",\n };\n\n if (include.requests) {\n plugin.guards = [\n async (ctx) => {\n const body = config.redactBody\n ? config.redactBody({ body: ctx.input, phase: \"request\" })\n : ctx.input;\n\n emitLog(config, {\n level: \"info\",\n event: \"request.received\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n data: {\n ...createRequestData(ctx),\n input: body,\n },\n });\n\n return null;\n },\n ];\n }\n\n if (include.events) {\n plugin.onEvent = async (event, ctx) => {\n const level = getEventLevel(event);\n if (level === \"error\" && !include.errors) return;\n\n emitLog(config, {\n level,\n event: \"run.event\",\n timestamp: new Date(event.timestamp).toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n type: event.type,\n },\n });\n };\n }\n\n if (include.steps) {\n plugin.onStep = async (ctx) => {\n emitLog(config, {\n level: \"info\",\n event: \"step.start\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: createStepData(ctx),\n });\n };\n }\n\n if (include.modelCalls) {\n plugin.onBeforeModelCall = async (ctx) => {\n emitLog(config, {\n level: \"debug\",\n event: \"model.before\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n stepIndex: ctx.stepIndex,\n inputCount: ctx.input.length,\n toolCount: ctx.tools.length,\n toolChoice: ctx.toolChoice,\n },\n });\n };\n\n plugin.onAfterModelCall = async (ctx) => {\n emitLog(config, {\n level: \"debug\",\n event: \"model.after\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n stepIndex: ctx.stepIndex,\n response: config.redactBody\n ? config.redactBody({ body: ctx.response, phase: \"response\" })\n : ctx.response,\n },\n });\n };\n }\n\n if (include.toolCalls) {\n plugin.onBeforeToolCall = async (ctx) => {\n emitLog(config, {\n level: \"info\",\n event: \"tool.before\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n toolName: ctx.toolName,\n toolCallId: ctx.toolCallId,\n args: config.redactBody\n ? config.redactBody({ body: ctx.args, phase: \"tool_args\" })\n : ctx.args,\n },\n });\n return undefined;\n };\n\n plugin.onAfterToolCall = async (ctx) => {\n emitLog(config, {\n level: ctx.error ? \"error\" : \"info\",\n event: \"tool.after\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n toolName: ctx.toolName,\n toolCallId: ctx.toolCallId,\n error: ctx.error,\n result: config.redactBody\n ? config.redactBody({ body: ctx.result, phase: \"tool_result\" })\n : ctx.result,\n },\n });\n };\n }\n\n if (include.saves) {\n plugin.onBeforeSave = async (ctx) => {\n emitLog(config, {\n level: \"debug\",\n event: \"save.before\",\n timestamp: new Date().toISOString(),\n agentName: ctx.agentName,\n runId: ctx.runId,\n conversationId: ctx.conversationId,\n data: {\n ...createSaveData(ctx),\n items: config.redactBody\n ? config.redactBody({ body: ctx.items, phase: \"save\" })\n : ctx.items,\n },\n });\n };\n }\n\n return plugin;\n};\n","import type { RateLimitBucket } from \"./types\";\n\n/** Creates a rate-limit bucket for the current window. */\nexport function createBucket(params: {\n key: string;\n now: Date;\n windowMs: number;\n}): RateLimitBucket {\n const nowMs = params.now.getTime();\n const windowStartMs = Math.floor(nowMs / params.windowMs) * params.windowMs;\n\n return {\n id: `${windowStartMs}:${params.key}`,\n key: params.key,\n now: params.now,\n windowStart: new Date(windowStartMs),\n windowEnd: new Date(windowStartMs + params.windowMs),\n };\n}\n","import type { RateLimitPluginConfig, RateLimitStorageState } from \"./types\";\n\n/** Creates an in-memory CAS store for rate limiting. */\nexport function createMemoryStore(): NonNullable<RateLimitPluginConfig[\"storage\"]> {\n const rows = new Map<string, RateLimitStorageState>();\n\n return {\n read: async ({ bucket }) => rows.get(bucket.id) ?? null,\n write: async ({ bucket, prevVersion, next }) => {\n const current = rows.get(bucket.id) ?? null;\n if (prevVersion === null) {\n if (current) return false;\n rows.set(bucket.id, next);\n return true;\n }\n\n if (!current || current.version !== prevVersion) {\n return false;\n }\n\n rows.set(bucket.id, next);\n return true;\n },\n };\n}\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { jsonResponse } from \"../shared/json\";\nimport type { RateLimitBucket } from \"./types\";\n\n/** Creates the default rate-limited response. */\nexport function createRateLimitedResponse(params: {\n bucket: RateLimitBucket;\n nowMs: number;\n key: string;\n max: number;\n}): Response {\n const retryAfter = Math.max(\n 1,\n Math.ceil((params.bucket.windowEnd.getTime() - params.nowMs) / 1000),\n );\n\n return jsonResponse(\n {\n error: \"rate_limited\",\n message: \"Too many requests.\",\n key: params.key,\n limit: params.max,\n remaining: 0,\n resetAt: params.bucket.windowEnd.toISOString(),\n },\n {\n status: 429,\n headers: {\n \"retry-after\": String(retryAfter),\n \"x-ratelimit-limit\": String(params.max),\n \"x-ratelimit-remaining\": \"0\",\n \"x-ratelimit-reset\": String(Math.floor(params.bucket.windowEnd.getTime() / 1000)),\n },\n },\n );\n}\n\n/** Creates the default storage unavailable response. */\nexport function createRateLimitStorageUnavailableResponse(): Response {\n return jsonResponse(\n {\n error: \"service_unavailable\",\n message: \"Rate limit storage is unavailable.\",\n },\n { status: 503 },\n );\n}\n\n/** Creates the CAS retries exceeded error. */\nexport function createCasRetriesExceededError(): BetterAgentError {\n return BetterAgentError.fromCode(\"INTERNAL\", \"Rate limit write failed after CAS retries.\", {\n trace: [{ at: \"plugins.rateLimitPlugin\" }],\n });\n}\n","import { requirePositiveNumber } from \"../shared/validation\";\nimport type { RateLimitPluginConfig } from \"./types\";\n\n/** Validates `rateLimitPlugin` configuration. */\nexport function validateRateLimitPluginConfig(config: RateLimitPluginConfig): void {\n requirePositiveNumber(config.windowMs, \"windowMs\", \"plugins.rateLimitPlugin\");\n requirePositiveNumber(config.max, \"max\", \"plugins.rateLimitPlugin\");\n requirePositiveNumber(config.casRetries ?? 8, \"casRetries\", \"plugins.rateLimitPlugin\");\n}\n","import type { Plugin } from \"@better-agent/core\";\nimport { createBucket } from \"./bucket\";\nimport { createMemoryStore } from \"./memory-store\";\nimport {\n createCasRetriesExceededError,\n createRateLimitStorageUnavailableResponse,\n createRateLimitedResponse,\n} from \"./responses\";\nimport type { RateLimitPluginConfig, RateLimitStorageState } from \"./types\";\nimport { validateRateLimitPluginConfig } from \"./validate\";\n\n/**\n * Creates a rate-limit plugin.\n *\n * Uses an in-memory store by default.\n *\n * @example\n * ```ts\n * const plugin = rateLimitPlugin({\n * windowMs: 60_000,\n * max: 30,\n * });\n * ```\n */\nexport const rateLimitPlugin = (config: RateLimitPluginConfig): Plugin => {\n validateRateLimitPluginConfig(config);\n\n const casRetries = config.casRetries ?? 8;\n const storage = config.storage ?? createMemoryStore();\n\n return {\n id: config.id ?? \"rate-limit\",\n guards: [\n async (ctx) => {\n const request = {\n mode: ctx.mode,\n agentName: ctx.agentName,\n request: ctx.request,\n };\n\n const now = new Date();\n const nowMs = now.getTime();\n const keyFromConfig = config.key\n ? await config.key(request)\n : `${ctx.agentName}:global`;\n const key =\n typeof keyFromConfig === \"string\" && keyFromConfig.trim().length > 0\n ? keyFromConfig.trim()\n : `${ctx.agentName}:global`;\n const bucket = createBucket({\n key,\n now,\n windowMs: config.windowMs,\n });\n\n const handleStoreError = async (error: unknown): Promise<Response | null> => {\n const action = config.onStoreError\n ? await config.onStoreError({ error, bucket, request })\n : \"allow\";\n\n if (action instanceof Response) return action;\n if (action === \"deny\") {\n return createRateLimitStorageUnavailableResponse();\n }\n\n return null;\n };\n\n for (let attempt = 0; attempt < casRetries; attempt += 1) {\n let state: RateLimitStorageState | null = null;\n try {\n state = await storage.read({ bucket, request });\n } catch (error) {\n return handleStoreError(error);\n }\n\n if (state && state.count >= config.max) {\n return createRateLimitedResponse({\n bucket,\n nowMs,\n key,\n max: config.max,\n });\n }\n\n try {\n const written = await storage.write({\n bucket,\n request,\n prevVersion: state?.version ?? null,\n next: {\n count: (state?.count ?? 0) + 1,\n version: (state?.version ?? 0) + 1,\n },\n });\n\n if (written) return null;\n } catch (error) {\n return handleStoreError(error);\n }\n }\n\n return handleStoreError(createCasRetriesExceededError());\n },\n ],\n };\n};\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type {\n DaytonaSandboxClientConfig,\n SandboxClient,\n SandboxCommandResult,\n SandboxFileEntry,\n SandboxPreviewInfo,\n} from \"./types\";\n\ntype DaytonaModule = {\n Daytona: new (config?: Record<string, unknown>) => DaytonaClientInstance;\n};\n\ntype DaytonaClientInstance = {\n create: (\n params?: Record<string, unknown>,\n options?: {\n timeout?: number;\n onSnapshotCreateLogs?: (chunk: string) => void;\n },\n ) => Promise<DaytonaSandboxInstance>;\n get: (sandboxIdOrName: string) => Promise<DaytonaSandboxInstance>;\n start?: (sandbox: DaytonaSandboxInstance, timeout?: number) => Promise<void>;\n stop?: (sandbox: DaytonaSandboxInstance) => Promise<void>;\n delete?: (sandbox: DaytonaSandboxInstance, timeout?: number) => Promise<void>;\n};\n\ntype DaytonaSandboxInstance = {\n id: string;\n process: {\n executeCommand: (\n command: string,\n cwd?: string,\n envVars?: Record<string, string>,\n timeout?: number,\n ) => Promise<{\n result?: string;\n exitCode?: number;\n }>;\n };\n fs: {\n downloadFile: (remotePath: string, timeout?: number) => Promise<Uint8Array | string>;\n uploadFile: (\n file: Uint8Array | string,\n remotePath: string,\n timeout?: number,\n ) => Promise<void>;\n listFiles: (path: string) => Promise<DaytonaFileInfo[]>;\n createFolder: (path: string, mode: string) => Promise<void>;\n deleteFile: (path: string, recursive?: boolean) => Promise<void>;\n };\n getPreviewLink: (port: number) => Promise<SandboxPreviewInfo>;\n start?: (timeout?: number) => Promise<void>;\n stop?: (timeout?: number) => Promise<void>;\n archive?: () => Promise<void>;\n delete?: (timeout?: number) => Promise<void>;\n};\n\ntype DaytonaFileInfo = {\n name?: string;\n path?: string;\n isDir?: boolean;\n type?: string;\n};\n\nconst loadDaytona = async (): Promise<DaytonaModule> => {\n try {\n const moduleName = \"@daytonaio/sdk\";\n return (await import(moduleName)) as DaytonaModule;\n } catch (error) {\n throw BetterAgentError.fromCode(\n \"INTERNAL\",\n \"The Daytona sandbox client requires the `@daytonaio/sdk` package to be installed in the host app.\",\n {\n cause: error,\n trace: [{ at: \"plugins.sandbox.createDaytonaSandboxClient.loadDaytona\" }],\n },\n );\n }\n};\n\nconst removeUndefined = (value: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));\n\nconst toSeconds = (value: number | undefined): number | undefined =>\n value === undefined ? undefined : Math.max(1, Math.ceil(value / 1000));\n\nconst toUtf8 = (value: Uint8Array | string): string =>\n typeof value === \"string\" ? value : new TextDecoder().decode(value);\n\nconst normalizeFileEntries = (files: DaytonaFileInfo[]): SandboxFileEntry[] =>\n files.map((entry) => ({\n name: entry.name ?? entry.path?.split(\"/\").filter(Boolean).at(-1) ?? \"\",\n path: entry.path ?? entry.name ?? \"\",\n type: entry.type ?? (entry.isDir ? \"directory\" : \"file\"),\n }));\n\n/**\n * Creates a sandbox client backed by the Daytona SDK.\n */\nexport function createDaytonaSandboxClient(config: DaytonaSandboxClientConfig = {}): SandboxClient {\n const clientConfig = removeUndefined({\n apiKey: config.apiKey,\n apiUrl: config.apiUrl,\n target: config.target,\n });\n\n const toProviderMinutes = (value: number | undefined): number | undefined =>\n value !== undefined ? Math.max(1, Math.ceil(value / 60_000)) : undefined;\n\n const buildCreateParams = (overrides?: {\n template?: string;\n lifecycle?: {\n idleStopMs?: number;\n archiveAfterMs?: number;\n deleteAfterMs?: number;\n };\n envs?: Record<string, string>;\n metadata?: Record<string, string>;\n }) => {\n const template = overrides?.template;\n const templateKind = config.templateKind ?? \"snapshot\";\n\n return removeUndefined({\n language: config.language,\n envVars: overrides?.envs,\n labels: overrides?.metadata,\n public: config.public,\n autoStopInterval: toProviderMinutes(overrides?.lifecycle?.idleStopMs),\n autoArchiveInterval: toProviderMinutes(overrides?.lifecycle?.archiveAfterMs),\n autoDeleteInterval: toProviderMinutes(overrides?.lifecycle?.deleteAfterMs),\n ...(template !== undefined\n ? templateKind === \"image\"\n ? { image: template }\n : { snapshot: template }\n : {}),\n });\n };\n\n const getClient = async (): Promise<DaytonaClientInstance> => {\n const { Daytona } = await loadDaytona();\n return new Daytona(clientConfig);\n };\n\n const getSandbox = async (\n sandboxId: string,\n ): Promise<{\n client: DaytonaClientInstance;\n sandbox: DaytonaSandboxInstance;\n }> => {\n const client = await getClient();\n return {\n sandbox: await client.get(sandboxId),\n client,\n };\n };\n\n const toCommandResult = (response: {\n result?: string;\n exitCode?: number;\n }): SandboxCommandResult => ({\n exitCode: response.exitCode,\n stdout: response.result,\n });\n\n return {\n provider: \"daytona\",\n capabilities: {\n commands: true,\n filesystem: true,\n preview: true,\n pty: true,\n desktop: true,\n git: true,\n snapshots: true,\n volumes: true,\n lifecycle: {\n start: true,\n stop: true,\n archive: true,\n resume: true,\n },\n },\n\n async createSandbox(params) {\n const client = await getClient();\n const timeout = toSeconds(params?.startupTimeoutMs);\n const sandbox = await client.create(buildCreateParams(params), {\n ...(timeout !== undefined ? { timeout } : {}),\n });\n\n return { sandboxId: sandbox.id };\n },\n\n async runCommand(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n return toCommandResult(\n await sandbox.process.executeCommand(\n params.cmd,\n params.cwd,\n params.envs,\n toSeconds(params.timeoutMs),\n ),\n );\n },\n\n async readFile(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n return toUtf8(await sandbox.fs.downloadFile(params.path));\n },\n\n async writeFile(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n await sandbox.fs.uploadFile(Buffer.from(params.content), params.path);\n return { path: params.path };\n },\n\n async listFiles(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n return normalizeFileEntries(await sandbox.fs.listFiles(params.path));\n },\n\n async makeDir(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n await sandbox.fs.createFolder(params.path, \"755\");\n return { created: true };\n },\n\n async removePath(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n await sandbox.fs.deleteFile(params.path, true);\n },\n\n async getHost(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n return await sandbox.getPreviewLink(params.port);\n },\n\n async killSandbox(params) {\n const { client, sandbox } = await getSandbox(params.sandboxId);\n if (typeof sandbox.delete === \"function\") {\n await sandbox.delete(60);\n return;\n }\n\n if (typeof client.delete === \"function\") {\n await client.delete(sandbox, 60);\n return;\n }\n\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n \"The active Daytona SDK instance does not expose sandbox deletion.\",\n {\n context: { sandboxId: params.sandboxId },\n trace: [{ at: \"plugins.sandbox.createDaytonaSandboxClient.killSandbox\" }],\n },\n );\n },\n\n lifecycle: {\n async startSandbox(params) {\n const { client, sandbox } = await getSandbox(params.sandboxId);\n const timeout = toSeconds(params.timeoutMs);\n\n if (typeof sandbox.start === \"function\") {\n await sandbox.start(timeout);\n return;\n }\n\n if (typeof client.start === \"function\") {\n await client.start(sandbox, timeout);\n }\n },\n\n async stopSandbox(params) {\n const { client, sandbox } = await getSandbox(params.sandboxId);\n\n if (typeof sandbox.stop === \"function\") {\n await sandbox.stop(toSeconds(params.timeoutMs));\n return;\n }\n\n if (typeof client.stop === \"function\") {\n await client.stop(sandbox);\n }\n },\n\n async archiveSandbox(params) {\n const { sandbox } = await getSandbox(params.sandboxId);\n if (typeof sandbox.archive === \"function\") {\n await sandbox.archive();\n return;\n }\n\n throw BetterAgentError.fromCode(\n \"NOT_IMPLEMENTED\",\n \"The active Daytona SDK instance does not expose sandbox archiving.\",\n {\n context: { sandboxId: params.sandboxId },\n trace: [\n {\n at: \"plugins.sandbox.createDaytonaSandboxClient.archiveSandbox\",\n },\n ],\n },\n );\n },\n },\n };\n}\n","import { BetterAgentError } from \"@better-agent/shared/errors\";\nimport type {\n E2BSandboxClientConfig,\n SandboxClient,\n SandboxCommandParams,\n SandboxCommandResult,\n SandboxFileEntry,\n} from \"./types\";\n\ntype E2BSandboxModule = {\n Sandbox: {\n create: (\n templateOrOptions?: string | Record<string, unknown>,\n options?: Record<string, unknown>,\n ) => Promise<E2BSandboxInstance>;\n connect: (\n sandboxId: string,\n options?: Record<string, unknown>,\n ) => Promise<E2BSandboxInstance>;\n };\n};\n\ntype E2BSandboxInstance = {\n sandboxId: string;\n commands: {\n run: (\n cmd: string,\n options?: Record<string, unknown>,\n ) => Promise<{\n exitCode?: number;\n stdout?: string;\n stderr?: string;\n pid?: number;\n }>;\n };\n files: {\n read: (path: string, options?: Record<string, unknown>) => Promise<string>;\n write: (\n path: string,\n data: string,\n options?: Record<string, unknown>,\n ) => Promise<{ path?: string }>;\n list: (path: string, options?: Record<string, unknown>) => Promise<SandboxFileEntry[]>;\n makeDir: (path: string, options?: Record<string, unknown>) => Promise<boolean>;\n remove: (path: string, options?: Record<string, unknown>) => Promise<void>;\n };\n getHost: (port: number) => string;\n kill: (options?: Record<string, unknown>) => Promise<void>;\n};\n\nconst removeUndefined = (value: Record<string, unknown>) =>\n Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));\n\nconst loadE2B = async (): Promise<E2BSandboxModule> => {\n try {\n const moduleName = \"e2b\";\n return (await import(moduleName)) as E2BSandboxModule;\n } catch (error) {\n throw BetterAgentError.fromCode(\n \"INTERNAL\",\n \"The built-in E2B sandbox client requires the `e2b` package to be installed in the host app.\",\n {\n cause: error,\n trace: [{ at: \"plugins.sandbox.createE2BSandboxClient.loadE2B\" }],\n },\n );\n }\n};\n\n/**\n * Creates a sandbox client backed by the E2B SDK.\n */\nexport function createE2BSandboxClient(config: E2BSandboxClientConfig = {}): SandboxClient {\n const connectionOptions = removeUndefined({\n apiKey: config.apiKey,\n accessToken: config.accessToken,\n domain: config.domain,\n requestTimeoutMs: config.requestTimeoutMs,\n });\n\n const toCreateOptions = (params?: {\n lifecycle?: {\n ttlMs?: number;\n };\n envs?: Record<string, string>;\n metadata?: Record<string, string>;\n }) =>\n removeUndefined({\n ...connectionOptions,\n timeoutMs: params?.lifecycle?.ttlMs,\n envs: params?.envs,\n metadata: params?.metadata,\n });\n\n const connectSandbox = async (sandboxId: string): Promise<E2BSandboxInstance> => {\n const { Sandbox } = await loadE2B();\n return await Sandbox.connect(sandboxId, connectionOptions);\n };\n\n const mapCommandResult = (\n result: Awaited<ReturnType<E2BSandboxInstance[\"commands\"][\"run\"]>>,\n ): SandboxCommandResult => ({\n exitCode: result.exitCode,\n stdout: result.stdout,\n stderr: result.stderr,\n pid: result.pid,\n });\n\n return {\n provider: \"e2b\",\n capabilities: {\n commands: true,\n filesystem: true,\n preview: true,\n mcp: true,\n pty: true,\n desktop: true,\n },\n async createSandbox(params) {\n const { Sandbox } = await loadE2B();\n const template = params?.template;\n const options = toCreateOptions(params);\n\n const sandbox =\n template !== undefined\n ? await Sandbox.create(template, options)\n : await Sandbox.create(options);\n\n return { sandboxId: sandbox.sandboxId };\n },\n\n async runCommand(params: SandboxCommandParams) {\n const sandbox = await connectSandbox(params.sandboxId);\n return mapCommandResult(\n await sandbox.commands.run(\n params.cmd,\n removeUndefined({\n cwd: params.cwd,\n envs: params.envs,\n timeoutMs: params.timeoutMs,\n }),\n ),\n );\n },\n\n async readFile(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n return await sandbox.files.read(params.path);\n },\n\n async writeFile(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n const result = await sandbox.files.write(params.path, params.content);\n return { path: result.path ?? params.path };\n },\n\n async listFiles(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n return await sandbox.files.list(params.path);\n },\n\n async makeDir(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n return {\n created: await sandbox.files.makeDir(params.path),\n };\n },\n\n async removePath(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n await sandbox.files.remove(params.path);\n },\n\n async getHost(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n return sandbox.getHost(params.port);\n },\n\n async killSandbox(params) {\n const sandbox = await connectSandbox(params.sandboxId);\n await sandbox.kill();\n },\n };\n}\n","import type { SandboxSessionStore } from \"./types\";\n\n/** Creates an in-memory sandbox session store. */\nexport function createMemorySandboxSessionStore(): SandboxSessionStore {\n const sessions = new Map<string, string>();\n\n return {\n async get(key) {\n return sessions.get(key) ?? null;\n },\n async set(key, sandboxId) {\n sessions.set(key, sandboxId);\n },\n async delete(key) {\n sessions.delete(key);\n },\n };\n}\n","import { createValidationError } from \"../shared/validation\";\nimport type { SandboxCreateParams, SandboxPluginConfig } from \"./types\";\n\nconst hasLifecycleValues = (lifecycle: SandboxCreateParams[\"lifecycle\"] | undefined): boolean =>\n Boolean(\n lifecycle?.ttlMs !== undefined ||\n lifecycle?.idleStopMs !== undefined ||\n lifecycle?.archiveAfterMs !== undefined ||\n lifecycle?.deleteAfterMs !== undefined,\n );\n\nexport function validateSandboxCreateParams(\n clientProvider: string | undefined,\n params: SandboxCreateParams,\n): void {\n const provider = clientProvider?.trim().toLowerCase();\n if (!provider) {\n return;\n }\n\n if (provider === \"daytona\") {\n if (params.lifecycle?.ttlMs !== undefined) {\n throw createValidationError(\n \"`lifecycle.ttlMs` is not supported by the Daytona sandbox client. Use `startupTimeoutMs` for creation readiness and Daytona lifecycle fields like `idleStopMs`, `archiveAfterMs`, or `deleteAfterMs` instead.\",\n \"plugins.sandboxPlugin.createConfig.lifecycle.ttlMs\",\n );\n }\n\n return;\n }\n\n if (provider === \"e2b\") {\n if (params.startupTimeoutMs !== undefined) {\n throw createValidationError(\n \"`startupTimeoutMs` is not supported by the E2B sandbox client. Use `lifecycle.ttlMs` to control sandbox lifetime.\",\n \"plugins.sandboxPlugin.createConfig.startupTimeoutMs\",\n );\n }\n\n if (\n params.lifecycle?.idleStopMs !== undefined ||\n params.lifecycle?.archiveAfterMs !== undefined ||\n params.lifecycle?.deleteAfterMs !== undefined\n ) {\n throw createValidationError(\n \"`lifecycle.idleStopMs`, `lifecycle.archiveAfterMs`, and `lifecycle.deleteAfterMs` are not supported by the E2B sandbox client.\",\n \"plugins.sandboxPlugin.createConfig.lifecycle\",\n );\n }\n\n return;\n }\n\n if (hasLifecycleValues(params.lifecycle) || params.startupTimeoutMs !== undefined) {\n return;\n }\n}\n\n/** Validates `sandboxPlugin` configuration. */\nexport function validateSandboxPluginConfig(config: SandboxPluginConfig): void {\n const client = config.client;\n\n if (!client || typeof client !== \"object\") {\n throw createValidationError(\n \"`sandboxPlugin` requires a `client`.\",\n \"plugins.sandboxPlugin\",\n );\n }\n\n if (config.prefix !== undefined && config.prefix.trim().length === 0) {\n throw createValidationError(\n \"`sandboxPlugin` requires `prefix` to be a non-empty string when provided.\",\n \"plugins.sandboxPlugin\",\n );\n }\n\n if (config.createConfig) {\n validateSandboxCreateParams(config.client.provider, config.createConfig);\n }\n\n if (config.createDefaults) {\n validateSandboxCreateParams(config.client.provider, config.createDefaults);\n }\n}\n","import { type Plugin, type ToolRunContext, defineTool } from \"@better-agent/core\";\nimport { BetterAgentError } from \"@better-agent/shared/errors\";\nimport { createMemorySandboxSessionStore } from \"./memory-store\";\nimport type { SandboxCreateParams, SandboxPluginConfig } from \"./types\";\nimport { validateSandboxCreateParams, validateSandboxPluginConfig } from \"./validate\";\n\nconst trimToUndefined = (value: string | undefined): string | undefined => {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n};\n\nconst normalizeHostUrl = (value: string): string =>\n /^[a-z][a-z0-9+.-]*:\\/\\//i.test(value) ? value : `https://${value}`;\n\nconst createValidationError = (message: string, at: string, context?: Record<string, unknown>) =>\n BetterAgentError.fromCode(\"VALIDATION_FAILED\", message, {\n ...(context !== undefined ? { context } : {}),\n trace: [{ at }],\n });\n\ntype ResolvedSandboxRef = {\n sandboxId: string;\n sessionKey?: string;\n created: boolean;\n};\n\ntype SessionPolicy =\n | {\n kind: \"managed\";\n sessionKey: string;\n }\n | {\n kind: \"disabled\";\n };\n\nconst resolveCreateParams = (\n overrides: SandboxCreateParams | undefined,\n createConfig: SandboxCreateParams | undefined,\n createDefaults: SandboxCreateParams | undefined,\n): SandboxCreateParams => ({\n template: createConfig?.template ?? overrides?.template ?? createDefaults?.template,\n startupTimeoutMs:\n createConfig?.startupTimeoutMs ??\n overrides?.startupTimeoutMs ??\n createDefaults?.startupTimeoutMs,\n envs:\n createDefaults?.envs || overrides?.envs || createConfig?.envs\n ? {\n ...(createDefaults?.envs ?? {}),\n ...(overrides?.envs ?? {}),\n ...(createConfig?.envs ?? {}),\n }\n : undefined,\n metadata:\n createDefaults?.metadata || overrides?.metadata || createConfig?.metadata\n ? {\n ...(createDefaults?.metadata ?? {}),\n ...(overrides?.metadata ?? {}),\n ...(createConfig?.metadata ?? {}),\n }\n : undefined,\n lifecycle:\n createDefaults?.lifecycle || overrides?.lifecycle || createConfig?.lifecycle\n ? {\n ...(createDefaults?.lifecycle ?? {}),\n ...(overrides?.lifecycle ?? {}),\n ...(createConfig?.lifecycle ?? {}),\n }\n : undefined,\n});\n\n/**\n * Adds sandbox tools.\n *\n * By default, the plugin reuses one sandbox per `conversationId`.\n * Use `sessionKey` to customize reuse, or return `null`/`undefined`\n * to disable reuse for a specific tool call.\n *\n * Uses an in-memory store by default.\n *\n * @example\n * ```ts\n * import { sandboxPlugin, createE2BSandboxClient } from \"@better-agent/plugins\";\n *\n * const plugin = sandboxPlugin({\n * client: createE2BSandboxClient({\n * apiKey: process.env.E2B_API_KEY,\n * }),\n * createConfig: {\n * template: \"base\",\n * },\n * createDefaults: {\n * startupTimeoutMs: 90_000,\n * },\n * });\n * ```\n */\nexport const sandboxPlugin = (pluginConfig: SandboxPluginConfig): Plugin => {\n validateSandboxPluginConfig(pluginConfig);\n\n const sandboxClient = pluginConfig.client;\n const store = pluginConfig.store ?? createMemorySandboxSessionStore();\n const prefix = trimToUndefined(pluginConfig.prefix) ?? \"sandbox\";\n const nameFor = (suffix: string) => `${prefix}_${suffix}`;\n\n const getSessionPolicy = (ctx: ToolRunContext, toolName: string): SessionPolicy => {\n if (pluginConfig.sessionKey) {\n const custom = trimToUndefined(\n pluginConfig.sessionKey({\n runId: ctx.runId,\n agentName: ctx.agentName,\n ...(ctx.conversationId !== undefined\n ? { conversationId: ctx.conversationId }\n : {}),\n toolName,\n }) ?? undefined,\n );\n\n return custom !== undefined\n ? { kind: \"managed\", sessionKey: custom }\n : { kind: \"disabled\" };\n }\n\n return ctx.conversationId\n ? { kind: \"managed\", sessionKey: `conversation:${ctx.conversationId}` }\n : { kind: \"disabled\" };\n };\n\n const getExplicitSandboxId = (value: string | undefined): string | undefined => {\n if (value === undefined) {\n return undefined;\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n throw createValidationError(\n \"`sandboxId` must be a non-empty string when provided.\",\n \"plugins.sandboxPlugin.sandboxId\",\n );\n }\n\n return trimmed;\n };\n\n const createSandbox = async (\n params: SandboxCreateParams | undefined,\n ctx: ToolRunContext,\n toolName: string,\n ): Promise<ResolvedSandboxRef> => {\n const sessionPolicy = getSessionPolicy(ctx, toolName);\n const resolvedParams = resolveCreateParams(\n params,\n pluginConfig.createConfig,\n pluginConfig.createDefaults,\n );\n validateSandboxCreateParams(sandboxClient.provider, resolvedParams);\n const created = await sandboxClient.createSandbox(resolvedParams);\n\n if (sessionPolicy.kind === \"managed\") {\n await store.set(sessionPolicy.sessionKey, created.sandboxId);\n }\n\n return {\n sandboxId: created.sandboxId,\n ...(sessionPolicy.kind === \"managed\" ? { sessionKey: sessionPolicy.sessionKey } : {}),\n created: true,\n };\n };\n\n const resolveSandbox = async (params: {\n sandboxId?: string;\n createIfMissing: boolean;\n createParams?: SandboxCreateParams;\n ctx: ToolRunContext;\n toolName: string;\n }): Promise<ResolvedSandboxRef> => {\n const explicitSandboxId = getExplicitSandboxId(params.sandboxId);\n if (explicitSandboxId) {\n return { sandboxId: explicitSandboxId, created: false };\n }\n\n const sessionPolicy = getSessionPolicy(params.ctx, params.toolName);\n if (sessionPolicy.kind === \"managed\") {\n const existing = trimToUndefined(\n (await store.get(sessionPolicy.sessionKey)) ?? undefined,\n );\n if (existing) {\n return {\n sandboxId: existing,\n sessionKey: sessionPolicy.sessionKey,\n created: false,\n };\n }\n }\n\n if (!params.createIfMissing) {\n throw createValidationError(\n `No sandbox is available for this ${params.ctx.conversationId ? \"conversation\" : \"run\"}. Create one first with '${nameFor(\"create\")}' or pass a sandboxId explicitly.`,\n \"plugins.sandboxPlugin.resolveSandbox.missing\",\n {\n runId: params.ctx.runId,\n agentName: params.ctx.agentName,\n conversationId: params.ctx.conversationId,\n toolName: params.toolName,\n },\n );\n }\n\n return await createSandbox(params.createParams, params.ctx, params.toolName);\n };\n\n const clearManagedSessionIfMatches = async (\n ctx: ToolRunContext,\n toolName: string,\n sandboxId: string,\n ): Promise<string | undefined> => {\n const sessionPolicy = getSessionPolicy(ctx, toolName);\n if (sessionPolicy.kind !== \"managed\") {\n return undefined;\n }\n\n const current = await store.get(sessionPolicy.sessionKey);\n if (current === sandboxId) {\n await store.delete(sessionPolicy.sessionKey);\n return sessionPolicy.sessionKey;\n }\n\n return undefined;\n };\n\n const createSchema = {\n type: \"object\",\n properties: {\n forceNew: { type: \"boolean\" },\n template: { type: \"string\" },\n startupTimeoutMs: { type: \"number\", exclusiveMinimum: 0 },\n envs: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n },\n metadata: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n },\n lifecycle: {\n type: \"object\",\n properties: {\n ttlMs: { type: \"number\", exclusiveMinimum: 0 },\n idleStopMs: { type: \"number\", exclusiveMinimum: 0 },\n archiveAfterMs: { type: \"number\", exclusiveMinimum: 0 },\n deleteAfterMs: { type: \"number\", exclusiveMinimum: 0 },\n },\n additionalProperties: false,\n },\n },\n additionalProperties: false,\n } as const;\n\n const sandboxIdSchema = {\n type: \"string\",\n } as const;\n\n const pathSchema = {\n type: \"string\",\n minLength: 1,\n } as const;\n\n const envsSchema = {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n } as const;\n\n const createTool = defineTool({\n name: nameFor(\"create\"),\n description:\n \"Create a sandbox, or reuse the current conversation sandbox unless forceNew is true.\",\n schema: createSchema,\n }).server(async (input, ctx) => {\n if (!input.forceNew) {\n const sessionPolicy = getSessionPolicy(ctx, nameFor(\"create\"));\n if (sessionPolicy.kind === \"managed\") {\n const existing = trimToUndefined(\n (await store.get(sessionPolicy.sessionKey)) ?? undefined,\n );\n if (existing) {\n return {\n sandboxId: existing,\n reused: true,\n created: false,\n sessionKey: sessionPolicy.sessionKey,\n };\n }\n }\n }\n\n const resolved = await createSandbox(\n {\n template: input.template,\n startupTimeoutMs: input.startupTimeoutMs,\n envs: input.envs,\n metadata: input.metadata,\n lifecycle: input.lifecycle,\n },\n ctx,\n nameFor(\"create\"),\n );\n\n return {\n sandboxId: resolved.sandboxId,\n reused: false,\n created: true,\n ...(resolved.sessionKey !== undefined ? { sessionKey: resolved.sessionKey } : {}),\n };\n });\n\n const execTool = defineTool({\n name: nameFor(\"exec\"),\n description:\n \"Run one shell command inside a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n cmd: { type: \"string\", minLength: 1 },\n cwd: { type: \"string\" },\n timeoutMs: { type: \"number\", exclusiveMinimum: 0 },\n envs: envsSchema,\n },\n required: [\"cmd\"],\n additionalProperties: false,\n } as const,\n approval: pluginConfig.approvals?.exec,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"exec\"),\n });\n const result = await sandboxClient.runCommand({\n sandboxId: resolved.sandboxId,\n cmd: input.cmd,\n cwd: input.cwd,\n timeoutMs: input.timeoutMs,\n envs: input.envs,\n });\n\n return {\n sandboxId: resolved.sandboxId,\n createdSandbox: resolved.created,\n ...result,\n };\n });\n\n const readFileTool = defineTool({\n name: nameFor(\"read_file\"),\n description:\n \"Read one text file from a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n },\n required: [\"path\"],\n additionalProperties: false,\n } as const,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"read_file\"),\n });\n\n return {\n sandboxId: resolved.sandboxId,\n path: input.path,\n content: await sandboxClient.readFile({\n sandboxId: resolved.sandboxId,\n path: input.path,\n }),\n };\n });\n\n const writeFileTool = defineTool({\n name: nameFor(\"write_file\"),\n description:\n \"Write one text file into a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n content: { type: \"string\" },\n },\n required: [\"path\", \"content\"],\n additionalProperties: false,\n } as const,\n approval: pluginConfig.approvals?.writeFile,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"write_file\"),\n });\n const result = await sandboxClient.writeFile({\n sandboxId: resolved.sandboxId,\n path: input.path,\n content: input.content,\n });\n\n return {\n sandboxId: resolved.sandboxId,\n createdSandbox: resolved.created,\n path: result.path,\n };\n });\n\n const listFilesTool = defineTool({\n name: nameFor(\"list_files\"),\n description:\n \"List directory entries inside a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n },\n required: [\"path\"],\n additionalProperties: false,\n } as const,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"list_files\"),\n });\n\n return {\n sandboxId: resolved.sandboxId,\n path: input.path,\n entries: await sandboxClient.listFiles({\n sandboxId: resolved.sandboxId,\n path: input.path,\n }),\n };\n });\n\n const makeDirTool = defineTool({\n name: nameFor(\"make_dir\"),\n description:\n \"Create a directory inside a sandbox. Creates a sandbox automatically when none exists for the conversation.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n },\n required: [\"path\"],\n additionalProperties: false,\n } as const,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: true,\n ctx,\n toolName: nameFor(\"make_dir\"),\n });\n const result = await sandboxClient.makeDir({\n sandboxId: resolved.sandboxId,\n path: input.path,\n });\n\n return {\n sandboxId: resolved.sandboxId,\n path: input.path,\n created: result.created,\n };\n });\n\n const removePathTool = defineTool({\n name: nameFor(\"remove_path\"),\n description: \"Remove a file or directory from a sandbox.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n path: pathSchema,\n },\n required: [\"path\"],\n additionalProperties: false,\n } as const,\n approval: pluginConfig.approvals?.removePath,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: false,\n ctx,\n toolName: nameFor(\"remove_path\"),\n });\n await sandboxClient.removePath({\n sandboxId: resolved.sandboxId,\n path: input.path,\n });\n\n return {\n sandboxId: resolved.sandboxId,\n removed: true,\n path: input.path,\n };\n });\n\n const getHostTool = defineTool({\n name: nameFor(\"get_host\"),\n description:\n \"Expose one sandbox port as a host URL so callers can reach an app running inside the sandbox.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n port: { type: \"number\", minimum: 1, maximum: 65535 },\n },\n required: [\"port\"],\n additionalProperties: false,\n } as const,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: false,\n ctx,\n toolName: nameFor(\"get_host\"),\n });\n const hostResult = await sandboxClient.getHost({\n sandboxId: resolved.sandboxId,\n port: input.port,\n });\n const preview = typeof hostResult === \"string\" ? undefined : hostResult;\n const host = normalizeHostUrl(typeof hostResult === \"string\" ? hostResult : hostResult.url);\n\n return {\n sandboxId: resolved.sandboxId,\n port: input.port,\n host,\n ...(preview?.token !== undefined ? { token: preview.token } : {}),\n };\n });\n\n const killTool = defineTool({\n name: nameFor(\"kill\"),\n description:\n \"Terminate a sandbox and clear the current conversation sandbox when applicable.\",\n schema: {\n type: \"object\",\n properties: {\n sandboxId: sandboxIdSchema,\n },\n additionalProperties: false,\n } as const,\n approval: pluginConfig.approvals?.killSandbox,\n }).server(async (input, ctx) => {\n const resolved = await resolveSandbox({\n sandboxId: input.sandboxId,\n createIfMissing: false,\n ctx,\n toolName: nameFor(\"kill\"),\n });\n\n await sandboxClient.killSandbox({\n sandboxId: resolved.sandboxId,\n });\n\n const clearedSessionKey = await clearManagedSessionIfMatches(\n ctx,\n nameFor(\"kill\"),\n resolved.sandboxId,\n );\n\n return {\n sandboxId: resolved.sandboxId,\n killed: true,\n ...(clearedSessionKey !== undefined ? { clearedSessionKey } : {}),\n };\n });\n\n // @ts-ignore\n const tools = [\n createTool,\n execTool,\n readFileTool,\n writeFileTool,\n listFilesTool,\n makeDirTool,\n removePathTool,\n getHostTool,\n killTool,\n ];\n\n const plugin: Plugin = {\n id: pluginConfig.id ?? \"sandbox\",\n tools,\n };\n\n return plugin;\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-agent/plugins",
3
- "version": "0.1.0-beta.2",
3
+ "version": "0.1.0-beta.4",
4
4
  "description": "Better Agent plugins TypeScript library",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -36,7 +36,7 @@
36
36
  "access": "public"
37
37
  },
38
38
  "dependencies": {
39
- "@better-agent/shared": "0.1.0-beta.2"
39
+ "@better-agent/shared": "0.1.0-beta.4"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@daytonaio/sdk": "^0.161.0",
@@ -45,6 +45,6 @@
45
45
  "e2b": "^2.19.0"
46
46
  },
47
47
  "peerDependencies": {
48
- "@better-agent/core": "0.1.0-beta.2"
48
+ "@better-agent/core": "0.1.0-beta.4"
49
49
  }
50
50
  }