@opengeni/db 0.28.9 → 0.31.1

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 (163) hide show
  1. package/dist/attached-browser-devices.d.ts +42 -0
  2. package/dist/attempt-tool-catalogs.d.ts +16 -0
  3. package/dist/browser-auth.d.ts +91 -0
  4. package/dist/browser-identities.d.ts +128 -0
  5. package/dist/browser-sessions.d.ts +272 -0
  6. package/dist/browser-state-artifacts.d.ts +17 -0
  7. package/dist/capability-components.d.ts +37 -0
  8. package/dist/capability-integrations.d.ts +192 -0
  9. package/dist/chunk-F5FT7BEZ.js +3535 -0
  10. package/dist/chunk-F5FT7BEZ.js.map +1 -0
  11. package/dist/chunk-ISI2TIUG.js +639 -0
  12. package/dist/chunk-ISI2TIUG.js.map +1 -0
  13. package/dist/chunk-MWDVXQOL.js +11639 -0
  14. package/dist/chunk-MWDVXQOL.js.map +1 -0
  15. package/dist/chunk-NBE6CHRI.js +955 -0
  16. package/dist/chunk-NBE6CHRI.js.map +1 -0
  17. package/dist/{chunk-VHBFHMPC.js → chunk-YHZXQ7HP.js} +754 -11
  18. package/dist/chunk-YHZXQ7HP.js.map +1 -0
  19. package/dist/codemode-operations.d.ts +117 -0
  20. package/dist/codex-token-resolver.d.ts +2 -2
  21. package/dist/company-profile-schema.d.ts +798 -0
  22. package/dist/company-profile.d.ts +268 -0
  23. package/dist/computer-sessions.d.ts +109 -0
  24. package/dist/connection-token-resolver.d.ts +9 -4
  25. package/dist/database.d.ts +52 -3
  26. package/dist/editable-artifact-durable-export.d.ts +153 -0
  27. package/dist/editable-artifact-durable-export.js +788 -0
  28. package/dist/editable-artifact-durable-export.js.map +1 -0
  29. package/dist/editable-artifact-materialization.d.ts +123 -0
  30. package/dist/editable-artifacts-schema.d.ts +4152 -0
  31. package/dist/editable-artifacts.d.ts +610 -0
  32. package/dist/editable-artifacts.js +26 -0
  33. package/dist/editable-artifacts.js.map +1 -0
  34. package/dist/generated-images.d.ts +139 -0
  35. package/dist/index.d.ts +698 -111
  36. package/dist/index.js +27573 -10322
  37. package/dist/index.js.map +1 -1
  38. package/dist/insights.d.ts +51 -4
  39. package/dist/integration-bindings.d.ts +70 -0
  40. package/dist/integration-features.d.ts +99 -0
  41. package/dist/interaction-revisions.d.ts +3 -0
  42. package/dist/interaction-schema.d.ts +5372 -0
  43. package/dist/knowledge-source-sync-schema.d.ts +1679 -0
  44. package/dist/knowledge-source-sync.d.ts +274 -0
  45. package/dist/memory-governance.d.ts +2 -2
  46. package/dist/memory-slack-delivery.d.ts +101 -0
  47. package/dist/new-session-drafts.d.ts +2 -2
  48. package/dist/pack-components.d.ts +76 -0
  49. package/dist/pack-installations.d.ts +86 -0
  50. package/dist/persistence-errors.d.ts +3 -3
  51. package/dist/plugin-packages.d.ts +126 -0
  52. package/dist/preference-registry.d.ts +1 -1
  53. package/dist/provision-roles.d.ts +9 -1
  54. package/dist/provision-roles.js +1 -1
  55. package/dist/runtime-posture.d.ts +18 -6
  56. package/dist/schema.d.ts +18342 -9099
  57. package/dist/schema.js +165 -1
  58. package/dist/scoped-knowledge.d.ts +97 -1
  59. package/dist/session-control.d.ts +4 -4
  60. package/dist/session-queue-commands.d.ts +19 -11
  61. package/dist/session-realtime-context.d.ts +2 -2
  62. package/dist/session-realtime-ledger.d.ts +4 -4
  63. package/dist/session-realtime-mirror.d.ts +2 -2
  64. package/dist/session-realtime-state.d.ts +1 -1
  65. package/dist/session-realtime-terminal.d.ts +1 -1
  66. package/dist/session-realtime.d.ts +7 -7
  67. package/dist/session-tool-call-settlement.d.ts +1 -1
  68. package/dist/slack-user-link-access.d.ts +54 -0
  69. package/dist/transcription-recordings.d.ts +2 -2
  70. package/dist/turn-initiator.d.ts +2 -2
  71. package/dist/video-generation.d.ts +216 -0
  72. package/dist/video-generation.js +66 -0
  73. package/dist/video-generation.js.map +1 -0
  74. package/dist/workspace-artifacts.d.ts +1 -1
  75. package/dist/workspace-instruction-policies.d.ts +1 -1
  76. package/dist/workspace-learning-policy-schema.d.ts +932 -0
  77. package/dist/workspace-learning-policy.d.ts +161 -0
  78. package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
  79. package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
  80. package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
  81. package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
  82. package/drizzle/0187_generated_image_artifacts.sql +173 -0
  83. package/drizzle/0188_image_generation_retention_failure.sql +25 -0
  84. package/drizzle/0189_retained_session_image_formats.sql +13 -0
  85. package/drizzle/0190_timeline_annotations.sql +31 -0
  86. package/drizzle/0191_editable_artifact_engine.sql +3853 -0
  87. package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
  88. package/drizzle/0193_editable_artifact_authorization.sql +190 -0
  89. package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
  90. package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
  91. package/drizzle/0196_rig_provider_images.sql +152 -0
  92. package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
  93. package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
  94. package/drizzle/0199_workspace_learning_policy.sql +980 -0
  95. package/drizzle/0201_company_profile_authority.sql +849 -0
  96. package/drizzle/0202_document_index_checkpoints.sql +85 -0
  97. package/drizzle/0203_durable_video_generation.sql +353 -0
  98. package/drizzle/0204_video_generation_funding.sql +44 -0
  99. package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
  100. package/drizzle/0206_browser_sessions.sql +646 -0
  101. package/drizzle/0207_browser_identities.sql +379 -0
  102. package/drizzle/0208_attached_browser_devices.sql +165 -0
  103. package/drizzle/0209_computer_sessions.sql +575 -0
  104. package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
  105. package/drizzle/0211_editable_artifact_session_links.sql +58 -0
  106. package/drizzle/0212_slack_installation_bindings.sql +348 -0
  107. package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
  108. package/drizzle/0214_session_activity_commit_gate.sql +262 -0
  109. package/drizzle/0215_capabilities_platform.sql +980 -0
  110. package/drizzle/0216_pack_component_ownership.sql +235 -0
  111. package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
  112. package/package.json +18 -5
  113. package/src/attached-browser-devices.ts +371 -0
  114. package/src/attempt-tool-catalogs.ts +131 -0
  115. package/src/browser-auth.ts +1896 -0
  116. package/src/browser-identities.ts +1168 -0
  117. package/src/browser-sessions.ts +2005 -0
  118. package/src/browser-state-artifacts.ts +59 -0
  119. package/src/capability-components.ts +166 -0
  120. package/src/capability-integrations.ts +1663 -0
  121. package/src/codemode-operations.ts +674 -0
  122. package/src/company-profile-schema.ts +143 -0
  123. package/src/company-profile.ts +968 -0
  124. package/src/computer-sessions.ts +1130 -0
  125. package/src/connection-token-resolver.ts +270 -25
  126. package/src/database.ts +427 -23
  127. package/src/editable-artifact-durable-export.ts +1201 -0
  128. package/src/editable-artifact-materialization.ts +893 -0
  129. package/src/editable-artifacts-schema.ts +879 -0
  130. package/src/editable-artifacts.ts +5404 -0
  131. package/src/generated-images.ts +740 -0
  132. package/src/index.ts +5917 -1182
  133. package/src/insights.ts +160 -13
  134. package/src/integration-bindings.ts +455 -0
  135. package/src/integration-features.ts +859 -0
  136. package/src/interaction-revisions.ts +40 -0
  137. package/src/interaction-schema.ts +1303 -0
  138. package/src/knowledge-source-sync-schema.ts +192 -0
  139. package/src/knowledge-source-sync.ts +1922 -0
  140. package/src/memory-slack-delivery.ts +801 -0
  141. package/src/pack-components.ts +954 -0
  142. package/src/pack-installations.ts +929 -0
  143. package/src/persistence-errors.ts +4 -7
  144. package/src/plugin-packages.ts +1186 -0
  145. package/src/provision-roles.ts +302 -1
  146. package/src/runtime-posture-cli.ts +9 -0
  147. package/src/runtime-posture.ts +508 -5
  148. package/src/schema.ts +5117 -3119
  149. package/src/scoped-knowledge-schema.ts +1 -1
  150. package/src/scoped-knowledge.ts +655 -3
  151. package/src/session-control.ts +8 -5
  152. package/src/session-queue-commands.ts +187 -14
  153. package/src/session-realtime-context.ts +2 -2
  154. package/src/session-realtime-ledger.ts +3 -3
  155. package/src/session-realtime.ts +7 -7
  156. package/src/session-tool-call-settlement.ts +9 -0
  157. package/src/slack-user-link-access.ts +702 -0
  158. package/src/video-generation.ts +1452 -0
  159. package/src/workspace-learning-policy-schema.ts +139 -0
  160. package/src/workspace-learning-policy.ts +595 -0
  161. package/dist/chunk-P6CUHXQZ.js +0 -7248
  162. package/dist/chunk-P6CUHXQZ.js.map +0 -1
  163. package/dist/chunk-VHBFHMPC.js.map +0 -1
