nexus-prime 0.2.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/README.md +253 -0
- package/dist/agents/adapters/mcp.d.ts +21 -0
- package/dist/agents/adapters/mcp.d.ts.map +1 -0
- package/dist/agents/adapters/mcp.js +447 -0
- package/dist/agents/adapters/mcp.js.map +1 -0
- package/dist/agents/adapters.d.ts +57 -0
- package/dist/agents/adapters.d.ts.map +1 -0
- package/dist/agents/adapters.js +151 -0
- package/dist/agents/adapters.js.map +1 -0
- package/dist/agents/coordinator.d.ts +75 -0
- package/dist/agents/coordinator.d.ts.map +1 -0
- package/dist/agents/coordinator.js +339 -0
- package/dist/agents/coordinator.js.map +1 -0
- package/dist/agents/core/types.d.ts +157 -0
- package/dist/agents/core/types.d.ts.map +1 -0
- package/dist/agents/core/types.js +5 -0
- package/dist/agents/core/types.js.map +1 -0
- package/dist/agents/learner.d.ts +25 -0
- package/dist/agents/learner.d.ts.map +1 -0
- package/dist/agents/learner.js +88 -0
- package/dist/agents/learner.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +237 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +74 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/core/evolution.d.ts +122 -0
- package/dist/core/evolution.d.ts.map +1 -0
- package/dist/core/evolution.js +319 -0
- package/dist/core/evolution.js.map +1 -0
- package/dist/core/memory.d.ts +96 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +304 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/optimize.d.ts +100 -0
- package/dist/core/optimize.d.ts.map +1 -0
- package/dist/core/optimize.js +263 -0
- package/dist/core/optimize.js.map +1 -0
- package/dist/core/types.d.ts +155 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/wave.d.ts +55 -0
- package/dist/core/wave.d.ts.map +1 -0
- package/dist/core/wave.js +119 -0
- package/dist/core/wave.js.map +1 -0
- package/dist/engines/benchmark.d.ts +76 -0
- package/dist/engines/benchmark.d.ts.map +1 -0
- package/dist/engines/benchmark.js +167 -0
- package/dist/engines/benchmark.js.map +1 -0
- package/dist/engines/cache-manager.d.ts +75 -0
- package/dist/engines/cache-manager.d.ts.map +1 -0
- package/dist/engines/cache-manager.js +200 -0
- package/dist/engines/cache-manager.js.map +1 -0
- package/dist/engines/context.d.ts +50 -0
- package/dist/engines/context.d.ts.map +1 -0
- package/dist/engines/context.js +99 -0
- package/dist/engines/context.js.map +1 -0
- package/dist/engines/embedder.d.ts +55 -0
- package/dist/engines/embedder.d.ts.map +1 -0
- package/dist/engines/embedder.js +223 -0
- package/dist/engines/embedder.js.map +1 -0
- package/dist/engines/guardrails-bridge.d.ts +64 -0
- package/dist/engines/guardrails-bridge.d.ts.map +1 -0
- package/dist/engines/guardrails-bridge.js +251 -0
- package/dist/engines/guardrails-bridge.js.map +1 -0
- package/dist/engines/index.d.ts +14 -0
- package/dist/engines/index.d.ts.map +1 -0
- package/dist/engines/index.js +14 -0
- package/dist/engines/index.js.map +1 -0
- package/dist/engines/memory.d.ts +76 -0
- package/dist/engines/memory.d.ts.map +1 -0
- package/dist/engines/memory.js +431 -0
- package/dist/engines/memory.js.map +1 -0
- package/dist/engines/meta-learner.d.ts +87 -0
- package/dist/engines/meta-learner.d.ts.map +1 -0
- package/dist/engines/meta-learner.js +214 -0
- package/dist/engines/meta-learner.js.map +1 -0
- package/dist/engines/orchestrator.d.ts +69 -0
- package/dist/engines/orchestrator.d.ts.map +1 -0
- package/dist/engines/orchestrator.js +175 -0
- package/dist/engines/orchestrator.js.map +1 -0
- package/dist/engines/pod-network.d.ts +31 -0
- package/dist/engines/pod-network.d.ts.map +1 -0
- package/dist/engines/pod-network.js +108 -0
- package/dist/engines/pod-network.js.map +1 -0
- package/dist/engines/token-optimizer.d.ts +53 -0
- package/dist/engines/token-optimizer.d.ts.map +1 -0
- package/dist/engines/token-optimizer.js +115 -0
- package/dist/engines/token-optimizer.js.map +1 -0
- package/dist/engines/token-supremacy.d.ts +86 -0
- package/dist/engines/token-supremacy.d.ts.map +1 -0
- package/dist/engines/token-supremacy.js +403 -0
- package/dist/engines/token-supremacy.js.map +1 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +302 -0
- package/dist/index.js.map +1 -0
- package/dist/nexus-prime.d.ts +15 -0
- package/dist/nexus-prime.d.ts.map +1 -0
- package/dist/nexus-prime.js +15 -0
- package/dist/nexus-prime.js.map +1 -0
- package/dist/phantom/index.d.ts +135 -0
- package/dist/phantom/index.d.ts.map +1 -0
- package/dist/phantom/index.js +286 -0
- package/dist/phantom/index.js.map +1 -0
- package/dist/phantom/merge-oracle.d.ts +35 -0
- package/dist/phantom/merge-oracle.d.ts.map +1 -0
- package/dist/phantom/merge-oracle.js +189 -0
- package/dist/phantom/merge-oracle.js.map +1 -0
- package/dist/phantom/phase4-orchestrator.d.ts +14 -0
- package/dist/phantom/phase4-orchestrator.d.ts.map +1 -0
- package/dist/phantom/phase4-orchestrator.js +488 -0
- package/dist/phantom/phase4-orchestrator.js.map +1 -0
- package/dist/verify-guardrails.d.ts +2 -0
- package/dist/verify-guardrails.d.ts.map +1 -0
- package/dist/verify-guardrails.js +48 -0
- package/dist/verify-guardrails.js.map +1 -0
- package/dist/verify-pod-sync.d.ts +2 -0
- package/dist/verify-pod-sync.d.ts.map +1 -0
- package/dist/verify-pod-sync.js +41 -0
- package/dist/verify-pod-sync.js.map +1 -0
- package/dist/verify-substrate.d.ts +2 -0
- package/dist/verify-substrate.d.ts.map +1 -0
- package/dist/verify-substrate.js +41 -0
- package/dist/verify-substrate.js.map +1 -0
- package/dist/verify-token-scoring.d.ts +2 -0
- package/dist/verify-token-scoring.d.ts.map +1 -0
- package/dist/verify-token-scoring.js +37 -0
- package/dist/verify-token-scoring.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Optimizer Engine
|
|
3
|
+
*
|
|
4
|
+
* Intelligent token allocation using AdaptiveKVMerge principles.
|
|
5
|
+
*/
|
|
6
|
+
export declare class TokenOptimizer {
|
|
7
|
+
private maxTokens;
|
|
8
|
+
private qualityThreshold;
|
|
9
|
+
private compressionHistory;
|
|
10
|
+
constructor(maxTokens?: number);
|
|
11
|
+
/**
|
|
12
|
+
* Assess task complexity (0-1)
|
|
13
|
+
*/
|
|
14
|
+
assessComplexity(task: string): number;
|
|
15
|
+
/**
|
|
16
|
+
* Determine compression ratio based on complexity
|
|
17
|
+
*/
|
|
18
|
+
getCompressionRatio(complexity: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Optimize token allocation
|
|
21
|
+
*/
|
|
22
|
+
optimize(context: string[], task: string): {
|
|
23
|
+
tokens: number;
|
|
24
|
+
ratio: number;
|
|
25
|
+
strategy: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Track compression for learning
|
|
29
|
+
*/
|
|
30
|
+
trackCompression(taskType: string, quality: number): void;
|
|
31
|
+
/**
|
|
32
|
+
* Get average quality for a task type
|
|
33
|
+
*/
|
|
34
|
+
getAverageQuality(taskType: string): number;
|
|
35
|
+
}
|
|
36
|
+
export declare const createTokenOptimizer: (maxTokens?: number) => TokenOptimizer;
|
|
37
|
+
export declare class SLERPCompressor {
|
|
38
|
+
/**
|
|
39
|
+
* SLERP interpolation between two vectors
|
|
40
|
+
*/
|
|
41
|
+
slerp(v1: number[], v2: number[], t: number): number[];
|
|
42
|
+
/**
|
|
43
|
+
* Compress layers using SLERP
|
|
44
|
+
*/
|
|
45
|
+
compressLayers(layers: number[][], strategy?: 'aggressive' | 'moderate' | 'conservative'): {
|
|
46
|
+
compressed: number[][];
|
|
47
|
+
ratio: number;
|
|
48
|
+
};
|
|
49
|
+
private magnitude;
|
|
50
|
+
private dotProduct;
|
|
51
|
+
}
|
|
52
|
+
export declare const createSLERPCompressor: () => SLERPCompressor;
|
|
53
|
+
//# sourceMappingURL=token-optimizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-optimizer.d.ts","sourceRoot":"","sources":["../../src/engines/token-optimizer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,kBAAkB,CAAkC;gBAEhD,SAAS,GAAE,MAAe;IAItC;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAoBtC;;OAEG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAM/C;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG;QACzC,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB;IAgBD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAIzD;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAI5C;AAED,eAAO,MAAM,oBAAoB,GAAI,YAAY,MAAM,mBACxB,CAAC;AAIhC,qBAAa,eAAe;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAetD;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAE,YAAY,GAAG,UAAU,GAAG,cAA2B,GAAG;QACrG,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf;IAiBD,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,UAAU;CAGnB;AAED,eAAO,MAAM,qBAAqB,uBAA8B,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Optimizer Engine
|
|
3
|
+
*
|
|
4
|
+
* Intelligent token allocation using AdaptiveKVMerge principles.
|
|
5
|
+
*/
|
|
6
|
+
export class TokenOptimizer {
|
|
7
|
+
maxTokens;
|
|
8
|
+
qualityThreshold = 0.64;
|
|
9
|
+
compressionHistory = new Map();
|
|
10
|
+
constructor(maxTokens = 128000) {
|
|
11
|
+
this.maxTokens = maxTokens;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Assess task complexity (0-1)
|
|
15
|
+
*/
|
|
16
|
+
assessComplexity(task) {
|
|
17
|
+
// Simple heuristic-based assessment
|
|
18
|
+
const indicators = {
|
|
19
|
+
simple: ['what', 'when', 'who', 'where', 'is', 'are', '?', 'list'],
|
|
20
|
+
complex: ['build', 'create', 'design', 'implement', 'develop', 'explain why', 'analyze']
|
|
21
|
+
};
|
|
22
|
+
let score = 0.5;
|
|
23
|
+
const taskLower = task.toLowerCase();
|
|
24
|
+
for (const word of indicators.simple) {
|
|
25
|
+
if (taskLower.includes(word))
|
|
26
|
+
score -= 0.1;
|
|
27
|
+
}
|
|
28
|
+
for (const word of indicators.complex) {
|
|
29
|
+
if (taskLower.includes(word))
|
|
30
|
+
score += 0.15;
|
|
31
|
+
}
|
|
32
|
+
return Math.max(0, Math.min(1, score));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Determine compression ratio based on complexity
|
|
36
|
+
*/
|
|
37
|
+
getCompressionRatio(complexity) {
|
|
38
|
+
if (complexity < 0.3)
|
|
39
|
+
return 8.0; // Aggressive for simple
|
|
40
|
+
if (complexity < 0.7)
|
|
41
|
+
return 5.0; // Moderate for normal
|
|
42
|
+
return 3.0; // Conservative for complex
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Optimize token allocation
|
|
46
|
+
*/
|
|
47
|
+
optimize(context, task) {
|
|
48
|
+
const complexity = this.assessComplexity(task);
|
|
49
|
+
const ratio = this.getCompressionRatio(complexity);
|
|
50
|
+
// Estimate tokens needed
|
|
51
|
+
const baseTokens = context.reduce((sum, c) => sum + c.length / 4, 0);
|
|
52
|
+
const optimizedTokens = Math.floor(baseTokens / ratio);
|
|
53
|
+
return {
|
|
54
|
+
tokens: Math.min(optimizedTokens, this.maxTokens),
|
|
55
|
+
ratio,
|
|
56
|
+
strategy: complexity < 0.3 ? 'aggressive' :
|
|
57
|
+
complexity < 0.7 ? 'moderate' : 'conservative'
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Track compression for learning
|
|
62
|
+
*/
|
|
63
|
+
trackCompression(taskType, quality) {
|
|
64
|
+
this.compressionHistory.set(taskType, quality);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get average quality for a task type
|
|
68
|
+
*/
|
|
69
|
+
getAverageQuality(taskType) {
|
|
70
|
+
const history = this.compressionHistory.get(taskType);
|
|
71
|
+
return history || 0.5;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export const createTokenOptimizer = (maxTokens) => new TokenOptimizer(maxTokens);
|
|
75
|
+
// ===== Advanced: SLERP-based compression (from AdaptiveKVMerge) =====
|
|
76
|
+
export class SLERPCompressor {
|
|
77
|
+
/**
|
|
78
|
+
* SLERP interpolation between two vectors
|
|
79
|
+
*/
|
|
80
|
+
slerp(v1, v2, t) {
|
|
81
|
+
const dot = this.dotProduct(v1, v2) / (this.magnitude(v1) * this.magnitude(v2) || 1);
|
|
82
|
+
const omega = Math.acos(Math.max(-1, Math.min(1, dot)));
|
|
83
|
+
const sinOmega = Math.sin(omega);
|
|
84
|
+
if (sinOmega < 1e-6) {
|
|
85
|
+
return v1.map((x, i) => (1 - t) * x + t * (v2[i] || 0));
|
|
86
|
+
}
|
|
87
|
+
const a = Math.sin((1 - t) * omega) / sinOmega;
|
|
88
|
+
const b = Math.sin(t * omega) / sinOmega;
|
|
89
|
+
return v1.map((x, i) => a * x + b * (v2[i] || 0));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Compress layers using SLERP
|
|
93
|
+
*/
|
|
94
|
+
compressLayers(layers, strategy = 'moderate') {
|
|
95
|
+
const t = strategy === 'aggressive' ? 0.7 : strategy === 'moderate' ? 0.5 : 0.3;
|
|
96
|
+
const compressed = [];
|
|
97
|
+
for (let i = 1; i < layers.length; i += 2) {
|
|
98
|
+
if (i < layers.length) {
|
|
99
|
+
compressed.push(this.slerp(layers[i], layers[i - 1], t));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
compressed,
|
|
104
|
+
ratio: layers.length / (compressed.length || 1)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
magnitude(v) {
|
|
108
|
+
return Math.sqrt(v.reduce((sum, x) => sum + x * x, 0));
|
|
109
|
+
}
|
|
110
|
+
dotProduct(a, b) {
|
|
111
|
+
return a.reduce((sum, x, i) => sum + x * (b[i] || 0), 0);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export const createSLERPCompressor = () => new SLERPCompressor();
|
|
115
|
+
//# sourceMappingURL=token-optimizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-optimizer.js","sourceRoot":"","sources":["../../src/engines/token-optimizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Supremacy Engine
|
|
3
|
+
*
|
|
4
|
+
* Purpose: Make every token count. This engine runs BEFORE any large context
|
|
5
|
+
* operation and decides what to read, what to skip, what to summarize.
|
|
6
|
+
*
|
|
7
|
+
* Built for AntiGravity to reduce token waste by 50-70%.
|
|
8
|
+
*/
|
|
9
|
+
export interface FileRef {
|
|
10
|
+
path: string;
|
|
11
|
+
sizeBytes: number;
|
|
12
|
+
lastModified?: number;
|
|
13
|
+
}
|
|
14
|
+
export type ReadAction = 'skip' | 'outline' | 'partial' | 'full';
|
|
15
|
+
export interface FileReadPlan {
|
|
16
|
+
file: FileRef;
|
|
17
|
+
action: ReadAction;
|
|
18
|
+
startLine?: number;
|
|
19
|
+
endLine?: number;
|
|
20
|
+
reason: string;
|
|
21
|
+
estimatedTokens: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ReadingPlan {
|
|
24
|
+
task: string;
|
|
25
|
+
files: FileReadPlan[];
|
|
26
|
+
totalEstimatedTokens: number;
|
|
27
|
+
savings: number;
|
|
28
|
+
sessionBudget: number;
|
|
29
|
+
}
|
|
30
|
+
export interface SessionSummary {
|
|
31
|
+
sessionId: string;
|
|
32
|
+
timestamp: number;
|
|
33
|
+
files: string[];
|
|
34
|
+
fileSHAs: Record<string, string>;
|
|
35
|
+
summary: string;
|
|
36
|
+
keyDecisions: string[];
|
|
37
|
+
}
|
|
38
|
+
export interface ContextDelta {
|
|
39
|
+
added: FileRef[];
|
|
40
|
+
changed: FileRef[];
|
|
41
|
+
unchanged: FileRef[];
|
|
42
|
+
summary?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface TokenBudget {
|
|
45
|
+
total: number;
|
|
46
|
+
allocated: Map<string, number>;
|
|
47
|
+
remaining: number;
|
|
48
|
+
}
|
|
49
|
+
export declare class TokenSupremacyEngine {
|
|
50
|
+
private sessionBudget;
|
|
51
|
+
private sessionPath;
|
|
52
|
+
private relevanceCache;
|
|
53
|
+
private relevanceCachePath;
|
|
54
|
+
constructor(sessionBudget?: number);
|
|
55
|
+
/**
|
|
56
|
+
* Plan a token-efficient reading strategy for a given task + files.
|
|
57
|
+
*/
|
|
58
|
+
plan(task: string, files: FileRef[]): ReadingPlan;
|
|
59
|
+
/**
|
|
60
|
+
* Legacy compatibility wrapper for NexusPrime.
|
|
61
|
+
*/
|
|
62
|
+
optimize(context: string[], task: string): ReadingPlan;
|
|
63
|
+
differential(prev: SessionSummary, curr: FileRef[]): ContextDelta;
|
|
64
|
+
allocateBudget(workers: Array<{
|
|
65
|
+
id: string;
|
|
66
|
+
estimatedValue: number;
|
|
67
|
+
estimatedCost: number;
|
|
68
|
+
}>, totalBudget?: number): TokenBudget;
|
|
69
|
+
learn(taskType: string, usefulFiles: string[], skipFiles: string[]): void;
|
|
70
|
+
private loadRelevanceCache;
|
|
71
|
+
private saveRelevanceCache;
|
|
72
|
+
saveSessionSummary(summary: SessionSummary): void;
|
|
73
|
+
loadLatestSessionSummary(): SessionSummary | null;
|
|
74
|
+
private extractKeywords;
|
|
75
|
+
private scoreRelevance;
|
|
76
|
+
private estimateHotLines;
|
|
77
|
+
private fingerprintFile;
|
|
78
|
+
/**
|
|
79
|
+
* Adjust token budget based on task complexity signals.
|
|
80
|
+
* Complex tasks get +25% budget; simple lookups get -25%.
|
|
81
|
+
*/
|
|
82
|
+
private hypertune;
|
|
83
|
+
}
|
|
84
|
+
export declare function formatReadingPlan(plan: ReadingPlan): string;
|
|
85
|
+
export declare const createTokenSupremacyEngine: (budget?: number) => TokenSupremacyEngine;
|
|
86
|
+
//# sourceMappingURL=token-supremacy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-supremacy.d.ts","sourceRoot":"","sources":["../../src/engines/token-supremacy.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACrB;AAMD,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAS;IAG5B,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,kBAAkB,CAAS;gBAEvB,aAAa,GAAE,MAAgB;IAc3C;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,WAAW;IA8EjD;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW;IActD,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,YAAY;IA6BjE,cAAc,CACV,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7E,WAAW,GAAE,MAA2B,GACzC,WAAW;IAuBd,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAgBzE,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,kBAAkB;IAgB1B,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAMjD,wBAAwB,IAAI,cAAc,GAAG,IAAI;IAuBjD,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,cAAc;IAmFtB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,eAAe;IAKvB;;;OAGG;IACH,OAAO,CAAC,SAAS;CAqBpB;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAmC3D;AAED,eAAO,MAAM,0BAA0B,GAAI,SAAS,MAAM,yBACtB,CAAC"}
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Supremacy Engine
|
|
3
|
+
*
|
|
4
|
+
* Purpose: Make every token count. This engine runs BEFORE any large context
|
|
5
|
+
* operation and decides what to read, what to skip, what to summarize.
|
|
6
|
+
*
|
|
7
|
+
* Built for AntiGravity to reduce token waste by 50-70%.
|
|
8
|
+
*/
|
|
9
|
+
import * as os from 'os';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
// Core Engine
|
|
14
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15
|
+
export class TokenSupremacyEngine {
|
|
16
|
+
sessionBudget;
|
|
17
|
+
sessionPath;
|
|
18
|
+
// Per-session learned relevance: task keyword → file paths that helped
|
|
19
|
+
relevanceCache = new Map();
|
|
20
|
+
relevanceCachePath;
|
|
21
|
+
constructor(sessionBudget = 200_000) {
|
|
22
|
+
this.sessionBudget = sessionBudget;
|
|
23
|
+
this.sessionPath = path.join(os.homedir(), '.nexus-prime', 'sessions');
|
|
24
|
+
this.relevanceCachePath = path.join(os.homedir(), '.nexus-prime', 'relevance.json');
|
|
25
|
+
fs.mkdirSync(this.sessionPath, { recursive: true });
|
|
26
|
+
if (!fs.existsSync(path.dirname(this.relevanceCachePath))) {
|
|
27
|
+
fs.mkdirSync(path.dirname(this.relevanceCachePath), { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
this.loadRelevanceCache();
|
|
30
|
+
}
|
|
31
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
32
|
+
// Primary API: generate a reading plan for a task
|
|
33
|
+
/**
|
|
34
|
+
* Plan a token-efficient reading strategy for a given task + files.
|
|
35
|
+
*/
|
|
36
|
+
plan(task, files) {
|
|
37
|
+
// Apply hypertuning if we have many files
|
|
38
|
+
if (files.length > 10) {
|
|
39
|
+
this.hypertune(task);
|
|
40
|
+
}
|
|
41
|
+
const taskKeywords = this.extractKeywords(task);
|
|
42
|
+
const plans = [];
|
|
43
|
+
let totalTokens = 0;
|
|
44
|
+
let fullReadTokens = 0;
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
const relevance = this.scoreRelevance(file.path, taskKeywords);
|
|
47
|
+
const estFull = Math.ceil(file.sizeBytes / 4); // ~4 chars per token
|
|
48
|
+
fullReadTokens += estFull;
|
|
49
|
+
let plan;
|
|
50
|
+
if (relevance < 0.15) {
|
|
51
|
+
// Irrelevant — skip entirely
|
|
52
|
+
plan = {
|
|
53
|
+
file,
|
|
54
|
+
action: 'skip',
|
|
55
|
+
reason: `low relevance (${relevance.toFixed(2)}) to task`,
|
|
56
|
+
estimatedTokens: 0
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
else if (estFull < 300) {
|
|
60
|
+
// Small file — always read fully
|
|
61
|
+
plan = {
|
|
62
|
+
file,
|
|
63
|
+
action: 'full',
|
|
64
|
+
reason: 'small file, cheap to read',
|
|
65
|
+
estimatedTokens: estFull
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
else if (relevance < 0.40 || estFull > 30_000) {
|
|
69
|
+
// Low relevance or huge file — outline only
|
|
70
|
+
plan = {
|
|
71
|
+
file,
|
|
72
|
+
action: 'outline',
|
|
73
|
+
reason: relevance < 0.40
|
|
74
|
+
? `medium relevance (${relevance.toFixed(2)}), read outline`
|
|
75
|
+
: `large file (${Math.round(file.sizeBytes / 1024)}KB), read outline`,
|
|
76
|
+
estimatedTokens: 250
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
else if (estFull > 5_000) {
|
|
80
|
+
// Large but relevant — read hot sections
|
|
81
|
+
const { start, end } = this.estimateHotLines(file, taskKeywords);
|
|
82
|
+
plan = {
|
|
83
|
+
file,
|
|
84
|
+
action: 'partial',
|
|
85
|
+
startLine: start,
|
|
86
|
+
endLine: end,
|
|
87
|
+
reason: `relevant but large — reading lines ${start}-${end}`,
|
|
88
|
+
estimatedTokens: Math.ceil(((end - start) * 80) / 4) // ~80 chars/line
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Relevant, reasonable size — full read
|
|
93
|
+
plan = {
|
|
94
|
+
file,
|
|
95
|
+
action: 'full',
|
|
96
|
+
reason: `high relevance (${relevance.toFixed(2)})`,
|
|
97
|
+
estimatedTokens: estFull
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
totalTokens += plan.estimatedTokens;
|
|
101
|
+
plans.push(plan);
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
task,
|
|
105
|
+
files: plans,
|
|
106
|
+
totalEstimatedTokens: totalTokens,
|
|
107
|
+
savings: fullReadTokens - totalTokens,
|
|
108
|
+
sessionBudget: this.sessionBudget
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Legacy compatibility wrapper for NexusPrime.
|
|
113
|
+
*/
|
|
114
|
+
optimize(context, task) {
|
|
115
|
+
const files = context.map((c, i) => ({
|
|
116
|
+
path: `context_${i}.txt`,
|
|
117
|
+
sizeBytes: c.length * 4,
|
|
118
|
+
lastModified: Date.now()
|
|
119
|
+
}));
|
|
120
|
+
return this.plan(task, files);
|
|
121
|
+
}
|
|
122
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
123
|
+
// Differential Context: only pass what CHANGED
|
|
124
|
+
// Saves ~60-70% tokens on follow-up sessions
|
|
125
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
126
|
+
differential(prev, curr) {
|
|
127
|
+
const delta = {
|
|
128
|
+
added: [],
|
|
129
|
+
changed: [],
|
|
130
|
+
unchanged: [],
|
|
131
|
+
summary: prev.summary
|
|
132
|
+
};
|
|
133
|
+
for (const file of curr) {
|
|
134
|
+
const prevSHA = prev.fileSHAs[file.path];
|
|
135
|
+
const currSHA = this.fingerprintFile(file);
|
|
136
|
+
if (!prevSHA) {
|
|
137
|
+
delta.added.push(file);
|
|
138
|
+
}
|
|
139
|
+
else if (prevSHA !== currSHA) {
|
|
140
|
+
delta.changed.push(file);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
delta.unchanged.push(file); // SKIP — use prior summary
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return delta;
|
|
147
|
+
}
|
|
148
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
149
|
+
// Multi-Worker Token Budget Allocation
|
|
150
|
+
// Byzantine-inspired: workers bid, budget allocated by expected value
|
|
151
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
152
|
+
allocateBudget(workers, totalBudget = this.sessionBudget) {
|
|
153
|
+
const bids = workers.map(w => ({
|
|
154
|
+
id: w.id,
|
|
155
|
+
score: w.estimatedValue / Math.max(w.estimatedCost, 1)
|
|
156
|
+
}));
|
|
157
|
+
const totalScore = bids.reduce((s, b) => s + b.score, 0) || 1;
|
|
158
|
+
const allocated = new Map();
|
|
159
|
+
let used = 0;
|
|
160
|
+
for (const bid of bids) {
|
|
161
|
+
const share = Math.floor((bid.score / totalScore) * totalBudget);
|
|
162
|
+
allocated.set(bid.id, share);
|
|
163
|
+
used += share;
|
|
164
|
+
}
|
|
165
|
+
return { total: totalBudget, allocated, remaining: totalBudget - used };
|
|
166
|
+
}
|
|
167
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
168
|
+
// Learn: record which files were actually useful for a task type
|
|
169
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
170
|
+
learn(taskType, usefulFiles, skipFiles) {
|
|
171
|
+
if (!this.relevanceCache.has(taskType)) {
|
|
172
|
+
this.relevanceCache.set(taskType, new Map());
|
|
173
|
+
}
|
|
174
|
+
const cache = this.relevanceCache.get(taskType);
|
|
175
|
+
for (const f of usefulFiles) {
|
|
176
|
+
cache.set(f, (cache.get(f) ?? 0) + 1.0);
|
|
177
|
+
}
|
|
178
|
+
for (const f of skipFiles) {
|
|
179
|
+
cache.set(f, (cache.get(f) ?? 0) - 0.3); // mild penalty
|
|
180
|
+
}
|
|
181
|
+
this.saveRelevanceCache();
|
|
182
|
+
}
|
|
183
|
+
loadRelevanceCache() {
|
|
184
|
+
try {
|
|
185
|
+
if (fs.existsSync(this.relevanceCachePath)) {
|
|
186
|
+
const data = JSON.parse(fs.readFileSync(this.relevanceCachePath, 'utf-8'));
|
|
187
|
+
for (const [taskType, fileScores] of Object.entries(data)) {
|
|
188
|
+
const scoreMap = new Map(Object.entries(fileScores));
|
|
189
|
+
this.relevanceCache.set(taskType, scoreMap);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
console.error('Failed to load relevance cache:', e);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
saveRelevanceCache() {
|
|
198
|
+
try {
|
|
199
|
+
const data = {};
|
|
200
|
+
for (const [taskType, scoreMap] of this.relevanceCache.entries()) {
|
|
201
|
+
data[taskType] = Object.fromEntries(scoreMap.entries());
|
|
202
|
+
}
|
|
203
|
+
fs.writeFileSync(this.relevanceCachePath, JSON.stringify(data, null, 2));
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
console.error('Failed to save relevance cache:', e);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
210
|
+
// Session summary persistence
|
|
211
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
212
|
+
saveSessionSummary(summary) {
|
|
213
|
+
const date = new Date(summary.timestamp).toISOString().slice(0, 10);
|
|
214
|
+
const file = path.join(this.sessionPath, `${date}-${summary.sessionId}.json`);
|
|
215
|
+
fs.writeFileSync(file, JSON.stringify(summary, null, 2));
|
|
216
|
+
}
|
|
217
|
+
loadLatestSessionSummary() {
|
|
218
|
+
try {
|
|
219
|
+
const files = fs.readdirSync(this.sessionPath)
|
|
220
|
+
.filter(f => f.endsWith('.json'))
|
|
221
|
+
.sort()
|
|
222
|
+
.reverse();
|
|
223
|
+
if (files.length === 0)
|
|
224
|
+
return null;
|
|
225
|
+
const content = fs.readFileSync(path.join(this.sessionPath, files[0]), 'utf-8');
|
|
226
|
+
return JSON.parse(content);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
233
|
+
// Helpers
|
|
234
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
235
|
+
extractKeywords(task) {
|
|
236
|
+
// Remove stop words, extract meaningful tokens
|
|
237
|
+
const stopWords = new Set([
|
|
238
|
+
'a', 'an', 'the', 'is', 'are', 'was', 'were', 'be', 'been',
|
|
239
|
+
'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will',
|
|
240
|
+
'would', 'could', 'should', 'may', 'might', 'must', 'can',
|
|
241
|
+
'to', 'of', 'in', 'for', 'on', 'with', 'at', 'by', 'from',
|
|
242
|
+
'and', 'or', 'but', 'if', 'then', 'than', 'that', 'this',
|
|
243
|
+
'it', 'its', 'we', 'our', 'you', 'your', 'i', 'my'
|
|
244
|
+
]);
|
|
245
|
+
return task
|
|
246
|
+
.toLowerCase()
|
|
247
|
+
.replace(/[^a-z0-9\s_\-\/\.]/g, ' ')
|
|
248
|
+
.split(/\s+/)
|
|
249
|
+
.filter(w => w.length > 2 && !stopWords.has(w));
|
|
250
|
+
}
|
|
251
|
+
scoreRelevance(filePath, keywords) {
|
|
252
|
+
if (keywords.length === 0)
|
|
253
|
+
return 0.5;
|
|
254
|
+
// ── Normalize path: strip cwd prefix so keywords match relative segments ──
|
|
255
|
+
const cwd = process.cwd().toLowerCase().replace(/\\/g, '/');
|
|
256
|
+
let normalized = filePath.toLowerCase().replace(/\\/g, '/');
|
|
257
|
+
if (normalized.startsWith(cwd)) {
|
|
258
|
+
normalized = normalized.slice(cwd.length).replace(/^\//, '');
|
|
259
|
+
}
|
|
260
|
+
const parts = normalized.split('/');
|
|
261
|
+
const fileName = parts[parts.length - 1];
|
|
262
|
+
const baseName = fileName.replace(/\.[^.]+$/, ''); // e.g. "memory" from "memory.ts"
|
|
263
|
+
const ext = fileName.split('.').pop() ?? '';
|
|
264
|
+
// ── Extension-based baseline: .ts/.js files always get a floor for code tasks ──
|
|
265
|
+
let extBaseline = 0;
|
|
266
|
+
if (['ts', 'js', 'tsx', 'jsx'].includes(ext))
|
|
267
|
+
extBaseline = 0.20;
|
|
268
|
+
else if (['json', 'md'].includes(ext))
|
|
269
|
+
extBaseline = 0.15;
|
|
270
|
+
// ── Path keyword matching ──
|
|
271
|
+
let pathScore = 0;
|
|
272
|
+
let pathMatches = 0;
|
|
273
|
+
for (const kw of keywords) {
|
|
274
|
+
// Check basename directly (e.g. keyword "memory" matches "memory.ts")
|
|
275
|
+
if (baseName === kw || baseName.includes(kw)) {
|
|
276
|
+
pathMatches++;
|
|
277
|
+
pathScore += 1.5;
|
|
278
|
+
}
|
|
279
|
+
else if (normalized.includes(kw)) {
|
|
280
|
+
pathMatches++;
|
|
281
|
+
pathScore += 0.8;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// ── Content-aware scoring (first 500 bytes) — weighted heavily ──
|
|
285
|
+
let contentBonus = 0;
|
|
286
|
+
try {
|
|
287
|
+
const fullPath = path.isAbsolute(filePath) ? filePath : path.join(process.cwd(), filePath);
|
|
288
|
+
if (fs.existsSync(fullPath)) {
|
|
289
|
+
const fd = fs.openSync(fullPath, 'r');
|
|
290
|
+
const buffer = Buffer.alloc(500);
|
|
291
|
+
const bytesRead = fs.readSync(fd, buffer, 0, 500, 0);
|
|
292
|
+
fs.closeSync(fd);
|
|
293
|
+
const content = buffer.toString('utf-8', 0, bytesRead).toLowerCase();
|
|
294
|
+
const contentKeywords = this.extractKeywords(content);
|
|
295
|
+
let contentMatches = 0;
|
|
296
|
+
for (const kw of keywords) {
|
|
297
|
+
if (contentKeywords.includes(kw))
|
|
298
|
+
contentMatches++;
|
|
299
|
+
}
|
|
300
|
+
// Boost from 0.6 → 0.8 — content is the most reliable signal
|
|
301
|
+
contentBonus = (contentMatches / keywords.length) * 0.8;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
catch { /* ignore */ }
|
|
305
|
+
// ── Learned relevance ──
|
|
306
|
+
const taskType = keywords.slice(0, 3).join('_');
|
|
307
|
+
const learnedScore = this.relevanceCache.get(taskType)?.get(filePath) ?? 0;
|
|
308
|
+
// ── Semantic type bonuses ──
|
|
309
|
+
let typeBonus = 0;
|
|
310
|
+
const codeKws = ['fix', 'bug', 'debug', 'error', 'impl', 'add', 'build', 'audit', 'nexus', 'prime', 'tools', 'code', 'source'];
|
|
311
|
+
const memKws = ['memory', 'cache', 'store', 'recall', 'persist'];
|
|
312
|
+
const testKws = ['test', 'spec', 'jest', 'validate', 'verify'];
|
|
313
|
+
if (keywords.some(k => codeKws.includes(k)) && ['ts', 'js', 'json', 'md'].includes(ext)) {
|
|
314
|
+
typeBonus = 0.15;
|
|
315
|
+
}
|
|
316
|
+
if (keywords.some(k => memKws.includes(k)) && (normalized.includes('memory') || baseName.includes('memory'))) {
|
|
317
|
+
typeBonus = 0.4;
|
|
318
|
+
}
|
|
319
|
+
if (keywords.some(k => testKws.includes(k)) && ['test', 'spec'].some(t => fileName.includes(t))) {
|
|
320
|
+
typeBonus = 0.3;
|
|
321
|
+
}
|
|
322
|
+
// ── Combine: baseline + path + content + type + learned ──
|
|
323
|
+
const pathComponent = keywords.length > 0
|
|
324
|
+
? (pathMatches / keywords.length) * (pathScore / Math.max(pathMatches, 1))
|
|
325
|
+
: 0;
|
|
326
|
+
return Math.min(1, Math.max(extBaseline, pathComponent + typeBonus + learnedScore * 0.1 + contentBonus));
|
|
327
|
+
}
|
|
328
|
+
estimateHotLines(file, keywords) {
|
|
329
|
+
// Without reading the file, estimate hot sections by filename heuristics
|
|
330
|
+
// In production, the Ghost Pass pre-reads and provides actual line hints
|
|
331
|
+
const totalLines = Math.ceil(file.sizeBytes / 80); // ~80 chars/line
|
|
332
|
+
const windowSize = Math.min(200, Math.ceil(totalLines * 0.3));
|
|
333
|
+
// Heuristic: hot code tends to be in first 30% or last 30% of file
|
|
334
|
+
// Default to first section (imports + main logic)
|
|
335
|
+
return {
|
|
336
|
+
start: 1,
|
|
337
|
+
end: Math.min(windowSize, totalLines)
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
fingerprintFile(file) {
|
|
341
|
+
// Use mtime + size as cheap fingerprint (no hashing needed)
|
|
342
|
+
return `${file.lastModified ?? 0}-${file.sizeBytes}`;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Adjust token budget based on task complexity signals.
|
|
346
|
+
* Complex tasks get +25% budget; simple lookups get -25%.
|
|
347
|
+
*/
|
|
348
|
+
hypertune(task) {
|
|
349
|
+
const taskLower = task.toLowerCase();
|
|
350
|
+
const originalBudget = this.sessionBudget;
|
|
351
|
+
// Complexity signals
|
|
352
|
+
const complexSignals = ['refactor', 'complex', 'rewrite', 'migration', 'audit', 'architecture', 'redesign'];
|
|
353
|
+
const simpleSignals = ['lookup', 'find', 'list', 'check', 'quick', 'status'];
|
|
354
|
+
const isComplex = complexSignals.some(s => taskLower.includes(s));
|
|
355
|
+
const isSimple = simpleSignals.some(s => taskLower.includes(s));
|
|
356
|
+
if (isComplex) {
|
|
357
|
+
this.sessionBudget = Math.round(originalBudget * 1.25);
|
|
358
|
+
}
|
|
359
|
+
else if (isSimple) {
|
|
360
|
+
this.sessionBudget = Math.round(originalBudget * 0.75);
|
|
361
|
+
}
|
|
362
|
+
if (this.sessionBudget !== originalBudget) {
|
|
363
|
+
console.error(`[Token Engine] Hypertuned: budget ${originalBudget.toLocaleString()} → ${this.sessionBudget.toLocaleString()} tokens (${isComplex ? 'complex' : 'simple'} task detected)`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
368
|
+
// Plan formatter (for MCP response)
|
|
369
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
370
|
+
export function formatReadingPlan(plan) {
|
|
371
|
+
const lines = [
|
|
372
|
+
`📊 Token Budget Plan for: "${plan.task}"`,
|
|
373
|
+
`Total estimated: ${plan.totalEstimatedTokens.toLocaleString()} tokens`,
|
|
374
|
+
`Savings vs full read: ${plan.savings.toLocaleString()} tokens (${Math.round(plan.savings / Math.max(plan.savings + plan.totalEstimatedTokens, 1) * 100)}%)`,
|
|
375
|
+
'',
|
|
376
|
+
'📋 Reading Plan:'
|
|
377
|
+
];
|
|
378
|
+
const byAction = {
|
|
379
|
+
full: [], outline: [], partial: [], skip: []
|
|
380
|
+
};
|
|
381
|
+
for (const fp of plan.files) {
|
|
382
|
+
byAction[fp.action].push(fp);
|
|
383
|
+
}
|
|
384
|
+
if (byAction.full.length > 0) {
|
|
385
|
+
lines.push(' ✅ Read fully:');
|
|
386
|
+
byAction.full.forEach(f => lines.push(` • ${f.file.path} (~${f.estimatedTokens} tokens)`));
|
|
387
|
+
}
|
|
388
|
+
if (byAction.partial.length > 0) {
|
|
389
|
+
lines.push(' ✂️ Read partially:');
|
|
390
|
+
byAction.partial.forEach(f => lines.push(` • ${f.file.path} lines ${f.startLine}-${f.endLine} (~${f.estimatedTokens} tokens)`));
|
|
391
|
+
}
|
|
392
|
+
if (byAction.outline.length > 0) {
|
|
393
|
+
lines.push(' 🔍 Outline only:');
|
|
394
|
+
byAction.outline.forEach(f => lines.push(` • ${f.file.path} (~${f.estimatedTokens} tokens)`));
|
|
395
|
+
}
|
|
396
|
+
if (byAction.skip.length > 0) {
|
|
397
|
+
lines.push(' ⏭️ Skip:');
|
|
398
|
+
byAction.skip.forEach(f => lines.push(` • ${f.file.path} (${f.reason})`));
|
|
399
|
+
}
|
|
400
|
+
return lines.join('\n');
|
|
401
|
+
}
|
|
402
|
+
export const createTokenSupremacyEngine = (budget) => new TokenSupremacyEngine(budget);
|
|
403
|
+
//# sourceMappingURL=token-supremacy.js.map
|