@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.cjs CHANGED
@@ -63,6 +63,14 @@ function runScript(cmd, args, opts) {
63
63
  }
64
64
  });
65
65
  }
66
+ var SECRET_ENV_VARS = ["ANTHROPIC_API_KEY", "OPENAI_API_KEY"];
67
+ function scopedToolEnv() {
68
+ const env = { ...process.env };
69
+ for (const key of SECRET_ENV_VARS) {
70
+ delete env[key];
71
+ }
72
+ return env;
73
+ }
66
74
  var ScriptSkill = class {
67
75
  name;
68
76
  description;
@@ -184,13 +192,21 @@ var ScriptSkill = class {
184
192
  if (value === void 0) {
185
193
  continue;
186
194
  }
195
+ const stringValue = String(value);
196
+ if (stringValue.startsWith("-")) {
197
+ return `Error: tool "${toolDef.name}" argument "${param.name}" must not begin with "-".`;
198
+ }
187
199
  if (param.required && index === 0) {
188
- args.push(String(value));
200
+ args.push(stringValue);
189
201
  } else {
190
- args.push(`--${param.name}`, String(value));
202
+ args.push(`--${param.name}`, stringValue);
191
203
  }
192
204
  }
193
- const result = await runScript(cmd, args, { cwd: this.skillDir, signal });
205
+ const result = await runScript(cmd, args, {
206
+ cwd: this.skillDir,
207
+ signal,
208
+ env: scopedToolEnv()
209
+ });
194
210
  if (result.spawnError) {
195
211
  return `Error: ${result.spawnError.message}`;
196
212
  }
@@ -253,6 +269,16 @@ var ScriptBillingExhaustedError = class extends Error {
253
269
  this.stderr = stderr;
254
270
  }
255
271
  };
272
+ var ScriptExecutionError = class extends Error {
273
+ exitCode;
274
+ detail;
275
+ constructor(exitCode, detail, summary) {
276
+ super(summary ?? `script failed (exit ${exitCode ?? "unknown"})`);
277
+ this.name = "ScriptExecutionError";
278
+ this.exitCode = exitCode;
279
+ this.detail = detail;
280
+ }
281
+ };
256
282
 
257
283
  // src/skills/staticScriptSkill.ts
258
284
  var StaticScriptSkill = class {
@@ -291,19 +317,23 @@ var StaticScriptSkill = class {
291
317
  env: this.scriptEnv
292
318
  });
293
319
  if (result.spawnError) {
294
- throw new Error(`script spawn failed: ${result.spawnError.message}`);
320
+ throw new ScriptExecutionError(
321
+ null,
322
+ result.spawnError.message,
323
+ "script could not be started"
324
+ );
295
325
  }
296
326
  if (result.code === SCRIPT_EXIT_BILLING_EXHAUSTED) {
297
327
  throw new ScriptBillingExhaustedError(result.code, result.stdout, result.stderr);
298
328
  }
299
329
  if (result.code !== 0) {
300
330
  const detail = result.stderr.trim() || result.stdout.trim() || "(no output)";
301
- throw new Error(`script failed (exit ${result.code}): ${detail}`);
331
+ throw new ScriptExecutionError(result.code, detail);
302
332
  }
303
333
  const output = result.stdout.trim();
304
334
  if (output === "") {
305
335
  const detail = result.stderr.trim() || "(no stderr)";
306
- throw new Error(`script exited 0 but produced empty output: ${detail}`);
336
+ throw new ScriptExecutionError(result.code, detail, "script produced empty output");
307
337
  }
308
338
  return { data: output };
309
339
  }
@@ -345,19 +375,23 @@ var DynamicScriptSkill = class {
345
375
  env: this.scriptEnv
346
376
  });
347
377
  if (result.spawnError) {
348
- throw new Error(`script spawn failed: ${result.spawnError.message}`);
378
+ throw new ScriptExecutionError(
379
+ null,
380
+ result.spawnError.message,
381
+ "script could not be started"
382
+ );
349
383
  }
350
384
  if (result.code === SCRIPT_EXIT_BILLING_EXHAUSTED) {
351
385
  throw new ScriptBillingExhaustedError(result.code, result.stdout, result.stderr);
352
386
  }
