myshell-tools 1.0.0 → 2.0.0-alpha.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/CHANGELOG.md +44 -69
- package/LICENSE +21 -21
- package/README.md +178 -318
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +106 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/cost.d.ts +36 -0
- package/dist/commands/cost.js +103 -0
- package/dist/commands/cost.js.map +1 -0
- package/dist/commands/doctor.d.ts +36 -0
- package/dist/commands/doctor.js +115 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/core/assess.d.ts +25 -0
- package/dist/core/assess.js +142 -0
- package/dist/core/assess.js.map +1 -0
- package/dist/core/classify.d.ts +19 -0
- package/dist/core/classify.js +80 -0
- package/dist/core/classify.js.map +1 -0
- package/dist/core/escalate.d.ts +32 -0
- package/dist/core/escalate.js +57 -0
- package/dist/core/escalate.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/orchestrate.d.ts +42 -0
- package/dist/core/orchestrate.js +439 -0
- package/dist/core/orchestrate.js.map +1 -0
- package/dist/core/policy.d.ts +9 -0
- package/dist/core/policy.js +27 -0
- package/dist/core/policy.js.map +1 -0
- package/dist/core/prompt.d.ts +26 -0
- package/dist/core/prompt.js +125 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/review.d.ts +46 -0
- package/dist/core/review.js +148 -0
- package/dist/core/review.js.map +1 -0
- package/dist/core/route.d.ts +28 -0
- package/dist/core/route.js +52 -0
- package/dist/core/route.js.map +1 -0
- package/dist/core/types.d.ts +141 -0
- package/dist/core/types.js +14 -0
- package/dist/core/types.js.map +1 -0
- package/dist/infra/atomic.d.ts +53 -0
- package/dist/infra/atomic.js +171 -0
- package/dist/infra/atomic.js.map +1 -0
- package/dist/infra/clock.d.ts +9 -0
- package/dist/infra/clock.js +15 -0
- package/dist/infra/clock.js.map +1 -0
- package/dist/infra/index.d.ts +9 -0
- package/dist/infra/index.js +7 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/ledger.d.ts +49 -0
- package/dist/infra/ledger.js +90 -0
- package/dist/infra/ledger.js.map +1 -0
- package/dist/infra/paths.d.ts +28 -0
- package/dist/infra/paths.js +38 -0
- package/dist/infra/paths.js.map +1 -0
- package/dist/infra/pricing.d.ts +47 -0
- package/dist/infra/pricing.js +151 -0
- package/dist/infra/pricing.js.map +1 -0
- package/dist/infra/session.d.ts +28 -0
- package/dist/infra/session.js +61 -0
- package/dist/infra/session.js.map +1 -0
- package/dist/interface/render.d.ts +27 -0
- package/dist/interface/render.js +134 -0
- package/dist/interface/render.js.map +1 -0
- package/dist/interface/repl.d.ts +23 -0
- package/dist/interface/repl.js +90 -0
- package/dist/interface/repl.js.map +1 -0
- package/dist/interface/run.d.ts +20 -0
- package/dist/interface/run.js +31 -0
- package/dist/interface/run.js.map +1 -0
- package/dist/providers/claude-parse.d.ts +24 -0
- package/dist/providers/claude-parse.js +113 -0
- package/dist/providers/claude-parse.js.map +1 -0
- package/dist/providers/claude.d.ts +45 -0
- package/dist/providers/claude.js +122 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex-parse.d.ts +32 -0
- package/dist/providers/codex-parse.js +145 -0
- package/dist/providers/codex-parse.js.map +1 -0
- package/dist/providers/codex.d.ts +44 -0
- package/dist/providers/codex.js +124 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/detect.d.ts +49 -0
- package/dist/providers/detect.js +125 -0
- package/dist/providers/detect.js.map +1 -0
- package/dist/providers/errors.d.ts +49 -0
- package/dist/providers/errors.js +189 -0
- package/dist/providers/errors.js.map +1 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.js +7 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/port.d.ts +74 -0
- package/dist/providers/port.js +16 -0
- package/dist/providers/port.js.map +1 -0
- package/dist/providers/registry.d.ts +21 -0
- package/dist/providers/registry.js +34 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/ui/banner.d.ts +19 -0
- package/dist/ui/banner.js +32 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/spinner.d.ts +27 -0
- package/dist/ui/spinner.js +67 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/theme.d.ts +32 -0
- package/dist/ui/theme.js +56 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +55 -49
- package/data/orchestrator.json +0 -113
- package/src/auth/recovery.mjs +0 -328
- package/src/auth/refresh.mjs +0 -373
- package/src/chef.mjs +0 -348
- package/src/cli/doctor.mjs +0 -568
- package/src/cli/reset.mjs +0 -447
- package/src/cli/status.mjs +0 -379
- package/src/cli.mjs +0 -429
- package/src/commands/doctor.mjs +0 -375
- package/src/commands/help.mjs +0 -324
- package/src/commands/status.mjs +0 -331
- package/src/monitor/health.mjs +0 -486
- package/src/monitor/performance.mjs +0 -442
- package/src/monitor/report.mjs +0 -535
- package/src/orchestrator/classify.mjs +0 -391
- package/src/orchestrator/confidence.mjs +0 -151
- package/src/orchestrator/handoffs.mjs +0 -231
- package/src/orchestrator/review.mjs +0 -222
- package/src/providers/balance.mjs +0 -201
- package/src/providers/claude.mjs +0 -236
- package/src/providers/codex.mjs +0 -255
- package/src/providers/detect.mjs +0 -185
- package/src/providers/errors.mjs +0 -373
- package/src/providers/select.mjs +0 -162
- package/src/repl-enhanced.mjs +0 -417
- package/src/repl.mjs +0 -321
- package/src/state/archive.mjs +0 -366
- package/src/state/atomic.mjs +0 -116
- package/src/state/cleanup.mjs +0 -440
- package/src/state/recovery.mjs +0 -461
- package/src/state/session.mjs +0 -147
- package/src/ui/errors.mjs +0 -456
- package/src/ui/formatter.mjs +0 -327
- package/src/ui/icons.mjs +0 -318
- package/src/ui/progress.mjs +0 -468
- package/templates/prompts/confidence-format.txt +0 -14
- package/templates/prompts/ic-with-feedback.txt +0 -41
- package/templates/prompts/ic.txt +0 -13
- package/templates/prompts/manager-review.txt +0 -40
- package/templates/prompts/manager.txt +0 -14
- package/templates/prompts/worker.txt +0 -12
|
@@ -1,442 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* performance.mjs — Performance tracking and efficiency monitoring
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { existsSync, mkdirSync } from 'fs';
|
|
6
|
-
import { join } from 'path';
|
|
7
|
-
import { atomicAppendJSONL, atomicWriteJSON, lockedReadModifyWrite } from '../state/atomic.mjs';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Performance baselines for comparison
|
|
11
|
-
*/
|
|
12
|
-
const BASELINES = {
|
|
13
|
-
// Estimated baseline costs for dual-verification vs. hierarchy
|
|
14
|
-
dualVerificationMultiplier: 2.5, // Dual-verification uses 2.5x more tokens
|
|
15
|
-
averageEscalationRate: 0.25, // 25% of tasks escalate
|
|
16
|
-
targetConfidence: 0.75, // Target average confidence
|
|
17
|
-
maxHandoffTime: 3000, // Maximum acceptable handoff time (ms)
|
|
18
|
-
|
|
19
|
-
// Token usage baselines (rough estimates)
|
|
20
|
-
tokenCosts: {
|
|
21
|
-
worker: { input: 0.25, output: 1.25 }, // per 1K tokens (USD)
|
|
22
|
-
ic: { input: 3.0, output: 15.0 },
|
|
23
|
-
manager: { input: 15.0, output: 75.0 }
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Get performance metrics directory
|
|
29
|
-
*/
|
|
30
|
-
function getMetricsDir(workspace = process.cwd()) {
|
|
31
|
-
const metricsDir = join(workspace, '.cortex', 'metrics');
|
|
32
|
-
if (!existsSync(metricsDir)) {
|
|
33
|
-
mkdirSync(metricsDir, { recursive: true });
|
|
34
|
-
}
|
|
35
|
-
return metricsDir;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Performance monitoring class
|
|
40
|
-
*/
|
|
41
|
-
export class PerformanceMonitor {
|
|
42
|
-
constructor(workspace = process.cwd()) {
|
|
43
|
-
this.workspace = workspace;
|
|
44
|
-
this.metricsDir = getMetricsDir(workspace);
|
|
45
|
-
this.currentSession = {
|
|
46
|
-
startTime: Date.now(),
|
|
47
|
-
handoffs: [],
|
|
48
|
-
escalations: 0,
|
|
49
|
-
totalTokensUsed: 0,
|
|
50
|
-
totalCostUSD: 0,
|
|
51
|
-
taskCount: 0
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Track a handoff operation
|
|
57
|
-
*/
|
|
58
|
-
trackHandoff(handoff) {
|
|
59
|
-
const handoffData = {
|
|
60
|
-
timestamp: Date.now(),
|
|
61
|
-
operation: handoff.operation, // 'execute', 'escalate', 'delegate', 'review'
|
|
62
|
-
fromTier: handoff.fromTier,
|
|
63
|
-
toTier: handoff.toTier,
|
|
64
|
-
provider: handoff.provider,
|
|
65
|
-
model: handoff.model,
|
|
66
|
-
confidence: handoff.confidence,
|
|
67
|
-
success: handoff.success,
|
|
68
|
-
durationMs: handoff.durationMs,
|
|
69
|
-
tokensUsed: handoff.tokensUsed || this.estimateTokens(handoff),
|
|
70
|
-
costUSD: handoff.costUSD || this.calculateCost(handoff),
|
|
71
|
-
sessionId: this.currentSession.startTime
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
this.currentSession.handoffs.push(handoffData);
|
|
75
|
-
this.currentSession.totalTokensUsed += handoffData.tokensUsed;
|
|
76
|
-
this.currentSession.totalCostUSD += handoffData.costUSD;
|
|
77
|
-
|
|
78
|
-
if (handoff.operation === 'escalate') {
|
|
79
|
-
this.currentSession.escalations++;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (handoff.operation === 'execute') {
|
|
83
|
-
this.currentSession.taskCount++;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Append to persistent log
|
|
87
|
-
const logPath = join(this.metricsDir, 'handoffs.jsonl');
|
|
88
|
-
atomicAppendJSONL(logPath, handoffData);
|
|
89
|
-
|
|
90
|
-
return handoffData;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Estimate token usage for a handoff
|
|
95
|
-
*/
|
|
96
|
-
estimateTokens(handoff) {
|
|
97
|
-
const promptLength = handoff.prompt?.length || 1000;
|
|
98
|
-
const outputLength = handoff.output?.length || 500;
|
|
99
|
-
|
|
100
|
-
// Rough estimation: 4 characters per token
|
|
101
|
-
const inputTokens = Math.ceil(promptLength / 4);
|
|
102
|
-
const outputTokens = Math.ceil(outputLength / 4);
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
input: inputTokens,
|
|
106
|
-
output: outputTokens,
|
|
107
|
-
total: inputTokens + outputTokens
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Calculate cost based on tier and tokens
|
|
113
|
-
*/
|
|
114
|
-
calculateCost(handoff) {
|
|
115
|
-
const tier = handoff.toTier || handoff.tier;
|
|
116
|
-
const tokens = handoff.tokensUsed || this.estimateTokens(handoff);
|
|
117
|
-
const rates = BASELINES.tokenCosts[tier] || BASELINES.tokenCosts.ic;
|
|
118
|
-
|
|
119
|
-
const inputCost = (tokens.input / 1000) * rates.input / 100; // Convert to USD
|
|
120
|
-
const outputCost = (tokens.output / 1000) * rates.output / 100;
|
|
121
|
-
|
|
122
|
-
return inputCost + outputCost;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Calculate efficiency vs baseline
|
|
127
|
-
*/
|
|
128
|
-
calculateEfficiencyVsBaseline() {
|
|
129
|
-
const totalTasks = this.currentSession.taskCount;
|
|
130
|
-
if (totalTasks === 0) return null;
|
|
131
|
-
|
|
132
|
-
// Estimated cost if using dual-verification for all tasks
|
|
133
|
-
const baselineCost = this.currentSession.totalCostUSD * BASELINES.dualVerificationMultiplier;
|
|
134
|
-
const actualCost = this.currentSession.totalCostUSD;
|
|
135
|
-
|
|
136
|
-
const efficiency = {
|
|
137
|
-
tokenSavings: 1 - (actualCost / baselineCost),
|
|
138
|
-
costSavingsUSD: baselineCost - actualCost,
|
|
139
|
-
escalationRate: this.currentSession.escalations / totalTasks,
|
|
140
|
-
averageConfidence: this.calculateAverageConfidence()
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
return efficiency;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Calculate average confidence across successful operations
|
|
148
|
-
*/
|
|
149
|
-
calculateAverageConfidence() {
|
|
150
|
-
const successfulHandoffs = this.currentSession.handoffs.filter(h =>
|
|
151
|
-
h.success && h.confidence !== null
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
if (successfulHandoffs.length === 0) return null;
|
|
155
|
-
|
|
156
|
-
const totalConfidence = successfulHandoffs.reduce((sum, h) => sum + h.confidence, 0);
|
|
157
|
-
return totalConfidence / successfulHandoffs.length;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Calculate escalation rate
|
|
162
|
-
*/
|
|
163
|
-
calculateEscalationRate() {
|
|
164
|
-
const totalTasks = this.currentSession.taskCount;
|
|
165
|
-
return totalTasks > 0 ? this.currentSession.escalations / totalTasks : 0;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Generate comprehensive performance report
|
|
170
|
-
*/
|
|
171
|
-
generateReport() {
|
|
172
|
-
const efficiency = this.calculateEfficiencyVsBaseline();
|
|
173
|
-
const duration = Date.now() - this.currentSession.startTime;
|
|
174
|
-
|
|
175
|
-
const report = {
|
|
176
|
-
timestamp: new Date().toISOString(),
|
|
177
|
-
sessionDuration: duration,
|
|
178
|
-
workspace: this.workspace,
|
|
179
|
-
|
|
180
|
-
// Core metrics
|
|
181
|
-
taskCount: this.currentSession.taskCount,
|
|
182
|
-
totalHandoffs: this.currentSession.handoffs.length,
|
|
183
|
-
escalationCount: this.currentSession.escalations,
|
|
184
|
-
|
|
185
|
-
// Performance metrics
|
|
186
|
-
escalationRate: this.calculateEscalationRate(),
|
|
187
|
-
averageConfidence: this.calculateAverageConfidence(),
|
|
188
|
-
|
|
189
|
-
// Efficiency metrics
|
|
190
|
-
efficiency: efficiency ? {
|
|
191
|
-
tokenSavingsPercentage: (efficiency.tokenSavings * 100).toFixed(1),
|
|
192
|
-
costSavingsUSD: efficiency.costSavingsUSD.toFixed(4),
|
|
193
|
-
escalationRate: (efficiency.escalationRate * 100).toFixed(1),
|
|
194
|
-
averageConfidence: efficiency.averageConfidence ? (efficiency.averageConfidence * 100).toFixed(1) : null
|
|
195
|
-
} : null,
|
|
196
|
-
|
|
197
|
-
// Cost metrics
|
|
198
|
-
totalCostUSD: this.currentSession.totalCostUSD.toFixed(4),
|
|
199
|
-
totalTokensUsed: this.currentSession.totalTokensUsed,
|
|
200
|
-
averageCostPerTask: this.currentSession.taskCount > 0 ?
|
|
201
|
-
(this.currentSession.totalCostUSD / this.currentSession.taskCount).toFixed(4) : null,
|
|
202
|
-
|
|
203
|
-
// Tier distribution
|
|
204
|
-
tierDistribution: this.calculateTierDistribution(),
|
|
205
|
-
|
|
206
|
-
// Performance indicators
|
|
207
|
-
indicators: this.generatePerformanceIndicators(efficiency),
|
|
208
|
-
|
|
209
|
-
// Raw session data
|
|
210
|
-
session: this.currentSession
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
return report;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Calculate tier usage distribution
|
|
218
|
-
*/
|
|
219
|
-
calculateTierDistribution() {
|
|
220
|
-
const tierCounts = { worker: 0, ic: 0, manager: 0 };
|
|
221
|
-
|
|
222
|
-
this.currentSession.handoffs.forEach(handoff => {
|
|
223
|
-
const tier = handoff.toTier || handoff.tier;
|
|
224
|
-
if (tierCounts.hasOwnProperty(tier)) {
|
|
225
|
-
tierCounts[tier]++;
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
const total = Object.values(tierCounts).reduce((sum, count) => sum + count, 0);
|
|
230
|
-
|
|
231
|
-
if (total === 0) return tierCounts;
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
worker: { count: tierCounts.worker, percentage: (tierCounts.worker / total * 100).toFixed(1) },
|
|
235
|
-
ic: { count: tierCounts.ic, percentage: (tierCounts.ic / total * 100).toFixed(1) },
|
|
236
|
-
manager: { count: tierCounts.manager, percentage: (tierCounts.manager / total * 100).toFixed(1) }
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Generate performance indicators and recommendations
|
|
242
|
-
*/
|
|
243
|
-
generatePerformanceIndicators(efficiency) {
|
|
244
|
-
const indicators = [];
|
|
245
|
-
|
|
246
|
-
if (efficiency) {
|
|
247
|
-
// Token savings indicator
|
|
248
|
-
if (efficiency.tokenSavings > 0.5) {
|
|
249
|
-
indicators.push({
|
|
250
|
-
type: 'excellent',
|
|
251
|
-
metric: 'token_efficiency',
|
|
252
|
-
message: `Excellent token efficiency: ${(efficiency.tokenSavings * 100).toFixed(1)}% savings vs baseline`,
|
|
253
|
-
recommendation: 'Continue current routing strategy'
|
|
254
|
-
});
|
|
255
|
-
} else if (efficiency.tokenSavings > 0.2) {
|
|
256
|
-
indicators.push({
|
|
257
|
-
type: 'good',
|
|
258
|
-
metric: 'token_efficiency',
|
|
259
|
-
message: `Good token efficiency: ${(efficiency.tokenSavings * 100).toFixed(1)}% savings`,
|
|
260
|
-
recommendation: 'Consider optimizing task classification for better tier routing'
|
|
261
|
-
});
|
|
262
|
-
} else {
|
|
263
|
-
indicators.push({
|
|
264
|
-
type: 'warning',
|
|
265
|
-
metric: 'token_efficiency',
|
|
266
|
-
message: `Low token efficiency: only ${(efficiency.tokenSavings * 100).toFixed(1)}% savings`,
|
|
267
|
-
recommendation: 'Review task routing - too many high-tier operations for simple tasks'
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Escalation rate indicator
|
|
272
|
-
if (efficiency.escalationRate <= BASELINES.averageEscalationRate) {
|
|
273
|
-
indicators.push({
|
|
274
|
-
type: 'good',
|
|
275
|
-
metric: 'escalation_rate',
|
|
276
|
-
message: `Healthy escalation rate: ${(efficiency.escalationRate * 100).toFixed(1)}%`,
|
|
277
|
-
recommendation: 'Task complexity assessment is working well'
|
|
278
|
-
});
|
|
279
|
-
} else {
|
|
280
|
-
indicators.push({
|
|
281
|
-
type: 'warning',
|
|
282
|
-
metric: 'escalation_rate',
|
|
283
|
-
message: `High escalation rate: ${(efficiency.escalationRate * 100).toFixed(1)}%`,
|
|
284
|
-
recommendation: 'Consider starting tasks at higher tiers or improving initial classification'
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Confidence indicator
|
|
289
|
-
if (efficiency.averageConfidence >= BASELINES.targetConfidence) {
|
|
290
|
-
indicators.push({
|
|
291
|
-
type: 'excellent',
|
|
292
|
-
metric: 'confidence',
|
|
293
|
-
message: `High confidence: ${(efficiency.averageConfidence * 100).toFixed(1)}%`,
|
|
294
|
-
recommendation: 'Models are well-matched to task complexity'
|
|
295
|
-
});
|
|
296
|
-
} else if (efficiency.averageConfidence >= 0.6) {
|
|
297
|
-
indicators.push({
|
|
298
|
-
type: 'good',
|
|
299
|
-
metric: 'confidence',
|
|
300
|
-
message: `Moderate confidence: ${(efficiency.averageConfidence * 100).toFixed(1)}%`,
|
|
301
|
-
recommendation: 'Consider task decomposition or tier adjustment'
|
|
302
|
-
});
|
|
303
|
-
} else {
|
|
304
|
-
indicators.push({
|
|
305
|
-
type: 'warning',
|
|
306
|
-
metric: 'confidence',
|
|
307
|
-
message: `Low confidence: ${(efficiency.averageConfidence * 100).toFixed(1)}%`,
|
|
308
|
-
recommendation: 'Review task complexity vs model capabilities'
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
return indicators;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Save session report to persistent storage
|
|
318
|
-
*/
|
|
319
|
-
saveSessionReport() {
|
|
320
|
-
const report = this.generateReport();
|
|
321
|
-
const reportsPath = join(this.metricsDir, 'session-reports.jsonl');
|
|
322
|
-
|
|
323
|
-
atomicAppendJSONL(reportsPath, report);
|
|
324
|
-
|
|
325
|
-
// Also save as individual report file
|
|
326
|
-
const reportId = `session-${this.currentSession.startTime}`;
|
|
327
|
-
const reportPath = join(this.metricsDir, `${reportId}.json`);
|
|
328
|
-
atomicWriteJSON(reportPath, report);
|
|
329
|
-
|
|
330
|
-
return { reportId, reportPath, report };
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Update running statistics
|
|
335
|
-
*/
|
|
336
|
-
updateRunningStats() {
|
|
337
|
-
const statsPath = join(this.metricsDir, 'running-stats.json');
|
|
338
|
-
|
|
339
|
-
const report = this.generateReport();
|
|
340
|
-
|
|
341
|
-
return lockedReadModifyWrite(statsPath, (stats) => {
|
|
342
|
-
const updated = stats || {
|
|
343
|
-
totalSessions: 0,
|
|
344
|
-
totalTasks: 0,
|
|
345
|
-
totalCostUSD: 0,
|
|
346
|
-
totalTokensUsed: 0,
|
|
347
|
-
averageEfficiency: 0,
|
|
348
|
-
averageConfidence: 0,
|
|
349
|
-
averageEscalationRate: 0,
|
|
350
|
-
lastUpdated: null
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
updated.totalSessions++;
|
|
354
|
-
updated.totalTasks += report.taskCount;
|
|
355
|
-
updated.totalCostUSD += parseFloat(report.totalCostUSD);
|
|
356
|
-
updated.totalTokensUsed += report.totalTokensUsed;
|
|
357
|
-
|
|
358
|
-
// Running averages
|
|
359
|
-
if (report.efficiency) {
|
|
360
|
-
const newEfficiency = parseFloat(report.efficiency.tokenSavingsPercentage) / 100;
|
|
361
|
-
updated.averageEfficiency = ((updated.averageEfficiency * (updated.totalSessions - 1)) + newEfficiency) / updated.totalSessions;
|
|
362
|
-
|
|
363
|
-
if (report.averageConfidence) {
|
|
364
|
-
const newConfidence = parseFloat(report.efficiency.averageConfidence) / 100;
|
|
365
|
-
updated.averageConfidence = ((updated.averageConfidence * (updated.totalSessions - 1)) + newConfidence) / updated.totalSessions;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const newEscalationRate = parseFloat(report.efficiency.escalationRate) / 100;
|
|
369
|
-
updated.averageEscalationRate = ((updated.averageEscalationRate * (updated.totalSessions - 1)) + newEscalationRate) / updated.totalSessions;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
updated.lastUpdated = new Date().toISOString();
|
|
373
|
-
|
|
374
|
-
return updated;
|
|
375
|
-
}, {
|
|
376
|
-
totalSessions: 0,
|
|
377
|
-
totalTasks: 0,
|
|
378
|
-
totalCostUSD: 0,
|
|
379
|
-
totalTokensUsed: 0,
|
|
380
|
-
averageEfficiency: 0,
|
|
381
|
-
averageConfidence: 0,
|
|
382
|
-
averageEscalationRate: 0,
|
|
383
|
-
lastUpdated: null
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* End session and finalize metrics
|
|
389
|
-
*/
|
|
390
|
-
endSession() {
|
|
391
|
-
const sessionReport = this.saveSessionReport();
|
|
392
|
-
const runningStats = this.updateRunningStats();
|
|
393
|
-
|
|
394
|
-
return {
|
|
395
|
-
...sessionReport,
|
|
396
|
-
runningStats
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Global performance monitor instance
|
|
403
|
-
*/
|
|
404
|
-
let globalMonitor = null;
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Get or create global performance monitor
|
|
408
|
-
*/
|
|
409
|
-
export function getPerformanceMonitor(workspace = process.cwd()) {
|
|
410
|
-
if (!globalMonitor) {
|
|
411
|
-
globalMonitor = new PerformanceMonitor(workspace);
|
|
412
|
-
}
|
|
413
|
-
return globalMonitor;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* Track handoff with global monitor
|
|
418
|
-
*/
|
|
419
|
-
export function trackHandoff(handoff) {
|
|
420
|
-
const monitor = getPerformanceMonitor();
|
|
421
|
-
return monitor.trackHandoff(handoff);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* Generate performance report
|
|
426
|
-
*/
|
|
427
|
-
export function generatePerformanceReport(workspace = process.cwd()) {
|
|
428
|
-
const monitor = getPerformanceMonitor(workspace);
|
|
429
|
-
return monitor.generateReport();
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* End session and save metrics
|
|
434
|
-
*/
|
|
435
|
-
export function endPerformanceSession(workspace = process.cwd()) {
|
|
436
|
-
if (!globalMonitor) return null;
|
|
437
|
-
|
|
438
|
-
const result = globalMonitor.endSession();
|
|
439
|
-
globalMonitor = null; // Reset for next session
|
|
440
|
-
|
|
441
|
-
return result;
|
|
442
|
-
}
|