@elisym/sdk 0.25.4 → 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 +16 -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 +17 -6
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +30 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -9
- package/dist/index.d.ts +28 -9
- package/dist/index.js +28 -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 +161 -10
- package/dist/skills.d.ts +161 -10
- package/dist/skills.js +189 -3
- package/dist/skills.js.map +1 -1
- package/package.json +1 -1
package/dist/skills.js
CHANGED
|
@@ -447,6 +447,53 @@ var DynamicScriptSkill = class {
|
|
|
447
447
|
}
|
|
448
448
|
}
|
|
449
449
|
};
|
|
450
|
+
|
|
451
|
+
// src/skills/x402ProxySkill.ts
|
|
452
|
+
var X402ProxySkill = class {
|
|
453
|
+
name;
|
|
454
|
+
description;
|
|
455
|
+
capabilities;
|
|
456
|
+
priceSubunits;
|
|
457
|
+
asset;
|
|
458
|
+
mode = "x402";
|
|
459
|
+
image;
|
|
460
|
+
imageFile;
|
|
461
|
+
llmOverride;
|
|
462
|
+
x402;
|
|
463
|
+
constructor(params) {
|
|
464
|
+
this.name = params.name;
|
|
465
|
+
this.description = params.description;
|
|
466
|
+
this.capabilities = params.capabilities;
|
|
467
|
+
this.priceSubunits = params.priceSubunits;
|
|
468
|
+
this.asset = params.asset;
|
|
469
|
+
this.x402 = params.x402;
|
|
470
|
+
this.image = params.image;
|
|
471
|
+
this.imageFile = params.imageFile;
|
|
472
|
+
}
|
|
473
|
+
/** GET upstream without a query param consumes no buyer input (card should be static). */
|
|
474
|
+
get noInput() {
|
|
475
|
+
return this.x402.method === "GET" && this.x402.queryParam === void 0;
|
|
476
|
+
}
|
|
477
|
+
requireInvoker(ctx) {
|
|
478
|
+
if (ctx.x402 === void 0) {
|
|
479
|
+
throw new Error(
|
|
480
|
+
`Skill "${this.name}": x402 skills require the elisym CLI runtime (no x402 driver in SkillContext)`
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
return ctx.x402;
|
|
484
|
+
}
|
|
485
|
+
async preflight(input, ctx) {
|
|
486
|
+
await this.requireInvoker(ctx).preflight(this.x402, input);
|
|
487
|
+
}
|
|
488
|
+
async execute(input, ctx) {
|
|
489
|
+
const result = await this.requireInvoker(ctx).execute(this.x402, input, ctx.signal);
|
|
490
|
+
return {
|
|
491
|
+
data: result.data,
|
|
492
|
+
outputMime: result.outputMime,
|
|
493
|
+
filePath: result.filePath
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
};
|
|
450
497
|
function resolveInsidePath(rootDir, value) {
|
|
451
498
|
const root = resolve(rootDir);
|
|
452
499
|
const candidate = resolve(root, value);
|
|
@@ -457,6 +504,10 @@ function resolveInsidePath(rootDir, value) {
|
|
|
457
504
|
return candidate;
|
|
458
505
|
}
|
|
459
506
|
var LIMITS = {
|
|
507
|
+
// Ceiling above which a text/* attachment is NOT materialized back into a string
|
|
508
|
+
// (re-inlined into SkillInput.data) - the consumer gets a filePath / explicit
|
|
509
|
+
// fetch instead. Also bounds the in-memory git-diff buffer (memory-DoS guard).
|
|
510
|
+
MAX_REINLINE_TEXT_BYTES: 4194304,
|
|
460
511
|
// Upper bound for execution budgets (`max_execution_secs` / `execution_timeout_secs`).
|
|
461
512
|
// Distinct from MAX_TIMEOUT_SECS (the result-wait cap): execution budgets may be
|
|
462
513
|
// hours, so this exists only to keep `secs * 1000` within Node's setTimeout limit
|
|
@@ -536,8 +587,10 @@ var VALID_MODES = [
|
|
|
536
587
|
"llm",
|
|
537
588
|
"static-file",
|
|
538
589
|
"static-script",
|
|
539
|
-
"dynamic-script"
|
|
590
|
+
"dynamic-script",
|
|
591
|
+
"x402"
|
|
540
592
|
];
|
|
593
|
+
var DEFAULT_X402_MAX_INPUT_BYTES = 1e5;
|
|
541
594
|
function solToLamports(sol) {
|
|
542
595
|
const asString = (typeof sol === "string" ? sol : String(sol)).trim();
|
|
543
596
|
if (/^0+(?:\.0+)?$/.test(asString)) {
|
|
@@ -693,6 +746,11 @@ function validateLlmOverride(skillName, frontmatter, mode) {
|
|
|
693
746
|
if (!hasProvider && !hasModel && !hasMaxTokens) {
|
|
694
747
|
return void 0;
|
|
695
748
|
}
|
|
749
|
+
if (mode === "x402") {
|
|
750
|
+
throw new Error(
|
|
751
|
+
`SKILL.md "${skillName}": "provider"/"model"/"max_tokens" are not valid in mode 'x402'`
|
|
752
|
+
);
|
|
753
|
+
}
|
|
696
754
|
if (hasMaxTokens && mode !== "llm") {
|
|
697
755
|
throw new Error(
|
|
698
756
|
`SKILL.md "${skillName}": "max_tokens" is only valid in mode 'llm' (got '${mode}'). For script modes, control token limits inside the script.`
|
|
@@ -816,6 +874,114 @@ function validateMaxExecutionSecs(skillName, raw) {
|
|
|
816
874
|
}
|
|
817
875
|
return raw;
|
|
818
876
|
}
|
|
877
|
+
var X402_METHODS = ["GET", "POST"];
|
|
878
|
+
function validateX402Config(skillName, frontmatter, mode, options) {
|
|
879
|
+
const fieldNames = [
|
|
880
|
+
"x402_url",
|
|
881
|
+
"x402_method",
|
|
882
|
+
"x402_query_param",
|
|
883
|
+
"x402_max_upstream",
|
|
884
|
+
"x402_max_input_bytes"
|
|
885
|
+
];
|
|
886
|
+
const presentFields = fieldNames.filter(
|
|
887
|
+
(field) => frontmatter[field] !== void 0 && frontmatter[field] !== null
|
|
888
|
+
);
|
|
889
|
+
if (mode !== "x402") {
|
|
890
|
+
if (presentFields.length > 0) {
|
|
891
|
+
throw new Error(
|
|
892
|
+
`SKILL.md "${skillName}": "${presentFields[0]}" is only valid in mode 'x402'`
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
return void 0;
|
|
896
|
+
}
|
|
897
|
+
if (!options.allowX402Skills) {
|
|
898
|
+
throw new Error(
|
|
899
|
+
`SKILL.md "${skillName}": x402 skills require the elisym CLI runtime; this host cannot execute mode 'x402'`
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
if (typeof frontmatter.x402_url !== "string" || frontmatter.x402_url.length === 0) {
|
|
903
|
+
throw new Error(`SKILL.md "${skillName}": mode 'x402' requires "x402_url" (string)`);
|
|
904
|
+
}
|
|
905
|
+
let url;
|
|
906
|
+
try {
|
|
907
|
+
url = new URL(frontmatter.x402_url);
|
|
908
|
+
} catch {
|
|
909
|
+
throw new Error(`SKILL.md "${skillName}": "x402_url" is not a valid URL`);
|
|
910
|
+
}
|
|
911
|
+
const isLoopback = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
|
|
912
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && isLoopback)) {
|
|
913
|
+
throw new Error(
|
|
914
|
+
`SKILL.md "${skillName}": "x402_url" must be an https:// URL (plain http is allowed for localhost only)`
|
|
915
|
+
);
|
|
916
|
+
}
|
|
917
|
+
let method = "POST";
|
|
918
|
+
if (frontmatter.x402_method !== void 0 && frontmatter.x402_method !== null) {
|
|
919
|
+
if (typeof frontmatter.x402_method !== "string" || !X402_METHODS.includes(frontmatter.x402_method)) {
|
|
920
|
+
throw new Error(
|
|
921
|
+
`SKILL.md "${skillName}": "x402_method" must be one of ${X402_METHODS.join(", ")}`
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
method = frontmatter.x402_method;
|
|
925
|
+
}
|
|
926
|
+
let queryParam;
|
|
927
|
+
if (frontmatter.x402_query_param !== void 0 && frontmatter.x402_query_param !== null) {
|
|
928
|
+
if (method !== "GET") {
|
|
929
|
+
throw new Error(
|
|
930
|
+
`SKILL.md "${skillName}": "x402_query_param" is only valid with x402_method 'GET' (POST maps the input to the request body)`
|
|
931
|
+
);
|
|
932
|
+
}
|
|
933
|
+
if (typeof frontmatter.x402_query_param !== "string" || frontmatter.x402_query_param.length === 0) {
|
|
934
|
+
throw new Error(`SKILL.md "${skillName}": "x402_query_param" must be a non-empty string`);
|
|
935
|
+
}
|
|
936
|
+
if (url.searchParams.has(frontmatter.x402_query_param)) {
|
|
937
|
+
throw new Error(
|
|
938
|
+
`SKILL.md "${skillName}": "x402_query_param" ("${frontmatter.x402_query_param}") collides with a parameter already present in "x402_url"`
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
queryParam = frontmatter.x402_query_param;
|
|
942
|
+
}
|
|
943
|
+
const rawMaxUpstream = frontmatter.x402_max_upstream;
|
|
944
|
+
if (rawMaxUpstream === void 0 || rawMaxUpstream === null) {
|
|
945
|
+
throw new Error(
|
|
946
|
+
`SKILL.md "${skillName}": mode 'x402' requires "x402_max_upstream" (integer subunits - the ceiling on the upstream quote)`
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
let maxUpstreamSubunits;
|
|
950
|
+
if (typeof rawMaxUpstream === "number" && Number.isSafeInteger(rawMaxUpstream)) {
|
|
951
|
+
maxUpstreamSubunits = BigInt(rawMaxUpstream);
|
|
952
|
+
} else if (typeof rawMaxUpstream === "string" && /^[0-9]+$/.test(rawMaxUpstream)) {
|
|
953
|
+
maxUpstreamSubunits = BigInt(rawMaxUpstream);
|
|
954
|
+
} else {
|
|
955
|
+
throw new Error(
|
|
956
|
+
`SKILL.md "${skillName}": "x402_max_upstream" must be a non-negative integer (subunits)`
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
if (maxUpstreamSubunits <= 0n) {
|
|
960
|
+
throw new Error(`SKILL.md "${skillName}": "x402_max_upstream" must be > 0`);
|
|
961
|
+
}
|
|
962
|
+
let maxInputBytes = DEFAULT_X402_MAX_INPUT_BYTES;
|
|
963
|
+
if (frontmatter.x402_max_input_bytes !== void 0 && frontmatter.x402_max_input_bytes !== null) {
|
|
964
|
+
const raw = frontmatter.x402_max_input_bytes;
|
|
965
|
+
if (typeof raw !== "number" || !Number.isInteger(raw) || raw <= 0) {
|
|
966
|
+
throw new Error(
|
|
967
|
+
`SKILL.md "${skillName}": "x402_max_input_bytes" must be a positive integer (bytes)`
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
if (raw > LIMITS.MAX_REINLINE_TEXT_BYTES) {
|
|
971
|
+
throw new Error(
|
|
972
|
+
`SKILL.md "${skillName}": "x402_max_input_bytes" must be <= ${LIMITS.MAX_REINLINE_TEXT_BYTES} (inputs above it never reach the skill as text)`
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
maxInputBytes = raw;
|
|
976
|
+
}
|
|
977
|
+
return {
|
|
978
|
+
url: frontmatter.x402_url,
|
|
979
|
+
method,
|
|
980
|
+
queryParam,
|
|
981
|
+
maxUpstreamSubunits,
|
|
982
|
+
maxInputBytes
|
|
983
|
+
};
|
|
984
|
+
}
|
|
819
985
|
function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
820
986
|
if (typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
|
|
821
987
|
throw new Error('SKILL.md: missing or invalid "name" field');
|
|
@@ -1008,6 +1174,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
1008
1174
|
frontmatter.name,
|
|
1009
1175
|
frontmatter.max_execution_secs
|
|
1010
1176
|
);
|
|
1177
|
+
const x402 = validateX402Config(frontmatter.name, frontmatter, mode, options);
|
|
1011
1178
|
return {
|
|
1012
1179
|
name: frontmatter.name,
|
|
1013
1180
|
description: frontmatter.description,
|
|
@@ -1029,7 +1196,9 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
1029
1196
|
inputMime,
|
|
1030
1197
|
inputText,
|
|
1031
1198
|
rateLimit,
|
|
1032
|
-
executionTimeoutSecs
|
|
1199
|
+
executionTimeoutSecs,
|
|
1200
|
+
x402,
|
|
1201
|
+
noInput: x402 === void 0 ? void 0 : x402.method === "GET" && x402.queryParam === void 0
|
|
1033
1202
|
};
|
|
1034
1203
|
}
|
|
1035
1204
|
function buildSkillFromParsed(parsed, skillDir, logger) {
|
|
@@ -1108,6 +1277,23 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
|
|
|
1108
1277
|
};
|
|
1109
1278
|
return parsed.mode === "dynamic-script" ? new DynamicScriptSkill({ ...scriptParams, outputMime: parsed.outputMime }) : new StaticScriptSkill(scriptParams);
|
|
1110
1279
|
}
|
|
1280
|
+
case "x402": {
|
|
1281
|
+
if (parsed.x402 === void 0) {
|
|
1282
|
+
throw new Error(
|
|
1283
|
+
`SKILL.md "${parsed.name}": internal error - x402 config missing for mode 'x402'`
|
|
1284
|
+
);
|
|
1285
|
+
}
|
|
1286
|
+
return new X402ProxySkill({
|
|
1287
|
+
name: parsed.name,
|
|
1288
|
+
description: parsed.description,
|
|
1289
|
+
capabilities: parsed.capabilities,
|
|
1290
|
+
priceSubunits: parsed.priceSubunits,
|
|
1291
|
+
asset: parsed.asset,
|
|
1292
|
+
x402: parsed.x402,
|
|
1293
|
+
image: parsed.image,
|
|
1294
|
+
imageFile
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1111
1297
|
}
|
|
1112
1298
|
}
|
|
1113
1299
|
function loadSkillsFromDir(skillsDir, options = {}) {
|
|
@@ -1143,6 +1329,6 @@ function loadSkillsFromDir(skillsDir, options = {}) {
|
|
|
1143
1329
|
return skills;
|
|
1144
1330
|
}
|
|
1145
1331
|
|
|
1146
|
-
export { DEFAULT_MAX_TOOL_ROUNDS, DEFAULT_SCRIPT_TIMEOUT_MS, DynamicScriptSkill, MAX_SCRIPT_OUTPUT, MAX_STATIC_FILE_SIZE, ScriptSkill, StaticFileSkill, StaticScriptSkill, loadSkillsFromDir, parseSkillMd, resolveInsidePath, runScript, validateSkillFrontmatter };
|
|
1332
|
+
export { DEFAULT_MAX_TOOL_ROUNDS, DEFAULT_SCRIPT_TIMEOUT_MS, DEFAULT_X402_MAX_INPUT_BYTES, DynamicScriptSkill, MAX_SCRIPT_OUTPUT, MAX_STATIC_FILE_SIZE, ScriptSkill, StaticFileSkill, StaticScriptSkill, X402ProxySkill, loadSkillsFromDir, parseSkillMd, resolveInsidePath, runScript, validateSkillFrontmatter };
|
|
1147
1333
|
//# sourceMappingURL=skills.js.map
|
|
1148
1334
|
//# sourceMappingURL=skills.js.map
|