@opengeni/db 0.31.1 → 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/browser-auth.d.ts +209 -1
- package/dist/browser-downloads.d.ts +51 -0
- package/dist/browser-identities.d.ts +11 -2
- package/dist/browser-sessions.d.ts +83 -1
- package/dist/browser-state-artifacts.d.ts +75 -1
- 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-integrations.d.ts +8 -6
- package/dist/{chunk-MWDVXQOL.js → chunk-5KTIEDX7.js} +5773 -4212
- package/dist/chunk-5KTIEDX7.js.map +1 -0
- package/dist/{chunk-NBE6CHRI.js → chunk-CQZ4QSP5.js} +49 -9
- 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-ISI2TIUG.js → chunk-JC5QPLUM.js} +30 -3
- package/dist/chunk-JC5QPLUM.js.map +1 -0
- package/dist/{chunk-F5FT7BEZ.js → chunk-P3RE4D2B.js} +2 -2
- package/dist/chunk-TAUTWOS5.js +259 -0
- package/dist/chunk-TAUTWOS5.js.map +1 -0
- package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
- package/dist/chunk-VKLB2ZGI.js.map +1 -0
- package/dist/database.d.ts +5 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +438 -29
- package/dist/index.js +35640 -28969
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +23 -7
- package/dist/integration-bindings.d.ts +24 -24
- package/dist/integration-facets.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +11 -0
- package/dist/interaction-schema.d.ts +698 -34
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +8 -7
- package/dist/schema.d.ts +9464 -5412
- package/dist/schema.js +51 -9
- package/dist/session-control.d.ts +29 -3
- 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/slack-task-policy-schema.d.ts +847 -0
- package/dist/slack-task-policy.d.ts +65 -0
- package/dist/task-notes-schema.d.ts +924 -0
- package/dist/task-notes.d.ts +85 -0
- package/dist/video-generation.d.ts +9 -0
- package/dist/video-generation.js +5 -3
- package/dist/xai-subscription.d.ts +326 -0
- package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
- package/drizzle/0213_browser_interaction_authority.sql +67 -0
- package/drizzle/0214_browser_download_saves.sql +34 -0
- package/drizzle/0215_browser_controller_host.sql +385 -0
- package/drizzle/0216_browser_auth_health_evidence.sql +137 -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 +13 -5
- package/src/browser-auth.ts +2600 -123
- package/src/browser-downloads.ts +517 -0
- package/src/browser-identities.ts +220 -3
- package/src/browser-sessions.ts +334 -45
- package/src/browser-state-artifacts.ts +402 -12
- package/src/canonical-human-identities.ts +317 -0
- package/src/capability-integrations.ts +121 -213
- package/src/database.ts +41 -1
- package/src/index.ts +4157 -394
- package/src/insights.ts +109 -28
- package/src/integration-bindings.ts +101 -101
- package/src/{integration-features.ts → integration-facets.ts} +187 -184
- package/src/interaction-revisions.ts +33 -3
- package/src/interaction-schema.ts +311 -8
- package/src/pack-components.ts +43 -43
- package/src/pack-installations.ts +0 -43
- package/src/plugin-packages.ts +9 -9
- package/src/provision-roles.ts +232 -0
- package/src/runtime-posture.ts +227 -14
- package/src/schema.ts +1188 -75
- package/src/session-control.ts +122 -37
- package/src/session-queue-commands.ts +78 -1
- package/src/session-tenancy.ts +188 -0
- package/src/session-tool-call-settlement.ts +9 -3
- package/src/slack-task-policy-schema.ts +130 -0
- package/src/slack-task-policy.ts +341 -0
- package/src/task-notes-schema.ts +135 -0
- package/src/task-notes.ts +178 -0
- package/src/video-generation.ts +90 -12
- package/src/workspace-artifacts.ts +1 -1
- package/src/xai-subscription.ts +1887 -0
- package/dist/chunk-ISI2TIUG.js.map +0 -1
- package/dist/chunk-MWDVXQOL.js.map +0 -1
- package/dist/chunk-NBE6CHRI.js.map +0 -1
- package/dist/chunk-YHZXQ7HP.js.map +0 -1
- package/dist/integration-features.d.ts +0 -99
- /package/dist/{chunk-F5FT7BEZ.js.map → chunk-P3RE4D2B.js.map} +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TASK_NOTE_LIST_DEFAULT_LIMIT,
|
|
3
|
+
TASK_NOTE_LIST_MAX_LIMIT,
|
|
4
|
+
TaskNote,
|
|
5
|
+
TaskNoteKind,
|
|
6
|
+
TaskNoteListResponse,
|
|
7
|
+
TaskNoteMutationResult,
|
|
8
|
+
TaskNoteReason,
|
|
9
|
+
TaskNoteText,
|
|
10
|
+
type TaskNoteKind as TaskNoteKindType,
|
|
11
|
+
} from "@opengeni/contracts";
|
|
12
|
+
import { sql } from "drizzle-orm";
|
|
13
|
+
import type { Database } from "./database";
|
|
14
|
+
import { rawRows, withRlsContext } from "./database";
|
|
15
|
+
|
|
16
|
+
export type TaskNoteAttemptClaims = {
|
|
17
|
+
accountId: string;
|
|
18
|
+
workspaceId: string;
|
|
19
|
+
sessionId: string;
|
|
20
|
+
turnId: string;
|
|
21
|
+
attemptId: string;
|
|
22
|
+
executionGeneration: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type CreateTaskNoteInput = TaskNoteAttemptClaims & {
|
|
26
|
+
operationId: string;
|
|
27
|
+
kind: TaskNoteKindType;
|
|
28
|
+
text: string;
|
|
29
|
+
expiresInDays: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type ArchiveTaskNoteInput = TaskNoteAttemptClaims & {
|
|
33
|
+
operationId: string;
|
|
34
|
+
noteId: string;
|
|
35
|
+
expectedVersion: number;
|
|
36
|
+
reason: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type ListTaskNotesInput = TaskNoteAttemptClaims & {
|
|
40
|
+
includeArchived?: boolean;
|
|
41
|
+
limit?: number;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type TaskNoteRow = {
|
|
45
|
+
note_id: string;
|
|
46
|
+
root_session_id: string;
|
|
47
|
+
kind: string;
|
|
48
|
+
note_text: string;
|
|
49
|
+
status: string;
|
|
50
|
+
version: number;
|
|
51
|
+
expires_at: Date | string;
|
|
52
|
+
created_at: Date | string;
|
|
53
|
+
updated_at: Date | string;
|
|
54
|
+
archived_at: Date | string | null;
|
|
55
|
+
actor_kind: string;
|
|
56
|
+
source_session_id: string;
|
|
57
|
+
source_turn_id: string;
|
|
58
|
+
replayed?: boolean;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
function iso(value: Date | string): string {
|
|
62
|
+
return (value instanceof Date ? value : new Date(value)).toISOString();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function noteFromRow(row: TaskNoteRow) {
|
|
66
|
+
return TaskNote.parse({
|
|
67
|
+
id: row.note_id,
|
|
68
|
+
rootSessionId: row.root_session_id,
|
|
69
|
+
kind: row.kind,
|
|
70
|
+
text: row.note_text,
|
|
71
|
+
status: row.status,
|
|
72
|
+
version: row.version,
|
|
73
|
+
expiresAt: iso(row.expires_at),
|
|
74
|
+
createdAt: iso(row.created_at),
|
|
75
|
+
updatedAt: iso(row.updated_at),
|
|
76
|
+
archivedAt: row.archived_at === null ? null : iso(row.archived_at),
|
|
77
|
+
provenance: {
|
|
78
|
+
actorKind: row.actor_kind,
|
|
79
|
+
sourceSessionId: row.source_session_id,
|
|
80
|
+
sourceTurnId: row.source_turn_id,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function assertAttemptClaims(claims: TaskNoteAttemptClaims): void {
|
|
86
|
+
if (!Number.isSafeInteger(claims.executionGeneration) || claims.executionGeneration < 1) {
|
|
87
|
+
throw new Error("Task notes require a positive exact execution generation");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function createTaskNote(db: Database, input: CreateTaskNoteInput) {
|
|
92
|
+
assertAttemptClaims(input);
|
|
93
|
+
TaskNoteKind.parse(input.kind);
|
|
94
|
+
TaskNoteText.parse(input.text);
|
|
95
|
+
if (
|
|
96
|
+
!Number.isSafeInteger(input.expiresInDays) ||
|
|
97
|
+
input.expiresInDays < 1 ||
|
|
98
|
+
input.expiresInDays > 30
|
|
99
|
+
) {
|
|
100
|
+
throw new Error("Task note expiry must be 1-30 whole days");
|
|
101
|
+
}
|
|
102
|
+
const rows = await withRlsContext(
|
|
103
|
+
db,
|
|
104
|
+
{ accountId: input.accountId, workspaceId: input.workspaceId },
|
|
105
|
+
async (tx) =>
|
|
106
|
+
await rawRows<TaskNoteRow>(
|
|
107
|
+
tx,
|
|
108
|
+
sql`SELECT * FROM create_task_note_for_attempt(
|
|
109
|
+
${input.accountId}::uuid,
|
|
110
|
+
${input.workspaceId}::uuid,
|
|
111
|
+
${input.sessionId}::uuid,
|
|
112
|
+
${input.turnId}::uuid,
|
|
113
|
+
${input.attemptId}::uuid,
|
|
114
|
+
${input.executionGeneration}::integer,
|
|
115
|
+
${input.operationId}::uuid,
|
|
116
|
+
${input.kind}::text,
|
|
117
|
+
${input.text}::text,
|
|
118
|
+
${input.expiresInDays}::integer
|
|
119
|
+
)`,
|
|
120
|
+
),
|
|
121
|
+
);
|
|
122
|
+
if (rows.length !== 1) throw new Error("Task note create returned no durable receipt");
|
|
123
|
+
return TaskNoteMutationResult.parse({ note: noteFromRow(rows[0]!), replayed: rows[0]!.replayed });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export async function archiveTaskNote(db: Database, input: ArchiveTaskNoteInput) {
|
|
127
|
+
assertAttemptClaims(input);
|
|
128
|
+
TaskNoteReason.parse(input.reason);
|
|
129
|
+
const rows = await withRlsContext(
|
|
130
|
+
db,
|
|
131
|
+
{ accountId: input.accountId, workspaceId: input.workspaceId },
|
|
132
|
+
async (tx) =>
|
|
133
|
+
await rawRows<TaskNoteRow>(
|
|
134
|
+
tx,
|
|
135
|
+
sql`SELECT * FROM archive_task_note_for_attempt(
|
|
136
|
+
${input.accountId}::uuid,
|
|
137
|
+
${input.workspaceId}::uuid,
|
|
138
|
+
${input.sessionId}::uuid,
|
|
139
|
+
${input.turnId}::uuid,
|
|
140
|
+
${input.attemptId}::uuid,
|
|
141
|
+
${input.executionGeneration}::integer,
|
|
142
|
+
${input.operationId}::uuid,
|
|
143
|
+
${input.noteId}::uuid,
|
|
144
|
+
${input.expectedVersion}::integer,
|
|
145
|
+
${input.reason}::text
|
|
146
|
+
)`,
|
|
147
|
+
),
|
|
148
|
+
);
|
|
149
|
+
if (rows.length !== 1) throw new Error("Task note archive returned no durable receipt");
|
|
150
|
+
return TaskNoteMutationResult.parse({ note: noteFromRow(rows[0]!), replayed: rows[0]!.replayed });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export async function listTaskNotes(db: Database, input: ListTaskNotesInput) {
|
|
154
|
+
assertAttemptClaims(input);
|
|
155
|
+
const limit = input.limit ?? TASK_NOTE_LIST_DEFAULT_LIMIT;
|
|
156
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > TASK_NOTE_LIST_MAX_LIMIT) {
|
|
157
|
+
throw new Error(`Task note list limit must be 1-${TASK_NOTE_LIST_MAX_LIMIT}`);
|
|
158
|
+
}
|
|
159
|
+
const rows = await withRlsContext(
|
|
160
|
+
db,
|
|
161
|
+
{ accountId: input.accountId, workspaceId: input.workspaceId },
|
|
162
|
+
async (tx) =>
|
|
163
|
+
await rawRows<TaskNoteRow>(
|
|
164
|
+
tx,
|
|
165
|
+
sql`SELECT * FROM list_task_notes_for_attempt(
|
|
166
|
+
${input.accountId}::uuid,
|
|
167
|
+
${input.workspaceId}::uuid,
|
|
168
|
+
${input.sessionId}::uuid,
|
|
169
|
+
${input.turnId}::uuid,
|
|
170
|
+
${input.attemptId}::uuid,
|
|
171
|
+
${input.executionGeneration}::integer,
|
|
172
|
+
${input.includeArchived ?? false}::boolean,
|
|
173
|
+
${limit}::integer
|
|
174
|
+
)`,
|
|
175
|
+
),
|
|
176
|
+
);
|
|
177
|
+
return TaskNoteListResponse.parse({ notes: rows.map(noteFromRow) });
|
|
178
|
+
}
|
package/src/video-generation.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GENERATED_VIDEO_MAX_BYTES,
|
|
3
3
|
GeneratedVideoReceipt,
|
|
4
|
+
GROK_IMAGINE_VIDEO_1_5_MODEL_ID,
|
|
4
5
|
SEEDANCE_2_5_MODEL_ID,
|
|
5
6
|
VideoGenerationPolicy,
|
|
6
7
|
VideoGenerationOperationSummary,
|
|
@@ -236,8 +237,13 @@ export async function admitVideoGenerationOperation(
|
|
|
236
237
|
}
|
|
237
238
|
await tx
|
|
238
239
|
.insert(schema.workspaceVideoGenerationQuotas)
|
|
239
|
-
.values({
|
|
240
|
-
|
|
240
|
+
.values({
|
|
241
|
+
workspaceId: input.workspaceId,
|
|
242
|
+
accountId: input.accountId,
|
|
243
|
+
})
|
|
244
|
+
.onConflictDoNothing({
|
|
245
|
+
target: schema.workspaceVideoGenerationQuotas.workspaceId,
|
|
246
|
+
});
|
|
241
247
|
const [quota] = await tx
|
|
242
248
|
.select()
|
|
243
249
|
.from(schema.workspaceVideoGenerationQuotas)
|
|
@@ -311,6 +317,44 @@ export async function admitVideoGenerationOperation(
|
|
|
311
317
|
);
|
|
312
318
|
}
|
|
313
319
|
|
|
320
|
+
/** Persist a rotated provider token before it is used for another remote call. */
|
|
321
|
+
export async function rotateVideoGenerationCredential(
|
|
322
|
+
db: Database,
|
|
323
|
+
input: {
|
|
324
|
+
accountId: string;
|
|
325
|
+
workspaceId: string;
|
|
326
|
+
operationId: string;
|
|
327
|
+
requestDigest: string;
|
|
328
|
+
expectedCredentialEncrypted: string;
|
|
329
|
+
credentialEncrypted: string;
|
|
330
|
+
},
|
|
331
|
+
): Promise<VideoGenerationOperation> {
|
|
332
|
+
const [row] = await db
|
|
333
|
+
.update(schema.videoGenerationOperations)
|
|
334
|
+
.set({
|
|
335
|
+
credentialEncrypted: input.credentialEncrypted,
|
|
336
|
+
updatedAt: new Date(),
|
|
337
|
+
})
|
|
338
|
+
.where(
|
|
339
|
+
and(
|
|
340
|
+
eq(schema.videoGenerationOperations.accountId, input.accountId),
|
|
341
|
+
eq(schema.videoGenerationOperations.workspaceId, input.workspaceId),
|
|
342
|
+
eq(schema.videoGenerationOperations.id, input.operationId),
|
|
343
|
+
eq(schema.videoGenerationOperations.requestDigest, input.requestDigest),
|
|
344
|
+
eq(schema.videoGenerationOperations.credentialEncrypted, input.expectedCredentialEncrypted),
|
|
345
|
+
inArray(schema.videoGenerationOperations.status, [
|
|
346
|
+
"accepted",
|
|
347
|
+
"submission_uncertain",
|
|
348
|
+
"provider_started",
|
|
349
|
+
"retaining",
|
|
350
|
+
]),
|
|
351
|
+
),
|
|
352
|
+
)
|
|
353
|
+
.returning();
|
|
354
|
+
if (!row) throw new VideoGenerationConflictError("Video provider credential changed");
|
|
355
|
+
return row;
|
|
356
|
+
}
|
|
357
|
+
|
|
314
358
|
/**
|
|
315
359
|
* Seal a reference-bearing operation only after every immutable staging object
|
|
316
360
|
* has been uploaded and independently verified by the worker. The source
|
|
@@ -422,11 +466,17 @@ export async function markVideoGenerationAcceptedInTransaction(
|
|
|
422
466
|
operation.connectionId === null &&
|
|
423
467
|
(operation.creditState === "debited" ||
|
|
424
468
|
(operation.creditState === "not_applicable" && operation.pricedCostMicros === 0));
|
|
469
|
+
const supergrokAuthorized =
|
|
470
|
+
operation.fundingSource === "supergrok_subscription" &&
|
|
471
|
+
operation.connectionId === null &&
|
|
472
|
+
operation.credentialEncrypted !== null &&
|
|
473
|
+
operation.pricedCostMicros === 0 &&
|
|
474
|
+
operation.creditState === "not_applicable";
|
|
425
475
|
if (
|
|
426
476
|
!policy ||
|
|
427
477
|
policy.fundingSource !== operation.fundingSource ||
|
|
428
478
|
!policy.enabledModelIds.includes(operation.modelId) ||
|
|
429
|
-
(!workspaceGatewayAuthorized && !managedAuthorized)
|
|
479
|
+
(!workspaceGatewayAuthorized && !managedAuthorized && !supergrokAuthorized)
|
|
430
480
|
) {
|
|
431
481
|
throw new VideoGenerationConflictError("Video generation authorization changed");
|
|
432
482
|
}
|
|
@@ -684,7 +734,10 @@ export async function markVideoGenerationSubmissionIntent(
|
|
|
684
734
|
|
|
685
735
|
export async function markVideoGenerationProviderStarted(
|
|
686
736
|
db: Database,
|
|
687
|
-
input: OperationMutationInput & {
|
|
737
|
+
input: OperationMutationInput & {
|
|
738
|
+
providerJobId: string;
|
|
739
|
+
nextReconcileAt: Date;
|
|
740
|
+
},
|
|
688
741
|
): Promise<VideoGenerationOperation> {
|
|
689
742
|
return await mutateOperation(db, input, async (tx, operation) => {
|
|
690
743
|
if (
|
|
@@ -720,7 +773,11 @@ export async function markVideoGenerationProviderStarted(
|
|
|
720
773
|
|
|
721
774
|
export async function rescheduleVideoGenerationOperation(
|
|
722
775
|
db: Database,
|
|
723
|
-
input: OperationMutationInput & {
|
|
776
|
+
input: OperationMutationInput & {
|
|
777
|
+
owner?: string;
|
|
778
|
+
nextReconcileAt: Date;
|
|
779
|
+
error?: string;
|
|
780
|
+
},
|
|
724
781
|
): Promise<boolean> {
|
|
725
782
|
return await withRlsContext(
|
|
726
783
|
db,
|
|
@@ -832,7 +889,10 @@ export type SettleVideoGenerationReadyInput = OperationMutationInput & {
|
|
|
832
889
|
export async function settleVideoGenerationReady(
|
|
833
890
|
db: Database,
|
|
834
891
|
input: SettleVideoGenerationReadyInput,
|
|
835
|
-
): Promise<{
|
|
892
|
+
): Promise<{
|
|
893
|
+
operation: VideoGenerationOperation;
|
|
894
|
+
artifact: GeneratedVideoArtifact;
|
|
895
|
+
}> {
|
|
836
896
|
return await withRlsContext(
|
|
837
897
|
db,
|
|
838
898
|
{ accountId: input.accountId, workspaceId: input.workspaceId },
|
|
@@ -931,6 +991,8 @@ export async function settleVideoGenerationReady(
|
|
|
931
991
|
providerRequestExpiresAt: null,
|
|
932
992
|
credentialEncrypted: null,
|
|
933
993
|
requestEncrypted: null,
|
|
994
|
+
boundedPublicReason: null,
|
|
995
|
+
lastError: null,
|
|
934
996
|
privateDataEraseAfter: now,
|
|
935
997
|
reconcileLeaseOwner: null,
|
|
936
998
|
reconcileLeaseExpiresAt: null,
|
|
@@ -950,7 +1012,10 @@ export async function getGeneratedVideoArtifact(
|
|
|
950
1012
|
db: Database,
|
|
951
1013
|
workspaceId: string,
|
|
952
1014
|
artifactId: string,
|
|
953
|
-
): Promise<{
|
|
1015
|
+
): Promise<{
|
|
1016
|
+
artifact: GeneratedVideoArtifact;
|
|
1017
|
+
file: typeof schema.files.$inferSelect;
|
|
1018
|
+
} | null> {
|
|
954
1019
|
return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {
|
|
955
1020
|
const [row] = await scopedDb
|
|
956
1021
|
.select({ artifact: schema.generatedVideoArtifacts, file: schema.files })
|
|
@@ -971,13 +1036,21 @@ export async function listSessionGeneratedVideoArtifacts(
|
|
|
971
1036
|
db: Database,
|
|
972
1037
|
workspaceId: string,
|
|
973
1038
|
sessionId: string,
|
|
974
|
-
): Promise<
|
|
1039
|
+
): Promise<
|
|
1040
|
+
Array<{
|
|
1041
|
+
artifact: GeneratedVideoArtifact;
|
|
1042
|
+
file: typeof schema.files.$inferSelect;
|
|
1043
|
+
}>
|
|
1044
|
+
> {
|
|
975
1045
|
return await withWorkspaceRls(
|
|
976
1046
|
db,
|
|
977
1047
|
workspaceId,
|
|
978
1048
|
async (scopedDb) =>
|
|
979
1049
|
await scopedDb
|
|
980
|
-
.select({
|
|
1050
|
+
.select({
|
|
1051
|
+
artifact: schema.generatedVideoArtifacts,
|
|
1052
|
+
file: schema.files,
|
|
1053
|
+
})
|
|
981
1054
|
.from(schema.generatedVideoArtifacts)
|
|
982
1055
|
.innerJoin(schema.files, eq(schema.files.id, schema.generatedVideoArtifacts.primaryFileId))
|
|
983
1056
|
.where(
|
|
@@ -1026,7 +1099,9 @@ export async function markVideoGenerationReferenceCleaned(
|
|
|
1026
1099
|
eq(schema.videoGenerationReferences.stagingObjectKey, input.stagingObjectKey),
|
|
1027
1100
|
),
|
|
1028
1101
|
)
|
|
1029
|
-
.returning({
|
|
1102
|
+
.returning({
|
|
1103
|
+
operationId: schema.videoGenerationReferences.operationId,
|
|
1104
|
+
});
|
|
1030
1105
|
if (updated) return true;
|
|
1031
1106
|
const [existing] = await scopedDb
|
|
1032
1107
|
.select({ cleanedAt: schema.videoGenerationReferences.cleanedAt })
|
|
@@ -1177,7 +1252,10 @@ export async function mediaGenerationResultForStoredOperation(
|
|
|
1177
1252
|
},
|
|
1178
1253
|
sandboxPath: `/workspace/generated-videos/${retained.artifact.sandboxFilename}`,
|
|
1179
1254
|
});
|
|
1180
|
-
return mediaGenerationResultForOperation({
|
|
1255
|
+
return mediaGenerationResultForOperation({
|
|
1256
|
+
operation,
|
|
1257
|
+
readyReceipt: receipt,
|
|
1258
|
+
});
|
|
1181
1259
|
}
|
|
1182
1260
|
|
|
1183
1261
|
export async function getVideoGenerationOperationSummary(
|
|
@@ -1399,7 +1477,7 @@ function policyFromRow(
|
|
|
1399
1477
|
|
|
1400
1478
|
function assertSupportedModels(modelIds: readonly string[]): void {
|
|
1401
1479
|
for (const modelId of modelIds) {
|
|
1402
|
-
if (modelId !== SEEDANCE_2_5_MODEL_ID) {
|
|
1480
|
+
if (modelId !== SEEDANCE_2_5_MODEL_ID && modelId !== GROK_IMAGINE_VIDEO_1_5_MODEL_ID) {
|
|
1403
1481
|
throw new Error(`Unknown video generation model: ${modelId}`);
|
|
1404
1482
|
}
|
|
1405
1483
|
}
|
|
@@ -320,7 +320,7 @@ async function assertAttemptAuthority(
|
|
|
320
320
|
session.first_party_mcp_permissions IS NULL
|
|
321
321
|
OR session.first_party_mcp_permissions @> '["artifacts:publish"]'::jsonb
|
|
322
322
|
)
|
|
323
|
-
FOR UPDATE OF session
|
|
323
|
+
FOR NO KEY UPDATE OF session
|
|
324
324
|
), locked_turn AS MATERIALIZED (
|
|
325
325
|
SELECT turn.id, turn.account_id, turn.workspace_id, turn.session_id,
|
|
326
326
|
turn.active_attempt_id, turn.execution_generation, turn.initiator_subject_id
|