@elisym/sdk 0.22.0 → 0.23.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/skills.js CHANGED
@@ -56,6 +56,14 @@ function runScript(cmd, args, opts) {
56
56
  }
57
57
  });
58
58
  }
59
+ var SECRET_ENV_VARS = ["ANTHROPIC_API_KEY", "OPENAI_API_KEY"];
60
+ function scopedToolEnv() {
61
+ const env = { ...process.env };
62
+ for (const key of SECRET_ENV_VARS) {
63
+ delete env[key];
64
+ }
65
+ return env;
66
+ }
59
67
  var ScriptSkill = class {
60
68
  name;
61
69
  description;
@@ -177,13 +185,21 @@ var ScriptSkill = class {
177
185
  if (value === void 0) {
178
186
  continue;
179
187
  }
188
+ const stringValue = String(value);
189
+ if (stringValue.startsWith("-")) {
190
+ return `Error: tool "${toolDef.name}" argument "${param.name}" must not begin with "-".`;
191
+ }
180
192
  if (param.required && index === 0) {
181
- args.push(String(value));
193
+ args.push(stringValue);
182
194
  } else {
183
- args.push(`--${param.name}`, String(value));
195
+ args.push(`--${param.name}`, stringValue);
184
196
  }
185
197
  }
186
- const result = await runScript(cmd, args, { cwd: this.skillDir, signal });
198
+ const result = await runScript(cmd, args, {
199
+ cwd: this.skillDir,
200
+ signal,
201
+ env: scopedToolEnv()
202
+ });
187
203
  if (result.spawnError) {
188
204
  return `Error: ${result.spawnError.message}`;
189
205
  }
@@ -246,6 +262,16 @@ var ScriptBillingExhaustedError = class extends Error {
246
262
  this.stderr = stderr;
247
263
  }
248
264
  };
265
+ var ScriptExecutionError = class extends Error {
266
+ exitCode;
267
+ detail;
268
+ constructor(exitCode, detail, summary) {
269
+ super(summary ?? `script failed (exit ${exitCode ?? "unknown"})`);
270
+ this.name = "ScriptExecutionError";
271
+ this.exitCode = exitCode;
272
+ this.detail = detail;
273
+ }
274
+ };
249
275
 
250
276
  // src/skills/staticScriptSkill.ts
251
277
  var StaticScriptSkill = class {
@@ -284,19 +310,23 @@ var StaticScriptSkill = class {
284
310
  env: this.scriptEnv
285
311
  });
286
312
  if (result.spawnError) {
287
- throw new Error(`script spawn failed: ${result.spawnError.message}`);
313
+ throw new ScriptExecutionError(
314
+ null,
315
+ result.spawnError.message,
316
+ "script could not be started"
317
+ );
288
318
  }
289
319
  if (result.code === SCRIPT_EXIT_BILLING_EXHAUSTED) {
290
320
  throw new ScriptBillingExhaustedError(result.code, result.stdout, result.stderr);
291
321
  }
292
322
  if (result.code !== 0) {
293
323
  const detail = result.stderr.trim() || result.stdout.trim() || "(no output)";
294
- throw new Error(`script failed (exit ${result.code}): ${detail}`);
324
+ throw new ScriptExecutionError(result.code, detail);
295
325
  }
296
326
  const output = result.stdout.trim();
297
327
  if (output === "") {
298
328
  const detail = result.stderr.trim() || "(no stderr)";
299
- throw new Error(`script exited 0 but produced empty output: ${detail}`);
329
+ throw new ScriptExecutionError(result.code, detail, "script produced empty output");
300
330
  }
301
331
  return { data: output };
302
332
  }
@@ -338,19 +368,23 @@ var DynamicScriptSkill = class {
338
368
  env: this.scriptEnv
339
369
  });
340
370
  if (result.spawnError) {
341
- throw new Error(`script spawn failed: ${result.spawnError.message}`);
371
+ throw new ScriptExecutionError(
372
+ null,
373
+ result.spawnError.message,
374
+ "script could not be started"
375
+ );
342
376
  }
343
377
  if (result.code === SCRIPT_EXIT_BILLING_EXHAUSTED) {
344
378
  throw new ScriptBillingExhaustedError(result.code, result.stdout, result.stderr);
345
379
  }