package/src/insights.ts CHANGED
@@ -19,10 +19,15 @@ export type ModelCallFactAggregateRow = {
19
19
  inputTokens: number;
20
20
  outputTokens: number;
21
21
  cachedTokens: number;
22
+ cacheInputTokens: number;
22
23
  cacheWriteTokens: number;
23
24
  reasoningTokens: number;
24
25
  totalTokens: number;
26
+ tokenKnownCalls: number;
27
+ cacheKnownCalls: number;
25
28
  pricedCostMicros: number;
29
+ estimatedProviderCostMicros: number;
30
+ estimatedProviderCostKnownCalls: number;
26
31
  };
27
32
 
28
33
  export type InsightsDayBucket = {
@@ -52,15 +57,21 @@ export type RootSessionDriverRow = {
52
57
  rootSessionId: string;
53
58
  title: string | null;
54
59
  pricedCostMicros: number;
55
- inputTokens: number;
60
+ estimatedProviderCostMicros: number;
61
+ estimatedProviderCostKnownCalls: number;
62
+ totalTokens: number;
56
63
  cachedTokens: number;
64
+ cacheInputTokens: number;
57
65
  };
58
66
 
59
67
  export type ScheduleFactAggregate = {
60
68
  scheduledTaskId: string;
61
69
  pricedCostMicros: number;
62
- inputTokens: number;
70
+ estimatedProviderCostMicros: number;
71
+ estimatedProviderCostKnownCalls: number;
72
+ totalTokens: number;
63
73
  cachedTokens: number;
74
+ cacheInputTokens: number;
64
75
  calls: number;
65
76
  /** Prefer credits whenever any credits-path call exists in the window. */
66
77
  billingPath: string;
@@ -88,6 +99,28 @@ export type FloorSessionRow = {
88
99
  createdAt: Date;
89
100
  };
90
101
 
102
+ export type RecentModelCallRow = {
103
+ id: string;
104
+ occurredAt: Date;
105
+ recordedAt: Date;
106
+ sessionId: string;
107
+ sessionTitle: string | null;
108
+ turnId: string;
109
+ provider: string;
110
+ providerApi: string;
111
+ model: string;
112
+ billingPath: string;
113
+ inputTokens: number | null;
114
+ outputTokens: number | null;
115
+ cachedTokens: number | null;
116
+ cacheWriteTokens: number | null;
117
+ reasoningTokens: number | null;
118
+ totalTokens: number | null;
119
+ pricedCostMicros: number;
120
+ estimatedProviderCostMicros: number | null;
121
+ pricingSource: string | null;
122
+ };
123
+
91
124
  function dayKeyUtc(value: Date): string {
92
125
  return value.toISOString().slice(0, 10);
93
126
  }
@@ -178,10 +211,15 @@ export async function aggregateModelCallFacts(
178
211
  inputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}), 0)`,
179
212
  outputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.outputTokens}), 0)`,
