@elisym/sdk 0.25.0 → 0.25.3
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.map +1 -1
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +369 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +378 -41
- package/dist/index.d.ts +378 -41
- package/dist/index.js +360 -13
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +83 -22
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +66 -0
- package/dist/node.d.ts +66 -0
- package/dist/node.js +83 -22
- package/dist/node.js.map +1 -1
- package/dist/skills.cjs +57 -1
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +23 -3
- package/dist/skills.d.ts +23 -3
- package/dist/skills.js +58 -2
- package/dist/skills.js.map +1 -1
- package/package.json +1 -1
package/dist/skills.d.cts
CHANGED
|
@@ -29,9 +29,16 @@ interface SkillOutput {
|
|
|
29
29
|
*/
|
|
30
30
|
filePath?: string;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Local paths to MULTIPLE file results (a skill that wrote several files to
|
|
33
|
+
* `ELISYM_OUTPUT_DIR`). When set, each is seeded + delivered as its own
|
|
34
|
+
* attachment; `outputMime` applies to all. Mutually exclusive with `filePath`
|
|
35
|
+
* (the runtime prefers `filePaths` when both are somehow present).
|
|
36
|
+
*/
|
|
37
|
+
filePaths?: string[];
|
|
38
|
+
/**
|
|
39
|
+
* Releases the resources backing `filePath`/`filePaths` (e.g. a temp dir). The
|
|
40
|
+
* runtime calls it once it has seeded the file(s) - or failed to - since seeding
|
|
41
|
+
* happens after `execute()` returns and the producer cannot release them itself.
|
|
35
42
|
* Mirrors the input-side cleanup callback in the runtime's `resolveInputFile`.
|
|
36
43
|
*/
|
|
37
44
|
cleanup?: () => Promise<void>;
|
|
@@ -451,6 +458,13 @@ interface SkillFrontmatter {
|
|
|
451
458
|
* exact. Its presence signals "this capability needs a file input".
|
|
452
459
|
*/
|
|
453
460
|
input_mime?: unknown;
|
|
461
|
+
/**
|
|
462
|
+
* Whether the skill ALSO accepts a text prompt alongside a file input
|
|
463
|
+
* (`dynamic-script` only; meaningful only with `input_mime`). `'none'` = file
|
|
464
|
+
* only, `'optional'` = file + optional note (default), `'required'` = needs both.
|
|
465
|
+
* Discovery hint only; lets the web app show/hide its text box for file jobs.
|
|
466
|
+
*/
|
|
467
|
+
input_text?: unknown;
|
|
454
468
|
/**
|
|
455
469
|
* Optional per-skill rate limit. Applies to any skill mode. Snake-case
|
|
456
470
|
* keys here match the YAML frontmatter convention; parsed into camelCase
|
|
@@ -503,6 +517,12 @@ interface ParsedSkill {
|
|
|
503
517
|
* capability needs a file input (clients gate file-only flows on it).
|
|
504
518
|
*/
|
|
505
519
|
inputMime?: string;
|
|
520
|
+
/**
|
|
521
|
+
* Whether the skill also accepts a text prompt with a file input (mode
|
|
522
|
+
* 'dynamic-script' only). Discovery hint; clients (the web app) gate their text
|
|
523
|
+
* box on it. Default behavior when absent = file + optional text.
|
|
524
|
+
*/
|
|
525
|
+
inputText?: 'required' | 'optional' | 'none';
|
|
506
526
|
/** Optional per-skill rate limit (any mode). */
|
|
507
527
|
rateLimit?: SkillRateLimit;
|
|
508
528
|
/**
|
package/dist/skills.d.ts
CHANGED
|
@@ -29,9 +29,16 @@ interface SkillOutput {
|
|
|
29
29
|
*/
|
|
30
30
|
filePath?: string;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Local paths to MULTIPLE file results (a skill that wrote several files to
|
|
33
|
+
* `ELISYM_OUTPUT_DIR`). When set, each is seeded + delivered as its own
|
|
34
|
+
* attachment; `outputMime` applies to all. Mutually exclusive with `filePath`
|
|
35
|
+
* (the runtime prefers `filePaths` when both are somehow present).
|
|
36
|
+
*/
|
|
37
|
+
filePaths?: string[];
|
|
38
|
+
/**
|
|
39
|
+
* Releases the resources backing `filePath`/`filePaths` (e.g. a temp dir). The
|
|
40
|
+
* runtime calls it once it has seeded the file(s) - or failed to - since seeding
|
|
41
|
+
* happens after `execute()` returns and the producer cannot release them itself.
|
|
35
42
|
* Mirrors the input-side cleanup callback in the runtime's `resolveInputFile`.
|
|
36
43
|
*/
|
|
37
44
|
cleanup?: () => Promise<void>;
|
|
@@ -451,6 +458,13 @@ interface SkillFrontmatter {
|
|
|
451
458
|
* exact. Its presence signals "this capability needs a file input".
|
|
452
459
|
*/
|
|
453
460
|
input_mime?: unknown;
|
|
461
|
+
/**
|
|
462
|
+
* Whether the skill ALSO accepts a text prompt alongside a file input
|
|
463
|
+
* (`dynamic-script` only; meaningful only with `input_mime`). `'none'` = file
|
|
464
|
+
* only, `'optional'` = file + optional note (default), `'required'` = needs both.
|
|
465
|
+
* Discovery hint only; lets the web app show/hide its text box for file jobs.
|
|
466
|
+
*/
|
|
467
|
+
input_text?: unknown;
|
|
454
468
|
/**
|
|
455
469
|
* Optional per-skill rate limit. Applies to any skill mode. Snake-case
|
|
456
470
|
* keys here match the YAML frontmatter convention; parsed into camelCase
|
|
@@ -503,6 +517,12 @@ interface ParsedSkill {
|
|
|
503
517
|
* capability needs a file input (clients gate file-only flows on it).
|
|
504
518
|
*/
|
|
505
519
|
inputMime?: string;
|
|
520
|
+
/**
|
|
521
|
+
* Whether the skill also accepts a text prompt with a file input (mode
|
|
522
|
+
* 'dynamic-script' only). Discovery hint; clients (the web app) gate their text
|
|
523
|
+
* box on it. Default behavior when absent = file + optional text.
|
|
524
|
+
*/
|
|
525
|
+
inputText?: 'required' | 'optional' | 'none';
|
|
506
526
|
/** Optional per-skill rate limit (any mode). */
|
|
507
527
|
rateLimit?: SkillRateLimit;
|
|
508
528
|
/**
|
package/dist/skills.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { StringDecoder } from 'node:string_decoder';
|
|
3
|
-
import { readFile, mkdtemp, stat, rm } from 'node:fs/promises';
|
|
3
|
+
import { readFile, mkdtemp, mkdir, readdir, stat, rm } from 'node:fs/promises';
|
|
4
4
|
import { dirname, join, resolve, relative, sep } from 'node:path';
|
|
5
5
|
import { tmpdir } from 'node:os';
|
|
6
6
|
import { readdirSync, statSync, readFileSync } from 'node:fs';
|
|
@@ -365,9 +365,12 @@ var DynamicScriptSkill = class {
|
|
|
365
365
|
async execute(input, ctx) {
|
|
366
366
|
const outDir = await mkdtemp(join(tmpdir(), "elisym-skill-out-"));
|
|
367
367
|
const outputFile = join(outDir, "output");
|
|
368
|
+
const outputDir = join(outDir, "files");
|
|
369
|
+
await mkdir(outputDir, { recursive: true });
|
|
368
370
|
const env = {
|
|
369
371
|
...this.scriptEnv ?? process.env,
|
|
370
|
-
ELISYM_OUTPUT_FILE: outputFile
|
|
372
|
+
ELISYM_OUTPUT_FILE: outputFile,
|
|
373
|
+
ELISYM_OUTPUT_DIR: outputDir
|
|
371
374
|
};
|
|
372
375
|
if (input.filePath !== void 0) {
|
|
373
376
|
env.ELISYM_INPUT_FILE = input.filePath;
|
|
@@ -395,6 +398,29 @@ var DynamicScriptSkill = class {
|
|
|
395
398
|
const detail = result.stderr.trim() || result.stdout.trim() || "(no output)";
|
|
396
399
|
throw new ScriptExecutionError(result.code, detail);
|
|
397
400
|
}
|
|
401
|
+
const dirEntries = await readdir(outputDir, { withFileTypes: true }).catch(() => []);
|
|
402
|
+
const filePaths = [];
|
|
403
|
+
for (const entry of dirEntries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
404
|
+
if (!entry.isFile()) {
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const candidate = join(outputDir, entry.name);
|
|
408
|
+
const entryStat = await stat(candidate).catch(() => null);
|
|
409
|
+
if (entryStat !== null && entryStat.isFile() && entryStat.size > 0) {
|
|
410
|
+
filePaths.push(candidate);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if (filePaths.length > 0) {
|
|
414
|
+
keepOutDir = true;
|
|
415
|
+
return {
|
|
416
|
+
data: result.stdout.trim(),
|
|
417
|
+
filePaths,
|
|
418
|
+
outputMime: this.outputMime ?? "application/octet-stream",
|
|
419
|
+
cleanup: async () => {
|
|
420
|
+
await rm(outDir, { recursive: true, force: true });
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
}
|
|
398
424
|
const outputStat = await stat(outputFile).catch(() => null);
|
|
399
425
|
if (outputStat !== null && outputStat.isFile() && outputStat.size > 0) {
|
|
400
426
|
keepOutDir = true;
|
|
@@ -762,6 +788,18 @@ function validateInputMime(skillName, raw) {
|
|
|
762
788
|
}
|
|
763
789
|
return raw;
|
|
764
790
|
}
|
|
791
|
+
var INPUT_TEXT_VALUES = ["required", "optional", "none"];
|
|
792
|
+
function validateInputText(skillName, raw) {
|
|
793
|
+
if (raw === void 0 || raw === null) {
|
|
794
|
+
return void 0;
|
|
795
|
+
}
|
|
796
|
+
if (typeof raw !== "string" || !INPUT_TEXT_VALUES.includes(raw)) {
|
|
797
|
+
throw new Error(
|
|
798
|
+
`SKILL.md "${skillName}": "input_text" must be one of "required", "optional", "none"`
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
return raw;
|
|
802
|
+
}
|
|
765
803
|
function validateMaxExecutionSecs(skillName, raw) {
|
|
766
804
|
if (raw === void 0 || raw === null) {
|
|
767
805
|
return void 0;
|
|
@@ -864,6 +902,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
864
902
|
let scriptTimeoutMs;
|
|
865
903
|
let outputMime;
|
|
866
904
|
let inputMime;
|
|
905
|
+
let inputText;
|
|
867
906
|
if (mode === "static-file") {
|
|
868
907
|
if (typeof frontmatter.output_file !== "string" || frontmatter.output_file.length === 0) {
|
|
869
908
|
throw new Error(
|
|
@@ -885,6 +924,11 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
885
924
|
`SKILL.md "${frontmatter.name}": "input_mime" is only valid in mode 'dynamic-script'`
|
|
886
925
|
);
|
|
887
926
|
}
|
|
927
|
+
if (frontmatter.input_text !== void 0) {
|
|
928
|
+
throw new Error(
|
|
929
|
+
`SKILL.md "${frontmatter.name}": "input_text" is only valid in mode 'dynamic-script'`
|
|
930
|
+
);
|
|
931
|
+
}
|
|
888
932
|
outputFile = frontmatter.output_file;
|
|
889
933
|
} else if (mode === "static-script" || mode === "dynamic-script") {
|
|
890
934
|
if (typeof frontmatter.script !== "string" || frontmatter.script.length === 0) {
|
|
@@ -901,6 +945,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
901
945
|
if (mode === "dynamic-script") {
|
|
902
946
|
outputMime = validateOutputMime(frontmatter.name, frontmatter.output_mime);
|
|
903
947
|
inputMime = validateInputMime(frontmatter.name, frontmatter.input_mime);
|
|
948
|
+
inputText = validateInputText(frontmatter.name, frontmatter.input_text);
|
|
904
949
|
} else {
|
|
905
950
|
if (frontmatter.output_mime !== void 0) {
|
|
906
951
|
throw new Error(
|
|
@@ -912,6 +957,11 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
912
957
|
`SKILL.md "${frontmatter.name}": "input_mime" is only valid in mode 'dynamic-script'`
|
|
913
958
|
);
|
|
914
959
|
}
|
|
960
|
+
if (frontmatter.input_text !== void 0) {
|
|
961
|
+
throw new Error(
|
|
962
|
+
`SKILL.md "${frontmatter.name}": "input_text" is only valid in mode 'dynamic-script'`
|
|
963
|
+
);
|
|
964
|
+
}
|
|
915
965
|
}
|
|
916
966
|
} else {
|
|
917
967
|
if (frontmatter.output_file !== void 0) {
|
|
@@ -944,6 +994,11 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
944
994
|
`SKILL.md "${frontmatter.name}": "input_mime" is only valid in mode 'dynamic-script'`
|
|
945
995
|
);
|
|
946
996
|
}
|
|
997
|
+
if (frontmatter.input_text !== void 0) {
|
|
998
|
+
throw new Error(
|
|
999
|
+
`SKILL.md "${frontmatter.name}": "input_text" is only valid in mode 'dynamic-script'`
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
947
1002
|
}
|
|
948
1003
|
const image = typeof frontmatter.image === "string" ? frontmatter.image : void 0;
|
|
949
1004
|
const imageFile = typeof frontmatter.image_file === "string" ? frontmatter.image_file : void 0;
|
|
@@ -972,6 +1027,7 @@ function validateSkillFrontmatter(frontmatter, systemPrompt, options = {}) {
|
|
|
972
1027
|
scriptTimeoutMs,
|
|
973
1028
|
outputMime,
|
|
974
1029
|
inputMime,
|
|
1030
|
+
inputText,
|
|
975
1031
|
rateLimit,
|
|
976
1032
|
executionTimeoutSecs
|
|
977
1033
|
};
|