@genesislcap/ai-assistant 15.4.1 → 15.6.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 +571 -82
- package/dist/ai-assistant.d.ts +336 -36
- package/dist/chat-driver.cjs +104 -26
- package/dist/chat-driver.cjs.map +3 -3
- package/dist/chat-driver.mjs +104 -26
- package/dist/chat-driver.mjs.map +3 -3
- package/dist/custom-elements.json +314 -36
- package/dist/dts/components/chat-driver/chat-driver.d.ts +12 -0
- 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/condense-history.d.ts +14 -0
- package/dist/dts/utils/condense-history.d.ts.map +1 -1
- 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 +9 -1
- 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/condense-history.js +18 -5
- package/dist/esm/utils/condense-history.test.js +67 -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 +21 -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/condense-history.test.ts +103 -0
- package/src/utils/condense-history.ts +33 -3
- 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,
|
|
@@ -2769,6 +2796,9 @@ function estimateTokensSaved(origLen, stubLen) {
|
|
|
2769
2796
|
function applyCondensation(history, policies, ctx, onCondensed) {
|
|
2770
2797
|
if (policies.size === 0) return history;
|
|
2771
2798
|
const triggersOf = (entry) => Array.isArray(entry.policy.on) ? entry.policy.on : [entry.policy.on];
|
|
2799
|
+
const batchCalls = Math.max(1, Math.floor(ctx.batchCalls ?? 1));
|
|
2800
|
+
const asOf = batchCalls === 1 ? ctx.modelCall : Math.floor(ctx.modelCall / batchCalls) * batchCalls;
|
|
2801
|
+
const withinBatch = (entry) => batchCalls === 1 || entry.iteration <= asOf;
|
|
2772
2802
|
const latestByKey = /* @__PURE__ */ new Map();
|
|
2773
2803
|
const nameById = /* @__PURE__ */ new Map();
|
|
2774
2804
|
for (const msg of history) {
|
|
@@ -2776,7 +2806,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
|
|
|
2776
2806
|
for (const tc of msg.toolCalls) {
|
|
2777
2807
|
nameById.set(tc.id, tc.name);
|
|
2778
2808
|
const entry = policies.get(tc.id);
|
|
2779
|
-
if (!entry) continue;
|
|
2809
|
+
if (!entry || !withinBatch(entry)) continue;
|
|
2780
2810
|
for (const t of triggersOf(entry)) {
|
|
2781
2811
|
if (t.kind === "superseded") latestByKey.set(t.by, tc.id);
|
|
2782
2812
|
}
|
|
@@ -2788,7 +2818,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
|
|
|
2788
2818
|
// past the last allowed view: turns:1 → seen once, then gone. Monotonic
|
|
2789
2819
|
// clock, so this holds across turn boundaries too.
|
|
2790
2820
|
case "age":
|
|
2791
|
-
return
|
|
2821
|
+
return asOf - entry.iteration > trig.turns;
|
|
2792
2822
|
case "turnEnd":
|
|
2793
2823
|
return ctx.turn > entry.turn;
|
|
2794
2824
|
case "agentEnd":
|
|
@@ -2802,7 +2832,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
|
|
|
2802
2832
|
return latestByKey.get(trig.by) !== toolCallId;
|
|
2803
2833
|
}
|
|
2804
2834
|
};
|
|
2805
|
-
const firstFired = (toolCallId, entry) => triggersOf(entry).find((t) => triggerFires(toolCallId, entry, t));
|
|
2835
|
+
const firstFired = (toolCallId, entry) => withinBatch(entry) ? triggersOf(entry).find((t) => triggerFires(toolCallId, entry, t)) : void 0;
|
|
2806
2836
|
return history.map((msg) => {
|
|
2807
2837
|
if (msg.toolCalls?.length) {
|
|
2808
2838
|
let changed = false;
|
|
@@ -2950,6 +2980,46 @@ The above summarizes earlier parts of this conversation that were compacted. Con
|
|
|
2950
2980
|
});
|
|
2951
2981
|
}
|
|
2952
2982
|
|
|
2983
|
+
// src/utils/sum-usage.ts
|
|
2984
|
+
function emptyUsage() {
|
|
2985
|
+
return {
|
|
2986
|
+
costUsd: 0,
|
|
2987
|
+
uncachedInputTokens: 0,
|
|
2988
|
+
cacheReadTokens: 0,
|
|
2989
|
+
cacheWriteTokens: 0,
|
|
2990
|
+
outputTokens: 0
|
|
2991
|
+
};
|
|
2992
|
+
}
|
|
2993
|
+
function sumUsage(messages) {
|
|
2994
|
+
const total = emptyUsage();
|
|
2995
|
+
accumulate(messages, total);
|
|
2996
|
+
return total;
|
|
2997
|
+
}
|
|
2998
|
+
function addInto(into, from) {
|
|
2999
|
+
into.costUsd += from.costUsd;
|
|
3000
|
+
into.uncachedInputTokens += from.uncachedInputTokens;
|
|
3001
|
+
into.cacheReadTokens += from.cacheReadTokens;
|
|
3002
|
+
into.cacheWriteTokens += from.cacheWriteTokens;
|
|
3003
|
+
into.outputTokens += from.outputTokens;
|
|
3004
|
+
}
|
|
3005
|
+
function accumulate(messages, into) {
|
|
3006
|
+
for (const m of messages) {
|
|
3007
|
+
if (m.cost != null) into.costUsd += m.cost;
|
|
3008
|
+
if (m.externalCostUsd != null) into.costUsd += m.externalCostUsd;
|
|
3009
|
+
const cacheRead = m.cacheReadTokens ?? 0;
|
|
3010
|
+
const cacheWrite = m.cacheWriteTokens ?? 0;
|
|
3011
|
+
into.cacheReadTokens += cacheRead;
|
|
3012
|
+
into.cacheWriteTokens += cacheWrite;
|
|
3013
|
+
into.uncachedInputTokens += Math.max(0, (m.inputTokens ?? 0) - cacheRead - cacheWrite);
|
|
3014
|
+
into.outputTokens += m.outputTokens ?? 0;
|
|
3015
|
+
const rolled = m.compaction?.rolledUpUsage;
|
|
3016
|
+
if (rolled) addInto(into, rolled);
|
|
3017
|
+
for (const tc of m.toolCalls ?? []) {
|
|
3018
|
+
if (tc.subAgentTrace) accumulate(tc.subAgentTrace, into);
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
|
|
2953
3023
|
// src/utils/tool-fold.ts
|
|
2954
3024
|
var TOOL_FOLD_SYMBOL = Symbol("toolFold");
|
|
2955
3025
|
|
|
@@ -3143,11 +3213,13 @@ var ChatDriver = class _ChatDriver extends EventTarget {
|
|
|
3143
3213
|
primerHistory,
|
|
3144
3214
|
maxToolIterations = DEFAULT_MAX_TOOL_ITERATIONS,
|
|
3145
3215
|
maxFoldOperations = DEFAULT_MAX_FOLD_OPERATIONS,
|
|
3216
|
+
condenseBatchCalls = 1,
|
|
3146
3217
|
maxTurnSnapshots = DEFAULT_MAX_TURN_SNAPSHOTS,
|
|
3147
3218
|
sessionKey = "",
|
|
3148
3219
|
activityBus = NOOP_ACTIVITY_BUS
|
|
3149
3220
|
} = config;
|
|
3150
3221
|
this.maxToolIterations = maxToolIterations;
|
|
3222
|
+
this.condenseBatchCalls = condenseBatchCalls;
|
|
3151
3223
|
this.sessionKey = sessionKey;
|
|
3152
3224
|
this.activityBus = activityBus;
|
|
3153
3225
|
if (typeof toolHandlers === "function") {
|
|
@@ -3697,7 +3769,12 @@ Output format (strict):
|
|
|
3697
3769
|
coveredThroughTimestamp: toCompact[toCompact.length - 1]?.timestamp,
|
|
3698
3770
|
tokensBefore,
|
|
3699
3771
|
model: status?.model,
|
|
3700
|
-
createdAt
|
|
3772
|
+
createdAt,
|
|
3773
|
+
// Bank what the replaced turns spent. `toCompact` is dropped from history
|
|
3774
|
+
// below, taking its per-message cost/token fields with it — so a host total
|
|
3775
|
+
// re-derived from the transcript would otherwise fall by exactly this much
|
|
3776
|
+
// on every compaction. Summarising a turn does not refund what it cost.
|
|
3777
|
+
rolledUpUsage: sumUsage(toCompact)
|
|
3701
3778
|
}
|
|
3702
3779
|
};
|
|
3703
3780
|
this.loadHistory([summaryMessage, ...tail]);
|
|
@@ -4381,7 +4458,8 @@ Output format (strict):
|
|
|
4381
4458
|
activationEnded: (activation) => activation < this.currentActivation,
|
|
4382
4459
|
// A call's phase has ended once the app declared a later phase epoch
|
|
4383
4460
|
// current via `endPhase()`.
|
|
4384
|
-
phaseEnded: (phaseEpoch) => phaseEpoch < this.currentPhaseEpoch
|
|
4461
|
+
phaseEnded: (phaseEpoch) => phaseEpoch < this.currentPhaseEpoch,
|
|
4462
|
+
batchCalls: this.condenseBatchCalls
|
|
4385
4463
|
},
|
|
4386
4464
|
(detail) => recordMetaEvent(this.sessionKey, "context.condensed", detail)
|
|
4387
4465
|
);
|