@vinkius-core/mcp-fusion 2.7.0 → 2.8.1

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 (68) hide show
  1. package/dist/cli/fusion.d.ts +101 -0
  2. package/dist/cli/fusion.d.ts.map +1 -0
  3. package/dist/cli/fusion.js +333 -0
  4. package/dist/cli/fusion.js.map +1 -0
  5. package/dist/index.d.ts +41 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +22 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/introspection/BehaviorDigest.d.ts +112 -0
  10. package/dist/introspection/BehaviorDigest.d.ts.map +1 -0
  11. package/dist/introspection/BehaviorDigest.js +147 -0
  12. package/dist/introspection/BehaviorDigest.js.map +1 -0
  13. package/dist/introspection/CapabilityLockfile.d.ts +261 -0
  14. package/dist/introspection/CapabilityLockfile.d.ts.map +1 -0
  15. package/dist/introspection/CapabilityLockfile.js +392 -0
  16. package/dist/introspection/CapabilityLockfile.js.map +1 -0
  17. package/dist/introspection/ContractAwareSelfHealing.d.ts +90 -0
  18. package/dist/introspection/ContractAwareSelfHealing.d.ts.map +1 -0
  19. package/dist/introspection/ContractAwareSelfHealing.js +132 -0
  20. package/dist/introspection/ContractAwareSelfHealing.js.map +1 -0
  21. package/dist/introspection/ContractDiff.d.ts +91 -0
  22. package/dist/introspection/ContractDiff.d.ts.map +1 -0
  23. package/dist/introspection/ContractDiff.js +466 -0
  24. package/dist/introspection/ContractDiff.js.map +1 -0
  25. package/dist/introspection/CryptoAttestation.d.ts +143 -0
  26. package/dist/introspection/CryptoAttestation.d.ts.map +1 -0
  27. package/dist/introspection/CryptoAttestation.js +194 -0
  28. package/dist/introspection/CryptoAttestation.js.map +1 -0
  29. package/dist/introspection/EntitlementScanner.d.ts +177 -0
  30. package/dist/introspection/EntitlementScanner.d.ts.map +1 -0
  31. package/dist/introspection/EntitlementScanner.js +459 -0
  32. package/dist/introspection/EntitlementScanner.js.map +1 -0
  33. package/dist/introspection/GovernanceObserver.d.ts +88 -0
  34. package/dist/introspection/GovernanceObserver.d.ts.map +1 -0
  35. package/dist/introspection/GovernanceObserver.js +132 -0
  36. package/dist/introspection/GovernanceObserver.js.map +1 -0
  37. package/dist/introspection/SemanticProbe.d.ts +207 -0
  38. package/dist/introspection/SemanticProbe.d.ts.map +1 -0
  39. package/dist/introspection/SemanticProbe.js +255 -0
  40. package/dist/introspection/SemanticProbe.js.map +1 -0
  41. package/dist/introspection/TokenEconomics.d.ts +210 -0
  42. package/dist/introspection/TokenEconomics.d.ts.map +1 -0
  43. package/dist/introspection/TokenEconomics.js +286 -0
  44. package/dist/introspection/TokenEconomics.js.map +1 -0
  45. package/dist/introspection/ToolContract.d.ts +161 -0
  46. package/dist/introspection/ToolContract.d.ts.map +1 -0
  47. package/dist/introspection/ToolContract.js +192 -0
  48. package/dist/introspection/ToolContract.js.map +1 -0
  49. package/dist/introspection/canonicalize.d.ts +20 -0
  50. package/dist/introspection/canonicalize.d.ts.map +1 -0
  51. package/dist/introspection/canonicalize.js +51 -0
  52. package/dist/introspection/canonicalize.js.map +1 -0
  53. package/dist/introspection/index.d.ts +20 -0
  54. package/dist/introspection/index.d.ts.map +1 -1
  55. package/dist/introspection/index.js +20 -0
  56. package/dist/introspection/index.js.map +1 -1
  57. package/dist/observability/DebugObserver.d.ts +26 -1
  58. package/dist/observability/DebugObserver.d.ts.map +1 -1
  59. package/dist/observability/DebugObserver.js +8 -1
  60. package/dist/observability/DebugObserver.js.map +1 -1
  61. package/dist/observability/index.d.ts +1 -1
  62. package/dist/observability/index.d.ts.map +1 -1
  63. package/dist/observability/index.js.map +1 -1
  64. package/dist/server/ServerAttachment.d.ts +41 -0
  65. package/dist/server/ServerAttachment.d.ts.map +1 -1
  66. package/dist/server/ServerAttachment.js +25 -1
  67. package/dist/server/ServerAttachment.js.map +1 -1
  68. package/package.json +8 -1