346
380
  if (result.code !== 0) {
347
381
  const detail = result.stderr.trim() || result.stdout.trim() || "(no output)";
348
- throw new Error(`script failed (exit ${result.code}): ${detail}`);
382
+ throw new ScriptExecutionError(result.code, detail);
349
383
  }
350
384
  const output = result.stdout.trim();
351
385
  if (output === "") {
352
386
  const detail = result.stderr.trim() || "(no stderr)";
353
- throw new Error(`script exited 0 but produced empty output: ${detail}`);
387
+ throw new ScriptExecutionError(result.code, detail, "script produced empty output");
354
388
  }
355
389
  return { data: output };
356
390
  }
@@ -364,7 +398,6 @@ function resolveInsidePath(rootDir, value) {
364
398
  }
365
399
  return candidate;
366
400
  }
367
- var LAMPORTS_PER_SOL = 1e9;
368
401
  var LIMITS = {
369
402
  // Upper bound for execution budgets (`max_execution_secs` / `execution_timeout_secs`).
370
403
  // Distinct from MAX_TIMEOUT_SECS (the result-wait cap): execution budgets may be
@@ -447,11 +480,15 @@ var VALID_MODES = [
447
480
  "dynamic-script"
448
481
  ];
449
482
  function solToLamports(sol) {
450
- const asNumber = typeof sol === "string" ? Number(sol) : sol;
451
- if (!Number.isFinite(asNumber) || asNumber < 0) {
483
+ const asString = (typeof sol === "string" ? sol : String(sol)).trim();
484
+ if (/^0+(?:\.0+)?$/.test(asString)) {
485
+ return 0n;
486
+ }
487
+ try {
488
+ return parseAssetAmount(NATIVE_SOL, asString);
489
+ } catch {
452
490
  throw new Error(`Invalid SOL amount: ${sol}`);
453
491
  }
454
- return BigInt(Math.round(asNumber * LAMPORTS_PER_SOL));
455
492
  }
456
493
  function resolveSkillAsset(skillName, token, mint) {
457
494
  if (token === void 0 || token === null) {
@@ -715,7 +752,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
715
752
  }
716
753
  const priceString = typeof priceRaw === "number" ? String(priceRaw) : priceRaw;
717
754
  if (asset === NATIVE_SOL) {
718
- priceSubunits = solToLamports(priceRaw);
755
+ priceSubunits = solToLamports(priceString);
719
756
  } else {
720
757
  try {
721
758
  priceSubunits = parseAssetAmount(asset, priceString);
@@ -840,6 +877,14 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
840
877
  };
841
878
  }
842
879
  function buildSkillFromParsed(parsed, skillDir, logger) {
880
+ let imageFile = parsed.imageFile;
881
+ if (imageFile !== void 0 && resolveInsidePath(skillDir, imageFile) === null) {
882
+ logger.warn?.(
883
+ { skill: parsed.name, imageFile },
884
+ 'SKILL.md "image_file" escapes the skill directory; ignoring it'
885
+ );
886
+ imageFile = void 0;
887
+ }
843
888
  switch (parsed.mode) {
844
889
  case "llm":
845
890
  return new ScriptSkill({
@@ -854,7 +899,7 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
854
899
  maxToolRounds: parsed.maxToolRounds,
855
900
  llmOverride: parsed.llmOverride,
856
901
  image: parsed.image,
857
- imageFile: parsed.imageFile,
902
+ imageFile,
858
903
  logger
859
904
  });
860
905
  case "static-file": {
@@ -877,7 +922,7 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
877
922
  asset: parsed.asset,
878
923
  outputFilePath,
879
924
  image: parsed.image,
880
- imageFile: parsed.imageFile,
925
+ imageFile,
881
926
  llmOverride: parsed.llmOverride
882
927
  });
883
928
  }
@@ -903,7 +948,7 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
903
948
  scriptArgs: parsed.scriptArgs,
904
949
  scriptTimeoutMs: parsed.scriptTimeoutMs ?? DEFAULT_SCRIPT_TIMEOUT_MS,
905
950
  image: parsed.image,
906
- imageFile: parsed.imageFile,
951
+ imageFile,
907
952
  llmOverride: parsed.llmOverride
908
953
  });
909
954
  }