agentfootprint 7.12.0 → 7.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/Agent.js +39 -5
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +59 -1
- package/dist/core/agent/AgentBuilder.js.map +1 -1
- package/dist/core/agent/buildAgentChart.js +6 -0
- package/dist/core/agent/buildAgentChart.js.map +1 -1
- package/dist/core/agent/buildDynamicAgentChart.js +14 -0
- package/dist/core/agent/buildDynamicAgentChart.js.map +1 -1
- package/dist/core/agent/stages/callLLM.js +10 -4
- package/dist/core/agent/stages/callLLM.js.map +1 -1
- package/dist/core/agent/stages/seed.js +16 -0
- package/dist/core/agent/stages/seed.js.map +1 -1
- package/dist/core/slots/buildSystemPromptSlot.js +2 -1
- package/dist/core/slots/buildSystemPromptSlot.js.map +1 -1
- package/dist/esm/core/Agent.d.ts +7 -3
- package/dist/esm/core/Agent.js +39 -5
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.d.ts +48 -1
- package/dist/esm/core/agent/AgentBuilder.js +59 -1
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/buildAgentChart.js +6 -0
- package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
- package/dist/esm/core/agent/buildDynamicAgentChart.js +14 -0
- package/dist/esm/core/agent/buildDynamicAgentChart.js.map +1 -1
- package/dist/esm/core/agent/stages/callLLM.d.ts +9 -0
- package/dist/esm/core/agent/stages/callLLM.js +10 -4
- package/dist/esm/core/agent/stages/callLLM.js.map +1 -1
- package/dist/esm/core/agent/stages/seed.d.ts +10 -1
- package/dist/esm/core/agent/stages/seed.js +16 -0
- package/dist/esm/core/agent/stages/seed.js.map +1 -1
- package/dist/esm/core/agent/types.d.ts +44 -0
- package/dist/esm/core/slots/buildSystemPromptSlot.d.ts +19 -4
- package/dist/esm/core/slots/buildSystemPromptSlot.js +2 -1
- package/dist/esm/core/slots/buildSystemPromptSlot.js.map +1 -1
- package/dist/esm/lib/injection-engine/index.d.ts +1 -0
- package/dist/esm/lib/injection-engine/index.js +4 -0
- package/dist/esm/lib/injection-engine/index.js.map +1 -1
- package/dist/esm/lib/injection-engine/skillsFromDir.d.ts +80 -0
- package/dist/esm/lib/injection-engine/skillsFromDir.js +243 -0
- package/dist/esm/lib/injection-engine/skillsFromDir.js.map +1 -0
- package/dist/esm/lib/mcp/index.d.ts +6 -5
- package/dist/esm/lib/mcp/index.js +5 -4
- package/dist/esm/lib/mcp/index.js.map +1 -1
- package/dist/esm/lib/mcp/mcpClient.js +21 -9
- package/dist/esm/lib/mcp/mcpClient.js.map +1 -1
- package/dist/esm/lib/mcp/mcpServe.d.ts +70 -0
- package/dist/esm/lib/mcp/mcpServe.js +374 -0
- package/dist/esm/lib/mcp/mcpServe.js.map +1 -0
- package/dist/esm/lib/mcp/types.d.ts +130 -17
- package/dist/esm/lib/mcp/types.js +10 -10
- package/dist/esm/tool-providers/index.d.ts +8 -2
- package/dist/esm/tool-providers/index.js +7 -1
- package/dist/esm/tool-providers/index.js.map +1 -1
- package/dist/lib/injection-engine/index.js +6 -1
- package/dist/lib/injection-engine/index.js.map +1 -1
- package/dist/lib/injection-engine/skillsFromDir.js +270 -0
- package/dist/lib/injection-engine/skillsFromDir.js.map +1 -0
- package/dist/lib/mcp/index.js +7 -5
- package/dist/lib/mcp/index.js.map +1 -1
- package/dist/lib/mcp/mcpClient.js +21 -9
- package/dist/lib/mcp/mcpClient.js.map +1 -1
- package/dist/lib/mcp/mcpServe.js +401 -0
- package/dist/lib/mcp/mcpServe.js.map +1 -0
- package/dist/lib/mcp/types.js +10 -10
- package/dist/tool-providers/index.js +8 -1
- package/dist/tool-providers/index.js.map +1 -1
- package/dist/types/core/Agent.d.ts +7 -3
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/agent/AgentBuilder.d.ts +48 -1
- package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
- package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
- package/dist/types/core/agent/buildDynamicAgentChart.d.ts.map +1 -1
- package/dist/types/core/agent/stages/callLLM.d.ts +9 -0
- package/dist/types/core/agent/stages/callLLM.d.ts.map +1 -1
- package/dist/types/core/agent/stages/seed.d.ts +10 -1
- package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +44 -0
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/slots/buildSystemPromptSlot.d.ts +19 -4
- package/dist/types/core/slots/buildSystemPromptSlot.d.ts.map +1 -1
- package/dist/types/lib/injection-engine/index.d.ts +1 -0
- package/dist/types/lib/injection-engine/index.d.ts.map +1 -1
- package/dist/types/lib/injection-engine/skillsFromDir.d.ts +81 -0
- package/dist/types/lib/injection-engine/skillsFromDir.d.ts.map +1 -0
- package/dist/types/lib/mcp/index.d.ts +6 -5
- package/dist/types/lib/mcp/index.d.ts.map +1 -1
- package/dist/types/lib/mcp/mcpClient.d.ts.map +1 -1
- package/dist/types/lib/mcp/mcpServe.d.ts +71 -0
- package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -0
- package/dist/types/lib/mcp/types.d.ts +130 -17
- package/dist/types/lib/mcp/types.d.ts.map +1 -1
- package/dist/types/tool-providers/index.d.ts +8 -2
- package/dist/types/tool-providers/index.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP — Model Context Protocol
|
|
2
|
+
* MCP — Model Context Protocol, in both directions.
|
|
3
3
|
*
|
|
4
4
|
* MCP (https://modelcontextprotocol.io) is an open standard for
|
|
5
|
-
* connecting LLMs to external tools and data sources.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* connecting LLMs to external tools and data sources. This module
|
|
6
|
+
* bridges it both ways:
|
|
7
|
+
*
|
|
8
|
+
* - `mcpClient(opts)` — consume an MCP server; its tools become
|
|
9
|
+
* agentfootprint `Tool[]` you can hand to `agent.tools(...)`.
|
|
10
|
+
* - `mcpServe(tools, opts)` — the other direction: expose your own
|
|
11
|
+
* `Tool[]` AS an MCP server, so any MCP client can call them.
|
|
9
12
|
*
|
|
10
13
|
* Pattern: Adapter (GoF) — translates MCP wire format ↔ agentfootprint
|
|
11
14
|
* `Tool` interface. The MCP SDK does the protocol work; we
|
|
@@ -14,11 +17,8 @@
|
|
|
14
17
|
* inline alternative for non-MCP tools).
|
|
15
18
|
* Emits: N/A directly — wrapped tools emit the standard
|
|
16
19
|
* `agentfootprint.stream.tool_start` / `tool_end` events
|
|
17
|
-
* when the agent calls them.
|
|
18
|
-
*
|
|
19
|
-
* Server-side support (exposing an agent or LLMCall as an MCP tool)
|
|
20
|
-
* is a separate concern not yet shipped. This module covers the
|
|
21
|
-
* 80% case: pulling an existing MCP server's tools INTO an agent.
|
|
20
|
+
* when the agent calls them. `mcpServe` runs OUTSIDE any
|
|
21
|
+
* agent run, so it emits nothing at all.
|
|
22
22
|
*/
|
|
23
23
|
import type { Tool } from '../../core/tools.js';
|
|
24
24
|
/**
|
|
@@ -32,7 +32,13 @@ export interface McpStdioTransport {
|
|
|
32
32
|
readonly command: string;
|
|
33
33
|
/** CLI args passed to the executable. */
|
|
34
34
|
readonly args?: readonly string[];
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Environment for the subprocess. Passed to the SDK as-is, and the SDK
|
|
37
|
+
* treats it as the WHOLE environment: set this and the child no longer
|
|
38
|
+
* inherits the safe default set (`PATH`, `HOME`, …). Omit it unless you
|
|
39
|
+
* mean to replace the environment; to merely add a variable, include the
|
|
40
|
+
* ones the child still needs.
|
|
41
|
+
*/
|
|
36
42
|
readonly env?: Readonly<Record<string, string>>;
|
|
37
43
|
/** Working directory for the subprocess. */
|
|
38
44
|
readonly cwd?: string;
|
|
@@ -107,22 +113,29 @@ export interface McpClient {
|
|
|
107
113
|
* a lazy peer-dep)
|
|
108
114
|
*
|
|
109
115
|
* The real SDK exports a richer surface; we narrow to what's needed.
|
|
116
|
+
*
|
|
117
|
+
* Argument POSITION matters here and is easy to get wrong: the SDK keeps
|
|
118
|
+
* per-request options (`signal`, `timeout`) in a SEPARATE trailing
|
|
119
|
+
* argument, never inside the JSON-RPC params. A `signal` smuggled into
|
|
120
|
+
* the params object is serialized onto the wire as `{}` and silently
|
|
121
|
+
* fails to cancel anything, so these signatures mirror the SDK's own
|
|
122
|
+
* shape rather than a flattened convenience version of it.
|
|
110
123
|
*/
|
|
111
124
|
export interface McpSdkClient {
|
|
112
|
-
connect(transport: unknown): Promise<void>;
|
|
113
|
-
listTools(): Promise<{
|
|
125
|
+
connect(transport: unknown, options?: McpRequestOptions): Promise<void>;
|
|
126
|
+
listTools(params?: undefined, options?: McpRequestOptions): Promise<{
|
|
114
127
|
readonly tools: ReadonlyArray<{
|
|
115
128
|
readonly name: string;
|
|
116
129
|
readonly description?: string;
|
|
117
130
|
readonly inputSchema: Readonly<Record<string, unknown>>;
|
|
118
131
|
}>;
|
|
119
132
|
}>;
|
|
120
|
-
callTool(
|
|
133
|
+
callTool(params: {
|
|
121
134
|
readonly name: string;
|
|
122
135
|
readonly arguments?: Readonly<Record<string, unknown>>;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
136
|
+
},
|
|
137
|
+
/** The SDK's result schema. We always want its default, so we pass `undefined`. */
|
|
138
|
+
resultSchema?: undefined, options?: McpRequestOptions): Promise<{
|
|
126
139
|
readonly content: ReadonlyArray<{
|
|
127
140
|
readonly type: string;
|
|
128
141
|
readonly text?: string;
|
|
@@ -131,3 +144,103 @@ export interface McpSdkClient {
|
|
|
131
144
|
}>;
|
|
132
145
|
close(): Promise<void>;
|
|
133
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* The SDK's trailing per-request options argument, narrowed to the one
|
|
149
|
+
* field we forward from {@link McpClientOptions.signal}.
|
|
150
|
+
*/
|
|
151
|
+
export interface McpRequestOptions {
|
|
152
|
+
readonly signal?: AbortSignal;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* `stdio` transport — the server speaks MCP over its own stdin/stdout.
|
|
156
|
+
* This is how a desktop MCP host launches a server: it spawns your
|
|
157
|
+
* process and talks down the pipe. The default.
|
|
158
|
+
*
|
|
159
|
+
* One consequence worth stating out loud: stdout belongs to the
|
|
160
|
+
* protocol. Anything else your process prints there corrupts the
|
|
161
|
+
* stream, so log to stderr.
|
|
162
|
+
*/
|
|
163
|
+
export interface McpStdioServeTransport {
|
|
164
|
+
readonly transport: 'stdio';
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* `http` transport — the server listens on a port and speaks MCP over
|
|
168
|
+
* Streamable HTTP. Stateless (no session ids): every request is
|
|
169
|
+
* self-contained, which is what makes it safe to run several replicas
|
|
170
|
+
* behind a load balancer.
|
|
171
|
+
*/
|
|
172
|
+
export interface McpHttpServeTransport {
|
|
173
|
+
readonly transport: 'http';
|
|
174
|
+
/** TCP port to listen on. */
|
|
175
|
+
readonly port: number;
|
|
176
|
+
/** Interface to bind. Defaults to Node's own default (all interfaces). */
|
|
177
|
+
readonly host?: string;
|
|
178
|
+
/** URL path the MCP endpoint answers on. Default `'/mcp'`. */
|
|
179
|
+
readonly path?: string;
|
|
180
|
+
}
|
|
181
|
+
export type McpServeTransport = McpStdioServeTransport | McpHttpServeTransport;
|
|
182
|
+
export interface McpServeOptions {
|
|
183
|
+
/**
|
|
184
|
+
* Server name reported to clients on connect. Surfaces in the
|
|
185
|
+
* client's server list. Default `'agentfootprint'`.
|
|
186
|
+
*/
|
|
187
|
+
readonly name?: string;
|
|
188
|
+
/** Server version reported to clients. Default `'0.0.0'`. */
|
|
189
|
+
readonly version?: string;
|
|
190
|
+
/** Transport configuration. Default `{ transport: 'stdio' }`. */
|
|
191
|
+
readonly transport?: McpServeTransport;
|
|
192
|
+
/**
|
|
193
|
+
* Credential provider for served tools that declare `needs`. The
|
|
194
|
+
* credential is resolved BEFORE `execute` and injected as
|
|
195
|
+
* `ctx.credential`, exactly as the Agent's tool-call stage does it.
|
|
196
|
+
*
|
|
197
|
+
* Serving a `needs`-declaring tool without this is refused at
|
|
198
|
+
* construction: the tool would run with `ctx.credential` undefined
|
|
199
|
+
* and fail somewhere further in, or worse, not fail at all.
|
|
200
|
+
*/
|
|
201
|
+
readonly credentials?: import('../../identity/types.js').CredentialProvider;
|
|
202
|
+
/**
|
|
203
|
+
* @internal Pre-built SDK server for tests. Skips SDK import +
|
|
204
|
+
* transport construction. Mirrors `McpClientOptions._client`.
|
|
205
|
+
*/
|
|
206
|
+
readonly _server?: McpSdkServer;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* What `mcpServe(...)` returns. The server is already listening by the
|
|
210
|
+
* time you hold this; `close()` is the only thing left to do.
|
|
211
|
+
*/
|
|
212
|
+
export interface McpServeHandle {
|
|
213
|
+
/** Server name from options (or the default). */
|
|
214
|
+
readonly name: string;
|
|
215
|
+
/** Names of the tools being served, in the order clients will list them. */
|
|
216
|
+
readonly toolNames: readonly string[];
|
|
217
|
+
/**
|
|
218
|
+
* Stop serving: closes the transport (and, for `http`, the listening
|
|
219
|
+
* socket) and then the MCP server. Idempotent — calling it twice is
|
|
220
|
+
* not an error, so a shutdown hook and an explicit close can coexist.
|
|
221
|
+
*/
|
|
222
|
+
close(): Promise<void>;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Minimal structural type for the parts of the MCP SDK's low-level
|
|
226
|
+
* `Server` we touch. Defined locally for the same two reasons as
|
|
227
|
+
* {@link McpSdkClient}: test injection via `McpServeOptions._server`,
|
|
228
|
+
* and no hard import on the lazy peer-dep.
|
|
229
|
+
*/
|
|
230
|
+
export interface McpSdkServer {
|
|
231
|
+
setRequestHandler(schema: unknown, handler: (request: McpCallToolRequest, extra: {
|
|
232
|
+
readonly signal?: AbortSignal;
|
|
233
|
+
}) => unknown): void;
|
|
234
|
+
connect(transport: unknown): Promise<void>;
|
|
235
|
+
close(): Promise<void>;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* The shape `tools/call` requests arrive in. `tools/list` requests carry
|
|
239
|
+
* no params we read, so one request type covers both handlers.
|
|
240
|
+
*/
|
|
241
|
+
export interface McpCallToolRequest {
|
|
242
|
+
readonly params?: {
|
|
243
|
+
readonly name?: string;
|
|
244
|
+
readonly arguments?: unknown;
|
|
245
|
+
};
|
|
246
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP — Model Context Protocol
|
|
2
|
+
* MCP — Model Context Protocol, in both directions.
|
|
3
3
|
*
|
|
4
4
|
* MCP (https://modelcontextprotocol.io) is an open standard for
|
|
5
|
-
* connecting LLMs to external tools and data sources.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* connecting LLMs to external tools and data sources. This module
|
|
6
|
+
* bridges it both ways:
|
|
7
|
+
*
|
|
8
|
+
* - `mcpClient(opts)` — consume an MCP server; its tools become
|
|
9
|
+
* agentfootprint `Tool[]` you can hand to `agent.tools(...)`.
|
|
10
|
+
* - `mcpServe(tools, opts)` — the other direction: expose your own
|
|
11
|
+
* `Tool[]` AS an MCP server, so any MCP client can call them.
|
|
9
12
|
*
|
|
10
13
|
* Pattern: Adapter (GoF) — translates MCP wire format ↔ agentfootprint
|
|
11
14
|
* `Tool` interface. The MCP SDK does the protocol work; we
|
|
@@ -14,11 +17,8 @@
|
|
|
14
17
|
* inline alternative for non-MCP tools).
|
|
15
18
|
* Emits: N/A directly — wrapped tools emit the standard
|
|
16
19
|
* `agentfootprint.stream.tool_start` / `tool_end` events
|
|
17
|
-
* when the agent calls them.
|
|
18
|
-
*
|
|
19
|
-
* Server-side support (exposing an agent or LLMCall as an MCP tool)
|
|
20
|
-
* is a separate concern not yet shipped. This module covers the
|
|
21
|
-
* 80% case: pulling an existing MCP server's tools INTO an agent.
|
|
20
|
+
* when the agent calls them. `mcpServe` runs OUTSIDE any
|
|
21
|
+
* agent run, so it emits nothing at all.
|
|
22
22
|
*/
|
|
23
23
|
export {};
|
|
24
24
|
//# sourceMappingURL=types.js.map
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
* - `mcpClient(opts)` — connect to an MCP server (real)
|
|
14
14
|
* - `mockMcpClient({ tools })` — in-memory MCP source for dev / tests
|
|
15
15
|
*
|
|
16
|
+
* 3. Tool sink — the other direction
|
|
17
|
+
* - `mcpServe(tools, opts)` — expose your own `Tool[]` AS an MCP
|
|
18
|
+
* server, so any MCP client can call them. The served tool is the
|
|
19
|
+
* SAME object you pass in, so whatever governance you composed
|
|
20
|
+
* around it still runs.
|
|
21
|
+
*
|
|
16
22
|
* Compose freely. The dispatch layer is decorator-shaped (mirroring
|
|
17
23
|
* `withRetry` / `withFallback` over LLMProvider). Tool sources produce
|
|
18
24
|
* `Tool[]` that flow into a `staticTools(arr)` provider, which can
|
|
@@ -37,5 +43,5 @@ export { staticTools } from './staticTools.js';
|
|
|
37
43
|
export { gatedTools } from './gatedTools.js';
|
|
38
44
|
export { skillScopedTools } from './skillScopedTools.js';
|
|
39
45
|
export type { ToolProvider, ToolDispatchContext, ToolGatePredicate } from './types.js';
|
|
40
|
-
export { mcpClient, mockMcpClient } from '../lib/mcp/index.js';
|
|
41
|
-
export type { McpClient, McpClientOptions, McpSdkClient, McpTransport, McpStdioTransport, McpHttpTransport, MockMcpClientOptions, MockMcpTool, } from '../lib/mcp/index.js';
|
|
46
|
+
export { mcpClient, mcpServe, mockMcpClient } from '../lib/mcp/index.js';
|
|
47
|
+
export type { McpClient, McpClientOptions, McpSdkClient, McpTransport, McpStdioTransport, McpHttpTransport, MockMcpClientOptions, MockMcpTool, McpServeOptions, McpServeHandle, McpServeTransport, McpStdioServeTransport, McpHttpServeTransport, McpSdkServer, } from '../lib/mcp/index.js';
|
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
* - `mcpClient(opts)` — connect to an MCP server (real)
|
|
14
14
|
* - `mockMcpClient({ tools })` — in-memory MCP source for dev / tests
|
|
15
15
|
*
|
|
16
|
+
* 3. Tool sink — the other direction
|
|
17
|
+
* - `mcpServe(tools, opts)` — expose your own `Tool[]` AS an MCP
|
|
18
|
+
* server, so any MCP client can call them. The served tool is the
|
|
19
|
+
* SAME object you pass in, so whatever governance you composed
|
|
20
|
+
* around it still runs.
|
|
21
|
+
*
|
|
16
22
|
* Compose freely. The dispatch layer is decorator-shaped (mirroring
|
|
17
23
|
* `withRetry` / `withFallback` over LLMProvider). Tool sources produce
|
|
18
24
|
* `Tool[]` that flow into a `staticTools(arr)` provider, which can
|
|
@@ -39,5 +45,5 @@ export { skillScopedTools } from './skillScopedTools.js';
|
|
|
39
45
|
// Re-export tool sources from the MCP module so consumers find them in
|
|
40
46
|
// one place. This subpath is the ONLY place `mcpClient` is public — the
|
|
41
47
|
// top-level barrel does not re-export it.
|
|
42
|
-
export { mcpClient, mockMcpClient } from '../lib/mcp/index.js';
|
|
48
|
+
export { mcpClient, mcpServe, mockMcpClient } from '../lib/mcp/index.js';
|
|
43
49
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tool-providers/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tool-providers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,uEAAuE;AACvE,wEAAwE;AACxE,0CAA0C;AAC1C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* factories. See `README.md` in this folder for the full concept.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.skillToolNames = exports.checkSkillContracts = exports.checkSkillContract = exports.rankEntries = exports.embeddingScorer = exports.keywordScorer = exports.SKILL_GRAPH_METADATA_KEY = exports.decideSkill = exports.skillGraph = exports.defineInjection = exports.defineFact = exports.defineSteering = exports.buildReadSkillTool = exports.buildListSkillsTool = exports.SkillRegistry = exports.resolveSurfaceMode = exports.defineSkill = exports.defineRelevanceHint = exports.defineInstruction = exports.buildInjectionEngineSubflow = exports.evaluateInjections = exports.projectActiveInjection = void 0;
|
|
10
|
+
exports.skillToolNames = exports.checkSkillContracts = exports.checkSkillContract = exports.rankEntries = exports.embeddingScorer = exports.keywordScorer = exports.SKILL_GRAPH_METADATA_KEY = exports.decideSkill = exports.skillGraph = exports.defineInjection = exports.defineFact = exports.defineSteering = exports.buildReadSkillTool = exports.buildListSkillsTool = exports.skillsFromDir = exports.SkillRegistry = exports.resolveSurfaceMode = exports.defineSkill = exports.defineRelevanceHint = exports.defineInstruction = exports.buildInjectionEngineSubflow = exports.evaluateInjections = exports.projectActiveInjection = void 0;
|
|
11
11
|
// POJO projection — used by slot subflows + advanced consumers
|
|
12
12
|
var types_js_1 = require("./types.js");
|
|
13
13
|
Object.defineProperty(exports, "projectActiveInjection", { enumerable: true, get: function () { return types_js_1.projectActiveInjection; } });
|
|
@@ -26,6 +26,11 @@ Object.defineProperty(exports, "defineSkill", { enumerable: true, get: function
|
|
|
26
26
|
Object.defineProperty(exports, "resolveSurfaceMode", { enumerable: true, get: function () { return defineSkill_js_1.resolveSurfaceMode; } });
|
|
27
27
|
var SkillRegistry_js_1 = require("./SkillRegistry.js");
|
|
28
28
|
Object.defineProperty(exports, "SkillRegistry", { enumerable: true, get: function () { return SkillRegistry_js_1.SkillRegistry; } });
|
|
29
|
+
// File-authored skills — a loader over `defineSkill`, not a second mechanism.
|
|
30
|
+
// Node-only (reads the filesystem); node:fs is imported lazily inside the call
|
|
31
|
+
// so this barrel stays safe to import from a browser bundle.
|
|
32
|
+
var skillsFromDir_js_1 = require("./skillsFromDir.js");
|
|
33
|
+
Object.defineProperty(exports, "skillsFromDir", { enumerable: true, get: function () { return skillsFromDir_js_1.skillsFromDir; } });
|
|
29
34
|
// Skill-tool builders — used by SkillRegistry.toTools() and the Agent's
|
|
30
35
|
// auto-attach path. Exported so consumers building custom tool wiring
|
|
31
36
|
// (e.g., gatedTools chains) can compose the same `list_skills` /
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/injection-engine/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAYH,+DAA+D;AAC/D,uCAAoD;AAA3C,kHAAA,sBAAsB,OAAA;AAE/B,SAAS;AACT,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAC3B,mFAG0C;AAFxC,6IAAA,2BAA2B,OAAA;AAI7B,gFAAgF;AAChF,yEAAoG;AAA3F,yHAAA,iBAAiB,OAAA;AAC1B,6EAAoG;AAA3F,6HAAA,mBAAmB,OAAA;AAE5B,6DAOoC;AANlC,6GAAA,WAAW,OAAA;AACX,oHAAA,kBAAkB,OAAA;AAOpB,uDAA8E;AAArE,iHAAA,aAAa,OAAA;AAEtB,wEAAwE;AACxE,sEAAsE;AACtE,iEAAiE;AACjE,+BAA+B;AAC/B,iDAA8F;AAArF,oHAAA,mBAAmB,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAEhD,mEAA2F;AAAlF,mHAAA,cAAc,OAAA;AAEvB,2DAA+E;AAAtE,2GAAA,UAAU,OAAA;AAEnB,6EAA6E;AAC7E,0EAA0E;AAC1E,qDAAqD;AACrD,qEAIwC;AAHtC,qHAAA,eAAe,OAAA;AAKjB,4EAA4E;AAC5E,8EAA8E;AAC9E,iDAuByB;AAtBvB,2GAAA,UAAU,OAAA;AACV,4GAAA,WAAW,OAAA;AACX,yHAAA,wBAAwB,OAAA;AAqB1B,mDAO0B;AANxB,+GAAA,aAAa,OAAA;AACb,iHAAA,eAAe,OAAA;AACf,6GAAA,WAAW,OAAA;AAKb,uDAA6F;AAApF,sHAAA,kBAAkB,OAAA;AAAE,uHAAA,mBAAmB,OAAA;AAAE,kHAAA,cAAc,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/injection-engine/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAYH,+DAA+D;AAC/D,uCAAoD;AAA3C,kHAAA,sBAAsB,OAAA;AAE/B,SAAS;AACT,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAC3B,mFAG0C;AAFxC,6IAAA,2BAA2B,OAAA;AAI7B,gFAAgF;AAChF,yEAAoG;AAA3F,yHAAA,iBAAiB,OAAA;AAC1B,6EAAoG;AAA3F,6HAAA,mBAAmB,OAAA;AAE5B,6DAOoC;AANlC,6GAAA,WAAW,OAAA;AACX,oHAAA,kBAAkB,OAAA;AAOpB,uDAA8E;AAArE,iHAAA,aAAa,OAAA;AAEtB,8EAA8E;AAC9E,+EAA+E;AAC/E,6DAA6D;AAC7D,uDAA8E;AAArE,iHAAA,aAAa,OAAA;AAEtB,wEAAwE;AACxE,sEAAsE;AACtE,iEAAiE;AACjE,+BAA+B;AAC/B,iDAA8F;AAArF,oHAAA,mBAAmB,OAAA;AAAE,mHAAA,kBAAkB,OAAA;AAEhD,mEAA2F;AAAlF,mHAAA,cAAc,OAAA;AAEvB,2DAA+E;AAAtE,2GAAA,UAAU,OAAA;AAEnB,6EAA6E;AAC7E,0EAA0E;AAC1E,qDAAqD;AACrD,qEAIwC;AAHtC,qHAAA,eAAe,OAAA;AAKjB,4EAA4E;AAC5E,8EAA8E;AAC9E,iDAuByB;AAtBvB,2GAAA,UAAU,OAAA;AACV,4GAAA,WAAW,OAAA;AACX,yHAAA,wBAAwB,OAAA;AAqB1B,mDAO0B;AANxB,+GAAA,aAAa,OAAA;AACb,iHAAA,eAAe,OAAA;AACf,6GAAA,WAAW,OAAA;AAKb,uDAA6F;AAApF,sHAAA,kBAAkB,OAAA;AAAE,uHAAA,mBAAmB,OAAA;AAAE,kHAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* skillsFromDir — load Skills that were AUTHORED AS FILES.
|
|
4
|
+
*
|
|
5
|
+
* The just-in-time half of skills already ships: `defineSkill` produces an
|
|
6
|
+
* Injection whose `description` is all the model sees until it calls
|
|
7
|
+
* `read_skill(<id>)`, at which point the body enters the context. What did not
|
|
8
|
+
* ship was the other half — a way to keep those bodies where prose belongs, in
|
|
9
|
+
* files, next to the code they describe, reviewable in a diff.
|
|
10
|
+
*
|
|
11
|
+
* This is that loader, and nothing more. It reads a directory of `SKILL.md`
|
|
12
|
+
* files and hands each one to `defineSkill`. The progressive disclosure, the
|
|
13
|
+
* activation tool, the slot routing — all unchanged, all upstream of here.
|
|
14
|
+
*
|
|
15
|
+
* skills/
|
|
16
|
+
* billing/SKILL.md
|
|
17
|
+
* refunds/SKILL.md
|
|
18
|
+
*
|
|
19
|
+
* ---
|
|
20
|
+
* name: billing
|
|
21
|
+
* description: Use for refunds, charges and billing questions.
|
|
22
|
+
* ---
|
|
23
|
+
* When handling billing: confirm identity first, then …
|
|
24
|
+
*
|
|
25
|
+
* const skills = await skillsFromDir('./skills');
|
|
26
|
+
* const agent = Agent.create({ provider, model }).skills({ list: () => skills }).build();
|
|
27
|
+
*
|
|
28
|
+
* The frontmatter is the disclosure stub (`name` + `description` — what the
|
|
29
|
+
* model reads when deciding), and everything after the closing fence is the
|
|
30
|
+
* body (what it reads after deciding). That is the same file convention Claude
|
|
31
|
+
* Code made familiar, so a skill folder is portable between the two.
|
|
32
|
+
*
|
|
33
|
+
* ── Why authorship is decided here, at load time ─────────────────────────────
|
|
34
|
+
* A Skill body is *instructions to a model*. Where it came from is therefore a
|
|
35
|
+
* security property, not a convenience: content fetched at run time from
|
|
36
|
+
* somewhere else is content someone else can change after you reviewed it.
|
|
37
|
+
* This loader accepts a local directory and nothing else — a URL is refused BY
|
|
38
|
+
* NAME rather than fetched — because "these files are mine" is a claim you can
|
|
39
|
+
* only make about a path on your own disk at build time. Each file is read
|
|
40
|
+
* ONCE, here; a later edit does not reach a run already in flight.
|
|
41
|
+
*
|
|
42
|
+
* Node-only. `node:fs/promises` and `node:path` are imported lazily inside the
|
|
43
|
+
* call, the same gating `lib/tool-lint/cli.ts` uses: this module is reachable
|
|
44
|
+
* from the `agentfootprint/injection-engine` barrel, and a TOP-LEVEL node:fs
|
|
45
|
+
* import detonates a browser bundle at module-eval even when nothing calls it.
|
|
46
|
+
*/
|
|
47
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
48
|
+
if (k2 === undefined) k2 = k;
|
|
49
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
50
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
51
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
52
|
+
}
|
|
53
|
+
Object.defineProperty(o, k2, desc);
|
|
54
|
+
}) : (function(o, m, k, k2) {
|
|
55
|
+
if (k2 === undefined) k2 = k;
|
|
56
|
+
o[k2] = m[k];
|
|
57
|
+
}));
|
|
58
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
59
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
60
|
+
}) : function(o, v) {
|
|
61
|
+
o["default"] = v;
|
|
62
|
+
});
|
|
63
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
64
|
+
if (mod && mod.__esModule) return mod;
|
|
65
|
+
var result = {};
|
|
66
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
67
|
+
__setModuleDefault(result, mod);
|
|
68
|
+
return result;
|
|
69
|
+
};
|
|
70
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
71
|
+
exports.skillsFromDir = void 0;
|
|
72
|
+
const defineSkill_js_1 = require("./factories/defineSkill.js");
|
|
73
|
+
/** The file name every skill folder is expected to use. */
|
|
74
|
+
const SKILL_FILE = 'SKILL.md';
|
|
75
|
+
/**
|
|
76
|
+
* Skill ids ride into `read_skill`'s `enum` and into the skill-graph's node
|
|
77
|
+
* ids. The house tool-name charset keeps them quotable in a prompt, comparable
|
|
78
|
+
* as plain strings, and safe as an object key.
|
|
79
|
+
*/
|
|
80
|
+
const SKILL_NAME_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
81
|
+
/** Anything of the form `scheme://…` — http, https, s3, git+ssh, file, … */
|
|
82
|
+
const URL_LIKE_RE = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//;
|
|
83
|
+
/**
|
|
84
|
+
* Load every `SKILL.md` under `dir` as a Skill Injection.
|
|
85
|
+
*
|
|
86
|
+
* Two layouts are accepted, and they can be mixed:
|
|
87
|
+
* - `dir/<anything>/SKILL.md` — one folder per skill (the portable layout,
|
|
88
|
+
* and the one to prefer: the folder can hold the skill's other assets).
|
|
89
|
+
* - `dir/SKILL.md` — the directory IS one skill.
|
|
90
|
+
*
|
|
91
|
+
* The returned array is sorted by skill name, so a chart built from it is
|
|
92
|
+
* stable regardless of the order the filesystem happened to hand back.
|
|
93
|
+
*
|
|
94
|
+
* @param dir - A local filesystem path. A URL (or any `scheme://` string, or a
|
|
95
|
+
* UNC network path) is refused by name — see the module header for why.
|
|
96
|
+
* @param opts - Applied uniformly to every loaded skill.
|
|
97
|
+
*
|
|
98
|
+
* @throws when `dir` is not a local path, does not exist, is not a directory,
|
|
99
|
+
* or contains no `SKILL.md` at all; when a file's frontmatter is malformed
|
|
100
|
+
* (the message names the file); or when two files claim the same skill name
|
|
101
|
+
* (the message names both).
|
|
102
|
+
*/
|
|
103
|
+
async function skillsFromDir(dir, opts = {}) {
|
|
104
|
+
assertLocalDirectoryArgument(dir);
|
|
105
|
+
// Lazy node imports (browser-compat) — see module header.
|
|
106
|
+
const { readdir, readFile, stat } = await Promise.resolve().then(() => __importStar(require('node:fs/promises')));
|
|
107
|
+
const { join } = await Promise.resolve().then(() => __importStar(require('node:path')));
|
|
108
|
+
let isDirectory = false;
|
|
109
|
+
try {
|
|
110
|
+
isDirectory = (await stat(dir)).isDirectory();
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
throw new Error(`skillsFromDir: '${dir}' does not exist. Pass the directory that holds your ` +
|
|
114
|
+
`${SKILL_FILE} folders.`);
|
|
115
|
+
}
|
|
116
|
+
if (!isDirectory) {
|
|
117
|
+
throw new Error(`skillsFromDir: '${dir}' is a file, not a directory. Pass the directory that holds ` +
|
|
118
|
+
`your ${SKILL_FILE} folders.`);
|
|
119
|
+
}
|
|
120
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
121
|
+
const files = [];
|
|
122
|
+
// `dir/SKILL.md` — the whole directory is one skill.
|
|
123
|
+
if (entries.some((e) => e.isFile() && e.name === SKILL_FILE)) {
|
|
124
|
+
files.push(join(dir, SKILL_FILE));
|
|
125
|
+
}
|
|
126
|
+
// `dir/<folder>/SKILL.md` — the portable layout.
|
|
127
|
+
for (const entry of entries) {
|
|
128
|
+
if (!entry.isDirectory())
|
|
129
|
+
continue;
|
|
130
|
+
const candidate = join(dir, entry.name, SKILL_FILE);
|
|
131
|
+
try {
|
|
132
|
+
if ((await stat(candidate)).isFile())
|
|
133
|
+
files.push(candidate);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// A subdirectory without a SKILL.md is not an error — a skill folder can
|
|
137
|
+
// sit next to assets, fixtures, or anything else the author keeps here.
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (files.length === 0) {
|
|
141
|
+
throw new Error(`skillsFromDir: no ${SKILL_FILE} found under '${dir}'. Expected '${dir}/<skill>/${SKILL_FILE}' ` +
|
|
142
|
+
`or '${dir}/${SKILL_FILE}'.`);
|
|
143
|
+
}
|
|
144
|
+
const parsed = [];
|
|
145
|
+
for (const file of files.sort()) {
|
|
146
|
+
parsed.push(parseSkillFile(await readFile(file, 'utf8'), file));
|
|
147
|
+
}
|
|
148
|
+
// Collisions are refused naming BOTH files: with only the id in the message
|
|
149
|
+
// you would know a duplicate exists and still have to go find the pair.
|
|
150
|
+
const byName = new Map();
|
|
151
|
+
for (const skill of parsed) {
|
|
152
|
+
const clash = byName.get(skill.name);
|
|
153
|
+
if (clash) {
|
|
154
|
+
throw new Error(`skillsFromDir: two files claim the skill name '${skill.name}' — '${clash.file}' and ` +
|
|
155
|
+
`'${skill.file}'. Skill ids must be unique (read_skill dispatches by id); rename one.`);
|
|
156
|
+
}
|
|
157
|
+
byName.set(skill.name, skill);
|
|
158
|
+
}
|
|
159
|
+
return parsed
|
|
160
|
+
.slice()
|
|
161
|
+
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))
|
|
162
|
+
.map((skill) => (0, defineSkill_js_1.defineSkill)({
|
|
163
|
+
id: skill.name,
|
|
164
|
+
description: skill.description,
|
|
165
|
+
body: skill.body,
|
|
166
|
+
...(opts.viaToolName !== undefined && { viaToolName: opts.viaToolName }),
|
|
167
|
+
...(opts.surfaceMode !== undefined && { surfaceMode: opts.surfaceMode }),
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
exports.skillsFromDir = skillsFromDir;
|
|
171
|
+
// ─── Authorship guard ──────────────────────────────────────────────
|
|
172
|
+
/**
|
|
173
|
+
* Refuse anything that is not a local path, BY NAME. The message quotes what
|
|
174
|
+
* was passed, because the whole point is that the reader can see the thing
|
|
175
|
+
* that was rejected.
|
|
176
|
+
*/
|
|
177
|
+
function assertLocalDirectoryArgument(dir) {
|
|
178
|
+
if (typeof dir !== 'string' || dir.trim().length === 0) {
|
|
179
|
+
throw new Error(`skillsFromDir: expected a local directory path, got ${JSON.stringify(dir)}.`);
|
|
180
|
+
}
|
|
181
|
+
const scheme = URL_LIKE_RE.exec(dir);
|
|
182
|
+
if (scheme) {
|
|
183
|
+
throw new Error(`skillsFromDir: '${dir}' is a ${scheme[0].slice(0, -3)} URL, not a local directory. ` +
|
|
184
|
+
`Skill bodies are instructions to a model, so this loader only reads files you own ` +
|
|
185
|
+
`at build time — fetch remote content yourself, review it, and pass defineSkill(...) ` +
|
|
186
|
+
`the result.`);
|
|
187
|
+
}
|
|
188
|
+
if (dir.startsWith('\\\\')) {
|
|
189
|
+
throw new Error(`skillsFromDir: '${dir}' is a network (UNC) path, not a local directory. ` +
|
|
190
|
+
`Skill bodies are instructions to a model, so this loader only reads files you own ` +
|
|
191
|
+
`at build time.`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// ─── Frontmatter ───────────────────────────────────────────────────
|
|
195
|
+
/**
|
|
196
|
+
* Parse one `SKILL.md`. Every refusal names the file — a loader that says
|
|
197
|
+
* "malformed frontmatter" over a directory of forty files has told you nothing.
|
|
198
|
+
*
|
|
199
|
+
* The grammar is deliberately small: an opening `---` line, `key: value` lines
|
|
200
|
+
* (`#` comments and blank lines skipped, single/double quotes stripped), a
|
|
201
|
+
* closing `---` line, then the body. Keys other than `name` and `description`
|
|
202
|
+
* are IGNORED rather than rejected, so a file carrying extra frontmatter for
|
|
203
|
+
* another tool still loads here.
|
|
204
|
+
*/
|
|
205
|
+
function parseSkillFile(raw, file) {
|
|
206
|
+
// Strip a UTF-8 BOM — an editor artifact, not the author's intent.
|
|
207
|
+
const text = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
|
|
208
|
+
const lines = text.split(/\r?\n/);
|
|
209
|
+
if (lines[0]?.trim() !== '---') {
|
|
210
|
+
throw new Error(`skillsFromDir: '${file}' does not start with a '---' frontmatter block. ` +
|
|
211
|
+
`Expected:\n---\nname: my-skill\ndescription: When to use it.\n---\n<the body>`);
|
|
212
|
+
}
|
|
213
|
+
const closingIndex = lines.findIndex((line, i) => i > 0 && line.trim() === '---');
|
|
214
|
+
if (closingIndex === -1) {
|
|
215
|
+
throw new Error(`skillsFromDir: '${file}' opens a '---' frontmatter block that is never closed. ` +
|
|
216
|
+
`Add a '---' line after the last frontmatter key.`);
|
|
217
|
+
}
|
|
218
|
+
const fields = new Map();
|
|
219
|
+
for (let i = 1; i < closingIndex; i++) {
|
|
220
|
+
const line = lines[i] ?? '';
|
|
221
|
+
if (line.trim().length === 0 || line.trimStart().startsWith('#'))
|
|
222
|
+
continue;
|
|
223
|
+
const separator = line.indexOf(':');
|
|
224
|
+
if (separator === -1) {
|
|
225
|
+
throw new Error(`skillsFromDir: '${file}' frontmatter line ${i + 1} is not 'key: value' — got ` +
|
|
226
|
+
`${JSON.stringify(line)}.`);
|
|
227
|
+
}
|
|
228
|
+
const key = line.slice(0, separator).trim();
|
|
229
|
+
if (key.length === 0) {
|
|
230
|
+
throw new Error(`skillsFromDir: '${file}' frontmatter line ${i + 1} has an empty key — got ` +
|
|
231
|
+
`${JSON.stringify(line)}.`);
|
|
232
|
+
}
|
|
233
|
+
fields.set(key, unquote(line.slice(separator + 1).trim()));
|
|
234
|
+
}
|
|
235
|
+
const name = fields.get('name') ?? '';
|
|
236
|
+
const description = fields.get('description') ?? '';
|
|
237
|
+
const body = lines
|
|
238
|
+
.slice(closingIndex + 1)
|
|
239
|
+
.join('\n')
|
|
240
|
+
.trim();
|
|
241
|
+
if (name.length === 0) {
|
|
242
|
+
throw new Error(`skillsFromDir: '${file}' frontmatter is missing 'name'. It becomes the skill id the ` +
|
|
243
|
+
`model passes to read_skill.`);
|
|
244
|
+
}
|
|
245
|
+
if (!SKILL_NAME_RE.test(name)) {
|
|
246
|
+
throw new Error(`skillsFromDir: '${file}' frontmatter name '${name}' must match ` +
|
|
247
|
+
`/^[a-zA-Z0-9_-]{1,64}$/ — it is the id the model passes to read_skill.`);
|
|
248
|
+
}
|
|
249
|
+
if (description.length === 0) {
|
|
250
|
+
throw new Error(`skillsFromDir: '${file}' frontmatter is missing 'description'. It is the ONLY thing ` +
|
|
251
|
+
`the model reads when deciding whether to open this skill.`);
|
|
252
|
+
}
|
|
253
|
+
if (body.length === 0) {
|
|
254
|
+
throw new Error(`skillsFromDir: '${file}' has no body after the closing '---'. The body is what the ` +
|
|
255
|
+
`model reads once it activates the skill.`);
|
|
256
|
+
}
|
|
257
|
+
return { name, description, body, file };
|
|
258
|
+
}
|
|
259
|
+
/** Strip one layer of matching single or double quotes from a YAML-ish scalar. */
|
|
260
|
+
function unquote(value) {
|
|
261
|
+
if (value.length >= 2) {
|
|
262
|
+
const first = value[0];
|
|
263
|
+
const last = value[value.length - 1];
|
|
264
|
+
if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
|
|
265
|
+
return value.slice(1, -1);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return value;
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=skillsFromDir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillsFromDir.js","sourceRoot":"","sources":["../../../src/lib/injection-engine/skillsFromDir.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/mcp/index.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mockMcpClient = exports.mcpClient = void 0;
|
|
3
|
+
exports.mockMcpClient = exports.mcpServe = exports.mcpClient = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* MCP — Model Context Protocol
|
|
6
|
-
* server
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* MCP — Model Context Protocol, both directions. `mcpClient` connects to
|
|
6
|
+
* someone else's MCP server and registers its tools on your Agent;
|
|
7
|
+
* `mcpServe` exposes your own tools AS an MCP server so any MCP client
|
|
8
|
+
* can call them.
|
|
9
9
|
*/
|
|
10
10
|
var mcpClient_js_1 = require("./mcpClient.js");
|
|
11
11
|
Object.defineProperty(exports, "mcpClient", { enumerable: true, get: function () { return mcpClient_js_1.mcpClient; } });
|
|
12
|
+
var mcpServe_js_1 = require("./mcpServe.js");
|
|
13
|
+
Object.defineProperty(exports, "mcpServe", { enumerable: true, get: function () { return mcpServe_js_1.mcpServe; } });
|
|
12
14
|
var mockMcpClient_js_1 = require("./mockMcpClient.js");
|
|
13
15
|
Object.defineProperty(exports, "mockMcpClient", { enumerable: true, get: function () { return mockMcpClient_js_1.mockMcpClient; } });
|
|
14
16
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/mcp/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAClB,uDAAgG;AAAvF,iHAAA,aAAa,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/mcp/index.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACH,+CAA2C;AAAlC,yGAAA,SAAS,OAAA;AAClB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AACjB,uDAAgG;AAAvF,iHAAA,aAAa,OAAA"}
|