@vinkius-core/mcp-fusion 2.9.0 → 2.12.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/cli/fusion.d.ts +3 -0
- package/dist/cli/fusion.d.ts.map +1 -1
- package/dist/cli/fusion.js +125 -3
- package/dist/cli/fusion.js.map +1 -1
- package/dist/cli/templates/config.js +3 -3
- package/dist/cli/templates/config.js.map +1 -1
- package/dist/cli/templates/constants.d.ts +1 -1
- package/dist/cli/templates/constants.d.ts.map +1 -1
- package/dist/cli/templates/constants.js +1 -1
- package/dist/cli/templates/constants.js.map +1 -1
- package/dist/cli/templates/core.js +5 -5
- package/dist/cli/templates/middleware.d.ts +1 -1
- package/dist/cli/templates/middleware.d.ts.map +1 -1
- package/dist/cli/templates/middleware.js +16 -13
- package/dist/cli/templates/middleware.js.map +1 -1
- package/dist/cli/templates/readme.d.ts.map +1 -1
- package/dist/cli/templates/readme.js +14 -18
- package/dist/cli/templates/readme.js.map +1 -1
- package/dist/cli/templates/tools.d.ts +4 -0
- package/dist/cli/templates/tools.d.ts.map +1 -1
- package/dist/cli/templates/tools.js +26 -29
- package/dist/cli/templates/tools.js.map +1 -1
- package/dist/cli/templates/vectors/database.d.ts.map +1 -1
- package/dist/cli/templates/vectors/database.js +14 -19
- package/dist/cli/templates/vectors/database.js.map +1 -1
- package/dist/cli/templates/vectors/oauth.d.ts.map +1 -1
- package/dist/cli/templates/vectors/oauth.js +4 -5
- package/dist/cli/templates/vectors/oauth.js.map +1 -1
- package/dist/cli/templates/vectors/openapi.js +2 -2
- package/dist/cli/templates/vectors/workflow.js +1 -1
- package/dist/cli/templates/vectors/workflow.js.map +1 -1
- package/dist/client/FusionClient.d.ts +55 -0
- package/dist/client/FusionClient.d.ts.map +1 -1
- package/dist/client/FusionClient.js +30 -0
- package/dist/client/FusionClient.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/core/builder/ActionGroupBuilder.d.ts +86 -46
- package/dist/core/builder/ActionGroupBuilder.d.ts.map +1 -1
- package/dist/core/builder/ActionGroupBuilder.js +68 -26
- package/dist/core/builder/ActionGroupBuilder.js.map +1 -1
- package/dist/core/builder/ErrorBuilder.d.ts +59 -0
- package/dist/core/builder/ErrorBuilder.d.ts.map +1 -0
- package/dist/core/builder/ErrorBuilder.js +99 -0
- package/dist/core/builder/ErrorBuilder.js.map +1 -0
- package/dist/core/builder/FluentRouter.d.ts +91 -0
- package/dist/core/builder/FluentRouter.d.ts.map +1 -0
- package/dist/core/builder/FluentRouter.js +121 -0
- package/dist/core/builder/FluentRouter.js.map +1 -0
- package/dist/core/builder/FluentSchemaHelpers.d.ts +237 -0
- package/dist/core/builder/FluentSchemaHelpers.d.ts.map +1 -0
- package/dist/core/builder/FluentSchemaHelpers.js +227 -0
- package/dist/core/builder/FluentSchemaHelpers.js.map +1 -0
- package/dist/core/builder/FluentToolBuilder.d.ts +347 -0
- package/dist/core/builder/FluentToolBuilder.d.ts.map +1 -0
- package/dist/core/builder/FluentToolBuilder.js +525 -0
- package/dist/core/builder/FluentToolBuilder.js.map +1 -0
- package/dist/core/builder/GroupedToolBuilder.d.ts +91 -1
- package/dist/core/builder/GroupedToolBuilder.d.ts.map +1 -1
- package/dist/core/builder/GroupedToolBuilder.js +122 -4
- package/dist/core/builder/GroupedToolBuilder.js.map +1 -1
- package/dist/core/builder/ToolDefinitionCompiler.d.ts +1 -0
- package/dist/core/builder/ToolDefinitionCompiler.d.ts.map +1 -1
- package/dist/core/builder/ToolDefinitionCompiler.js +1 -1
- package/dist/core/builder/ToolDefinitionCompiler.js.map +1 -1
- package/dist/core/builder/index.d.ts +4 -0
- package/dist/core/builder/index.d.ts.map +1 -1
- package/dist/core/builder/index.js +7 -0
- package/dist/core/builder/index.js.map +1 -1
- package/dist/core/execution/EgressGuard.js +1 -1
- package/dist/core/execution/EgressGuard.js.map +1 -1
- package/dist/core/execution/ExecutionPipeline.d.ts +8 -2
- package/dist/core/execution/ExecutionPipeline.d.ts.map +1 -1
- package/dist/core/execution/ExecutionPipeline.js +18 -9
- package/dist/core/execution/ExecutionPipeline.js.map +1 -1
- package/dist/core/execution/PipelineHooks.d.ts +0 -6
- package/dist/core/execution/PipelineHooks.d.ts.map +1 -1
- package/dist/core/execution/PipelineHooks.js +7 -3
- package/dist/core/execution/PipelineHooks.js.map +1 -1
- package/dist/core/index.d.ts +5 -7
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/initFusion.d.ts +119 -87
- package/dist/core/initFusion.d.ts.map +1 -1
- package/dist/core/initFusion.js +56 -66
- package/dist/core/initFusion.js.map +1 -1
- package/dist/core/registry/ToolRegistry.d.ts +1 -1
- package/dist/core/registry/ToolRegistry.d.ts.map +1 -1
- package/dist/core/registry/ToolRegistry.js +1 -1
- package/dist/core/registry/ToolRegistry.js.map +1 -1
- package/dist/core/schema/SchemaGenerator.d.ts +1 -1
- package/dist/core/schema/SchemaGenerator.d.ts.map +1 -1
- package/dist/core/schema/SchemaGenerator.js +38 -1
- package/dist/core/schema/SchemaGenerator.js.map +1 -1
- package/dist/core/types.d.ts +19 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/exposition/ExpositionCompiler.d.ts.map +1 -1
- package/dist/exposition/ExpositionCompiler.js +25 -2
- package/dist/exposition/ExpositionCompiler.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/introspection/BehaviorDigest.d.ts +2 -2
- package/dist/introspection/BehaviorDigest.d.ts.map +1 -1
- package/dist/introspection/BehaviorDigest.js +38 -36
- package/dist/introspection/BehaviorDigest.js.map +1 -1
- package/dist/introspection/CapabilityLockfile.d.ts +2 -2
- package/dist/introspection/CapabilityLockfile.d.ts.map +1 -1
- package/dist/introspection/CapabilityLockfile.js +9 -9
- package/dist/introspection/CapabilityLockfile.js.map +1 -1
- package/dist/introspection/CryptoAttestation.d.ts.map +1 -1
- package/dist/introspection/CryptoAttestation.js +27 -36
- package/dist/introspection/CryptoAttestation.js.map +1 -1
- package/dist/introspection/ToolContract.d.ts +2 -2
- package/dist/introspection/ToolContract.d.ts.map +1 -1
- package/dist/introspection/ToolContract.js +9 -9
- package/dist/introspection/ToolContract.js.map +1 -1
- package/dist/introspection/canonicalize.d.ts +16 -1
- package/dist/introspection/canonicalize.d.ts.map +1 -1
- package/dist/introspection/canonicalize.js +24 -3
- package/dist/introspection/canonicalize.js.map +1 -1
- package/dist/presenter/PostProcessor.d.ts +4 -2
- package/dist/presenter/PostProcessor.d.ts.map +1 -1
- package/dist/presenter/PostProcessor.js +10 -10
- package/dist/presenter/PostProcessor.js.map +1 -1
- package/dist/presenter/Presenter.d.ts +112 -6
- package/dist/presenter/Presenter.d.ts.map +1 -1
- package/dist/presenter/Presenter.js +134 -40
- package/dist/presenter/Presenter.js.map +1 -1
- package/dist/presenter/SelectUtils.d.ts +78 -0
- package/dist/presenter/SelectUtils.d.ts.map +1 -0
- package/dist/presenter/SelectUtils.js +141 -0
- package/dist/presenter/SelectUtils.js.map +1 -0
- package/dist/presenter/index.d.ts +3 -0
- package/dist/presenter/index.d.ts.map +1 -1
- package/dist/presenter/index.js +6 -0
- package/dist/presenter/index.js.map +1 -1
- package/dist/presenter/suggest.d.ts +39 -0
- package/dist/presenter/suggest.d.ts.map +1 -0
- package/dist/presenter/suggest.js +41 -0
- package/dist/presenter/suggest.js.map +1 -0
- package/dist/presenter/typeHelpers.d.ts +147 -0
- package/dist/presenter/typeHelpers.d.ts.map +1 -0
- package/dist/presenter/typeHelpers.js +152 -0
- package/dist/presenter/typeHelpers.js.map +1 -0
- package/dist/prompt/FluentPromptBuilder.d.ts +155 -0
- package/dist/prompt/FluentPromptBuilder.d.ts.map +1 -0
- package/dist/prompt/FluentPromptBuilder.js +193 -0
- package/dist/prompt/FluentPromptBuilder.js.map +1 -0
- package/dist/prompt/index.d.ts +1 -0
- package/dist/prompt/index.d.ts.map +1 -1
- package/dist/prompt/index.js +1 -0
- package/dist/prompt/index.js.map +1 -1
- package/dist/server/DevServer.js +8 -8
- package/dist/server/DevServer.js.map +1 -1
- package/dist/server/ServerAttachment.d.ts +1 -1
- package/dist/server/ServerAttachment.d.ts.map +1 -1
- package/dist/server/ServerAttachment.js +57 -4
- package/dist/server/ServerAttachment.js.map +1 -1
- package/dist/state-sync/ResponseDecorator.d.ts +1 -1
- package/dist/state-sync/StateSyncBuilder.d.ts +75 -0
- package/dist/state-sync/StateSyncBuilder.d.ts.map +1 -0
- package/dist/state-sync/StateSyncBuilder.js +123 -0
- package/dist/state-sync/StateSyncBuilder.js.map +1 -0
- package/dist/state-sync/index.d.ts +1 -0
- package/dist/state-sync/index.d.ts.map +1 -1
- package/dist/state-sync/index.js +1 -0
- package/dist/state-sync/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FluentToolBuilder — Type-Chaining Builder for Semantic Verb Tools
|
|
3
|
+
*
|
|
4
|
+
* The core builder behind `f.query()`, `f.mutation()`, and `f.action()`.
|
|
5
|
+
* Uses TypeScript generic accumulation so that each fluent step narrows
|
|
6
|
+
* the types — the IDE "magically" knows the exact shape of `input` and
|
|
7
|
+
* `ctx` inside `.handle()` without any manual Interface declaration.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const f = initFusion<AppContext>();
|
|
12
|
+
*
|
|
13
|
+
* const listUsers = f.query('users.list')
|
|
14
|
+
* .describe('List users from the database')
|
|
15
|
+
* .withNumber('limit', 'Max results to return')
|
|
16
|
+
* .withOptionalEnum('status', ['active', 'inactive'], 'Filter by status')
|
|
17
|
+
* .returns(UserPresenter)
|
|
18
|
+
* .handle(async (input, ctx) => {
|
|
19
|
+
* return ctx.db.user.findMany({ take: input.limit });
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @see {@link FluentRouter} for prefix grouping
|
|
24
|
+
* @see {@link initFusion} for the factory that creates these builders
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
import { z } from 'zod';
|
|
29
|
+
import { GroupedToolBuilder } from './GroupedToolBuilder.js';
|
|
30
|
+
import {} from '../types.js';
|
|
31
|
+
import { success } from '../response.js';
|
|
32
|
+
import {} from '../../presenter/Presenter.js';
|
|
33
|
+
import {} from '../execution/ConcurrencyGuard.js';
|
|
34
|
+
/** Defaults for `f.query()` — read-only, no side effects */
|
|
35
|
+
export const QUERY_DEFAULTS = { readOnly: true };
|
|
36
|
+
/** Defaults for `f.mutation()` — destructive, irreversible */
|
|
37
|
+
export const MUTATION_DEFAULTS = { destructive: true };
|
|
38
|
+
/** Defaults for `f.action()` — neutral, no assumptions */
|
|
39
|
+
export const ACTION_DEFAULTS = {};
|
|
40
|
+
// ── Array Item Type Resolution ───────────────────────────
|
|
41
|
+
/** Resolve Zod type from array item type string */
|
|
42
|
+
function resolveArrayItemType(itemType) {
|
|
43
|
+
switch (itemType) {
|
|
44
|
+
case 'string': return z.string();
|
|
45
|
+
case 'number': return z.number();
|
|
46
|
+
case 'boolean': return z.boolean();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// ── FluentToolBuilder ────────────────────────────────────
|
|
50
|
+
/**
|
|
51
|
+
* Fluent builder that accumulates types at each step.
|
|
52
|
+
*
|
|
53
|
+
* @typeParam TContext - Base application context (from `initFusion<TContext>()`)
|
|
54
|
+
* @typeParam TInput - Accumulated input type (built by `with*()` methods)
|
|
55
|
+
* @typeParam TCtx - Accumulated context type (enriched by `.use()`)
|
|
56
|
+
*/
|
|
57
|
+
export class FluentToolBuilder {
|
|
58
|
+
/** @internal */ _name;
|
|
59
|
+
/** @internal */ _description;
|
|
60
|
+
/** @internal */ _instructions;
|
|
61
|
+
/** @internal */ _inputSchema;
|
|
62
|
+
/** @internal */ _withParams = {};
|
|
63
|
+
/** @internal */ _tags = [];
|
|
64
|
+
/** @internal */ _middlewares = [];
|
|
65
|
+
/** @internal */ _returns;
|
|
66
|
+
/** @internal */ _semanticDefaults;
|
|
67
|
+
/** @internal */ _readOnly;
|
|
68
|
+
/** @internal */ _destructive;
|
|
69
|
+
/** @internal */ _idempotent;
|
|
70
|
+
/** @internal */ _toonMode = false;
|
|
71
|
+
/** @internal */ _annotations;
|
|
72
|
+
/** @internal */ _invalidatesPatterns = [];
|
|
73
|
+
/** @internal */ _cacheControl;
|
|
74
|
+
/** @internal */ _concurrency;
|
|
75
|
+
/** @internal */ _egressMaxBytes;
|
|
76
|
+
/**
|
|
77
|
+
* @param name - Tool name in `domain.action` format (e.g. `'users.list'`)
|
|
78
|
+
* @param defaults - Semantic defaults from the verb (`query`, `mutation`, `action`)
|
|
79
|
+
*/
|
|
80
|
+
constructor(name, defaults = {}) {
|
|
81
|
+
this._name = name;
|
|
82
|
+
this._semanticDefaults = defaults;
|
|
83
|
+
}
|
|
84
|
+
// ── Configuration (fluent, each returns narrowed type) ──
|
|
85
|
+
/**
|
|
86
|
+
* Set the tool description shown to the LLM.
|
|
87
|
+
*
|
|
88
|
+
* @param text - Human-readable description
|
|
89
|
+
* @returns `this` for chaining
|
|
90
|
+
*/
|
|
91
|
+
describe(text) {
|
|
92
|
+
this._description = text;
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Set AI-First instructions — injected as system-level guidance in the tool description.
|
|
97
|
+
*
|
|
98
|
+
* This is **Prompt Engineering embedded in the framework**. The instructions
|
|
99
|
+
* tell the LLM WHEN and HOW to use this tool, reducing hallucination.
|
|
100
|
+
*
|
|
101
|
+
* @param text - System prompt for the tool
|
|
102
|
+
* @returns `this` for chaining
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* f.query('docs.search')
|
|
107
|
+
* .describe('Search internal documentation')
|
|
108
|
+
* .instructions('Use ONLY when the user asks about internal policies.')
|
|
109
|
+
* .withString('query', 'Search term')
|
|
110
|
+
* .handle(async (input) => { ... });
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
instructions(text) {
|
|
114
|
+
this._instructions = text;
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
// ── Parameter Declaration (with* methods) ────────────
|
|
118
|
+
/**
|
|
119
|
+
* Add a required string parameter.
|
|
120
|
+
*
|
|
121
|
+
* @param name - Parameter name
|
|
122
|
+
* @param description - Human-readable description for the LLM
|
|
123
|
+
* @returns Builder with narrowed `TInput` type
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* f.query('projects.get')
|
|
128
|
+
* .withString('project_id', 'The project ID to retrieve')
|
|
129
|
+
* .handle(async (input) => { ... });
|
|
130
|
+
* // input.project_id: string ✅
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
withString(name, description) {
|
|
134
|
+
this._withParams[name] = description ? z.string().describe(description) : z.string();
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Add an optional string parameter.
|
|
139
|
+
*
|
|
140
|
+
* @param name - Parameter name
|
|
141
|
+
* @param description - Human-readable description for the LLM
|
|
142
|
+
* @returns Builder with narrowed `TInput` type
|
|
143
|
+
*/
|
|
144
|
+
withOptionalString(name, description) {
|
|
145
|
+
const base = description ? z.string().describe(description) : z.string();
|
|
146
|
+
this._withParams[name] = base.optional();
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Add a required number parameter.
|
|
151
|
+
*
|
|
152
|
+
* @param name - Parameter name
|
|
153
|
+
* @param description - Human-readable description for the LLM
|
|
154
|
+
* @returns Builder with narrowed `TInput` type
|
|
155
|
+
*/
|
|
156
|
+
withNumber(name, description) {
|
|
157
|
+
this._withParams[name] = description ? z.number().describe(description) : z.number();
|
|
158
|
+
return this;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Add an optional number parameter.
|
|
162
|
+
*
|
|
163
|
+
* @param name - Parameter name
|
|
164
|
+
* @param description - Human-readable description for the LLM
|
|
165
|
+
* @returns Builder with narrowed `TInput` type
|
|
166
|
+
*/
|
|
167
|
+
withOptionalNumber(name, description) {
|
|
168
|
+
const base = description ? z.number().describe(description) : z.number();
|
|
169
|
+
this._withParams[name] = base.optional();
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Add a required boolean parameter.
|
|
174
|
+
*
|
|
175
|
+
* @param name - Parameter name
|
|
176
|
+
* @param description - Human-readable description for the LLM
|
|
177
|
+
* @returns Builder with narrowed `TInput` type
|
|
178
|
+
*/
|
|
179
|
+
withBoolean(name, description) {
|
|
180
|
+
this._withParams[name] = description ? z.boolean().describe(description) : z.boolean();
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Add an optional boolean parameter.
|
|
185
|
+
*
|
|
186
|
+
* @param name - Parameter name
|
|
187
|
+
* @param description - Human-readable description for the LLM
|
|
188
|
+
* @returns Builder with narrowed `TInput` type
|
|
189
|
+
*/
|
|
190
|
+
withOptionalBoolean(name, description) {
|
|
191
|
+
const base = description ? z.boolean().describe(description) : z.boolean();
|
|
192
|
+
this._withParams[name] = base.optional();
|
|
193
|
+
return this;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Add a required enum parameter.
|
|
197
|
+
*
|
|
198
|
+
* @param name - Parameter name
|
|
199
|
+
* @param values - Allowed enum values
|
|
200
|
+
* @param description - Human-readable description for the LLM
|
|
201
|
+
* @returns Builder with narrowed `TInput` type
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* f.query('invoices.list')
|
|
206
|
+
* .withEnum('status', ['draft', 'sent', 'paid'], 'Filter by status')
|
|
207
|
+
* .handle(async (input) => { ... });
|
|
208
|
+
* // input.status: 'draft' | 'sent' | 'paid' ✅
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
withEnum(name, values, description) {
|
|
212
|
+
const schema = z.enum(values);
|
|
213
|
+
this._withParams[name] = description ? schema.describe(description) : schema;
|
|
214
|
+
return this;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Add an optional enum parameter.
|
|
218
|
+
*
|
|
219
|
+
* @param name - Parameter name
|
|
220
|
+
* @param values - Allowed enum values
|
|
221
|
+
* @param description - Human-readable description for the LLM
|
|
222
|
+
* @returns Builder with narrowed `TInput` type
|
|
223
|
+
*/
|
|
224
|
+
withOptionalEnum(name, values, description) {
|
|
225
|
+
const schema = z.enum(values);
|
|
226
|
+
this._withParams[name] = description ? schema.describe(description).optional() : schema.optional();
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Add a required array parameter.
|
|
231
|
+
*
|
|
232
|
+
* @param name - Parameter name
|
|
233
|
+
* @param itemType - Type of array items (`'string'`, `'number'`, `'boolean'`)
|
|
234
|
+
* @param description - Human-readable description for the LLM
|
|
235
|
+
* @returns Builder with narrowed `TInput` type
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* f.mutation('tasks.tag')
|
|
240
|
+
* .withString('task_id', 'The task to tag')
|
|
241
|
+
* .withArray('tags', 'string', 'Tags to apply')
|
|
242
|
+
* .handle(async (input) => { ... });
|
|
243
|
+
* // input.tags: string[] ✅
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
withArray(name, itemType, description) {
|
|
247
|
+
const schema = z.array(resolveArrayItemType(itemType));
|
|
248
|
+
this._withParams[name] = description ? schema.describe(description) : schema;
|
|
249
|
+
return this;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Add an optional array parameter.
|
|
253
|
+
*
|
|
254
|
+
* @param name - Parameter name
|
|
255
|
+
* @param itemType - Type of array items (`'string'`, `'number'`, `'boolean'`)
|
|
256
|
+
* @param description - Human-readable description for the LLM
|
|
257
|
+
* @returns Builder with narrowed `TInput` type
|
|
258
|
+
*/
|
|
259
|
+
withOptionalArray(name, itemType, description) {
|
|
260
|
+
const schema = z.array(resolveArrayItemType(itemType));
|
|
261
|
+
this._withParams[name] = description ? schema.describe(description).optional() : schema.optional();
|
|
262
|
+
return this;
|
|
263
|
+
}
|
|
264
|
+
// ── Middleware ────────────────────────────────────────
|
|
265
|
+
/**
|
|
266
|
+
* Add context-derivation middleware (tRPC-style).
|
|
267
|
+
*
|
|
268
|
+
* The middleware receives `{ ctx, next }` and can enrich the context
|
|
269
|
+
* for downstream steps. The TypeScript type of `ctx` in `.handle()`
|
|
270
|
+
* is automatically extended with the derived properties.
|
|
271
|
+
*
|
|
272
|
+
* @param mw - Middleware that returns enriched context
|
|
273
|
+
* @returns A **new type** of `FluentToolBuilder` with `TCtx` enriched
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* ```typescript
|
|
277
|
+
* f.mutation('users.delete')
|
|
278
|
+
* .use(async ({ ctx, next }) => {
|
|
279
|
+
* const admin = await requireAdmin(ctx.headers);
|
|
280
|
+
* return next({ ...ctx, adminUser: admin });
|
|
281
|
+
* })
|
|
282
|
+
* .withString('id', 'User ID to delete')
|
|
283
|
+
* .handle(async (input, ctx) => {
|
|
284
|
+
* // ctx.adminUser is typed! Zero casting.
|
|
285
|
+
* ctx.logger.info(`${ctx.adminUser.name} deleting ${input.id}`);
|
|
286
|
+
* });
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
use(mw) {
|
|
290
|
+
// Convert the fluent middleware signature to the standard MiddlewareFn
|
|
291
|
+
const standardMw = async (ctx, args, next) => {
|
|
292
|
+
const wrappedNext = async (enrichedCtx) => {
|
|
293
|
+
// Merge enriched properties into context
|
|
294
|
+
Object.assign(ctx, enrichedCtx);
|
|
295
|
+
return next();
|
|
296
|
+
};
|
|
297
|
+
return mw({ ctx: ctx, next: wrappedNext });
|
|
298
|
+
};
|
|
299
|
+
this._middlewares.push(standardMw);
|
|
300
|
+
return this;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Set the MVA Presenter for automatic response formatting.
|
|
304
|
+
*
|
|
305
|
+
* When a Presenter is attached, the handler can return raw data
|
|
306
|
+
* and the framework pipes it through schema validation, system rules,
|
|
307
|
+
* and UI block generation.
|
|
308
|
+
*
|
|
309
|
+
* @param presenter - A Presenter instance
|
|
310
|
+
* @returns `this` for chaining
|
|
311
|
+
*/
|
|
312
|
+
returns(presenter) {
|
|
313
|
+
this._returns = presenter;
|
|
314
|
+
return this;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Add capability tags for selective tool exposure.
|
|
318
|
+
*
|
|
319
|
+
* Tags are accumulated — calling `.tags()` multiple times
|
|
320
|
+
* (or inheriting from a router) appends rather than replaces.
|
|
321
|
+
*
|
|
322
|
+
* @param tags - Tag strings for filtering
|
|
323
|
+
* @returns `this` for chaining
|
|
324
|
+
*/
|
|
325
|
+
tags(...tags) {
|
|
326
|
+
this._tags.push(...tags);
|
|
327
|
+
return this;
|
|
328
|
+
}
|
|
329
|
+
// ── Semantic Overrides ───────────────────────────────
|
|
330
|
+
/** Override: mark this tool as read-only (no side effects) */
|
|
331
|
+
readOnly() {
|
|
332
|
+
this._readOnly = true;
|
|
333
|
+
return this;
|
|
334
|
+
}
|
|
335
|
+
/** Override: mark this tool as destructive (irreversible) */
|
|
336
|
+
destructive() {
|
|
337
|
+
this._destructive = true;
|
|
338
|
+
return this;
|
|
339
|
+
}
|
|
340
|
+
/** Override: mark this tool as idempotent (safe to retry) */
|
|
341
|
+
idempotent() {
|
|
342
|
+
this._idempotent = true;
|
|
343
|
+
return this;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Enable TOON-formatted descriptions for token optimization.
|
|
347
|
+
*
|
|
348
|
+
* @returns `this` for chaining
|
|
349
|
+
*/
|
|
350
|
+
toonDescription() {
|
|
351
|
+
this._toonMode = true;
|
|
352
|
+
return this;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Set MCP tool annotations.
|
|
356
|
+
*
|
|
357
|
+
* @param a - Annotation key-value pairs
|
|
358
|
+
* @returns `this` for chaining
|
|
359
|
+
*/
|
|
360
|
+
annotations(a) {
|
|
361
|
+
this._annotations = a;
|
|
362
|
+
return this;
|
|
363
|
+
}
|
|
364
|
+
// ── State Sync (Fluent) ──────────────────────────────
|
|
365
|
+
/**
|
|
366
|
+
* Declare glob patterns invalidated when this tool succeeds.
|
|
367
|
+
*
|
|
368
|
+
* @param patterns - Glob patterns (e.g. `'sprints.*'`, `'tasks.*'`)
|
|
369
|
+
* @returns `this` for chaining
|
|
370
|
+
*/
|
|
371
|
+
invalidates(...patterns) {
|
|
372
|
+
this._invalidatesPatterns.push(...patterns);
|
|
373
|
+
return this;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Mark this tool's data as immutable (safe to cache forever).
|
|
377
|
+
*
|
|
378
|
+
* @returns `this` for chaining
|
|
379
|
+
*/
|
|
380
|
+
cached() {
|
|
381
|
+
this._cacheControl = 'immutable';
|
|
382
|
+
return this;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Mark this tool's data as volatile (never cache).
|
|
386
|
+
*
|
|
387
|
+
* @returns `this` for chaining
|
|
388
|
+
*/
|
|
389
|
+
stale() {
|
|
390
|
+
this._cacheControl = 'no-store';
|
|
391
|
+
return this;
|
|
392
|
+
}
|
|
393
|
+
// ── Runtime Guards (Fluent) ──────────────────────────
|
|
394
|
+
/**
|
|
395
|
+
* Set concurrency limits for this tool (Semaphore + Queue pattern).
|
|
396
|
+
*
|
|
397
|
+
* @param config - Concurrency configuration
|
|
398
|
+
* @returns `this` for chaining
|
|
399
|
+
*/
|
|
400
|
+
concurrency(config) {
|
|
401
|
+
this._concurrency = config;
|
|
402
|
+
return this;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Set maximum payload size for tool responses (Egress Guard).
|
|
406
|
+
*
|
|
407
|
+
* @param bytes - Maximum payload size in bytes
|
|
408
|
+
* @returns `this` for chaining
|
|
409
|
+
*/
|
|
410
|
+
egress(bytes) {
|
|
411
|
+
this._egressMaxBytes = bytes;
|
|
412
|
+
return this;
|
|
413
|
+
}
|
|
414
|
+
// ── Terminal: handle() ───────────────────────────────
|
|
415
|
+
/**
|
|
416
|
+
* Set the handler and build the tool — the terminal step.
|
|
417
|
+
*
|
|
418
|
+
* The handler receives `(input, ctx)` with fully typed `TInput` and `TCtx`.
|
|
419
|
+
* **Implicit `success()` wrapping**: if the handler returns raw data
|
|
420
|
+
* (not a `ToolResponse`), the framework wraps it with `success()`.
|
|
421
|
+
*
|
|
422
|
+
* @param handler - Async function receiving typed `(input, ctx)`
|
|
423
|
+
* @returns A `GroupedToolBuilder` ready for registration
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* const getProject = f.query('projects.get')
|
|
428
|
+
* .describe('Get a project by ID')
|
|
429
|
+
* .withString('project_id', 'The exact project ID')
|
|
430
|
+
* .handle(async (input, ctx) => {
|
|
431
|
+
* return await ctx.db.projects.findUnique({ where: { id: input.project_id } });
|
|
432
|
+
* });
|
|
433
|
+
* ```
|
|
434
|
+
*/
|
|
435
|
+
handle(handler) {
|
|
436
|
+
return this._build(handler);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Alias for `.handle()` — for backward compatibility.
|
|
440
|
+
* @internal
|
|
441
|
+
*/
|
|
442
|
+
resolve(handler) {
|
|
443
|
+
// Adapt { input, ctx } signature to (input, ctx)
|
|
444
|
+
return this._build((input, ctx) => handler({ input, ctx }));
|
|
445
|
+
}
|
|
446
|
+
// ── Internal Build ───────────────────────────────────
|
|
447
|
+
/** @internal */
|
|
448
|
+
_build(handler) {
|
|
449
|
+
// Build accumulated with* params into ZodObject
|
|
450
|
+
if (Object.keys(this._withParams).length > 0) {
|
|
451
|
+
this._inputSchema = z.object(this._withParams);
|
|
452
|
+
}
|
|
453
|
+
// Parse name: 'domain.action' → tool='domain', action='action'
|
|
454
|
+
const dotIndex = this._name.indexOf('.');
|
|
455
|
+
const toolName = dotIndex > 0 ? this._name.slice(0, dotIndex) : this._name;
|
|
456
|
+
const actionName = dotIndex > 0 ? this._name.slice(dotIndex + 1) : 'default';
|
|
457
|
+
// Compile description: instructions + description
|
|
458
|
+
const descParts = [];
|
|
459
|
+
if (this._instructions) {
|
|
460
|
+
descParts.push(`[INSTRUCTIONS] ${this._instructions}`);
|
|
461
|
+
}
|
|
462
|
+
if (this._description) {
|
|
463
|
+
descParts.push(this._description);
|
|
464
|
+
}
|
|
465
|
+
const compiledDescription = descParts.length > 0 ? descParts.join('\n\n') : undefined;
|
|
466
|
+
// Resolve semantic defaults + overrides
|
|
467
|
+
const readOnly = this._readOnly ?? this._semanticDefaults.readOnly;
|
|
468
|
+
const destructive = this._destructive ?? this._semanticDefaults.destructive;
|
|
469
|
+
const idempotent = this._idempotent ?? this._semanticDefaults.idempotent;
|
|
470
|
+
// Wrap handler: (input, ctx) → (ctx, args)
|
|
471
|
+
const resolvedHandler = handler;
|
|
472
|
+
const wrappedHandler = async (ctx, args) => {
|
|
473
|
+
const result = await resolvedHandler(args, ctx);
|
|
474
|
+
// Auto-wrap non-ToolResponse results (implicit success)
|
|
475
|
+
if (typeof result === 'object' &&
|
|
476
|
+
result !== null &&
|
|
477
|
+
'content' in result &&
|
|
478
|
+
Array.isArray(result.content)) {
|
|
479
|
+
return result;
|
|
480
|
+
}
|
|
481
|
+
// Implicit success() — the dev just returns raw data!
|
|
482
|
+
return success(result);
|
|
483
|
+
};
|
|
484
|
+
// Build via GroupedToolBuilder for consistency with existing pipeline
|
|
485
|
+
const builder = new GroupedToolBuilder(toolName);
|
|
486
|
+
if (compiledDescription)
|
|
487
|
+
builder.description(compiledDescription);
|
|
488
|
+
if (this._tags.length > 0)
|
|
489
|
+
builder.tags(...this._tags);
|
|
490
|
+
if (this._toonMode)
|
|
491
|
+
builder.toonDescription();
|
|
492
|
+
if (this._annotations)
|
|
493
|
+
builder.annotations(this._annotations);
|
|
494
|
+
// Propagate state sync hints
|
|
495
|
+
if (this._invalidatesPatterns.length > 0) {
|
|
496
|
+
builder.invalidates(...this._invalidatesPatterns);
|
|
497
|
+
}
|
|
498
|
+
if (this._cacheControl) {
|
|
499
|
+
this._cacheControl === 'immutable' ? builder.cached() : builder.stale();
|
|
500
|
+
}
|
|
501
|
+
// Propagate runtime guards
|
|
502
|
+
if (this._concurrency) {
|
|
503
|
+
builder.concurrency(this._concurrency);
|
|
504
|
+
}
|
|
505
|
+
if (this._egressMaxBytes !== undefined) {
|
|
506
|
+
builder.maxPayloadBytes(this._egressMaxBytes);
|
|
507
|
+
}
|
|
508
|
+
// Apply middleware
|
|
509
|
+
for (const mw of this._middlewares) {
|
|
510
|
+
builder.use(mw);
|
|
511
|
+
}
|
|
512
|
+
// Register the single action
|
|
513
|
+
builder.action({
|
|
514
|
+
name: actionName,
|
|
515
|
+
handler: wrappedHandler,
|
|
516
|
+
...(this._inputSchema ? { schema: this._inputSchema } : {}),
|
|
517
|
+
...(readOnly !== undefined ? { readOnly } : {}),
|
|
518
|
+
...(destructive !== undefined ? { destructive } : {}),
|
|
519
|
+
...(idempotent !== undefined ? { idempotent } : {}),
|
|
520
|
+
...(this._returns ? { returns: this._returns } : {}),
|
|
521
|
+
});
|
|
522
|
+
return builder;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
//# sourceMappingURL=FluentToolBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FluentToolBuilder.js","sourceRoot":"","sources":["../../../src/core/builder/FluentToolBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
*/
|
|
46
46
|
import { type ZodObject, type ZodRawShape } from 'zod';
|
|
47
47
|
import { type Tool as McpTool } from '@modelcontextprotocol/sdk/types.js';
|
|
48
|
-
import { type ToolResponse, type ToolBuilder, type ActionMetadata, type InternalAction, type MiddlewareFn, type ActionConfig } from '../types.js';
|
|
48
|
+
import { type ToolResponse, type ToolBuilder, type ActionMetadata, type InternalAction, type MiddlewareFn, type ActionConfig, type StateSyncHint } from '../types.js';
|
|
49
49
|
import { type DebugObserverFn } from '../../observability/DebugObserver.js';
|
|
50
50
|
import { type FusionTracer } from '../../observability/Tracing.js';
|
|
51
51
|
import { type ProgressSink } from '../execution/ProgressHelper.js';
|
|
@@ -129,12 +129,14 @@ export declare class GroupedToolBuilder<TContext = void, TCommon extends Record<
|
|
|
129
129
|
private _hasFlat;
|
|
130
130
|
private _hasGroup;
|
|
131
131
|
private _toonMode;
|
|
132
|
+
private _selectEnabled;
|
|
132
133
|
private _frozen;
|
|
133
134
|
private _debug?;
|
|
134
135
|
private _tracer?;
|
|
135
136
|
private _concurrencyGuard?;
|
|
136
137
|
private _egressMaxBytes?;
|
|
137
138
|
private _mutationSerializer?;
|
|
139
|
+
private readonly _stateSyncHints;
|
|
138
140
|
private _cachedTool?;
|
|
139
141
|
private _executionContext?;
|
|
140
142
|
constructor(name: string);
|
|
@@ -263,6 +265,90 @@ export declare class GroupedToolBuilder<TContext = void, TCommon extends Record<
|
|
|
263
265
|
* @see {@link toonSuccess} for TOON-encoded responses
|
|
264
266
|
*/
|
|
265
267
|
toonDescription(): this;
|
|
268
|
+
/**
|
|
269
|
+
* Declare glob patterns invalidated when this tool succeeds.
|
|
270
|
+
*
|
|
271
|
+
* Eliminates manual `stateSync.policies` configuration —
|
|
272
|
+
* the framework auto-collects hints from all builders.
|
|
273
|
+
*
|
|
274
|
+
* @param patterns - Glob patterns (e.g. `'sprints.*'`, `'tasks.*'`)
|
|
275
|
+
* @returns `this` for chaining
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* createTool('tasks')
|
|
280
|
+
* .invalidates('tasks.*', 'sprints.*')
|
|
281
|
+
* .action({ name: 'update', handler: updateTask });
|
|
282
|
+
* ```
|
|
283
|
+
*
|
|
284
|
+
* @see {@link StateSyncConfig} for centralized configuration
|
|
285
|
+
*/
|
|
286
|
+
invalidates(...patterns: string[]): this;
|
|
287
|
+
/**
|
|
288
|
+
* Mark this tool's data as immutable (safe to cache forever).
|
|
289
|
+
*
|
|
290
|
+
* Use for reference data: countries, currencies, ICD-10 codes.
|
|
291
|
+
* Equivalent to `cacheControl: 'immutable'` in manual policies.
|
|
292
|
+
*
|
|
293
|
+
* @returns `this` for chaining
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```typescript
|
|
297
|
+
* createTool('countries')
|
|
298
|
+
* .cached()
|
|
299
|
+
* .action({ name: 'list', readOnly: true, handler: listCountries });
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
cached(): this;
|
|
303
|
+
/**
|
|
304
|
+
* Mark this tool's data as volatile (never cache).
|
|
305
|
+
*
|
|
306
|
+
* Equivalent to `cacheControl: 'no-store'` in manual policies.
|
|
307
|
+
* Use for dynamic data that changes frequently.
|
|
308
|
+
*
|
|
309
|
+
* @returns `this` for chaining
|
|
310
|
+
*/
|
|
311
|
+
stale(): this;
|
|
312
|
+
/** @internal */
|
|
313
|
+
private _setCacheDirective;
|
|
314
|
+
/**
|
|
315
|
+
* Enable `_select` reflection for context window optimization.
|
|
316
|
+
*
|
|
317
|
+
* When enabled, actions that use a Presenter with a Zod schema
|
|
318
|
+
* expose an optional `_select` parameter in the input schema.
|
|
319
|
+
* The AI can send `_select: ['status', 'amount']` to receive
|
|
320
|
+
* only the specified top-level fields in the data payload,
|
|
321
|
+
* reducing context window usage without developer effort.
|
|
322
|
+
*
|
|
323
|
+
* **Disabled by default** — opt-in to avoid changing existing
|
|
324
|
+
* tool schemas.
|
|
325
|
+
*
|
|
326
|
+
* **Late Guillotine**: UI blocks, system rules, and action
|
|
327
|
+
* suggestions are always computed with the **full** validated
|
|
328
|
+
* data. Only the wire-facing data block is filtered.
|
|
329
|
+
*
|
|
330
|
+
* **Shallow (top-level only)**: Nested objects are returned
|
|
331
|
+
* whole. If the AI selects `'user'`, it gets the entire `user`
|
|
332
|
+
* object. No recursive GraphQL-style traversal.
|
|
333
|
+
*
|
|
334
|
+
* @returns `this` for chaining
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* ```typescript
|
|
338
|
+
* createTool<AppContext>('invoices')
|
|
339
|
+
* .enableSelect() // Expose _select in input schema
|
|
340
|
+
* .action({
|
|
341
|
+
* name: 'get',
|
|
342
|
+
* returns: InvoicePresenter,
|
|
343
|
+
* handler: async (ctx, args) => ctx.db.invoices.findUnique(args.id),
|
|
344
|
+
* });
|
|
345
|
+
* // AI sends: { action: 'get', id: '123', _select: ['status'] }
|
|
346
|
+
* // Returns: { status: 'paid' } instead of full invoice
|
|
347
|
+
* ```
|
|
348
|
+
*
|
|
349
|
+
* @see {@link Presenter.getSchemaKeys} for introspection
|
|
350
|
+
*/
|
|
351
|
+
enableSelect(): this;
|
|
266
352
|
/**
|
|
267
353
|
* Set concurrency limits for this tool (Semaphore + Queue pattern).
|
|
268
354
|
*
|
|
@@ -589,6 +675,10 @@ export declare class GroupedToolBuilder<TContext = void, TCommon extends Record<
|
|
|
589
675
|
* @returns The common Zod schema, or undefined if not set
|
|
590
676
|
*/
|
|
591
677
|
getCommonSchema(): ZodObject<ZodRawShape> | undefined;
|
|
678
|
+
/** Check if `_select` reflection is enabled. Used by the Exposition Compiler. */
|
|
679
|
+
getSelectEnabled(): boolean;
|
|
680
|
+
/** Get per-action state sync hints for auto-policy generation. */
|
|
681
|
+
getStateSyncHints(): ReadonlyMap<string, StateSyncHint>;
|
|
592
682
|
/**
|
|
593
683
|
* Preview the exact MCP protocol payload that the LLM will receive.
|
|
594
684
|
*
|