@elisym/sdk 0.12.5 → 0.13.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 -22
- package/dist/agent-store.cjs.map +1 -1
- package/dist/agent-store.d.cts +7 -3
- package/dist/agent-store.d.ts +7 -3
- package/dist/agent-store.js +16 -22
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +4 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -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 +80 -5
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +54 -2
- package/dist/skills.d.ts +54 -2
- package/dist/skills.js +80 -5
- package/dist/skills.js.map +1 -1
- package/package.json +1 -1
package/dist/skills.d.ts
CHANGED
|
@@ -16,9 +16,28 @@ interface SkillOutput {
|
|
|
16
16
|
data: string;
|
|
17
17
|
outputMime?: string;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Optional per-skill LLM override declared in SKILL.md frontmatter.
|
|
21
|
+
*
|
|
22
|
+
* Parse-time invariant (enforced by `validateLlmOverride` in the loader):
|
|
23
|
+
* `provider` is set iff `model` is set. `maxTokens` is independent. So
|
|
24
|
+
* downstream code may rely on: when `provider !== undefined`, `model` is
|
|
25
|
+
* also defined.
|
|
26
|
+
*/
|
|
27
|
+
interface SkillLlmOverride {
|
|
28
|
+
provider?: 'anthropic' | 'openai';
|
|
29
|
+
model?: string;
|
|
30
|
+
maxTokens?: number;
|
|
31
|
+
}
|
|
19
32
|
interface SkillContext {
|
|
20
|
-
/**
|
|
33
|
+
/** Agent-default LLM client. May be undefined when every LLM skill overrides. */
|
|
21
34
|
llm?: LlmClient;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the LLM client for a skill. The runtime caches clients by
|
|
37
|
+
* resolved (provider, model, maxTokens) triple. Callers pass their
|
|
38
|
+
* `llmOverride` (or undefined for the agent default).
|
|
39
|
+
*/
|
|
40
|
+
getLlm?: (override?: SkillLlmOverride) => LlmClient | undefined;
|
|
22
41
|
agentName: string;
|
|
23
42
|
agentDescription: string;
|
|
24
43
|
signal?: AbortSignal;
|
|
@@ -74,6 +93,12 @@ interface Skill {
|
|
|
74
93
|
asset: Asset;
|
|
75
94
|
/** Execution mode. Default 'llm' for back-compat. */
|
|
76
95
|
mode: SkillMode;
|
|
96
|
+
/**
|
|
97
|
+
* Optional per-skill LLM config override (only set when mode === 'llm').
|
|
98
|
+
* Carried through from SKILL.md frontmatter so the runtime can route this
|
|
99
|
+
* skill to a non-default model/provider/max_tokens.
|
|
100
|
+
*/
|
|
101
|
+
llmOverride?: SkillLlmOverride;
|
|
77
102
|
image?: string;
|
|
78
103
|
imageFile?: string;
|
|
79
104
|
execute(input: SkillInput, ctx: SkillContext): Promise<SkillOutput>;
|
|
@@ -144,6 +169,8 @@ interface ScriptSkillParams {
|
|
|
144
169
|
systemPrompt: string;
|
|
145
170
|
tools: SkillToolDef[];
|
|
146
171
|
maxToolRounds: number;
|
|
172
|
+
/** Optional per-skill LLM override (provider/model pair and/or maxTokens). */
|
|
173
|
+
llmOverride?: SkillLlmOverride;
|
|
147
174
|
image?: string;
|
|
148
175
|
imageFile?: string;
|
|
149
176
|
logger?: ScriptSkillLogger;
|
|
@@ -162,6 +189,7 @@ declare class ScriptSkill implements Skill {
|
|
|
162
189
|
priceSubunits: bigint;
|
|
163
190
|
asset: Asset;
|
|
164
191
|
mode: SkillMode;
|
|
192
|
+
readonly llmOverride?: SkillLlmOverride;
|
|
165
193
|
image?: string;
|
|
166
194
|
imageFile?: string;
|
|
167
195
|
private skillDir;
|
|
@@ -171,6 +199,18 @@ declare class ScriptSkill implements Skill {
|
|
|
171
199
|
private logger;
|
|
172
200
|
constructor(params: ScriptSkillParams);
|
|
173
201
|
execute(input: SkillInput, ctx: SkillContext): Promise<SkillOutput>;
|
|
202
|
+
/**
|
|
203
|
+
* Resolve the LLM client for this skill from the runtime context.
|
|
204
|
+
*
|
|
205
|
+
* Contract:
|
|
206
|
+
* - When `llmOverride` is set, `ctx.getLlm` MUST be wired. Falling back to
|
|
207
|
+
* `ctx.llm` (the agent default) would silently use the wrong configuration
|
|
208
|
+
* for max-tokens-only overrides.
|
|
209
|
+
* - When no override is set, prefer `ctx.getLlm()` (returns the agent
|
|
210
|
+
* default), then fall back to `ctx.llm` for legacy callers that wire only
|
|
211
|
+
* a single client.
|
|
212
|
+
*/
|
|
213
|
+
private resolveLlmClient;
|
|
174
214
|
private runTool;
|
|
175
215
|
}
|
|
176
216
|
|
|
@@ -304,6 +344,12 @@ interface SkillFrontmatter {
|
|
|
304
344
|
image_file?: unknown;
|
|
305
345
|
tools?: unknown;
|
|
306
346
|
max_tool_rounds?: unknown;
|
|
347
|
+
/** Optional per-skill LLM provider override ('anthropic' | 'openai'). Pairs with `model`. */
|
|
348
|
+
provider?: unknown;
|
|
349
|
+
/** Optional per-skill LLM model override. Pairs with `provider`. */
|
|
350
|
+
model?: unknown;
|
|
351
|
+
/** Optional per-skill max_tokens override. Independent of provider/model. */
|
|
352
|
+
max_tokens?: unknown;
|
|
307
353
|
/** Execution mode. Default 'llm'. */
|
|
308
354
|
mode?: unknown;
|
|
309
355
|
/** Required when mode === 'static-file'. Path relative to skill dir. */
|
|
@@ -326,6 +372,12 @@ interface ParsedSkill {
|
|
|
326
372
|
systemPrompt: string;
|
|
327
373
|
tools: SkillToolDef[];
|
|
328
374
|
maxToolRounds: number;
|
|
375
|
+
/**
|
|
376
|
+
* Per-skill LLM override (only present when mode === 'llm' and the SKILL.md
|
|
377
|
+
* declared at least one of `provider`/`model`/`max_tokens`). Parse-time
|
|
378
|
+
* invariant: `provider` set iff `model` set.
|
|
379
|
+
*/
|
|
380
|
+
llmOverride?: SkillLlmOverride;
|
|
329
381
|
image?: string;
|
|
330
382
|
imageFile?: string;
|
|
331
383
|
/** Set when mode === 'static-file'. */
|
|
@@ -362,4 +414,4 @@ declare function validateSkillFrontmatter(frontmatter: SkillFrontmatter, systemP
|
|
|
362
414
|
*/
|
|
363
415
|
declare function loadSkillsFromDir(skillsDir: string, options?: LoadSkillsOptions): Skill[];
|
|
364
416
|
|
|
365
|
-
export { type CompletionResult, DEFAULT_MAX_TOOL_ROUNDS, DEFAULT_SCRIPT_TIMEOUT_MS, DynamicScriptSkill, type DynamicScriptSkillParams, type LlmClient, type LlmClientConfig, type LlmProvider, type LoadSkillsOptions, type LoaderLogger, MAX_SCRIPT_OUTPUT, MAX_STATIC_FILE_SIZE, type ParsedSkill, type RunScriptOptions, type RunScriptResult, ScriptSkill, type ScriptSkillLogger, type ScriptSkillParams, type Skill, type SkillContext, type SkillFrontmatter, type SkillInput, type SkillMode, type SkillOutput, type SkillToolDef, StaticFileSkill, type StaticFileSkillParams, StaticScriptSkill, type StaticScriptSkillParams, type ToolCall, type ToolDef, type ToolResult, createAnthropicClient, createLlmClient, createOpenAIClient, loadSkillsFromDir, parseSkillMd, resolveInsidePath, runScript, validateSkillFrontmatter };
|
|
417
|
+
export { type CompletionResult, DEFAULT_MAX_TOOL_ROUNDS, DEFAULT_SCRIPT_TIMEOUT_MS, DynamicScriptSkill, type DynamicScriptSkillParams, type LlmClient, type LlmClientConfig, type LlmProvider, type LoadSkillsOptions, type LoaderLogger, MAX_SCRIPT_OUTPUT, MAX_STATIC_FILE_SIZE, type ParsedSkill, type RunScriptOptions, type RunScriptResult, ScriptSkill, type ScriptSkillLogger, type ScriptSkillParams, type Skill, type SkillContext, type SkillFrontmatter, type SkillInput, type SkillLlmOverride, type SkillMode, type SkillOutput, type SkillToolDef, StaticFileSkill, type StaticFileSkillParams, StaticScriptSkill, type StaticScriptSkillParams, type ToolCall, type ToolDef, type ToolResult, createAnthropicClient, createLlmClient, createOpenAIClient, loadSkillsFromDir, parseSkillMd, resolveInsidePath, runScript, validateSkillFrontmatter };
|
package/dist/skills.js
CHANGED
|
@@ -358,6 +358,7 @@ var ScriptSkill = class {
|
|
|
358
358
|
priceSubunits;
|
|
359
359
|
asset;
|
|
360
360
|
mode = "llm";
|
|
361
|
+
llmOverride;
|
|
361
362
|
image;
|
|
362
363
|
imageFile;
|
|
363
364
|
skillDir;
|
|
@@ -371,6 +372,7 @@ var ScriptSkill = class {
|
|
|
371
372
|
this.capabilities = params.capabilities;
|
|
372
373
|
this.priceSubunits = params.priceSubunits;
|
|
373
374
|
this.asset = params.asset;
|
|
375
|
+
this.llmOverride = params.llmOverride;
|
|
374
376
|
this.image = params.image;
|
|
375
377
|
this.imageFile = params.imageFile;
|
|
376
378
|
this.skillDir = params.skillDir;
|
|
@@ -380,11 +382,9 @@ var ScriptSkill = class {
|
|
|
380
382
|
this.logger = params.logger ?? {};
|
|
381
383
|
}
|
|
382
384
|
async execute(input, ctx) {
|
|
383
|
-
|
|
384
|
-
throw new Error("LLM client not configured for skill runtime");
|
|
385
|
-
}
|
|
385
|
+
const llm = this.resolveLlmClient(ctx);
|
|
386
386
|
if (this.tools.length === 0) {
|
|
387
|
-
const result = await
|
|
387
|
+
const result = await llm.complete(this.systemPrompt, input.data, ctx.signal);
|
|
388
388
|
return { data: result };
|
|
389
389
|
}
|
|
390
390
|
const toolDefs = this.tools.map((tool) => ({
|
|
@@ -397,7 +397,6 @@ var ScriptSkill = class {
|
|
|
397
397
|
}))
|
|
398
398
|
}));
|
|
399
399
|
const messages = [{ role: "user", content: input.data }];
|
|
400
|
-
const llm = ctx.llm;
|
|
401
400
|
for (let round = 0; round < this.maxToolRounds; round++) {
|
|
402
401
|
if (ctx.signal?.aborted) {
|
|
403
402
|
throw new Error("Job aborted");
|
|
@@ -429,6 +428,34 @@ var ScriptSkill = class {
|
|
|
429
428
|
}
|
|
430
429
|
throw new Error(`Max tool rounds (${this.maxToolRounds}) exceeded`);
|
|
431
430
|
}
|
|
431
|
+
/**
|
|
432
|
+
* Resolve the LLM client for this skill from the runtime context.
|
|
433
|
+
*
|
|
434
|
+
* Contract:
|
|
435
|
+
* - When `llmOverride` is set, `ctx.getLlm` MUST be wired. Falling back to
|
|
436
|
+
* `ctx.llm` (the agent default) would silently use the wrong configuration
|
|
437
|
+
* for max-tokens-only overrides.
|
|
438
|
+
* - When no override is set, prefer `ctx.getLlm()` (returns the agent
|
|
439
|
+
* default), then fall back to `ctx.llm` for legacy callers that wire only
|
|
440
|
+
* a single client.
|
|
441
|
+
*/
|
|
442
|
+
resolveLlmClient(ctx) {
|
|
443
|
+
let client;
|
|
444
|
+
if (this.llmOverride) {
|
|
445
|
+
client = ctx.getLlm?.(this.llmOverride);
|
|
446
|
+
if (!client) {
|
|
447
|
+
throw new Error(
|
|
448
|
+
`Skill "${this.name}" requires ctx.getLlm to be configured (llmOverride is set)`
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
return client;
|
|
452
|
+
}
|
|
453
|
+
client = ctx.getLlm?.() ?? ctx.llm;
|
|
454
|
+
if (!client) {
|
|
455
|
+
throw new Error("LLM client not configured for skill runtime");
|
|
456
|
+
}
|
|
457
|
+
return client;
|
|
458
|
+
}
|
|
432
459
|
async runTool(toolDef, call, signal) {
|
|
433
460
|
const args = [...toolDef.command];
|
|
434
461
|
const cmd = args.shift();
|
|
@@ -654,6 +681,8 @@ function parseAssetAmount(asset, human) {
|
|
|
654
681
|
Decimal.clone({ toExpNeg: -100, toExpPos: 100, precision: 50 });
|
|
655
682
|
|
|
656
683
|
// src/skills/loader.ts
|
|
684
|
+
var VALID_PROVIDERS = ["anthropic", "openai"];
|
|
685
|
+
var MAX_TOKENS_LIMIT = 2e5;
|
|
657
686
|
var DEFAULT_MAX_TOOL_ROUNDS = 10;
|
|
658
687
|
var VALID_MODES = [
|
|
659
688
|
"llm",
|
|
@@ -805,6 +834,49 @@ function validateScriptArgs(skillName, raw) {
|
|
|
805
834
|
}
|
|
806
835
|
return raw;
|
|
807
836
|
}
|
|
837
|
+
function validateLlmOverride(skillName, frontmatter, mode) {
|
|
838
|
+
const hasProvider = frontmatter.provider !== void 0 && frontmatter.provider !== null;
|
|
839
|
+
const hasModel = frontmatter.model !== void 0 && frontmatter.model !== null;
|
|
840
|
+
const hasMaxTokens = frontmatter.max_tokens !== void 0 && frontmatter.max_tokens !== null;
|
|
841
|
+
if (!hasProvider && !hasModel && !hasMaxTokens) {
|
|
842
|
+
return void 0;
|
|
843
|
+
}
|
|
844
|
+
if (mode !== "llm") {
|
|
845
|
+
throw new Error(
|
|
846
|
+
`SKILL.md "${skillName}": "provider"/"model"/"max_tokens" are only valid in mode 'llm' (got '${mode}')`
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
if (hasProvider !== hasModel) {
|
|
850
|
+
throw new Error(
|
|
851
|
+
`SKILL.md "${skillName}": "provider" and "model" must be set together (declare both, or neither)`
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
const override = {};
|
|
855
|
+
if (hasProvider && hasModel) {
|
|
856
|
+
if (typeof frontmatter.provider !== "string") {
|
|
857
|
+
throw new Error(`SKILL.md "${skillName}": "provider" must be a string`);
|
|
858
|
+
}
|
|
859
|
+
if (!VALID_PROVIDERS.includes(frontmatter.provider)) {
|
|
860
|
+
throw new Error(
|
|
861
|
+
`SKILL.md "${skillName}": invalid provider "${frontmatter.provider}". Allowed: ${VALID_PROVIDERS.join(", ")}`
|
|
862
|
+
);
|
|
863
|
+
}
|
|
864
|
+
if (typeof frontmatter.model !== "string" || frontmatter.model.length === 0) {
|
|
865
|
+
throw new Error(`SKILL.md "${skillName}": "model" must be a non-empty string`);
|
|
866
|
+
}
|
|
867
|
+
override.provider = frontmatter.provider;
|
|
868
|
+
override.model = frontmatter.model;
|
|
869
|
+
}
|
|
870
|
+
if (hasMaxTokens) {
|
|
871
|
+
if (typeof frontmatter.max_tokens !== "number" || !Number.isInteger(frontmatter.max_tokens) || frontmatter.max_tokens <= 0 || frontmatter.max_tokens > MAX_TOKENS_LIMIT) {
|
|
872
|
+
throw new Error(
|
|
873
|
+
`SKILL.md "${skillName}": "max_tokens" must be a positive integer <= ${MAX_TOKENS_LIMIT}`
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
override.maxTokens = frontmatter.max_tokens;
|
|
877
|
+
}
|
|
878
|
+
return override;
|
|
879
|
+
}
|
|
808
880
|
function validateScriptTimeoutMs(skillName, raw) {
|
|
809
881
|
if (raw === void 0 || raw === null) {
|
|
810
882
|
return void 0;
|
|
@@ -946,6 +1018,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
946
1018
|
}
|
|
947
1019
|
const image = typeof frontmatter.image === "string" ? frontmatter.image : void 0;
|
|
948
1020
|
const imageFile = typeof frontmatter.image_file === "string" ? frontmatter.image_file : void 0;
|
|
1021
|
+
const llmOverride = validateLlmOverride(frontmatter.name, frontmatter, mode);
|
|
949
1022
|
return {
|
|
950
1023
|
name: frontmatter.name,
|
|
951
1024
|
description: frontmatter.description,
|
|
@@ -956,6 +1029,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
956
1029
|
systemPrompt,
|
|
957
1030
|
tools,
|
|
958
1031
|
maxToolRounds,
|
|
1032
|
+
llmOverride,
|
|
959
1033
|
image,
|
|
960
1034
|
imageFile,
|
|
961
1035
|
outputFile,
|
|
@@ -977,6 +1051,7 @@ function buildSkillFromParsed(parsed, skillDir, logger) {
|
|
|
977
1051
|
systemPrompt: parsed.systemPrompt,
|
|
978
1052
|
tools: parsed.tools,
|
|
979
1053
|
maxToolRounds: parsed.maxToolRounds,
|
|
1054
|
+
llmOverride: parsed.llmOverride,
|
|
980
1055
|
image: parsed.image,
|
|
981
1056
|
imageFile: parsed.imageFile,
|
|
982
1057
|
logger
|