@opengeni/db 0.28.9 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attached-browser-devices.d.ts +42 -0
- package/dist/attempt-tool-catalogs.d.ts +16 -0
- package/dist/browser-auth.d.ts +299 -0
- package/dist/browser-downloads.d.ts +51 -0
- package/dist/browser-identities.d.ts +137 -0
- package/dist/browser-sessions.d.ts +354 -0
- package/dist/browser-state-artifacts.d.ts +91 -0
- package/dist/canonical-human-identities.d.ts +48 -0
- package/dist/canonical-human-identities.js +28 -0
- package/dist/canonical-human-identities.js.map +1 -0
- package/dist/capability-components.d.ts +37 -0
- package/dist/capability-integrations.d.ts +194 -0
- package/dist/chunk-5KTIEDX7.js +13200 -0
- package/dist/chunk-5KTIEDX7.js.map +1 -0
- package/dist/chunk-CQZ4QSP5.js +995 -0
- package/dist/chunk-CQZ4QSP5.js.map +1 -0
- package/dist/chunk-F32YT7MP.js +117 -0
- package/dist/chunk-F32YT7MP.js.map +1 -0
- package/dist/chunk-JC5QPLUM.js +666 -0
- package/dist/chunk-JC5QPLUM.js.map +1 -0
- package/dist/chunk-P3RE4D2B.js +3535 -0
- package/dist/chunk-P3RE4D2B.js.map +1 -0
- package/dist/chunk-TAUTWOS5.js +259 -0
- package/dist/chunk-TAUTWOS5.js.map +1 -0
- package/dist/chunk-VKLB2ZGI.js +2389 -0
- package/dist/chunk-VKLB2ZGI.js.map +1 -0
- package/dist/codemode-operations.d.ts +117 -0
- package/dist/codex-token-resolver.d.ts +2 -2
- package/dist/company-profile-schema.d.ts +798 -0
- package/dist/company-profile.d.ts +268 -0
- package/dist/computer-sessions.d.ts +109 -0
- package/dist/connection-token-resolver.d.ts +9 -4
- package/dist/database.d.ts +57 -3
- package/dist/editable-artifact-durable-export.d.ts +153 -0
- package/dist/editable-artifact-durable-export.js +788 -0
- package/dist/editable-artifact-durable-export.js.map +1 -0
- package/dist/editable-artifact-materialization.d.ts +123 -0
- package/dist/editable-artifacts-schema.d.ts +4152 -0
- package/dist/editable-artifacts.d.ts +610 -0
- package/dist/editable-artifacts.js +26 -0
- package/dist/editable-artifacts.js.map +1 -0
- package/dist/generated-images.d.ts +139 -0
- package/dist/index.d.ts +1122 -126
- package/dist/index.js +42329 -18407
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +73 -10
- package/dist/integration-bindings.d.ts +70 -0
- package/dist/integration-facets.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +14 -0
- package/dist/interaction-schema.d.ts +6036 -0
- package/dist/knowledge-source-sync-schema.d.ts +1679 -0
- package/dist/knowledge-source-sync.d.ts +274 -0
- package/dist/memory-governance.d.ts +2 -2
- package/dist/memory-slack-delivery.d.ts +101 -0
- package/dist/new-session-drafts.d.ts +2 -2
- package/dist/pack-components.d.ts +76 -0
- package/dist/pack-installations.d.ts +86 -0
- package/dist/persistence-errors.d.ts +3 -3
- package/dist/plugin-packages.d.ts +126 -0
- package/dist/preference-registry.d.ts +1 -1
- package/dist/provision-roles.d.ts +9 -1
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +19 -6
- package/dist/schema.d.ts +22654 -9359
- package/dist/schema.js +209 -3
- package/dist/scoped-knowledge.d.ts +97 -1
- package/dist/session-control.d.ts +33 -7
- package/dist/session-queue-commands.d.ts +19 -11
- package/dist/session-realtime-context.d.ts +2 -2
- package/dist/session-realtime-ledger.d.ts +4 -4
- package/dist/session-realtime-mirror.d.ts +2 -2
- package/dist/session-realtime-state.d.ts +1 -1
- package/dist/session-realtime-terminal.d.ts +1 -1
- package/dist/session-realtime.d.ts +7 -7
- package/dist/session-tenancy.d.ts +44 -0
- package/dist/session-tenancy.js +16 -0
- package/dist/session-tenancy.js.map +1 -0
- package/dist/session-tool-call-settlement.d.ts +1 -1
- package/dist/slack-task-policy-schema.d.ts +847 -0
- package/dist/slack-task-policy.d.ts +65 -0
- package/dist/slack-user-link-access.d.ts +54 -0
- package/dist/task-notes-schema.d.ts +924 -0
- package/dist/task-notes.d.ts +85 -0
- package/dist/transcription-recordings.d.ts +2 -2
- package/dist/turn-initiator.d.ts +2 -2
- package/dist/video-generation.d.ts +225 -0
- package/dist/video-generation.js +68 -0
- package/dist/video-generation.js.map +1 -0
- package/dist/workspace-artifacts.d.ts +1 -1
- package/dist/workspace-instruction-policies.d.ts +1 -1
- package/dist/workspace-learning-policy-schema.d.ts +932 -0
- package/dist/workspace-learning-policy.d.ts +161 -0
- package/dist/xai-subscription.d.ts +326 -0
- package/drizzle/0183_model_call_provider_cost_estimates.sql +39 -0
- package/drizzle/0184_sandbox_drain_teardown_fence.sql +682 -0
- package/drizzle/0185_temporal_schedule_cleanup_outbox.sql +168 -0
- package/drizzle/0186_sandbox_capture_provider_contract.sql +400 -0
- package/drizzle/0187_generated_image_artifacts.sql +173 -0
- package/drizzle/0188_image_generation_retention_failure.sql +25 -0
- package/drizzle/0189_retained_session_image_formats.sql +13 -0
- package/drizzle/0190_timeline_annotations.sql +31 -0
- package/drizzle/0191_editable_artifact_engine.sql +3853 -0
- package/drizzle/0192_editable_artifact_live_tickets.sql +338 -0
- package/drizzle/0193_editable_artifact_authorization.sql +190 -0
- package/drizzle/0194_editable_artifact_durable_exports.sql +160 -0
- package/drizzle/0195_editable_artifact_import_authorization.sql +203 -0
- package/drizzle/0196_rig_provider_images.sql +152 -0
- package/drizzle/0197_knowledge_source_sync_schedules.sql +523 -0
- package/drizzle/0198_memory_slack_publication_delivery.sql +393 -0
- package/drizzle/0199_workspace_learning_policy.sql +980 -0
- package/drizzle/0201_company_profile_authority.sql +849 -0
- package/drizzle/0202_document_index_checkpoints.sql +85 -0
- package/drizzle/0203_durable_video_generation.sql +353 -0
- package/drizzle/0204_video_generation_funding.sql +44 -0
- package/drizzle/0205_attempt_tool_catalogs.sql +230 -0
- package/drizzle/0206_browser_sessions.sql +646 -0
- package/drizzle/0207_browser_identities.sql +379 -0
- package/drizzle/0208_attached_browser_devices.sql +165 -0
- package/drizzle/0209_computer_sessions.sql +575 -0
- package/drizzle/0210_browser_auth_network_interventions.sql +441 -0
- package/drizzle/0211_editable_artifact_session_links.sql +58 -0
- package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
- package/drizzle/0212_slack_installation_bindings.sql +348 -0
- package/drizzle/0213_browser_interaction_authority.sql +67 -0
- package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
- package/drizzle/0214_browser_download_saves.sql +34 -0
- package/drizzle/0214_session_activity_commit_gate.sql +262 -0
- package/drizzle/0215_browser_controller_host.sql +385 -0
- package/drizzle/0215_capabilities_platform.sql +980 -0
- package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
- package/drizzle/0216_pack_component_ownership.sql +235 -0
- package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
- package/drizzle/0217_external_browser_auth_operations.sql +22 -0
- package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
- package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
- package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
- package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
- package/drizzle/0220_session_channels.sql +54 -0
- package/drizzle/0221_sessions_channel_index.sql +5 -0
- package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
- package/drizzle/0222_sessions_channel_fk.sql +89 -0
- package/drizzle/0223_pending_tool_event_output.sql +55 -0
- package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
- package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
- package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
- package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
- package/drizzle/0227_slack_native_actions.sql +145 -0
- package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
- package/drizzle/0228_slack_task_policy.sql +400 -0
- package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
- package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
- package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
- package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
- package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
- package/drizzle/0234_xai_subscription_authority.sql +1139 -0
- package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
- package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
- package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
- package/drizzle/0237_interaction_transition_reaper.sql +263 -0
- package/drizzle/0238_goal_persistence_policy.sql +471 -0
- package/drizzle/0238_supergrok_realtime_model.sql +29 -0
- package/drizzle/0239_supergrok_video_funding.sql +50 -0
- package/drizzle/0239_task_tree_notes.sql +990 -0
- package/package.json +26 -5
- package/src/attached-browser-devices.ts +371 -0
- package/src/attempt-tool-catalogs.ts +131 -0
- package/src/browser-auth.ts +4373 -0
- package/src/browser-downloads.ts +517 -0
- package/src/browser-identities.ts +1385 -0
- package/src/browser-sessions.ts +2294 -0
- package/src/browser-state-artifacts.ts +449 -0
- package/src/canonical-human-identities.ts +317 -0
- package/src/capability-components.ts +166 -0
- package/src/capability-integrations.ts +1571 -0
- package/src/codemode-operations.ts +674 -0
- package/src/company-profile-schema.ts +143 -0
- package/src/company-profile.ts +968 -0
- package/src/computer-sessions.ts +1130 -0
- package/src/connection-token-resolver.ts +270 -25
- package/src/database.ts +468 -24
- package/src/editable-artifact-durable-export.ts +1201 -0
- package/src/editable-artifact-materialization.ts +893 -0
- package/src/editable-artifacts-schema.ts +879 -0
- package/src/editable-artifacts.ts +5404 -0
- package/src/generated-images.ts +740 -0
- package/src/index.ts +9963 -1465
- package/src/insights.ts +251 -23
- package/src/integration-bindings.ts +455 -0
- package/src/integration-facets.ts +862 -0
- package/src/interaction-revisions.ts +70 -0
- package/src/interaction-schema.ts +1606 -0
- package/src/knowledge-source-sync-schema.ts +192 -0
- package/src/knowledge-source-sync.ts +1922 -0
- package/src/memory-slack-delivery.ts +801 -0
- package/src/pack-components.ts +954 -0
- package/src/pack-installations.ts +886 -0
- package/src/persistence-errors.ts +4 -7
- package/src/plugin-packages.ts +1186 -0
- package/src/provision-roles.ts +534 -1
- package/src/runtime-posture-cli.ts +9 -0
- package/src/runtime-posture.ts +721 -5
- package/src/schema.ts +6270 -3159
- package/src/scoped-knowledge-schema.ts +1 -1
- package/src/scoped-knowledge.ts +655 -3
- package/src/session-control.ts +130 -42
- package/src/session-queue-commands.ts +265 -15
- package/src/session-realtime-context.ts +2 -2
- package/src/session-realtime-ledger.ts +3 -3
- package/src/session-realtime.ts +7 -7
- package/src/session-tenancy.ts +188 -0
- package/src/session-tool-call-settlement.ts +18 -3
- package/src/slack-task-policy-schema.ts +130 -0
- package/src/slack-task-policy.ts +341 -0
- package/src/slack-user-link-access.ts +702 -0
- package/src/task-notes-schema.ts +135 -0
- package/src/task-notes.ts +178 -0
- package/src/video-generation.ts +1530 -0
- package/src/workspace-artifacts.ts +1 -1
- package/src/workspace-learning-policy-schema.ts +139 -0
- package/src/workspace-learning-policy.ts +595 -0
- package/src/xai-subscription.ts +1887 -0
- package/dist/chunk-P6CUHXQZ.js +0 -7248
- package/dist/chunk-P6CUHXQZ.js.map +0 -1
- package/dist/chunk-VHBFHMPC.js +0 -1219
- 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
|
-
|
|
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
|
-
|
|
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,10 +99,36 @@ 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
|
}
|
|
94
127
|
|
|
128
|
+
function hourKeyUtc(value: Date): string {
|
|
129
|
+
return `${value.toISOString().slice(0, 13)}:00`;
|
|
130
|
+
}
|
|
131
|
+
|
|
95
132
|
export async function sumUsageQuantityInRange(
|
|
96
133
|
db: Database,
|
|
97
134
|
input: {
|
|
@@ -120,7 +157,7 @@ export async function sumUsageQuantityInRange(
|
|
|
120
157
|
});
|
|
121
158
|
}
|
|
122
159
|
|
|
123
|
-
|
|
160
|
+
async function sumUsageQuantityByBucket(
|
|
124
161
|
db: Database,
|
|
125
162
|
input: {
|
|
126
163
|
workspaceId: string;
|
|
@@ -128,12 +165,21 @@ export async function sumUsageQuantityByDay(
|
|
|
128
165
|
since: Date;
|
|
129
166
|
until: Date;
|
|
130
167
|
},
|
|
168
|
+
granularity: "day" | "hour",
|
|
131
169
|
): Promise<Map<string, number>> {
|
|
132
170
|
const context = await rlsContextForWorkspace(db, input.workspaceId);
|
|
133
171
|
return await withRlsContext(db, context, async (scopedDb) => {
|
|
172
|
+
const bucket =
|
|
173
|
+
granularity === "hour"
|
|
174
|
+
? sql<string>`to_char(date_trunc('hour', ${schema.usageEvents.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD"T"HH24:00')`
|
|
175
|
+
: sql<string>`to_char(date_trunc('day', ${schema.usageEvents.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD')`;
|
|
176
|
+
const bucketGroup =
|
|
177
|
+
granularity === "hour"
|
|
178
|
+
? sql`date_trunc('hour', ${schema.usageEvents.occurredAt} at time zone 'UTC')`
|
|
179
|
+
: sql`date_trunc('day', ${schema.usageEvents.occurredAt} at time zone 'UTC')`;
|
|
134
180
|
const rows = await scopedDb
|
|
135
181
|
.select({
|
|
136
|
-
|
|
182
|
+
bucket,
|
|
137
183
|
total: sql<number>`coalesce(sum(${schema.usageEvents.quantity}), 0)`,
|
|
138
184
|
})
|
|
139
185
|
.from(schema.usageEvents)
|
|
@@ -145,11 +191,35 @@ export async function sumUsageQuantityByDay(
|
|
|
145
191
|
lt(schema.usageEvents.occurredAt, input.until),
|
|
146
192
|
),
|
|
147
193
|
)
|
|
148
|
-
.groupBy(
|
|
149
|
-
return new Map(rows.map((row) => [row.
|
|
194
|
+
.groupBy(bucketGroup);
|
|
195
|
+
return new Map(rows.map((row) => [row.bucket, Number(row.total)]));
|
|
150
196
|
});
|
|
151
197
|
}
|
|
152
198
|
|
|
199
|
+
export async function sumUsageQuantityByDay(
|
|
200
|
+
db: Database,
|
|
201
|
+
input: {
|
|
202
|
+
workspaceId: string;
|
|
203
|
+
eventType: string;
|
|
204
|
+
since: Date;
|
|
205
|
+
until: Date;
|
|
206
|
+
},
|
|
207
|
+
): Promise<Map<string, number>> {
|
|
208
|
+
return await sumUsageQuantityByBucket(db, input, "day");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export async function sumUsageQuantityByHour(
|
|
212
|
+
db: Database,
|
|
213
|
+
input: {
|
|
214
|
+
workspaceId: string;
|
|
215
|
+
eventType: string;
|
|
216
|
+
since: Date;
|
|
217
|
+
until: Date;
|
|
218
|
+
},
|
|
219
|
+
): Promise<Map<string, number>> {
|
|
220
|
+
return await sumUsageQuantityByBucket(db, input, "hour");
|
|
221
|
+
}
|
|
222
|
+
|
|
153
223
|
export async function aggregateModelCallFacts(
|
|
154
224
|
db: Database,
|
|
155
225
|
input: {
|
|
@@ -178,10 +248,15 @@ export async function aggregateModelCallFacts(
|
|
|
178
248
|
inputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}), 0)`,
|
|
179
249
|
outputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.outputTokens}), 0)`,
|
|
180
250
|
cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
|
|
251
|
+
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
252
|
cacheWriteTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cacheWriteTokens}), 0)`,
|
|
182
253
|
reasoningTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.reasoningTokens}), 0)`,
|
|
183
254
|
totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
|
|
184
|
-
|
|
255
|
+
tokenKnownCalls: sql<number>`count(${schema.modelCallFacts.totalTokens})::int`,
|
|
256
|
+
cacheKnownCalls: sql<number>`count(*) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null)::int`,
|
|
257
|
+
pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
|
|
258
|
+
estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
|
|
259
|
+
estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
|
|
185
260
|
})
|
|
186
261
|
.from(schema.modelCallFacts)
|
|
187
262
|
.where(and(...clauses))
|
|
@@ -198,15 +273,36 @@ export async function aggregateModelCallFacts(
|
|
|
198
273
|
inputTokens: Number(row.inputTokens),
|
|
199
274
|
outputTokens: Number(row.outputTokens),
|
|
200
275
|
cachedTokens: Number(row.cachedTokens),
|
|
276
|
+
cacheInputTokens: Number(row.cacheInputTokens),
|
|
201
277
|
cacheWriteTokens: Number(row.cacheWriteTokens),
|
|
202
278
|
reasoningTokens: Number(row.reasoningTokens),
|
|
203
279
|
totalTokens: Number(row.totalTokens),
|
|
280
|
+
tokenKnownCalls: Number(row.tokenKnownCalls),
|
|
281
|
+
cacheKnownCalls: Number(row.cacheKnownCalls),
|
|
204
282
|
pricedCostMicros: Number(row.pricedCostMicros),
|
|
283
|
+
estimatedProviderCostMicros: Number(row.estimatedProviderCostMicros),
|
|
284
|
+
estimatedProviderCostKnownCalls: Number(row.estimatedProviderCostKnownCalls),
|
|
205
285
|
}));
|
|
206
286
|
});
|
|
207
287
|
}
|
|
208
288
|
|
|
209
|
-
|
|
289
|
+
type ModelCallFactSeriesAggregate = {
|
|
290
|
+
costMicros: number;
|
|
291
|
+
estimatedProviderCostMicros: number;
|
|
292
|
+
estimatedProviderCostKnownCalls: number;
|
|
293
|
+
inputTokens: number;
|
|
294
|
+
outputTokens: number;
|
|
295
|
+
cachedTokens: number;
|
|
296
|
+
cacheInputTokens: number;
|
|
297
|
+
cacheWriteTokens: number;
|
|
298
|
+
reasoningTokens: number;
|
|
299
|
+
totalTokens: number;
|
|
300
|
+
tokenKnownCalls: number;
|
|
301
|
+
cacheKnownCalls: number;
|
|
302
|
+
calls: number;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
async function aggregateModelCallFactsByBucket(
|
|
210
306
|
db: Database,
|
|
211
307
|
input: {
|
|
212
308
|
workspaceId: string;
|
|
@@ -215,9 +311,8 @@ export async function aggregateModelCallFactsByDay(
|
|
|
215
311
|
provider?: string | null;
|
|
216
312
|
model?: string | null;
|
|
217
313
|
},
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
> {
|
|
314
|
+
granularity: "day" | "hour",
|
|
315
|
+
): Promise<Map<string, ModelCallFactSeriesAggregate>> {
|
|
221
316
|
const context = await rlsContextForWorkspace(db, input.workspaceId);
|
|
222
317
|
return await withRlsContext(db, context, async (scopedDb) => {
|
|
223
318
|
const clauses = [
|
|
@@ -227,24 +322,50 @@ export async function aggregateModelCallFactsByDay(
|
|
|
227
322
|
...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
|
|
228
323
|
...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
|
|
229
324
|
];
|
|
325
|
+
const bucket =
|
|
326
|
+
granularity === "hour"
|
|
327
|
+
? sql<string>`to_char(date_trunc('hour', ${schema.modelCallFacts.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD"T"HH24:00')`
|
|
328
|
+
: sql<string>`to_char(date_trunc('day', ${schema.modelCallFacts.occurredAt} at time zone 'UTC'), 'YYYY-MM-DD')`;
|
|
329
|
+
const bucketGroup =
|
|
330
|
+
granularity === "hour"
|
|
331
|
+
? sql`date_trunc('hour', ${schema.modelCallFacts.occurredAt} at time zone 'UTC')`
|
|
332
|
+
: sql`date_trunc('day', ${schema.modelCallFacts.occurredAt} at time zone 'UTC')`;
|
|
230
333
|
const rows = await scopedDb
|
|
231
334
|
.select({
|
|
232
|
-
|
|
233
|
-
costMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}), 0)`,
|
|
335
|
+
bucket,
|
|
336
|
+
costMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
|
|
337
|
+
estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
|
|
338
|
+
estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
|
|
234
339
|
inputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}), 0)`,
|
|
340
|
+
outputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.outputTokens}), 0)`,
|
|
235
341
|
cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
|
|
342
|
+
cacheInputTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.inputTokens}) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null), 0)`,
|
|
343
|
+
cacheWriteTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cacheWriteTokens}), 0)`,
|
|
344
|
+
reasoningTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.reasoningTokens}), 0)`,
|
|
345
|
+
totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
|
|
346
|
+
tokenKnownCalls: sql<number>`count(${schema.modelCallFacts.totalTokens})::int`,
|
|
347
|
+
cacheKnownCalls: sql<number>`count(*) filter (where ${schema.modelCallFacts.cachedTokens} is not null and ${schema.modelCallFacts.inputTokens} is not null)::int`,
|
|
236
348
|
calls: sql<number>`count(*)::int`,
|
|
237
349
|
})
|
|
238
350
|
.from(schema.modelCallFacts)
|
|
239
351
|
.where(and(...clauses))
|
|
240
|
-
.groupBy(
|
|
352
|
+
.groupBy(bucketGroup);
|
|
241
353
|
return new Map(
|
|
242
354
|
rows.map((row) => [
|
|
243
|
-
row.
|
|
355
|
+
row.bucket,
|
|
244
356
|
{
|
|
245
357
|
costMicros: Number(row.costMicros),
|
|
358
|
+
estimatedProviderCostMicros: Number(row.estimatedProviderCostMicros),
|
|
359
|
+
estimatedProviderCostKnownCalls: Number(row.estimatedProviderCostKnownCalls),
|
|
246
360
|
inputTokens: Number(row.inputTokens),
|
|
361
|
+
outputTokens: Number(row.outputTokens),
|
|
247
362
|
cachedTokens: Number(row.cachedTokens),
|
|
363
|
+
cacheInputTokens: Number(row.cacheInputTokens),
|
|
364
|
+
cacheWriteTokens: Number(row.cacheWriteTokens),
|
|
365
|
+
reasoningTokens: Number(row.reasoningTokens),
|
|
366
|
+
totalTokens: Number(row.totalTokens),
|
|
367
|
+
tokenKnownCalls: Number(row.tokenKnownCalls),
|
|
368
|
+
cacheKnownCalls: Number(row.cacheKnownCalls),
|
|
248
369
|
calls: Number(row.calls),
|
|
249
370
|
},
|
|
250
371
|
]),
|
|
@@ -252,6 +373,32 @@ export async function aggregateModelCallFactsByDay(
|
|
|
252
373
|
});
|
|
253
374
|
}
|
|
254
375
|
|
|
376
|
+
export async function aggregateModelCallFactsByDay(
|
|
377
|
+
db: Database,
|
|
378
|
+
input: {
|
|
379
|
+
workspaceId: string;
|
|
380
|
+
since: Date;
|
|
381
|
+
until: Date;
|
|
382
|
+
provider?: string | null;
|
|
383
|
+
model?: string | null;
|
|
384
|
+
},
|
|
385
|
+
): Promise<Map<string, ModelCallFactSeriesAggregate>> {
|
|
386
|
+
return await aggregateModelCallFactsByBucket(db, input, "day");
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export async function aggregateModelCallFactsByHour(
|
|
390
|
+
db: Database,
|
|
391
|
+
input: {
|
|
392
|
+
workspaceId: string;
|
|
393
|
+
since: Date;
|
|
394
|
+
until: Date;
|
|
395
|
+
provider?: string | null;
|
|
396
|
+
model?: string | null;
|
|
397
|
+
},
|
|
398
|
+
): Promise<Map<string, ModelCallFactSeriesAggregate>> {
|
|
399
|
+
return await aggregateModelCallFactsByBucket(db, input, "hour");
|
|
400
|
+
}
|
|
401
|
+
|
|
255
402
|
export async function aggregateWarmSecondsByGroup(
|
|
256
403
|
db: Database,
|
|
257
404
|
input: InsightsTimeWindow & { workspaceId: string; limit?: number },
|
|
@@ -378,9 +525,12 @@ export async function aggregateRootSessionDrivers(
|
|
|
378
525
|
.select({
|
|
379
526
|
rootSessionId: childSessions.rootSessionId,
|
|
380
527
|
title: rootSessions.title,
|
|
381
|
-
pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}), 0)`,
|
|
382
|
-
|
|
528
|
+
pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
|
|
529
|
+
estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
|
|
530
|
+
estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
|
|
531
|
+
totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
|
|
383
532
|
cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
|
|
533
|
+
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
534
|
})
|
|
385
535
|
.from(schema.modelCallFacts)
|
|
386
536
|
.innerJoin(
|
|
@@ -399,14 +549,17 @@ export async function aggregateRootSessionDrivers(
|
|
|
399
549
|
)
|
|
400
550
|
.where(and(...clauses))
|
|
401
551
|
.groupBy(childSessions.rootSessionId, rootSessions.title)
|
|
402
|
-
.orderBy(sql`coalesce(sum(${schema.modelCallFacts.
|
|
552
|
+
.orderBy(sql`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0) desc`);
|
|
403
553
|
const rows = input.rootSessionIds ? await query : await query.limit(input.limit ?? 8);
|
|
404
554
|
return rows.map((row) => ({
|
|
405
555
|
rootSessionId: row.rootSessionId,
|
|
406
556
|
title: row.title,
|
|
407
557
|
pricedCostMicros: Number(row.pricedCostMicros),
|
|
408
|
-
|
|
558
|
+
estimatedProviderCostMicros: Number(row.estimatedProviderCostMicros),
|
|
559
|
+
estimatedProviderCostKnownCalls: Number(row.estimatedProviderCostKnownCalls),
|
|
560
|
+
totalTokens: Number(row.totalTokens),
|
|
409
561
|
cachedTokens: Number(row.cachedTokens),
|
|
562
|
+
cacheInputTokens: Number(row.cacheInputTokens),
|
|
410
563
|
}));
|
|
411
564
|
});
|
|
412
565
|
}
|
|
@@ -436,6 +589,62 @@ export async function listModelCallFacets(
|
|
|
436
589
|
});
|
|
437
590
|
}
|
|
438
591
|
|
|
592
|
+
export async function listRecentModelCalls(
|
|
593
|
+
db: Database,
|
|
594
|
+
input: InsightsTimeWindow & {
|
|
595
|
+
workspaceId: string;
|
|
596
|
+
provider?: string | null;
|
|
597
|
+
model?: string | null;
|
|
598
|
+
limit?: number;
|
|
599
|
+
},
|
|
600
|
+
): Promise<RecentModelCallRow[]> {
|
|
601
|
+
const context = await rlsContextForWorkspace(db, input.workspaceId);
|
|
602
|
+
const factSessions = alias(schema.sessions, "insight_recent_fact_sessions");
|
|
603
|
+
return await withRlsContext(db, context, async (scopedDb) => {
|
|
604
|
+
const clauses = [
|
|
605
|
+
eq(schema.modelCallFacts.workspaceId, input.workspaceId),
|
|
606
|
+
gte(schema.modelCallFacts.occurredAt, input.since),
|
|
607
|
+
lt(schema.modelCallFacts.occurredAt, input.until),
|
|
608
|
+
...(input.provider ? [eq(schema.modelCallFacts.provider, input.provider)] : []),
|
|
609
|
+
...(input.model ? [eq(schema.modelCallFacts.model, input.model)] : []),
|
|
610
|
+
];
|
|
611
|
+
const rows = await scopedDb
|
|
612
|
+
.select({
|
|
613
|
+
id: schema.modelCallFacts.id,
|
|
614
|
+
occurredAt: schema.modelCallFacts.occurredAt,
|
|
615
|
+
recordedAt: schema.modelCallFacts.recordedAt,
|
|
616
|
+
sessionId: schema.modelCallFacts.sessionId,
|
|
617
|
+
sessionTitle: factSessions.title,
|
|
618
|
+
turnId: schema.modelCallFacts.turnId,
|
|
619
|
+
provider: schema.modelCallFacts.provider,
|
|
620
|
+
providerApi: schema.modelCallFacts.providerApi,
|
|
621
|
+
model: schema.modelCallFacts.model,
|
|
622
|
+
billingPath: schema.modelCallFacts.billingPath,
|
|
623
|
+
inputTokens: schema.modelCallFacts.inputTokens,
|
|
624
|
+
outputTokens: schema.modelCallFacts.outputTokens,
|
|
625
|
+
cachedTokens: schema.modelCallFacts.cachedTokens,
|
|
626
|
+
cacheWriteTokens: schema.modelCallFacts.cacheWriteTokens,
|
|
627
|
+
reasoningTokens: schema.modelCallFacts.reasoningTokens,
|
|
628
|
+
totalTokens: schema.modelCallFacts.totalTokens,
|
|
629
|
+
pricedCostMicros: schema.modelCallFacts.pricedCostMicros,
|
|
630
|
+
estimatedProviderCostMicros: schema.modelCallFacts.estimatedProviderCostMicros,
|
|
631
|
+
pricingSource: schema.modelCallFacts.pricingSource,
|
|
632
|
+
})
|
|
633
|
+
.from(schema.modelCallFacts)
|
|
634
|
+
.leftJoin(
|
|
635
|
+
factSessions,
|
|
636
|
+
and(
|
|
637
|
+
eq(factSessions.workspaceId, schema.modelCallFacts.workspaceId),
|
|
638
|
+
eq(factSessions.id, schema.modelCallFacts.sessionId),
|
|
639
|
+
),
|
|
640
|
+
)
|
|
641
|
+
.where(and(...clauses))
|
|
642
|
+
.orderBy(desc(schema.modelCallFacts.occurredAt), desc(schema.modelCallFacts.id))
|
|
643
|
+
.limit(Math.max(1, Math.min(input.limit ?? 50, 100)));
|
|
644
|
+
return rows;
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
|
|
439
648
|
export async function aggregateScheduleFacts(
|
|
440
649
|
db: Database,
|
|
441
650
|
input: InsightsTimeWindow & {
|
|
@@ -457,9 +666,12 @@ export async function aggregateScheduleFacts(
|
|
|
457
666
|
const rows = await scopedDb
|
|
458
667
|
.select({
|
|
459
668
|
scheduledTaskId: schema.modelCallFacts.scheduledTaskId,
|
|
460
|
-
pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}), 0)`,
|
|
461
|
-
|
|
669
|
+
pricedCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.pricedCostMicros}) filter (where ${schema.modelCallFacts.billingPath} = 'opengeni_credits'), 0)`,
|
|
670
|
+
estimatedProviderCostMicros: sql<number>`coalesce(sum(${schema.modelCallFacts.estimatedProviderCostMicros}), 0)`,
|
|
671
|
+
estimatedProviderCostKnownCalls: sql<number>`count(${schema.modelCallFacts.estimatedProviderCostMicros})::int`,
|
|
672
|
+
totalTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.totalTokens}), 0)`,
|
|
462
673
|
cachedTokens: sql<number>`coalesce(sum(${schema.modelCallFacts.cachedTokens}), 0)`,
|
|
674
|
+
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
675
|
calls: sql<number>`count(*)::int`,
|
|
464
676
|
billingPath: sql<string>`case
|
|
465
677
|
when bool_or(${schema.modelCallFacts.billingPath} = 'opengeni_credits')
|
|
@@ -475,8 +687,11 @@ export async function aggregateScheduleFacts(
|
|
|
475
687
|
.map((row) => ({
|
|
476
688
|
scheduledTaskId: row.scheduledTaskId,
|
|
477
689
|
pricedCostMicros: Number(row.pricedCostMicros),
|
|
478
|
-
|
|
690
|
+
estimatedProviderCostMicros: Number(row.estimatedProviderCostMicros),
|
|
691
|
+
estimatedProviderCostKnownCalls: Number(row.estimatedProviderCostKnownCalls),
|
|
692
|
+
totalTokens: Number(row.totalTokens),
|
|
479
693
|
cachedTokens: Number(row.cachedTokens),
|
|
694
|
+
cacheInputTokens: Number(row.cacheInputTokens),
|
|
480
695
|
calls: Number(row.calls),
|
|
481
696
|
billingPath: row.billingPath,
|
|
482
697
|
}));
|
|
@@ -605,10 +820,11 @@ export async function countOnlineMachines(
|
|
|
605
820
|
db: Database,
|
|
606
821
|
workspaceId: string,
|
|
607
822
|
heartbeatFreshMs: number,
|
|
823
|
+
now = new Date(),
|
|
608
824
|
): Promise<number> {
|
|
609
825
|
const context = await rlsContextForWorkspace(db, workspaceId);
|
|
610
826
|
return await withRlsContext(db, context, async (scopedDb) => {
|
|
611
|
-
const cutoff = new Date(
|
|
827
|
+
const cutoff = new Date(now.getTime() - heartbeatFreshMs);
|
|
612
828
|
const [{ n } = { n: 0 }] = await scopedDb
|
|
613
829
|
.select({ n: sql<number>`count(*)::int` })
|
|
614
830
|
.from(schema.enrollments)
|
|
@@ -636,6 +852,18 @@ export function enumerateUtcDays(since: Date, until: Date): string[] {
|
|
|
636
852
|
return days;
|
|
637
853
|
}
|
|
638
854
|
|
|
855
|
+
export function enumerateUtcHours(since: Date, until: Date): string[] {
|
|
856
|
+
const hours: string[] = [];
|
|
857
|
+
const cursor = new Date(since);
|
|
858
|
+
cursor.setUTCMinutes(0, 0, 0);
|
|
859
|
+
const end = until.getTime();
|
|
860
|
+
while (cursor.getTime() < end) {
|
|
861
|
+
hours.push(hourKeyUtc(cursor));
|
|
862
|
+
cursor.setUTCHours(cursor.getUTCHours() + 1);
|
|
863
|
+
}
|
|
864
|
+
return hours;
|
|
865
|
+
}
|
|
866
|
+
|
|
639
867
|
/**
|
|
640
868
|
* Idempotent YTD backfill from authoritative agent.model.usage into model_call_facts.
|
|
641
869
|
* Never rewrites billing rows or existing live facts (onConflictDoNothing).
|