kimiflare 0.67.0 → 0.68.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/dist/index.js +92 -2
- package/dist/index.js.map +1 -1
- package/dist/sdk/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6322,6 +6322,12 @@ var init_renderer = __esm({
|
|
|
6322
6322
|
});
|
|
6323
6323
|
|
|
6324
6324
|
// src/cost-attribution/reconcile.ts
|
|
6325
|
+
var reconcile_exports = {};
|
|
6326
|
+
__export(reconcile_exports, {
|
|
6327
|
+
aggregateByFeature: () => aggregateByFeature,
|
|
6328
|
+
fetchGatewayLogs: () => fetchGatewayLogs,
|
|
6329
|
+
reconcileWithCloudflare: () => reconcileWithCloudflare
|
|
6330
|
+
});
|
|
6325
6331
|
function cacheKey(opts2) {
|
|
6326
6332
|
return `${opts2.gatewayId ?? "none"}:${opts2.startDate}:${opts2.endDate}`;
|
|
6327
6333
|
}
|
|
@@ -6360,6 +6366,28 @@ async function fetchGatewayLogs(accountId, apiToken, gatewayId, startDate, endDa
|
|
|
6360
6366
|
}
|
|
6361
6367
|
return out;
|
|
6362
6368
|
}
|
|
6369
|
+
function aggregateByFeature(logs) {
|
|
6370
|
+
const map = /* @__PURE__ */ new Map();
|
|
6371
|
+
for (const log2 of logs) {
|
|
6372
|
+
let feature = "unknown";
|
|
6373
|
+
const m = log2.metadata;
|
|
6374
|
+
if (m && typeof m === "object" && !Array.isArray(m)) {
|
|
6375
|
+
const f = m.feature;
|
|
6376
|
+
if (typeof f === "string") feature = f;
|
|
6377
|
+
} else if (typeof m === "string") {
|
|
6378
|
+
try {
|
|
6379
|
+
const parsed = JSON.parse(m);
|
|
6380
|
+
if (typeof parsed.feature === "string") feature = parsed.feature;
|
|
6381
|
+
} catch {
|
|
6382
|
+
}
|
|
6383
|
+
}
|
|
6384
|
+
const entry = map.get(feature) ?? { feature, cost: 0, requests: 0 };
|
|
6385
|
+
entry.cost += typeof log2.cost === "number" ? log2.cost : 0;
|
|
6386
|
+
entry.requests += 1;
|
|
6387
|
+
map.set(feature, entry);
|
|
6388
|
+
}
|
|
6389
|
+
return Array.from(map.values()).sort((a, b) => b.cost - a.cost);
|
|
6390
|
+
}
|
|
6363
6391
|
async function reconcileWithCloudflare(opts2) {
|
|
6364
6392
|
if (!opts2.accountId || !opts2.apiToken) {
|
|
6365
6393
|
return {
|
|
@@ -6399,7 +6427,8 @@ async function reconcileWithCloudflare(opts2) {
|
|
|
6399
6427
|
localCost: opts2.localCost,
|
|
6400
6428
|
cloudflareCost,
|
|
6401
6429
|
driftPct: Math.round(driftPct * 1e3) / 10,
|
|
6402
|
-
message: `Reconciled ${logs.length} Gateway log entries
|
|
6430
|
+
message: `Reconciled ${logs.length} Gateway log entries`,
|
|
6431
|
+
featureBreakdown: aggregateByFeature(logs)
|
|
6403
6432
|
};
|
|
6404
6433
|
cache.set(key, { result, expires: Date.now() + 60 * 60 * 1e3 });
|
|
6405
6434
|
return result;
|
|
@@ -9459,7 +9488,8 @@ async function getCostReport(sessionId) {
|
|
|
9459
9488
|
gatewayRequests: rawSession.gatewayRequests,
|
|
9460
9489
|
gatewayCachedRequests: rawSession.gatewayCachedRequests,
|
|
9461
9490
|
gatewayCost: rawSession.gatewayCost,
|
|
9462
|
-
reconcilePending: hasPendingReconcile(rawSession)
|
|
9491
|
+
reconcilePending: hasPendingReconcile(rawSession),
|
|
9492
|
+
lastTurnMs: latestConfirmedDurationMs(rawSession)
|
|
9463
9493
|
} : { date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 };
|
|
9464
9494
|
const todayUsage = log2.days.find((d) => d.date === date) ?? { date, promptTokens: 0, completionTokens: 0, cachedTokens: 0, cost: 0 };
|
|
9465
9495
|
const monthUsage = {
|
|
@@ -9504,6 +9534,14 @@ function hasPendingReconcile(session) {
|
|
|
9504
9534
|
(t) => t.logId && t.confirmedCost === void 0 && !t.reconcileFailed
|
|
9505
9535
|
);
|
|
9506
9536
|
}
|
|
9537
|
+
function latestConfirmedDurationMs(session) {
|
|
9538
|
+
if (!session.turns) return void 0;
|
|
9539
|
+
for (let i = session.turns.length - 1; i >= 0; i--) {
|
|
9540
|
+
const ms = session.turns[i]?.durationMs;
|
|
9541
|
+
if (typeof ms === "number") return ms;
|
|
9542
|
+
}
|
|
9543
|
+
return void 0;
|
|
9544
|
+
}
|
|
9507
9545
|
async function getSessionGatewayLogs(sessionId) {
|
|
9508
9546
|
const log2 = await loadLog2();
|
|
9509
9547
|
const session = log2.sessions.find((s) => s.id === sessionId);
|
|
@@ -9549,6 +9587,17 @@ function formatGatewaySection(report, accountId, gatewayId, recentLogs2 = []) {
|
|
|
9549
9587
|
);
|
|
9550
9588
|
return lines.join("\n");
|
|
9551
9589
|
}
|
|
9590
|
+
function formatFeatureBreakdown(breakdown) {
|
|
9591
|
+
if (!breakdown || breakdown.length === 0) return "";
|
|
9592
|
+
if (breakdown.length === 1 && breakdown[0].feature === "unknown") return "";
|
|
9593
|
+
const lines = ["\u2500\u2500\u2500 By feature (Gateway-confirmed) \u2500\u2500\u2500"];
|
|
9594
|
+
for (const row of breakdown) {
|
|
9595
|
+
lines.push(
|
|
9596
|
+
` ${row.feature.padEnd(20)} $${row.cost.toFixed(4)} (${row.requests} req)`
|
|
9597
|
+
);
|
|
9598
|
+
}
|
|
9599
|
+
return lines.join("\n");
|
|
9600
|
+
}
|
|
9552
9601
|
function formatCostReport(report) {
|
|
9553
9602
|
const lines = [];
|
|
9554
9603
|
const add = (label, u) => {
|
|
@@ -11752,6 +11801,9 @@ function buildRightParts(usage, contextLimit, sessionUsage, gatewayMeta, cloudMo
|
|
|
11752
11801
|
} else {
|
|
11753
11802
|
parts.push(`${prefix}${sessionUsage.cost.toFixed(2)}`);
|
|
11754
11803
|
}
|
|
11804
|
+
if (typeof sessionUsage.lastTurnMs === "number") {
|
|
11805
|
+
parts.push(formatDuration(sessionUsage.lastTurnMs));
|
|
11806
|
+
}
|
|
11755
11807
|
} else {
|
|
11756
11808
|
const cached = usage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
11757
11809
|
const cost = calculateCost(usage.prompt_tokens, usage.completion_tokens, cached);
|
|
@@ -11780,6 +11832,10 @@ function formatGatewayCacheStatus(gatewayMeta) {
|
|
|
11780
11832
|
const status = gatewayMeta?.cacheStatus?.trim();
|
|
11781
11833
|
return status ? `AI Gateway \xB7 cache ${status.toLowerCase()}` : null;
|
|
11782
11834
|
}
|
|
11835
|
+
function formatDuration(ms) {
|
|
11836
|
+
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
11837
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
11838
|
+
}
|
|
11783
11839
|
function formatElapsed2(ms) {
|
|
11784
11840
|
const total = Math.floor(ms / 1e3);
|
|
11785
11841
|
const m = Math.floor(total / 60);
|
|
@@ -20079,6 +20135,22 @@ ${wcagWarnings.join("\n")}` }
|
|
|
20079
20135
|
const logs = sid ? await getSessionGatewayLogs(sid).catch(() => []) : [];
|
|
20080
20136
|
const gwSection = formatGatewaySection(report, cfg.accountId, cfg.aiGatewayId, logs);
|
|
20081
20137
|
if (gwSection) lines.push("", gwSection);
|
|
20138
|
+
try {
|
|
20139
|
+
const { reconcileWithCloudflare: reconcileWithCloudflare2 } = await Promise.resolve().then(() => (init_reconcile(), reconcile_exports));
|
|
20140
|
+
const today4 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
20141
|
+
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1e3).toISOString().slice(0, 10);
|
|
20142
|
+
const recon = await reconcileWithCloudflare2({
|
|
20143
|
+
localCost: report.month.cost,
|
|
20144
|
+
accountId: cfg.accountId,
|
|
20145
|
+
apiToken: cfg.apiToken,
|
|
20146
|
+
gatewayId: cfg.aiGatewayId,
|
|
20147
|
+
startDate: sevenDaysAgo,
|
|
20148
|
+
endDate: today4
|
|
20149
|
+
});
|
|
20150
|
+
const breakdown = formatFeatureBreakdown(recon.featureBreakdown);
|
|
20151
|
+
if (breakdown) lines.push("", breakdown);
|
|
20152
|
+
} catch {
|
|
20153
|
+
}
|
|
20082
20154
|
}
|
|
20083
20155
|
if (cfg?.costAttribution) {
|
|
20084
20156
|
const { getCategoryReportText: getCategoryReportText2 } = await Promise.resolve().then(() => (init_tui_report(), tui_report_exports));
|
|
@@ -20156,6 +20228,24 @@ ${wcagWarnings.join("\n")}` }
|
|
|
20156
20228
|
lines.push(`collect-logs: ${cfg.aiGatewayCollectLogPayload ?? false}`);
|
|
20157
20229
|
const meta = cfg.aiGatewayMetadata;
|
|
20158
20230
|
lines.push(`metadata: ${meta && Object.keys(meta).length > 0 ? JSON.stringify(meta) : "none"}`);
|
|
20231
|
+
const sid = sessionIdRef.current;
|
|
20232
|
+
if (sid) {
|
|
20233
|
+
void getCostReport(sid).then((report) => {
|
|
20234
|
+
const req = report.session.gatewayRequests ?? 0;
|
|
20235
|
+
if (req === 0) return;
|
|
20236
|
+
const cached = report.session.gatewayCachedRequests ?? 0;
|
|
20237
|
+
const pct = (cached / req * 100).toFixed(1);
|
|
20238
|
+
setEvents((e) => [
|
|
20239
|
+
...e,
|
|
20240
|
+
{
|
|
20241
|
+
kind: "info",
|
|
20242
|
+
key: mkKey(),
|
|
20243
|
+
text: `cache hits (session): ${cached}/${req} (${pct}%)`
|
|
20244
|
+
}
|
|
20245
|
+
]);
|
|
20246
|
+
}).catch(() => {
|
|
20247
|
+
});
|
|
20248
|
+
}
|
|
20159
20249
|
} else {
|
|
20160
20250
|
lines.push("gateway: off (direct Workers AI)");
|
|
20161
20251
|
}
|