@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
@@ -0,0 +1,681 @@
1
+ import { sql } from "drizzle-orm";
2
+
3
+ import type { Database } from "./database";
4
+ import { rlsContextForWorkspace, withRlsContext } from "./database";
5
+ import type {
6
+ ModelCallFactAggregateRow,
7
+ ModelCallFactSeriesAggregate,
8
+ ModelCallFacetRow,
9
+ ModelContextContributionAggregate,
10
+ RecentModelCallRow,
11
+ RootSessionDriverRow,
12
+ ScheduleFactAggregate,
13
+ } from "./insights";
14
+
15
+ export type WorkspaceInsightsModelBundleInput = {
16
+ workspaceId: string;
17
+ since: Date;
18
+ until: Date;
19
+ priorSince: Date;
20
+ priorUntil: Date;
21
+ granularity: "day" | "hour";
22
+ provider?: string | null;
23
+ model?: string | null;
24
+ };
25
+
26
+ export type WorkspaceInsightsModelBundle = {
27
+ modelRows: ModelCallFactAggregateRow[];
28
+ priorModelRows: ModelCallFactAggregateRow[];
29
+ factBuckets: Map<string, ModelCallFactSeriesAggregate>;
30
+ rootDrivers: RootSessionDriverRow[];
31
+ priorRootDrivers: RootSessionDriverRow[];
32
+ scheduleFacts: ScheduleFactAggregate[];
33
+ facets: ModelCallFacetRow[];
34
+ recentCalls: RecentModelCallRow[];
35
+ promptContributions: ModelContextContributionAggregate;
36
+ };
37
+
38
+ type RawBundleRow = { payload: unknown };
39
+ type JsonRecord = Record<string, unknown>;
40
+
41
+ function record(value: unknown, label: string): JsonRecord {
42
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
43
+ throw new Error(`Insights model bundle ${label} is not an object`);
44
+ }
45
+ return value as JsonRecord;
46
+ }
47
+
48
+ function records(value: unknown, label: string): JsonRecord[] {
49
+ if (!Array.isArray(value)) {
50
+ throw new Error(`Insights model bundle ${label} is not an array`);
51
+ }
52
+ return value.map((item, index) => record(item, `${label}[${index}]`));
53
+ }
54
+
55
+ function stringValue(row: JsonRecord, key: string): string {
56
+ const value = row[key];
57
+ if (typeof value !== "string") {
58
+ throw new Error(`Insights model bundle ${key} is not a string`);
59
+ }
60
+ return value;
61
+ }
62
+
63
+ function nullableString(row: JsonRecord, key: string): string | null {
64
+ const value = row[key];
65
+ if (value === null || value === undefined) return null;
66
+ if (typeof value !== "string") {
67
+ throw new Error(`Insights model bundle ${key} is not nullable text`);
68
+ }
69
+ return value;
70
+ }
71
+
72
+ function numberValue(row: JsonRecord, key: string): number {
73
+ const raw = row[key];
74
+ if (
75
+ (typeof raw !== "number" && typeof raw !== "string") ||
76
+ (typeof raw === "string" && raw.trim().length === 0)
77
+ ) {
78
+ throw new Error(`Insights model bundle ${key} is not numeric`);
79
+ }
80
+ const value = Number(raw);
81
+ if (!Number.isFinite(value)) {
82
+ throw new Error(`Insights model bundle ${key} is not numeric`);
83
+ }
84
+ return value;
85
+ }
86
+
87
+ function nullableNumber(row: JsonRecord, key: string): number | null {
88
+ if (row[key] === null || row[key] === undefined) return null;
89
+ return numberValue(row, key);
90
+ }
91
+
92
+ function dateValue(row: JsonRecord, key: string): Date {
93
+ const value = row[key];
94
+ const date = value instanceof Date ? value : new Date(String(value));
95
+ if (!Number.isFinite(date.getTime())) {
96
+ throw new Error(`Insights model bundle ${key} is not a timestamp`);
97
+ }
98
+ return date;
99
+ }
100
+
101
+ function mapModelRows(value: unknown, label: string): ModelCallFactAggregateRow[] {
102
+ return records(value, label).map((row) => ({
103
+ provider: stringValue(row, "provider"),
104
+ model: stringValue(row, "model"),
105
+ billingPath: stringValue(row, "billingPath"),
106
+ calls: numberValue(row, "calls"),
107
+ inputTokens: numberValue(row, "inputTokens"),
108
+ outputTokens: numberValue(row, "outputTokens"),
109
+ cachedTokens: numberValue(row, "cachedTokens"),
110
+ cacheInputTokens: numberValue(row, "cacheInputTokens"),
111
+ cacheWriteTokens: numberValue(row, "cacheWriteTokens"),
112
+ reasoningTokens: numberValue(row, "reasoningTokens"),
113
+ totalTokens: numberValue(row, "totalTokens"),
114
+ tokenKnownCalls: numberValue(row, "tokenKnownCalls"),
115
+ cacheKnownCalls: numberValue(row, "cacheKnownCalls"),
116
+ pricedCostMicros: numberValue(row, "pricedCostMicros"),
117
+ estimatedProviderCostMicros: numberValue(row, "estimatedProviderCostMicros"),
118
+ estimatedProviderCostKnownCalls: numberValue(row, "estimatedProviderCostKnownCalls"),
119
+ }));
120
+ }
121
+
122
+ function mapRootRows(value: unknown, label: string): RootSessionDriverRow[] {
123
+ return records(value, label).map((row) => ({
124
+ rootSessionId: stringValue(row, "rootSessionId"),
125
+ title: nullableString(row, "title"),
126
+ pricedCostMicros: numberValue(row, "pricedCostMicros"),
127
+ estimatedProviderCostMicros: numberValue(row, "estimatedProviderCostMicros"),
128
+ estimatedProviderCostKnownCalls: numberValue(row, "estimatedProviderCostKnownCalls"),
129
+ totalTokens: numberValue(row, "totalTokens"),
130
+ cachedTokens: numberValue(row, "cachedTokens"),
131
+ cacheInputTokens: numberValue(row, "cacheInputTokens"),
132
+ }));
133
+ }
134
+
135
+ function mapBundle(value: unknown): WorkspaceInsightsModelBundle {
136
+ const payload = record(value, "payload");
137
+ const bucketRows = records(payload.factBuckets, "factBuckets");
138
+ const contribution = record(payload.promptContributions, "promptContributions");
139
+ const sources = records(contribution.sources, "promptContributions.sources").map((row) => ({
140
+ source: stringValue(row, "source"),
141
+ items: numberValue(row, "items"),
142
+ utf8Bytes: numberValue(row, "utf8Bytes"),
143
+ estimatedTokens: numberValue(row, "estimatedTokens"),
144
+ calls: numberValue(row, "calls"),
145
+ }));
146
+ return {
147
+ modelRows: mapModelRows(payload.modelRows, "modelRows"),
148
+ priorModelRows: mapModelRows(payload.priorModelRows, "priorModelRows"),
149
+ factBuckets: new Map(
150
+ bucketRows.map((row) => [
151
+ stringValue(row, "bucket"),
152
+ {
153
+ costMicros: numberValue(row, "costMicros"),
154
+ estimatedProviderCostMicros: numberValue(row, "estimatedProviderCostMicros"),
155
+ estimatedProviderCostKnownCalls: numberValue(row, "estimatedProviderCostKnownCalls"),
156
+ inputTokens: numberValue(row, "inputTokens"),
157
+ outputTokens: numberValue(row, "outputTokens"),
158
+ cachedTokens: numberValue(row, "cachedTokens"),
159
+ cacheInputTokens: numberValue(row, "cacheInputTokens"),
160
+ cacheWriteTokens: numberValue(row, "cacheWriteTokens"),
161
+ reasoningTokens: numberValue(row, "reasoningTokens"),
162
+ totalTokens: numberValue(row, "totalTokens"),
163
+ tokenKnownCalls: numberValue(row, "tokenKnownCalls"),
164
+ cacheKnownCalls: numberValue(row, "cacheKnownCalls"),
165
+ calls: numberValue(row, "calls"),
166
+ },
167
+ ]),
168
+ ),
169
+ rootDrivers: mapRootRows(payload.rootDrivers, "rootDrivers"),
170
+ priorRootDrivers: mapRootRows(payload.priorRootDrivers, "priorRootDrivers"),
171
+ scheduleFacts: records(payload.scheduleFacts, "scheduleFacts").map((row) => ({
172
+ scheduledTaskId: stringValue(row, "scheduledTaskId"),
173
+ pricedCostMicros: numberValue(row, "pricedCostMicros"),
174
+ estimatedProviderCostMicros: numberValue(row, "estimatedProviderCostMicros"),
175
+ estimatedProviderCostKnownCalls: numberValue(row, "estimatedProviderCostKnownCalls"),
176
+ totalTokens: numberValue(row, "totalTokens"),
177
+ cachedTokens: numberValue(row, "cachedTokens"),
178
+ cacheInputTokens: numberValue(row, "cacheInputTokens"),
179
+ calls: numberValue(row, "calls"),
180
+ billingPath: stringValue(row, "billingPath"),
181
+ })),
182
+ facets: records(payload.facets, "facets").map((row) => ({
183
+ provider: stringValue(row, "provider"),
184
+ model: stringValue(row, "model"),
185
+ })),
186
+ recentCalls: records(payload.recentCalls, "recentCalls").map((row) => ({
187
+ id: stringValue(row, "id"),
188
+ occurredAt: dateValue(row, "occurredAt"),
189
+ recordedAt: dateValue(row, "recordedAt"),
190
+ sessionId: stringValue(row, "sessionId"),
191
+ sessionTitle: nullableString(row, "sessionTitle"),
192
+ sessionDepth: nullableNumber(row, "sessionDepth"),
193
+ turnId: stringValue(row, "turnId"),
194
+ provider: stringValue(row, "provider"),
195
+ providerApi: stringValue(row, "providerApi"),
196
+ model: stringValue(row, "model"),
197
+ billingPath: stringValue(row, "billingPath"),
198
+ inputTokens: nullableNumber(row, "inputTokens"),
199
+ outputTokens: nullableNumber(row, "outputTokens"),
200
+ cachedTokens: nullableNumber(row, "cachedTokens"),
201
+ cacheWriteTokens: nullableNumber(row, "cacheWriteTokens"),
202
+ reasoningTokens: nullableNumber(row, "reasoningTokens"),
203
+ totalTokens: nullableNumber(row, "totalTokens"),
204
+ pricedCostMicros: numberValue(row, "pricedCostMicros"),
205
+ estimatedProviderCostMicros: nullableNumber(row, "estimatedProviderCostMicros"),
206
+ pricingSource: nullableString(row, "pricingSource"),
207
+ })),
208
+ promptContributions: {
209
+ estimatedTokens: numberValue(contribution, "estimatedTokens"),
210
+ utf8Bytes: numberValue(contribution, "utf8Bytes"),
211
+ coveredCalls: numberValue(contribution, "coveredCalls"),
212
+ totalCalls: numberValue(contribution, "totalCalls"),
213
+ sources,
214
+ },
215
+ };
216
+ }
217
+
218
+ /**
219
+ * One bounded model-fact query for the Workspace Insights response. The two
220
+ * narrow materialized inputs are the exact filtered current/prior UTC windows.
221
+ * A filtered request adds one unfiltered current-window read because facets are
222
+ * deliberately workspace-wide; an unfiltered request reuses current_visible.
223
+ */
224
+ export async function readWorkspaceInsightsModelBundle(
225
+ db: Database,
226
+ input: WorkspaceInsightsModelBundleInput,
227
+ ): Promise<WorkspaceInsightsModelBundle> {
228
+ const context = await rlsContextForWorkspace(db, input.workspaceId);
229
+ const bucket =
230
+ input.granularity === "hour"
231
+ ? sql`to_char(date_trunc('hour', fact.occurred_at at time zone 'UTC'), 'YYYY-MM-DD"T"HH24:00')`
232
+ : sql`to_char(date_trunc('day', fact.occurred_at at time zone 'UTC'), 'YYYY-MM-DD')`;
233
+ const facetSource =
234
+ input.provider != null || input.model != null
235
+ ? sql`opengeni_private.visible_workspace_insights_model_call_facts(
236
+ ${input.workspaceId},
237
+ ${input.since.toISOString()}::timestamp with time zone,
238
+ ${input.until.toISOString()}::timestamp with time zone,
239
+ null::text,
240
+ null::text
241
+ ) fact`
242
+ : sql`current_visible fact`;
243
+ return await withRlsContext(db, context, async (scopedDb) => {
244
+ const [row] = await scopedDb.execute<RawBundleRow>(sql`
245
+ with current_visible as materialized (
246
+ select
247
+ fact.id,
248
+ fact.workspace_id,
249
+ fact.session_id,
250
+ fact.turn_id,
251
+ fact.provider,
252
+ fact.provider_api,
253
+ fact.model,
254
+ fact.billing_path,
255
+ fact.scheduled_task_id,
256
+ fact.input_tokens,
257
+ fact.output_tokens,
258
+ fact.cached_tokens,
259
+ fact.cache_write_tokens,
260
+ fact.reasoning_tokens,
261
+ fact.total_tokens,
262
+ fact.priced_cost_micros,
263
+ fact.estimated_provider_cost_micros,
264
+ fact.pricing_source,
265
+ fact.context_contributions,
266
+ fact.occurred_at,
267
+ fact.recorded_at
268
+ from opengeni_private.visible_workspace_insights_model_call_facts(
269
+ ${input.workspaceId},
270
+ ${input.since.toISOString()}::timestamp with time zone,
271
+ ${input.until.toISOString()}::timestamp with time zone,
272
+ ${input.provider ?? null}::text,
273
+ ${input.model ?? null}::text
274
+ ) fact
275
+ ), prior_visible as materialized (
276
+ select
277
+ fact.workspace_id,
278
+ fact.session_id,
279
+ fact.provider,
280
+ fact.model,
281
+ fact.billing_path,
282
+ fact.input_tokens,
283
+ fact.output_tokens,
284
+ fact.cached_tokens,
285
+ fact.cache_write_tokens,
286
+ fact.reasoning_tokens,
287
+ fact.total_tokens,
288
+ fact.priced_cost_micros,
289
+ fact.estimated_provider_cost_micros
290
+ from opengeni_private.visible_workspace_insights_model_call_facts(
291
+ ${input.workspaceId},
292
+ ${input.priorSince.toISOString()}::timestamp with time zone,
293
+ ${input.priorUntil.toISOString()}::timestamp with time zone,
294
+ ${input.provider ?? null}::text,
295
+ ${input.model ?? null}::text
296
+ ) fact
297
+ ), selected_session_refs as (
298
+ select fact.workspace_id, fact.session_id
299
+ from current_visible fact
300
+ union
301
+ select fact.workspace_id, fact.session_id
302
+ from prior_visible fact
303
+ ), selected_sessions as materialized (
304
+ select
305
+ child.workspace_id,
306
+ child.id as session_id,
307
+ child.root_session_id,
308
+ child.title as session_title,
309
+ child.nested_agent_depth as session_depth,
310
+ root.title as root_title
311
+ from selected_session_refs fact_reference
312
+ inner join sessions child
313
+ on child.workspace_id = fact_reference.workspace_id
314
+ and child.id = fact_reference.session_id
315
+ left join sessions root
316
+ on root.workspace_id = child.workspace_id
317
+ and root.id = child.root_session_id
318
+ ), current_model_rows as (
319
+ select
320
+ fact.provider,
321
+ fact.model,
322
+ fact.billing_path,
323
+ count(*)::bigint as calls,
324
+ coalesce(sum(fact.input_tokens), 0)::bigint as input_tokens,
325
+ coalesce(sum(fact.output_tokens), 0)::bigint as output_tokens,
326
+ coalesce(sum(fact.cached_tokens), 0)::bigint as cached_tokens,
327
+ coalesce(sum(fact.input_tokens) filter (
328
+ where fact.cached_tokens is not null and fact.input_tokens is not null
329
+ ), 0)::bigint as cache_input_tokens,
330
+ coalesce(sum(fact.cache_write_tokens), 0)::bigint as cache_write_tokens,
331
+ coalesce(sum(fact.reasoning_tokens), 0)::bigint as reasoning_tokens,
332
+ coalesce(sum(fact.total_tokens), 0)::bigint as total_tokens,
333
+ count(fact.total_tokens)::bigint as token_known_calls,
334
+ count(*) filter (
335
+ where fact.cached_tokens is not null and fact.input_tokens is not null
336
+ )::bigint as cache_known_calls,
337
+ coalesce(sum(fact.priced_cost_micros) filter (
338
+ where fact.billing_path = 'opengeni_credits'
339
+ ), 0)::bigint as priced_cost_micros,
340
+ coalesce(sum(fact.estimated_provider_cost_micros), 0)::bigint
341
+ as estimated_provider_cost_micros,
342
+ count(fact.estimated_provider_cost_micros)::bigint
343
+ as estimated_provider_cost_known_calls
344
+ from current_visible fact
345
+ group by fact.provider, fact.model, fact.billing_path
346
+ ), prior_model_rows as (
347
+ select
348
+ fact.provider,
349
+ fact.model,
350
+ fact.billing_path,
351
+ count(*)::bigint as calls,
352
+ coalesce(sum(fact.input_tokens), 0)::bigint as input_tokens,
353
+ coalesce(sum(fact.output_tokens), 0)::bigint as output_tokens,
354
+ coalesce(sum(fact.cached_tokens), 0)::bigint as cached_tokens,
355
+ coalesce(sum(fact.input_tokens) filter (
356
+ where fact.cached_tokens is not null and fact.input_tokens is not null
357
+ ), 0)::bigint as cache_input_tokens,
358
+ coalesce(sum(fact.cache_write_tokens), 0)::bigint as cache_write_tokens,
359
+ coalesce(sum(fact.reasoning_tokens), 0)::bigint as reasoning_tokens,
360
+ coalesce(sum(fact.total_tokens), 0)::bigint as total_tokens,
361
+ count(fact.total_tokens)::bigint as token_known_calls,
362
+ count(*) filter (
363
+ where fact.cached_tokens is not null and fact.input_tokens is not null
364
+ )::bigint as cache_known_calls,
365
+ coalesce(sum(fact.priced_cost_micros) filter (
366
+ where fact.billing_path = 'opengeni_credits'
367
+ ), 0)::bigint as priced_cost_micros,
368
+ coalesce(sum(fact.estimated_provider_cost_micros), 0)::bigint
369
+ as estimated_provider_cost_micros,
370
+ count(fact.estimated_provider_cost_micros)::bigint
371
+ as estimated_provider_cost_known_calls
372
+ from prior_visible fact
373
+ group by fact.provider, fact.model, fact.billing_path
374
+ ), current_series_rows as (
375
+ select
376
+ ${bucket} as bucket,
377
+ coalesce(sum(fact.priced_cost_micros) filter (
378
+ where fact.billing_path = 'opengeni_credits'
379
+ ), 0)::bigint as cost_micros,
380
+ coalesce(sum(fact.estimated_provider_cost_micros), 0)::bigint
381
+ as estimated_provider_cost_micros,
382
+ count(fact.estimated_provider_cost_micros)::bigint
383
+ as estimated_provider_cost_known_calls,
384
+ coalesce(sum(fact.input_tokens), 0)::bigint as input_tokens,
385
+ coalesce(sum(fact.output_tokens), 0)::bigint as output_tokens,
386
+ coalesce(sum(fact.cached_tokens), 0)::bigint as cached_tokens,
387
+ coalesce(sum(fact.input_tokens) filter (
388
+ where fact.cached_tokens is not null and fact.input_tokens is not null
389
+ ), 0)::bigint as cache_input_tokens,
390
+ coalesce(sum(fact.cache_write_tokens), 0)::bigint as cache_write_tokens,
391
+ coalesce(sum(fact.reasoning_tokens), 0)::bigint as reasoning_tokens,
392
+ coalesce(sum(fact.total_tokens), 0)::bigint as total_tokens,
393
+ count(fact.total_tokens)::bigint as token_known_calls,
394
+ count(*) filter (
395
+ where fact.cached_tokens is not null and fact.input_tokens is not null
396
+ )::bigint as cache_known_calls,
397
+ count(*)::bigint as calls
398
+ from current_visible fact
399
+ group by ${bucket}
400
+ ), current_root_aggregates as (
401
+ select
402
+ session.root_session_id,
403
+ session.root_title as title,
404
+ coalesce(sum(fact.priced_cost_micros) filter (
405
+ where fact.billing_path = 'opengeni_credits'
406
+ ), 0)::bigint as priced_cost_micros,
407
+ coalesce(sum(fact.estimated_provider_cost_micros), 0)::bigint
408
+ as estimated_provider_cost_micros,
409
+ count(fact.estimated_provider_cost_micros)::bigint
410
+ as estimated_provider_cost_known_calls,
411
+ coalesce(sum(fact.total_tokens), 0)::bigint as total_tokens,
412
+ coalesce(sum(fact.cached_tokens), 0)::bigint as cached_tokens,
413
+ coalesce(sum(fact.input_tokens) filter (
414
+ where fact.cached_tokens is not null and fact.input_tokens is not null
415
+ ), 0)::bigint as cache_input_tokens
416
+ from current_visible fact
417
+ inner join selected_sessions session
418
+ on session.workspace_id = fact.workspace_id and session.session_id = fact.session_id
419
+ group by session.root_session_id, session.root_title
420
+ ), current_root_rows as materialized (
421
+ select *
422
+ from current_root_aggregates
423
+ order by total_tokens desc
424
+ limit 8
425
+ ), prior_root_rows as (
426
+ select
427
+ session.root_session_id,
428
+ session.root_title as title,
429
+ coalesce(sum(fact.priced_cost_micros) filter (
430
+ where fact.billing_path = 'opengeni_credits'
431
+ ), 0)::bigint as priced_cost_micros,
432
+ coalesce(sum(fact.estimated_provider_cost_micros), 0)::bigint
433
+ as estimated_provider_cost_micros,
434
+ count(fact.estimated_provider_cost_micros)::bigint
435
+ as estimated_provider_cost_known_calls,
436
+ coalesce(sum(fact.total_tokens), 0)::bigint as total_tokens,
437
+ coalesce(sum(fact.cached_tokens), 0)::bigint as cached_tokens,
438
+ coalesce(sum(fact.input_tokens) filter (
439
+ where fact.cached_tokens is not null and fact.input_tokens is not null
440
+ ), 0)::bigint as cache_input_tokens
441
+ from prior_visible fact
442
+ inner join selected_sessions session
443
+ on session.workspace_id = fact.workspace_id and session.session_id = fact.session_id
444
+ inner join current_root_rows selected_root
445
+ on selected_root.root_session_id = session.root_session_id
446
+ group by session.root_session_id, session.root_title
447
+ ), schedule_rows as (
448
+ select
449
+ fact.scheduled_task_id,
450
+ coalesce(sum(fact.priced_cost_micros) filter (
451
+ where fact.billing_path = 'opengeni_credits'
452
+ ), 0)::bigint as priced_cost_micros,
453
+ coalesce(sum(fact.estimated_provider_cost_micros), 0)::bigint
454
+ as estimated_provider_cost_micros,
455
+ count(fact.estimated_provider_cost_micros)::bigint
456
+ as estimated_provider_cost_known_calls,
457
+ coalesce(sum(fact.total_tokens), 0)::bigint as total_tokens,
458
+ coalesce(sum(fact.cached_tokens), 0)::bigint as cached_tokens,
459
+ coalesce(sum(fact.input_tokens) filter (
460
+ where fact.cached_tokens is not null and fact.input_tokens is not null
461
+ ), 0)::bigint as cache_input_tokens,
462
+ count(*)::bigint as calls,
463
+ case when bool_or(fact.billing_path = 'opengeni_credits')
464
+ then 'opengeni_credits' else 'external' end as billing_path
465
+ from current_visible fact
466
+ where fact.scheduled_task_id is not null
467
+ group by fact.scheduled_task_id
468
+ ), facet_rows as (
469
+ select distinct fact.provider, fact.model
470
+ from ${facetSource}
471
+ order by fact.provider, fact.model
472
+ limit 500
473
+ ), recent_rows as (
474
+ select
475
+ fact.id,
476
+ fact.occurred_at,
477
+ fact.recorded_at,
478
+ fact.session_id,
479
+ session.session_title,
480
+ session.session_depth,
481
+ fact.turn_id,
482
+ fact.provider,
483
+ fact.provider_api,
484
+ fact.model,
485
+ fact.billing_path,
486
+ fact.input_tokens,
487
+ fact.output_tokens,
488
+ fact.cached_tokens,
489
+ fact.cache_write_tokens,
490
+ fact.reasoning_tokens,
491
+ fact.total_tokens,
492
+ fact.priced_cost_micros,
493
+ fact.estimated_provider_cost_micros,
494
+ fact.pricing_source
495
+ from current_visible fact
496
+ left join selected_sessions session
497
+ on session.workspace_id = fact.workspace_id and session.session_id = fact.session_id
498
+ order by fact.occurred_at desc, fact.id desc
499
+ limit 50
500
+ ), contribution_coverage as (
501
+ select
502
+ count(*)::bigint as total_calls,
503
+ count(fact.context_contributions)::bigint as covered_calls
504
+ from current_visible fact
505
+ ), contribution_source_rows as (
506
+ select
507
+ fact.id,
508
+ contribution->>'source' as source,
509
+ (contribution->>'items')::bigint as items,
510
+ (contribution->>'utf8Bytes')::bigint as utf8_bytes,
511
+ (contribution->>'estimatedTokens')::bigint as estimated_tokens
512
+ from current_visible fact
513
+ cross join lateral jsonb_array_elements(fact.context_contributions) contribution
514
+ ), contribution_rows as (
515
+ select
516
+ source,
517
+ sum(items)::bigint as items,
518
+ sum(utf8_bytes)::bigint as utf8_bytes,
519
+ sum(estimated_tokens)::bigint as estimated_tokens,
520
+ count(distinct id)::bigint as calls
521
+ from contribution_source_rows
522
+ group by source
523
+ )
524
+ select jsonb_build_object(
525
+ 'modelRows', coalesce((
526
+ select jsonb_agg(jsonb_build_object(
527
+ 'provider', provider,
528
+ 'model', model,
529
+ 'billingPath', billing_path,
530
+ 'calls', calls,
531
+ 'inputTokens', input_tokens,
532
+ 'outputTokens', output_tokens,
533
+ 'cachedTokens', cached_tokens,
534
+ 'cacheInputTokens', cache_input_tokens,
535
+ 'cacheWriteTokens', cache_write_tokens,
536
+ 'reasoningTokens', reasoning_tokens,
537
+ 'totalTokens', total_tokens,
538
+ 'tokenKnownCalls', token_known_calls,
539
+ 'cacheKnownCalls', cache_known_calls,
540
+ 'pricedCostMicros', priced_cost_micros,
541
+ 'estimatedProviderCostMicros', estimated_provider_cost_micros,
542
+ 'estimatedProviderCostKnownCalls', estimated_provider_cost_known_calls
543
+ ) order by provider, model, billing_path)
544
+ from current_model_rows
545
+ ), '[]'::jsonb),
546
+ 'priorModelRows', coalesce((
547
+ select jsonb_agg(jsonb_build_object(
548
+ 'provider', provider,
549
+ 'model', model,
550
+ 'billingPath', billing_path,
551
+ 'calls', calls,
552
+ 'inputTokens', input_tokens,
553
+ 'outputTokens', output_tokens,
554
+ 'cachedTokens', cached_tokens,
555
+ 'cacheInputTokens', cache_input_tokens,
556
+ 'cacheWriteTokens', cache_write_tokens,
557
+ 'reasoningTokens', reasoning_tokens,
558
+ 'totalTokens', total_tokens,
559
+ 'tokenKnownCalls', token_known_calls,
560
+ 'cacheKnownCalls', cache_known_calls,
561
+ 'pricedCostMicros', priced_cost_micros,
562
+ 'estimatedProviderCostMicros', estimated_provider_cost_micros,
563
+ 'estimatedProviderCostKnownCalls', estimated_provider_cost_known_calls
564
+ ) order by provider, model, billing_path)
565
+ from prior_model_rows
566
+ ), '[]'::jsonb),
567
+ 'factBuckets', coalesce((
568
+ select jsonb_agg(jsonb_build_object(
569
+ 'bucket', bucket,
570
+ 'costMicros', cost_micros,
571
+ 'estimatedProviderCostMicros', estimated_provider_cost_micros,
572
+ 'estimatedProviderCostKnownCalls', estimated_provider_cost_known_calls,
573
+ 'inputTokens', input_tokens,
574
+ 'outputTokens', output_tokens,
575
+ 'cachedTokens', cached_tokens,
576
+ 'cacheInputTokens', cache_input_tokens,
577
+ 'cacheWriteTokens', cache_write_tokens,
578
+ 'reasoningTokens', reasoning_tokens,
579
+ 'totalTokens', total_tokens,
580
+ 'tokenKnownCalls', token_known_calls,
581
+ 'cacheKnownCalls', cache_known_calls,
582
+ 'calls', calls
583
+ ) order by bucket)
584
+ from current_series_rows
585
+ ), '[]'::jsonb),
586
+ 'rootDrivers', coalesce((
587
+ select jsonb_agg(jsonb_build_object(
588
+ 'rootSessionId', root_session_id,
589
+ 'title', title,
590
+ 'pricedCostMicros', priced_cost_micros,
591
+ 'estimatedProviderCostMicros', estimated_provider_cost_micros,
592
+ 'estimatedProviderCostKnownCalls', estimated_provider_cost_known_calls,
593
+ 'totalTokens', total_tokens,
594
+ 'cachedTokens', cached_tokens,
595
+ 'cacheInputTokens', cache_input_tokens
596
+ ) order by total_tokens desc)
597
+ from current_root_rows
598
+ ), '[]'::jsonb),
599
+ 'priorRootDrivers', coalesce((
600
+ select jsonb_agg(jsonb_build_object(
601
+ 'rootSessionId', root_session_id,
602
+ 'title', title,
603
+ 'pricedCostMicros', priced_cost_micros,
604
+ 'estimatedProviderCostMicros', estimated_provider_cost_micros,
605
+ 'estimatedProviderCostKnownCalls', estimated_provider_cost_known_calls,
606
+ 'totalTokens', total_tokens,
607
+ 'cachedTokens', cached_tokens,
608
+ 'cacheInputTokens', cache_input_tokens
609
+ ) order by total_tokens desc)
610
+ from prior_root_rows
611
+ ), '[]'::jsonb),
612
+ 'scheduleFacts', coalesce((
613
+ select jsonb_agg(jsonb_build_object(
614
+ 'scheduledTaskId', scheduled_task_id,
615
+ 'pricedCostMicros', priced_cost_micros,
616
+ 'estimatedProviderCostMicros', estimated_provider_cost_micros,
617
+ 'estimatedProviderCostKnownCalls', estimated_provider_cost_known_calls,
618
+ 'totalTokens', total_tokens,
619
+ 'cachedTokens', cached_tokens,
620
+ 'cacheInputTokens', cache_input_tokens,
621
+ 'calls', calls,
622
+ 'billingPath', billing_path
623
+ ) order by scheduled_task_id)
624
+ from schedule_rows
625
+ ), '[]'::jsonb),
626
+ 'facets', coalesce((
627
+ select jsonb_agg(jsonb_build_object(
628
+ 'provider', provider,
629
+ 'model', model
630
+ ) order by provider, model)
631
+ from facet_rows
632
+ ), '[]'::jsonb),
633
+ 'recentCalls', coalesce((
634
+ select jsonb_agg(jsonb_build_object(
635
+ 'id', id,
636
+ 'occurredAt', occurred_at,
637
+ 'recordedAt', recorded_at,
638
+ 'sessionId', session_id,
639
+ 'sessionTitle', session_title,
640
+ 'sessionDepth', session_depth,
641
+ 'turnId', turn_id,
642
+ 'provider', provider,
643
+ 'providerApi', provider_api,
644
+ 'model', model,
645
+ 'billingPath', billing_path,
646
+ 'inputTokens', input_tokens,
647
+ 'outputTokens', output_tokens,
648
+ 'cachedTokens', cached_tokens,
649
+ 'cacheWriteTokens', cache_write_tokens,
650
+ 'reasoningTokens', reasoning_tokens,
651
+ 'totalTokens', total_tokens,
652
+ 'pricedCostMicros', priced_cost_micros,
653
+ 'estimatedProviderCostMicros', estimated_provider_cost_micros,
654
+ 'pricingSource', pricing_source
655
+ ) order by occurred_at desc, id desc)
656
+ from recent_rows
657
+ ), '[]'::jsonb),
658
+ 'promptContributions', jsonb_build_object(
659
+ 'estimatedTokens', coalesce((select sum(estimated_tokens) from contribution_rows), 0),
660
+ 'utf8Bytes', coalesce((select sum(utf8_bytes) from contribution_rows), 0),
661
+ 'coveredCalls', (select covered_calls from contribution_coverage),
662
+ 'totalCalls', (select total_calls from contribution_coverage),
663
+ 'sources', coalesce((
664
+ select jsonb_agg(jsonb_build_object(
665
+ 'source', source,
666
+ 'items', items,
667
+ 'utf8Bytes', utf8_bytes,
668
+ 'estimatedTokens', estimated_tokens,
669
+ 'calls', calls
670
+ ) order by estimated_tokens desc nulls last, source)
671
+ from contribution_rows
672
+ ), '[]'::jsonb)
673
+ )
674
+ ) as payload
675
+ `);
676
+ if (!row) {
677
+ throw new Error("Insights model bundle query returned no row");
678
+ }
679
+ return mapBundle(row.payload);
680
+ });
681
+ }