@agent-finops/core 0.5.9 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/activitySnapshot.d.ts +676 -0
- package/dist/activitySnapshot.js +1220 -0
- package/dist/activitySnapshotCache.d.ts +54 -0
- package/dist/activitySnapshotCache.js +489 -0
- package/dist/discovery.d.ts +6 -2
- package/dist/discovery.js +36 -14
- package/dist/glance.d.ts +6 -2
- package/dist/glance.js +62 -13
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/localAgentLogs.d.ts +68 -2
- package/dist/localAgentLogs.js +972 -59
- package/dist/modelPricing.js +0 -1
- package/dist/providerConnectors.d.ts +13 -2
- package/dist/providerConnectors.js +708 -95
- package/dist/sampleData.js +4 -3
- package/dist/schema.d.ts +31 -29
- package/dist/schema.js +27 -3
- package/dist/sourceRegistry.d.ts +30 -5
- package/dist/sourceRegistry.js +250 -21
- package/dist/sourceStatus.d.ts +65 -0
- package/dist/sourceStatus.js +147 -0
- package/dist/stateTrust.d.ts +37 -0
- package/dist/stateTrust.js +277 -0
- package/package.json +1 -1
- package/samples/openai-usage.csv +2 -2
package/dist/discovery.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { lstat, readdir, readFile } from "node:fs/promises";
|
|
2
|
-
import {
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { basename, join, relative, sep } from "node:path";
|
|
3
4
|
import { resolveSafeScanRoot } from "./scanGuard.js";
|
|
4
5
|
const skippedDirectoryNames = new Set([
|
|
5
6
|
".git",
|
|
@@ -93,13 +94,15 @@ export async function scanLocalUsageSignals(rootPath) {
|
|
|
93
94
|
return;
|
|
94
95
|
}
|
|
95
96
|
const redacted = redactSecrets(raw);
|
|
96
|
-
const relativePath = relative(canonicalRoot, path) ||
|
|
97
|
+
const relativePath = relative(canonicalRoot, path) || ".";
|
|
98
|
+
const pathReference = opaquePathReference(relativePath);
|
|
97
99
|
result.scannedFiles += 1;
|
|
98
100
|
for (const name of detectSecretNames(raw)) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
const secretReference = opaqueSecretReference(name);
|
|
102
|
+
secrets.add(secretReference);
|
|
103
|
+
result.redactedEvidence.push(`${pathReference}: ${secretReference}=[REDACTED]`);
|
|
101
104
|
}
|
|
102
|
-
for (const signal of detectExportSignals(relativePath, redacted)) {
|
|
105
|
+
for (const signal of detectExportSignals(relativePath, redacted, pathReference)) {
|
|
103
106
|
result.signals.push(signal);
|
|
104
107
|
}
|
|
105
108
|
for (const rule of providerRules) {
|
|
@@ -108,11 +111,11 @@ export async function scanLocalUsageSignals(rootPath) {
|
|
|
108
111
|
continue;
|
|
109
112
|
}
|
|
110
113
|
const kind = inferKind(path, rule.kind);
|
|
111
|
-
const evidenceMeta = buildEvidence(
|
|
114
|
+
const evidenceMeta = buildEvidence(pathReference, rule.provider, kind, rule.id);
|
|
112
115
|
result.signals.push({
|
|
113
116
|
provider: rule.provider,
|
|
114
117
|
kind,
|
|
115
|
-
filePath:
|
|
118
|
+
filePath: pathReference,
|
|
116
119
|
ruleId: rule.id,
|
|
117
120
|
evidenceMeta,
|
|
118
121
|
evidence: encodeEvidence(evidenceMeta),
|
|
@@ -120,12 +123,14 @@ export async function scanLocalUsageSignals(rootPath) {
|
|
|
120
123
|
});
|
|
121
124
|
}
|
|
122
125
|
}, skipped, symlinks, unreadable);
|
|
123
|
-
result.skippedDirectories = Array.from(skipped)
|
|
126
|
+
result.skippedDirectories = Array.from(skipped)
|
|
127
|
+
.map((path) => opaquePathReference(relative(canonicalRoot, path) || "."))
|
|
128
|
+
.sort();
|
|
124
129
|
result.skippedSymlinks = Array.from(symlinks)
|
|
125
|
-
.map((path) => relative(canonicalRoot, path) ||
|
|
130
|
+
.map((path) => opaquePathReference(relative(canonicalRoot, path) || "."))
|
|
126
131
|
.sort();
|
|
127
132
|
result.unreadablePaths = Array.from(unreadable)
|
|
128
|
-
.map((path) => relative(canonicalRoot, path) ||
|
|
133
|
+
.map((path) => opaquePathReference(relative(canonicalRoot, path) || "."))
|
|
129
134
|
.sort();
|
|
130
135
|
result.secretsDetected = Array.from(secrets).sort();
|
|
131
136
|
result.signals = dedupeSignals(result.signals).sort((left, right) => {
|
|
@@ -169,7 +174,7 @@ async function walk(rootPath, visit, skipped, symlinks, unreadable) {
|
|
|
169
174
|
}
|
|
170
175
|
if (entry.isDirectory()) {
|
|
171
176
|
if (skippedDirectoryNames.has(entry.name)) {
|
|
172
|
-
skipped.add(
|
|
177
|
+
skipped.add(path);
|
|
173
178
|
continue;
|
|
174
179
|
}
|
|
175
180
|
await walk(path, visit, skipped, symlinks, unreadable);
|
|
@@ -203,7 +208,7 @@ function inferKind(path, fallback) {
|
|
|
203
208
|
}
|
|
204
209
|
return fallback;
|
|
205
210
|
}
|
|
206
|
-
function detectExportSignals(filePath, redacted) {
|
|
211
|
+
function detectExportSignals(filePath, redacted, pathReference) {
|
|
207
212
|
const lowerPath = filePath.toLowerCase();
|
|
208
213
|
const lowerText = redacted.toLowerCase();
|
|
209
214
|
const providers = ["openai", "anthropic", "cursor", "helicone", "langfuse", "gemini", "google", "replit"];
|
|
@@ -219,11 +224,11 @@ function detectExportSignals(filePath, redacted) {
|
|
|
219
224
|
const normalizedProvider = provider === "google" ? "gemini" : provider;
|
|
220
225
|
const kind = isInvoice ? "invoice" : "provider_export";
|
|
221
226
|
const ruleId = `export.${normalizedProvider}.${kind}`;
|
|
222
|
-
const evidenceMeta = buildEvidence(
|
|
227
|
+
const evidenceMeta = buildEvidence(pathReference, normalizedProvider, kind, ruleId);
|
|
223
228
|
return [{
|
|
224
229
|
provider: normalizedProvider,
|
|
225
230
|
kind,
|
|
226
|
-
filePath,
|
|
231
|
+
filePath: pathReference,
|
|
227
232
|
ruleId,
|
|
228
233
|
evidenceMeta,
|
|
229
234
|
evidence: encodeEvidence(evidenceMeta),
|
|
@@ -236,6 +241,23 @@ function buildEvidence(file, provider, signal, ruleId) {
|
|
|
236
241
|
function encodeEvidence(evidence) {
|
|
237
242
|
return JSON.stringify(evidence);
|
|
238
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Repository-controlled descendant names are untrusted metadata. Discovery may
|
|
246
|
+
* use the real relative path internally for classification, but persisted and
|
|
247
|
+
* agent-facing output receives only this stable, non-semantic reference.
|
|
248
|
+
*/
|
|
249
|
+
function opaquePathReference(relativePath) {
|
|
250
|
+
// Normalize only the current platform's separator. A literal backslash is
|
|
251
|
+
// a valid POSIX filename character and must not alias a nested POSIX path.
|
|
252
|
+
const normalized = (relativePath || ".").split(sep).join("/");
|
|
253
|
+
const digest = createHash("sha256").update(normalized, "utf8").digest("hex").slice(0, 16);
|
|
254
|
+
return `path-${digest}`;
|
|
255
|
+
}
|
|
256
|
+
/** Repository-controlled environment names are untrusted metadata too. */
|
|
257
|
+
function opaqueSecretReference(name) {
|
|
258
|
+
const digest = createHash("sha256").update(name, "utf8").digest("hex").slice(0, 16);
|
|
259
|
+
return `secret-${digest}`;
|
|
260
|
+
}
|
|
239
261
|
function dedupeSignals(signals) {
|
|
240
262
|
const byKey = new Map();
|
|
241
263
|
for (const signal of signals) {
|
package/dist/glance.d.ts
CHANGED
|
@@ -11,8 +11,12 @@ export type GlanceSession = {
|
|
|
11
11
|
durationMinutes: number;
|
|
12
12
|
apiEquivalentUsd: number | null;
|
|
13
13
|
costConfidence: "estimated" | "missing";
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
/** Null when the transcript reports only a total and no priceable breakdown. */
|
|
15
|
+
inputTokens: number | null;
|
|
16
|
+
/** Null when the transcript reports only a total and no priceable breakdown. */
|
|
17
|
+
outputTokens: number | null;
|
|
18
|
+
/** Provider-reported total retained without inventing input/output components. */
|
|
19
|
+
reportedTotalTokens?: number;
|
|
16
20
|
};
|
|
17
21
|
export type GlanceLimit = {
|
|
18
22
|
agent: LocalAgentCall["agent"];
|
package/dist/glance.js
CHANGED
|
@@ -193,6 +193,10 @@ function groupSessions(calls) {
|
|
|
193
193
|
const last = ordered[ordered.length - 1];
|
|
194
194
|
const costs = ordered.map(callCost);
|
|
195
195
|
const costComplete = costs.every((cost) => typeof cost === "number");
|
|
196
|
+
const tokenComponentsComplete = ordered.every((call) => call.usageSupport !== "unsupported_token_shape");
|
|
197
|
+
const reportedTotalTokens = tokenComponentsComplete
|
|
198
|
+
? undefined
|
|
199
|
+
: sessionReportedTotalTokens(ordered);
|
|
196
200
|
const startedAt = ordered
|
|
197
201
|
.map((call) => call.startedAt ?? call.timestamp)
|
|
198
202
|
.sort()[0];
|
|
@@ -205,16 +209,13 @@ function groupSessions(calls) {
|
|
|
205
209
|
startedAt,
|
|
206
210
|
lastActivityAt: last.timestamp,
|
|
207
211
|
apiEquivalentUsd: costComplete ? costs.reduce((total, cost) => total + cost, 0) : null,
|
|
208
|
-
inputTokens:
|
|
209
|
-
(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
(call.usage.cacheReadTokens ?? 0) +
|
|
216
|
-
(call.usage.cacheWrite5mTokens ?? 0) +
|
|
217
|
-
(call.usage.cacheWrite1hTokens ?? 0))),
|
|
212
|
+
inputTokens: tokenComponentsComplete
|
|
213
|
+
? sum(ordered, inputSideTokens)
|
|
214
|
+
: null,
|
|
215
|
+
outputTokens: tokenComponentsComplete
|
|
216
|
+
? sum(ordered, (call) => call.usage.outputTokens)
|
|
217
|
+
: null,
|
|
218
|
+
...(reportedTotalTokens !== undefined ? { reportedTotalTokens } : {}),
|
|
218
219
|
activity: ordered
|
|
219
220
|
.slice()
|
|
220
221
|
.reverse()
|
|
@@ -237,7 +238,10 @@ function toGlanceSession(session, now, activeWithinMinutes) {
|
|
|
237
238
|
apiEquivalentUsd: roundUsd(session.apiEquivalentUsd),
|
|
238
239
|
costConfidence: session.apiEquivalentUsd === null ? "missing" : "estimated",
|
|
239
240
|
inputTokens: session.inputTokens,
|
|
240
|
-
outputTokens: session.outputTokens
|
|
241
|
+
outputTokens: session.outputTokens,
|
|
242
|
+
...(session.reportedTotalTokens !== undefined
|
|
243
|
+
? { reportedTotalTokens: session.reportedTotalTokens }
|
|
244
|
+
: {})
|
|
241
245
|
};
|
|
242
246
|
}
|
|
243
247
|
function latestLimits(calls, now) {
|
|
@@ -516,8 +520,11 @@ function buildPrimaryAction(input) {
|
|
|
516
520
|
: input.limits.length > 0
|
|
517
521
|
? "No transcript-reported plan window is currently projected to exhaust before reset."
|
|
518
522
|
: "Not available; no plan window was reported in the local transcript.";
|
|
523
|
+
const reportedTotalEvidence = input.currentSession?.reportedTotalTokens === undefined
|
|
524
|
+
? ""
|
|
525
|
+
: `; provider-reported total tokens=${input.currentSession.reportedTotalTokens.toLocaleString("en-US")}; input/output breakdown unavailable`;
|
|
519
526
|
const sessionEvidence = input.currentSession
|
|
520
|
-
? `${input.currentSession.agent}; model=${input.currentSession.model}; status=${input.currentSession.status}; API-equivalent value=${input.currentSession.apiEquivalentUsd
|
|
527
|
+
? `${input.currentSession.agent}; model=${input.currentSession.model}; status=${input.currentSession.status}; API-equivalent value=${formatGlanceUsd(input.currentSession.apiEquivalentUsd)} (${input.currentSession.costConfidence}, not billed spend)${reportedTotalEvidence}`
|
|
521
528
|
: "not available";
|
|
522
529
|
const promptLines = [
|
|
523
530
|
"Use this aibill Glance evidence to prepare a bounded session handoff.",
|
|
@@ -603,8 +610,37 @@ function limitActionName(limit) {
|
|
|
603
610
|
: limit.name;
|
|
604
611
|
}
|
|
605
612
|
function callCost(call) {
|
|
613
|
+
if (call.usageSupport === "unsupported_token_shape")
|
|
614
|
+
return undefined;
|
|
606
615
|
return estimateTokenCostUsd(call.model, call.usage);
|
|
607
616
|
}
|
|
617
|
+
function inputSideTokens(call) {
|
|
618
|
+
return call.usage.inputTokens +
|
|
619
|
+
(call.usage.cacheReadTokens ?? 0) +
|
|
620
|
+
(call.usage.cacheWrite5mTokens ?? 0) +
|
|
621
|
+
(call.usage.cacheWrite1hTokens ?? 0);
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Preserve a provider-reported total when a session contains a total-only
|
|
625
|
+
* snapshot. Complete calls can be added from their real components; an
|
|
626
|
+
* unsupported call without a trustworthy total makes the aggregate unknown.
|
|
627
|
+
*/
|
|
628
|
+
function sessionReportedTotalTokens(calls) {
|
|
629
|
+
let total = 0;
|
|
630
|
+
for (const call of calls) {
|
|
631
|
+
if (call.usageSupport === "unsupported_token_shape") {
|
|
632
|
+
if (typeof call.reportedTotalTokens !== "number" ||
|
|
633
|
+
!Number.isFinite(call.reportedTotalTokens) ||
|
|
634
|
+
call.reportedTotalTokens < 0) {
|
|
635
|
+
return undefined;
|
|
636
|
+
}
|
|
637
|
+
total += call.reportedTotalTokens;
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
total += inputSideTokens(call) + call.usage.outputTokens;
|
|
641
|
+
}
|
|
642
|
+
return total;
|
|
643
|
+
}
|
|
608
644
|
function uniqueAgents(calls) {
|
|
609
645
|
return [...new Set(calls.map((call) => call.agent))].sort();
|
|
610
646
|
}
|
|
@@ -612,7 +648,20 @@ function sum(calls, pick) {
|
|
|
612
648
|
return calls.reduce((total, call) => total + pick(call), 0);
|
|
613
649
|
}
|
|
614
650
|
function roundUsd(value) {
|
|
615
|
-
|
|
651
|
+
if (value === null)
|
|
652
|
+
return null;
|
|
653
|
+
if (value > 0 && value < 0.01) {
|
|
654
|
+
const precise = Math.round(value * 1_000_000) / 1_000_000;
|
|
655
|
+
return precise === 0 ? value : precise;
|
|
656
|
+
}
|
|
657
|
+
return Math.round(value * 100) / 100;
|
|
658
|
+
}
|
|
659
|
+
function formatGlanceUsd(value) {
|
|
660
|
+
if (value === null)
|
|
661
|
+
return "unpriced";
|
|
662
|
+
if (value > 0 && value < 0.01)
|
|
663
|
+
return "<$0.01";
|
|
664
|
+
return `$${value.toFixed(2)}`;
|
|
616
665
|
}
|
|
617
666
|
function roundPercent(value) {
|
|
618
667
|
return Math.round(value * 10) / 10;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export * from "./analyze.js";
|
|
2
2
|
export * from "./agentInventory.js";
|
|
3
|
+
export * from "./activitySnapshot.js";
|
|
4
|
+
export * from "./activitySnapshotCache.js";
|
|
3
5
|
export * from "./attribution.js";
|
|
4
6
|
export * from "./credentialDetection.js";
|
|
5
7
|
export * from "./contextHealth.js";
|
|
@@ -17,5 +19,7 @@ export * from "./sampleData.js";
|
|
|
17
19
|
export * from "./scanGuard.js";
|
|
18
20
|
export * from "./schema.js";
|
|
19
21
|
export * from "./sourceRegistry.js";
|
|
22
|
+
export * from "./sourceStatus.js";
|
|
23
|
+
export * from "./stateTrust.js";
|
|
20
24
|
export * from "./providerConnectors.js";
|
|
21
25
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export * from "./analyze.js";
|
|
2
2
|
export * from "./agentInventory.js";
|
|
3
|
+
export * from "./activitySnapshot.js";
|
|
4
|
+
export * from "./activitySnapshotCache.js";
|
|
3
5
|
export * from "./attribution.js";
|
|
4
6
|
export * from "./credentialDetection.js";
|
|
5
7
|
export * from "./contextHealth.js";
|
|
@@ -17,5 +19,7 @@ export * from "./sampleData.js";
|
|
|
17
19
|
export * from "./scanGuard.js";
|
|
18
20
|
export * from "./schema.js";
|
|
19
21
|
export * from "./sourceRegistry.js";
|
|
22
|
+
export * from "./sourceStatus.js";
|
|
23
|
+
export * from "./stateTrust.js";
|
|
20
24
|
export * from "./providerConnectors.js";
|
|
21
25
|
//# sourceMappingURL=index.js.map
|
package/dist/localAgentLogs.d.ts
CHANGED
|
@@ -41,6 +41,14 @@ export type LocalAgentCall = {
|
|
|
41
41
|
latestTurnUsage?: LocalAgentTurnUsage;
|
|
42
42
|
/** Whether `usage` is one model turn or the session's cumulative financial total. */
|
|
43
43
|
usageScope?: "turn" | "session_cumulative";
|
|
44
|
+
/**
|
|
45
|
+
* Whether the transcript exposed the input/output components required for
|
|
46
|
+
* pricing. A total-only snapshot is still usage evidence, but pricing it as
|
|
47
|
+
* zero would be false precision.
|
|
48
|
+
*/
|
|
49
|
+
usageSupport?: "complete" | "unsupported_token_shape";
|
|
50
|
+
/** Provider-reported total retained when component fields are unavailable. */
|
|
51
|
+
reportedTotalTokens?: number;
|
|
44
52
|
usage: TokenUsage;
|
|
45
53
|
sessionId?: string;
|
|
46
54
|
/** Provider-reported plan windows embedded in the transcript, when present. */
|
|
@@ -101,6 +109,43 @@ export type LocalAgentLogOptions = {
|
|
|
101
109
|
/** Collect privacy-safe Codex invocation summaries during the same JSON pass. */
|
|
102
110
|
collectCodexInvocationEvidence?: boolean;
|
|
103
111
|
};
|
|
112
|
+
/**
|
|
113
|
+
* Options accepted by the financial-only loader. Invocation collection is
|
|
114
|
+
* intentionally unavailable: this path reads only the evidence needed for a
|
|
115
|
+
* financial snapshot and transcript-reported plan limits.
|
|
116
|
+
*/
|
|
117
|
+
export type LocalAgentFinancialLogOptions = Omit<LocalAgentLogOptions, "collectCodexInvocationEvidence">;
|
|
118
|
+
export type LocalAgentLogDiagnosticCode = "directory_missing" | "directory_unreadable" | "file_unreadable" | "malformed_jsonl" | "unsupported_token_shape";
|
|
119
|
+
export type LocalAgentLogDiagnostic = {
|
|
120
|
+
agent: LocalAgentCall["agent"];
|
|
121
|
+
code: LocalAgentLogDiagnosticCode;
|
|
122
|
+
severity: "info" | "warning" | "error";
|
|
123
|
+
/** Privacy-safe summary; absolute local paths and transcript text are omitted. */
|
|
124
|
+
message: string;
|
|
125
|
+
count: number;
|
|
126
|
+
};
|
|
127
|
+
export type LocalAgentSourceScan = {
|
|
128
|
+
agent: LocalAgentCall["agent"];
|
|
129
|
+
directoryStatus: "readable" | "missing" | "unreadable";
|
|
130
|
+
filesDiscovered: number;
|
|
131
|
+
filesParsed: number;
|
|
132
|
+
/** Malformed lines observed inside `jsonlValidationCoverage`. */
|
|
133
|
+
malformedLines: number;
|
|
134
|
+
unreadableFiles: number;
|
|
135
|
+
unsupportedUsageSnapshots: number;
|
|
136
|
+
/** Regular files safely excluded because their metadata predates `sinceIso`. */
|
|
137
|
+
filesSkippedBeforeWindow?: number;
|
|
138
|
+
/** Codex files resolved from bounded head/tail financial evidence. */
|
|
139
|
+
filesReadFinancially?: number;
|
|
140
|
+
/** Bytes not replayed as events after the required Codex financial state was proved. */
|
|
141
|
+
bytesSkippedAsNonFinancialHistory?: number;
|
|
142
|
+
/** JSONL lines classified from their envelope and skipped before JSON decoding. */
|
|
143
|
+
nonFinancialLinesPrefiltered?: number;
|
|
144
|
+
/** Bytes covered by the non-financial event prefilter. */
|
|
145
|
+
nonFinancialBytesPrefiltered?: number;
|
|
146
|
+
/** Whether JSON syntax was checked for every line or financial events only. */
|
|
147
|
+
jsonlValidationCoverage?: "complete" | "financial_events_only";
|
|
148
|
+
};
|
|
104
149
|
export type LocalAgentLogResult = {
|
|
105
150
|
records: UsageRecord[];
|
|
106
151
|
/** Per-call entries before aggregation (for drill-down/debugging). */
|
|
@@ -108,9 +153,18 @@ export type LocalAgentLogResult = {
|
|
|
108
153
|
filesParsed: number;
|
|
109
154
|
/** Which agents actually had data on this machine. */
|
|
110
155
|
agentsDetected: Array<LocalAgentCall["agent"]>;
|
|
156
|
+
/** Per-source scan outcome, including honest empty and unsupported states. */
|
|
157
|
+
sourceScans: LocalAgentSourceScan[];
|
|
158
|
+
/** Structured, privacy-safe failures/warnings encountered during the scan. */
|
|
159
|
+
diagnostics: LocalAgentLogDiagnostic[];
|
|
111
160
|
/** Present only when requested; contains counts/basenames, never raw text. */
|
|
112
161
|
codexInvocationFiles?: ParsedInvocationFile[];
|
|
113
162
|
};
|
|
163
|
+
type TranscriptParseDiagnostic = {
|
|
164
|
+
code: "malformed_jsonl" | "unsupported_token_shape";
|
|
165
|
+
count: number;
|
|
166
|
+
};
|
|
167
|
+
type TranscriptParseDiagnosticHandler = (diagnostic: TranscriptParseDiagnostic) => void;
|
|
114
168
|
/**
|
|
115
169
|
* Codex rollout/compaction files can repeat the same session's cumulative
|
|
116
170
|
* token counter. Keep only the latest snapshot per session so financial value,
|
|
@@ -119,11 +173,22 @@ export type LocalAgentLogResult = {
|
|
|
119
173
|
*/
|
|
120
174
|
export declare function dedupeCumulativeSessionCalls(calls: LocalAgentCall[]): LocalAgentCall[];
|
|
121
175
|
/** Parse one Claude Code transcript (JSONL). Exported for tests. */
|
|
122
|
-
export declare function parseClaudeCodeTranscript(content: string, filePath?: string, sinceMs?: number): LocalAgentCall[];
|
|
176
|
+
export declare function parseClaudeCodeTranscript(content: string, filePath?: string, sinceMs?: number, onDiagnostic?: TranscriptParseDiagnosticHandler): LocalAgentCall[];
|
|
123
177
|
/** Parse one Codex rollout file (JSONL event stream). Exported for tests. */
|
|
124
|
-
export declare function parseCodexRollout(content: string, onEntry?: (entry: Record<string, unknown>) => void): LocalAgentCall[];
|
|
178
|
+
export declare function parseCodexRollout(content: string, onEntry?: (entry: Record<string, unknown>) => void, onDiagnostic?: TranscriptParseDiagnosticHandler): LocalAgentCall[];
|
|
125
179
|
/** Scan this machine's agent logs and return aggregated UsageRecords. */
|
|
126
180
|
export declare function loadLocalAgentUsage(options?: LocalAgentLogOptions): Promise<LocalAgentLogResult>;
|
|
181
|
+
/**
|
|
182
|
+
* Stream only the financial evidence required by init/status snapshots.
|
|
183
|
+
*
|
|
184
|
+
* Unlike `loadLocalAgentUsage`, this path never derives prompts, file focus,
|
|
185
|
+
* tool activity, or invocation evidence. It deliberately returns the same
|
|
186
|
+
* result contract so callers can preserve the existing evidence and
|
|
187
|
+
* diagnostics vocabulary without maintaining a second loader schema. Codex
|
|
188
|
+
* project attribution intentionally uses only root metadata; home-launched
|
|
189
|
+
* tool-workdir inference remains exclusive to the full qualitative loader.
|
|
190
|
+
*/
|
|
191
|
+
export declare function loadLocalAgentFinancialUsage(options?: LocalAgentFinancialLogOptions): Promise<LocalAgentLogResult>;
|
|
127
192
|
/** Aggregate per-call usage into one UsageRecord per day+agent+model+project. */
|
|
128
193
|
export declare function aggregateCalls(calls: LocalAgentCall[]): UsageRecord[];
|
|
129
194
|
/**
|
|
@@ -132,4 +197,5 @@ export declare function aggregateCalls(calls: LocalAgentCall[]): UsageRecord[];
|
|
|
132
197
|
* This intentionally favors dropping a suspicious token over displaying it.
|
|
133
198
|
*/
|
|
134
199
|
export declare function sanitizeLocalActivityText(value: string): string;
|
|
200
|
+
export {};
|
|
135
201
|
//# sourceMappingURL=localAgentLogs.d.ts.map
|