@@ -0,0 +1,210 @@
1
+ /**
2
+ * TokenEconomics — Cognitive Overload Detection
3
+ *
4
+ * **Evolution 3: Token Economics**
5
+ *
6
+ * Profiles the token density and context spread of MCP tool
7
+ * responses to detect cognitive overload scenarios where the
8
+ * LLM's working memory is flooded by verbose tool output,
9
+ * evicting system rules and degrading reasoning quality.
10
+ *
11
+ * **Key insight**: An MCP tool that returns 50KB of JSON per
12
+ * call will rapidly exhaust the context window. If that output
13
+ * isn't constrained by `agentLimit` or `egressMaxBytes`, the
14
+ * system rules injected by the Presenter's `addRules()` will
15
+ * be pushed out of the LLM's attention window — silently
16
+ * degrading behavioral correctness.
17
+ *
18
+ * This module provides:
19
+ *
20
+ * 1. **Static analysis**: Estimate token density from Presenter
21
+ * schema and guardrail configuration (zero-cost at runtime).
22
+ *
23
+ * 2. **Runtime profiling**: Measure actual token counts of
24
+ * response blocks after Presenter rendering (opt-in).
25
+ *
26
+ * 3. **Overload classification**: Classify responses into
27
+ * risk levels based on configurable thresholds.
28
+ *
29
+ * 4. **Integration with BehaviorDigest**: Token economics risk
30
+ * level is part of the behavioral contract — changes to
31
+ * the token profile are tracked as contract deltas.
32
+ *
33
+ * Pure-function module for analysis; runtime profiling hooks
34
+ * are designed for zero-overhead when not configured.
35
+ *
36
+ * @module
37
+ */
38
+ /**
39
+ * Token economics analysis for a single tool response.
40
+ */
41
+ export interface TokenAnalysis {
42
+ /** Tool name */
43
+ readonly toolName: string;
44
+ /** Action key, if applicable */
45
+ readonly actionKey: string | null;
46
+ /** Estimated total tokens in the response */
47
+ readonly estimatedTokens: number;
48
+ /** Number of content blocks in the response */
49
+ readonly blockCount: number;
50
+ /** Per-block token breakdown */
51
+ readonly blocks: readonly BlockTokenProfile[];
52
+ /** Overhead tokens (rules, affordances, UI decorators) */
53
+ readonly overheadTokens: number;
54
+ /** Data payload tokens (actual tool output) */
55
+ readonly dataTokens: number;
56
+ /** Overhead-to-data ratio (higher = more overhead) */
57
+ readonly overheadRatio: number;
58
+ /** Risk classification */
59
+ readonly risk: TokenRisk;
60
+ /** Human-readable advisory */
61
+ readonly advisory: string | null;
62
+ }
63
+ /**
64
+ * Token profile for a single content block.
65
+ */
66
+ export interface BlockTokenProfile {
67
+ /** Block type (e.g., 'text', 'resource', 'image') */
68
+ readonly type: string;
69
+ /** Estimated tokens in this block */
70
+ readonly estimatedTokens: number;
71
+ /** Raw byte size */
72
+ readonly bytes: number;
73
+ }
74
+ /**
75
+ * Token risk classification.
76
+ */
77
+ export type TokenRisk = 'low' | 'medium' | 'high' | 'critical';
78
+ /**
79
+ * Thresholds for token risk classification.
80
+ */
81
+ export interface TokenThresholds {
82
+ /** Maximum tokens for 'low' risk (default: 1000) */
83
+ readonly low: number;
84
+ /** Maximum tokens for 'medium' risk (default: 4000) */
85
+ readonly medium: number;
86
+ /** Maximum tokens for 'high' risk (default: 8000) */
87
+ readonly high: number;
88
+ }
89
+ /**
90
+ * Configuration for the token economics profiler.
91
+ */
92
+ export interface TokenEconomicsConfig {
93
+ /** Custom thresholds (defaults provided) */
94
+ readonly thresholds?: Partial<TokenThresholds>;
95
+ /** Whether to emit warnings to debug observer */
96
+ readonly emitWarnings?: boolean;
97
+ /** Maximum acceptable overhead ratio (default: 0.3) */
98
+ readonly maxOverheadRatio?: number;
99
+ }
100
+ /**
101
+ * Static token profile derived from Presenter configuration.
102
+ * Computed once at build time — zero runtime cost.
103
+ */
104
+ export interface StaticTokenProfile {
105
+ /** Tool name */
106
+ readonly toolName: string;
107
+ /** Estimated minimum tokens per response */
108
+ readonly minTokens: number;
109
+ /** Estimated maximum tokens per response (with agentLimit) */
110
+ readonly maxTokens: number;
111
+ /** Whether the maximum is bounded (agentLimit/egressMaxBytes set) */
112
+ readonly bounded: boolean;
113
+ /** Per-field estimated token cost */
114
+ readonly fieldBreakdown: readonly FieldTokenEstimate[];
115
+ /** Risk classification based on max estimate */
116
+ readonly risk: TokenRisk;
117
+ /** Recommendations for reducing token cost */
118
+ readonly recommendations: readonly string[];
119
+ }
120
+ /**
121
+ * Per-field token estimate.
122
+ */
123
+ export interface FieldTokenEstimate {
124
+ /** Field name */
125
+ readonly name: string;
126
+ /** Estimated tokens per occurrence */
127
+ readonly estimatedTokens: number;
128
+ /** Whether this field is a collection/array type */
129
+ readonly isCollection: boolean;
130
+ }
131
+ /**
132
+ * Estimate token count from a string using the ~4 chars/token heuristic.
133
+ *
134
+ * This is a fast approximation suitable for profiling. For precise
135
+ * token counting, use a tokenizer library (tiktoken, etc.).
136
+ *
137
+ * @param text - The text to estimate tokens for
138
+ * @returns Estimated token count
139
+ */
140
+ export declare function estimateTokens(text: string): number;
141
+ /**
142
+ * Estimate tokens for a content block structure (MCP response block).
143
+ *
144
+ * @param block - The content block with `type` and `text` fields
145
+ * @returns Block-level token profile
146
+ */
147
+ export declare function profileBlock(block: {
148
+ type: string;
149
+ text?: string;
150
+ }): BlockTokenProfile;
151
+ /**
152
+ * Profile a complete tool response for token economics.
153
+ *
154
+ * Analyzes all content blocks in a tool response to compute
155
+ * total token usage, overhead ratio, and risk classification.
156
+ *
157
+ * @param toolName - Name of the tool that produced the response
158
+ * @param actionKey - Action key (if applicable)
159
+ * @param blocks - Content blocks from the tool response
160
+ * @param overheadBlocks - Number of blocks that are overhead (rules, UI)
161
+ * @param config - Token economics configuration
162
+ * @returns Complete token analysis
163
+ */
164
+ export declare function profileResponse(toolName: string, actionKey: string | null, blocks: readonly {
165
+ type: string;
166
+ text?: string;
167
+ }[], overheadBlocks?: number, config?: TokenEconomicsConfig): TokenAnalysis;
168
+ /**
169
+ * Compute a static token profile from Presenter metadata.
170
+ *
171
+ * This runs once at manifest compilation time and produces
172
+ * a zero-cost profile that estimates the worst-case token
173
+ * usage for a tool based on its schema and guardrail config.
174
+ *
175
+ * @param toolName - Tool name
176
+ * @param schemaKeys - Presenter schema field names
177
+ * @param agentLimitMax - Maximum items from agentLimit() config
178
+ * @param egressMaxBytes - Maximum bytes from egressMaxBytes() config
179
+ * @returns Static token profile with recommendations
180
+ */
181
+ export declare function computeStaticProfile(toolName: string, schemaKeys: readonly string[], agentLimitMax: number | null, egressMaxBytes: number | null): StaticTokenProfile;
182
+ /**
183
+ * Aggregate static profiles into a server-level summary.
184
+ *
185
+ * @param profiles - All static profiles for the server
186
+ * @returns Server-level token economics summary
187
+ */
188
+ export declare function aggregateProfiles(profiles: readonly StaticTokenProfile[]): ServerTokenSummary;
189
+ /**
190
+ * Server-level token economics summary.
191
+ */
192
+ export interface ServerTokenSummary {
193
+ /** Total number of tools */
194
+ readonly toolCount: number;
195
+ /** Sum of all tools' minimum token estimates */
196
+ readonly totalMinTokens: number;
197
+ /** Sum of all tools' maximum token estimates */
198
+ readonly totalMaxTokens: number;
199
+ /** Number of tools without bounded output */
200
+ readonly unboundedToolCount: number;
201
+ /** Names of unbounded tools */
202
+ readonly unboundedToolNames: readonly string[];
203
+ /** Overall risk classification */
204
+ readonly overallRisk: TokenRisk;
205
+ /** Names of critical-risk tools */
206
+ readonly criticalToolNames: readonly string[];
207
+ /** Aggregated recommendations */
208
+ readonly recommendations: readonly string[];
209
+ }
210
+ //# sourceMappingURL=TokenEconomics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenEconomics.d.ts","sourceRoot":"","sources":["../../src/introspection/TokenEconomics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * TokenEconomics — Cognitive Overload Detection
3
+ *
4
+ * **Evolution 3: Token Economics**
5
+ *
6
+ * Profiles the token density and context spread of MCP tool
7
+ * responses to detect cognitive overload scenarios where the
8
+ * LLM's working memory is flooded by verbose tool output,
9
+ * evicting system rules and degrading reasoning quality.
10
+ *
11
+ * **Key insight**: An MCP tool that returns 50KB of JSON per
12
+ * call will rapidly exhaust the context window. If that output
13
+ * isn't constrained by `agentLimit` or `egressMaxBytes`, the
14
+ * system rules injected by the Presenter's `addRules()` will
15
+ * be pushed out of the LLM's attention window — silently
16
+ * degrading behavioral correctness.
17
+ *
18
+ * This module provides:
19
+ *
20
+ * 1. **Static analysis**: Estimate token density from Presenter
21
+ * schema and guardrail configuration (zero-cost at runtime).
22
+ *
23
+ * 2. **Runtime profiling**: Measure actual token counts of
24
+ * response blocks after Presenter rendering (opt-in).
25
+ *
26
+ * 3. **Overload classification**: Classify responses into
27
+ * risk levels based on configurable thresholds.
28
+ *
29
+ * 4. **Integration with BehaviorDigest**: Token economics risk
30
+ * level is part of the behavioral contract — changes to
31
+ * the token profile are tracked as contract deltas.
32
+ *
33
+ * Pure-function module for analysis; runtime profiling hooks
34
+ * are designed for zero-overhead when not configured.
35
+ *
36
+ * @module
37
+ */
38
+ // ============================================================================
39
+ // Default Thresholds
40
+ // ============================================================================
41
+ const DEFAULT_THRESHOLDS = {
42
+ low: 1000,
43
+ medium: 4000,
44
+ high: 8000,
45
+ };
46
+ const DEFAULT_MAX_OVERHEAD_RATIO = 0.3;
47
+ // ============================================================================
48
+ // Token Estimation
49
+ // ============================================================================
50
+ /**
51
+ * Estimate token count from a string using the ~4 chars/token heuristic.
52
+ *
53
+ * This is a fast approximation suitable for profiling. For precise
54
+ * token counting, use a tokenizer library (tiktoken, etc.).
55
+ *
56
+ * @param text - The text to estimate tokens for
57
+ * @returns Estimated token count
58
+ */
59
+ export function estimateTokens(text) {
60
+ // GPT-family heuristic: ~4 characters per token for English
61
+ // JSON/code tends to be ~3.5 chars/token due to syntax characters
62
+ return Math.ceil(text.length / 3.5);
63
+ }
64
+ /**
65
+ * Estimate tokens for a content block structure (MCP response block).
66
+ *
67
+ * @param block - The content block with `type` and `text` fields
68
+ * @returns Block-level token profile
69
+ */
70
+ export function profileBlock(block) {
71
+ const text = block.text ?? '';
72
+ const bytes = new TextEncoder().encode(text).byteLength;
73
+ const estimatedTokens = estimateTokens(text);
74
+ return {
75
+ type: block.type,
76
+ estimatedTokens,
77
+ bytes,
78
+ };
79
+ }
80
+ // ============================================================================
81
+ // Runtime Profiling
82
+ // ============================================================================
83
+ /**
84
+ * Profile a complete tool response for token economics.
85
+ *
86
+ * Analyzes all content blocks in a tool response to compute
87
+ * total token usage, overhead ratio, and risk classification.
88
+ *
89
+ * @param toolName - Name of the tool that produced the response
90
+ * @param actionKey - Action key (if applicable)
91
+ * @param blocks - Content blocks from the tool response
92
+ * @param overheadBlocks - Number of blocks that are overhead (rules, UI)
93
+ * @param config - Token economics configuration
94
+ * @returns Complete token analysis
95
+ */
96
+ export function profileResponse(toolName, actionKey, blocks, overheadBlocks = 0, config = {}) {
97
+ const thresholds = resolveThresholds(config);
98
+ const blockProfiles = blocks.map(profileBlock);
99
+ const totalTokens = blockProfiles.reduce((sum, b) => sum + b.estimatedTokens, 0);
100
+ // Split tokens into overhead vs data
101
+ const overheadTokens = blockProfiles
102
+ .slice(0, overheadBlocks)
103
+ .reduce((sum, b) => sum + b.estimatedTokens, 0);
104
+ const dataTokens = totalTokens - overheadTokens;
105
+ const overheadRatio = dataTokens > 0 ? overheadTokens / dataTokens : 0;
106
+ const risk = classifyRisk(totalTokens, thresholds);
107
+ const advisory = generateAdvisory(toolName, totalTokens, risk, overheadRatio, config);
108
+ return {
109
+ toolName,
110
+ actionKey,
111
+ estimatedTokens: totalTokens,
112
+ blockCount: blocks.length,
113
+ blocks: blockProfiles,
114
+ overheadTokens,
115
+ dataTokens,
116
+ overheadRatio,
117
+ risk,
118
+ advisory,
119
+ };
120
+ }
121
+ // ============================================================================
122
+ // Static Analysis
123
+ // ============================================================================
124
+ /**
125
+ * Compute a static token profile from Presenter metadata.
126
+ *
127
+ * This runs once at manifest compilation time and produces
128
+ * a zero-cost profile that estimates the worst-case token
129
+ * usage for a tool based on its schema and guardrail config.
130
+ *
131
+ * @param toolName - Tool name
132
+ * @param schemaKeys - Presenter schema field names
133
+ * @param agentLimitMax - Maximum items from agentLimit() config
134
+ * @param egressMaxBytes - Maximum bytes from egressMaxBytes() config
135
+ * @returns Static token profile with recommendations
136
+ */
137
+ export function computeStaticProfile(toolName, schemaKeys, agentLimitMax, egressMaxBytes) {
138
+ // Estimate per-field token cost
139
+ const fieldBreakdown = schemaKeys.map(name => ({
140
+ name,
141
+ estimatedTokens: estimateFieldTokens(name),
142
+ isCollection: name.endsWith('s') || name.includes('list') || name.includes('items'),
143
+ }));
144
+ // Base token cost: field names + structure + JSON overhead
145
+ const baseTokens = fieldBreakdown.reduce((sum, f) => sum + f.estimatedTokens, 0);
146
+ // Minimum: one item with all fields
147
+ const minTokens = baseTokens + 20; // JSON structure overhead
148
+ // Maximum: bounded by egressMaxBytes, agentLimit, or worst-case estimate
149
+ const { maxTokens, bounded } = computeBounds(baseTokens, agentLimitMax, egressMaxBytes);
150
+ const risk = classifyRisk(maxTokens, DEFAULT_THRESHOLDS);
151
+ const recommendations = buildRecommendations(toolName, bounded, risk, schemaKeys, agentLimitMax, fieldBreakdown);
152
+ return {
153
+ toolName,
154
+ minTokens,
155
+ maxTokens,
156
+ bounded,
157
+ fieldBreakdown,
158
+ risk,
159
+ recommendations,
160
+ };
161
+ }
162
+ /**
163
+ * Aggregate static profiles into a server-level summary.
164
+ *
165
+ * @param profiles - All static profiles for the server
166
+ * @returns Server-level token economics summary
167
+ */
168
+ export function aggregateProfiles(profiles) {
169
+ const totalMinTokens = profiles.reduce((sum, p) => sum + p.minTokens, 0);
170
+ const totalMaxTokens = profiles.reduce((sum, p) => sum + p.maxTokens, 0);
171
+ const unboundedTools = profiles.filter(p => !p.bounded);
172
+ const criticalTools = profiles.filter(p => p.risk === 'critical');
173
+ const highRiskTools = profiles.filter(p => p.risk === 'high');
174
+ const overallRisk = criticalTools.length > 0
175
+ ? 'critical'
176
+ : highRiskTools.length > 0
177
+ ? 'high'
178
+ : unboundedTools.length > 0
179
+ ? 'medium'
180
+ : 'low';
181
+ return {
182
+ toolCount: profiles.length,
183
+ totalMinTokens,
184
+ totalMaxTokens,
185
+ unboundedToolCount: unboundedTools.length,
186
+ unboundedToolNames: unboundedTools.map(p => p.toolName),
187
+ overallRisk,
188
+ criticalToolNames: criticalTools.map(p => p.toolName),
189
+ recommendations: [
190
+ ...criticalTools.flatMap(p => p.recommendations.map(r => `[${p.toolName}] ${r}`)),
191
+ ...highRiskTools.flatMap(p => p.recommendations.map(r => `[${p.toolName}] ${r}`)),
192
+ ],
193
+ };
194
+ }
195
+ // ============================================================================
196
+ // Internals
197
+ // ============================================================================
198
+ /**
199
+ * Classify token risk based on thresholds.
200
+ * @internal
201
+ */
202
+ function classifyRisk(tokens, thresholds) {
203
+ if (tokens <= thresholds.low)
204
+ return 'low';
205
+ if (tokens <= thresholds.medium)
206
+ return 'medium';
207
+ if (tokens <= thresholds.high)
208
+ return 'high';
209
+ return 'critical';
210
+ }
211
+ /**
212
+ * Resolve thresholds with defaults.
213
+ * @internal
214
+ */
215
+ function resolveThresholds(config) {
216
+ return {
217
+ low: config.thresholds?.low ?? DEFAULT_THRESHOLDS.low,
218
+ medium: config.thresholds?.medium ?? DEFAULT_THRESHOLDS.medium,
219
+ high: config.thresholds?.high ?? DEFAULT_THRESHOLDS.high,
220
+ };
221
+ }
222
+ /** Advisory templates keyed by risk level. @internal */
223
+ const ADVISORY_TEMPLATES = {
224
+ critical: (toolName, tokens) => `COGNITIVE OVERLOAD: Tool "${toolName}" response estimated at ${tokens} tokens. ` +
225
+ `This will consume significant context window space. Consider adding agentLimit() or egressMaxBytes().`,
226
+ high: (toolName, tokens) => `HIGH TOKEN DENSITY: Tool "${toolName}" response estimated at ${tokens} tokens. ` +
227
+ `Consider reducing response verbosity or adding pagination.`,
228
+ };
229
+ /**
230
+ * Generate advisory for elevated risk levels.
231
+ * @internal
232
+ */
233
+ function generateAdvisory(toolName, tokens, risk, overheadRatio, config) {
234
+ const template = ADVISORY_TEMPLATES[risk];
235
+ if (template)
236
+ return template(toolName, tokens);
237
+ const maxRatio = config.maxOverheadRatio ?? DEFAULT_MAX_OVERHEAD_RATIO;
238
+ if (overheadRatio > maxRatio) {
239
+ return `OVERHEAD WARNING: Tool "${toolName}" has ${Math.round(overheadRatio * 100)}% overhead ratio. ` +
240
+ `System rules and UI decorators are consuming significant context.`;
241
+ }
242
+ return null;
243
+ }
244
+ /**
245
+ * Compute upper bounds for token estimation.
246
+ * @internal
247
+ */
248
+ function computeBounds(baseTokens, agentLimitMax, egressMaxBytes) {
249
+ // egressMaxBytes provides a hard ceiling
250
+ if (egressMaxBytes !== null)
251
+ return { maxTokens: Math.ceil(egressMaxBytes / 3.5), bounded: true };
252
+ // agentLimit bounds the collection size
253
+ if (agentLimitMax !== null)
254
+ return { maxTokens: baseTokens * agentLimitMax + 50, bounded: true };
255
+ // No bounds — worst-case estimate (100 items)
256
+ return { maxTokens: baseTokens * 100, bounded: false };
257
+ }
258
+ const RECOMMENDATION_RULES = [
259
+ { predicate: (bounded) => !bounded, message: 'Add .agentLimit() to bound collection size' },
260
+ { predicate: (_, risk) => risk === 'critical' || risk === 'high', message: 'Add .egressMaxBytes() to cap payload size' },
261
+ { predicate: (_, __, hasUnbounded) => hasUnbounded, message: 'Collection fields detected without agentLimit — risk of context flooding' },
262
+ { predicate: (_, __, ___, fieldCount) => fieldCount > 15, message: 'Consider reducing schema field count (>15 fields adds cognitive load)' },
263
+ ];
264
+ /**
265
+ * Build recommendations based on profile characteristics.
266
+ * @internal
267
+ */
268
+ function buildRecommendations(_toolName, bounded, risk, schemaKeys, agentLimitMax, fieldBreakdown) {
269
+ const hasUnboundedCollections = fieldBreakdown.some(f => f.isCollection) && agentLimitMax === null;
270
+ return RECOMMENDATION_RULES
271
+ .filter(rule => rule.predicate(bounded, risk, hasUnboundedCollections, schemaKeys.length))
272
+ .map(rule => rule.message);
273
+ }
274
+ /**
275
+ * Estimate tokens for a single field name.
276
+ * Heuristic: field name tokens + value tokens (estimated from name length).
277
+ * @internal
278
+ */
279
+ function estimateFieldTokens(fieldName) {
280
+ // Field name in JSON: "fieldName": → ~name.length/4 + 1
281
+ const nameTokens = Math.ceil(fieldName.length / 4) + 1;
282
+ // Value estimate: assume average 5 tokens per field value
283
+ const valueTokens = 5;
284
+ return nameTokens + valueTokens;
285
+ }
286
+ //# sourceMappingURL=TokenEconomics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenEconomics.js","sourceRoot":"","sources":["../../src/introspection/TokenEconomics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * ToolContract — Behavioral Contract Materialization
3
+ *
4
+ * Unifies the declarative surface (tool names, schemas, tags) with
5
+ * the behavioral contract (Presenter egress schema, system rules,
6
+ * cognitive guardrails, middleware chain, state-sync policies) into
7
+ * a single, serializable, diffable, hashable artifact.
8
+ *
9
+ * **Key insight**: MCP Fusion's Presenter is not just a response
10
+ * formatter — it's a declarative behavioral specification. The Zod
11
+ * schema, system rules, agent limits, and affordances are all
12
+ * explicit, serializable contracts. By materializing them into a
13
+ * `ToolContract`, we create a fingerprint that changes when behavior
14
+ * changes — even if the MCP tool declaration stays identical.
15
+ *
16
+ * **Zero developer effort**: The contract materializes from what the
17
+ * developer has already declared. No annotations, no config, no
18
+ * ceremony — just `materializeContract(builder)`.
19
+ *
20
+ * Pure-function module: no state, no side effects.
21
+ *
22
+ * @module
23
+ */
24
+ import { type ToolBuilder } from '../core/types.js';
25
+ /**
26
+ * Complete behavioral contract for a single tool.
27
+ *
28
+ * Captures both the MCP-visible surface (schema, description) and
29
+ * the behavioral internals (Presenter egress, rules, guardrails,
30
+ * middleware, state-sync, concurrency).
31
+ */
32
+ export interface ToolContract {
33
+ /** Declarative surface visible via MCP `tools/list` */
34
+ readonly surface: ToolSurface;
35
+ /** Behavioral contract extracted from runtime primitives */
36
+ readonly behavior: ToolBehavior;
37
+ /** Token economics profile for cognitive overload detection */
38
+ readonly tokenEconomics: TokenEconomicsProfile;
39
+ /** Handler entitlements from static analysis */
40
+ readonly entitlements: HandlerEntitlements;
41
+ }
42
+ /** Declarative surface — what `tools/list` exposes */
43
+ export interface ToolSurface {
44
+ /** Tool name */
45
+ readonly name: string;
46
+ /** Tool description */
47
+ readonly description: string | undefined;
48
+ /** Tags for selective exposure */
49
+ readonly tags: readonly string[];
50
+ /** Per-action contracts */
51
+ readonly actions: Record<string, ActionContract>;
52
+ /** SHA-256 of canonical JSON Schema */
53
+ readonly inputSchemaDigest: string;
54
+ }
55
+ /** Per-action behavioral contract */
56
+ export interface ActionContract {
57
+ /** Human-readable description */
58
+ readonly description: string | undefined;
59
+ /** Whether this action is destructive */
60
+ readonly destructive: boolean;
61
+ /** Whether this action is idempotent */
62
+ readonly idempotent: boolean;
63
+ /** Whether this action is read-only */
64
+ readonly readOnly: boolean;
65
+ /** Required field names */
66
+ readonly requiredFields: readonly string[];
67
+ /** Presenter name (if MVA pattern is used) */
68
+ readonly presenterName: string | undefined;
69
+ /** SHA-256 of action-level input schema */
70
+ readonly inputSchemaDigest: string;
71
+ /** Whether the action has per-action middleware */
72
+ readonly hasMiddleware: boolean;
73
+ }
74
+ /** Behavioral contract — internal runtime guarantees */
75
+ export interface ToolBehavior {
76
+ /** SHA-256 of Presenter's Zod schema shape (field names + types) */
77
+ readonly egressSchemaDigest: string | null;
78
+ /**
79
+ * Fingerprint of system rules configuration.
80
+ * Static rules: SHA-256 of sorted rule strings.
81
+ * Dynamic rules: `"dynamic:<function-hash>"`.
82
+ */
83
+ readonly systemRulesFingerprint: string;
84
+ /** Cognitive guardrail configuration */
85
+ readonly cognitiveGuardrails: CognitiveGuardrailsContract;
86
+ /** Middleware chain identity */
87
+ readonly middlewareChain: readonly string[];
88
+ /** State sync policy fingerprint */
89
+ readonly stateSyncFingerprint: string | null;
90
+ /** Concurrency configuration fingerprint */
91
+ readonly concurrencyFingerprint: string | null;
92
+ /** Affordance topology — tool names from suggestActions */
93
+ readonly affordanceTopology: readonly string[];
94
+ /** Embedded child Presenter names */
95
+ readonly embeddedPresenters: readonly string[];
96
+ }
97
+ /** Cognitive guardrails configuration snapshot */
98
+ export interface CognitiveGuardrailsContract {
99
+ /** Maximum items before truncation (from Presenter) */
100
+ readonly agentLimitMax: number | null;
101
+ /** Maximum egress payload bytes (from builder) */
102
+ readonly egressMaxBytes: number | null;
103
+ }
104
+ /**
105
+ * Token economics profile for cognitive overload detection.
106
+ *
107
+ * Captures the expected token density of a tool's responses
108
+ * to detect context inflation that would evict system rules
109
+ * from the LLM's working memory.
110
+ */
111
+ export interface TokenEconomicsProfile {
112
+ /** Estimated tokens per field in the egress schema */
113
+ readonly schemaFieldCount: number;
114
+ /** Whether collections may be unbounded (no agentLimit) */
115
+ readonly unboundedCollection: boolean;
116
+ /** Estimated base token overhead (rules + UI + affordances) */
117
+ readonly baseOverheadTokens: number;
118
+ /** Risk level based on configuration */
119
+ readonly inflationRisk: 'low' | 'medium' | 'high' | 'critical';
120
+ }
121
+ /**
122
+ * Handler entitlements derived from static analysis.
123
+ *
124
+ * Tracks I/O capabilities that the handler accesses, forming
125
+ * a security contract. If a read-only tool suddenly imports
126
+ * `fs.writeFileSync`, the entitlement contract breaks.
127
+ */
128
+ export interface HandlerEntitlements {
129
+ /** Whether any handler references filesystem APIs */
130
+ readonly filesystem: boolean;
131
+ /** Whether any handler references network/fetch APIs */
132
+ readonly network: boolean;
133
+ /** Whether any handler references child_process/exec APIs */
134
+ readonly subprocess: boolean;
135
+ /** Whether any handler references crypto/signing APIs */
136
+ readonly crypto: boolean;
137
+ /** Whether any handler uses dynamic code evaluation (eval, Function, vm) */
138
+ readonly codeEvaluation: boolean;
139
+ /** Raw entitlement identifiers for granular diff */
140
+ readonly raw: readonly string[];
141
+ }
142
+ /**
143
+ * Materialize a `ToolContract` from a builder's public API.
144
+ *
145
+ * Extracts all behavioral metadata from the builder's introspection
146
+ * methods without accessing any private internals. This guarantees
147
+ * compatibility with any `ToolBuilder` implementation.
148
+ *
149
+ * @param builder - A registered tool builder
150
+ * @returns A fully materialized `ToolContract`
151
+ */
152
+ export declare function materializeContract<TContext>(builder: ToolBuilder<TContext>): ToolContract;
153
+ /**
154
+ * Compile contracts for all tools in a registry.
155
+ *
156
+ * @param builders - Iterable of all registered tool builders
157
+ * @returns Record mapping tool names to their materialized contracts
158
+ */
159
+ export declare function compileContracts<TContext>(builders: Iterable<ToolBuilder<TContext>>): Record<string, ToolContract>;
160
+ export { sha256, canonicalize } from './canonicalize.js';
161
+ //# sourceMappingURL=ToolContract.d.ts.map