chati-dev 4.0.0 → 4.0.2
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/framework/agents/build/dev.md +23 -3
- package/framework/agents/plan/ux.md +395 -9
- package/framework/config.yaml +3 -3
- package/framework/constitution.md +10 -3
- package/framework/data/entity-registry.yaml +43 -3
- package/framework/domains/agents/architect.yaml +1 -3
- package/framework/domains/agents/brief.yaml +1 -1
- package/framework/domains/agents/brownfield-wu.yaml +2 -2
- package/framework/domains/agents/detail.yaml +1 -1
- package/framework/domains/agents/devops.yaml +2 -4
- package/framework/domains/agents/greenfield-wu.yaml +2 -2
- package/framework/domains/agents/phases.yaml +1 -1
- package/framework/domains/agents/qa-implementation.yaml +4 -6
- package/framework/domains/agents/qa-planning.yaml +7 -10
- package/framework/domains/agents/tasks.yaml +1 -1
- package/framework/domains/agents/ux.yaml +21 -3
- package/framework/domains/constitution.yaml +5 -5
- package/framework/domains/global.yaml +8 -4
- package/framework/domains/workflows/standard-flow.yaml +33 -0
- package/framework/i18n/en.yaml +11 -2
- package/framework/i18n/es.yaml +11 -2
- package/framework/i18n/fr.yaml +11 -2
- package/framework/i18n/pt.yaml +11 -2
- package/framework/intelligence/context-engine.md +1 -1
- package/framework/presets/nextjs.yaml +41 -0
- package/framework/presets/node-express.yaml +39 -0
- package/framework/presets/react-vite.yaml +37 -0
- package/framework/presets/supabase-fullstack.yaml +37 -0
- package/framework/templates/brandbook-tmpl.yaml +153 -0
- package/framework/templates/component-spec-tmpl.yaml +121 -0
- package/framework/templates/design-token-tmpl.yaml +55 -0
- package/framework/templates/icon-system-tmpl.yaml +95 -0
- package/package.json +1 -1
- package/scripts/bundle-framework.js +1 -1
- package/src/api/index.js +10 -19
- package/src/autonomy/build-loop.js +1 -1
- package/src/autonomy/cause-analyzer.js +1 -1
- package/src/autonomy/worktree-manager.js +7 -2
- package/src/config/agent-customizer.js +1 -5
- package/src/config/context-file-generator.js +1 -1
- package/src/context/bracket-tracker.js +2 -13
- package/src/decision/engine.js +4 -0
- package/src/health/auto-fix.js +1 -1
- package/src/installer/core.js +8 -1
- package/src/intelligence/context-status.js +2 -17
- package/src/intelligence/decision-engine.js +8 -5
- package/src/intelligence/timeline.js +1 -1
- package/src/merger/semantic-merger.js +1 -1
- package/src/orchestrator/pipeline-manager.js +33 -46
- package/src/quality/metrics-collector.js +0 -2
- package/src/telemetry/config.js +2 -2
- package/src/telemetry/schema.js +1 -1
- package/src/terminal/isolation.js +10 -1
- package/src/terminal/prompt-builder.js +77 -9
- package/src/utils/brackets.js +29 -0
- package/src/utils/event-bus.js +1 -1
- package/src/utils/provider-limits.js +13 -0
|
@@ -4,13 +4,16 @@
|
|
|
4
4
|
* Before creating any new artifact, scores existing registry entities
|
|
5
5
|
* for similarity. Enforces Constitution Article XIV: REUSE > ADAPT > CREATE.
|
|
6
6
|
*
|
|
7
|
+
* NOTE: This module handles intent-level similarity with weighted scoring.
|
|
8
|
+
* For entity-level routing (COMPASS registry lookup), see `decision/engine.js`.
|
|
9
|
+
*
|
|
7
10
|
* Algorithm:
|
|
8
11
|
* similarity = (keywordOverlap * 0.6) + (purposeSimilarity * 0.4)
|
|
9
12
|
* >= 90% → REUSE, 60-89% → ADAPT, < 60% → CREATE
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
import { existsSync, readFileSync } from 'fs';
|
|
13
|
-
|
|
16
|
+
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* @typedef {object} DecisionIntent
|
|
@@ -61,7 +64,7 @@ export function evaluateDecision(intent, registryPath) {
|
|
|
61
64
|
let bestId = null;
|
|
62
65
|
|
|
63
66
|
for (const entity of entities) {
|
|
64
|
-
const score =
|
|
67
|
+
const score = calculateIntentSimilarity(intent, entity);
|
|
65
68
|
if (score > bestScore) {
|
|
66
69
|
bestScore = score;
|
|
67
70
|
bestMatch = entity;
|
|
@@ -104,7 +107,7 @@ export function evaluateDecision(intent, registryPath) {
|
|
|
104
107
|
* @param {{ keywords: string[], purpose: string }} entity
|
|
105
108
|
* @returns {number} 0.0 to 1.0
|
|
106
109
|
*/
|
|
107
|
-
export function
|
|
110
|
+
export function calculateIntentSimilarity(intent, entity) {
|
|
108
111
|
const kwScore = keywordOverlap(intent.keywords, entity.keywords || []);
|
|
109
112
|
const purposeScore = purposeSimilarity(intent.purpose, entity.purpose || '');
|
|
110
113
|
return (kwScore * 0.6) + (purposeScore * 0.4);
|
|
@@ -198,7 +201,7 @@ export function parseRegistryEntities(raw) {
|
|
|
198
201
|
|
|
199
202
|
for (const line of lines) {
|
|
200
203
|
// Category header (agents:, templates:, etc.) — 2-space indent under entities:
|
|
201
|
-
const categoryMatch = line.match(/^
|
|
204
|
+
const categoryMatch = line.match(/^ {2}(\w[\w-]*):\s*$/);
|
|
202
205
|
if (categoryMatch && !line.match(/^\s{4}/)) {
|
|
203
206
|
// Save previous entity
|
|
204
207
|
if (currentEntity && currentData.purpose) {
|
|
@@ -211,7 +214,7 @@ export function parseRegistryEntities(raw) {
|
|
|
211
214
|
}
|
|
212
215
|
|
|
213
216
|
// Entity header (e.g., " orchestrator:") — 4-space indent
|
|
214
|
-
const entityMatch = line.match(/^
|
|
217
|
+
const entityMatch = line.match(/^ {4}([\w][\w-]*):\s*$/);
|
|
215
218
|
if (entityMatch) {
|
|
216
219
|
// Save previous entity
|
|
217
220
|
if (currentEntity && currentData.purpose) {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @deprecated Not currently imported by any production module.
|
|
11
|
-
* Retained for potential future integration.
|
|
11
|
+
* Retained for potential future integration. Review for removal or integration by v5.0.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
@@ -165,7 +165,7 @@ export function mergeChanges(changes, strategy = MERGE_STRATEGIES.CONSERVATIVE)
|
|
|
165
165
|
const merged = [];
|
|
166
166
|
const skipped = [];
|
|
167
167
|
|
|
168
|
-
for (const [
|
|
168
|
+
for (const [, agentChanges] of fileAgentMap.entries()) {
|
|
169
169
|
const agents = [...new Set(agentChanges.map(c => c.agent))];
|
|
170
170
|
|
|
171
171
|
if (agents.length === 1) {
|
|
@@ -15,6 +15,37 @@ import { getCurrentVersion } from '../upgrade/checker.js';
|
|
|
15
15
|
*/
|
|
16
16
|
export const PIPELINE_PHASES = ['discover', 'plan', 'build', 'deploy'];
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Emit telemetry events for pipeline completion and flush to backend.
|
|
20
|
+
*
|
|
21
|
+
* @param {object} state - Pipeline state
|
|
22
|
+
*/
|
|
23
|
+
function emitPipelineComplete(state) {
|
|
24
|
+
const pipelineType = state.isQuickFlow ? 'quick-flow' : state.isStandardFlow ? 'standard' : 'full';
|
|
25
|
+
const totalDuration = Date.now() - new Date(state.startedAt).getTime();
|
|
26
|
+
telemetryTrack('pipeline_completed', {
|
|
27
|
+
pipelineType,
|
|
28
|
+
totalDuration,
|
|
29
|
+
agentsRun: state.completedAgents.length,
|
|
30
|
+
finalStatus: 'completed',
|
|
31
|
+
deviationCount: (state.modeTransitions || []).length,
|
|
32
|
+
});
|
|
33
|
+
telemetryTrack('session_completed', {
|
|
34
|
+
sessionId: state.sessionId || 'unknown',
|
|
35
|
+
pipelineType,
|
|
36
|
+
mode: state.phase === 'deploy' ? 'deploy' : 'build',
|
|
37
|
+
finalStage: state.phase,
|
|
38
|
+
duration: totalDuration,
|
|
39
|
+
agentCount: state.completedAgents.length,
|
|
40
|
+
success: true,
|
|
41
|
+
});
|
|
42
|
+
const flushedEvents = telemetryFlush();
|
|
43
|
+
if (flushedEvents.length > 0) {
|
|
44
|
+
const tConfig = getTelemetryConfig(state.targetDir || process.cwd());
|
|
45
|
+
sendEvents(flushedEvents, { ...tConfig, version: state.chatiVersion || 'unknown' });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
18
49
|
/**
|
|
19
50
|
* Agent status values.
|
|
20
51
|
*/
|
|
@@ -294,29 +325,7 @@ export function advancePipeline(pipelineState, completedAgent, results = {}) {
|
|
|
294
325
|
|
|
295
326
|
// Pipeline complete
|
|
296
327
|
newState.completedAt = new Date().toISOString();
|
|
297
|
-
|
|
298
|
-
const totalDuration1 = Date.now() - new Date(newState.startedAt).getTime();
|
|
299
|
-
telemetryTrack('pipeline_completed', {
|
|
300
|
-
pipelineType: pipelineType1,
|
|
301
|
-
totalDuration: totalDuration1,
|
|
302
|
-
agentsRun: newState.completedAgents.length,
|
|
303
|
-
finalStatus: 'completed',
|
|
304
|
-
deviationCount: (newState.modeTransitions || []).length,
|
|
305
|
-
});
|
|
306
|
-
telemetryTrack('session_completed', {
|
|
307
|
-
sessionId: newState.sessionId || 'unknown',
|
|
308
|
-
pipelineType: pipelineType1,
|
|
309
|
-
mode: newState.phase === 'deploy' ? 'deploy' : 'build',
|
|
310
|
-
finalStage: newState.phase,
|
|
311
|
-
duration: totalDuration1,
|
|
312
|
-
agentCount: newState.completedAgents.length,
|
|
313
|
-
success: true,
|
|
314
|
-
});
|
|
315
|
-
const flushedEvents = telemetryFlush();
|
|
316
|
-
if (flushedEvents.length > 0) {
|
|
317
|
-
const tConfig = getTelemetryConfig(newState.targetDir || process.cwd());
|
|
318
|
-
sendEvents(flushedEvents, { ...tConfig, version: newState.chatiVersion || 'unknown' });
|
|
319
|
-
}
|
|
328
|
+
emitPipelineComplete(newState);
|
|
320
329
|
return {
|
|
321
330
|
state: newState,
|
|
322
331
|
nextAction: 'complete',
|
|
@@ -366,29 +375,7 @@ export function advancePipeline(pipelineState, completedAgent, results = {}) {
|
|
|
366
375
|
|
|
367
376
|
// Pipeline complete
|
|
368
377
|
newState.completedAt = new Date().toISOString();
|
|
369
|
-
|
|
370
|
-
const totalDuration2 = Date.now() - new Date(newState.startedAt).getTime();
|
|
371
|
-
telemetryTrack('pipeline_completed', {
|
|
372
|
-
pipelineType: pipelineType2,
|
|
373
|
-
totalDuration: totalDuration2,
|
|
374
|
-
agentsRun: newState.completedAgents.length,
|
|
375
|
-
finalStatus: 'completed',
|
|
376
|
-
deviationCount: (newState.modeTransitions || []).length,
|
|
377
|
-
});
|
|
378
|
-
telemetryTrack('session_completed', {
|
|
379
|
-
sessionId: newState.sessionId || 'unknown',
|
|
380
|
-
pipelineType: pipelineType2,
|
|
381
|
-
mode: newState.phase === 'deploy' ? 'deploy' : 'build',
|
|
382
|
-
finalStage: newState.phase,
|
|
383
|
-
duration: totalDuration2,
|
|
384
|
-
agentCount: newState.completedAgents.length,
|
|
385
|
-
success: true,
|
|
386
|
-
});
|
|
387
|
-
const flushedEvents2 = telemetryFlush();
|
|
388
|
-
if (flushedEvents2.length > 0) {
|
|
389
|
-
const tConfig2 = getTelemetryConfig(newState.targetDir || process.cwd());
|
|
390
|
-
sendEvents(flushedEvents2, { ...tConfig2, version: newState.chatiVersion || 'unknown' });
|
|
391
|
-
}
|
|
378
|
+
emitPipelineComplete(newState);
|
|
392
379
|
return {
|
|
393
380
|
state: newState,
|
|
394
381
|
nextAction: 'complete',
|
|
@@ -199,14 +199,12 @@ export function calculateTrend(metrics) {
|
|
|
199
199
|
let sumY = 0;
|
|
200
200
|
let sumXY = 0;
|
|
201
201
|
let sumX2 = 0;
|
|
202
|
-
let sumY2 = 0;
|
|
203
202
|
|
|
204
203
|
for (let i = 0; i < n; i++) {
|
|
205
204
|
sumX += i;
|
|
206
205
|
sumY += values[i];
|
|
207
206
|
sumXY += i * values[i];
|
|
208
207
|
sumX2 += i * i;
|
|
209
|
-
sumY2 += values[i] * values[i];
|
|
210
208
|
}
|
|
211
209
|
|
|
212
210
|
const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
|
package/src/telemetry/config.js
CHANGED
|
@@ -26,8 +26,8 @@ export function getTelemetryConfig(targetDir) {
|
|
|
26
26
|
const defaults = {
|
|
27
27
|
enabled: true,
|
|
28
28
|
anonymousId: null,
|
|
29
|
-
endpoint: 'https://chati-telemetry.vercel.app/api/events',
|
|
30
|
-
apiKey: '10b0b54ba4f392fa46379ba778062ab0af5ca61e79609a7dce4aadd660104b56',
|
|
29
|
+
endpoint: process.env.CHATI_TELEMETRY_ENDPOINT || 'https://chati-telemetry.vercel.app/api/events',
|
|
30
|
+
apiKey: process.env.CHATI_TELEMETRY_KEY || '10b0b54ba4f392fa46379ba778062ab0af5ca61e79609a7dce4aadd660104b56',
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
if (!existsSync(configPath)) return defaults;
|
package/src/telemetry/schema.js
CHANGED
|
@@ -25,7 +25,7 @@ export const TELEMETRY_EVENTS = [
|
|
|
25
25
|
// Property Schemas (allowed fields per event type)
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
27
27
|
|
|
28
|
-
const EVENT_PROPERTIES = {
|
|
28
|
+
export const EVENT_PROPERTIES = {
|
|
29
29
|
installation_completed: [
|
|
30
30
|
'providers', 'editors', 'projectType', 'language',
|
|
31
31
|
'primaryProvider', 'installDuration',
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { posix } from 'path';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* @fileoverview Write scope isolation for multi-terminal execution.
|
|
3
5
|
*
|
|
@@ -96,7 +98,14 @@ export function isPathAllowed(agent, filePath) {
|
|
|
96
98
|
return false;
|
|
97
99
|
}
|
|
98
100
|
|
|
99
|
-
|
|
101
|
+
// Normalize backslashes and resolve traversal sequences (../)
|
|
102
|
+
const normalised = posix.normalize(filePath.replace(/\\/g, '/'));
|
|
103
|
+
|
|
104
|
+
// Reject paths that escape the project root
|
|
105
|
+
if (normalised.startsWith('../') || normalised.startsWith('/')) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
100
109
|
return scope.some(prefix => normalised === prefix || normalised.startsWith(prefix));
|
|
101
110
|
}
|
|
102
111
|
|
|
@@ -17,6 +17,7 @@ import { resolveOverlayPath } from '../installer/provider-overlay.js';
|
|
|
17
17
|
import { resolveProviderForAgent } from './cli-registry.js';
|
|
18
18
|
import { buildCompactGotchasSummary } from '../memory/gotchas-injector.js';
|
|
19
19
|
import { estimateTokens } from './cost-tracker.js';
|
|
20
|
+
import { PROVIDER_LIMITS as PROVIDER_TOKEN_LIMITS } from '../utils/provider-limits.js';
|
|
20
21
|
|
|
21
22
|
// Import AGENT_MODELS from model-governance (safe — named export,
|
|
22
23
|
// does not trigger main() which is guarded by fileURLToPath check).
|
|
@@ -186,12 +187,15 @@ export function buildAgentPrompt(config) {
|
|
|
186
187
|
// 8. Session context (uses resolved model/provider)
|
|
187
188
|
sections.push(buildSessionSection(config, { model, provider: resolvedProvider }));
|
|
188
189
|
|
|
189
|
-
// 9.
|
|
190
|
+
// 9. Anti-laziness reinforcement (proven remediation techniques)
|
|
191
|
+
sections.push(buildAntiLazinessSection(config.agent));
|
|
192
|
+
|
|
193
|
+
// 10. Output format instructions (handoff template — includes provider/model for audit)
|
|
190
194
|
sections.push(buildOutputInstructions({ provider: resolvedProvider, model }));
|
|
191
195
|
|
|
192
196
|
const prompt = sections.join('\n\n---\n\n');
|
|
193
197
|
|
|
194
|
-
//
|
|
198
|
+
// 11. Prompt size guard — validate before returning
|
|
195
199
|
const sizeCheck = validatePromptSize(prompt, resolvedProvider);
|
|
196
200
|
|
|
197
201
|
return {
|
|
@@ -362,17 +366,81 @@ function buildSessionSection(config, resolvedModelInfo = {}) {
|
|
|
362
366
|
}
|
|
363
367
|
|
|
364
368
|
// ---------------------------------------------------------------------------
|
|
365
|
-
//
|
|
369
|
+
// Anti-Laziness Reinforcement
|
|
366
370
|
// ---------------------------------------------------------------------------
|
|
367
371
|
|
|
368
372
|
/**
|
|
369
|
-
*
|
|
373
|
+
* Agents whose output is code or artifacts benefit most from anti-laziness.
|
|
374
|
+
* Planning/discovery agents get a lighter version.
|
|
370
375
|
*/
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
+
const CODE_PRODUCING_AGENTS = new Set(['dev', 'architect', 'ux', 'devops']);
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Build anti-laziness reinforcement section.
|
|
380
|
+
*
|
|
381
|
+
* Injects proven remediation techniques into every spawned agent prompt.
|
|
382
|
+
* Techniques sourced from empirical research (Microsoft Research, LazyBench):
|
|
383
|
+
* - Stakes framing (+10% performance)
|
|
384
|
+
* - Step-by-step structure (+34% -> 80% accuracy)
|
|
385
|
+
* - Completeness enforcement (+45% output quality)
|
|
386
|
+
*
|
|
387
|
+
* @param {string} agent - Agent name
|
|
388
|
+
* @returns {string} Formatted anti-laziness section
|
|
389
|
+
*/
|
|
390
|
+
export function buildAntiLazinessSection(agent) {
|
|
391
|
+
const isCodeAgent = CODE_PRODUCING_AGENTS.has(agent);
|
|
392
|
+
|
|
393
|
+
const lines = [
|
|
394
|
+
'<!-- ANTI-LAZINESS REINFORCEMENT -->',
|
|
395
|
+
'## Output Quality Requirements',
|
|
396
|
+
'',
|
|
397
|
+
'This is production-critical work for a real project. Every artifact you produce will be consumed by downstream agents and must be complete and accurate.',
|
|
398
|
+
'',
|
|
399
|
+
'### Completeness Rules',
|
|
400
|
+
'1. Before starting, count all deliverables. Lock that count.',
|
|
401
|
+
'2. Produce EVERY deliverable completely. No shortcuts, no placeholders.',
|
|
402
|
+
'3. After finishing, cross-check: output count MUST match initial scope.',
|
|
403
|
+
'',
|
|
404
|
+
];
|
|
405
|
+
|
|
406
|
+
if (isCodeAgent) {
|
|
407
|
+
lines.push(
|
|
408
|
+
'### Code Output Rules',
|
|
409
|
+
'- NEVER use placeholder comments: `// ...`, `// rest of code`, `// TODO`, `// implement here`',
|
|
410
|
+
'- NEVER output skeleton/stub code when full implementation is expected',
|
|
411
|
+
'- NEVER describe what code should do instead of writing it',
|
|
412
|
+
'- NEVER compress or skip sections when approaching output limits',
|
|
413
|
+
'',
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (agent === 'ux') {
|
|
418
|
+
lines.push(
|
|
419
|
+
'### Design Anti-Bias Rules',
|
|
420
|
+
'- NEVER default to centered single-column layouts — vary layout structure across sections',
|
|
421
|
+
'- NEVER use oversaturated primary colors (HSL saturation > 80%) without brand justification',
|
|
422
|
+
'- NEVER use only one sans-serif font (Inter, Roboto) — evaluate serif and display alternatives',
|
|
423
|
+
'- NEVER show only happy-path states — every component needs empty, loading, error, and disabled states',
|
|
424
|
+
'- NEVER use lorem ipsum, "John Doe", or generic placeholder content',
|
|
425
|
+
'- NEVER animate width/height/top/left — use transform and opacity only',
|
|
426
|
+
'',
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
lines.push(
|
|
431
|
+
'### When Approaching Output Limits',
|
|
432
|
+
'- Do NOT compress remaining sections',
|
|
433
|
+
'- Do NOT skip to conclusion',
|
|
434
|
+
'- Write at full quality to a clean breakpoint',
|
|
435
|
+
'- Signal clearly: `[PAUSED at deliverable X of Y. Continuing in next iteration.]`',
|
|
436
|
+
);
|
|
437
|
+
|
|
438
|
+
return lines.join('\n');
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// ---------------------------------------------------------------------------
|
|
442
|
+
// Prompt Size Guard
|
|
443
|
+
// ---------------------------------------------------------------------------
|
|
376
444
|
|
|
377
445
|
/**
|
|
378
446
|
* Validate prompt size against provider-specific limits.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Canonical bracket definitions for context window management.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for bracket thresholds, layer configurations,
|
|
5
|
+
* and budget ratios. Consumers import from here to avoid duplication.
|
|
6
|
+
*
|
|
7
|
+
* Progressive Reinforcement Model (v4.0):
|
|
8
|
+
* As context depletes, budget INCREASES (model needs MORE reinforcement).
|
|
9
|
+
* Budget expressed as ratio of provider's total context window.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Bracket definitions as an object (keyed by name).
|
|
14
|
+
* @type {Record<string, {min: number, max: number, layers: string[], budgetRatio: number}>}
|
|
15
|
+
*/
|
|
16
|
+
export const BRACKETS = {
|
|
17
|
+
FRESH: { min: 60, max: 100, layers: ['L0', 'L1', 'L2', 'L3', 'L4', 'L5'], budgetRatio: 0.015 },
|
|
18
|
+
MODERATE: { min: 40, max: 60, layers: ['L0', 'L1', 'L2', 'L3', 'L5'], budgetRatio: 0.025 },
|
|
19
|
+
DEPLETED: { min: 25, max: 40, layers: ['L0', 'L1', 'L2'], budgetRatio: 0.040 },
|
|
20
|
+
CRITICAL: { min: 0, max: 25, layers: ['L0', 'L1'], budgetRatio: 0.050 },
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Bracket definitions as an ordered array (for iteration/lookup by range).
|
|
25
|
+
* @type {Array<{name: string, min: number, max: number, layers: string[], budgetRatio: number}>}
|
|
26
|
+
*/
|
|
27
|
+
export const BRACKETS_LIST = Object.entries(BRACKETS).map(
|
|
28
|
+
([name, data]) => ({ name, ...data }),
|
|
29
|
+
);
|
package/src/utils/event-bus.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @deprecated Not currently imported by any production module.
|
|
10
|
-
* Retained for potential future integration.
|
|
10
|
+
* Retained for potential future integration. Review for removal or integration by v5.0.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { EventEmitter } from 'node:events';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Canonical provider context window limits.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for provider token limits used by
|
|
5
|
+
* bracket-tracker, context-status, and prompt-builder.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Provider context window limits (tokens). */
|
|
9
|
+
export const PROVIDER_LIMITS = {
|
|
10
|
+
claude: 200_000,
|
|
11
|
+
gemini: 1_000_000,
|
|
12
|
+
codex: 128_000,
|
|
13
|
+
};
|