melchizedek-agents 0.18.0 → 0.20.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/.env.example +12 -0
- package/CHANGELOG.md +1001 -0
- package/DOCUMENTATION.md +252 -65
- package/QUICKSTART.md +9 -6
- package/README.md +42 -4
- package/config/agents/examples/harness.yaml +3 -1
- package/config/agents/examples/model_zoo.yaml +10 -9
- package/config/agents/syndicateSchema.yaml +53 -16
- package/config/agents/templates/account_memory.yaml +2 -6
- package/config/agents/templates/case_desk.yaml +3 -9
- package/config/agents/templates/draft_review.yaml +3 -9
- package/config/agents/templates/intake_extractor.yaml +1 -3
- package/config/agents/templates/research_brief.yaml +3 -9
- package/config/agents/templates/research_desk.yaml +3 -9
- package/config/agents/templates/review_panel.yaml +4 -12
- package/config/agents/templates/support_triage.yaml +4 -12
- package/config/agents/templates/systems_operator.yaml +2 -6
- package/db/hardening.sql +7 -1
- package/db/migrations/0013_tool_credentials.sql +260 -0
- package/dist/lib/a2a/app.d.ts +70 -6
- package/dist/lib/a2a/app.js +107 -2
- package/dist/lib/a2a/executor.d.ts +20 -3
- package/dist/lib/a2a/executor.js +66 -7
- package/dist/lib/a2a/remoteAgent.d.ts +24 -9
- package/dist/lib/a2a/remoteAgent.js +31 -14
- package/dist/lib/adkPeer.d.ts +63 -0
- package/dist/lib/adkPeer.js +240 -0
- package/dist/lib/compile.d.ts +159 -30
- package/dist/lib/compile.js +215 -134
- package/dist/lib/compileAdk.d.ts +32 -0
- package/dist/lib/compileAdk.js +142 -0
- package/dist/lib/compileNative.d.ts +111 -0
- package/dist/lib/compileNative.js +278 -0
- package/dist/lib/config.d.ts +6 -5
- package/dist/lib/config.js +6 -5
- package/dist/lib/doctor.d.ts +28 -1
- package/dist/lib/doctor.js +64 -2
- package/dist/lib/index.d.ts +6 -1
- package/dist/lib/index.js +7 -1
- package/dist/lib/loadSyndicate.d.ts +18 -0
- package/dist/lib/memory/erase.d.ts +5 -3
- package/dist/lib/memory/erase.js +5 -2
- package/dist/lib/memory/namespace.d.ts +8 -1
- package/dist/lib/memory/namespace.js +12 -6
- package/dist/lib/memory/providers.js +2 -1
- package/dist/lib/memory/supabaseMemoryService.d.ts +37 -3
- package/dist/lib/memory/supabaseMemoryService.js +42 -2
- package/dist/lib/model.d.ts +47 -0
- package/dist/lib/model.js +37 -0
- package/dist/lib/models/adapterResolver.d.ts +115 -0
- package/dist/lib/models/adapterResolver.js +137 -0
- package/dist/lib/models/adkGeminiAdapter.d.ts +90 -0
- package/dist/lib/models/adkGeminiAdapter.js +369 -0
- package/dist/lib/models/adkShim.d.ts +111 -0
- package/dist/lib/models/adkShim.js +136 -0
- package/dist/lib/models/capabilities.d.ts +3 -0
- package/dist/lib/models/capabilities.js +33 -23
- package/dist/lib/models/chatCompletionsAdapter.d.ts +279 -0
- package/dist/lib/models/chatCompletionsAdapter.js +854 -0
- package/dist/lib/models/circuitBreaker.d.ts +42 -0
- package/dist/lib/models/circuitBreaker.js +70 -0
- package/dist/lib/models/claudeAdapter.d.ts +103 -0
- package/dist/lib/models/claudeAdapter.js +669 -0
- package/dist/lib/models/claudeLlm.d.ts +39 -62
- package/dist/lib/models/claudeLlm.js +45 -350
- package/dist/lib/models/claudeModels.d.ts +127 -0
- package/dist/lib/models/claudeModels.js +237 -0
- package/dist/lib/models/contract.d.ts +395 -0
- package/dist/lib/models/contract.js +39 -0
- package/dist/lib/models/endpoints.js +2 -1
- package/dist/lib/models/errorResponse.d.ts +50 -0
- package/dist/lib/models/errorResponse.js +48 -0
- package/dist/lib/models/fallback.d.ts +18 -11
- package/dist/lib/models/fallback.js +54 -43
- package/dist/lib/models/fallbackAdapter.d.ts +55 -0
- package/dist/lib/models/fallbackAdapter.js +62 -0
- package/dist/lib/models/gateway.js +2 -1
- package/dist/lib/models/gatewayAdapter.d.ts +51 -0
- package/dist/lib/models/gatewayAdapter.js +81 -0
- package/dist/lib/models/gatewayLlm.d.ts +12 -33
- package/dist/lib/models/gatewayLlm.js +16 -77
- package/dist/lib/models/geminiAdapter.d.ts +125 -0
- package/dist/lib/models/geminiAdapter.js +854 -0
- package/dist/lib/models/geminiState.d.ts +46 -0
- package/dist/lib/models/geminiState.js +51 -0
- package/dist/lib/models/genaiMapping.d.ts +283 -0
- package/dist/lib/models/genaiMapping.js +965 -0
- package/dist/lib/models/gptAdapter.d.ts +240 -0
- package/dist/lib/models/gptAdapter.js +804 -0
- package/dist/lib/models/gptLlm.d.ts +63 -123
- package/dist/lib/models/gptLlm.js +89 -603
- package/dist/lib/models/grokAdapter.d.ts +86 -0
- package/dist/lib/models/grokAdapter.js +142 -0
- package/dist/lib/models/grokLlm.d.ts +22 -45
- package/dist/lib/models/grokLlm.js +24 -69
- package/dist/lib/models/kimiAdapter.d.ts +157 -0
- package/dist/lib/models/kimiAdapter.js +203 -0
- package/dist/lib/models/kimiLlm.d.ts +15 -107
- package/dist/lib/models/kimiLlm.js +19 -155
- package/dist/lib/models/ollamaAdapter.d.ts +125 -0
- package/dist/lib/models/ollamaAdapter.js +155 -0
- package/dist/lib/models/ollamaLlm.d.ts +11 -107
- package/dist/lib/models/ollamaLlm.js +15 -153
- package/dist/lib/models/openAiCompatibleLlm.d.ts +73 -216
- package/dist/lib/models/openAiCompatibleLlm.js +109 -671
- package/dist/lib/models/providerState.d.ts +63 -0
- package/dist/lib/models/providerState.js +61 -0
- package/dist/lib/models/reasoning.d.ts +26 -0
- package/dist/lib/models/reasoning.js +59 -0
- package/dist/lib/models/registry.d.ts +62 -35
- package/dist/lib/models/registry.js +100 -124
- package/dist/lib/models/retry.d.ts +2 -1
- package/dist/lib/models/retry.js +3 -2
- package/dist/lib/models/schemaNormalize.d.ts +98 -0
- package/dist/lib/models/schemaNormalize.js +321 -1
- package/dist/lib/models/tracedGemini.d.ts +41 -0
- package/dist/lib/models/tracedGemini.js +98 -0
- package/dist/lib/models/urls.d.ts +11 -0
- package/dist/lib/models/urls.js +16 -0
- package/dist/lib/net/redirects.d.ts +21 -2
- package/dist/lib/net/redirects.js +11 -34
- package/dist/lib/observability/audit.d.ts +5 -1
- package/dist/lib/observability/lineage.d.ts +14 -0
- package/dist/lib/observability/lineage.js +33 -0
- package/dist/lib/observability/supabaseSpanExporter.d.ts +10 -4
- package/dist/lib/observability/supabaseSpanExporter.js +17 -9
- package/dist/lib/observability/tracer.d.ts +26 -8
- package/dist/lib/observability/tracer.js +43 -18
- package/dist/lib/runtime/adkMemoryBridge.d.ts +46 -0
- package/dist/lib/runtime/adkMemoryBridge.js +68 -0
- package/dist/lib/runtime/adkSessionBridge.d.ts +78 -0
- package/dist/lib/runtime/adkSessionBridge.js +176 -0
- package/dist/lib/runtime/approvals.d.ts +5 -0
- package/dist/lib/runtime/approvals.js +39 -8
- package/dist/lib/runtime/credentials.d.ts +61 -0
- package/dist/lib/runtime/credentials.js +67 -0
- package/dist/lib/runtime/events.d.ts +229 -0
- package/dist/lib/runtime/events.js +274 -0
- package/dist/lib/runtime/logging.d.ts +32 -0
- package/dist/lib/runtime/logging.js +55 -0
- package/dist/lib/runtime/memoryService.d.ts +72 -0
- package/dist/lib/runtime/memoryService.js +25 -0
- package/dist/lib/runtime/native/agentLoop.d.ts +209 -0
- package/dist/lib/runtime/native/agentLoop.js +705 -0
- package/dist/lib/runtime/native/compaction.d.ts +103 -0
- package/dist/lib/runtime/native/compaction.js +191 -0
- package/dist/lib/runtime/native/delegate.d.ts +151 -0
- package/dist/lib/runtime/native/delegate.js +256 -0
- package/dist/lib/runtime/native/history.d.ts +83 -0
- package/dist/lib/runtime/native/history.js +312 -0
- package/dist/lib/runtime/native/interrupts.d.ts +129 -0
- package/dist/lib/runtime/native/interrupts.js +310 -0
- package/dist/lib/runtime/native/request.d.ts +215 -0
- package/dist/lib/runtime/native/request.js +585 -0
- package/dist/lib/runtime/native/selfCorrection.d.ts +164 -0
- package/dist/lib/runtime/native/selfCorrection.js +327 -0
- package/dist/lib/runtime/native/step.d.ts +156 -0
- package/dist/lib/runtime/native/step.js +263 -0
- package/dist/lib/runtime/native/taskMode.d.ts +64 -0
- package/dist/lib/runtime/native/taskMode.js +126 -0
- package/dist/lib/runtime/native/telemetry.d.ts +75 -0
- package/dist/lib/runtime/native/telemetry.js +299 -0
- package/dist/lib/runtime/native/tempState.d.ts +31 -0
- package/dist/lib/runtime/native/tempState.js +56 -0
- package/dist/lib/runtime/nativeTurn.d.ts +86 -0
- package/dist/lib/runtime/nativeTurn.js +107 -0
- package/dist/lib/runtime/questions.d.ts +29 -7
- package/dist/lib/runtime/questions.js +47 -32
- package/dist/lib/runtime/runtimeFlag.d.ts +38 -0
- package/dist/lib/runtime/runtimeFlag.js +58 -0
- package/dist/lib/runtime/sessions.d.ts +166 -0
- package/dist/lib/runtime/sessions.js +201 -0
- package/dist/lib/runtime/syndicateTurn.d.ts +46 -5
- package/dist/lib/runtime/syndicateTurn.js +233 -36
- package/dist/lib/runtime/valueDepth.d.ts +23 -0
- package/dist/lib/runtime/valueDepth.js +41 -0
- package/dist/lib/session/supabaseSessionService.d.ts +65 -18
- package/dist/lib/session/supabaseSessionService.js +148 -105
- package/dist/lib/session/transcript.d.ts +69 -23
- package/dist/lib/session/transcript.js +105 -29
- package/dist/lib/skills.js +33 -7
- package/dist/lib/storage/postgres/credentialStore.d.ts +20 -0
- package/dist/lib/storage/postgres/credentialStore.js +82 -0
- package/dist/lib/storage/postgres/index.d.ts +12 -0
- package/dist/lib/storage/postgres/index.js +6 -1
- package/dist/lib/storage/postgres/sessionService.d.ts +44 -16
- package/dist/lib/storage/postgres/sessionService.js +128 -66
- package/dist/lib/syndicateSchema.d.ts +49 -0
- package/dist/lib/syndicateSchema.js +99 -9
- package/dist/lib/toolRegistry.d.ts +26 -2
- package/dist/lib/toolRegistry.js +73 -17
- package/dist/lib/tools/adkTool.d.ts +81 -0
- package/dist/lib/tools/adkTool.js +268 -0
- package/dist/lib/tools/auth.d.ts +118 -0
- package/dist/lib/tools/auth.js +89 -0
- package/dist/lib/tools/collectionsSearchTool.d.ts +8 -7
- package/dist/lib/tools/collectionsSearchTool.js +12 -27
- package/dist/lib/tools/credentialCipher.d.ts +58 -0
- package/dist/lib/tools/credentialCipher.js +116 -0
- package/dist/lib/tools/credentialStore.d.ts +77 -0
- package/dist/lib/tools/credentialStore.js +246 -0
- package/dist/lib/tools/examples.d.ts +43 -0
- package/dist/lib/tools/examples.js +62 -0
- package/dist/lib/tools/generateImageTool.d.ts +15 -6
- package/dist/lib/tools/generateImageTool.js +19 -29
- package/dist/lib/tools/inspectImageTool.d.ts +9 -6
- package/dist/lib/tools/inspectImageTool.js +13 -17
- package/dist/lib/tools/mcpToolFactory.d.ts +42 -1
- package/dist/lib/tools/mcpToolFactory.js +46 -47
- package/dist/lib/tools/memoryTools.d.ts +61 -0
- package/dist/lib/tools/memoryTools.js +119 -0
- package/dist/lib/tools/nativeTools.d.ts +38 -0
- package/dist/lib/tools/nativeTools.js +43 -0
- package/dist/lib/tools/oauthConsent.d.ts +181 -0
- package/dist/lib/tools/oauthConsent.js +330 -0
- package/dist/lib/tools/openapi/call.d.ts +108 -0
- package/dist/lib/tools/openapi/call.js +295 -0
- package/dist/lib/tools/openapi/parse.d.ts +147 -0
- package/dist/lib/tools/openapi/parse.js +570 -0
- package/dist/lib/tools/openapiTools.d.ts +25 -17
- package/dist/lib/tools/openapiTools.js +124 -121
- package/dist/lib/tools/scienceTools.d.ts +14 -14
- package/dist/lib/tools/skillToolset.d.ts +58 -87
- package/dist/lib/tools/skillToolset.js +61 -142
- package/dist/lib/tools/skills/env.d.ts +58 -0
- package/dist/lib/tools/skills/env.js +165 -0
- package/dist/lib/tools/skills/executor.d.ts +114 -0
- package/dist/lib/tools/skills/executor.js +331 -0
- package/dist/lib/tools/skills/frontmatter.d.ts +79 -0
- package/dist/lib/tools/skills/frontmatter.js +215 -0
- package/dist/lib/tools/skills/loader.d.ts +91 -0
- package/dist/lib/tools/skills/loader.js +257 -0
- package/dist/lib/tools/skills/tools.d.ts +187 -0
- package/dist/lib/tools/skills/tools.js +386 -0
- package/dist/lib/tools/taskTools.d.ts +15 -15
- package/dist/lib/tools/tool.d.ts +354 -0
- package/dist/lib/tools/tool.js +304 -0
- package/dist/lib/tools/toolContract.d.ts +89 -33
- package/dist/lib/tools/toolContract.js +104 -82
- package/dist/lib/tools/urlContextTool.d.ts +4 -1
- package/dist/lib/tools/urlContextTool.js +6 -2
- package/dist/lib/tools/webExtractTool.d.ts +3 -3
- package/dist/lib/tools/webExtractTool.js +2 -1
- package/dist/lib/tools/webSearchTool.d.ts +7 -10
- package/dist/lib/tools/webSearchTool.js +15 -60
- package/dist/lib/tools/wikiTools.d.ts +19 -19
- package/dist/lib/tools/wikiTools.js +13 -9
- package/dist/lib/tools/xApiSearchTool.d.ts +3 -3
- package/dist/lib/tools/xApiSearchTool.js +2 -1
- package/dist/lib/tools/xSearchTool.d.ts +8 -10
- package/dist/lib/tools/xSearchTool.js +12 -63
- package/dist/lib/tools/xaiSearchParams.d.ts +41 -0
- package/dist/lib/tools/xaiSearchParams.js +126 -0
- package/dist/lib/wiki/agentRun.d.ts +12 -0
- package/dist/lib/wiki/agentRun.js +74 -35
- package/dist/lib/wiki/entities.d.ts +12 -0
- package/dist/lib/wiki/entities.js +45 -3
- package/dist/lib/workflow/agentNode.d.ts +153 -0
- package/dist/lib/workflow/agentNode.js +365 -0
- package/dist/lib/workflow/graph.d.ts +178 -0
- package/dist/lib/workflow/graph.js +468 -0
- package/dist/lib/workflow/nodeEvents.d.ts +50 -0
- package/dist/lib/workflow/nodeEvents.js +101 -0
- package/dist/lib/workflow/pause.d.ts +122 -0
- package/dist/lib/workflow/pause.js +180 -0
- package/dist/lib/workflow/resume.d.ts +166 -0
- package/dist/lib/workflow/resume.js +441 -0
- package/dist/lib/workflow/route.d.ts +58 -0
- package/dist/lib/workflow/route.js +69 -0
- package/dist/lib/workflow/scheduler.d.ts +418 -0
- package/dist/lib/workflow/scheduler.js +756 -0
- package/dist/lib/workflow/toolNode.d.ts +127 -0
- package/dist/lib/workflow/toolNode.js +236 -0
- package/dist/lib/workflow/turn.d.ts +118 -0
- package/dist/lib/workflow/turn.js +216 -0
- package/dist/lib/workflow.d.ts +33 -11
- package/dist/lib/workflow.js +49 -27
- package/dist/lib/workflowConfig.d.ts +7 -2
- package/dist/lib/workflowConfig.js +7 -12
- package/dist/scripts/a2a_server.js +4 -3
- package/dist/scripts/assistant_worker.d.ts +2 -1
- package/dist/scripts/assistant_worker.js +9 -4
- package/dist/scripts/doctor.d.ts +3 -1
- package/dist/scripts/doctor.js +4 -2
- package/dist/scripts/syndicate_chat.js +19 -10
- package/package.json +9 -3
- package/skills/briefs/melchizedek-author.md +3 -2
- package/skills/briefs/melchizedek-models.md +13 -9
- package/skills/briefs/melchizedek.md +3 -3
- package/skills/melchizedek/SKILL.md +2 -1
- package/skills/melchizedek-author/SKILL.md +2 -1
- package/skills/melchizedek-author/assets/minimal.yaml +2 -0
- package/skills/melchizedek-models/SKILL.md +23 -6
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/tools/skills/loader.ts — a directory of skills, loaded by the engine
|
|
3
|
+
* (WS3-3, ADR 0083).
|
|
4
|
+
*
|
|
5
|
+
* WHY this file exists:
|
|
6
|
+
* The skills harness (lib/tools/skillToolset.ts, ADR 0029) loaded skills
|
|
7
|
+
* through ADK's `loadAllSkillsInDir` until WS3-3. This module walks the
|
|
8
|
+
* same layout to the same objects, so a skill reads the same on either
|
|
9
|
+
* runtime:
|
|
10
|
+
* - a skill is a directory, other than the base itself, holding a file
|
|
11
|
+
* named SKILL.md in any case; its name must equal the directory's;
|
|
12
|
+
* - a directory that is not a skill is searched for skills below it;
|
|
13
|
+
* - a skill's `references/`, `assets/` and `scripts/` are read whole,
|
|
14
|
+
* each file keyed by its path inside that directory: UTF-8 text as a
|
|
15
|
+
* string, anything else as a Buffer; a script is `{ src }` and only a
|
|
16
|
+
* text one is kept;
|
|
17
|
+
* - build and tool directories (node_modules, .git, __pycache__, …) and
|
|
18
|
+
* compiled files (.pyc, …) are skipped, as are symbolic links, which a
|
|
19
|
+
* directory listing never reports as a file or a directory;
|
|
20
|
+
* - an invalid skill is skipped (validateSkillDir says why).
|
|
21
|
+
*
|
|
22
|
+
* WHAT IS BOUNDED (none of these limits exists in ADK's loader):
|
|
23
|
+
* SKILL_LIMITS caps a SKILL.md's size, each resource file's size, the
|
|
24
|
+
* files one skill may ship, and how deep the walk goes. A resource over
|
|
25
|
+
* its limit is skipped and reported through `onWarning`; nothing larger is
|
|
26
|
+
* read into memory.
|
|
27
|
+
*
|
|
28
|
+
* The files are the operator's: the YAML's `skills.dir` names the shelf,
|
|
29
|
+
* and nothing a model sends reaches this module.
|
|
30
|
+
*/
|
|
31
|
+
import type { SkillFrontmatter } from './frontmatter.ts';
|
|
32
|
+
/** A file a skill ships: text as a string, binary as a Buffer. */
|
|
33
|
+
export type SkillFile = string | Buffer;
|
|
34
|
+
/** One skill, loaded: the shape load_skill and the tools read. */
|
|
35
|
+
export interface Skill {
|
|
36
|
+
frontmatter: SkillFrontmatter;
|
|
37
|
+
/** The SKILL.md body: the procedure. */
|
|
38
|
+
instructions: string;
|
|
39
|
+
resources: {
|
|
40
|
+
references: Record<string, SkillFile>;
|
|
41
|
+
assets: Record<string, SkillFile>;
|
|
42
|
+
scripts: Record<string, {
|
|
43
|
+
src: string;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** What the loader refuses to read. */
|
|
48
|
+
/**
|
|
49
|
+
* A file's bytes read through one open handle, so the size checked is the
|
|
50
|
+
* size of the file read (no check-then-read race): undefined when it holds
|
|
51
|
+
* more than `maxBytes`, or is not a regular file.
|
|
52
|
+
*/
|
|
53
|
+
export declare function readFileBounded(file: string, maxBytes: number): Promise<Buffer | undefined>;
|
|
54
|
+
export declare const SKILL_LIMITS: {
|
|
55
|
+
/** Bytes a SKILL.md may hold. */
|
|
56
|
+
readonly skillMdBytes: number;
|
|
57
|
+
/** Bytes one resource file may hold; a larger one is skipped. */
|
|
58
|
+
readonly resourceBytes: number;
|
|
59
|
+
/** Resource files one skill may ship; those past it are skipped. */
|
|
60
|
+
readonly resourceFiles: 1000;
|
|
61
|
+
/** Directory levels below the base (or below a resource directory) the walk descends. */
|
|
62
|
+
readonly depth: 12;
|
|
63
|
+
};
|
|
64
|
+
/** Directories never searched for skills or resources (ADK's list). */
|
|
65
|
+
export declare const IGNORED_DIRECTORIES: ReadonlySet<string>;
|
|
66
|
+
/** Files never read as resources (ADK's list). */
|
|
67
|
+
export declare const IGNORED_EXTENSIONS: ReadonlySet<string>;
|
|
68
|
+
/** Where the loader reports what it skipped for a limit. */
|
|
69
|
+
export interface LoadOptions {
|
|
70
|
+
onWarning?: (message: string) => void;
|
|
71
|
+
}
|
|
72
|
+
/** The SKILL.md in `skillDir`, checked; throws ADK's texts when it is missing or invalid. */
|
|
73
|
+
export declare function loadSkillFile(skillDir: string): Promise<{
|
|
74
|
+
frontmatter: SkillFrontmatter;
|
|
75
|
+
instructions: string;
|
|
76
|
+
}>;
|
|
77
|
+
/** One skill directory: its SKILL.md and the files it ships. */
|
|
78
|
+
export declare function loadSkillFromDir(skillDir: string, opts?: LoadOptions): Promise<Skill>;
|
|
79
|
+
/**
|
|
80
|
+
* Why `skillDir` is not a valid skill, or nothing: ADK's validateSkillDir.
|
|
81
|
+
* A SKILL.md that cannot be read or parsed is one problem; otherwise each
|
|
82
|
+
* frontmatter key the standard does not name, and a name that is not the
|
|
83
|
+
* directory's.
|
|
84
|
+
*/
|
|
85
|
+
export declare function validateSkillDir(skillDir: string): Promise<string[]>;
|
|
86
|
+
/**
|
|
87
|
+
* Every valid skill under `basePath`, by name, in the order the walk finds
|
|
88
|
+
* them (a later skill of the same name replaces an earlier one, as in ADK).
|
|
89
|
+
* A base that is not a readable directory yields none.
|
|
90
|
+
*/
|
|
91
|
+
export declare function loadAllSkillsInDir(basePath: string, opts?: LoadOptions): Promise<Record<string, Skill>>;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/tools/skills/loader.ts — a directory of skills, loaded by the engine
|
|
3
|
+
* (WS3-3, ADR 0083).
|
|
4
|
+
*
|
|
5
|
+
* WHY this file exists:
|
|
6
|
+
* The skills harness (lib/tools/skillToolset.ts, ADR 0029) loaded skills
|
|
7
|
+
* through ADK's `loadAllSkillsInDir` until WS3-3. This module walks the
|
|
8
|
+
* same layout to the same objects, so a skill reads the same on either
|
|
9
|
+
* runtime:
|
|
10
|
+
* - a skill is a directory, other than the base itself, holding a file
|
|
11
|
+
* named SKILL.md in any case; its name must equal the directory's;
|
|
12
|
+
* - a directory that is not a skill is searched for skills below it;
|
|
13
|
+
* - a skill's `references/`, `assets/` and `scripts/` are read whole,
|
|
14
|
+
* each file keyed by its path inside that directory: UTF-8 text as a
|
|
15
|
+
* string, anything else as a Buffer; a script is `{ src }` and only a
|
|
16
|
+
* text one is kept;
|
|
17
|
+
* - build and tool directories (node_modules, .git, __pycache__, …) and
|
|
18
|
+
* compiled files (.pyc, …) are skipped, as are symbolic links, which a
|
|
19
|
+
* directory listing never reports as a file or a directory;
|
|
20
|
+
* - an invalid skill is skipped (validateSkillDir says why).
|
|
21
|
+
*
|
|
22
|
+
* WHAT IS BOUNDED (none of these limits exists in ADK's loader):
|
|
23
|
+
* SKILL_LIMITS caps a SKILL.md's size, each resource file's size, the
|
|
24
|
+
* files one skill may ship, and how deep the walk goes. A resource over
|
|
25
|
+
* its limit is skipped and reported through `onWarning`; nothing larger is
|
|
26
|
+
* read into memory.
|
|
27
|
+
*
|
|
28
|
+
* The files are the operator's: the YAML's `skills.dir` names the shelf,
|
|
29
|
+
* and nothing a model sends reaches this module.
|
|
30
|
+
*/
|
|
31
|
+
import { isUtf8 } from 'node:buffer';
|
|
32
|
+
import { constants as fsConstants } from 'node:fs';
|
|
33
|
+
import * as fs from 'node:fs/promises';
|
|
34
|
+
import * as path from 'node:path';
|
|
35
|
+
import { ALLOWED_FRONTMATTER_KEYS, MAX_SKILL_MD_CHARS, parseSkillMdContent } from './frontmatter.js';
|
|
36
|
+
/** What the loader refuses to read. */
|
|
37
|
+
/**
|
|
38
|
+
* A file's bytes read through one open handle, so the size checked is the
|
|
39
|
+
* size of the file read (no check-then-read race): undefined when it holds
|
|
40
|
+
* more than `maxBytes`, or is not a regular file.
|
|
41
|
+
*/
|
|
42
|
+
export async function readFileBounded(file, maxBytes) {
|
|
43
|
+
const handle = await fs.open(file, fsConstants.O_RDONLY | (fsConstants.O_NOFOLLOW ?? 0));
|
|
44
|
+
try {
|
|
45
|
+
const stat = await handle.stat();
|
|
46
|
+
if (!stat.isFile() || stat.size > maxBytes)
|
|
47
|
+
return undefined;
|
|
48
|
+
const buffer = Buffer.alloc(maxBytes + 1);
|
|
49
|
+
let length = 0;
|
|
50
|
+
for (;;) {
|
|
51
|
+
const { bytesRead } = await handle.read(buffer, length, buffer.length - length, length);
|
|
52
|
+
if (bytesRead === 0)
|
|
53
|
+
break;
|
|
54
|
+
length += bytesRead;
|
|
55
|
+
if (length > maxBytes)
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return buffer.subarray(0, length);
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
await handle.close();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export const SKILL_LIMITS = {
|
|
65
|
+
/** Bytes a SKILL.md may hold. */
|
|
66
|
+
skillMdBytes: MAX_SKILL_MD_CHARS,
|
|
67
|
+
/** Bytes one resource file may hold; a larger one is skipped. */
|
|
68
|
+
resourceBytes: 8 * 1024 * 1024,
|
|
69
|
+
/** Resource files one skill may ship; those past it are skipped. */
|
|
70
|
+
resourceFiles: 1000,
|
|
71
|
+
/** Directory levels below the base (or below a resource directory) the walk descends. */
|
|
72
|
+
depth: 12,
|
|
73
|
+
};
|
|
74
|
+
/** Directories never searched for skills or resources (ADK's list). */
|
|
75
|
+
export const IGNORED_DIRECTORIES = new Set([
|
|
76
|
+
'__pycache__',
|
|
77
|
+
'.pytest_cache',
|
|
78
|
+
'.mypy_cache',
|
|
79
|
+
'.ruff_cache',
|
|
80
|
+
'node_modules',
|
|
81
|
+
'coverage',
|
|
82
|
+
'venv',
|
|
83
|
+
'.venv',
|
|
84
|
+
'env',
|
|
85
|
+
'.env',
|
|
86
|
+
'.git',
|
|
87
|
+
'.vscode',
|
|
88
|
+
'.idea',
|
|
89
|
+
]);
|
|
90
|
+
/** Files never read as resources (ADK's list). */
|
|
91
|
+
export const IGNORED_EXTENSIONS = new Set(['.pyc', '.pyo', '.pyd', '.tsbuildinfo', '.DS_Store']);
|
|
92
|
+
function decode(data) {
|
|
93
|
+
return isUtf8(data) ? data.toString('utf-8') : data;
|
|
94
|
+
}
|
|
95
|
+
/** Every file under `directoryPath`, keyed by its relative path, within the limits. Absent: none. */
|
|
96
|
+
async function loadDir(directoryPath, budget, opts) {
|
|
97
|
+
const files = {};
|
|
98
|
+
const walk = async (dir, depth) => {
|
|
99
|
+
if (depth > SKILL_LIMITS.depth) {
|
|
100
|
+
opts.onWarning?.(`skipped '${dir}': deeper than ${SKILL_LIMITS.depth} levels`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
104
|
+
for (const entry of entries) {
|
|
105
|
+
const fullPath = path.join(dir, entry.name);
|
|
106
|
+
if (entry.isDirectory()) {
|
|
107
|
+
if (IGNORED_DIRECTORIES.has(entry.name))
|
|
108
|
+
continue;
|
|
109
|
+
await walk(fullPath, depth + 1);
|
|
110
|
+
}
|
|
111
|
+
else if (entry.isFile()) {
|
|
112
|
+
if (IGNORED_EXTENSIONS.has(path.extname(entry.name)))
|
|
113
|
+
continue;
|
|
114
|
+
const relativePath = path.relative(directoryPath, fullPath);
|
|
115
|
+
if (budget.files <= 0) {
|
|
116
|
+
opts.onWarning?.(`skipped '${fullPath}': a skill ships at most ${SKILL_LIMITS.resourceFiles} files`);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const bytes = await readFileBounded(fullPath, SKILL_LIMITS.resourceBytes);
|
|
120
|
+
if (!bytes) {
|
|
121
|
+
opts.onWarning?.(`skipped '${fullPath}': larger than ${SKILL_LIMITS.resourceBytes} bytes`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
budget.files -= 1;
|
|
125
|
+
Object.defineProperty(files, relativePath, { value: decode(bytes), enumerable: true, writable: true, configurable: true });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
let isDir = false;
|
|
130
|
+
try {
|
|
131
|
+
isDir = (await fs.stat(directoryPath)).isDirectory();
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return files; // no such directory: the skill ships none of this kind
|
|
135
|
+
}
|
|
136
|
+
if (isDir) {
|
|
137
|
+
try {
|
|
138
|
+
await walk(directoryPath, 0);
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
opts.onWarning?.(`failed to load directory '${directoryPath}': ${e.message}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return files;
|
|
145
|
+
}
|
|
146
|
+
/** The SKILL.md in `skillDir`, checked; throws ADK's texts when it is missing or invalid. */
|
|
147
|
+
export async function loadSkillFile(skillDir) {
|
|
148
|
+
const resolvedDir = path.resolve(skillDir);
|
|
149
|
+
let content;
|
|
150
|
+
let entries = [];
|
|
151
|
+
try {
|
|
152
|
+
entries = await fs.readdir(resolvedDir, { withFileTypes: true });
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
entries = [];
|
|
156
|
+
}
|
|
157
|
+
for (const entry of entries) {
|
|
158
|
+
if (!entry.isFile() || entry.name.toLowerCase() !== 'skill.md')
|
|
159
|
+
continue;
|
|
160
|
+
const file = path.join(resolvedDir, entry.name);
|
|
161
|
+
try {
|
|
162
|
+
const bytes = await readFileBounded(file, SKILL_LIMITS.skillMdBytes);
|
|
163
|
+
if (!bytes)
|
|
164
|
+
throw new Error(`SKILL.md is larger than ${SKILL_LIMITS.skillMdBytes} bytes`);
|
|
165
|
+
content = bytes.toString('utf-8');
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
if (e.message.startsWith('SKILL.md is larger'))
|
|
170
|
+
throw e;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (content === undefined)
|
|
174
|
+
throw new Error(`SKILL.md (or any case variation like skill.md) not found in '${skillDir}'.`);
|
|
175
|
+
const { frontmatter, body } = parseSkillMdContent(content);
|
|
176
|
+
const dirName = path.basename(resolvedDir);
|
|
177
|
+
if (dirName !== frontmatter.name)
|
|
178
|
+
throw new Error(`Skill name '${frontmatter.name}' does not match directory name '${dirName}'.`);
|
|
179
|
+
return { frontmatter, instructions: body };
|
|
180
|
+
}
|
|
181
|
+
/** One skill directory: its SKILL.md and the files it ships. */
|
|
182
|
+
export async function loadSkillFromDir(skillDir, opts = {}) {
|
|
183
|
+
const resolvedDir = path.resolve(skillDir);
|
|
184
|
+
const skill = await loadSkillFile(skillDir);
|
|
185
|
+
const budget = { files: SKILL_LIMITS.resourceFiles };
|
|
186
|
+
const references = await loadDir(path.join(resolvedDir, 'references'), budget, opts);
|
|
187
|
+
const assets = await loadDir(path.join(resolvedDir, 'assets'), budget, opts);
|
|
188
|
+
const rawScripts = await loadDir(path.join(resolvedDir, 'scripts'), budget, opts);
|
|
189
|
+
const scripts = {};
|
|
190
|
+
for (const [name, src] of Object.entries(rawScripts)) {
|
|
191
|
+
if (typeof src === 'string')
|
|
192
|
+
Object.defineProperty(scripts, name, { value: { src }, enumerable: true, writable: true, configurable: true });
|
|
193
|
+
}
|
|
194
|
+
return { ...skill, resources: { references, assets, scripts } };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Why `skillDir` is not a valid skill, or nothing: ADK's validateSkillDir.
|
|
198
|
+
* A SKILL.md that cannot be read or parsed is one problem; otherwise each
|
|
199
|
+
* frontmatter key the standard does not name, and a name that is not the
|
|
200
|
+
* directory's.
|
|
201
|
+
*/
|
|
202
|
+
export async function validateSkillDir(skillDir) {
|
|
203
|
+
const resolvedDir = path.resolve(skillDir);
|
|
204
|
+
let skill;
|
|
205
|
+
try {
|
|
206
|
+
skill = await loadSkillFile(resolvedDir);
|
|
207
|
+
}
|
|
208
|
+
catch (e) {
|
|
209
|
+
return [e.message];
|
|
210
|
+
}
|
|
211
|
+
const problems = [];
|
|
212
|
+
const unknown = Object.keys(skill.frontmatter).filter((k) => !ALLOWED_FRONTMATTER_KEYS.has(k));
|
|
213
|
+
if (unknown.length > 0)
|
|
214
|
+
problems.push(`Unknown frontmatter fields: [${unknown.sort().join(', ')}]`);
|
|
215
|
+
const dirName = path.basename(resolvedDir);
|
|
216
|
+
if (dirName !== skill.frontmatter.name)
|
|
217
|
+
problems.push(`Skill name '${skill.frontmatter.name}' does not match directory name '${dirName}'.`);
|
|
218
|
+
return problems;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Every valid skill under `basePath`, by name, in the order the walk finds
|
|
222
|
+
* them (a later skill of the same name replaces an earlier one, as in ADK).
|
|
223
|
+
* A base that is not a readable directory yields none.
|
|
224
|
+
*/
|
|
225
|
+
export async function loadAllSkillsInDir(basePath, opts = {}) {
|
|
226
|
+
const resolvedPath = path.resolve(basePath);
|
|
227
|
+
const skills = {};
|
|
228
|
+
const scan = async (currentDir, depth) => {
|
|
229
|
+
if (depth > SKILL_LIMITS.depth)
|
|
230
|
+
return;
|
|
231
|
+
let entries;
|
|
232
|
+
try {
|
|
233
|
+
entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const isSkillDir = currentDir !== resolvedPath && entries.some((e) => e.isFile() && e.name.toLowerCase() === 'skill.md');
|
|
239
|
+
if (isSkillDir) {
|
|
240
|
+
try {
|
|
241
|
+
const skill = await loadSkillFromDir(currentDir, opts);
|
|
242
|
+
Object.defineProperty(skills, skill.frontmatter.name, { value: skill, enumerable: true, writable: true, configurable: true });
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// Skipped: validateSkillDir (skillSuiteProblems) reports why.
|
|
246
|
+
}
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
for (const entry of entries) {
|
|
250
|
+
if (!entry.isDirectory() || IGNORED_DIRECTORIES.has(entry.name))
|
|
251
|
+
continue;
|
|
252
|
+
await scan(path.join(currentDir, entry.name), depth + 1);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
await scan(resolvedPath, 0);
|
|
256
|
+
return skills;
|
|
257
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/tools/skills/tools.ts — the skill tools and the toolset that holds
|
|
3
|
+
* them, on the engine's own tool base (lib/tools/tool.ts; WS3-3, ADR 0083).
|
|
4
|
+
*
|
|
5
|
+
* WHY this file exists:
|
|
6
|
+
* The skills harness (ADR 0029) was built on ADK's SkillToolset until
|
|
7
|
+
* WS3-3. These are the same tools as own Tools, so the native loop runs
|
|
8
|
+
* them directly and the ADK runtime runs them through the one tool
|
|
9
|
+
* adapter (lib/tools/adkTool.ts, toAdkToolset). A model is sent the same
|
|
10
|
+
* names, descriptions and parameters as before, and reads the same
|
|
11
|
+
* results and error texts, on either runtime:
|
|
12
|
+
* - list_skills: the `<available_skills>` index (ADK's ListSkillsTool).
|
|
13
|
+
* The harness leaves it out, since the index is in the instruction.
|
|
14
|
+
* - load_skill: the procedure, the frontmatter and the NAMES of the files
|
|
15
|
+
* the skill ships (ADR 0029's lean load), and it activates the skill.
|
|
16
|
+
* - load_skill_resource: one of those files (ADK's tool, word for word).
|
|
17
|
+
* A binary file is shown to the model as inline data in the next
|
|
18
|
+
* request, through the Tool's `contents` hook, as ADK's tool did in its
|
|
19
|
+
* processLlmRequest.
|
|
20
|
+
* - run_skill_script: asks a person to approve, then runs one script the
|
|
21
|
+
* skill ships on the local executor (./executor.ts).
|
|
22
|
+
*
|
|
23
|
+
* ACTIVATION: load_skill appends the skill's name to the session state key
|
|
24
|
+
* `_adk_activated_skill_<agent>` (ADK's key, so a session stored by
|
|
25
|
+
* either runtime reads the same). SkillToolset.getTools reads it and adds
|
|
26
|
+
* the tools the activated skills name (`metadata.adk_additional_tools`,
|
|
27
|
+
* filled from `allowed-tools`), but only from the tools the YAML handed
|
|
28
|
+
* it under `skills.tools`: a skill cannot grant itself a tool the YAML
|
|
29
|
+
* withheld.
|
|
30
|
+
*
|
|
31
|
+
* WHY NOT defineTool: a defineTool contract validates its arguments with
|
|
32
|
+
* zod and answers a bad call with its own error string. These tools keep
|
|
33
|
+
* ADK's answers to a bad call (`{ error, error_code }`), so their
|
|
34
|
+
* parameters are written here as JSON Schema and their arguments checked
|
|
35
|
+
* in execute.
|
|
36
|
+
*
|
|
37
|
+
* UNTRUSTED INPUT: every argument is the model's. A skill name and a file
|
|
38
|
+
* path are looked up as own keys of the loaded maps (never on a
|
|
39
|
+
* prototype), so nothing a model sends opens a file the skill did not
|
|
40
|
+
* ship or names a script outside its `scripts/`.
|
|
41
|
+
*/
|
|
42
|
+
import type { ToolDeclaration } from '../../models/contract.ts';
|
|
43
|
+
import type { TurnContent } from '../../runtime/events.ts';
|
|
44
|
+
import type { Tool, ToolContext, Toolset, ToolsetContext } from '../tool.ts';
|
|
45
|
+
import { LocalScriptExecutor } from './executor.ts';
|
|
46
|
+
import type { Skill } from './loader.ts';
|
|
47
|
+
/** The `<available_skills>` index, in the skills' order (ADK's formatSkillsAsXml). */
|
|
48
|
+
export declare function formatSkillsAsXml(skills: Skill[]): string;
|
|
49
|
+
/** The session state key holding the skills an agent has loaded (ADK's). */
|
|
50
|
+
export declare function activatedSkillsKey(agentName: string | undefined): string;
|
|
51
|
+
/** Seconds a skill script may run before the local executor kills it. */
|
|
52
|
+
export declare const SCRIPT_TIMEOUT_SECONDS = 120;
|
|
53
|
+
export interface SkillToolsetOptions {
|
|
54
|
+
/** `local` runs a skill's scripts on this machine, each after approval; otherwise run_skill_script is absent. */
|
|
55
|
+
scripts?: 'none' | 'local';
|
|
56
|
+
/** The tools a loaded skill may unlock by name (the YAML's `skills.tools`, resolved). */
|
|
57
|
+
additionalTools?: readonly unknown[];
|
|
58
|
+
/** Variable names a script gets beyond the base allowlist (the YAML's `skills.env` and `skills.secret_env`; ADR 0086). */
|
|
59
|
+
envNames?: readonly string[];
|
|
60
|
+
/** The executor for `scripts: local`. Default: the local executor with SCRIPT_TIMEOUT_SECONDS and `envNames`. */
|
|
61
|
+
executor?: LocalScriptExecutor;
|
|
62
|
+
/** Where script output files are copied. Default: a private temp directory, made once. */
|
|
63
|
+
scriptOutputDir?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The tools an agent with `skills:` carries: load_skill and
|
|
67
|
+
* load_skill_resource always, run_skill_script with `scripts: local`, and
|
|
68
|
+
* the tools its loaded skills unlock. A toolset by shape (getTools), which
|
|
69
|
+
* the native loop expands and lib/tools/adkTool.ts wraps for ADK.
|
|
70
|
+
*/
|
|
71
|
+
export declare class SkillToolset implements Toolset {
|
|
72
|
+
#private;
|
|
73
|
+
readonly name = "skill_toolset";
|
|
74
|
+
readonly skills: Readonly<Record<string, Skill>>;
|
|
75
|
+
readonly executor?: LocalScriptExecutor;
|
|
76
|
+
constructor(skills: Record<string, Skill>, options?: SkillToolsetOptions);
|
|
77
|
+
/** The skill named `name`, or undefined. Only the toolset's own skills, never a prototype key. */
|
|
78
|
+
getSkill(name: string): Skill | undefined;
|
|
79
|
+
/** The harness tools, then the tools the agent's loaded skills unlock. */
|
|
80
|
+
getTools(context?: ToolsetContext): Promise<unknown[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Where a script's output files are copied: the configured directory, or
|
|
83
|
+
* a private temp directory made once per toolset. Output file names are
|
|
84
|
+
* the script's choice, so they are never resolved against the server's
|
|
85
|
+
* working directory.
|
|
86
|
+
*/
|
|
87
|
+
scriptOutputDir(): Promise<string>;
|
|
88
|
+
}
|
|
89
|
+
declare abstract class SkillTool implements Tool {
|
|
90
|
+
abstract readonly name: string;
|
|
91
|
+
abstract readonly description: string;
|
|
92
|
+
protected abstract readonly parameters: Record<string, unknown>;
|
|
93
|
+
protected readonly toolset: SkillToolset;
|
|
94
|
+
constructor(toolset: SkillToolset);
|
|
95
|
+
declaration(): ToolDeclaration;
|
|
96
|
+
abstract execute(args: Record<string, unknown>, ctx: ToolContext): Promise<unknown>;
|
|
97
|
+
}
|
|
98
|
+
/** list_skills: the index of every installed skill. The harness does not carry it (ADR 0029). */
|
|
99
|
+
export declare class ListSkillsTool extends SkillTool {
|
|
100
|
+
readonly name = "list_skills";
|
|
101
|
+
readonly description = "Lists all available skills with their names and descriptions.";
|
|
102
|
+
protected readonly parameters: {
|
|
103
|
+
type: string;
|
|
104
|
+
properties: {};
|
|
105
|
+
};
|
|
106
|
+
execute(): Promise<unknown>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* load_skill, lean (ADR 0029): the procedure, the frontmatter and the names
|
|
110
|
+
* of the files the skill ships, never their contents. Loading activates the
|
|
111
|
+
* skill, which unlocks its permitted `allowed-tools` on the next request.
|
|
112
|
+
*/
|
|
113
|
+
export declare class LoadSkillTool extends SkillTool {
|
|
114
|
+
readonly name = "load_skill";
|
|
115
|
+
readonly description = "Read one installed skill in full: its SKILL.md procedure, its frontmatter, and the names of the files it ships. Read a skill before you follow it.";
|
|
116
|
+
protected readonly parameters: {
|
|
117
|
+
type: string;
|
|
118
|
+
properties: {
|
|
119
|
+
name: {
|
|
120
|
+
type: string;
|
|
121
|
+
description: string;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
required: string[];
|
|
125
|
+
};
|
|
126
|
+
execute(args: Record<string, unknown>, ctx: ToolContext): Promise<unknown>;
|
|
127
|
+
}
|
|
128
|
+
/** load_skill_resource: one file a skill ships, by its path (ADK's tool). */
|
|
129
|
+
export declare class LoadSkillResourceTool extends SkillTool {
|
|
130
|
+
readonly name = "load_skill_resource";
|
|
131
|
+
readonly description = "Loads a resource file (from references/, assets/, or scripts/) from within a skill.";
|
|
132
|
+
protected readonly parameters: {
|
|
133
|
+
type: string;
|
|
134
|
+
properties: {
|
|
135
|
+
skill_name: {
|
|
136
|
+
type: string;
|
|
137
|
+
description: string;
|
|
138
|
+
};
|
|
139
|
+
path: {
|
|
140
|
+
type: string;
|
|
141
|
+
description: string;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
required: string[];
|
|
145
|
+
};
|
|
146
|
+
execute(args: Record<string, unknown>): Promise<unknown>;
|
|
147
|
+
/**
|
|
148
|
+
* A binary file this tool just answered for is added to the request as
|
|
149
|
+
* inline data, after the history (ADK's processLlmRequest): the latest
|
|
150
|
+
* content, when it is the tools' answer, is searched for this tool's
|
|
151
|
+
* binary notices.
|
|
152
|
+
*/
|
|
153
|
+
contents(contents: TurnContent[]): Promise<void>;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* run_skill_script behind a person's approval: the first call asks for it
|
|
157
|
+
* (the hint names the skill, the script and the arguments) and returns
|
|
158
|
+
* without running; the call made again with the answer runs only when the
|
|
159
|
+
* answer approved it. The confirmation travels as `adk_request_confirmation`
|
|
160
|
+
* on either runtime, so the turn pauses `input-required` exactly as for
|
|
161
|
+
* `require_approval` (ADR 0028), with this tool's own texts.
|
|
162
|
+
*/
|
|
163
|
+
export declare class RunSkillScriptTool extends SkillTool {
|
|
164
|
+
#private;
|
|
165
|
+
readonly name = "run_skill_script";
|
|
166
|
+
readonly description = "Executes a script from a skill's scripts/ directory.";
|
|
167
|
+
protected readonly parameters: {
|
|
168
|
+
type: string;
|
|
169
|
+
properties: {
|
|
170
|
+
skill_name: {
|
|
171
|
+
type: string;
|
|
172
|
+
description: string;
|
|
173
|
+
};
|
|
174
|
+
script_path: {
|
|
175
|
+
type: string;
|
|
176
|
+
description: string;
|
|
177
|
+
};
|
|
178
|
+
args: {
|
|
179
|
+
type: string;
|
|
180
|
+
description: string;
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
required: string[];
|
|
184
|
+
};
|
|
185
|
+
execute(args: Record<string, unknown>, ctx: ToolContext): Promise<unknown>;
|
|
186
|
+
}
|
|
187
|
+
export {};
|