@elisym/sdk 0.25.5 → 0.26.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/agent-store.cjs +14 -4
- package/dist/agent-store.cjs.map +1 -1
- package/dist/agent-store.d.cts +11 -4
- package/dist/agent-store.d.ts +11 -4
- package/dist/agent-store.js +15 -6
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +28 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.js.map +1 -1
- package/dist/skills.cjs +190 -2
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +152 -3
- package/dist/skills.d.ts +152 -3
- package/dist/skills.js +189 -3
- package/dist/skills.js.map +1 -1
- package/package.json +1 -1
package/dist/skills.cjs
CHANGED
|
@@ -454,6 +454,53 @@ var DynamicScriptSkill = class {
|
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
456
|
};
|
|
457
|
+
|
|
458
|
+
// src/skills/x402ProxySkill.ts
|
|
459
|
+
var X402ProxySkill = class {
|
|
460
|
+
name;
|
|
461
|
+
description;
|
|
462
|
+
capabilities;
|
|
463
|
+
priceSubunits;
|
|
464
|
+
asset;
|
|
465
|
+
mode = "x402";
|
|
466
|
+
image;
|
|
467
|
+
imageFile;
|
|
468
|
+
llmOverride;
|
|
469
|
+
x402;
|
|
470
|
+
constructor(params) {
|
|
471
|
+
this.name = params.name;
|
|
472
|
+
this.description = params.description;
|
|
473
|
+
this.capabilities = params.capabilities;
|
|
474
|
+
this.priceSubunits = params.priceSubunits;
|
|
475
|
+
this.asset = params.asset;
|
|
476
|
+
this.x402 = params.x402;
|
|
477
|
+
this.image = params.image;
|
|
478
|
+
this.imageFile = params.imageFile;
|
|
479
|
+
}
|
|
480
|
+
/** GET upstream without a query param consumes no buyer input (card should be static). */
|
|
481
|
+
get noInput() {
|
|
482
|
+
return this.x402.method === "GET" && this.x402.queryParam === void 0;
|
|
483
|
+
}
|
|
484
|
+
requireInvoker(ctx) {
|
|
485
|
+
if (ctx.x402 === void 0) {
|
|
486
|
+
throw new Error(
|
|
487
|
+
`Skill "${this.name}": x402 skills require the elisym CLI runtime (no x402 driver in SkillContext)`
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
return ctx.x402;
|
|
491
|
+
}
|
|
492
|
+
async preflight(input, ctx) {
|
|
493
|
+
await this.requireInvoker(ctx).preflight(this.x402, input);
|
|
494
|
+
}
|
|
495
|
+
async execute(input, ctx) {
|
|
496
|
+
const result = await this.requireInvoker(ctx).execute(this.x402, input, ctx.signal);
|
|
497
|
+
return {
|
|
498
|
+
data: result.data,
|
|
499
|
+
outputMime: result.outputMime,
|
|
500
|
+
filePath: result.filePath
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
};
|
|
457
504
|
function resolveInsidePath(rootDir, value) {
|
|
458
505
|
const root = path.resolve(rootDir);
|
|
459
506
|
const candidate = path.resolve(root, value);
|
|
@@ -464,6 +511,10 @@ function resolveInsidePath(rootDir, value) {
|
|
|
464
511
|
return candidate;
|
|
465
512
|
}
|
|
466
513
|
var LIMITS = {
|
|
514
|
+
// Ceiling above which a text/* attachment is NOT materialized back into a string
|
|
515
|
+
// (re-inlined into SkillInput.data) - the consumer gets a filePath / explicit
|
|
516
|
+
// fetch instead. Also bounds the in-memory git-diff buffer (memory-DoS guard).
|
|
517
|
+
MAX_REINLINE_TEXT_BYTES: 4194304,
|
|
467
518
|
// Upper bound for execution budgets (`max_execution_secs` / `execution_timeout_secs`).
|
|
468
519
|
// Distinct from MAX_TIMEOUT_SECS (the result-wait cap): execution budgets may be
|
|
469
520
|
// hours, so this exists only to keep `secs * 1000` within Node's setTimeout limit
|
|
@@ -543,8 +594,10 @@ var VALID_MODES = [
|
|
|
543
594
|
"llm",
|
|
544
595
|
"static-file",
|
|
545
596
|
"static-script",
|
|
546
|
-
"dynamic-script"
|
|
597
|
+
"dynamic-script",
|
|
598
|
+
"x402"
|
|
547
599
|
];
|
|
600
|
+
var DEFAULT_X402_MAX_INPUT_BYTES = 1e5;
|
|
548
601
|
function solToLamports(sol) {
|
|
549
602
|
const asString = (typeof sol === "string" ? sol : String(sol)).trim();
|
|
550
603
|
if (/^0+(?:\.0+)?$/.test(asString)) {
|
|
@@ -700,6 +753,11 @@ function validateLlmOverride(skillName, frontmatter, mode) {
|
|
|
700
753
|
if (!hasProvider && !hasModel && !hasMaxTokens) {
|
|
701
754
|
return void 0;
|
|
702
755
|
}
|
|
756
|
+
if (mode === "x402") {
|
|
757
|
+
throw new Error(
|
|
758
|
+
`SKILL.md "${skillName}": "provider"/"model"/"max_tokens" are not valid in mode 'x402'`
|
|
759
|
+
);
|
|
760
|
+
}
|
|
703
761
|
if (hasMaxTokens && mode !== "llm") {
|
|
704
762
|
throw new Error(
|
|
705
763
|
`SKILL.md "${skillName}": "max_tokens" is only valid in mode 'llm' (got '${mode}'). For script modes, control token limits inside the script.`
|
|
@@ -823,6 +881,114 @@ function validateMaxExecutionSecs(skillName, raw) {
|
|
|
823
881
|
}
|
|
824
882
|
return raw;
|
|
825
883
|
}
|
|
884
|
+
var X402_METHODS = ["GET", "POST"];
|
|
885
|
+
function validateX402Config(skillName, frontmatter, mode, options) {
|
|
886
|
+
const fieldNames = [
|
|
887
|
+
"x402_url",
|
|
888
|
+
"x402_method",
|
|
889
|
+
"x402_query_param",
|
|
890
|
+
"x402_max_upstream",
|
|
891
|
+
"x402_max_input_bytes"
|
|
892
|
+
];
|
|
893
|
+
const presentFields = fieldNames.filter(
|
|
894
|
+
(field) => frontmatter[field] !== void 0 && frontmatter[field] !== null
|
|
895
|
+
);
|
|
896
|
+
if (mode !== "x402") {
|
|
897
|
+
if (presentFields.length > 0) {
|
|
898
|
+
throw new Error(
|
|
899
|
+
`SKILL.md "${skillName}": "${presentFields[0]}" is only valid in mode 'x402'`
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
return void 0;
|
|
903
|
+
}
|
|
904
|
+
if (!options.allowX402Skills) {
|
|
905
|
+
throw new Error(
|
|
906
|
+
`SKILL.md "${skillName}": x402 skills require the elisym CLI runtime; this host cannot execute mode 'x402'`
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
if (typeof frontmatter.x402_url !== "string" || frontmatter.x402_url.length === 0) {
|
|
910
|
+
throw new Error(`SKILL.md "${skillName}": mode 'x402' requires "x402_url" (string)`);
|
|
911
|
+
}
|
|
912
|
+
let url;
|
|
913
|
+
try {
|
|
914
|
+
url = new URL(frontmatter.x402_url);
|
|
915
|
+
} catch {
|
|
916
|
+
throw new Error(`SKILL.md "${skillName}": "x402_url" is not a valid URL`);
|
|
917
|
+
}
|
|
918
|
+
const isLoopback = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
|
|
919
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && isLoopback)) {
|
|
920
|
+
throw new Error(
|
|
921
|
+
`SKILL.md "${skillName}": "x402_url" must be an https:// URL (plain http is allowed for localhost only)`
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
let method = "POST";
|
|
925
|
+
if (frontmatter.x402_method !== void 0 && frontmatter.x402_method !== null) {
|
|
926
|
+
if (typeof frontmatter.x402_method !== "string" || !X402_METHODS.includes(frontmatter.x402_method)) {
|
|
927
|
+
throw new Error(
|
|
928
|
+
`SKILL.md "${skillName}": "x402_method" must be one of ${X402_METHODS.join(", ")}`
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
method = frontmatter.x402_method;
|
|
932
|
+
}
|
|
933
|
+
let queryParam;
|
|
934
|
+
if (frontmatter.x402_query_param !== void 0 && frontmatter.x402_query_param !== null) {
|
|
935
|
+
if (method !== "GET") {
|
|
936
|
+
throw new Error(
|
|
937
|
+
`SKILL.md "${skillName}": "x402_query_param" is only valid with x402_method 'GET' (POST maps the input to the request body)`
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
if (typeof frontmatter.x402_query_param !== "string" || frontmatter.x402_query_param.length === 0) {
|
|
941
|
+
throw new Error(`SKILL.md "${skillName}": "x402_query_param" must be a non-empty string`);
|
|
942
|
+
}
|
|
943
|
+
if (url.searchParams.has(frontmatter.x402_query_param)) {
|
|
944
|
+
throw new Error(
|
|
945
|
+
`SKILL.md "${skillName}": "x402_query_param" ("${frontmatter.x402_query_param}") collides with a parameter already present in "x402_url"`
|
|
946
|
+
);
|
|
947
|
+
}
|
|
948
|
+
queryParam = frontmatter.x402_query_param;
|
|
949
|
+
}
|
|
950
|
+
const rawMaxUpstream = frontmatter.x402_max_upstream;
|
|
951
|
+
if (rawMaxUpstream === void 0 || rawMaxUpstream === null) {
|
|
952
|
+
throw new Error(
|
|
953
|
+
`SKILL.md "${skillName}": mode 'x402' requires "x402_max_upstream" (integer subunits - the ceiling on the upstream quote)`
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
let maxUpstreamSubunits;
|
|
957
|
+
if (typeof rawMaxUpstream === "number" && Number.isSafeInteger(rawMaxUpstream)) {
|
|
958
|
+
maxUpstreamSubunits = BigInt(rawMaxUpstream);
|
|
959
|
+
} else if (typeof rawMaxUpstream === "string" && /^[0-9]+$/.test(rawMaxUpstream)) {
|
|
960
|
+
maxUpstreamSubunits = BigInt(rawMaxUpstream);
|
|
961
|
+
} else {
|
|
962
|
+
throw new Error(
|
|
963
|
+
`SKILL.md "${skillName}": "x402_max_upstream" must be a non-negative integer (subunits)`
|
|
964
|
+
);
|
|
965
|
+
}
|
|
966
|
+
if (maxUpstreamSubunits <= 0n) {
|
|
967
|
+
throw new Error(`SKILL.md "${skillName}": "x402_max_upstream" must be > 0`);
|
|
968
|
+
}
|
|
969
|
+
let maxInputBytes = DEFAULT_X402_MAX_INPUT_BYTES;
|
|
970
|
+
if (frontmatter.x402_max_input_bytes !== void 0 && frontmatter.x402_max_input_bytes !== null) {
|
|
971
|
+
const raw = frontmatter.x402_max_input_bytes;
|
|
972
|
+
if (typeof raw !== "number" || !Number.isInteger(raw) || raw <= 0) {
|
|
973
|
+
throw new Error(
|
|
974
|
+
`SKILL.md "${skillName}": "x402_max_input_bytes" must be a positive integer (bytes)`
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
if (raw > LIMITS.MAX_REINLINE_TEXT_BYTES) {
|
|
978
|
+
throw new Error(
|
|
979
|
+
`SKILL.md "${skillName}": "x402_max_input_bytes" must be <= ${LIMITS.MAX_REINLINE_TEXT_BYTES} (inputs above it never reach the skill as text)`
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
maxInputBytes = raw;
|
|
983
|
+
}
|
|
984
|
+
return {
|
|
985
|
+
url: frontmatter.x402_url,
|
|
986
|
+
method,
|
|
987
|
+
queryParam,
|
|
988
|
+
maxUpstreamSubunits,
|
|
989
|
+
maxInputBytes
|
|
990
|
+
};
|
|
991
|
+
}
|
|
826
992
|
function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
827
993
|
if (typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
|
|
828
994
|
throw new Error('SKILL.md: missing or invalid "name" field');
|
|
@@ -1015,6 +1181,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
1015
1181
|
frontmatter.name,
|
|
1016
1182
|
frontmatter.max_execution_secs
|
|
1017
1183
|
);
|
|
1184
|
+
const x402 = validateX402Config(frontmatter.name, frontmatter, mode, options);
|
|
1018
1185
|
return {
|
|
1019
1186
|
name: frontmatter.name,
|
|
1020
1187
|
description: frontmatter.description,
|
|
@@ -1036,7 +1203,9 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
1036
1203
|
inputMime,
|
|
1037
1204
|
inputText,
|
|
1038
1205
|
rateLimit,
|
|
1039
|
-
executionTimeoutSecs
|
|
1206
|
+
executionTimeoutSecs,
|
|
1207
|
+
x402,
|
|
1208
|
+
noInput: x402 === void 0 ? void 0 : x402.method === "GET" && x402.queryParam === void 0
|
|
1040
1209
|
};
|
|
1041
1210
|
}
|
|
1042
1211
|
function buildSkillFromParsed(parsed, skillDir, logger) {
|
|
@@ -1115,6 +1284,23 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
|
|
|
1115
1284
|
};
|
|
1116
1285
|
return parsed.mode === "dynamic-script" ? new DynamicScriptSkill({ ...scriptParams, outputMime: parsed.outputMime }) : new StaticScriptSkill(scriptParams);
|
|
1117
1286
|
}
|
|
1287
|
+
case "x402": {
|
|
1288
|
+
if (parsed.x402 === void 0) {
|
|
1289
|
+
throw new Error(
|
|
1290
|
+
`SKILL.md "${parsed.name}": internal error - x402 config missing for mode 'x402'`
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1293
|
+
return new X402ProxySkill({
|
|
1294
|
+
name: parsed.name,
|
|
1295
|
+
description: parsed.description,
|
|
1296
|
+
capabilities: parsed.capabilities,
|
|
1297
|
+
priceSubunits: parsed.priceSubunits,
|
|
1298
|
+
asset: parsed.asset,
|
|
1299
|
+
x402: parsed.x402,
|
|
1300
|
+
image: parsed.image,
|
|
1301
|
+
imageFile
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1118
1304
|
}
|
|
1119
1305
|
}
|
|
1120
1306
|
function loadSkillsFromDir(skillsDir, options = {}) {
|
|
@@ -1152,12 +1338,14 @@ function loadSkillsFromDir(skillsDir, options = {}) {
|
|
|
1152
1338
|
|
|
1153
1339
|
exports.DEFAULT_MAX_TOOL_ROUNDS = DEFAULT_MAX_TOOL_ROUNDS;
|
|
1154
1340
|
exports.DEFAULT_SCRIPT_TIMEOUT_MS = DEFAULT_SCRIPT_TIMEOUT_MS;
|
|
1341
|
+
exports.DEFAULT_X402_MAX_INPUT_BYTES = DEFAULT_X402_MAX_INPUT_BYTES;
|
|
1155
1342
|
exports.DynamicScriptSkill = DynamicScriptSkill;
|
|
1156
1343
|
exports.MAX_SCRIPT_OUTPUT = MAX_SCRIPT_OUTPUT;
|
|
1157
1344
|
exports.MAX_STATIC_FILE_SIZE = MAX_STATIC_FILE_SIZE;
|
|
1158
1345
|
exports.ScriptSkill = ScriptSkill;
|
|
1159
1346
|
exports.StaticFileSkill = StaticFileSkill;
|
|
1160
1347
|
exports.StaticScriptSkill = StaticScriptSkill;
|
|
1348
|
+
exports.X402ProxySkill = X402ProxySkill;
|
|
1161
1349
|
exports.loadSkillsFromDir = loadSkillsFromDir;
|
|
1162
1350
|
exports.parseSkillMd = parseSkillMd;
|
|
1163
1351
|
exports.resolveInsidePath = resolveInsidePath;
|