180
213
  cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
214
+ cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
181
215
  cacheWriteTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cacheWriteTokens}), 0)`,
182
216
  reasoningTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.reasoningTokens}), 0)`,
183
217
  totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
184
- pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}), 0)`,
218
+ tokenKnownCalls: sql<number>`count(${schema.modelCallFacts.totalTokens})::int`,
219
+ cacheKnownCalls: sql<number>`count(*) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null)::int`,
220
+ pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
221
+ estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
222
+ estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
185
223
  })
186
224
  .from(schema.modelCallFacts)
187
225
  .where(and(...clauses))
@@ -198,10 +236,15 @@ export async function aggregateModelCallFacts(
198
236
  inputTokens: Number(row.inputTokens),
199
237
  outputTokens: Number(row.outputTokens),
200
238
  cachedTokens: Number(row.cachedTokens),
239
+ cacheInputTokens: Number(row.cacheInputTokens),
201
240
  cacheWriteTokens: Number(row.cacheWriteTokens),
202
241
  reasoningTokens: Number(row.reasoningTokens),
203
242
  totalTokens: Number(row.totalTokens),
243
+ tokenKnownCalls: Number(row.tokenKnownCalls),
244
+ cacheKnownCalls: Number(row.cacheKnownCalls),
204
245
  pricedCostMicros: Number(row.pricedCostMicros),
246
+ estimatedProviderCostMicros: Number(row.estimatedProviderCostMicros),
247
+ estimatedProviderCostKnownCalls: Number(row.estimatedProviderCostKnownCalls),
205
248
  }));
206
249
  });
207
250
  }
@@ -216,7 +259,24 @@ export async function aggregateModelCallFactsByDay(
216
259
  model?: string | null;
217
260
  },
218
261
  ): Promise<
219
- Map<string, { costMicros: number; inputTokens: number; cachedTokens: number; calls: number }>
262
+ Map<
263
+ string,
264
+ {
265
+ costMicros: number;
266
+ estimatedProviderCostMicros: number;
267
+ estimatedProviderCostKnownCalls: number;
268
+ inputTokens: number;
269
+ outputTokens: number;
270
+ cachedTokens: number;
271
+ cacheInputTokens: number;
272
+ cacheWriteTokens: number;
273
+ reasoningTokens: number;
274
+ totalTokens: number;
275
+ tokenKnownCalls: number;
276
+ cacheKnownCalls: number;
277
+ calls: number;
278
+ }
279
+ >
220
280
  > {
221
281
  const context = await rlsContextForWorkspace(db, input.workspaceId);
222
282
  return await withRlsContext(db, context, async (scopedDb) => {
@@ -230,9 +290,18 @@ export async function aggregateModelCallFactsByDay(
230
290
  const rows = await scopedDb
231
291
  .select({
232
292
  day: sql<string>`to_char(date_trunc('day', ${schema.modelCallFacts.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD')`,
233
- costMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}), 0)`,
293
+ costMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
294
+ estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
295
+ estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
234
296
  inputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}), 0)`,
