tokentrace 0.21.1 → 0.21.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/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/src/lib/analytics-types.ts +56 -5
- package/src/lib/evidence/query.ts +1 -1
- package/src/lib/evidence-trail.ts +1 -1
- package/src/lib/project-signals.ts +2 -13
- package/src/lib/review-queue.ts +4 -21
- package/src/lib/scan-health-rules.ts +1 -1
- package/src/lib/scan-health-types.ts +104 -0
- package/src/lib/scan-health.ts +16 -104
- package/src/lib/session-comparison.ts +2 -20
- package/src/lib/unknown-cost-repair/auto-classify.ts +16 -41
- package/src/lib/unknown-cost-repair/classification-types.ts +41 -0
- package/src/lib/unknown-cost-repair/types.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ All notable changes to TokenTrace are documented here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## [0.21.2] - 2026-06-26
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **ProjScan circular-import warnings removed.** Shared scan-health, analytics,
|
|
12
|
+
evidence, review-queue, project-signal, session-comparison, and unknown-cost
|
|
13
|
+
repair contracts now live in leaf type modules so the import graph stays
|
|
14
|
+
acyclic. Added a regression test for these architecture boundaries.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **Low-risk dependency refresh.** Updated patch and minor dependencies within
|
|
19
|
+
the existing major-version ranges after audit and package-security checks.
|
|
20
|
+
|
|
7
21
|
## [0.21.1] - 2026-06-26
|
|
8
22
|
|
|
9
23
|
### Changed
|
package/README.md
CHANGED
|
@@ -417,7 +417,7 @@ Stop the server with `Ctrl+C` in the terminal where `tokentrace` is running.
|
|
|
417
417
|
- `npm run security:ioc` scans lockfiles, workflows, and local Claude/VS Code hook files for high-signal supply-chain compromise indicators.
|
|
418
418
|
- Public npm publishing is configured through GitHub Actions Trusted Publishing and provenance from version tags.
|
|
419
419
|
- Socket GitHub checks and ProjScan are used as release guardrails, alongside `npm audit --audit-level=moderate`.
|
|
420
|
-
- `npm run release:check` fails when a gate command exits non-zero.
|
|
420
|
+
- `npm run release:check` fails when a gate command exits non-zero. The import graph is expected to remain free of circular dependencies; `tests/import-boundaries.test.ts` protects shared type/helper modules from importing higher-level orchestration barrels.
|
|
421
421
|
- Release notes are published directly in GitHub Releases from the relevant changelog section, not as a link-only summary.
|
|
422
422
|
|
|
423
423
|
See [SECURITY.md](SECURITY.md) for the full security and privacy model.
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"url": "https://github.com/abhiyoheswaran1/tokentrace",
|
|
9
9
|
"source": "github"
|
|
10
10
|
},
|
|
11
|
-
"version": "0.21.
|
|
11
|
+
"version": "0.21.2",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "tokentrace",
|
|
16
|
-
"version": "0.21.
|
|
16
|
+
"version": "0.21.2",
|
|
17
17
|
"runtimeHint": "npx",
|
|
18
18
|
"packageArguments": [
|
|
19
19
|
{
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import type { DataConfidenceGrade, DataConfidenceScore } from "@/src/lib/data-confidence";
|
|
2
|
-
import type { EvidenceMetric } from "@/src/lib/evidence
|
|
2
|
+
import type { EvidenceMetric } from "@/src/lib/evidence/metrics";
|
|
3
3
|
import type { LocalRecommendation } from "@/src/lib/recommendations";
|
|
4
|
-
import type {
|
|
5
|
-
import type { ReviewQueueItem } from "@/src/lib/review-queue";
|
|
6
|
-
import type { ScanConfidenceSummary, ScanHealth } from "@/src/lib/scan-health";
|
|
7
|
-
import type { SessionComparisonRow } from "@/src/lib/session-comparison";
|
|
4
|
+
import type { ScanConfidenceSummary, ScanHealth } from "@/src/lib/scan-health-types";
|
|
8
5
|
import type { UsageGuardrailProgress } from "@/src/lib/usage-guardrails";
|
|
9
6
|
|
|
10
7
|
export type TrendPoint = {
|
|
@@ -172,6 +169,60 @@ export type ModelAliasSuggestion = {
|
|
|
172
169
|
parserHref: string;
|
|
173
170
|
};
|
|
174
171
|
|
|
172
|
+
export type ReviewQueueCategory =
|
|
173
|
+
| "guardrail"
|
|
174
|
+
| "cost-repair"
|
|
175
|
+
| "session"
|
|
176
|
+
| "project"
|
|
177
|
+
| "model"
|
|
178
|
+
| "cache"
|
|
179
|
+
| "baseline";
|
|
180
|
+
|
|
181
|
+
export type ReviewQueueItem = {
|
|
182
|
+
id: string;
|
|
183
|
+
severity: "high" | "medium" | "low";
|
|
184
|
+
category: ReviewQueueCategory;
|
|
185
|
+
title: string;
|
|
186
|
+
evidence: string;
|
|
187
|
+
action: string;
|
|
188
|
+
href: string;
|
|
189
|
+
impactLabel: string;
|
|
190
|
+
impactValue: string;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export type SessionComparisonRow = {
|
|
194
|
+
sessionId: string;
|
|
195
|
+
title: string;
|
|
196
|
+
project: string;
|
|
197
|
+
tool: string;
|
|
198
|
+
models: string;
|
|
199
|
+
totalTokens: number;
|
|
200
|
+
cost: number | null;
|
|
201
|
+
peerSessions: number;
|
|
202
|
+
peerMedianTokens: number;
|
|
203
|
+
peerMedianCost: number | null;
|
|
204
|
+
tokenMultiple: number;
|
|
205
|
+
costMultiple: number | null;
|
|
206
|
+
severity: "high" | "medium" | "low";
|
|
207
|
+
flag: "token outlier" | "cost outlier";
|
|
208
|
+
evidence: string;
|
|
209
|
+
action: string;
|
|
210
|
+
href: string;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export type ProjectSignalRow = {
|
|
214
|
+
id: string;
|
|
215
|
+
severity: "high" | "medium" | "low";
|
|
216
|
+
project: string;
|
|
217
|
+
path: string;
|
|
218
|
+
signal: "dominant usage" | "unknown cost" | "estimated tokens" | "model concentration";
|
|
219
|
+
evidence: string;
|
|
220
|
+
action: string;
|
|
221
|
+
href: string;
|
|
222
|
+
metricLabel: string;
|
|
223
|
+
metricValue: string;
|
|
224
|
+
};
|
|
225
|
+
|
|
175
226
|
export type DebugScanFile = {
|
|
176
227
|
id: string;
|
|
177
228
|
scanRunId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { sqlite } from "@/src/db/client";
|
|
2
|
-
import type { AnalyticsFilters } from "@/src/lib/analytics";
|
|
2
|
+
import type { AnalyticsFilters } from "@/src/lib/analytics-types";
|
|
3
3
|
import type { EvidenceMetric } from "@/src/lib/evidence/metrics";
|
|
4
4
|
|
|
5
5
|
export type EvidenceSessionRow = {
|
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
import type { ProjectAnalyticsRow, SessionRow } from "@/src/lib/analytics";
|
|
1
|
+
import type { ProjectAnalyticsRow, ProjectSignalRow, SessionRow } from "@/src/lib/analytics-types";
|
|
2
2
|
import { formatTokens } from "@/src/lib/format";
|
|
3
3
|
|
|
4
|
-
export type ProjectSignalRow
|
|
5
|
-
id: string;
|
|
6
|
-
severity: "high" | "medium" | "low";
|
|
7
|
-
project: string;
|
|
8
|
-
path: string;
|
|
9
|
-
signal: "dominant usage" | "unknown cost" | "estimated tokens" | "model concentration";
|
|
10
|
-
evidence: string;
|
|
11
|
-
action: string;
|
|
12
|
-
href: string;
|
|
13
|
-
metricLabel: string;
|
|
14
|
-
metricValue: string;
|
|
15
|
-
};
|
|
4
|
+
export type { ProjectSignalRow } from "@/src/lib/analytics-types";
|
|
16
5
|
|
|
17
6
|
type ProjectSignalInput = {
|
|
18
7
|
totalTokens: number;
|
package/src/lib/review-queue.ts
CHANGED
|
@@ -2,33 +2,16 @@ import { formatCurrency, formatTokens } from "@/src/lib/format";
|
|
|
2
2
|
import type {
|
|
3
3
|
ModelAnalyticsRow,
|
|
4
4
|
ProjectAnalyticsRow,
|
|
5
|
+
ReviewQueueCategory,
|
|
6
|
+
ReviewQueueItem,
|
|
5
7
|
SessionRow,
|
|
6
8
|
SummaryMetrics,
|
|
7
9
|
ToolComparisonRow,
|
|
8
10
|
UnknownCostQueueRow
|
|
9
|
-
} from "@/src/lib/analytics";
|
|
11
|
+
} from "@/src/lib/analytics-types";
|
|
10
12
|
import type { UsageGuardrailProgress, UsageGuardrailMetric } from "@/src/lib/usage-guardrails";
|
|
11
13
|
|
|
12
|
-
export type ReviewQueueCategory
|
|
13
|
-
| "guardrail"
|
|
14
|
-
| "cost-repair"
|
|
15
|
-
| "session"
|
|
16
|
-
| "project"
|
|
17
|
-
| "model"
|
|
18
|
-
| "cache"
|
|
19
|
-
| "baseline";
|
|
20
|
-
|
|
21
|
-
export type ReviewQueueItem = {
|
|
22
|
-
id: string;
|
|
23
|
-
severity: "high" | "medium" | "low";
|
|
24
|
-
category: ReviewQueueCategory;
|
|
25
|
-
title: string;
|
|
26
|
-
evidence: string;
|
|
27
|
-
action: string;
|
|
28
|
-
href: string;
|
|
29
|
-
impactLabel: string;
|
|
30
|
-
impactValue: string;
|
|
31
|
-
};
|
|
14
|
+
export type { ReviewQueueCategory, ReviewQueueItem } from "@/src/lib/analytics-types";
|
|
32
15
|
|
|
33
16
|
type ReviewQueueInput = {
|
|
34
17
|
summary: Pick<SummaryMetrics, "totalTokens" | "totalCost" | "inputTokens" | "cachedTokens" | "unknownCostInteractions">;
|
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
ScanHealthNoteGroup,
|
|
7
7
|
ScanHealthRun,
|
|
8
8
|
SupplyChainHealth
|
|
9
|
-
} from "@/src/lib/scan-health";
|
|
9
|
+
} from "@/src/lib/scan-health-types";
|
|
10
10
|
|
|
11
11
|
export function incrementCount(target: Record<string, number>, key: string, amount = 1) {
|
|
12
12
|
target[key] = (target[key] ?? 0) + amount;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export type ScanHealthRun = {
|
|
2
|
+
id: string;
|
|
3
|
+
startedAt: number;
|
|
4
|
+
completedAt: number | null;
|
|
5
|
+
filesScanned: number;
|
|
6
|
+
recordsImported: number;
|
|
7
|
+
warnings: string[];
|
|
8
|
+
errors: string[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type ScanHealthFile = {
|
|
12
|
+
id: string;
|
|
13
|
+
scanRunId: string;
|
|
14
|
+
path: string;
|
|
15
|
+
modifiedTime: number | null;
|
|
16
|
+
sizeBytes: number;
|
|
17
|
+
parser: string | null;
|
|
18
|
+
status: string;
|
|
19
|
+
recordsImported: number;
|
|
20
|
+
warnings: string[];
|
|
21
|
+
errors: string[];
|
|
22
|
+
rawMetadata: Record<string, unknown>;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type ScanConfidenceSummary = {
|
|
26
|
+
interactions: number;
|
|
27
|
+
exactTokenInteractions: number;
|
|
28
|
+
tokenizerEstimateInteractions?: number;
|
|
29
|
+
simpleEstimateInteractions?: number;
|
|
30
|
+
highConfidenceTokenInteractions: number;
|
|
31
|
+
lowConfidenceTokenInteractions: number;
|
|
32
|
+
unknownTokenInteractions: number;
|
|
33
|
+
estimatedTokenInteractions: number;
|
|
34
|
+
exactCostInteractions: number;
|
|
35
|
+
estimatedCostInteractions: number;
|
|
36
|
+
unknownCostInteractions: number;
|
|
37
|
+
unknownCostCauses: {
|
|
38
|
+
missingModelName: number;
|
|
39
|
+
missingPricing: number;
|
|
40
|
+
missingTokenCount: number;
|
|
41
|
+
other: number;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type ScanHealthAction = {
|
|
46
|
+
label: string;
|
|
47
|
+
href: string;
|
|
48
|
+
reason: string;
|
|
49
|
+
tone: "default" | "warning" | "destructive";
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type SupplyChainHealth = {
|
|
53
|
+
status: "passed" | "failed" | "not-run";
|
|
54
|
+
checkedAt: number | null;
|
|
55
|
+
findings: number;
|
|
56
|
+
summary: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type ScanHealthNoteGroup = {
|
|
60
|
+
severity: "warning" | "error";
|
|
61
|
+
message: string;
|
|
62
|
+
count: number;
|
|
63
|
+
examples: string[];
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type ScanHealth = {
|
|
67
|
+
latestRun: ScanHealthRun | null;
|
|
68
|
+
lastSuccessfulRun: ScanHealthRun | null;
|
|
69
|
+
latestFiles: ScanHealthFile[];
|
|
70
|
+
headline: string;
|
|
71
|
+
description: string;
|
|
72
|
+
tone: "success" | "warning" | "destructive" | "secondary";
|
|
73
|
+
latestStatusCounts: Record<string, number>;
|
|
74
|
+
parserCounts: Record<string, number>;
|
|
75
|
+
latestWarnings: string[];
|
|
76
|
+
latestErrors: string[];
|
|
77
|
+
latestNoteGroups: ScanHealthNoteGroup[];
|
|
78
|
+
freshness: {
|
|
79
|
+
state: "no-scan" | "no-successful-scan" | "fresh" | "stale";
|
|
80
|
+
lastSuccessfulCompletedAt: number | null;
|
|
81
|
+
staleAfterMs: number;
|
|
82
|
+
description: string;
|
|
83
|
+
};
|
|
84
|
+
tokenCoverage: {
|
|
85
|
+
exact: number;
|
|
86
|
+
tokenizerEstimate: number;
|
|
87
|
+
simpleEstimate: number;
|
|
88
|
+
highConfidenceEstimate: number;
|
|
89
|
+
lowConfidenceEstimate: number;
|
|
90
|
+
unknown: number;
|
|
91
|
+
estimated: number;
|
|
92
|
+
total: number;
|
|
93
|
+
};
|
|
94
|
+
costCoverage: {
|
|
95
|
+
priced: number;
|
|
96
|
+
exact: number;
|
|
97
|
+
estimated: number;
|
|
98
|
+
unknown: number;
|
|
99
|
+
unknownCauses: ScanConfidenceSummary["unknownCostCauses"];
|
|
100
|
+
total: number;
|
|
101
|
+
};
|
|
102
|
+
supplyChain: SupplyChainHealth;
|
|
103
|
+
actions: ScanHealthAction[];
|
|
104
|
+
};
|
package/src/lib/scan-health.ts
CHANGED
|
@@ -8,111 +8,23 @@ import {
|
|
|
8
8
|
uniqueMessages,
|
|
9
9
|
type ScanHealthRuleStats
|
|
10
10
|
} from "@/src/lib/scan-health-rules";
|
|
11
|
+
import type {
|
|
12
|
+
ScanConfidenceSummary,
|
|
13
|
+
ScanHealth,
|
|
14
|
+
ScanHealthFile,
|
|
15
|
+
ScanHealthRun,
|
|
16
|
+
SupplyChainHealth
|
|
17
|
+
} from "@/src/lib/scan-health-types";
|
|
11
18
|
|
|
12
|
-
export type
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export type ScanHealthFile = {
|
|
23
|
-
id: string;
|
|
24
|
-
scanRunId: string;
|
|
25
|
-
path: string;
|
|
26
|
-
modifiedTime: number | null;
|
|
27
|
-
sizeBytes: number;
|
|
28
|
-
parser: string | null;
|
|
29
|
-
status: string;
|
|
30
|
-
recordsImported: number;
|
|
31
|
-
warnings: string[];
|
|
32
|
-
errors: string[];
|
|
33
|
-
rawMetadata: Record<string, unknown>;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export type ScanConfidenceSummary = {
|
|
37
|
-
interactions: number;
|
|
38
|
-
exactTokenInteractions: number;
|
|
39
|
-
tokenizerEstimateInteractions?: number;
|
|
40
|
-
simpleEstimateInteractions?: number;
|
|
41
|
-
highConfidenceTokenInteractions: number;
|
|
42
|
-
lowConfidenceTokenInteractions: number;
|
|
43
|
-
unknownTokenInteractions: number;
|
|
44
|
-
estimatedTokenInteractions: number;
|
|
45
|
-
exactCostInteractions: number;
|
|
46
|
-
estimatedCostInteractions: number;
|
|
47
|
-
unknownCostInteractions: number;
|
|
48
|
-
unknownCostCauses: {
|
|
49
|
-
missingModelName: number;
|
|
50
|
-
missingPricing: number;
|
|
51
|
-
missingTokenCount: number;
|
|
52
|
-
other: number;
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export type ScanHealthAction = {
|
|
57
|
-
label: string;
|
|
58
|
-
href: string;
|
|
59
|
-
reason: string;
|
|
60
|
-
tone: "default" | "warning" | "destructive";
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export type SupplyChainHealth = {
|
|
64
|
-
status: "passed" | "failed" | "not-run";
|
|
65
|
-
checkedAt: number | null;
|
|
66
|
-
findings: number;
|
|
67
|
-
summary: string;
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
export type ScanHealthNoteGroup = {
|
|
71
|
-
severity: "warning" | "error";
|
|
72
|
-
message: string;
|
|
73
|
-
count: number;
|
|
74
|
-
examples: string[];
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export type ScanHealth = {
|
|
78
|
-
latestRun: ScanHealthRun | null;
|
|
79
|
-
lastSuccessfulRun: ScanHealthRun | null;
|
|
80
|
-
latestFiles: ScanHealthFile[];
|
|
81
|
-
headline: string;
|
|
82
|
-
description: string;
|
|
83
|
-
tone: "success" | "warning" | "destructive" | "secondary";
|
|
84
|
-
latestStatusCounts: Record<string, number>;
|
|
85
|
-
parserCounts: Record<string, number>;
|
|
86
|
-
latestWarnings: string[];
|
|
87
|
-
latestErrors: string[];
|
|
88
|
-
latestNoteGroups: ScanHealthNoteGroup[];
|
|
89
|
-
freshness: {
|
|
90
|
-
state: "no-scan" | "no-successful-scan" | "fresh" | "stale";
|
|
91
|
-
lastSuccessfulCompletedAt: number | null;
|
|
92
|
-
staleAfterMs: number;
|
|
93
|
-
description: string;
|
|
94
|
-
};
|
|
95
|
-
tokenCoverage: {
|
|
96
|
-
exact: number;
|
|
97
|
-
tokenizerEstimate: number;
|
|
98
|
-
simpleEstimate: number;
|
|
99
|
-
highConfidenceEstimate: number;
|
|
100
|
-
lowConfidenceEstimate: number;
|
|
101
|
-
unknown: number;
|
|
102
|
-
estimated: number;
|
|
103
|
-
total: number;
|
|
104
|
-
};
|
|
105
|
-
costCoverage: {
|
|
106
|
-
priced: number;
|
|
107
|
-
exact: number;
|
|
108
|
-
estimated: number;
|
|
109
|
-
unknown: number;
|
|
110
|
-
unknownCauses: ScanConfidenceSummary["unknownCostCauses"];
|
|
111
|
-
total: number;
|
|
112
|
-
};
|
|
113
|
-
supplyChain: SupplyChainHealth;
|
|
114
|
-
actions: ScanHealthAction[];
|
|
115
|
-
};
|
|
19
|
+
export type {
|
|
20
|
+
ScanConfidenceSummary,
|
|
21
|
+
ScanHealth,
|
|
22
|
+
ScanHealthAction,
|
|
23
|
+
ScanHealthFile,
|
|
24
|
+
ScanHealthNoteGroup,
|
|
25
|
+
ScanHealthRun,
|
|
26
|
+
SupplyChainHealth
|
|
27
|
+
} from "@/src/lib/scan-health-types";
|
|
116
28
|
|
|
117
29
|
export function buildScanHealth({
|
|
118
30
|
scanRuns,
|
|
@@ -1,25 +1,7 @@
|
|
|
1
|
-
import type { SessionRow } from "@/src/lib/analytics";
|
|
1
|
+
import type { SessionComparisonRow, SessionRow } from "@/src/lib/analytics-types";
|
|
2
2
|
import { formatCurrency, formatTokens } from "@/src/lib/format";
|
|
3
3
|
|
|
4
|
-
export type SessionComparisonRow
|
|
5
|
-
sessionId: string;
|
|
6
|
-
title: string;
|
|
7
|
-
project: string;
|
|
8
|
-
tool: string;
|
|
9
|
-
models: string;
|
|
10
|
-
totalTokens: number;
|
|
11
|
-
cost: number | null;
|
|
12
|
-
peerSessions: number;
|
|
13
|
-
peerMedianTokens: number;
|
|
14
|
-
peerMedianCost: number | null;
|
|
15
|
-
tokenMultiple: number;
|
|
16
|
-
costMultiple: number | null;
|
|
17
|
-
severity: "high" | "medium" | "low";
|
|
18
|
-
flag: "token outlier" | "cost outlier";
|
|
19
|
-
evidence: string;
|
|
20
|
-
action: string;
|
|
21
|
-
href: string;
|
|
22
|
-
};
|
|
4
|
+
export type { SessionComparisonRow } from "@/src/lib/analytics-types";
|
|
23
5
|
|
|
24
6
|
function median(values: number[]) {
|
|
25
7
|
if (!values.length) return 0;
|
|
@@ -1,46 +1,21 @@
|
|
|
1
1
|
import { prepareCached } from "@/src/db/prepared";
|
|
2
2
|
import { modelNameCandidates } from "@/src/lib/model-aliases";
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
cause: UnknownCostRepairWorkbenchGroup["cause"];
|
|
20
|
-
providerId: string;
|
|
21
|
-
model: string;
|
|
22
|
-
sourceFile: string;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export type PricedModelRow = {
|
|
26
|
-
providerId: string;
|
|
27
|
-
providerName: string;
|
|
28
|
-
modelName: string;
|
|
29
|
-
usageCount: number;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export type SourcePricedRow = {
|
|
33
|
-
sourceFile: string;
|
|
34
|
-
providerId: string;
|
|
35
|
-
providerName: string;
|
|
36
|
-
modelName: string;
|
|
37
|
-
usageCount: number;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export type ClassificationLookups = {
|
|
41
|
-
pricedByProvider: Map<string, PricedModelRow[]>;
|
|
42
|
-
pricedBySource: Map<string, SourcePricedRow>;
|
|
43
|
-
};
|
|
3
|
+
import type {
|
|
4
|
+
AutoClassification,
|
|
5
|
+
ClassificationLookups,
|
|
6
|
+
ClassifyInput,
|
|
7
|
+
PricedModelRow,
|
|
8
|
+
SourcePricedRow
|
|
9
|
+
} from "@/src/lib/unknown-cost-repair/classification-types";
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
AutoClassification,
|
|
13
|
+
AutoClassificationRule,
|
|
14
|
+
ClassificationLookups,
|
|
15
|
+
ClassifyInput,
|
|
16
|
+
PricedModelRow,
|
|
17
|
+
SourcePricedRow
|
|
18
|
+
} from "@/src/lib/unknown-cost-repair/classification-types";
|
|
44
19
|
|
|
45
20
|
export function buildClassificationLookups(): ClassificationLookups {
|
|
46
21
|
const pricedRows = prepareCached(
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { UnknownCostRepairCause } from "@/src/lib/repair-actions";
|
|
2
|
+
|
|
3
|
+
export type AutoClassificationRule = "exact-model" | "family-fragment" | "parser-source" | "none";
|
|
4
|
+
|
|
5
|
+
export type AutoClassification = {
|
|
6
|
+
suggestedModel: string | null;
|
|
7
|
+
suggestedProvider: string | null;
|
|
8
|
+
confidence: number;
|
|
9
|
+
rule: AutoClassificationRule;
|
|
10
|
+
evidence: {
|
|
11
|
+
matchedRows: number;
|
|
12
|
+
sampleSourceFile: string | null;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type ClassifyInput = {
|
|
17
|
+
cause: UnknownCostRepairCause;
|
|
18
|
+
providerId: string;
|
|
19
|
+
model: string;
|
|
20
|
+
sourceFile: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type PricedModelRow = {
|
|
24
|
+
providerId: string;
|
|
25
|
+
providerName: string;
|
|
26
|
+
modelName: string;
|
|
27
|
+
usageCount: number;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type SourcePricedRow = {
|
|
31
|
+
sourceFile: string;
|
|
32
|
+
providerId: string;
|
|
33
|
+
providerName: string;
|
|
34
|
+
modelName: string;
|
|
35
|
+
usageCount: number;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type ClassificationLookups = {
|
|
39
|
+
pricedByProvider: Map<string, PricedModelRow[]>;
|
|
40
|
+
pricedBySource: Map<string, SourcePricedRow>;
|
|
41
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AutoClassification } from "@/src/lib/unknown-cost-repair/
|
|
1
|
+
import type { AutoClassification } from "@/src/lib/unknown-cost-repair/classification-types";
|
|
2
2
|
import type { UnknownCostRepairAction, UnknownCostRepairCause } from "@/src/lib/repair-actions";
|
|
3
3
|
|
|
4
4
|
export type UnknownCostRepairStatus = "unresolved" | "ignored" | "resolved" | "needs-parser-review";
|