@aigne/agent-runtime 1.12.0-beta.5
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/LICENSE.md +26 -0
- package/README.md +79 -0
- package/dist/agent-runners/ai-runner.cjs +133 -0
- package/dist/agent-runners/ai-runner.d.cts +33 -0
- package/dist/agent-runners/ai-runner.d.cts.map +1 -0
- package/dist/agent-runners/ai-runner.d.mts +33 -0
- package/dist/agent-runners/ai-runner.d.mts.map +1 -0
- package/dist/agent-runners/ai-runner.mjs +134 -0
- package/dist/agent-runners/ai-runner.mjs.map +1 -0
- package/dist/agent-runners/ash-runner.cjs +272 -0
- package/dist/agent-runners/ash-runner.d.cts +30 -0
- package/dist/agent-runners/ash-runner.d.cts.map +1 -0
- package/dist/agent-runners/ash-runner.d.mts +30 -0
- package/dist/agent-runners/ash-runner.d.mts.map +1 -0
- package/dist/agent-runners/ash-runner.mjs +273 -0
- package/dist/agent-runners/ash-runner.mjs.map +1 -0
- package/dist/agent-runners/budget.cjs +71 -0
- package/dist/agent-runners/budget.d.cts +40 -0
- package/dist/agent-runners/budget.d.cts.map +1 -0
- package/dist/agent-runners/budget.d.mts +40 -0
- package/dist/agent-runners/budget.d.mts.map +1 -0
- package/dist/agent-runners/budget.mjs +67 -0
- package/dist/agent-runners/budget.mjs.map +1 -0
- package/dist/agent-runners/code-runner.cjs +61 -0
- package/dist/agent-runners/code-runner.mjs +61 -0
- package/dist/agent-runners/code-runner.mjs.map +1 -0
- package/dist/agent-runners/env-whitelist.cjs +36 -0
- package/dist/agent-runners/env-whitelist.d.cts +5 -0
- package/dist/agent-runners/env-whitelist.d.cts.map +1 -0
- package/dist/agent-runners/env-whitelist.d.mts +5 -0
- package/dist/agent-runners/env-whitelist.d.mts.map +1 -0
- package/dist/agent-runners/env-whitelist.mjs +36 -0
- package/dist/agent-runners/env-whitelist.mjs.map +1 -0
- package/dist/agent-runners/guide-rails.cjs +47 -0
- package/dist/agent-runners/guide-rails.d.cts +16 -0
- package/dist/agent-runners/guide-rails.d.cts.map +1 -0
- package/dist/agent-runners/guide-rails.d.mts +16 -0
- package/dist/agent-runners/guide-rails.d.mts.map +1 -0
- package/dist/agent-runners/guide-rails.mjs +48 -0
- package/dist/agent-runners/guide-rails.mjs.map +1 -0
- package/dist/agent-runners/hook-channel.cjs +55 -0
- package/dist/agent-runners/hook-channel.d.cts +38 -0
- package/dist/agent-runners/hook-channel.d.cts.map +1 -0
- package/dist/agent-runners/hook-channel.d.mts +38 -0
- package/dist/agent-runners/hook-channel.d.mts.map +1 -0
- package/dist/agent-runners/hook-channel.mjs +55 -0
- package/dist/agent-runners/hook-channel.mjs.map +1 -0
- package/dist/agent-runners/hooks.cjs +107 -0
- package/dist/agent-runners/hooks.d.cts +41 -0
- package/dist/agent-runners/hooks.d.cts.map +1 -0
- package/dist/agent-runners/hooks.d.mts +41 -0
- package/dist/agent-runners/hooks.d.mts.map +1 -0
- package/dist/agent-runners/hooks.mjs +107 -0
- package/dist/agent-runners/hooks.mjs.map +1 -0
- package/dist/agent-runners/memory-afs.cjs +342 -0
- package/dist/agent-runners/memory-afs.d.cts +221 -0
- package/dist/agent-runners/memory-afs.d.cts.map +1 -0
- package/dist/agent-runners/memory-afs.d.mts +221 -0
- package/dist/agent-runners/memory-afs.d.mts.map +1 -0
- package/dist/agent-runners/memory-afs.mjs +326 -0
- package/dist/agent-runners/memory-afs.mjs.map +1 -0
- package/dist/agent-runners/memory-archive.cjs +263 -0
- package/dist/agent-runners/memory-archive.d.cts +47 -0
- package/dist/agent-runners/memory-archive.d.cts.map +1 -0
- package/dist/agent-runners/memory-archive.d.mts +47 -0
- package/dist/agent-runners/memory-archive.d.mts.map +1 -0
- package/dist/agent-runners/memory-archive.mjs +257 -0
- package/dist/agent-runners/memory-archive.mjs.map +1 -0
- package/dist/agent-runners/orchestrator-runner.cjs +302 -0
- package/dist/agent-runners/orchestrator-runner.d.cts +23 -0
- package/dist/agent-runners/orchestrator-runner.d.cts.map +1 -0
- package/dist/agent-runners/orchestrator-runner.d.mts +23 -0
- package/dist/agent-runners/orchestrator-runner.d.mts.map +1 -0
- package/dist/agent-runners/orchestrator-runner.mjs +303 -0
- package/dist/agent-runners/orchestrator-runner.mjs.map +1 -0
- package/dist/agent-runners/orchestrator-state.cjs +68 -0
- package/dist/agent-runners/orchestrator-state.d.cts +23 -0
- package/dist/agent-runners/orchestrator-state.d.cts.map +1 -0
- package/dist/agent-runners/orchestrator-state.d.mts +23 -0
- package/dist/agent-runners/orchestrator-state.d.mts.map +1 -0
- package/dist/agent-runners/orchestrator-state.mjs +65 -0
- package/dist/agent-runners/orchestrator-state.mjs.map +1 -0
- package/dist/agent-runners/retry.cjs +30 -0
- package/dist/agent-runners/retry.d.cts +13 -0
- package/dist/agent-runners/retry.d.cts.map +1 -0
- package/dist/agent-runners/retry.d.mts +13 -0
- package/dist/agent-runners/retry.d.mts.map +1 -0
- package/dist/agent-runners/retry.mjs +30 -0
- package/dist/agent-runners/retry.mjs.map +1 -0
- package/dist/agent-runners/scratchpad-afs.cjs +276 -0
- package/dist/agent-runners/scratchpad-afs.d.cts +103 -0
- package/dist/agent-runners/scratchpad-afs.d.cts.map +1 -0
- package/dist/agent-runners/scratchpad-afs.d.mts +103 -0
- package/dist/agent-runners/scratchpad-afs.d.mts.map +1 -0
- package/dist/agent-runners/scratchpad-afs.mjs +271 -0
- package/dist/agent-runners/scratchpad-afs.mjs.map +1 -0
- package/dist/agent-runners/stream-router.cjs +72 -0
- package/dist/agent-runners/stream-router.d.cts +22 -0
- package/dist/agent-runners/stream-router.d.cts.map +1 -0
- package/dist/agent-runners/stream-router.d.mts +22 -0
- package/dist/agent-runners/stream-router.d.mts.map +1 -0
- package/dist/agent-runners/stream-router.mjs +72 -0
- package/dist/agent-runners/stream-router.mjs.map +1 -0
- package/dist/agent-runners/system-prompt.cjs +35 -0
- package/dist/agent-runners/system-prompt.d.cts +17 -0
- package/dist/agent-runners/system-prompt.d.cts.map +1 -0
- package/dist/agent-runners/system-prompt.d.mts +17 -0
- package/dist/agent-runners/system-prompt.d.mts.map +1 -0
- package/dist/agent-runners/system-prompt.mjs +34 -0
- package/dist/agent-runners/system-prompt.mjs.map +1 -0
- package/dist/agent-runners/team-modes/aggregates.cjs +36 -0
- package/dist/agent-runners/team-modes/aggregates.mjs +35 -0
- package/dist/agent-runners/team-modes/aggregates.mjs.map +1 -0
- package/dist/agent-runners/team-modes/iterate.cjs +46 -0
- package/dist/agent-runners/team-modes/iterate.mjs +47 -0
- package/dist/agent-runners/team-modes/iterate.mjs.map +1 -0
- package/dist/agent-runners/team-modes/parallel.cjs +59 -0
- package/dist/agent-runners/team-modes/parallel.mjs +60 -0
- package/dist/agent-runners/team-modes/parallel.mjs.map +1 -0
- package/dist/agent-runners/team-modes/reflection.cjs +155 -0
- package/dist/agent-runners/team-modes/reflection.mjs +156 -0
- package/dist/agent-runners/team-modes/reflection.mjs.map +1 -0
- package/dist/agent-runners/team-modes/sequential.cjs +63 -0
- package/dist/agent-runners/team-modes/sequential.mjs +64 -0
- package/dist/agent-runners/team-modes/sequential.mjs.map +1 -0
- package/dist/agent-runners/team-modes/utils.cjs +39 -0
- package/dist/agent-runners/team-modes/utils.mjs +36 -0
- package/dist/agent-runners/team-modes/utils.mjs.map +1 -0
- package/dist/agent-runners/team-runner.cjs +277 -0
- package/dist/agent-runners/team-runner.d.cts +34 -0
- package/dist/agent-runners/team-runner.d.cts.map +1 -0
- package/dist/agent-runners/team-runner.d.mts +34 -0
- package/dist/agent-runners/team-runner.d.mts.map +1 -0
- package/dist/agent-runners/team-runner.mjs +278 -0
- package/dist/agent-runners/team-runner.mjs.map +1 -0
- package/dist/agent-runners/template-context.cjs +32 -0
- package/dist/agent-runners/template-context.d.cts +43 -0
- package/dist/agent-runners/template-context.d.cts.map +1 -0
- package/dist/agent-runners/template-context.d.mts +43 -0
- package/dist/agent-runners/template-context.d.mts.map +1 -0
- package/dist/agent-runners/template-context.mjs +33 -0
- package/dist/agent-runners/template-context.mjs.map +1 -0
- package/dist/index.cjs +123 -0
- package/dist/index.d.cts +29 -0
- package/dist/index.d.mts +29 -0
- package/dist/index.mjs +29 -0
- package/dist/program/agent-action.cjs +496 -0
- package/dist/program/agent-action.d.cts +42 -0
- package/dist/program/agent-action.d.cts.map +1 -0
- package/dist/program/agent-action.d.mts +42 -0
- package/dist/program/agent-action.d.mts.map +1 -0
- package/dist/program/agent-action.mjs +497 -0
- package/dist/program/agent-action.mjs.map +1 -0
- package/dist/program/agent-messages-tools.cjs +137 -0
- package/dist/program/agent-messages-tools.d.cts +59 -0
- package/dist/program/agent-messages-tools.d.cts.map +1 -0
- package/dist/program/agent-messages-tools.d.mts +59 -0
- package/dist/program/agent-messages-tools.d.mts.map +1 -0
- package/dist/program/agent-messages-tools.mjs +130 -0
- package/dist/program/agent-messages-tools.mjs.map +1 -0
- package/dist/program/agent-runner-registry.cjs +314 -0
- package/dist/program/agent-runner-registry.d.cts +52 -0
- package/dist/program/agent-runner-registry.d.cts.map +1 -0
- package/dist/program/agent-runner-registry.d.mts +52 -0
- package/dist/program/agent-runner-registry.d.mts.map +1 -0
- package/dist/program/agent-runner-registry.mjs +313 -0
- package/dist/program/agent-runner-registry.mjs.map +1 -0
- package/dist/program/agent-subscribe.cjs +72 -0
- package/dist/program/agent-subscribe.d.cts +18 -0
- package/dist/program/agent-subscribe.d.cts.map +1 -0
- package/dist/program/agent-subscribe.d.mts +18 -0
- package/dist/program/agent-subscribe.d.mts.map +1 -0
- package/dist/program/agent-subscribe.mjs +73 -0
- package/dist/program/agent-subscribe.mjs.map +1 -0
- package/dist/program/agent-tools.cjs +135 -0
- package/dist/program/agent-tools.d.cts +35 -0
- package/dist/program/agent-tools.d.cts.map +1 -0
- package/dist/program/agent-tools.d.mts +35 -0
- package/dist/program/agent-tools.d.mts.map +1 -0
- package/dist/program/agent-tools.mjs +136 -0
- package/dist/program/agent-tools.mjs.map +1 -0
- package/dist/program/manifest-nesting.cjs +57 -0
- package/dist/program/manifest-nesting.d.cts +13 -0
- package/dist/program/manifest-nesting.d.cts.map +1 -0
- package/dist/program/manifest-nesting.d.mts +13 -0
- package/dist/program/manifest-nesting.d.mts.map +1 -0
- package/dist/program/manifest-nesting.mjs +57 -0
- package/dist/program/manifest-nesting.mjs.map +1 -0
- package/dist/program/result-contract.cjs +55 -0
- package/dist/program/result-contract.d.cts +23 -0
- package/dist/program/result-contract.d.cts.map +1 -0
- package/dist/program/result-contract.d.mts +23 -0
- package/dist/program/result-contract.d.mts.map +1 -0
- package/dist/program/result-contract.mjs +51 -0
- package/dist/program/result-contract.mjs.map +1 -0
- package/dist/program/runner-error.cjs +71 -0
- package/dist/program/runner-error.d.cts +25 -0
- package/dist/program/runner-error.d.cts.map +1 -0
- package/dist/program/runner-error.d.mts +25 -0
- package/dist/program/runner-error.d.mts.map +1 -0
- package/dist/program/runner-error.mjs +72 -0
- package/dist/program/runner-error.mjs.map +1 -0
- package/dist/program/scoped-afs.cjs +538 -0
- package/dist/program/scoped-afs.d.cts +245 -0
- package/dist/program/scoped-afs.d.cts.map +1 -0
- package/dist/program/scoped-afs.d.mts +245 -0
- package/dist/program/scoped-afs.d.mts.map +1 -0
- package/dist/program/scoped-afs.mjs +531 -0
- package/dist/program/scoped-afs.mjs.map +1 -0
- package/dist/program/session-hierarchy.cjs +1 -0
- package/dist/program/session-hierarchy.d.cts +2 -0
- package/dist/program/session-hierarchy.d.mts +2 -0
- package/dist/program/session-hierarchy.mjs +3 -0
- package/dist/program/tool-discovery/ash-frontmatter.cjs +83 -0
- package/dist/program/tool-discovery/ash-frontmatter.d.cts +21 -0
- package/dist/program/tool-discovery/ash-frontmatter.d.cts.map +1 -0
- package/dist/program/tool-discovery/ash-frontmatter.d.mts +21 -0
- package/dist/program/tool-discovery/ash-frontmatter.d.mts.map +1 -0
- package/dist/program/tool-discovery/ash-frontmatter.mjs +84 -0
- package/dist/program/tool-discovery/ash-frontmatter.mjs.map +1 -0
- package/dist/program/tool-discovery/dot-path-resolver.cjs +60 -0
- package/dist/program/tool-discovery/dot-path-resolver.mjs +61 -0
- package/dist/program/tool-discovery/dot-path-resolver.mjs.map +1 -0
- package/dist/program/tool-discovery/skill-gate.cjs +36 -0
- package/dist/program/tool-discovery/skill-gate.d.cts +10 -0
- package/dist/program/tool-discovery/skill-gate.d.cts.map +1 -0
- package/dist/program/tool-discovery/skill-gate.d.mts +10 -0
- package/dist/program/tool-discovery/skill-gate.d.mts.map +1 -0
- package/dist/program/tool-discovery/skill-gate.mjs +35 -0
- package/dist/program/tool-discovery/skill-gate.mjs.map +1 -0
- package/dist/providers/basic/ash/dist/index.cjs +1809 -0
- package/dist/providers/basic/ash/dist/index.mjs +1807 -0
- package/dist/providers/basic/ash/dist/index.mjs.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
let js_yaml = require("js-yaml");
|
|
2
|
+
|
|
3
|
+
//#region src/program/tool-discovery/ash-frontmatter.ts
|
|
4
|
+
/**
|
|
5
|
+
* ASH frontmatter parser (S13).
|
|
6
|
+
*
|
|
7
|
+
* Extracts tool schemas from `# ---` YAML blocks in .ash files.
|
|
8
|
+
* All file I/O goes through AFS (never `fs.readFile`).
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Parse the `# ---` YAML frontmatter from an .ash file.
|
|
12
|
+
* Returns ToolSchema on success, FrontmatterError on failure.
|
|
13
|
+
*/
|
|
14
|
+
async function parseFrontmatter(afs, filePath) {
|
|
15
|
+
let content;
|
|
16
|
+
try {
|
|
17
|
+
content = await afs.read(filePath);
|
|
18
|
+
} catch {
|
|
19
|
+
return {
|
|
20
|
+
error: `Failed to read file: ${filePath}`,
|
|
21
|
+
file: filePath
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (!content || !content.trim()) return {
|
|
25
|
+
error: "Empty file",
|
|
26
|
+
file: filePath
|
|
27
|
+
};
|
|
28
|
+
const yamlBlock = extractYamlBlock(content);
|
|
29
|
+
if (!yamlBlock) return {
|
|
30
|
+
error: "No valid frontmatter block found (missing # --- delimiters)",
|
|
31
|
+
file: filePath
|
|
32
|
+
};
|
|
33
|
+
let parsed;
|
|
34
|
+
try {
|
|
35
|
+
parsed = (0, js_yaml.load)(yamlBlock);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return {
|
|
38
|
+
error: `YAML parse error: ${e instanceof Error ? e.message : String(e)}`,
|
|
39
|
+
file: filePath
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (!parsed || typeof parsed !== "object") return {
|
|
43
|
+
error: "Frontmatter must be a YAML mapping",
|
|
44
|
+
file: filePath
|
|
45
|
+
};
|
|
46
|
+
const name = parsed.name;
|
|
47
|
+
if (!name || typeof name !== "string" || !name.trim()) return {
|
|
48
|
+
error: "Missing or empty 'name' field in frontmatter",
|
|
49
|
+
file: filePath
|
|
50
|
+
};
|
|
51
|
+
const description = typeof parsed.description === "string" ? parsed.description.trim() : "";
|
|
52
|
+
const input = typeof parsed.input === "object" && parsed.input !== null ? parsed.input : void 0;
|
|
53
|
+
const output = typeof parsed.output === "object" && parsed.output !== null ? parsed.output : void 0;
|
|
54
|
+
return {
|
|
55
|
+
name: name.trim(),
|
|
56
|
+
description,
|
|
57
|
+
filePath,
|
|
58
|
+
input,
|
|
59
|
+
output
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function extractYamlBlock(content) {
|
|
63
|
+
const lines = content.split("\n");
|
|
64
|
+
let startIdx = -1;
|
|
65
|
+
let endIdx = -1;
|
|
66
|
+
for (let i = 0; i < lines.length; i++) if (lines[i].trim() === "# ---") if (startIdx === -1) startIdx = i;
|
|
67
|
+
else {
|
|
68
|
+
endIdx = i;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (startIdx === -1 || endIdx === -1) return null;
|
|
72
|
+
const yamlLines = [];
|
|
73
|
+
for (let i = startIdx + 1; i < endIdx; i++) {
|
|
74
|
+
const line = lines[i];
|
|
75
|
+
if (line.startsWith("# ")) yamlLines.push(line.slice(2));
|
|
76
|
+
else if (line.startsWith("#")) yamlLines.push(line.slice(1));
|
|
77
|
+
else yamlLines.push(line);
|
|
78
|
+
}
|
|
79
|
+
return yamlLines.join("\n");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//#endregion
|
|
83
|
+
exports.parseFrontmatter = parseFrontmatter;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/program/tool-discovery/ash-frontmatter.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* ASH frontmatter parser (S13).
|
|
4
|
+
*
|
|
5
|
+
* Extracts tool schemas from `# ---` YAML blocks in .ash files.
|
|
6
|
+
* All file I/O goes through AFS (never `fs.readFile`).
|
|
7
|
+
*/
|
|
8
|
+
interface ToolSchema {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
filePath: string;
|
|
12
|
+
input?: Record<string, {
|
|
13
|
+
type?: string;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
description?: string;
|
|
16
|
+
}>;
|
|
17
|
+
output?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { ToolSchema };
|
|
21
|
+
//# sourceMappingURL=ash-frontmatter.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ash-frontmatter.d.cts","names":[],"sources":["../../../src/program/tool-discovery/ash-frontmatter.ts"],"mappings":";;AASA;;;;;UAAiB,UAAA;EACf,IAAA;EACA,WAAA;EACA,QAAA;EACA,KAAA,GAAQ,MAAA;IAAiB,IAAA;IAAe,QAAA;IAAoB,WAAA;EAAA;EAC5D,MAAA,GAAS,MAAA;AAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/program/tool-discovery/ash-frontmatter.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* ASH frontmatter parser (S13).
|
|
4
|
+
*
|
|
5
|
+
* Extracts tool schemas from `# ---` YAML blocks in .ash files.
|
|
6
|
+
* All file I/O goes through AFS (never `fs.readFile`).
|
|
7
|
+
*/
|
|
8
|
+
interface ToolSchema {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
filePath: string;
|
|
12
|
+
input?: Record<string, {
|
|
13
|
+
type?: string;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
description?: string;
|
|
16
|
+
}>;
|
|
17
|
+
output?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { ToolSchema };
|
|
21
|
+
//# sourceMappingURL=ash-frontmatter.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ash-frontmatter.d.mts","names":[],"sources":["../../../src/program/tool-discovery/ash-frontmatter.ts"],"mappings":";;AASA;;;;;UAAiB,UAAA;EACf,IAAA;EACA,WAAA;EACA,QAAA;EACA,KAAA,GAAQ,MAAA;IAAiB,IAAA;IAAe,QAAA;IAAoB,WAAA;EAAA;EAC5D,MAAA,GAAS,MAAA;AAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { load } from "js-yaml";
|
|
2
|
+
|
|
3
|
+
//#region src/program/tool-discovery/ash-frontmatter.ts
|
|
4
|
+
/**
|
|
5
|
+
* ASH frontmatter parser (S13).
|
|
6
|
+
*
|
|
7
|
+
* Extracts tool schemas from `# ---` YAML blocks in .ash files.
|
|
8
|
+
* All file I/O goes through AFS (never `fs.readFile`).
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Parse the `# ---` YAML frontmatter from an .ash file.
|
|
12
|
+
* Returns ToolSchema on success, FrontmatterError on failure.
|
|
13
|
+
*/
|
|
14
|
+
async function parseFrontmatter(afs, filePath) {
|
|
15
|
+
let content;
|
|
16
|
+
try {
|
|
17
|
+
content = await afs.read(filePath);
|
|
18
|
+
} catch {
|
|
19
|
+
return {
|
|
20
|
+
error: `Failed to read file: ${filePath}`,
|
|
21
|
+
file: filePath
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (!content || !content.trim()) return {
|
|
25
|
+
error: "Empty file",
|
|
26
|
+
file: filePath
|
|
27
|
+
};
|
|
28
|
+
const yamlBlock = extractYamlBlock(content);
|
|
29
|
+
if (!yamlBlock) return {
|
|
30
|
+
error: "No valid frontmatter block found (missing # --- delimiters)",
|
|
31
|
+
file: filePath
|
|
32
|
+
};
|
|
33
|
+
let parsed;
|
|
34
|
+
try {
|
|
35
|
+
parsed = load(yamlBlock);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return {
|
|
38
|
+
error: `YAML parse error: ${e instanceof Error ? e.message : String(e)}`,
|
|
39
|
+
file: filePath
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (!parsed || typeof parsed !== "object") return {
|
|
43
|
+
error: "Frontmatter must be a YAML mapping",
|
|
44
|
+
file: filePath
|
|
45
|
+
};
|
|
46
|
+
const name = parsed.name;
|
|
47
|
+
if (!name || typeof name !== "string" || !name.trim()) return {
|
|
48
|
+
error: "Missing or empty 'name' field in frontmatter",
|
|
49
|
+
file: filePath
|
|
50
|
+
};
|
|
51
|
+
const description = typeof parsed.description === "string" ? parsed.description.trim() : "";
|
|
52
|
+
const input = typeof parsed.input === "object" && parsed.input !== null ? parsed.input : void 0;
|
|
53
|
+
const output = typeof parsed.output === "object" && parsed.output !== null ? parsed.output : void 0;
|
|
54
|
+
return {
|
|
55
|
+
name: name.trim(),
|
|
56
|
+
description,
|
|
57
|
+
filePath,
|
|
58
|
+
input,
|
|
59
|
+
output
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function extractYamlBlock(content) {
|
|
63
|
+
const lines = content.split("\n");
|
|
64
|
+
let startIdx = -1;
|
|
65
|
+
let endIdx = -1;
|
|
66
|
+
for (let i = 0; i < lines.length; i++) if (lines[i].trim() === "# ---") if (startIdx === -1) startIdx = i;
|
|
67
|
+
else {
|
|
68
|
+
endIdx = i;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (startIdx === -1 || endIdx === -1) return null;
|
|
72
|
+
const yamlLines = [];
|
|
73
|
+
for (let i = startIdx + 1; i < endIdx; i++) {
|
|
74
|
+
const line = lines[i];
|
|
75
|
+
if (line.startsWith("# ")) yamlLines.push(line.slice(2));
|
|
76
|
+
else if (line.startsWith("#")) yamlLines.push(line.slice(1));
|
|
77
|
+
else yamlLines.push(line);
|
|
78
|
+
}
|
|
79
|
+
return yamlLines.join("\n");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//#endregion
|
|
83
|
+
export { parseFrontmatter };
|
|
84
|
+
//# sourceMappingURL=ash-frontmatter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ash-frontmatter.mjs","names":["parseYAML"],"sources":["../../../src/program/tool-discovery/ash-frontmatter.ts"],"sourcesContent":["/**\n * ASH frontmatter parser (S13).\n *\n * Extracts tool schemas from `# ---` YAML blocks in .ash files.\n * All file I/O goes through AFS (never `fs.readFile`).\n */\n\nimport { load as parseYAML } from \"js-yaml\";\n\nexport interface ToolSchema {\n name: string;\n description: string;\n filePath: string;\n input?: Record<string, { type?: string; required?: boolean; description?: string }>;\n output?: Record<string, unknown>;\n}\n\nexport interface FrontmatterError {\n error: string;\n file: string;\n}\n\ninterface AFSReader {\n read(path: string): Promise<string>;\n}\n\n/**\n * Parse the `# ---` YAML frontmatter from an .ash file.\n * Returns ToolSchema on success, FrontmatterError on failure.\n */\nexport async function parseFrontmatter(\n afs: AFSReader,\n filePath: string,\n): Promise<ToolSchema | FrontmatterError> {\n let content: string;\n try {\n content = await afs.read(filePath);\n } catch {\n return { error: `Failed to read file: ${filePath}`, file: filePath };\n }\n\n if (!content || !content.trim()) {\n return { error: \"Empty file\", file: filePath };\n }\n\n const yamlBlock = extractYamlBlock(content);\n if (!yamlBlock) {\n return { error: \"No valid frontmatter block found (missing # --- delimiters)\", file: filePath };\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = parseYAML(yamlBlock) as Record<string, unknown>;\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return { error: `YAML parse error: ${msg}`, file: filePath };\n }\n\n if (!parsed || typeof parsed !== \"object\") {\n return { error: \"Frontmatter must be a YAML mapping\", file: filePath };\n }\n\n const name = parsed.name;\n if (!name || typeof name !== \"string\" || !name.trim()) {\n return { error: \"Missing or empty 'name' field in frontmatter\", file: filePath };\n }\n\n const description = typeof parsed.description === \"string\" ? parsed.description.trim() : \"\";\n const input =\n typeof parsed.input === \"object\" && parsed.input !== null\n ? (parsed.input as Record<\n string,\n { type?: string; required?: boolean; description?: string }\n >)\n : undefined;\n const output =\n typeof parsed.output === \"object\" && parsed.output !== null\n ? (parsed.output as Record<string, unknown>)\n : undefined;\n\n return { name: name.trim(), description, filePath, input, output };\n}\n\nfunction extractYamlBlock(content: string): string | null {\n const lines = content.split(\"\\n\");\n\n let startIdx = -1;\n let endIdx = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i]!.trim();\n if (trimmed === \"# ---\") {\n if (startIdx === -1) {\n startIdx = i;\n } else {\n endIdx = i;\n break;\n }\n }\n }\n\n if (startIdx === -1 || endIdx === -1) return null;\n\n const yamlLines: string[] = [];\n for (let i = startIdx + 1; i < endIdx; i++) {\n const line = lines[i]!;\n // Strip leading \"# \" or \"#\" prefix\n if (line.startsWith(\"# \")) {\n yamlLines.push(line.slice(2));\n } else if (line.startsWith(\"#\")) {\n yamlLines.push(line.slice(1));\n } else {\n yamlLines.push(line);\n }\n }\n\n return yamlLines.join(\"\\n\");\n}\n"],"mappings":";;;;;;;;;;;;;AA8BA,eAAsB,iBACpB,KACA,UACwC;CACxC,IAAI;AACJ,KAAI;AACF,YAAU,MAAM,IAAI,KAAK,SAAS;SAC5B;AACN,SAAO;GAAE,OAAO,wBAAwB;GAAY,MAAM;GAAU;;AAGtE,KAAI,CAAC,WAAW,CAAC,QAAQ,MAAM,CAC7B,QAAO;EAAE,OAAO;EAAc,MAAM;EAAU;CAGhD,MAAM,YAAY,iBAAiB,QAAQ;AAC3C,KAAI,CAAC,UACH,QAAO;EAAE,OAAO;EAA+D,MAAM;EAAU;CAGjG,IAAI;AACJ,KAAI;AACF,WAASA,KAAU,UAAU;UACtB,GAAG;AAEV,SAAO;GAAE,OAAO,qBADJ,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;GACV,MAAM;GAAU;;AAG9D,KAAI,CAAC,UAAU,OAAO,WAAW,SAC/B,QAAO;EAAE,OAAO;EAAsC,MAAM;EAAU;CAGxE,MAAM,OAAO,OAAO;AACpB,KAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,CAAC,KAAK,MAAM,CACnD,QAAO;EAAE,OAAO;EAAgD,MAAM;EAAU;CAGlF,MAAM,cAAc,OAAO,OAAO,gBAAgB,WAAW,OAAO,YAAY,MAAM,GAAG;CACzF,MAAM,QACJ,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,OAChD,OAAO,QAIR;CACN,MAAM,SACJ,OAAO,OAAO,WAAW,YAAY,OAAO,WAAW,OAClD,OAAO,SACR;AAEN,QAAO;EAAE,MAAM,KAAK,MAAM;EAAE;EAAa;EAAU;EAAO;EAAQ;;AAGpE,SAAS,iBAAiB,SAAgC;CACxD,MAAM,QAAQ,QAAQ,MAAM,KAAK;CAEjC,IAAI,WAAW;CACf,IAAI,SAAS;AAEb,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,IAEhC,KADgB,MAAM,GAAI,MAAM,KAChB,QACd,KAAI,aAAa,GACf,YAAW;MACN;AACL,WAAS;AACT;;AAKN,KAAI,aAAa,MAAM,WAAW,GAAI,QAAO;CAE7C,MAAM,YAAsB,EAAE;AAC9B,MAAK,IAAI,IAAI,WAAW,GAAG,IAAI,QAAQ,KAAK;EAC1C,MAAM,OAAO,MAAM;AAEnB,MAAI,KAAK,WAAW,KAAK,CACvB,WAAU,KAAK,KAAK,MAAM,EAAE,CAAC;WACpB,KAAK,WAAW,IAAI,CAC7B,WAAU,KAAK,KAAK,MAAM,EAAE,CAAC;MAE7B,WAAU,KAAK,KAAK;;AAIxB,QAAO,UAAU,KAAK,KAAK"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
let ufo = require("ufo");
|
|
2
|
+
|
|
3
|
+
//#region src/program/tool-discovery/dot-path-resolver.ts
|
|
4
|
+
const DEFAULT_OPS = [
|
|
5
|
+
"read",
|
|
6
|
+
"list",
|
|
7
|
+
"search",
|
|
8
|
+
"query"
|
|
9
|
+
];
|
|
10
|
+
const DEFAULT_MAX_DEPTH = 5;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve bare dot-paths (e.g. `./knowledge/`, `./tools/`) to absolute
|
|
13
|
+
* blocklet-scoped whitelist entries.
|
|
14
|
+
*
|
|
15
|
+
* Directories (trailing `/` or `/**`) become glob patterns with maxDepth.
|
|
16
|
+
* File paths resolve to exact entries without maxDepth.
|
|
17
|
+
*/
|
|
18
|
+
function resolveDotPaths(paths, blockletRoot) {
|
|
19
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20
|
+
const result = [];
|
|
21
|
+
for (const raw of paths) {
|
|
22
|
+
if (!raw) continue;
|
|
23
|
+
if (raw.includes("\0")) throw new Error("TOOL_PATH_OUTSIDE_BLOCKLET: null bytes disallowed");
|
|
24
|
+
const normalized = normalizeDotPath(raw, blockletRoot);
|
|
25
|
+
if (seen.has(normalized.path)) continue;
|
|
26
|
+
seen.add(normalized.path);
|
|
27
|
+
result.push(normalized);
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
function normalizeDotPath(raw, blockletRoot) {
|
|
32
|
+
if (!raw.startsWith("./") && !raw.startsWith("../") && raw.startsWith("/")) throw new Error(`TOOL_PATH_OUTSIDE_BLOCKLET: absolute path '${raw}' outside blocklet root`);
|
|
33
|
+
const stripped = raw.replace(/\/?\*\*\/?$/, "").replace(/\/$/, "");
|
|
34
|
+
const isDir = raw.endsWith("/") || raw.endsWith("/**") || raw.endsWith("/**/");
|
|
35
|
+
const absolute = (0, ufo.joinURL)(blockletRoot, ...resolveSegments(stripped));
|
|
36
|
+
if (isDir) return {
|
|
37
|
+
path: `${absolute}/**`,
|
|
38
|
+
ops: DEFAULT_OPS,
|
|
39
|
+
maxDepth: DEFAULT_MAX_DEPTH
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
path: absolute,
|
|
43
|
+
ops: DEFAULT_OPS
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function resolveSegments(dotPath) {
|
|
47
|
+
const parts = dotPath.split("/").filter(Boolean);
|
|
48
|
+
const resolved = [];
|
|
49
|
+
for (const part of parts) {
|
|
50
|
+
if (part === ".") continue;
|
|
51
|
+
if (part === "..") {
|
|
52
|
+
if (resolved.length === 0) throw new Error(`TOOL_PATH_OUTSIDE_BLOCKLET: path '${dotPath}' escapes outside blocklet root`);
|
|
53
|
+
resolved.pop();
|
|
54
|
+
} else resolved.push(part);
|
|
55
|
+
}
|
|
56
|
+
return resolved;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
exports.resolveDotPaths = resolveDotPaths;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { joinURL } from "ufo";
|
|
2
|
+
|
|
3
|
+
//#region src/program/tool-discovery/dot-path-resolver.ts
|
|
4
|
+
const DEFAULT_OPS = [
|
|
5
|
+
"read",
|
|
6
|
+
"list",
|
|
7
|
+
"search",
|
|
8
|
+
"query"
|
|
9
|
+
];
|
|
10
|
+
const DEFAULT_MAX_DEPTH = 5;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve bare dot-paths (e.g. `./knowledge/`, `./tools/`) to absolute
|
|
13
|
+
* blocklet-scoped whitelist entries.
|
|
14
|
+
*
|
|
15
|
+
* Directories (trailing `/` or `/**`) become glob patterns with maxDepth.
|
|
16
|
+
* File paths resolve to exact entries without maxDepth.
|
|
17
|
+
*/
|
|
18
|
+
function resolveDotPaths(paths, blockletRoot) {
|
|
19
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20
|
+
const result = [];
|
|
21
|
+
for (const raw of paths) {
|
|
22
|
+
if (!raw) continue;
|
|
23
|
+
if (raw.includes("\0")) throw new Error("TOOL_PATH_OUTSIDE_BLOCKLET: null bytes disallowed");
|
|
24
|
+
const normalized = normalizeDotPath(raw, blockletRoot);
|
|
25
|
+
if (seen.has(normalized.path)) continue;
|
|
26
|
+
seen.add(normalized.path);
|
|
27
|
+
result.push(normalized);
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
function normalizeDotPath(raw, blockletRoot) {
|
|
32
|
+
if (!raw.startsWith("./") && !raw.startsWith("../") && raw.startsWith("/")) throw new Error(`TOOL_PATH_OUTSIDE_BLOCKLET: absolute path '${raw}' outside blocklet root`);
|
|
33
|
+
const stripped = raw.replace(/\/?\*\*\/?$/, "").replace(/\/$/, "");
|
|
34
|
+
const isDir = raw.endsWith("/") || raw.endsWith("/**") || raw.endsWith("/**/");
|
|
35
|
+
const absolute = joinURL(blockletRoot, ...resolveSegments(stripped));
|
|
36
|
+
if (isDir) return {
|
|
37
|
+
path: `${absolute}/**`,
|
|
38
|
+
ops: DEFAULT_OPS,
|
|
39
|
+
maxDepth: DEFAULT_MAX_DEPTH
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
path: absolute,
|
|
43
|
+
ops: DEFAULT_OPS
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function resolveSegments(dotPath) {
|
|
47
|
+
const parts = dotPath.split("/").filter(Boolean);
|
|
48
|
+
const resolved = [];
|
|
49
|
+
for (const part of parts) {
|
|
50
|
+
if (part === ".") continue;
|
|
51
|
+
if (part === "..") {
|
|
52
|
+
if (resolved.length === 0) throw new Error(`TOOL_PATH_OUTSIDE_BLOCKLET: path '${dotPath}' escapes outside blocklet root`);
|
|
53
|
+
resolved.pop();
|
|
54
|
+
} else resolved.push(part);
|
|
55
|
+
}
|
|
56
|
+
return resolved;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
export { resolveDotPaths };
|
|
61
|
+
//# sourceMappingURL=dot-path-resolver.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dot-path-resolver.mjs","names":[],"sources":["../../../src/program/tool-discovery/dot-path-resolver.ts"],"sourcesContent":["/**\n * Dot-protocol bare-path resolver (S13).\n *\n * Resolves relative paths from manifest `tools:` into absolute blocklet-scoped\n * ToolEntry[] for the path-validator whitelist. Pure function; no I/O.\n */\n\nimport type { ToolEntry } from \"@aigne/afs-ash\";\nimport { joinURL } from \"ufo\";\n\n// `query` pairs with `list` (read-class collection view, design §3.1b).\nconst DEFAULT_OPS: string[] = [\"read\", \"list\", \"search\", \"query\"];\nconst DEFAULT_MAX_DEPTH = 5;\n\n/**\n * Resolve bare dot-paths (e.g. `./knowledge/`, `./tools/`) to absolute\n * blocklet-scoped whitelist entries.\n *\n * Directories (trailing `/` or `/**`) become glob patterns with maxDepth.\n * File paths resolve to exact entries without maxDepth.\n */\nexport function resolveDotPaths(paths: string[], blockletRoot: string): ToolEntry[] {\n const seen = new Set<string>();\n const result: ToolEntry[] = [];\n\n for (const raw of paths) {\n if (!raw) continue;\n\n if (raw.includes(\"\\0\")) {\n throw new Error(\"TOOL_PATH_OUTSIDE_BLOCKLET: null bytes disallowed\");\n }\n\n const normalized = normalizeDotPath(raw, blockletRoot);\n if (seen.has(normalized.path)) continue;\n seen.add(normalized.path);\n result.push(normalized);\n }\n\n return result;\n}\n\nfunction normalizeDotPath(raw: string, blockletRoot: string): ToolEntry {\n if (!raw.startsWith(\"./\") && !raw.startsWith(\"../\") && raw.startsWith(\"/\")) {\n throw new Error(`TOOL_PATH_OUTSIDE_BLOCKLET: absolute path '${raw}' outside blocklet root`);\n }\n\n const stripped = raw.replace(/\\/?\\*\\*\\/?$/, \"\").replace(/\\/$/, \"\");\n const isDir = raw.endsWith(\"/\") || raw.endsWith(\"/**\") || raw.endsWith(\"/**/\");\n\n const cleanSegments = resolveSegments(stripped);\n const absolute = joinURL(blockletRoot, ...cleanSegments);\n\n if (isDir) {\n return {\n path: `${absolute}/**`,\n ops: DEFAULT_OPS,\n maxDepth: DEFAULT_MAX_DEPTH,\n };\n }\n\n return { path: absolute, ops: DEFAULT_OPS };\n}\n\nfunction resolveSegments(dotPath: string): string[] {\n const parts = dotPath.split(\"/\").filter(Boolean);\n const resolved: string[] = [];\n\n for (const part of parts) {\n if (part === \".\") continue;\n if (part === \"..\") {\n if (resolved.length === 0) {\n throw new Error(\n `TOOL_PATH_OUTSIDE_BLOCKLET: path '${dotPath}' escapes outside blocklet root`,\n );\n }\n resolved.pop();\n } else {\n resolved.push(part);\n }\n }\n\n return resolved;\n}\n"],"mappings":";;;AAWA,MAAM,cAAwB;CAAC;CAAQ;CAAQ;CAAU;CAAQ;AACjE,MAAM,oBAAoB;;;;;;;;AAS1B,SAAgB,gBAAgB,OAAiB,cAAmC;CAClF,MAAM,uBAAO,IAAI,KAAa;CAC9B,MAAM,SAAsB,EAAE;AAE9B,MAAK,MAAM,OAAO,OAAO;AACvB,MAAI,CAAC,IAAK;AAEV,MAAI,IAAI,SAAS,KAAK,CACpB,OAAM,IAAI,MAAM,oDAAoD;EAGtE,MAAM,aAAa,iBAAiB,KAAK,aAAa;AACtD,MAAI,KAAK,IAAI,WAAW,KAAK,CAAE;AAC/B,OAAK,IAAI,WAAW,KAAK;AACzB,SAAO,KAAK,WAAW;;AAGzB,QAAO;;AAGT,SAAS,iBAAiB,KAAa,cAAiC;AACtE,KAAI,CAAC,IAAI,WAAW,KAAK,IAAI,CAAC,IAAI,WAAW,MAAM,IAAI,IAAI,WAAW,IAAI,CACxE,OAAM,IAAI,MAAM,8CAA8C,IAAI,yBAAyB;CAG7F,MAAM,WAAW,IAAI,QAAQ,eAAe,GAAG,CAAC,QAAQ,OAAO,GAAG;CAClE,MAAM,QAAQ,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,MAAM,IAAI,IAAI,SAAS,OAAO;CAG9E,MAAM,WAAW,QAAQ,cAAc,GADjB,gBAAgB,SAAS,CACS;AAExD,KAAI,MACF,QAAO;EACL,MAAM,GAAG,SAAS;EAClB,KAAK;EACL,UAAU;EACX;AAGH,QAAO;EAAE,MAAM;EAAU,KAAK;EAAa;;AAG7C,SAAS,gBAAgB,SAA2B;CAClD,MAAM,QAAQ,QAAQ,MAAM,IAAI,CAAC,OAAO,QAAQ;CAChD,MAAM,WAAqB,EAAE;AAE7B,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,SAAS,IAAK;AAClB,MAAI,SAAS,MAAM;AACjB,OAAI,SAAS,WAAW,EACtB,OAAM,IAAI,MACR,qCAAqC,QAAQ,iCAC9C;AAEH,YAAS,KAAK;QAEd,UAAS,KAAK,KAAK;;AAIvB,QAAO"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/program/tool-discovery/skill-gate.ts
|
|
3
|
+
/**
|
|
4
|
+
* Return only the ToolSchemas whose gating skill is in the active set.
|
|
5
|
+
* Must be called on every tool call (not just catalog build) so mid-run
|
|
6
|
+
* skill removal disables helpers immediately.
|
|
7
|
+
*/
|
|
8
|
+
function filterByActiveSkills(helpers, activeSkills) {
|
|
9
|
+
return helpers.filter((h) => activeSkills.has(h.skill)).map((h) => h.schema);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Merge local tools with active skill helpers. When a skill helper has the
|
|
13
|
+
* same name as a local tool, the helper wins (shadow) and a warning is emitted.
|
|
14
|
+
*/
|
|
15
|
+
function mergeWithShadowing(tools, activeHelpers) {
|
|
16
|
+
const warnings = [];
|
|
17
|
+
const helperNames = new Set(activeHelpers.map((h) => h.name));
|
|
18
|
+
const merged = [];
|
|
19
|
+
for (const tool of tools) {
|
|
20
|
+
if (helperNames.has(tool.name)) {
|
|
21
|
+
const helper = activeHelpers.find((h) => h.name === tool.name);
|
|
22
|
+
warnings.push(`tool_shadow: "${tool.name}" from ${tool.filePath} shadowed by skill helper ${helper.filePath}`);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
merged.push(tool);
|
|
26
|
+
}
|
|
27
|
+
merged.push(...activeHelpers);
|
|
28
|
+
return {
|
|
29
|
+
merged,
|
|
30
|
+
warnings
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
exports.filterByActiveSkills = filterByActiveSkills;
|
|
36
|
+
exports.mergeWithShadowing = mergeWithShadowing;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ToolSchema } from "./ash-frontmatter.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/program/tool-discovery/skill-gate.d.ts
|
|
4
|
+
interface SkillHelper {
|
|
5
|
+
skill: string;
|
|
6
|
+
schema: ToolSchema;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { SkillHelper };
|
|
10
|
+
//# sourceMappingURL=skill-gate.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-gate.d.cts","names":[],"sources":["../../../src/program/tool-discovery/skill-gate.ts"],"mappings":";;;UASiB,WAAA;EACf,KAAA;EACA,MAAA,EAAQ,UAAA;AAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ToolSchema } from "./ash-frontmatter.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/program/tool-discovery/skill-gate.d.ts
|
|
4
|
+
interface SkillHelper {
|
|
5
|
+
skill: string;
|
|
6
|
+
schema: ToolSchema;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { SkillHelper };
|
|
10
|
+
//# sourceMappingURL=skill-gate.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-gate.d.mts","names":[],"sources":["../../../src/program/tool-discovery/skill-gate.ts"],"mappings":";;;UASiB,WAAA;EACf,KAAA;EACA,MAAA,EAAQ,UAAA;AAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/program/tool-discovery/skill-gate.ts
|
|
2
|
+
/**
|
|
3
|
+
* Return only the ToolSchemas whose gating skill is in the active set.
|
|
4
|
+
* Must be called on every tool call (not just catalog build) so mid-run
|
|
5
|
+
* skill removal disables helpers immediately.
|
|
6
|
+
*/
|
|
7
|
+
function filterByActiveSkills(helpers, activeSkills) {
|
|
8
|
+
return helpers.filter((h) => activeSkills.has(h.skill)).map((h) => h.schema);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Merge local tools with active skill helpers. When a skill helper has the
|
|
12
|
+
* same name as a local tool, the helper wins (shadow) and a warning is emitted.
|
|
13
|
+
*/
|
|
14
|
+
function mergeWithShadowing(tools, activeHelpers) {
|
|
15
|
+
const warnings = [];
|
|
16
|
+
const helperNames = new Set(activeHelpers.map((h) => h.name));
|
|
17
|
+
const merged = [];
|
|
18
|
+
for (const tool of tools) {
|
|
19
|
+
if (helperNames.has(tool.name)) {
|
|
20
|
+
const helper = activeHelpers.find((h) => h.name === tool.name);
|
|
21
|
+
warnings.push(`tool_shadow: "${tool.name}" from ${tool.filePath} shadowed by skill helper ${helper.filePath}`);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
merged.push(tool);
|
|
25
|
+
}
|
|
26
|
+
merged.push(...activeHelpers);
|
|
27
|
+
return {
|
|
28
|
+
merged,
|
|
29
|
+
warnings
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//#endregion
|
|
34
|
+
export { filterByActiveSkills, mergeWithShadowing };
|
|
35
|
+
//# sourceMappingURL=skill-gate.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-gate.mjs","names":[],"sources":["../../../src/program/tool-discovery/skill-gate.ts"],"sourcesContent":["/**\n * Skill-gated helper filter (S13).\n *\n * Runtime filter that intersects the full helper catalog with the active $skills set.\n * Pure function; no I/O.\n */\n\nimport type { ToolSchema } from \"./ash-frontmatter.js\";\n\nexport interface SkillHelper {\n skill: string;\n schema: ToolSchema;\n}\n\n/**\n * Return only the ToolSchemas whose gating skill is in the active set.\n * Must be called on every tool call (not just catalog build) so mid-run\n * skill removal disables helpers immediately.\n */\nexport function filterByActiveSkills(\n helpers: SkillHelper[],\n activeSkills: Set<string>,\n): ToolSchema[] {\n return helpers.filter((h) => activeSkills.has(h.skill)).map((h) => h.schema);\n}\n\n/**\n * Merge local tools with active skill helpers. When a skill helper has the\n * same name as a local tool, the helper wins (shadow) and a warning is emitted.\n */\nexport function mergeWithShadowing(\n tools: ToolSchema[],\n activeHelpers: ToolSchema[],\n): { merged: ToolSchema[]; warnings: string[] } {\n const warnings: string[] = [];\n const helperNames = new Set(activeHelpers.map((h) => h.name));\n const merged: ToolSchema[] = [];\n\n for (const tool of tools) {\n if (helperNames.has(tool.name)) {\n const helper = activeHelpers.find((h) => h.name === tool.name)!;\n warnings.push(\n `tool_shadow: \"${tool.name}\" from ${tool.filePath} shadowed by skill helper ${helper.filePath}`,\n );\n continue;\n }\n merged.push(tool);\n }\n\n merged.push(...activeHelpers);\n return { merged, warnings };\n}\n"],"mappings":";;;;;;AAmBA,SAAgB,qBACd,SACA,cACc;AACd,QAAO,QAAQ,QAAQ,MAAM,aAAa,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,MAAM,EAAE,OAAO;;;;;;AAO9E,SAAgB,mBACd,OACA,eAC8C;CAC9C,MAAM,WAAqB,EAAE;CAC7B,MAAM,cAAc,IAAI,IAAI,cAAc,KAAK,MAAM,EAAE,KAAK,CAAC;CAC7D,MAAM,SAAuB,EAAE;AAE/B,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,YAAY,IAAI,KAAK,KAAK,EAAE;GAC9B,MAAM,SAAS,cAAc,MAAM,MAAM,EAAE,SAAS,KAAK,KAAK;AAC9D,YAAS,KACP,iBAAiB,KAAK,KAAK,SAAS,KAAK,SAAS,4BAA4B,OAAO,WACtF;AACD;;AAEF,SAAO,KAAK,KAAK;;AAGnB,QAAO,KAAK,GAAG,cAAc;AAC7B,QAAO;EAAE;EAAQ;EAAU"}
|