@declaw/sdk 1.2.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -509,7 +509,7 @@ function createInjectionDefenseConfig(opts) {
509
509
  enabled: opts?.enabled ?? false,
510
510
  sensitivity: opts?.sensitivity ?? "medium" /* Medium */,
511
511
  action: opts?.action ?? "log_only" /* LogOnly */,
512
- threshold: opts?.threshold ?? 0.8,
512
+ threshold: opts?.threshold ?? 0.95,
513
513
  domains: opts?.domains,
514
514
  judge: opts?.judge,
515
515
  injectionMode: opts?.injectionMode
@@ -536,7 +536,7 @@ function parseInjectionDefenseConfig(data) {
536
536
  enabled: data.enabled ?? false,
537
537
  sensitivity: data.sensitivity ?? "medium" /* Medium */,
538
538
  action: data.action ?? "log_only" /* LogOnly */,
539
- threshold: data.threshold ?? 0.8,
539
+ threshold: data.threshold ?? 0.95,
540
540
  domains: data.domains,
541
541
  judge: data.judge ? { enabled: data.judge.enabled ?? false, always: data.judge.always, policy: data.judge.policy } : void 0,
542
542
  injectionMode: data.injection_mode ?? data.injectionMode
@@ -914,14 +914,14 @@ function fullInjectionDefensePolicy(opts) {
914
914
  injectionDefense: createInjectionDefenseConfig({
915
915
  enabled: true,
916
916
  action: opts?.action ?? "block",
917
- threshold: opts?.threshold ?? 0.8,
917
+ threshold: opts?.threshold ?? 0.95,
918
918
  domains: opts?.domains,
919
919
  injectionMode: opts?.mode ?? "balanced",
920
920
  judge: { enabled: true, always: opts?.alwaysJudge ?? false, policy: opts?.agentPolicy ?? "" }
921
921
  }),
922
922
  customPolicy: createCustomPolicyConfig({
923
923
  enabled: true,
924
- policyRef: "prompt-injection@v2",
924
+ policyRef: "prompt-injection@v3",
925
925
  defaultDeny: false
926
926
  })
927
927
  });
@@ -962,7 +962,7 @@ function securityPolicyToJSON(policy) {
962
962
  action: injDefConfig.action,
963
963
  threshold: injDefConfig.threshold
964
964
  };
965
- if (injDefConfig.domains !== void 0) {
965
+ if (injDefConfig.domains !== void 0 && injDefConfig.domains.length > 0) {
966
966
  injDef.domains = injDefConfig.domains;
967
967
  }
968
968
  if (injDefConfig.injectionMode !== void 0) {
@@ -2074,6 +2074,311 @@ function volumeAttachmentToJSON(att) {
2074
2074
  return out;
2075
2075
  }
2076
2076
 
2077
+ // src/vault/models.ts
2078
+ function parseVaultScope(data) {
2079
+ const scope = {
2080
+ domainRegex: String(data.domain_regex ?? "")
2081
+ };
2082
+ if (data.injection_type !== void 0 && data.injection_type !== null) {
2083
+ scope.injectionType = String(data.injection_type);
2084
+ }
2085
+ if (data.header_name !== void 0 && data.header_name !== null) {
2086
+ scope.headerName = String(data.header_name);
2087
+ }
2088
+ if (data.value_prefix !== void 0 && data.value_prefix !== null) {
2089
+ scope.valuePrefix = String(data.value_prefix);
2090
+ }
2091
+ if (data.basic_username !== void 0 && data.basic_username !== null) {
2092
+ scope.basicUsername = String(data.basic_username);
2093
+ }
2094
+ if (data.extra_headers !== void 0 && data.extra_headers !== null) {
2095
+ scope.extraHeaders = data.extra_headers;
2096
+ }
2097
+ if (data.query_params !== void 0 && data.query_params !== null) {
2098
+ scope.queryParams = data.query_params;
2099
+ }
2100
+ return scope;
2101
+ }
2102
+ function parseVaultSecret(data) {
2103
+ const secret = {
2104
+ secretId: String(data.secret_id ?? ""),
2105
+ name: String(data.name ?? ""),
2106
+ createdAt: String(data.created_at ?? ""),
2107
+ updatedAt: String(data.updated_at ?? "")
2108
+ };
2109
+ const rawScopes = data.scopes;
2110
+ if (rawScopes && rawScopes.length > 0) {
2111
+ secret.scopes = rawScopes.map(parseVaultScope);
2112
+ }
2113
+ if (data.rotated_at !== void 0 && data.rotated_at !== null) {
2114
+ secret.rotatedAt = String(data.rotated_at);
2115
+ }
2116
+ if (data.rotation_interval_days !== void 0 && data.rotation_interval_days !== null) {
2117
+ secret.rotationIntervalDays = Number(data.rotation_interval_days);
2118
+ }
2119
+ if (data.rotation_due !== void 0 && data.rotation_due !== null) {
2120
+ secret.rotationDue = Boolean(data.rotation_due);
2121
+ }
2122
+ return secret;
2123
+ }
2124
+ function parseVaultPreset(data) {
2125
+ const rawScopes = data.scopes ?? [];
2126
+ const preset = {
2127
+ key: String(data.key ?? ""),
2128
+ name: String(data.name ?? ""),
2129
+ category: String(data.category ?? ""),
2130
+ keyHint: String(data.key_hint ?? ""),
2131
+ scopes: rawScopes.map(parseVaultScope)
2132
+ };
2133
+ if (data.docs_url !== void 0 && data.docs_url !== null) {
2134
+ preset.docsUrl = String(data.docs_url);
2135
+ }
2136
+ return preset;
2137
+ }
2138
+ function vaultScopeToJSON(scope) {
2139
+ const out = {
2140
+ domain_regex: scope.domainRegex
2141
+ };
2142
+ if (scope.injectionType !== void 0) {
2143
+ out.injection_type = scope.injectionType;
2144
+ }
2145
+ if (scope.headerName !== void 0) {
2146
+ out.header_name = scope.headerName;
2147
+ }
2148
+ if (scope.valuePrefix !== void 0) {
2149
+ out.value_prefix = scope.valuePrefix;
2150
+ }
2151
+ if (scope.basicUsername !== void 0) {
2152
+ out.basic_username = scope.basicUsername;
2153
+ }
2154
+ if (scope.extraHeaders !== void 0) {
2155
+ out.extra_headers = scope.extraHeaders;
2156
+ }
2157
+ if (scope.queryParams !== void 0) {
2158
+ out.query_params = scope.queryParams;
2159
+ }
2160
+ return out;
2161
+ }
2162
+
2163
+ // src/vault/vault.ts
2164
+ var DEFAULT_TEAM_NAME = "default";
2165
+ var DEFAULT_ENV_NAME = "prod";
2166
+ var defaultTeamCache = /* @__PURE__ */ new Map();
2167
+ function cacheKey(config) {
2168
+ return `${config.apiUrl}\0${config.apiKey}`;
2169
+ }
2170
+ async function resolveDefaultTeamId(config, create, timeout) {
2171
+ const key = cacheKey(config);
2172
+ const cached = defaultTeamCache.get(key);
2173
+ if (cached !== void 0) return cached;
2174
+ const client = getSharedClient(config);
2175
+ const resp = await client.get("/teams", { timeout });
2176
+ const rows = resp.teams ?? [];
2177
+ let best = null;
2178
+ for (const t of rows) {
2179
+ if (t.name === DEFAULT_TEAM_NAME) {
2180
+ if (best === null || t.created_at < best.created_at) {
2181
+ best = t;
2182
+ }
2183
+ }
2184
+ }
2185
+ if (best !== null) {
2186
+ defaultTeamCache.set(key, best.team_id);
2187
+ return best.team_id;
2188
+ }
2189
+ if (!create) return null;
2190
+ const created = await client.post("/teams", {
2191
+ json: { name: DEFAULT_TEAM_NAME },
2192
+ timeout
2193
+ });
2194
+ defaultTeamCache.set(key, created.team_id);
2195
+ return created.team_id;
2196
+ }
2197
+ async function ensureDefaultEnv(config, teamId, timeout) {
2198
+ const client = getSharedClient(config);
2199
+ const resp = await client.get(
2200
+ `/teams/${encodeURIComponent(teamId)}/environments`,
2201
+ { timeout }
2202
+ );
2203
+ const rows = resp.environments ?? [];
2204
+ if (rows.some((e) => e.name === DEFAULT_ENV_NAME)) return;
2205
+ try {
2206
+ await client.post(`/teams/${encodeURIComponent(teamId)}/environments`, {
2207
+ json: { name: DEFAULT_ENV_NAME },
2208
+ timeout
2209
+ });
2210
+ } catch {
2211
+ const resp2 = await client.get(
2212
+ `/teams/${encodeURIComponent(teamId)}/environments`,
2213
+ { timeout }
2214
+ );
2215
+ const rows2 = resp2.environments ?? [];
2216
+ if (rows2.some((e) => e.name === DEFAULT_ENV_NAME)) return;
2217
+ throw new Error(`Failed to ensure default environment "${DEFAULT_ENV_NAME}" on team ${teamId}`);
2218
+ }
2219
+ }
2220
+ async function expandVaultRefs(config, refs, timeout) {
2221
+ if (Object.keys(refs).length === 0) return refs;
2222
+ const needsTeam = Object.values(refs).some((v) => !v.startsWith("vault://"));
2223
+ if (!needsTeam) return refs;
2224
+ const teamId = await resolveDefaultTeamId(config, false, timeout);
2225
+ if (teamId === null) {
2226
+ throw new Error("vault_refs given but no vault secrets exist for this account");
2227
+ }
2228
+ const out = {};
2229
+ for (const [envVar, ref] of Object.entries(refs)) {
2230
+ out[envVar] = ref.startsWith("vault://") ? ref : `vault://${teamId}/${DEFAULT_ENV_NAME}/${ref}`;
2231
+ }
2232
+ return out;
2233
+ }
2234
+ function buildConfig(opts) {
2235
+ return new ConnectionConfig({
2236
+ apiKey: opts?.apiKey,
2237
+ domain: opts?.domain,
2238
+ apiUrl: opts?.apiUrl,
2239
+ requestTimeout: opts?.requestTimeout
2240
+ });
2241
+ }
2242
+ var Vault = class _Vault {
2243
+ // -------------------------------------------------------------------------
2244
+ // Secrets
2245
+ // -------------------------------------------------------------------------
2246
+ /**
2247
+ * Store a secret's value (server-side, in OpenBao) plus its injection
2248
+ * scopes, under the auto-provisioned default team + "prod" environment.
2249
+ * Returns metadata only — the value is never echoed.
2250
+ *
2251
+ * POST /teams/{teamId}/vault/secrets
2252
+ */
2253
+ static async createSecret(input, opts) {
2254
+ const config = buildConfig(opts);
2255
+ const teamId = await resolveDefaultTeamId(config, true, opts?.requestTimeout);
2256
+ if (teamId === null) throw new Error("Failed to resolve or create default team");
2257
+ await ensureDefaultEnv(config, teamId, opts?.requestTimeout);
2258
+ const body = {
2259
+ environment: DEFAULT_ENV_NAME,
2260
+ value: input.value
2261
+ };
2262
+ if (input.name) body.name = input.name;
2263
+ if (input.provider) body.provider = input.provider;
2264
+ if (input.scopes && input.scopes.length > 0) {
2265
+ body.scopes = input.scopes.map(vaultScopeToJSON);
2266
+ }
2267
+ if (input.rotationIntervalDays && input.rotationIntervalDays > 0) {
2268
+ body.rotation_interval_days = input.rotationIntervalDays;
2269
+ }
2270
+ const client = getSharedClient(config);
2271
+ const resp = await client.post(
2272
+ `/teams/${encodeURIComponent(teamId)}/vault/secrets`,
2273
+ { json: body, timeout: opts?.requestTimeout }
2274
+ );
2275
+ return parseVaultSecret(resp);
2276
+ }
2277
+ /**
2278
+ * List secret metadata for the default team. Returns an empty array if no
2279
+ * default team has been provisioned yet.
2280
+ *
2281
+ * GET /teams/{teamId}/vault/secrets -> {secrets}
2282
+ */
2283
+ static async listSecrets(opts) {
2284
+ const config = buildConfig(opts);
2285
+ const teamId = await resolveDefaultTeamId(config, false, opts?.requestTimeout);
2286
+ if (teamId === null) return [];
2287
+ const client = getSharedClient(config);
2288
+ const resp = await client.get(
2289
+ `/teams/${encodeURIComponent(teamId)}/vault/secrets`,
2290
+ { timeout: opts?.requestTimeout }
2291
+ );
2292
+ const rows = resp.secrets ?? [];
2293
+ return rows.map(parseVaultSecret);
2294
+ }
2295
+ /**
2296
+ * Replace a secret's value by name (server-side); scopes are unchanged.
2297
+ *
2298
+ * POST /teams/{teamId}/vault/secrets/{secretId}/rotate {value}
2299
+ */
2300
+ static async rotateSecret(name, value, opts) {
2301
+ const config = buildConfig(opts);
2302
+ const teamId = await resolveDefaultTeamId(config, false, opts?.requestTimeout);
2303
+ if (teamId === null) throw new Error(`vault secret "${name}" not found`);
2304
+ const secretId = await _Vault._resolveSecretId(config, teamId, name, opts?.requestTimeout);
2305
+ const client = getSharedClient(config);
2306
+ await client.post(
2307
+ `/teams/${encodeURIComponent(teamId)}/vault/secrets/${encodeURIComponent(secretId)}/rotate`,
2308
+ { json: { value }, timeout: opts?.requestTimeout }
2309
+ );
2310
+ }
2311
+ /**
2312
+ * Delete a secret by name — metadata and stored value.
2313
+ *
2314
+ * DELETE /teams/{teamId}/vault/secrets/{secretId}
2315
+ */
2316
+ static async deleteSecret(name, opts) {
2317
+ const config = buildConfig(opts);
2318
+ const teamId = await resolveDefaultTeamId(config, false, opts?.requestTimeout);
2319
+ if (teamId === null) throw new Error(`vault secret "${name}" not found`);
2320
+ const secretId = await _Vault._resolveSecretId(config, teamId, name, opts?.requestTimeout);
2321
+ const client = getSharedClient(config);
2322
+ await client.delete(
2323
+ `/teams/${encodeURIComponent(teamId)}/vault/secrets/${encodeURIComponent(secretId)}`,
2324
+ { timeout: opts?.requestTimeout }
2325
+ );
2326
+ }
2327
+ /**
2328
+ * Replace a secret's injection scopes by name; the value is unchanged. Use
2329
+ * this to change a secret's destination(s) or injection format in place
2330
+ * instead of delete + recreate. At least one scope is required.
2331
+ *
2332
+ * POST /teams/{teamId}/vault/secrets/{secretId}/scopes
2333
+ */
2334
+ static async updateScopes(name, scopes, opts) {
2335
+ if (!scopes || scopes.length === 0) {
2336
+ throw new Error("at least one scope is required");
2337
+ }
2338
+ const config = buildConfig(opts);
2339
+ const teamId = await resolveDefaultTeamId(config, false, opts?.requestTimeout);
2340
+ if (teamId === null) throw new Error(`vault secret "${name}" not found`);
2341
+ const secretId = await _Vault._resolveSecretId(config, teamId, name, opts?.requestTimeout);
2342
+ const client = getSharedClient(config);
2343
+ await client.post(
2344
+ `/teams/${encodeURIComponent(teamId)}/vault/secrets/${encodeURIComponent(secretId)}/scopes`,
2345
+ { json: { scopes: scopes.map(vaultScopeToJSON) }, timeout: opts?.requestTimeout }
2346
+ );
2347
+ }
2348
+ // -------------------------------------------------------------------------
2349
+ // Presets
2350
+ // -------------------------------------------------------------------------
2351
+ /**
2352
+ * List built-in provider preset catalog (templates only, no secret material).
2353
+ *
2354
+ * GET /vault/presets -> {presets}
2355
+ */
2356
+ static async listPresets(opts) {
2357
+ const client = getSharedClient(buildConfig(opts));
2358
+ const resp = await client.get("/vault/presets", {
2359
+ timeout: opts?.requestTimeout
2360
+ });
2361
+ const rows = resp.presets ?? [];
2362
+ return rows.map(parseVaultPreset);
2363
+ }
2364
+ // -------------------------------------------------------------------------
2365
+ // Internal helpers
2366
+ // -------------------------------------------------------------------------
2367
+ /** Maps a secret name to its id within the given team. */
2368
+ static async _resolveSecretId(config, teamId, name, timeout) {
2369
+ const client = getSharedClient(config);
2370
+ const resp = await client.get(
2371
+ `/teams/${encodeURIComponent(teamId)}/vault/secrets`,
2372
+ { timeout }
2373
+ );
2374
+ const rows = resp.secrets ?? [];
2375
+ for (const s of rows) {
2376
+ if (s.name === name) return String(s.secret_id ?? "");
2377
+ }
2378
+ throw new Error(`vault secret "${name}" not found`);
2379
+ }
2380
+ };
2381
+
2077
2382
  // src/sandbox/sandbox.ts
2078
2383
  var DEFAULT_TEMPLATE = "base";
2079
2384
  var DEFAULT_TIMEOUT = 300;
@@ -2219,6 +2524,9 @@ var Sandbox = class _Sandbox {
2219
2524
  if (opts?.envs) {
2220
2525
  body.envs = opts.envs;
2221
2526
  }
2527
+ if (opts?.vaultRefs) {
2528
+ body.vault_refs = await expandVaultRefs(config, opts.vaultRefs, opts.requestTimeout);
2529
+ }
2222
2530
  if (opts?.network) {
2223
2531
  body.network = networkOptsToJSON(opts.network);
2224
2532
  } else if (opts?.allowInternetAccess === false) {
@@ -3122,7 +3430,16 @@ function assertValidVolumeId3(id) {
3122
3430
  }
3123
3431
  }
3124
3432
  var Volumes = class {
3125
- /** Create a volume by streaming a tarball (gzip tar.gz) to the server. */
3433
+ /**
3434
+ * Create a volume named `name`, optionally populated with `data`.
3435
+ *
3436
+ * `POST /volumes` is the canonical create endpoint. With `data` (a gzip tar.gz)
3437
+ * the body is ingested into a new file-granular volume (or a legacy tarball
3438
+ * blob if no file-granular backend is configured). Creating an empty volume
3439
+ * (no `data`, or an empty buffer) requires a file-granular backend.
3440
+ * `empty(name)` / `ingest(name, data)` remain available for explicit,
3441
+ * backend-specific control.
3442
+ */
3126
3443
  static async create(name, data, opts) {
3127
3444
  if (!name) {
3128
3445
  throw new InvalidArgumentError("volume name is required");
@@ -3134,6 +3451,13 @@ var Volumes = class {
3134
3451
  requestTimeout: opts?.requestTimeout
3135
3452
  });
3136
3453
  const client = getSharedClient(config);
3454
+ if (data === void 0 || data.byteLength === 0) {
3455
+ const resp2 = await client.post("/volumes", {
3456
+ params: { name },
3457
+ timeout: opts?.requestTimeout
3458
+ });
3459
+ return parseVolumeInfo(resp2);
3460
+ }
3137
3461
  const body = data instanceof Uint8Array ? data : new Uint8Array(data);
3138
3462
  const resp = await client.post("/volumes", {
3139
3463
  params: { name },
@@ -3437,6 +3761,7 @@ export {
3437
3761
  TemplateError,
3438
3762
  TimeoutError,
3439
3763
  TransformDirection,
3764
+ Vault,
3440
3765
  VolumeFiles,
3441
3766
  VolumeLocks,
3442
3767
  Volumes,
@@ -3488,6 +3813,9 @@ export {
3488
3813
  parseSnapshotInfo,
3489
3814
  parseTemplateBuildStatus,
3490
3815
  parseToxicityConfig,
3816
+ parseVaultPreset,
3817
+ parseVaultScope,
3818
+ parseVaultSecret,
3491
3819
  parseVolumeInfo,
3492
3820
  parseWriteInfo,
3493
3821
  requiresTlsInterception,
@@ -3495,6 +3823,7 @@ export {
3495
3823
  securityPolicyToJSON,
3496
3824
  toxicityConfigToJSON,
3497
3825
  validateNetworkEntry,
3826
+ vaultScopeToJSON,
3498
3827
  volumeAttachmentToJSON
3499
3828
  };
3500
3829
  //# sourceMappingURL=index.js.map