@opengeni/db 3.2.0-canary.0 → 3.4.0-canary.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.
Files changed (81) hide show
  1. package/dist/canonical-human-identities.js +3 -3
  2. package/dist/{chunk-SIBYBA2D.js → chunk-6DPJA36C.js} +30 -11
  3. package/dist/chunk-6DPJA36C.js.map +1 -0
  4. package/dist/{chunk-KRLPEMLH.js → chunk-C2AFP7SB.js} +184 -6
  5. package/dist/chunk-C2AFP7SB.js.map +1 -0
  6. package/dist/{chunk-AZHW7R5V.js → chunk-H7MXYG7R.js} +12 -8
  7. package/dist/chunk-H7MXYG7R.js.map +1 -0
  8. package/dist/{chunk-2PRS4J5Q.js → chunk-HY3F5Q4E.js} +3 -3
  9. package/dist/{chunk-NAB6FKFN.js → chunk-O6FTELKH.js} +3 -3
  10. package/dist/{chunk-UZNXG44K.js → chunk-PYMY3AJW.js} +324 -8
  11. package/dist/chunk-PYMY3AJW.js.map +1 -0
  12. package/dist/{chunk-6HMM2R5T.js → chunk-TRBOWUG3.js} +98 -4
  13. package/dist/chunk-TRBOWUG3.js.map +1 -0
  14. package/dist/{chunk-E6CLMKEE.js → chunk-V3TRUXFJ.js} +2 -2
  15. package/dist/{chunk-2EH4WRHL.js → chunk-ZWRIPCTR.js} +2 -2
  16. package/dist/editable-artifact-durable-export.js +2 -2
  17. package/dist/editable-artifacts.js +3 -3
  18. package/dist/governed-learning-activation.d.ts +16 -0
  19. package/dist/index.d.ts +108 -7
  20. package/dist/index.js +3605 -1417
  21. package/dist/index.js.map +1 -1
  22. package/dist/insights-model-bundle.d.ts +30 -0
  23. package/dist/insights-usage-bundle.d.ts +32 -0
  24. package/dist/insights.d.ts +10 -2
  25. package/dist/lossless-json.d.ts +1 -1
  26. package/dist/managed-user-setup.d.ts +82 -0
  27. package/dist/memory-domain.d.ts +2 -2
  28. package/dist/migrate.d.ts +3 -1
  29. package/dist/migrate.js +1 -1
  30. package/dist/new-session-drafts.d.ts +4 -4
  31. package/dist/organization-membership-lifecycle.d.ts +60 -1
  32. package/dist/pr-review.d.ts +44 -3
  33. package/dist/provision-roles.js +1 -1
  34. package/dist/runtime-posture.d.ts +12 -7
  35. package/dist/schema.d.ts +839 -101
  36. package/dist/schema.js +9 -1
  37. package/dist/session-background-commands.js +3 -3
  38. package/dist/session-tenancy.d.ts +12 -1
  39. package/dist/session-tenancy.js +3 -3
  40. package/dist/video-generation.js +3 -3
  41. package/drizzle/0348_named_signup_and_user_setup.sql +838 -0
  42. package/drizzle/0349_greenfield_session_tenancy_activation.sql +792 -0
  43. package/drizzle/0350_organization_shared_workspace_administration.sql +889 -0
  44. package/drizzle/0351_organization_user_setup_delivery.sql +978 -0
  45. package/drizzle/0352_session_variable_set_attachments.sql +1661 -0
  46. package/drizzle/0353_automatic_session_title_policy_fence.sql +476 -0
  47. package/drizzle/0354_automatic_session_title_quarantine_index.sql +9 -0
  48. package/drizzle/0355_automatic_session_title_quarantine.sql +92 -0
  49. package/drizzle/0356_set_based_insights_session_visibility.sql +237 -0
  50. package/drizzle/0357_rig_platform_base_only.sql +44 -0
  51. package/drizzle/0358_pr_review_managed_github_app.sql +108 -0
  52. package/drizzle/0359_insights_force_rls_read_capability.sql +936 -0
  53. package/drizzle/0360_organization_identity_confirmation_prompt.sql +103 -0
  54. package/drizzle/0361_remember_knowledge_memory_materialization.sql +249 -0
  55. package/package.json +6 -6
  56. package/src/database.ts +12 -8
  57. package/src/governed-learning-activation.ts +74 -2
  58. package/src/index.ts +879 -92
  59. package/src/insights-model-bundle.ts +681 -0
  60. package/src/insights-usage-bundle.ts +240 -0
  61. package/src/insights.ts +265 -152
  62. package/src/lossless-json.ts +2 -1
  63. package/src/managed-user-setup.ts +316 -0
  64. package/src/memory-domain.ts +3 -3
  65. package/src/migrate.ts +38 -14
  66. package/src/new-session-drafts.ts +22 -15
  67. package/src/organization-membership-lifecycle.ts +253 -1
  68. package/src/pr-review.ts +449 -6
  69. package/src/provision-roles.ts +92 -0
  70. package/src/runtime-posture.ts +247 -4
  71. package/src/schema.ts +210 -4
  72. package/src/session-tenancy.ts +120 -2
  73. package/dist/chunk-6HMM2R5T.js.map +0 -1
  74. package/dist/chunk-AZHW7R5V.js.map +0 -1
  75. package/dist/chunk-KRLPEMLH.js.map +0 -1
  76. package/dist/chunk-SIBYBA2D.js.map +0 -1
  77. package/dist/chunk-UZNXG44K.js.map +0 -1
  78. /package/dist/{chunk-2PRS4J5Q.js.map → chunk-HY3F5Q4E.js.map} +0 -0
  79. /package/dist/{chunk-NAB6FKFN.js.map → chunk-O6FTELKH.js.map} +0 -0
  80. /package/dist/{chunk-E6CLMKEE.js.map → chunk-V3TRUXFJ.js.map} +0 -0
  81. /package/dist/{chunk-2EH4WRHL.js.map → chunk-ZWRIPCTR.js.map} +0 -0
