@genesislcap/ai-assistant 15.4.1 → 15.5.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/ai-assistant.api.json +544 -82
- package/dist/ai-assistant.d.ts +324 -36
- package/dist/chat-driver.cjs +94 -22
- package/dist/chat-driver.cjs.map +3 -3
- package/dist/chat-driver.mjs +94 -22
- package/dist/chat-driver.mjs.map +3 -3
- package/dist/custom-elements.json +303 -36
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/settings-modal/settings-modal.styles.d.ts.map +1 -1
- package/dist/dts/components/settings-modal/settings-modal.template.d.ts +9 -2
- package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
- package/dist/dts/index.d.ts +1 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/main/cost-session-banking.test.d.ts +2 -0
- package/dist/dts/main/cost-session-banking.test.d.ts.map +1 -0
- package/dist/dts/main/main.d.ts +184 -24
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/provider/assistant-app-settings.d.ts +30 -5
- package/dist/dts/provider/assistant-app-settings.d.ts.map +1 -1
- package/dist/dts/state/ai-assistant-slice.d.ts +11 -8
- package/dist/dts/state/ai-assistant-slice.d.ts.map +1 -1
- package/dist/dts/state/persistence/session-persistence-provider.d.ts +23 -0
- package/dist/dts/state/persistence/session-persistence-provider.d.ts.map +1 -1
- package/dist/dts/state/persistence/session-snapshot.d.ts.map +1 -1
- package/dist/dts/state/session-store.d.ts +1 -2
- package/dist/dts/state/session-store.d.ts.map +1 -1
- package/dist/dts/styles/settings-section.d.ts +29 -0
- package/dist/dts/styles/settings-section.d.ts.map +1 -0
- package/dist/dts/utils/cost-session-history.d.ts +103 -12
- package/dist/dts/utils/cost-session-history.d.ts.map +1 -1
- package/dist/dts/utils/resolve-cost-history-config.d.ts +9 -3
- package/dist/dts/utils/resolve-cost-history-config.d.ts.map +1 -1
- package/dist/dts/utils/sum-costs.d.ts.map +1 -1
- package/dist/dts/utils/sum-tokens.d.ts +8 -8
- package/dist/dts/utils/sum-tokens.d.ts.map +1 -1
- package/dist/dts/utils/sum-usage.d.ts +59 -0
- package/dist/dts/utils/sum-usage.d.ts.map +1 -0
- package/dist/dts/utils/sum-usage.test.d.ts +2 -0
- package/dist/dts/utils/sum-usage.test.d.ts.map +1 -0
- package/dist/esm/components/chat-driver/chat-driver.js +6 -0
- package/dist/esm/components/settings-modal/settings-modal.styles.js +237 -18
- package/dist/esm/components/settings-modal/settings-modal.template.js +229 -73
- package/dist/esm/index.js +1 -0
- package/dist/esm/main/cost-session-banking.test.js +308 -0
- package/dist/esm/main/main.js +424 -71
- package/dist/esm/state/ai-assistant-slice.js +11 -8
- package/dist/esm/state/ai-assistant-slice.test.js +12 -5
- package/dist/esm/state/debug-event-log.js +2 -2
- package/dist/esm/state/persistence/session-persistence.integration.test.js +5 -1
- package/dist/esm/state/persistence/session-persister.js +2 -2
- package/dist/esm/state/persistence/session-persister.test.js +10 -1
- package/dist/esm/state/persistence/session-snapshot.js +6 -2
- package/dist/esm/state/persistence/session-snapshot.test.js +4 -1
- package/dist/esm/state/persistence/stateful-restore.e2e.test.js +10 -1
- package/dist/esm/styles/settings-section.js +39 -0
- package/dist/esm/utils/cost-session-history.js +92 -15
- package/dist/esm/utils/cost-session-history.test.js +155 -13
- package/dist/esm/utils/resolve-cost-history-config.js +2 -1
- package/dist/esm/utils/sum-costs.js +2 -13
- package/dist/esm/utils/sum-tokens.js +10 -27
- package/dist/esm/utils/sum-tokens.test.js +1 -5
- package/dist/esm/utils/sum-usage.js +123 -0
- package/dist/esm/utils/sum-usage.test.js +120 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -17
- package/src/components/chat-driver/chat-driver.ts +6 -0
- package/src/components/settings-modal/settings-modal.styles.ts +237 -18
- package/src/components/settings-modal/settings-modal.template.ts +270 -81
- package/src/index.ts +1 -0
- package/src/main/cost-session-banking.test.ts +407 -0
- package/src/main/main.ts +433 -68
- package/src/provider/assistant-app-settings.ts +31 -5
- package/src/state/ai-assistant-slice.test.ts +12 -5
- package/src/state/ai-assistant-slice.ts +21 -13
- package/src/state/debug-event-log.ts +2 -2
- package/src/state/persistence/session-persistence-provider.ts +24 -0
- package/src/state/persistence/session-persistence.integration.test.ts +8 -1
- package/src/state/persistence/session-persister.test.ts +10 -1
- package/src/state/persistence/session-persister.ts +2 -2
- package/src/state/persistence/session-snapshot.test.ts +4 -1
- package/src/state/persistence/session-snapshot.ts +5 -1
- package/src/state/persistence/stateful-restore.e2e.test.ts +9 -1
- package/src/styles/settings-section.ts +40 -0
- package/src/utils/cost-session-history.test.ts +187 -16
- package/src/utils/cost-session-history.ts +142 -23
- package/src/utils/resolve-cost-history-config.ts +10 -3
- package/src/utils/sum-costs.ts +2 -9
- package/src/utils/sum-tokens.test.ts +1 -11
- package/src/utils/sum-tokens.ts +10 -26
- package/src/utils/sum-usage.test.ts +140 -0
- package/src/utils/sum-usage.ts +130 -0
package/dist/chat-driver.mjs
CHANGED
|
@@ -1518,6 +1518,8 @@ ${att.content}` });
|
|
|
1518
1518
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1519
1519
|
let inputTokens;
|
|
1520
1520
|
let outputTokens;
|
|
1521
|
+
let cacheReadTokens;
|
|
1522
|
+
let cacheWriteTokens;
|
|
1521
1523
|
let cost;
|
|
1522
1524
|
if (response.usage) {
|
|
1523
1525
|
const uncachedInput = (_a = response.usage.input_tokens) !== null && _a !== void 0 ? _a : 0;
|
|
@@ -1527,6 +1529,8 @@ ${att.content}` });
|
|
|
1527
1529
|
const cacheCreation = (_d = response.usage.cache_creation_input_tokens) !== null && _d !== void 0 ? _d : breakdown ? ((_e = breakdown.ephemeral_5m_input_tokens) !== null && _e !== void 0 ? _e : 0) + cacheCreation1h : 0;
|
|
1528
1530
|
cost = this.logTokenUsage(uncachedInput, (_f = response.usage.output_tokens) !== null && _f !== void 0 ? _f : 0, cacheRead, cacheCreation, cacheCreation1h);
|
|
1529
1531
|
inputTokens = uncachedInput + cacheRead + cacheCreation;
|
|
1532
|
+
cacheReadTokens = cacheRead;
|
|
1533
|
+
cacheWriteTokens = cacheCreation;
|
|
1530
1534
|
if (response.usage.output_tokens != null) {
|
|
1531
1535
|
outputTokens = response.usage.output_tokens;
|
|
1532
1536
|
}
|
|
@@ -1557,6 +1561,10 @@ ${att.content}` });
|
|
|
1557
1561
|
base.inputTokens = inputTokens;
|
|
1558
1562
|
if (outputTokens != null)
|
|
1559
1563
|
base.outputTokens = outputTokens;
|
|
1564
|
+
if (cacheReadTokens != null)
|
|
1565
|
+
base.cacheReadTokens = cacheReadTokens;
|
|
1566
|
+
if (cacheWriteTokens != null)
|
|
1567
|
+
base.cacheWriteTokens = cacheWriteTokens;
|
|
1560
1568
|
if (cost != null)
|
|
1561
1569
|
base.cost = cost;
|
|
1562
1570
|
if (response.stop_reason === "max_tokens") {
|
|
@@ -2083,28 +2091,45 @@ ${att.content}`
|
|
|
2083
2091
|
}
|
|
2084
2092
|
return contents;
|
|
2085
2093
|
}
|
|
2094
|
+
/**
|
|
2095
|
+
* Map Gemini's `usageMetadata` onto the provider-agnostic usage fields, pricing
|
|
2096
|
+
* the call as a side effect (`logTokenUsage`). Returns an empty object when the
|
|
2097
|
+
* response carries no usage — every field is optional, so an absent count stays
|
|
2098
|
+
* `undefined` rather than being reported as a measured 0.
|
|
2099
|
+
*
|
|
2100
|
+
* Split out of `fromGeminiResponse` because it is self-contained bookkeeping
|
|
2101
|
+
* that reads better alone — and because folding it inline pushed that method
|
|
2102
|
+
* past the complexity ceiling.
|
|
2103
|
+
*/
|
|
2104
|
+
usageFromGemini(usageMetadata) {
|
|
2105
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2106
|
+
if (!usageMetadata)
|
|
2107
|
+
return {};
|
|
2108
|
+
const usage = usageMetadata;
|
|
2109
|
+
const cost = this.logTokenUsage((_a = usage.promptTokenCount) !== null && _a !== void 0 ? _a : 0, (_b = usage.candidatesTokenCount) !== null && _b !== void 0 ? _b : 0, (_c = usage.thoughtsTokenCount) !== null && _c !== void 0 ? _c : 0, (_d = usage.cachedContentTokenCount) !== null && _d !== void 0 ? _d : 0);
|
|
2110
|
+
return {
|
|
2111
|
+
inputTokens: usage.promptTokenCount,
|
|
2112
|
+
// Thinking tokens are generated output, billed at the candidate rate, but
|
|
2113
|
+
// reported in a field disjoint from `candidatesTokenCount`. Fold them into the
|
|
2114
|
+
// provider-agnostic `outputTokens` so it reflects the true generated total —
|
|
2115
|
+
// matching Anthropic, whose `output_tokens` already includes them. Left
|
|
2116
|
+
// `undefined` only when the provider reported neither count.
|
|
2117
|
+
outputTokens: usage.candidatesTokenCount != null || usage.thoughtsTokenCount != null ? ((_e = usage.candidatesTokenCount) !== null && _e !== void 0 ? _e : 0) + ((_f = usage.thoughtsTokenCount) !== null && _f !== void 0 ? _f : 0) : void 0,
|
|
2118
|
+
thoughtsTokens: usage.thoughtsTokenCount,
|
|
2119
|
+
// Gemini reports cache HITS only — implicit caching bills no separate write, so
|
|
2120
|
+
// `cacheWriteTokens` is left unset rather than 0 (there is no write bucket to
|
|
2121
|
+
// measure, which is not the same as measuring 0). Already counted inside
|
|
2122
|
+
// `promptTokenCount`, so this breaks that total down rather than adding to it.
|
|
2123
|
+
cacheReadTokens: usage.cachedContentTokenCount,
|
|
2124
|
+
cost
|
|
2125
|
+
};
|
|
2126
|
+
}
|
|
2086
2127
|
fromGeminiResponse(response, offeredToolNames = /* @__PURE__ */ new Set()) {
|
|
2087
|
-
var _a, _b, _c, _d
|
|
2088
|
-
|
|
2089
|
-
let outputTokens;
|
|
2090
|
-
let thoughtsTokens;
|
|
2091
|
-
let cost;
|
|
2092
|
-
if (response.usageMetadata) {
|
|
2093
|
-
const usage = response.usageMetadata;
|
|
2094
|
-
cost = this.logTokenUsage((_a = usage.promptTokenCount) !== null && _a !== void 0 ? _a : 0, (_b = usage.candidatesTokenCount) !== null && _b !== void 0 ? _b : 0, (_c = usage.thoughtsTokenCount) !== null && _c !== void 0 ? _c : 0, (_d = usage.cachedContentTokenCount) !== null && _d !== void 0 ? _d : 0);
|
|
2095
|
-
if (usage.promptTokenCount != null) {
|
|
2096
|
-
inputTokens = usage.promptTokenCount;
|
|
2097
|
-
}
|
|
2098
|
-
if (usage.thoughtsTokenCount != null) {
|
|
2099
|
-
thoughtsTokens = usage.thoughtsTokenCount;
|
|
2100
|
-
}
|
|
2101
|
-
if (usage.candidatesTokenCount != null || usage.thoughtsTokenCount != null) {
|
|
2102
|
-
outputTokens = ((_e = usage.candidatesTokenCount) !== null && _e !== void 0 ? _e : 0) + ((_f = usage.thoughtsTokenCount) !== null && _f !== void 0 ? _f : 0);
|
|
2103
|
-
}
|
|
2104
|
-
}
|
|
2128
|
+
var _a, _b, _c, _d;
|
|
2129
|
+
const { inputTokens, outputTokens, thoughtsTokens, cacheReadTokens, cost } = this.usageFromGemini(response.usageMetadata);
|
|
2105
2130
|
const candidates = response === null || response === void 0 ? void 0 : response.candidates;
|
|
2106
2131
|
const firstCandidate = candidates === null || candidates === void 0 ? void 0 : candidates[0];
|
|
2107
|
-
const parts = (
|
|
2132
|
+
const parts = (_b = (_a = firstCandidate === null || firstCandidate === void 0 ? void 0 : firstCandidate.content) === null || _a === void 0 ? void 0 : _a.parts) !== null && _b !== void 0 ? _b : [];
|
|
2108
2133
|
const toolCalls = [];
|
|
2109
2134
|
const thoughtParts = [];
|
|
2110
2135
|
const textParts = [];
|
|
@@ -2117,7 +2142,7 @@ ${att.content}`
|
|
|
2117
2142
|
toolCalls.push({
|
|
2118
2143
|
id: crypto.randomUUID(),
|
|
2119
2144
|
name: part.functionCall.name,
|
|
2120
|
-
args: (
|
|
2145
|
+
args: (_c = part.functionCall.args) !== null && _c !== void 0 ? _c : {},
|
|
2121
2146
|
providerMetadata: { [GEMINI_PROVIDER_KEY]: state }
|
|
2122
2147
|
});
|
|
2123
2148
|
} else if (part.thought && part.text) {
|
|
@@ -2151,9 +2176,11 @@ ${att.content}`
|
|
|
2151
2176
|
base.inputTokens = inputTokens;
|
|
2152
2177
|
if (outputTokens != null)
|
|
2153
2178
|
base.outputTokens = outputTokens;
|
|
2179
|
+
if (cacheReadTokens != null)
|
|
2180
|
+
base.cacheReadTokens = cacheReadTokens;
|
|
2154
2181
|
if (cost != null)
|
|
2155
2182
|
base.cost = cost;
|
|
2156
|
-
const blockReason = (
|
|
2183
|
+
const blockReason = (_d = response.promptFeedback) === null || _d === void 0 ? void 0 : _d.blockReason;
|
|
2157
2184
|
if (finishReason != null || thoughtsTokens != null || blockReason != null) {
|
|
2158
2185
|
base.responseMeta = {
|
|
2159
2186
|
finishReason,
|
|
@@ -2950,6 +2977,46 @@ The above summarizes earlier parts of this conversation that were compacted. Con
|
|
|
2950
2977
|
});
|
|
2951
2978
|
}
|
|
2952
2979
|
|
|
2980
|
+
// src/utils/sum-usage.ts
|
|
2981
|
+
function emptyUsage() {
|
|
2982
|
+
return {
|
|
2983
|
+
costUsd: 0,
|
|
2984
|
+
uncachedInputTokens: 0,
|
|
2985
|
+
cacheReadTokens: 0,
|
|
2986
|
+
cacheWriteTokens: 0,
|
|
2987
|
+
outputTokens: 0
|
|
2988
|
+
};
|
|
2989
|
+
}
|
|
2990
|
+
function sumUsage(messages) {
|
|
2991
|
+
const total = emptyUsage();
|
|
2992
|
+
accumulate(messages, total);
|
|
2993
|
+
return total;
|
|
2994
|
+
}
|
|
2995
|
+
function addInto(into, from) {
|
|
2996
|
+
into.costUsd += from.costUsd;
|
|
2997
|
+
into.uncachedInputTokens += from.uncachedInputTokens;
|
|
2998
|
+
into.cacheReadTokens += from.cacheReadTokens;
|
|
2999
|
+
into.cacheWriteTokens += from.cacheWriteTokens;
|
|
3000
|
+
into.outputTokens += from.outputTokens;
|
|
3001
|
+
}
|
|
3002
|
+
function accumulate(messages, into) {
|
|
3003
|
+
for (const m of messages) {
|
|
3004
|
+
if (m.cost != null) into.costUsd += m.cost;
|
|
3005
|
+
if (m.externalCostUsd != null) into.costUsd += m.externalCostUsd;
|
|
3006
|
+
const cacheRead = m.cacheReadTokens ?? 0;
|
|
3007
|
+
const cacheWrite = m.cacheWriteTokens ?? 0;
|
|
3008
|
+
into.cacheReadTokens += cacheRead;
|
|
3009
|
+
into.cacheWriteTokens += cacheWrite;
|
|
3010
|
+
into.uncachedInputTokens += Math.max(0, (m.inputTokens ?? 0) - cacheRead - cacheWrite);
|
|
3011
|
+
into.outputTokens += m.outputTokens ?? 0;
|
|
3012
|
+
const rolled = m.compaction?.rolledUpUsage;
|
|
3013
|
+
if (rolled) addInto(into, rolled);
|
|
3014
|
+
for (const tc of m.toolCalls ?? []) {
|
|
3015
|
+
if (tc.subAgentTrace) accumulate(tc.subAgentTrace, into);
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
|
|
2953
3020
|
// src/utils/tool-fold.ts
|
|
2954
3021
|
var TOOL_FOLD_SYMBOL = Symbol("toolFold");
|
|
2955
3022
|
|
|
@@ -3697,7 +3764,12 @@ Output format (strict):
|
|
|
3697
3764
|
coveredThroughTimestamp: toCompact[toCompact.length - 1]?.timestamp,
|
|
3698
3765
|
tokensBefore,
|
|
3699
3766
|
model: status?.model,
|
|
3700
|
-
createdAt
|
|
3767
|
+
createdAt,
|
|
3768
|
+
// Bank what the replaced turns spent. `toCompact` is dropped from history
|
|
3769
|
+
// below, taking its per-message cost/token fields with it — so a host total
|
|
3770
|
+
// re-derived from the transcript would otherwise fall by exactly this much
|
|
3771
|
+
// on every compaction. Summarising a turn does not refund what it cost.
|
|
3772
|
+
rolledUpUsage: sumUsage(toCompact)
|
|
3701
3773
|
}
|
|
3702
3774
|
};
|
|
3703
3775
|
this.loadHistory([summaryMessage, ...tail]);
|