297
+ outputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.outputTokens}), 0)`,
235
298
  cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
299
+ cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
300
+ cacheWriteTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cacheWriteTokens}), 0)`,
301
+ reasoningTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.reasoningTokens}), 0)`,
302
+ totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
303
+ tokenKnownCalls: sql<number>`count(${schema.modelCallFacts.totalTokens})::int`,
304
+ cacheKnownCalls: sql<number>`count(*) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null)::int`,
236
305
  calls: sql<number>`count(*)::int`,
237
306
  })
238
307
  .from(schema.modelCallFacts)
@@ -243,8 +312,17 @@ export async function aggregateModelCallFactsByDay(
243
312
  row.day,
244
313
  {
245
314
  costMicros: Number(row.costMicros),
315
+ estimatedProviderCostMicros: Number(row.estimatedProviderCostMicros),
316
+ estimatedProviderCostKnownCalls: Number(row.estimatedProviderCostKnownCalls),
246
317
  inputTokens: Number(row.inputTokens),
318
+ outputTokens: Number(row.outputTokens),
247
319
  cachedTokens: Number(row.cachedTokens),
320
+ cacheInputTokens: Number(row.cacheInputTokens),
321
+ cacheWriteTokens: Number(row.cacheWriteTokens),
322
+ reasoningTokens: Number(row.reasoningTokens),
323
+ totalTokens: Number(row.totalTokens),
324
+ tokenKnownCalls: Number(row.tokenKnownCalls),
325
+ cacheKnownCalls: Number(row.cacheKnownCalls),
248
326
  calls: Number(row.calls),
249
327
  },
250
328
  ]),
@@ -378,9 +456,12 @@ export async function aggregateRootSessionDrivers(
378
456
  .select({
379
457
  rootSessionId: childSessions.rootSessionId,
380
458
  title: rootSessions.title,
381
- pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}), 0)`,
382
- inputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}), 0)`,
459
+ pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
460
+ estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
461
+ estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
462
+ totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
383
463
  cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
464
+ cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
384
465
  })
385
466
  .from(schema.modelCallFacts)
386
467
  .innerJoin(
@@ -399,14 +480,17 @@ export async function aggregateRootSessionDrivers(
399
480
  )
400
481
  .where(and(...clauses))
401
482
  .groupBy(childSessions.rootSessionId, rootSessions.title)
402
- .orderBy(sql`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}), 0) desc`);
483
+ .orderBy(sql`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0) desc`);
403
484
  const rows = input.rootSessionIds ? await query : await query.limit(input.limit ?? 8);
404
485
  return rows.map((row) => ({
405
486
  rootSessionId: row.rootSessionId,
406
487
  title: row.title,
407
488
  pricedCostMicros: Number(row.pricedCostMicros),
408
- inputTokens: Number(row.inputTokens),
489
+ estimatedProviderCostMicros: Number(row.estimatedProviderCostMicros),
490
+ estimatedProviderCostKnownCalls: Number(row.estimatedProviderCostKnownCalls),
491
+ totalTokens: Number(row.totalTokens),
409
492
  cachedTokens: Number(row.cachedTokens),
493
+ cacheInputTokens: Number(row.cacheInputTokens),
410
494
  }));
411
495
  });
412
496
  }
@@ -436,6 +520,62 @@ export async function listModelCallFacets(
436
520
  });
437
521
  }
438
522
 
523
+ export async function listRecentModelCalls(
524
+ db: Database,
525
+ input: InsightsTimeWindow & {
526
+ workspaceId: string;
527
+ provider?: string | null;
528
+ model?: string | null;
529
+ limit?: number;
530
+ },
531
+ ): Promise<RecentModelCallRow[]> {
532
+ const context = await rlsContextForWorkspace(db, input.workspaceId);
533
+ const factSessions = alias(schema.sessions, "insight_recent_fact_sessions");
534
+ return await withRlsContext(db, context, async (scopedDb) => {
535
+ const clauses = [
536
+ eq(schema.modelCallFacts.workspaceId, input.workspaceId),
537
+ gte(schema.modelCallFacts.occurredAt, input.since),
538
+ lt(schema.modelCallFacts.occurredAt, input.until),
539
+ ...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
540
+ ...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
541
+ ];
542
+ const rows = await scopedDb
543
+ .select({
544
+ id: schema.modelCallFacts.id,
545
+ occurredAt: schema.modelCallFacts.occurredAt,
546
+ recordedAt: schema.modelCallFacts.recordedAt,
547
+ sessionId: schema.modelCallFacts.sessionId,
548
+ sessionTitle: factSessions.title,
549
+ turnId: schema.modelCallFacts.turnId,
550
+ provider: schema.modelCallFacts.provider,
551
+ providerApi: schema.modelCallFacts.providerApi,
552
+ model: schema.modelCallFacts.model,
553
+ billingPath: schema.modelCallFacts.billingPath,
554
+ inputTokens: schema.modelCallFacts.inputTokens,
555
+ outputTokens: schema.modelCallFacts.outputTokens,
556
+ cachedTokens: schema.modelCallFacts.cachedTokens,
557
+ cacheWriteTokens: schema.modelCallFacts.cacheWriteTokens,
558
+ reasoningTokens: schema.modelCallFacts.reasoningTokens,
559
+ totalTokens: schema.modelCallFacts.totalTokens,
560
+ pricedCostMicros: schema.modelCallFacts.pricedCostMicros,
561
+ estimatedProviderCostMicros: schema.modelCallFacts.estimatedProviderCostMicros,
562
+ pricingSource: schema.modelCallFacts.pricingSource,
563
+ })
564
+ .from(schema.modelCallFacts)
565
+ .leftJoin(
566
+ factSessions,
567
+ and(
568
+ eq(factSessions.workspaceId, schema.modelCallFacts.workspaceId),
569
+ eq(factSessions.id, schema.modelCallFacts.sessionId),
570
+ ),
571
+ )
572
+ .where(and(...clauses))
573
+ .orderBy(desc(schema.modelCallFacts.occurredAt), desc(schema.modelCallFacts.id))
574
+ .limit(Math.max(1, Math.min(input.limit ?? 50, 100)));
575
+ return rows;
576
+ });
577
+ }
578
+
439
579
  export async function aggregateScheduleFacts(
440
580
  db: Database,
441
581
  input: InsightsTimeWindow & {
@@ -457,9 +597,12 @@ export async function aggregateScheduleFacts(
457
597
  const rows = await scopedDb
458
598
  .select({
459
599
  scheduledTaskId: schema.modelCallFacts.scheduledTaskId,
460
- pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}), 0)`,
461
- inputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}), 0)`,
600
+ pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
601
+ estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
602
+ estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
603
+ totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
462
604
  cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
605
+ cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
463
606
  calls: sql<number>`count(*)::int`,
464
607
  billingPath: sql<string>`case