package/src/insights.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { and, desc, eq, gte, inArray, lt, sql } from "drizzle-orm";
1
+ import { and, desc, eq, gt, gte, inArray, lt, sql } from "drizzle-orm";
2
2
  import { alias } from "drizzle-orm/pg-core";
3
3
  import type { Database } from "./database";
4
4
  import { rlsContextForWorkspace, withRlsContext } from "./database";
5
5
  import * as schema from "./schema";
6
6
 
7
- const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
7
+ export const INSIGHTS_WARM_GROUP_UUID_RE =
8
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
8
9
 
9
10
  export type InsightsTimeWindow = {
10
11
  since: Date;
@@ -119,6 +120,7 @@ export type RecentModelCallRow = {
119
120
  recordedAt: Date;
120
121
  sessionId: string;
121
122
  sessionTitle: string | null;
123
+ sessionDepth: number | null;
122
124
  turnId: string;
123
125
  provider: string;
124
126
  providerApi: string;
@@ -143,6 +145,62 @@ function hourKeyUtc(value: Date): string {
143
145
  return `${value.toISOString().slice(0, 13)}:00`;
144
146
  }
145
147
 
148
+ function insightsDate(value: unknown, field: string): Date {
149
+ const date = value instanceof Date ? value : new Date(String(value));
150
+ if (!Number.isFinite(date.getTime())) {
151
+ throw new Error(`Workspace Insights returned an invalid ${field}`);
152
+ }
153
+ return date;
154
+ }
155
+
156
+ function insightsNumber(value: unknown, field: string): number {
157
+ const number = typeof value === "number" ? value : Number(value);
158
+ if (!Number.isFinite(number)) {
159
+ throw new Error(`Workspace Insights returned an invalid ${field}`);
160
+ }
161
+ return number;
162
+ }
163
+
164
+ function insightsNullableNumber(value: unknown, field: string): number | null {
165
+ return value === null ? null : insightsNumber(value, field);
166
+ }
167
+
168
+ function visibleUsageEventsSource(input: InsightsTimeWindow & { workspaceId: string }) {
169
+ const usageEvents = alias(schema.usageEvents, "insights_visible_usage_events");
170
+ return {
171
+ usageEvents,
172
+ source: sql`opengeni_private.visible_workspace_insights_usage_events(
173
+ ${input.workspaceId},
174
+ ${input.since.toISOString()}::timestamp with time zone,
175
+ ${input.until.toISOString()}::timestamp with time zone
176
+ ) "insights_visible_usage_events"`,
177
+ };
178
+ }
179
+
180
+ function visibleUsageEventsSinceSource(input: { workspaceId: string; since: Date }) {
181
+ const usageEvents = alias(schema.usageEvents, "insights_visible_usage_events_since");
182
+ return {
183
+ usageEvents,
184
+ source: sql`opengeni_private.visible_workspace_insights_usage_events(
185
+ ${input.workspaceId},
186
+ ${input.since.toISOString()}::timestamp with time zone,
187
+ 'infinity'::timestamp with time zone
188
+ ) "insights_visible_usage_events_since"`,
189
+ };
190
+ }
191
+
192
+ function visibleModelCallFactsSource(input: InsightsTimeWindow & { workspaceId: string }) {
193
+ const modelCallFacts = alias(schema.modelCallFacts, "insights_visible_model_call_facts");
194
+ return {
195
+ modelCallFacts,
196
+ source: sql`opengeni_private.visible_workspace_insights_model_call_facts(
197
+ ${input.workspaceId},
198
+ ${input.since.toISOString()}::timestamp with time zone,
199
+ ${input.until.toISOString()}::timestamp with time zone
200
+ ) "insights_visible_model_call_facts"`,
201
+ };
202
+ }
203
+
146
204
  export async function sumUsageQuantityInRange(
147
205
  db: Database,
148
206
  input: {
@@ -154,17 +212,46 @@ export async function sumUsageQuantityInRange(
154
212
  ): Promise<number> {
155
213
  const context = await rlsContextForWorkspace(db, input.workspaceId);
156
214
  return await withRlsContext(db, context, async (scopedDb) => {
215
+ const { usageEvents, source } = visibleUsageEventsSource(input);
157
216
  const [{ total } = { total: 0 }] = await scopedDb
158
217
  .select({
159
- total: sql<number>`coalesce(sum(${schema.usageEvents.quantity}), 0)`,
218
+ total: sql<number>`coalesce(sum(${usageEvents.quantity}), 0)`,
160
219
  })
161
- .from(schema.usageEvents)
220
+ .from(source)
162
221
  .where(
163
222
  and(
164
- eq(schema.usageEvents.workspaceId, input.workspaceId),
165
- eq(schema.usageEvents.eventType, input.eventType),
166
- gte(schema.usageEvents.occurredAt, input.since),
167
- lt(schema.usageEvents.occurredAt, input.until),
223
+ eq(usageEvents.workspaceId, input.workspaceId),
224
+ eq(usageEvents.eventType, input.eventType),
225
+ gte(usageEvents.occurredAt, input.since),
226
+ lt(usageEvents.occurredAt, input.until),
227
+ ),
228
+ );
229
+ return Number(total);
230
+ });
231
+ }
232
+
233
+ /** Preserve the existing strictly-after boundary used by monthly cap meters. */
234
+ export async function sumUsageQuantitySinceForInsights(
235
+ db: Database,
236
+ input: {
237
+ workspaceId: string;
238
+ eventType: string;
239
+ since: Date;
240
+ },
241
+ ): Promise<number> {
242
+ const context = await rlsContextForWorkspace(db, input.workspaceId);
243
+ return await withRlsContext(db, context, async (scopedDb) => {
244
+ const { usageEvents, source } = visibleUsageEventsSinceSource(input);
245
+ const [{ total } = { total: 0 }] = await scopedDb
246
+ .select({
247
+ total: sql<number>`coalesce(sum(${usageEvents.quantity}), 0)`,
248
+ })
249
+ .from(source)
250
+ .where(
251
+ and(
252
+ eq(usageEvents.workspaceId, input.workspaceId),
253
+ eq(usageEvents.eventType, input.eventType),
254
+ gt(usageEvents.occurredAt, input.since),
168
255
  ),
169
256
  );
170
257
  return Number(total);
@@ -183,26 +270,27 @@ async function sumUsageQuantityByBucket(
183
270
  ): Promise<Map<string, number>> {
184
271
  const context = await rlsContextForWorkspace(db, input.workspaceId);
185
272
  return await withRlsContext(db, context, async (scopedDb) => {
273
+ const { usageEvents, source } = visibleUsageEventsSource(input);
186
274
  const bucket =
187
275
  granularity === "hour"
188
- ? sql<string>`to_char(date_trunc('hour', ${schema.usageEvents.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD"T"HH24:00')`
189
- : sql<string>`to_char(date_trunc('day', ${schema.usageEvents.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD')`;
276
+ ? sql<string>`to_char(date_trunc('hour', ${usageEvents.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD"T"HH24:00')`
277
+ : sql<string>`to_char(date_trunc('day', ${usageEvents.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD')`;
190
278
  const bucketGroup =
191
279
  granularity === "hour"
192
- ? sql`date_trunc('hour', ${schema.usageEvents.occurredAt} at time zone 'UTC')`
193
- : sql`date_trunc('day', ${schema.usageEvents.occurredAt} at time zone 'UTC')`;
280
+ ? sql`date_trunc('hour', ${usageEvents.occurredAt} at time zone 'UTC')`
281
+ : sql`date_trunc('day', ${usageEvents.occurredAt} at time zone 'UTC')`;
194
282
  const rows = await scopedDb
195
283
  .select({
196
284
  bucket,
197
- total: sql<number>`coalesce(sum(${schema.usageEvents.quantity}), 0)`,
285
+ total: sql<number>`coalesce(sum(${usageEvents.quantity}), 0)`,
198
286
  })
199
- .from(schema.usageEvents)
287
+ .from(source)
200
288
  .where(
201
289
  and(
202
- eq(schema.usageEvents.workspaceId, input.workspaceId),
203
- eq(schema.usageEvents.eventType, input.eventType),
204
- gte(schema.usageEvents.occurredAt, input.since),
205
- lt(schema.usageEvents.occurredAt, input.until),
290
+ eq(usageEvents.workspaceId, input.workspaceId),
291
+ eq(usageEvents.eventType, input.eventType),
292
+ gte(usageEvents.occurredAt, input.since),
293
+ lt(usageEvents.occurredAt, input.until),
206
294
  ),
207
295
  )
208
296
  .groupBy(bucketGroup);
@@ -246,39 +334,36 @@ export async function aggregateModelCallFacts(
246
334
  ): Promise<ModelCallFactAggregateRow[]> {
247
335
  const context = await rlsContextForWorkspace(db, input.workspaceId);
248
336
  return await withRlsContext(db, context, async (scopedDb) => {
337
+ const { modelCallFacts, source } = visibleModelCallFactsSource(input);
249
338
  const clauses = [
250
- eq(schema.modelCallFacts.workspaceId, input.workspaceId),
251
- gte(schema.modelCallFacts.occurredAt, input.since),
252
- lt(schema.modelCallFacts.occurredAt, input.until),
253
- ...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
254
- ...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
339
+ eq(modelCallFacts.workspaceId, input.workspaceId),
340
+ gte(modelCallFacts.occurredAt, input.since),
341
+ lt(modelCallFacts.occurredAt, input.until),
342
+ ...(input.provider ? [eq(modelCallFacts.provider, input.provider)] : []),
343
+ ...(input.model ? [eq(modelCallFacts.model, input.model)] : []),
255
344
  ];
256
345
  const rows = await scopedDb
257
346
  .select({
258
- provider: schema.modelCallFacts.provider,
259
- model: schema.modelCallFacts.model,
260
- billingPath: schema.modelCallFacts.billingPath,
347
+ provider: sql<string>`${modelCallFacts.provider}`,
348
+ model: sql<string>`${modelCallFacts.model}`,
349
+ billingPath: sql<string>`${modelCallFacts.billingPath}`,
261
350
  calls: sql<number>`count(*)::int`,
262
- inputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}), 0)`,
263
- outputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.outputTokens}), 0)`,
264
- cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
265
- cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
266
- cacheWriteTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cacheWriteTokens}), 0)`,
267
- reasoningTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.reasoningTokens}), 0)`,
268
- totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
269
- tokenKnownCalls: sql<number>`count(${schema.modelCallFacts.totalTokens})::int`,
270
- cacheKnownCalls: sql<number>`count(*) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null)::int`,
271
- pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
272
- estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
273
- estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
351
+ inputTokens: sql<number>`coalesce(sum(${modelCallFacts.inputTokens}), 0)`,
352
+ outputTokens: sql<number>`coalesce(sum(${modelCallFacts.outputTokens}), 0)`,
353
+ cachedTokens: sql<number>`coalesce(sum(${modelCallFacts.cachedTokens}), 0)`,
354
+ cacheInputTokens: sql<number>`coalesce(sum(${modelCallFacts.inputTokens}) filter (where ${modelCallFacts.cachedTokens} is not null and ${modelCallFacts.inputTokens} is not null), 0)`,
355
+ cacheWriteTokens: sql<number>`coalesce(sum(${modelCallFacts.cacheWriteTokens}), 0)`,
356
+ reasoningTokens: sql<number>`coalesce(sum(${modelCallFacts.reasoningTokens}), 0)`,
357
+ totalTokens: sql<number>`coalesce(sum(${modelCallFacts.totalTokens}), 0)`,
358
+ tokenKnownCalls: sql<number>`count(${modelCallFacts.totalTokens})::int`,
359
+ cacheKnownCalls: sql<number>`count(*) filter (where ${modelCallFacts.cachedTokens} is not null and ${modelCallFacts.inputTokens} is not null)::int`,
360
+ pricedCostMicros: sql<number>`coalesce(sum(${modelCallFacts.pricedCostMicros}) filter (where ${modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
361
+ estimatedProviderCostMicros: sql<number>`coalesce(sum(${modelCallFacts.estimatedProviderCostMicros}), 0)`,
362
+ estimatedProviderCostKnownCalls: sql<number>`count(${modelCallFacts.estimatedProviderCostMicros})::int`,
274
363
  })
275
- .from(schema.modelCallFacts)
364
+ .from(source)
276
365
  .where(and(...clauses))
277
- .groupBy(
278
- schema.modelCallFacts.provider,
279
- schema.modelCallFacts.model,
280
- schema.modelCallFacts.billingPath,
281
- );
366
+ .groupBy(modelCallFacts.provider, modelCallFacts.model, modelCallFacts.billingPath);
282
367
  return rows.map((row) => ({
283
368
  provider: row.provider,
284
369
  model: row.model,
@@ -300,7 +385,7 @@ export async function aggregateModelCallFacts(
300
385
  });
301
386
  }
302
387
 
303
- type ModelCallFactSeriesAggregate = {
388
+ export type ModelCallFactSeriesAggregate = {
304
389
  costMicros: number;
305
390
  estimatedProviderCostMicros: number;
306
391
  estimatedProviderCostKnownCalls: number;
@@ -329,39 +414,40 @@ async function aggregateModelCallFactsByBucket(
329
414
  ): Promise<Map<string, ModelCallFactSeriesAggregate>> {
330
415
  const context = await rlsContextForWorkspace(db, input.workspaceId);
331
416
  return await withRlsContext(db, context, async (scopedDb) => {
417
+ const { modelCallFacts, source } = visibleModelCallFactsSource(input);
332
418
  const clauses = [
333
- eq(schema.modelCallFacts.workspaceId, input.workspaceId),
334
- gte(schema.modelCallFacts.occurredAt, input.since),
335
- lt(schema.modelCallFacts.occurredAt, input.until),
336
- ...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
337
- ...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
419
+ eq(modelCallFacts.workspaceId, input.workspaceId),
420
+ gte(modelCallFacts.occurredAt, input.since),
421
+ lt(modelCallFacts.occurredAt, input.until),
422
+ ...(input.provider ? [eq(modelCallFacts.provider, input.provider)] : []),
423
+ ...(input.model ? [eq(modelCallFacts.model, input.model)] : []),
338
424
  ];
339
425
  const bucket =
340
426
  granularity === "hour"
341
- ? sql<string>`to_char(date_trunc('hour', ${schema.modelCallFacts.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD"T"HH24:00')`
342
- : sql<string>`to_char(date_trunc('day', ${schema.modelCallFacts.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD')`;
427
+ ? sql<string>`to_char(date_trunc('hour', ${modelCallFacts.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD"T"HH24:00')`
428
+ : sql<string>`to_char(date_trunc('day', ${modelCallFacts.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD')`;
343
429
  const bucketGroup =
344
430
  granularity === "hour"
345
- ? sql`date_trunc('hour', ${schema.modelCallFacts.occurredAt} at time zone 'UTC')`
346
- : sql`date_trunc('day', ${schema.modelCallFacts.occurredAt} at time zone 'UTC')`;
431
+ ? sql`date_trunc('hour', ${modelCallFacts.occurredAt} at time zone 'UTC')`
432
+ : sql`date_trunc('day', ${modelCallFacts.occurredAt} at time zone 'UTC')`;
347
433
  const rows = await scopedDb
348
434
  .select({
349
435
  bucket,
350
- costMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
351
- estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
352
- estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
353
- inputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}), 0)`,
354
- outputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.outputTokens}), 0)`,
355
- cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
356
- cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
357
- cacheWriteTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cacheWriteTokens}), 0)`,
358
- reasoningTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.reasoningTokens}), 0)`,
359
- totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
360
- tokenKnownCalls: sql<number>`count(${schema.modelCallFacts.totalTokens})::int`,
361
- cacheKnownCalls: sql<number>`count(*) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null)::int`,
436
+ costMicros: sql<number>`coalesce(sum(${modelCallFacts.pricedCostMicros}) filter (where ${modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
437
+ estimatedProviderCostMicros: sql<number>`coalesce(sum(${modelCallFacts.estimatedProviderCostMicros}), 0)`,
438
+ estimatedProviderCostKnownCalls: sql<number>`count(${modelCallFacts.estimatedProviderCostMicros})::int`,
439
+ inputTokens: sql<number>`coalesce(sum(${modelCallFacts.inputTokens}), 0)`,
440
+ outputTokens: sql<number>`coalesce(sum(${modelCallFacts.outputTokens}), 0)`,
441
+ cachedTokens: sql<number>`coalesce(sum(${modelCallFacts.cachedTokens}), 0)`,
442
+ cacheInputTokens: sql<number>`coalesce(sum(${modelCallFacts.inputTokens}) filter (where ${modelCallFacts.cachedTokens} is not null and ${modelCallFacts.inputTokens} is not null), 0)`,
443
+ cacheWriteTokens: sql<number>`coalesce(sum(${modelCallFacts.cacheWriteTokens}), 0)`,
444
+ reasoningTokens: sql<number>`coalesce(sum(${modelCallFacts.reasoningTokens}), 0)`,
445
+ totalTokens: sql<number>`coalesce(sum(${modelCallFacts.totalTokens}), 0)`,
446
+ tokenKnownCalls: sql<number>`count(${modelCallFacts.totalTokens})::int`,
447
+ cacheKnownCalls: sql<number>`count(*) filter (where ${modelCallFacts.cachedTokens} is not null and ${modelCallFacts.inputTokens} is not null)::int`,
362
448
  calls: sql<number>`count(*)::int`,
363
449
  })
364
- .from(schema.modelCallFacts)
450
+ .from(source)
365
451
  .where(and(...clauses))
366
452
  .groupBy(bucketGroup);
367
453
  return new Map(
@@ -420,26 +506,27 @@ export async function aggregateWarmSecondsByGroup(
420
506
  const context = await rlsContextForWorkspace(db, input.workspaceId);
421
507
  const limit = input.limit ?? 24;
422
508
  return await withRlsContext(db, context, async (scopedDb) => {
509
+ const { usageEvents, source } = visibleUsageEventsSource(input);
423
510
  const rows = await scopedDb
424
511
  .select({
425
- groupId: sql<string>`split_part(${schema.usageEvents.sourceResourceId}, ':', 1)`,
426
- warmSeconds: sql<number>`coalesce(sum(${schema.usageEvents.quantity}), 0)`,
512
+ groupId: sql<string>`split_part(${usageEvents.sourceResourceId}, ':', 1)`,
513
+ warmSeconds: sql<number>`coalesce(sum(${usageEvents.quantity}), 0)`,
427
514
  })
428
- .from(schema.usageEvents)
515
+ .from(source)
429
516
  .where(
430
517
  and(
431
- eq(schema.usageEvents.workspaceId, input.workspaceId),
432
- eq(schema.usageEvents.eventType, "sandbox.warm_seconds"),
433
- gte(schema.usageEvents.occurredAt, input.since),
434
- lt(schema.usageEvents.occurredAt, input.until),
435
- sql`${schema.usageEvents.sourceResourceId} is not null`,
518
+ eq(usageEvents.workspaceId, input.workspaceId),
519
+ eq(usageEvents.eventType, "sandbox.warm_seconds"),
520
+ gte(usageEvents.occurredAt, input.since),
521
+ lt(usageEvents.occurredAt, input.until),
522
+ sql`${usageEvents.sourceResourceId} is not null`,
436
523
  ),
437
524
  )
438
- .groupBy(sql`split_part(${schema.usageEvents.sourceResourceId}, ':', 1)`)
439
- .orderBy(sql`coalesce(sum(${schema.usageEvents.quantity}), 0) desc`)
525
+ .groupBy(sql`split_part(${usageEvents.sourceResourceId}, ':', 1)`)
526
+ .orderBy(sql`coalesce(sum(${usageEvents.quantity}), 0) desc`)
440
527
  .limit(Math.max(limit * 4, limit));
441
528
  return rows
442
- .filter((row) => UUID_RE.test(row.groupId))
529
+ .filter((row) => INSIGHTS_WARM_GROUP_UUID_RE.test(row.groupId))
443
530
  .slice(0, limit)
444
531
  .map((row) => ({
445
532
  groupId: row.groupId,
@@ -527,31 +614,32 @@ export async function aggregateRootSessionDrivers(
527
614
  const childSessions = alias(schema.sessions, "insight_child_sessions");
528
615
  const rootSessions = alias(schema.sessions, "insight_root_sessions");
529
616
  return await withRlsContext(db, context, async (scopedDb) => {
617
+ const { modelCallFacts, source } = visibleModelCallFactsSource(input);
530
618
  const clauses = [
531
- eq(schema.modelCallFacts.workspaceId, input.workspaceId),
532
- gte(schema.modelCallFacts.occurredAt, input.since),
533
- lt(schema.modelCallFacts.occurredAt, input.until),
534
- ...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
535
- ...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
619
+ eq(modelCallFacts.workspaceId, input.workspaceId),
620
+ gte(modelCallFacts.occurredAt, input.since),
621
+ lt(modelCallFacts.occurredAt, input.until),
622
+ ...(input.provider ? [eq(modelCallFacts.provider, input.provider)] : []),
623
+ ...(input.model ? [eq(modelCallFacts.model, input.model)] : []),
536
624
  ...(input.rootSessionIds ? [inArray(childSessions.rootSessionId, input.rootSessionIds)] : []),
537
625
  ];
538
626
  const query = scopedDb
539
627
  .select({
540
628
  rootSessionId: childSessions.rootSessionId,
541
629
  title: rootSessions.title,
542
- pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
543
- estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
544
- estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
545
- totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
546
- cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
547
- cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
630
+ pricedCostMicros: sql<number>`coalesce(sum(${modelCallFacts.pricedCostMicros}) filter (where ${modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
631
+ estimatedProviderCostMicros: sql<number>`coalesce(sum(${modelCallFacts.estimatedProviderCostMicros}), 0)`,
632
+ estimatedProviderCostKnownCalls: sql<number>`count(${modelCallFacts.estimatedProviderCostMicros})::int`,
633
+ totalTokens: sql<number>`coalesce(sum(${modelCallFacts.totalTokens}), 0)`,
634
+ cachedTokens: sql<number>`coalesce(sum(${modelCallFacts.cachedTokens}), 0)`,
635
+ cacheInputTokens: sql<number>`coalesce(sum(${modelCallFacts.inputTokens}) filter (where ${modelCallFacts.cachedTokens} is not null and ${modelCallFacts.inputTokens} is not null), 0)`,
548
636
  })
549
- .from(schema.modelCallFacts)
637
+ .from(source)
550
638
  .innerJoin(
551
639
  childSessions,
552
640
  and(
553
- eq(childSessions.workspaceId, schema.modelCallFacts.workspaceId),
554
- eq(childSessions.id, schema.modelCallFacts.sessionId),
641
+ eq(childSessions.workspaceId, modelCallFacts.workspaceId),
642
+ eq(childSessions.id, modelCallFacts.sessionId),
555
643
  ),
556
644
  )
557
645
  .leftJoin(
@@ -563,7 +651,7 @@ export async function aggregateRootSessionDrivers(
563
651
  )
564
652
  .where(and(...clauses))
565
653
  .groupBy(childSessions.rootSessionId, rootSessions.title)
566
- .orderBy(sql`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0) desc`);
654
+ .orderBy(sql`coalesce(sum(${modelCallFacts.totalTokens}), 0) desc`);
567
655
  const rows = input.rootSessionIds ? await query : await query.limit(input.limit ?? 8);
568
656
  return rows.map((row) => ({
569
657
  rootSessionId: row.rootSessionId,
@@ -584,20 +672,21 @@ export async function listModelCallFacets(
584
672
  ): Promise<ModelCallFacetRow[]> {
585
673
  const context = await rlsContextForWorkspace(db, input.workspaceId);
586
674
  return await withRlsContext(db, context, async (scopedDb) => {
675
+ const { modelCallFacts, source } = visibleModelCallFactsSource(input);
587
676
  const rows = await scopedDb
588
677
  .selectDistinct({
589
- provider: schema.modelCallFacts.provider,
590
- model: schema.modelCallFacts.model,
678
+ provider: sql<string>`${modelCallFacts.provider}`,
679
+ model: sql<string>`${modelCallFacts.model}`,
591
680
  })
592
- .from(schema.modelCallFacts)
681
+ .from(source)
593
682
  .where(
594
683
  and(
595
- eq(schema.modelCallFacts.workspaceId, input.workspaceId),
596
- gte(schema.modelCallFacts.occurredAt, input.since),
597
- lt(schema.modelCallFacts.occurredAt, input.until),
684
+ eq(modelCallFacts.workspaceId, input.workspaceId),
685
+ gte(modelCallFacts.occurredAt, input.since),
686
+ lt(modelCallFacts.occurredAt, input.until),
598
687
  ),
599
688
  )
600
- .orderBy(schema.modelCallFacts.provider, schema.modelCallFacts.model)
689
+ .orderBy(modelCallFacts.provider, modelCallFacts.model)
601
690
  .limit(500);
602
691
  return rows;
603
692
  });
@@ -615,47 +704,66 @@ export async function listRecentModelCalls(
615
704
  const context = await rlsContextForWorkspace(db, input.workspaceId);
616
705
  const factSessions = alias(schema.sessions, "insight_recent_fact_sessions");
617
706
  return await withRlsContext(db, context, async (scopedDb) => {
707
+ const { modelCallFacts, source } = visibleModelCallFactsSource(input);
618
708
  const clauses = [
619
- eq(schema.modelCallFacts.workspaceId, input.workspaceId),
620
- gte(schema.modelCallFacts.occurredAt, input.since),
621
- lt(schema.modelCallFacts.occurredAt, input.until),
622
- ...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
623
- ...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
709
+ eq(modelCallFacts.workspaceId, input.workspaceId),
710
+ gte(modelCallFacts.occurredAt, input.since),
711
+ lt(modelCallFacts.occurredAt, input.until),
712
+ ...(input.provider ? [eq(modelCallFacts.provider, input.provider)] : []),
713
+ ...(input.model ? [eq(modelCallFacts.model, input.model)] : []),
624
714
  ];
625
715
  const rows = await scopedDb
626
716
  .select({
627
- id: schema.modelCallFacts.id,
628
- occurredAt: schema.modelCallFacts.occurredAt,
629
- recordedAt: schema.modelCallFacts.recordedAt,
630
- sessionId: schema.modelCallFacts.sessionId,
717
+ id: sql<string>`${modelCallFacts.id}`,
718
+ occurredAt: sql<Date>`${modelCallFacts.occurredAt}`,
719
+ recordedAt: sql<Date>`${modelCallFacts.recordedAt}`,
720
+ sessionId: sql<string>`${modelCallFacts.sessionId}`,
631
721
  sessionTitle: factSessions.title,
632
- turnId: schema.modelCallFacts.turnId,
633
- provider: schema.modelCallFacts.provider,
634
- providerApi: schema.modelCallFacts.providerApi,
635
- model: schema.modelCallFacts.model,
636
- billingPath: schema.modelCallFacts.billingPath,
637
- inputTokens: schema.modelCallFacts.inputTokens,
638
- outputTokens: schema.modelCallFacts.outputTokens,
639
- cachedTokens: schema.modelCallFacts.cachedTokens,
640
- cacheWriteTokens: schema.modelCallFacts.cacheWriteTokens,
641
- reasoningTokens: schema.modelCallFacts.reasoningTokens,
642
- totalTokens: schema.modelCallFacts.totalTokens,
643
- pricedCostMicros: schema.modelCallFacts.pricedCostMicros,
644
- estimatedProviderCostMicros: schema.modelCallFacts.estimatedProviderCostMicros,
645
- pricingSource: schema.modelCallFacts.pricingSource,
722
+ sessionDepth: factSessions.nestedAgentDepth,
723
+ turnId: sql<string>`${modelCallFacts.turnId}`,
724
+ provider: sql<string>`${modelCallFacts.provider}`,
725
+ providerApi: sql<string>`${modelCallFacts.providerApi}`,
726
+ model: sql<string>`${modelCallFacts.model}`,
727
+ billingPath: sql<string>`${modelCallFacts.billingPath}`,
728
+ inputTokens: sql<number | null>`${modelCallFacts.inputTokens}`,
729
+ outputTokens: sql<number | null>`${modelCallFacts.outputTokens}`,
730
+ cachedTokens: sql<number | null>`${modelCallFacts.cachedTokens}`,
731
+ cacheWriteTokens: sql<number | null>`${modelCallFacts.cacheWriteTokens}`,
732
+ reasoningTokens: sql<number | null>`${modelCallFacts.reasoningTokens}`,
733
+ totalTokens: sql<number | null>`${modelCallFacts.totalTokens}`,
734
+ pricedCostMicros: sql<number>`${modelCallFacts.pricedCostMicros}`,
735
+ estimatedProviderCostMicros: sql<
736
+ number | null
737
+ >`${modelCallFacts.estimatedProviderCostMicros}`,
738
+ pricingSource: sql<string | null>`${modelCallFacts.pricingSource}`,
646
739
  })
647
- .from(schema.modelCallFacts)
740
+ .from(source)
648
741
  .leftJoin(
649
742
  factSessions,
650
743
  and(
651
- eq(factSessions.workspaceId, schema.modelCallFacts.workspaceId),
652
- eq(factSessions.id, schema.modelCallFacts.sessionId),
744
+ eq(factSessions.workspaceId, modelCallFacts.workspaceId),
745
+ eq(factSessions.id, modelCallFacts.sessionId),
653
746
  ),
654
747
  )
655
748
  .where(and(...clauses))
656
- .orderBy(desc(schema.modelCallFacts.occurredAt), desc(schema.modelCallFacts.id))
749
+ .orderBy(desc(modelCallFacts.occurredAt), desc(modelCallFacts.id))
657
750
  .limit(Math.max(1, Math.min(input.limit ?? 50, 100)));
658
- return rows;
751
+ return rows.map((row) => ({
752
+ ...row,
753
+ occurredAt: insightsDate(row.occurredAt, "model-call occurrence timestamp"),
754
+ recordedAt: insightsDate(row.recordedAt, "model-call recording timestamp"),
755
+ inputTokens: insightsNullableNumber(row.inputTokens, "input token count"),
756
+ outputTokens: insightsNullableNumber(row.outputTokens, "output token count"),
757
+ cachedTokens: insightsNullableNumber(row.cachedTokens, "cached token count"),
758
+ cacheWriteTokens: insightsNullableNumber(row.cacheWriteTokens, "cache-write token count"),
759
+ reasoningTokens: insightsNullableNumber(row.reasoningTokens, "reasoning token count"),
760
+ totalTokens: insightsNullableNumber(row.totalTokens, "total token count"),
761
+ pricedCostMicros: insightsNumber(row.pricedCostMicros, "priced cost"),
762
+ estimatedProviderCostMicros: insightsNullableNumber(
763
+ row.estimatedProviderCostMicros,
764
+ "estimated provider cost",
765
+ ),
766
+ }));
659
767
  });
660
768
  }
661
769
 
@@ -669,12 +777,13 @@ export async function aggregateModelContextContributions(
669
777
  ): Promise<ModelContextContributionAggregate> {
670
778
  const context = await rlsContextForWorkspace(db, input.workspaceId);
671
779
  return await withRlsContext(db, context, async (scopedDb) => {
780
+ const { modelCallFacts, source } = visibleModelCallFactsSource(input);
672
781
  const clauses = [
673
- eq(schema.modelCallFacts.workspaceId, input.workspaceId),
674
- gte(schema.modelCallFacts.occurredAt, input.since),
675
- lt(schema.modelCallFacts.occurredAt, input.until),
676
- ...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
677
- ...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
782
+ eq(modelCallFacts.workspaceId, input.workspaceId),
783
+ gte(modelCallFacts.occurredAt, input.since),
784
+ lt(modelCallFacts.occurredAt, input.until),
785
+ ...(input.provider ? [eq(modelCallFacts.provider, input.provider)] : []),
786
+ ...(input.model ? [eq(modelCallFacts.model, input.model)] : []),
678
787
  ];
679
788
  type ContributionRow = {
680
789
  total_calls: number | string;
@@ -688,9 +797,9 @@ export async function aggregateModelContextContributions(
688
797
  const rows = (await scopedDb.execute(sql<ContributionRow>`
689
798
  with filtered as (
690
799
  select
691
- ${schema.modelCallFacts.id} as id,
692
- ${schema.modelCallFacts.contextContributions} as context_contributions
693
- from ${schema.modelCallFacts}
800
+ ${modelCallFacts.id} as id,
801
+ ${modelCallFacts.contextContributions} as context_contributions
802
+ from ${source}
694
803
  where ${and(...clauses)}
695
804
  ), coverage as (
696
805
  select
@@ -762,33 +871,34 @@ export async function aggregateScheduleFacts(
762
871
  ): Promise<ScheduleFactAggregate[]> {
763
872
  const context = await rlsContextForWorkspace(db, input.workspaceId);
764
873
  return await withRlsContext(db, context, async (scopedDb) => {
874
+ const { modelCallFacts, source } = visibleModelCallFactsSource(input);
765
875
  const clauses = [
766
- eq(schema.modelCallFacts.workspaceId, input.workspaceId),
767
- gte(schema.modelCallFacts.occurredAt, input.since),
768
- lt(schema.modelCallFacts.occurredAt, input.until),
769
- sql`${schema.modelCallFacts.scheduledTaskId} is not null`,
770
- ...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
771
- ...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
876
+ eq(modelCallFacts.workspaceId, input.workspaceId),
877
+ gte(modelCallFacts.occurredAt, input.since),
878
+ lt(modelCallFacts.occurredAt, input.until),
879
+ sql`${modelCallFacts.scheduledTaskId} is not null`,
880
+ ...(input.provider ? [eq(modelCallFacts.provider, input.provider)] : []),
881
+ ...(input.model ? [eq(modelCallFacts.model, input.model)] : []),
772
882
  ];
773
883
  const rows = await scopedDb
774
884
  .select({
775
- scheduledTaskId: schema.modelCallFacts.scheduledTaskId,
776
- pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
777
- estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
778
- estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
779
- totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
780
- cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
781
- cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
885
+ scheduledTaskId: sql<string | null>`${modelCallFacts.scheduledTaskId}`,
886
+ pricedCostMicros: sql<number>`coalesce(sum(${modelCallFacts.pricedCostMicros}) filter (where ${modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
887
+ estimatedProviderCostMicros: sql<number>`coalesce(sum(${modelCallFacts.estimatedProviderCostMicros}), 0)`,
888
+ estimatedProviderCostKnownCalls: sql<number>`count(${modelCallFacts.estimatedProviderCostMicros})::int`,
889
+ totalTokens: sql<number>`coalesce(sum(${modelCallFacts.totalTokens}), 0)`,
890
+ cachedTokens: sql<number>`coalesce(sum(${modelCallFacts.cachedTokens}), 0)`,
891
+ cacheInputTokens: sql<number>`coalesce(sum(${modelCallFacts.inputTokens}) filter (where ${modelCallFacts.cachedTokens} is not null and ${modelCallFacts.inputTokens} is not null), 0)`,
782
892
  calls: sql<number>`count(*)::int`,
783
893
  billingPath: sql<string>`case
784
- when bool_or(${schema.modelCallFacts.billingPath} = 'opengeni_credits')
894
+ when bool_or(${modelCallFacts.billingPath} = 'opengeni_credits')
785
895
  then 'opengeni_credits'
786
896
  else 'external'
787
897
  end`,
788
898
  })
789
- .from(schema.modelCallFacts)
899
+ .from(source)
790
900
  .where(and(...clauses))
791
- .groupBy(schema.modelCallFacts.scheduledTaskId);
901
+ .groupBy(modelCallFacts.scheduledTaskId);
792
902
  return rows
793
903
  .filter((row): row is typeof row & { scheduledTaskId: string } => row.scheduledTaskId != null)
794
904
  .map((row) => ({
@@ -839,6 +949,7 @@ export async function aggregateSessionDepth(
839
949
  sessionsTouched: number;
840
950
  rootSessions: number;
841
951
  deepestDepth: number;
952
+ deepestSessionId: string | null;
842
953
  deepestSessionTitle: string;
843
954
  avgDepth: number;
844
955
  goalsActive: number;
@@ -866,6 +977,7 @@ export async function aggregateSessionDepth(
866
977
  .where(eq(schema.sessions.workspaceId, workspaceId));
867
978
  const [deepest] = await scopedDb
868
979
  .select({
980
+ id: schema.sessions.id,
869
981
  title: schema.sessions.title,
870
982
  depth: schema.sessions.nestedAgentDepth,
871
983
  })
@@ -888,6 +1000,7 @@ export async function aggregateSessionDepth(
888
1000
  sessionsTouched: Number(stats?.sessionsTouched ?? 0),
889
1001
  rootSessions: Number(stats?.rootSessions ?? 0),
890
1002
  deepestDepth: Number(stats?.deepestDepth ?? 0),
1003
+ deepestSessionId: deepest?.id ?? null,
891
1004
  deepestSessionTitle: deepest?.title?.trim() || "",
892
1005
  avgDepth: Number(stats?.avgDepth ?? 0),
893
1006
  goalsActive: Number(goals?.active ?? 0),
@@ -9,7 +9,8 @@ const MAX_JSON_DEPTH = 512;
9
9
  * column and must never be decoded based on content shape alone.
10
10
  */
11
11
  export const LOSSLESS_CONTENT_CODEC_VERSION = 1 as const;
12
- export const LOSSLESS_CONTENT_WRITER_APPLICATION_NAME = "opengeni-lossless-v1";
12
+ export const LOSSLESS_CONTENT_WRITER_APPLICATION_NAME =
13
+ "opengeni-lossless-v1-session-variable-sets-v1";
13
14
 
14
15
  export function withLosslessContentWriteVersion<
15
16
  const ContentKey extends string,