353
387
  if (result.code !== 0) {
354
388
  const detail = result.stderr.trim() || result.stdout.trim() || "(no output)";
355
- throw new Error(`script failed (exit ${result.code}): ${detail}`);
389
+ throw new ScriptExecutionError(result.code, detail);
356
390
  }
357
391
  const output = result.stdout.trim();
358
392
  if (output === "") {
359
393
  const detail = result.stderr.trim() || "(no stderr)";
360
- throw new Error(`script exited 0 but produced empty output: ${detail}`);
394
+ throw new ScriptExecutionError(result.code, detail, "script produced empty output");
361
395
  }
362
396
  return { data: output };
363
397
  }
@@ -371,7 +405,6 @@ function resolveInsidePath(rootDir, value) {
371
405
  }
372
406
  return candidate;
373
407
  }
374
- var LAMPORTS_PER_SOL = 1e9;
375
408
  var LIMITS = {
376
409
  // Upper bound for execution budgets (`max_execution_secs` / `execution_timeout_secs`).
377
410
  // Distinct from MAX_TIMEOUT_SECS (the result-wait cap): execution budgets may be
@@ -454,11 +487,15 @@ var VALID_MODES = [
454
487
  "dynamic-script"
455
488
  ];
456
489
  function solToLamports(sol) {
457
- const asNumber = typeof sol === "string" ? Number(sol) : sol;
458
- if (!Number.isFinite(asNumber) || asNumber < 0) {
490
+ const asString = (typeof sol === "string" ? sol : String(sol)).trim();
491
+ if (/^0+(?:\.0+)?$/.test(asString)) {
492
+ return 0n;
493
+ }
494
+ try {
495
+ return parseAssetAmount(NATIVE_SOL, asString);
496
+ } catch {
459
497
  throw new Error(`Invalid SOL amount: ${sol}`);
460
498
  }
461
- return BigInt(Math.round(asNumber * LAMPORTS_PER_SOL));
462
499
  }
463
500
  function resolveSkillAsset(skillName, token, mint) {
464
501
  if (token === void 0 || token === null) {
@@ -722,7 +759,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
722
759
  }
723
760
  const priceString = typeof priceRaw === "number" ? String(priceRaw) : priceRaw;
724
761
  if (asset === NATIVE_SOL) {
725
- priceSubunits = solToLamports(priceRaw);
762
+ priceSubunits = solToLamports(priceString);
726
763
  } else {
727
764
  try {
728
765
  priceSubunits = parseAssetAmount(asset, priceString);
@@ -847,6 +884,14 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
847
884
  };
848
885
  }
849
886
  function buildSkillFromParsed(parsed, skillDir, logger) {
887
+ let imageFile = parsed.imageFile;
888
+ if (imageFile !== void 0 && resolveInsidePath(skillDir, imageFile) === null) {
889
+ logger.warn?.(
890
+ { skill: parsed.name, imageFile },
891
+ 'SKILL.md "image_file" escapes the skill directory; ignoring it'
892
+ );
893
+ imageFile = void 0;
894
+ }
850
895
  switch (parsed.mode) {
851
896
  case "llm":
852
897
  return new ScriptSkill({
@@ -861,7 +906,7 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
861
906
  maxToolRounds: parsed.maxToolRounds,
862
907
  llmOverride: parsed.llmOverride,
863
908
  image: parsed.image,
864
- imageFile: parsed.imageFile,
909
+ imageFile,
865
910
  logger
866
911
  });
867
912
  case "static-file": {
@@ -884,7 +929,7 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
884
929
  asset: parsed.asset,
885
930
  outputFilePath,
886
931
  image: parsed.image,
887
- imageFile: parsed.imageFile,
932
+ imageFile,
888
933
  llmOverride: parsed.llmOverride
889
934
  });
890
935
  }
@@ -910,7 +955,7 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
910
955
  scriptArgs: parsed.scriptArgs,
911
956
  scriptTimeoutMs: parsed.scriptTimeoutMs ?? DEFAULT_SCRIPT_TIMEOUT_MS,
912
957
  image: parsed.image,
913
- imageFile: parsed.imageFile,
958
+ imageFile,
914
959
  llmOverride: parsed.llmOverride
915
960
  });
916
961
  }