465
608
  when bool_or(${schema.modelCallFacts.billingPath} = 'opengeni_credits')
@@ -475,8 +618,11 @@ export async function aggregateScheduleFacts(
475
618
  .map((row) => ({
476
619
  scheduledTaskId: row.scheduledTaskId,
477
620
  pricedCostMicros: Number(row.pricedCostMicros),
478
- inputTokens: Number(row.inputTokens),
621
+ estimatedProviderCostMicros: Number(row.estimatedProviderCostMicros),
622
+ estimatedProviderCostKnownCalls: Number(row.estimatedProviderCostKnownCalls),
623
+ totalTokens: Number(row.totalTokens),
479
624
  cachedTokens: Number(row.cachedTokens),
625
+ cacheInputTokens: Number(row.cacheInputTokens),
480
626
  calls: Number(row.calls),
481
627
  billingPath: row.billingPath,
482
628
  }));
@@ -605,10 +751,11 @@ export async function countOnlineMachines(
605
751
  db: Database,
606
752
  workspaceId: string,
607
753
  heartbeatFreshMs: number,
754
+ now = new Date(),
608
755
  ): Promise<number> {
609
756
  const context = await rlsContextForWorkspace(db, workspaceId);
610
757
  return await withRlsContext(db, context, async (scopedDb) => {
611
- const cutoff = new Date(Date.now() - heartbeatFreshMs);
758
+ const cutoff = new Date(now.getTime() - heartbeatFreshMs);
612
759
  const [{ n } = { n: 0 }] = await scopedDb
613
760
  .select({ n: sql<number>`count(*)::int` })
614
761
  .from(schema.enrollments)