@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.
Files changed (172) hide show
  1. package/dist/cli/fusion.d.ts +3 -0
  2. package/dist/cli/fusion.d.ts.map +1 -1
  3. package/dist/cli/fusion.js +125 -3
  4. package/dist/cli/fusion.js.map +1 -1
  5. package/dist/cli/templates/config.js +3 -3
  6. package/dist/cli/templates/config.js.map +1 -1
  7. package/dist/cli/templates/constants.d.ts +1 -1
  8. package/dist/cli/templates/constants.d.ts.map +1 -1
  9. package/dist/cli/templates/constants.js +1 -1
  10. package/dist/cli/templates/constants.js.map +1 -1
  11. package/dist/cli/templates/core.js +5 -5
  12. package/dist/cli/templates/middleware.d.ts +1 -1
  13. package/dist/cli/templates/middleware.d.ts.map +1 -1
  14. package/dist/cli/templates/middleware.js +16 -13
  15. package/dist/cli/templates/middleware.js.map +1 -1
  16. package/dist/cli/templates/readme.d.ts.map +1 -1
  17. package/dist/cli/templates/readme.js +14 -18
  18. package/dist/cli/templates/readme.js.map +1 -1
  19. package/dist/cli/templates/tools.d.ts +4 -0
  20. package/dist/cli/templates/tools.d.ts.map +1 -1
  21. package/dist/cli/templates/tools.js +26 -29
  22. package/dist/cli/templates/tools.js.map +1 -1
  23. package/dist/cli/templates/vectors/database.d.ts.map +1 -1
  24. package/dist/cli/templates/vectors/database.js +14 -19
  25. package/dist/cli/templates/vectors/database.js.map +1 -1
  26. package/dist/cli/templates/vectors/oauth.d.ts.map +1 -1
  27. package/dist/cli/templates/vectors/oauth.js +4 -5
  28. package/dist/cli/templates/vectors/oauth.js.map +1 -1
  29. package/dist/cli/templates/vectors/openapi.js +2 -2
  30. package/dist/cli/templates/vectors/workflow.js +1 -1
  31. package/dist/cli/templates/vectors/workflow.js.map +1 -1
  32. package/dist/client/FusionClient.d.ts +55 -0
  33. package/dist/client/FusionClient.d.ts.map +1 -1
  34. package/dist/client/FusionClient.js +30 -0
  35. package/dist/client/FusionClient.js.map +1 -1
  36. package/dist/client/index.d.ts +1 -1
  37. package/dist/client/index.d.ts.map +1 -1
  38. package/dist/client/index.js.map +1 -1
  39. package/dist/core/builder/ActionGroupBuilder.d.ts +86 -46
  40. package/dist/core/builder/ActionGroupBuilder.d.ts.map +1 -1
  41. package/dist/core/builder/ActionGroupBuilder.js +68 -26
  42. package/dist/core/builder/ActionGroupBuilder.js.map +1 -1
  43. package/dist/core/builder/ErrorBuilder.d.ts +59 -0
  44. package/dist/core/builder/ErrorBuilder.d.ts.map +1 -0
  45. package/dist/core/builder/ErrorBuilder.js +99 -0
  46. package/dist/core/builder/ErrorBuilder.js.map +1 -0
  47. package/dist/core/builder/FluentRouter.d.ts +91 -0
  48. package/dist/core/builder/FluentRouter.d.ts.map +1 -0
  49. package/dist/core/builder/FluentRouter.js +121 -0
  50. package/dist/core/builder/FluentRouter.js.map +1 -0
  51. package/dist/core/builder/FluentSchemaHelpers.d.ts +237 -0
  52. package/dist/core/builder/FluentSchemaHelpers.d.ts.map +1 -0
  53. package/dist/core/builder/FluentSchemaHelpers.js +227 -0
  54. package/dist/core/builder/FluentSchemaHelpers.js.map +1 -0
  55. package/dist/core/builder/FluentToolBuilder.d.ts +347 -0
  56. package/dist/core/builder/FluentToolBuilder.d.ts.map +1 -0
  57. package/dist/core/builder/FluentToolBuilder.js +525 -0
  58. package/dist/core/builder/FluentToolBuilder.js.map +1 -0
  59. package/dist/core/builder/GroupedToolBuilder.d.ts +91 -1
  60. package/dist/core/builder/GroupedToolBuilder.d.ts.map +1 -1
  61. package/dist/core/builder/GroupedToolBuilder.js +122 -4
  62. package/dist/core/builder/GroupedToolBuilder.js.map +1 -1
  63. package/dist/core/builder/ToolDefinitionCompiler.d.ts +1 -0
  64. package/dist/core/builder/ToolDefinitionCompiler.d.ts.map +1 -1
  65. package/dist/core/builder/ToolDefinitionCompiler.js +1 -1
  66. package/dist/core/builder/ToolDefinitionCompiler.js.map +1 -1
  67. package/dist/core/builder/index.d.ts +4 -0
  68. package/dist/core/builder/index.d.ts.map +1 -1
  69. package/dist/core/builder/index.js +7 -0
  70. package/dist/core/builder/index.js.map +1 -1
  71. package/dist/core/execution/EgressGuard.js +1 -1
  72. package/dist/core/execution/EgressGuard.js.map +1 -1
  73. package/dist/core/execution/ExecutionPipeline.d.ts +8 -2
  74. package/dist/core/execution/ExecutionPipeline.d.ts.map +1 -1
  75. package/dist/core/execution/ExecutionPipeline.js +18 -9
  76. package/dist/core/execution/ExecutionPipeline.js.map +1 -1
  77. package/dist/core/execution/PipelineHooks.d.ts +0 -6
  78. package/dist/core/execution/PipelineHooks.d.ts.map +1 -1
  79. package/dist/core/execution/PipelineHooks.js +7 -3
  80. package/dist/core/execution/PipelineHooks.js.map +1 -1
  81. package/dist/core/index.d.ts +5 -7
  82. package/dist/core/index.d.ts.map +1 -1
  83. package/dist/core/index.js +2 -4
  84. package/dist/core/index.js.map +1 -1
  85. package/dist/core/initFusion.d.ts +119 -87
  86. package/dist/core/initFusion.d.ts.map +1 -1
  87. package/dist/core/initFusion.js +56 -66
  88. package/dist/core/initFusion.js.map +1 -1
  89. package/dist/core/registry/ToolRegistry.d.ts +1 -1
  90. package/dist/core/registry/ToolRegistry.d.ts.map +1 -1
  91. package/dist/core/registry/ToolRegistry.js +1 -1
  92. package/dist/core/registry/ToolRegistry.js.map +1 -1
  93. package/dist/core/schema/SchemaGenerator.d.ts +1 -1
  94. package/dist/core/schema/SchemaGenerator.d.ts.map +1 -1
  95. package/dist/core/schema/SchemaGenerator.js +38 -1
  96. package/dist/core/schema/SchemaGenerator.js.map +1 -1
  97. package/dist/core/types.d.ts +19 -0
  98. package/dist/core/types.d.ts.map +1 -1
  99. package/dist/exposition/ExpositionCompiler.d.ts.map +1 -1
  100. package/dist/exposition/ExpositionCompiler.js +25 -2
  101. package/dist/exposition/ExpositionCompiler.js.map +1 -1
  102. package/dist/index.d.ts +3 -3
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +4 -2
  105. package/dist/index.js.map +1 -1
  106. package/dist/introspection/BehaviorDigest.d.ts +2 -2
  107. package/dist/introspection/BehaviorDigest.d.ts.map +1 -1
  108. package/dist/introspection/BehaviorDigest.js +38 -36
  109. package/dist/introspection/BehaviorDigest.js.map +1 -1
  110. package/dist/introspection/CapabilityLockfile.d.ts +2 -2
  111. package/dist/introspection/CapabilityLockfile.d.ts.map +1 -1
  112. package/dist/introspection/CapabilityLockfile.js +9 -9
  113. package/dist/introspection/CapabilityLockfile.js.map +1 -1
  114. package/dist/introspection/CryptoAttestation.d.ts.map +1 -1
  115. package/dist/introspection/CryptoAttestation.js +27 -36
  116. package/dist/introspection/CryptoAttestation.js.map +1 -1
  117. package/dist/introspection/ToolContract.d.ts +2 -2
  118. package/dist/introspection/ToolContract.d.ts.map +1 -1
  119. package/dist/introspection/ToolContract.js +9 -9
  120. package/dist/introspection/ToolContract.js.map +1 -1
  121. package/dist/introspection/canonicalize.d.ts +16 -1
  122. package/dist/introspection/canonicalize.d.ts.map +1 -1
  123. package/dist/introspection/canonicalize.js +24 -3
  124. package/dist/introspection/canonicalize.js.map +1 -1
  125. package/dist/presenter/PostProcessor.d.ts +4 -2
  126. package/dist/presenter/PostProcessor.d.ts.map +1 -1
  127. package/dist/presenter/PostProcessor.js +10 -10
  128. package/dist/presenter/PostProcessor.js.map +1 -1
  129. package/dist/presenter/Presenter.d.ts +112 -6
  130. package/dist/presenter/Presenter.d.ts.map +1 -1
  131. package/dist/presenter/Presenter.js +134 -40
  132. package/dist/presenter/Presenter.js.map +1 -1
  133. package/dist/presenter/SelectUtils.d.ts +78 -0
  134. package/dist/presenter/SelectUtils.d.ts.map +1 -0
  135. package/dist/presenter/SelectUtils.js +141 -0
  136. package/dist/presenter/SelectUtils.js.map +1 -0
  137. package/dist/presenter/index.d.ts +3 -0
  138. package/dist/presenter/index.d.ts.map +1 -1
  139. package/dist/presenter/index.js +6 -0
  140. package/dist/presenter/index.js.map +1 -1
  141. package/dist/presenter/suggest.d.ts +39 -0
  142. package/dist/presenter/suggest.d.ts.map +1 -0
  143. package/dist/presenter/suggest.js +41 -0
  144. package/dist/presenter/suggest.js.map +1 -0
  145. package/dist/presenter/typeHelpers.d.ts +147 -0
  146. package/dist/presenter/typeHelpers.d.ts.map +1 -0
  147. package/dist/presenter/typeHelpers.js +152 -0
  148. package/dist/presenter/typeHelpers.js.map +1 -0
  149. package/dist/prompt/FluentPromptBuilder.d.ts +155 -0
  150. package/dist/prompt/FluentPromptBuilder.d.ts.map +1 -0
  151. package/dist/prompt/FluentPromptBuilder.js +193 -0
  152. package/dist/prompt/FluentPromptBuilder.js.map +1 -0
  153. package/dist/prompt/index.d.ts +1 -0
  154. package/dist/prompt/index.d.ts.map +1 -1
  155. package/dist/prompt/index.js +1 -0
  156. package/dist/prompt/index.js.map +1 -1
  157. package/dist/server/DevServer.js +8 -8
  158. package/dist/server/DevServer.js.map +1 -1
  159. package/dist/server/ServerAttachment.d.ts +1 -1
  160. package/dist/server/ServerAttachment.d.ts.map +1 -1
  161. package/dist/server/ServerAttachment.js +57 -4
  162. package/dist/server/ServerAttachment.js.map +1 -1
  163. package/dist/state-sync/ResponseDecorator.d.ts +1 -1
  164. package/dist/state-sync/StateSyncBuilder.d.ts +75 -0
  165. package/dist/state-sync/StateSyncBuilder.d.ts.map +1 -0
  166. package/dist/state-sync/StateSyncBuilder.js +123 -0
  167. package/dist/state-sync/StateSyncBuilder.js.map +1 -0
  168. package/dist/state-sync/index.d.ts +1 -0
  169. package/dist/state-sync/index.d.ts.map +1 -1
  170. package/dist/state-sync/index.js +1 -0
  171. package/dist/state-sync/index.js.map +1 -1
  172. 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
  *