@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.cjs
CHANGED
|
@@ -1565,6 +1565,8 @@ ${att.content}` });
|
|
|
1565
1565
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1566
1566
|
let inputTokens;
|
|
1567
1567
|
let outputTokens;
|
|
1568
|
+
let cacheReadTokens;
|
|
1569
|
+
let cacheWriteTokens;
|
|
1568
1570
|
let cost;
|
|
1569
1571
|
if (response.usage) {
|
|
1570
1572
|
const uncachedInput = (_a = response.usage.input_tokens) !== null && _a !== void 0 ? _a : 0;
|
|
@@ -1574,6 +1576,8 @@ ${att.content}` });
|
|
|
1574
1576
|
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;
|
|
1575
1577
|
cost = this.logTokenUsage(uncachedInput, (_f = response.usage.output_tokens) !== null && _f !== void 0 ? _f : 0, cacheRead, cacheCreation, cacheCreation1h);
|
|
1576
1578
|
inputTokens = uncachedInput + cacheRead + cacheCreation;
|
|
1579
|
+
cacheReadTokens = cacheRead;
|
|
1580
|
+
cacheWriteTokens = cacheCreation;
|
|
1577
1581
|
if (response.usage.output_tokens != null) {
|
|
1578
1582
|
outputTokens = response.usage.output_tokens;
|
|
1579
1583
|
}
|
|
@@ -1604,6 +1608,10 @@ ${att.content}` });
|
|
|
1604
1608
|
base.inputTokens = inputTokens;
|
|
1605
1609
|
if (outputTokens != null)
|
|
1606
1610
|
base.outputTokens = outputTokens;
|
|
1611
|
+
if (cacheReadTokens != null)
|
|
1612
|
+
base.cacheReadTokens = cacheReadTokens;
|
|
1613
|
+
if (cacheWriteTokens != null)
|
|
1614
|
+
base.cacheWriteTokens = cacheWriteTokens;
|
|
1607
1615
|
if (cost != null)
|
|
1608
1616
|
base.cost = cost;
|
|
1609
1617
|
if (response.stop_reason === "max_tokens") {
|
|
@@ -2130,28 +2138,45 @@ ${att.content}`
|
|
|
2130
2138
|
}
|
|
2131
2139
|
return contents;
|
|
2132
2140
|
}
|
|
2141
|
+
/**
|
|
2142
|
+
* Map Gemini's `usageMetadata` onto the provider-agnostic usage fields, pricing
|
|
2143
|
+
* the call as a side effect (`logTokenUsage`). Returns an empty object when the
|
|
2144
|
+
* response carries no usage — every field is optional, so an absent count stays
|
|
2145
|
+
* `undefined` rather than being reported as a measured 0.
|
|
2146
|
+
*
|
|
2147
|
+
* Split out of `fromGeminiResponse` because it is self-contained bookkeeping
|
|
2148
|
+
* that reads better alone — and because folding it inline pushed that method
|
|
2149
|
+
* past the complexity ceiling.
|
|
2150
|
+
*/
|
|
2151
|
+
usageFromGemini(usageMetadata) {
|
|
2152
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2153
|
+
if (!usageMetadata)
|
|
2154
|
+
return {};
|
|
2155
|
+
const usage = usageMetadata;
|
|
2156
|
+
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);
|
|
2157
|
+
return {
|
|
2158
|
+
inputTokens: usage.promptTokenCount,
|
|
2159
|
+
// Thinking tokens are generated output, billed at the candidate rate, but
|
|
2160
|
+
// reported in a field disjoint from `candidatesTokenCount`. Fold them into the
|
|
2161
|
+
// provider-agnostic `outputTokens` so it reflects the true generated total —
|
|
2162
|
+
// matching Anthropic, whose `output_tokens` already includes them. Left
|
|
2163
|
+
// `undefined` only when the provider reported neither count.
|
|
2164
|
+
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,
|
|
2165
|
+
thoughtsTokens: usage.thoughtsTokenCount,
|
|
2166
|
+
// Gemini reports cache HITS only — implicit caching bills no separate write, so
|
|
2167
|
+
// `cacheWriteTokens` is left unset rather than 0 (there is no write bucket to
|
|
2168
|
+
// measure, which is not the same as measuring 0). Already counted inside
|
|
2169
|
+
// `promptTokenCount`, so this breaks that total down rather than adding to it.
|
|
2170
|
+
cacheReadTokens: usage.cachedContentTokenCount,
|
|
2171
|
+
cost
|
|
2172
|
+
};
|
|
2173
|
+
}
|
|
2133
2174
|
fromGeminiResponse(response, offeredToolNames = /* @__PURE__ */ new Set()) {
|
|
2134
|
-
var _a, _b, _c, _d
|
|
2135
|
-
|
|
2136
|
-
let outputTokens;
|
|
2137
|
-
let thoughtsTokens;
|
|
2138
|
-
let cost;
|
|
2139
|
-
if (response.usageMetadata) {
|
|
2140
|
-
const usage = response.usageMetadata;
|
|
2141
|
-
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);
|
|
2142
|
-
if (usage.promptTokenCount != null) {
|
|
2143
|
-
inputTokens = usage.promptTokenCount;
|
|
2144
|
-
}
|
|
2145
|
-
if (usage.thoughtsTokenCount != null) {
|
|
2146
|
-
thoughtsTokens = usage.thoughtsTokenCount;
|
|
2147
|
-
}
|
|
2148
|
-
if (usage.candidatesTokenCount != null || usage.thoughtsTokenCount != null) {
|
|
2149
|
-
outputTokens = ((_e = usage.candidatesTokenCount) !== null && _e !== void 0 ? _e : 0) + ((_f = usage.thoughtsTokenCount) !== null && _f !== void 0 ? _f : 0);
|
|
2150
|
-
}
|
|
2151
|
-
}
|
|
2175
|
+
var _a, _b, _c, _d;
|
|
2176
|
+
const { inputTokens, outputTokens, thoughtsTokens, cacheReadTokens, cost } = this.usageFromGemini(response.usageMetadata);
|
|
2152
2177
|
const candidates = response === null || response === void 0 ? void 0 : response.candidates;
|
|
2153
2178
|
const firstCandidate = candidates === null || candidates === void 0 ? void 0 : candidates[0];
|
|
2154
|
-
const parts = (
|
|
2179
|
+
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 : [];
|
|
2155
2180
|
const toolCalls = [];
|
|
2156
2181
|
const thoughtParts = [];
|
|
2157
2182
|
const textParts = [];
|
|
@@ -2164,7 +2189,7 @@ ${att.content}`
|
|
|
2164
2189
|
toolCalls.push({
|
|
2165
2190
|
id: crypto.randomUUID(),
|
|
2166
2191
|
name: part.functionCall.name,
|
|
2167
|
-
args: (
|
|
2192
|
+
args: (_c = part.functionCall.args) !== null && _c !== void 0 ? _c : {},
|
|
2168
2193
|
providerMetadata: { [GEMINI_PROVIDER_KEY]: state }
|
|
2169
2194
|
});
|
|
2170
2195
|
} else if (part.thought && part.text) {
|
|
@@ -2198,9 +2223,11 @@ ${att.content}`
|
|
|
2198
2223
|
base.inputTokens = inputTokens;
|
|
2199
2224
|
if (outputTokens != null)
|
|
2200
2225
|
base.outputTokens = outputTokens;
|
|
2226
|
+
if (cacheReadTokens != null)
|
|
2227
|
+
base.cacheReadTokens = cacheReadTokens;
|
|
2201
2228
|
if (cost != null)
|
|
2202
2229
|
base.cost = cost;
|
|
2203
|
-
const blockReason = (
|
|
2230
|
+
const blockReason = (_d = response.promptFeedback) === null || _d === void 0 ? void 0 : _d.blockReason;
|
|
2204
2231
|
if (finishReason != null || thoughtsTokens != null || blockReason != null) {
|
|
2205
2232
|
base.responseMeta = {
|
|
2206
2233
|
finishReason,
|
|
@@ -2816,6 +2843,9 @@ function estimateTokensSaved(origLen, stubLen) {
|
|
|
2816
2843
|
function applyCondensation(history, policies, ctx, onCondensed) {
|
|
2817
2844
|
if (policies.size === 0) return history;
|
|
2818
2845
|
const triggersOf = (entry) => Array.isArray(entry.policy.on) ? entry.policy.on : [entry.policy.on];
|
|
2846
|
+
const batchCalls = Math.max(1, Math.floor(ctx.batchCalls ?? 1));
|
|
2847
|
+
const asOf = batchCalls === 1 ? ctx.modelCall : Math.floor(ctx.modelCall / batchCalls) * batchCalls;
|
|
2848
|
+
const withinBatch = (entry) => batchCalls === 1 || entry.iteration <= asOf;
|
|
2819
2849
|
const latestByKey = /* @__PURE__ */ new Map();
|
|
2820
2850
|
const nameById = /* @__PURE__ */ new Map();
|
|
2821
2851
|
for (const msg of history) {
|
|
@@ -2823,7 +2853,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
|
|
|
2823
2853
|
for (const tc of msg.toolCalls) {
|
|
2824
2854
|
nameById.set(tc.id, tc.name);
|
|
2825
2855
|
const entry = policies.get(tc.id);
|
|
2826
|
-
if (!entry) continue;
|
|
2856
|
+
if (!entry || !withinBatch(entry)) continue;
|
|
2827
2857
|
for (const t of triggersOf(entry)) {
|
|
2828
2858
|
if (t.kind === "superseded") latestByKey.set(t.by, tc.id);
|
|
2829
2859
|
}
|
|
@@ -2835,7 +2865,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
|
|
|
2835
2865
|
// past the last allowed view: turns:1 → seen once, then gone. Monotonic
|
|
2836
2866
|
// clock, so this holds across turn boundaries too.
|
|
2837
2867
|
case "age":
|
|
2838
|
-
return
|
|
2868
|
+
return asOf - entry.iteration > trig.turns;
|
|
2839
2869
|
case "turnEnd":
|
|
2840
2870
|
return ctx.turn > entry.turn;
|
|
2841
2871
|
case "agentEnd":
|
|
@@ -2849,7 +2879,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
|
|
|
2849
2879
|
return latestByKey.get(trig.by) !== toolCallId;
|
|
2850
2880
|
}
|
|
2851
2881
|
};
|
|
2852
|
-
const firstFired = (toolCallId, entry) => triggersOf(entry).find((t) => triggerFires(toolCallId, entry, t));
|
|
2882
|
+
const firstFired = (toolCallId, entry) => withinBatch(entry) ? triggersOf(entry).find((t) => triggerFires(toolCallId, entry, t)) : void 0;
|
|
2853
2883
|
return history.map((msg) => {
|
|
2854
2884
|
if (msg.toolCalls?.length) {
|
|
2855
2885
|
let changed = false;
|
|
@@ -2997,6 +3027,46 @@ The above summarizes earlier parts of this conversation that were compacted. Con
|
|
|
2997
3027
|
});
|
|
2998
3028
|
}
|
|
2999
3029
|
|
|
3030
|
+
// src/utils/sum-usage.ts
|
|
3031
|
+
function emptyUsage() {
|
|
3032
|
+
return {
|
|
3033
|
+
costUsd: 0,
|
|
3034
|
+
uncachedInputTokens: 0,
|
|
3035
|
+
cacheReadTokens: 0,
|
|
3036
|
+
cacheWriteTokens: 0,
|
|
3037
|
+
outputTokens: 0
|
|
3038
|
+
};
|
|
3039
|
+
}
|
|
3040
|
+
function sumUsage(messages) {
|
|
3041
|
+
const total = emptyUsage();
|
|
3042
|
+
accumulate(messages, total);
|
|
3043
|
+
return total;
|
|
3044
|
+
}
|
|
3045
|
+
function addInto(into, from) {
|
|
3046
|
+
into.costUsd += from.costUsd;
|
|
3047
|
+
into.uncachedInputTokens += from.uncachedInputTokens;
|
|
3048
|
+
into.cacheReadTokens += from.cacheReadTokens;
|
|
3049
|
+
into.cacheWriteTokens += from.cacheWriteTokens;
|
|
3050
|
+
into.outputTokens += from.outputTokens;
|
|
3051
|
+
}
|
|
3052
|
+
function accumulate(messages, into) {
|
|
3053
|
+
for (const m of messages) {
|
|
3054
|
+
if (m.cost != null) into.costUsd += m.cost;
|
|
3055
|
+
if (m.externalCostUsd != null) into.costUsd += m.externalCostUsd;
|
|
3056
|
+
const cacheRead = m.cacheReadTokens ?? 0;
|
|
3057
|
+
const cacheWrite = m.cacheWriteTokens ?? 0;
|
|
3058
|
+
into.cacheReadTokens += cacheRead;
|
|
3059
|
+
into.cacheWriteTokens += cacheWrite;
|
|
3060
|
+
into.uncachedInputTokens += Math.max(0, (m.inputTokens ?? 0) - cacheRead - cacheWrite);
|
|
3061
|
+
into.outputTokens += m.outputTokens ?? 0;
|
|
3062
|
+
const rolled = m.compaction?.rolledUpUsage;
|
|
3063
|
+
if (rolled) addInto(into, rolled);
|
|
3064
|
+
for (const tc of m.toolCalls ?? []) {
|
|
3065
|
+
if (tc.subAgentTrace) accumulate(tc.subAgentTrace, into);
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
|
|
3000
3070
|
// src/utils/tool-fold.ts
|
|
3001
3071
|
var TOOL_FOLD_SYMBOL = Symbol("toolFold");
|
|
3002
3072
|
|
|
@@ -3190,11 +3260,13 @@ var ChatDriver = class _ChatDriver extends EventTarget {
|
|
|
3190
3260
|
primerHistory,
|
|
3191
3261
|
maxToolIterations = DEFAULT_MAX_TOOL_ITERATIONS,
|
|
3192
3262
|
maxFoldOperations = DEFAULT_MAX_FOLD_OPERATIONS,
|
|
3263
|
+
condenseBatchCalls = 1,
|
|
3193
3264
|
maxTurnSnapshots = DEFAULT_MAX_TURN_SNAPSHOTS,
|
|
3194
3265
|
sessionKey = "",
|
|
3195
3266
|
activityBus = NOOP_ACTIVITY_BUS
|
|
3196
3267
|
} = config;
|
|
3197
3268
|
this.maxToolIterations = maxToolIterations;
|
|
3269
|
+
this.condenseBatchCalls = condenseBatchCalls;
|
|
3198
3270
|
this.sessionKey = sessionKey;
|
|
3199
3271
|
this.activityBus = activityBus;
|
|
3200
3272
|
if (typeof toolHandlers === "function") {
|
|
@@ -3744,7 +3816,12 @@ Output format (strict):
|
|
|
3744
3816
|
coveredThroughTimestamp: toCompact[toCompact.length - 1]?.timestamp,
|
|
3745
3817
|
tokensBefore,
|
|
3746
3818
|
model: status?.model,
|
|
3747
|
-
createdAt
|
|
3819
|
+
createdAt,
|
|
3820
|
+
// Bank what the replaced turns spent. `toCompact` is dropped from history
|
|
3821
|
+
// below, taking its per-message cost/token fields with it — so a host total
|
|
3822
|
+
// re-derived from the transcript would otherwise fall by exactly this much
|
|
3823
|
+
// on every compaction. Summarising a turn does not refund what it cost.
|
|
3824
|
+
rolledUpUsage: sumUsage(toCompact)
|
|
3748
3825
|
}
|
|
3749
3826
|
};
|
|
3750
3827
|
this.loadHistory([summaryMessage, ...tail]);
|
|
@@ -4428,7 +4505,8 @@ Output format (strict):
|
|
|
4428
4505
|
activationEnded: (activation) => activation < this.currentActivation,
|
|
4429
4506
|
// A call's phase has ended once the app declared a later phase epoch
|
|
4430
4507
|
// current via `endPhase()`.
|
|
4431
|
-
phaseEnded: (phaseEpoch) => phaseEpoch < this.currentPhaseEpoch
|
|
4508
|
+
phaseEnded: (phaseEpoch) => phaseEpoch < this.currentPhaseEpoch,
|
|
4509
|
+
batchCalls: this.condenseBatchCalls
|
|
4432
4510
|
},
|
|
4433
4511
|
(detail) => recordMetaEvent(this.sessionKey, "context.condensed", detail)
|
|
4434
4512
|
);
|