@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
@@ -0,0 +1,85 @@
1
+ -- deployment-mode: rolling
2
+ -- Add a database-assigned completion order for successful document indexing.
3
+ -- A trigger stamps both current and old application writers only when status
4
+ -- transitions to ready, so metadata refreshes and base moves cannot advance an
5
+ -- agent's review checkpoint.
6
+
7
+ SET LOCAL lock_timeout = '5s';
8
+ SET LOCAL statement_timeout = '10min';
9
+
10
+ ALTER TABLE "documents" ADD COLUMN "index_sequence" bigint;
11
+ ALTER TABLE "documents" ADD COLUMN "indexed_at" timestamptz;
12
+
13
+ CREATE SEQUENCE "document_index_completion_seq" AS bigint;
14
+
15
+ WITH ranked AS (
16
+ SELECT
17
+ id,
18
+ row_number() OVER (ORDER BY updated_at, id)::bigint AS index_sequence
19
+ FROM documents
20
+ WHERE status = 'ready'
21
+ )
22
+ UPDATE documents document
23
+ SET
24
+ index_sequence = ranked.index_sequence,
25
+ indexed_at = document.updated_at
26
+ FROM ranked
27
+ WHERE document.id = ranked.id;
28
+
29
+ SELECT setval(
30
+ 'document_index_completion_seq',
31
+ greatest(coalesce((SELECT max(index_sequence) + 1 FROM documents), 1), 1),
32
+ false
33
+ );
34
+
35
+ CREATE OR REPLACE FUNCTION opengeni_private.stamp_document_index_completion()
36
+ RETURNS trigger
37
+ LANGUAGE plpgsql
38
+ SECURITY DEFINER
39
+ SET search_path = pg_catalog, public
40
+ AS $$
41
+ BEGIN
42
+ IF TG_OP = 'INSERT' THEN
43
+ IF NEW.status = 'ready' THEN
44
+ NEW.index_sequence := nextval('document_index_completion_seq');
45
+ NEW.indexed_at := clock_timestamp();
46
+ ELSE
47
+ NEW.index_sequence := NULL;
48
+ NEW.indexed_at := NULL;
49
+ END IF;
50
+ RETURN NEW;
51
+ END IF;
52
+
53
+ IF NEW.status = 'ready' AND OLD.status IS DISTINCT FROM 'ready' THEN
54
+ NEW.index_sequence := nextval('document_index_completion_seq');
55
+ NEW.indexed_at := clock_timestamp();
56
+ ELSE
57
+ NEW.index_sequence := OLD.index_sequence;
58
+ NEW.indexed_at := OLD.indexed_at;
59
+ END IF;
60
+ RETURN NEW;
61
+ END;
62
+ $$;
63
+
64
+ REVOKE ALL ON FUNCTION opengeni_private.stamp_document_index_completion() FROM PUBLIC;
65
+
66
+ CREATE TRIGGER documents_index_completion_stamp
67
+ BEFORE INSERT OR UPDATE ON documents
68
+ FOR EACH ROW EXECUTE FUNCTION opengeni_private.stamp_document_index_completion();
69
+
70
+ ALTER TABLE documents ADD CONSTRAINT documents_index_sequence_chk CHECK (
71
+ (index_sequence IS NULL OR index_sequence > 0)
72
+ AND (
73
+ status <> 'ready'
74
+ OR (index_sequence IS NOT NULL AND indexed_at IS NOT NULL)
75
+ )
76
+ );
77
+
78
+ CREATE INDEX documents_account_index_sequence_idx
79
+ ON documents (account_id, index_sequence)
80
+ WHERE status = 'ready' AND index_sequence IS NOT NULL;
81
+
82
+ COMMENT ON COLUMN documents.index_sequence IS
83
+ 'Database-assigned order of the latest successful transition to ready; immutable until the next successful reindex.';
84
+ COMMENT ON COLUMN documents.indexed_at IS
85
+ 'Database timestamp of the latest successful transition to ready.';
@@ -0,0 +1,353 @@
1
+ -- deployment-mode: rolling
2
+ -- Durable workspace-owned video generation. A paid provider operation is
3
+ -- independent from its originating turn/session; its retained product owns a
4
+ -- separate File and permanent video-artifact identity.
5
+
6
+ SET LOCAL lock_timeout = '5s';
7
+ SET LOCAL statement_timeout = '10min';
8
+
9
+ ALTER TABLE "session_system_updates" DROP CONSTRAINT "system_updates_kind_check";
10
+ ALTER TABLE "session_system_updates" ADD CONSTRAINT "system_updates_kind_check" CHECK (
11
+ "kind" IN (
12
+ 'scheduled_occurrence', 'goal_continuation', 'agent_message',
13
+ 'agent_steer_instruction', 'child_terminal_result', 'media_generation_result'
14
+ )
15
+ );
16
+
17
+ CREATE TABLE "workspace_video_generation_policies" (
18
+ "workspace_id" uuid PRIMARY KEY REFERENCES "workspaces"("id") ON DELETE CASCADE,
19
+ "account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
20
+ "revision" bigint NOT NULL DEFAULT 0,
21
+ "enabled_model_ids" jsonb NOT NULL DEFAULT '[]'::jsonb,
22
+ "default_model_id" text,
23
+ "updated_by_subject_id" text,
24
+ "created_at" timestamptz NOT NULL DEFAULT now(),
25
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
26
+ CONSTRAINT "workspace_video_generation_policies_workspace_account_fk"
27
+ FOREIGN KEY ("workspace_id", "account_id")
28
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
29
+ CONSTRAINT "workspace_video_generation_policies_revision_chk"
30
+ CHECK ("revision" BETWEEN 0 AND 9007199254740991),
31
+ CONSTRAINT "workspace_video_generation_policies_models_chk" CHECK (
32
+ jsonb_typeof("enabled_model_ids") = 'array'
33
+ AND jsonb_array_length("enabled_model_ids") <= 16
34
+ AND ("default_model_id" IS NULL OR "enabled_model_ids" ? "default_model_id")
35
+ )
36
+ );
37
+
38
+ CREATE TABLE "workspace_video_generation_quotas" (
39
+ "workspace_id" uuid PRIMARY KEY REFERENCES "workspaces"("id") ON DELETE CASCADE,
40
+ "account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
41
+ "reserved_bytes" bigint NOT NULL DEFAULT 0,
42
+ "ready_bytes" bigint NOT NULL DEFAULT 0,
43
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
44
+ CONSTRAINT "workspace_video_generation_quotas_workspace_account_fk"
45
+ FOREIGN KEY ("workspace_id", "account_id")
46
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
47
+ CONSTRAINT "workspace_video_generation_quotas_nonnegative_chk"
48
+ CHECK ("reserved_bytes" >= 0 AND "ready_bytes" >= 0)
49
+ );
50
+
51
+ CREATE TABLE "video_generation_operations" (
52
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
53
+ "account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
54
+ "workspace_id" uuid NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
55
+ "session_id" uuid,
56
+ "turn_id" uuid,
57
+ "attempt_id" uuid,
58
+ "tool_call_id" text NOT NULL,
59
+ "admission_key" text NOT NULL,
60
+ "request_digest" text NOT NULL,
61
+ "prompt_digest" text NOT NULL,
62
+ "request_encrypted" text,
63
+ "model_id" text NOT NULL,
64
+ "source_mode" text NOT NULL,
65
+ "capability_revision" text NOT NULL,
66
+ "connection_id" uuid,
67
+ "credential_version" integer NOT NULL,
68
+ "credential_encrypted" text,
69
+ "provider_idempotency_key" text NOT NULL,
70
+ "provider_job_id" text,
71
+ "provider_request_encrypted" text,
72
+ "provider_request_expires_at" timestamptz,
73
+ "expected_artifact_id" uuid NOT NULL,
74
+ "expected_file_id" uuid NOT NULL,
75
+ "reserved_bytes" bigint NOT NULL,
76
+ "quota_state" text NOT NULL DEFAULT 'reserved',
77
+ "status" text NOT NULL DEFAULT 'preparing',
78
+ "admission_output_state" text NOT NULL DEFAULT 'pending',
79
+ "terminal_update_state" text NOT NULL DEFAULT 'ineligible',
80
+ "terminal_update_id" uuid,
81
+ "reconcile_revision" bigint NOT NULL DEFAULT 0,
82
+ "reconcile_lease_owner" text,
83
+ "reconcile_lease_expires_at" timestamptz,
84
+ "next_reconcile_at" timestamptz,
85
+ "provider_request_sent_at" timestamptz,
86
+ "provider_started_at" timestamptz,
87
+ "recovery_deadline_at" timestamptz NOT NULL,
88
+ "terminal_at" timestamptz,
89
+ "private_data_erase_after" timestamptz,
90
+ "bounded_public_reason" text,
91
+ "last_error" text,
92
+ "created_at" timestamptz NOT NULL DEFAULT now(),
93
+ "updated_at" timestamptz NOT NULL DEFAULT now(),
94
+ CONSTRAINT "video_generation_operations_workspace_account_fk"
95
+ FOREIGN KEY ("workspace_id", "account_id")
96
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
97
+ CONSTRAINT "video_generation_operations_workspace_session_fk"
98
+ FOREIGN KEY ("workspace_id", "session_id")
99
+ REFERENCES "sessions"("workspace_id", "id") ON DELETE SET NULL ("session_id"),
100
+ CONSTRAINT "video_generation_operations_workspace_turn_fk"
101
+ FOREIGN KEY ("workspace_id", "turn_id")
102
+ REFERENCES "session_turns"("workspace_id", "id") ON DELETE SET NULL ("turn_id"),
103
+ CONSTRAINT "video_generation_operations_workspace_attempt_fk"
104
+ FOREIGN KEY ("workspace_id", "attempt_id")
105
+ REFERENCES "session_turn_attempts"("workspace_id", "id") ON DELETE SET NULL ("attempt_id"),
106
+ CONSTRAINT "video_generation_operations_hashes_chk" CHECK (
107
+ "admission_key" ~ '^[0-9a-f]{64}$'
108
+ AND "request_digest" ~ '^[0-9a-f]{64}$'
109
+ AND "prompt_digest" ~ '^[0-9a-f]{64}$'
110
+ AND "capability_revision" ~ '^[0-9a-f]{64}$'
111
+ ),
112
+ CONSTRAINT "video_generation_operations_shape_chk" CHECK (
113
+ octet_length("tool_call_id") BETWEEN 1 AND 512
114
+ AND octet_length("model_id") BETWEEN 1 AND 256
115
+ AND octet_length("provider_idempotency_key") BETWEEN 1 AND 128
116
+ AND "source_mode" IN ('text','first_frame','first_and_last_frames','image_reference','video_reference')
117
+ AND "reserved_bytes" > 0 AND "reserved_bytes" <= 536870912
118
+ AND ("bounded_public_reason" IS NULL OR octet_length("bounded_public_reason") <= 4000)
119
+ AND ("last_error" IS NULL OR octet_length("last_error") <= 16384)
120
+ ),
121
+ CONSTRAINT "video_generation_operations_state_chk" CHECK (
122
+ "status" IN (
123
+ 'preparing','prepared','accepted','submission_uncertain','provider_started',
124
+ 'retaining','completed','provider_failed','cancelled_before_submit',
125
+ 'outcome_unknown','retention_failed'
126
+ )
127
+ AND "admission_output_state" IN ('pending','recorded')
128
+ AND "terminal_update_state" IN ('ineligible','pending','leased','delivered','suppressed')
129
+ AND "quota_state" IN ('reserved','ready','released')
130
+ AND (("terminal_at" IS NOT NULL) = ("status" IN (
131
+ 'completed','provider_failed','cancelled_before_submit','outcome_unknown','retention_failed'
132
+ )))
133
+ AND ("status" <> 'submission_uncertain' OR (
134
+ "provider_request_encrypted" IS NOT NULL AND "provider_request_expires_at" IS NOT NULL
135
+ ))
136
+ AND ("provider_request_encrypted" IS NULL OR "status" = 'submission_uncertain')
137
+ AND ("status" NOT IN ('provider_started','retaining','completed','retention_failed')
138
+ OR "provider_job_id" IS NOT NULL)
139
+ AND ("provider_job_id" IS NULL OR "status" IN (
140
+ 'provider_started','retaining','completed','provider_failed','retention_failed'
141
+ ))
142
+ )
143
+ );
144
+
145
+ CREATE UNIQUE INDEX "video_generation_operations_admission_uq"
146
+ ON "video_generation_operations" ("workspace_id", "admission_key");
147
+ CREATE UNIQUE INDEX "video_generation_operations_expected_artifact_uq"
148
+ ON "video_generation_operations" ("workspace_id", "expected_artifact_id");
149
+ CREATE UNIQUE INDEX "video_generation_operations_expected_file_uq"
150
+ ON "video_generation_operations" ("workspace_id", "expected_file_id");
151
+ CREATE INDEX "video_generation_operations_due_idx"
152
+ ON "video_generation_operations" ("status", "next_reconcile_at", "id");
153
+ CREATE INDEX "video_generation_operations_workspace_created_idx"
154
+ ON "video_generation_operations" ("workspace_id", "created_at", "id");
155
+
156
+ CREATE TABLE "video_generation_references" (
157
+ "operation_id" uuid NOT NULL REFERENCES "video_generation_operations"("id") ON DELETE CASCADE,
158
+ "workspace_id" uuid NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
159
+ "account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
160
+ "ordinal" integer NOT NULL,
161
+ "role" text NOT NULL,
162
+ "content_type" text NOT NULL,
163
+ "size_bytes" bigint NOT NULL,
164
+ "sha256" text NOT NULL,
165
+ "staging_object_key" text,
166
+ "grant_expires_at" timestamptz,
167
+ "cleanup_after" timestamptz,
168
+ "cleaned_at" timestamptz,
169
+ "created_at" timestamptz NOT NULL DEFAULT now(),
170
+ CONSTRAINT "video_generation_references_pk" PRIMARY KEY ("operation_id", "ordinal"),
171
+ CONSTRAINT "video_generation_references_workspace_account_fk"
172
+ FOREIGN KEY ("workspace_id", "account_id")
173
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
174
+ CONSTRAINT "video_generation_references_hash_chk" CHECK ("sha256" ~ '^[0-9a-f]{64}$'),
175
+ CONSTRAINT "video_generation_references_bounds_chk" CHECK (
176
+ "ordinal" BETWEEN 0 AND 1
177
+ AND "role" IN ('first_frame','last_frame','image_reference','video_reference')
178
+ AND octet_length("content_type") BETWEEN 3 AND 128
179
+ AND "size_bytes" > 0 AND "size_bytes" <= 209715200
180
+ )
181
+ );
182
+
183
+ CREATE TABLE "generated_video_artifacts" (
184
+ "id" uuid PRIMARY KEY,
185
+ "account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
186
+ "workspace_id" uuid NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
187
+ "primary_file_id" uuid NOT NULL REFERENCES "files"("id") ON DELETE RESTRICT,
188
+ "operation_id" uuid NOT NULL REFERENCES "video_generation_operations"("id") ON DELETE RESTRICT,
189
+ "session_id" uuid,
190
+ "turn_id" uuid,
191
+ "attempt_id" uuid,
192
+ "model_id" text NOT NULL,
193
+ "source_mode" text NOT NULL,
194
+ "prompt_digest" text NOT NULL,
195
+ "content_type" text NOT NULL,
196
+ "size_bytes" bigint NOT NULL,
197
+ "sha256" text NOT NULL,
198
+ "duration_millis" integer NOT NULL,
199
+ "width" integer NOT NULL,
200
+ "height" integer NOT NULL,
201
+ "fps_milli" integer NOT NULL,
202
+ "video_codec" text NOT NULL,
203
+ "audio_codec" text,
204
+ "has_audio" boolean NOT NULL,
205
+ "sandbox_filename" text NOT NULL,
206
+ "deleted_at" timestamptz,
207
+ "ready_at" timestamptz NOT NULL DEFAULT now(),
208
+ "created_at" timestamptz NOT NULL DEFAULT now(),
209
+ CONSTRAINT "generated_video_artifacts_workspace_account_fk"
210
+ FOREIGN KEY ("workspace_id", "account_id")
211
+ REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE,
212
+ CONSTRAINT "generated_video_artifacts_workspace_file_scope_fk"
213
+ FOREIGN KEY ("account_id", "workspace_id", "primary_file_id")
214
+ REFERENCES "files"("account_id", "workspace_id", "id") ON DELETE RESTRICT,
215
+ CONSTRAINT "generated_video_artifacts_workspace_session_fk"
216
+ FOREIGN KEY ("workspace_id", "session_id")
217
+ REFERENCES "sessions"("workspace_id", "id") ON DELETE SET NULL ("session_id"),
218
+ CONSTRAINT "generated_video_artifacts_workspace_turn_fk"
219
+ FOREIGN KEY ("workspace_id", "turn_id")
220
+ REFERENCES "session_turns"("workspace_id", "id") ON DELETE SET NULL ("turn_id"),
221
+ CONSTRAINT "generated_video_artifacts_workspace_attempt_fk"
222
+ FOREIGN KEY ("workspace_id", "attempt_id")
223
+ REFERENCES "session_turn_attempts"("workspace_id", "id") ON DELETE SET NULL ("attempt_id"),
224
+ CONSTRAINT "generated_video_artifacts_values_chk" CHECK (
225
+ "content_type" = 'video/mp4'
226
+ AND "size_bytes" > 0 AND "size_bytes" <= 536870912
227
+ AND "sha256" ~ '^[0-9a-f]{64}$'
228
+ AND "prompt_digest" ~ '^[0-9a-f]{64}$'
229
+ AND "duration_millis" BETWEEN 1 AND 120000
230
+ AND "width" BETWEEN 1 AND 8192 AND "height" BETWEEN 1 AND 8192
231
+ AND "fps_milli" BETWEEN 1 AND 120000
232
+ AND "video_codec" = 'h264'
233
+ AND (("has_audio" AND "audio_codec" = 'aac') OR (NOT "has_audio" AND "audio_codec" IS NULL))
234
+ AND "sandbox_filename" = 'generated-video-' || "id"::text || '.mp4'
235
+ )
236
+ );
237
+
238
+ CREATE UNIQUE INDEX "generated_video_artifacts_workspace_file_uq"
239
+ ON "generated_video_artifacts" ("workspace_id", "primary_file_id");
240
+ CREATE UNIQUE INDEX "generated_video_artifacts_workspace_operation_uq"
241
+ ON "generated_video_artifacts" ("workspace_id", "operation_id");
242
+ CREATE INDEX "generated_video_artifacts_session_created_idx"
243
+ ON "generated_video_artifacts" ("workspace_id", "session_id", "created_at", "id");
244
+
245
+ CREATE OR REPLACE FUNCTION opengeni_private.claim_video_generation_operations(
246
+ p_owner text,
247
+ p_lease_seconds integer,
248
+ p_limit integer
249
+ ) RETURNS TABLE(operation_id uuid, account_id uuid, workspace_id uuid)
250
+ LANGUAGE plpgsql
251
+ SECURITY DEFINER
252
+ SET search_path = pg_catalog, public, opengeni_private
253
+ AS $$
254
+ BEGIN
255
+ IF p_owner IS NULL OR length(btrim(p_owner)) NOT BETWEEN 1 AND 256
256
+ OR p_lease_seconds NOT BETWEEN 5 AND 600
257
+ OR p_limit NOT BETWEEN 1 AND 100
258
+ THEN
259
+ RAISE EXCEPTION 'invalid video generation claim request';
260
+ END IF;
261
+ RETURN QUERY
262
+ WITH candidates AS (
263
+ SELECT operation.id
264
+ FROM public.video_generation_operations AS operation
265
+ WHERE (
266
+ (
267
+ operation.status IN ('accepted','submission_uncertain','provider_started','retaining')
268
+ AND coalesce(operation.next_reconcile_at, operation.updated_at) <= clock_timestamp()
269
+ )
270
+ OR (
271
+ operation.status IN (
272
+ 'completed','provider_failed','cancelled_before_submit','outcome_unknown','retention_failed'
273
+ )
274
+ AND (
275
+ operation.terminal_update_state IN ('pending','leased')
276
+ OR EXISTS (
277
+ SELECT 1
278
+ FROM public.video_generation_references AS reference
279
+ WHERE reference.operation_id = operation.id
280
+ AND reference.staging_object_key IS NOT NULL
281
+ AND reference.cleaned_at IS NULL
282
+ AND coalesce(reference.cleanup_after, operation.recovery_deadline_at)
283
+ <= clock_timestamp()
284
+ )
285
+ )
286
+ )
287
+ )
288
+ AND (
289
+ operation.reconcile_lease_expires_at IS NULL
290
+ OR operation.reconcile_lease_expires_at <= clock_timestamp()
291
+ )
292
+ ORDER BY coalesce(operation.next_reconcile_at, operation.updated_at), operation.id
293
+ FOR UPDATE SKIP LOCKED
294
+ LIMIT p_limit
295
+ ), claimed AS (
296
+ UPDATE public.video_generation_operations AS operation
297
+ SET reconcile_lease_owner = p_owner,
298
+ reconcile_lease_expires_at = clock_timestamp() + make_interval(secs => p_lease_seconds),
299
+ reconcile_revision = operation.reconcile_revision + 1,
300
+ updated_at = clock_timestamp()
301
+ FROM candidates
302
+ WHERE operation.id = candidates.id
303
+ RETURNING operation.id, operation.account_id, operation.workspace_id
304
+ )
305
+ SELECT claimed.id, claimed.account_id, claimed.workspace_id FROM claimed;
306
+ END;
307
+ $$;
308
+
309
+ REVOKE ALL ON FUNCTION opengeni_private.claim_video_generation_operations(text, integer, integer)
310
+ FROM PUBLIC;
311
+
312
+ ALTER TABLE "workspace_video_generation_policies" ENABLE ROW LEVEL SECURITY;
313
+ ALTER TABLE "workspace_video_generation_policies" FORCE ROW LEVEL SECURITY;
314
+ CREATE POLICY "workspace_isolation" ON "workspace_video_generation_policies"
315
+ USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
316
+ WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
317
+
318
+ ALTER TABLE "workspace_video_generation_quotas" ENABLE ROW LEVEL SECURITY;
319
+ ALTER TABLE "workspace_video_generation_quotas" FORCE ROW LEVEL SECURITY;
320
+ CREATE POLICY "workspace_isolation" ON "workspace_video_generation_quotas"
321
+ USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
322
+ WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
323
+
324
+ ALTER TABLE "video_generation_operations" ENABLE ROW LEVEL SECURITY;
325
+ ALTER TABLE "video_generation_operations" FORCE ROW LEVEL SECURITY;
326
+ CREATE POLICY "workspace_isolation" ON "video_generation_operations"
327
+ USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
328
+ WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
329
+
330
+ ALTER TABLE "video_generation_references" ENABLE ROW LEVEL SECURITY;
331
+ ALTER TABLE "video_generation_references" FORCE ROW LEVEL SECURITY;
332
+ CREATE POLICY "workspace_isolation" ON "video_generation_references"
333
+ USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
334
+ WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
335
+
336
+ ALTER TABLE "generated_video_artifacts" ENABLE ROW LEVEL SECURITY;
337
+ ALTER TABLE "generated_video_artifacts" FORCE ROW LEVEL SECURITY;
338
+ CREATE POLICY "workspace_isolation" ON "generated_video_artifacts"
339
+ USING (opengeni_private.workspace_rls_visible(account_id, workspace_id))
340
+ WITH CHECK (opengeni_private.workspace_rls_visible(account_id, workspace_id));
341
+
342
+ DO $$
343
+ BEGIN
344
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
345
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "workspace_video_generation_policies" TO opengeni_app;
346
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "workspace_video_generation_quotas" TO opengeni_app;
347
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "video_generation_operations" TO opengeni_app;
348
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "video_generation_references" TO opengeni_app;
349
+ GRANT SELECT, INSERT, UPDATE, DELETE ON "generated_video_artifacts" TO opengeni_app;
350
+ GRANT EXECUTE ON FUNCTION opengeni_private.claim_video_generation_operations(text, integer, integer)
351
+ TO opengeni_app;
352
+ END IF;
353
+ END $$;
@@ -0,0 +1,44 @@
1
+ -- deployment-mode: rolling
2
+ -- Add one frozen funding choice to the existing durable video operation.
3
+ -- Existing rows retain the original workspace-Gateway behavior.
4
+
5
+ SET LOCAL lock_timeout = '5s';
6
+ SET LOCAL statement_timeout = '10min';
7
+
8
+ ALTER TABLE "workspace_video_generation_policies"
9
+ ADD COLUMN "funding_source" text NOT NULL DEFAULT 'workspace_gateway';
10
+ ALTER TABLE "workspace_video_generation_policies"
11
+ ADD CONSTRAINT "workspace_video_generation_policies_funding_source_chk"
12
+ CHECK ("funding_source" IN ('opengeni_credits', 'workspace_gateway')) NOT VALID;
13
+ ALTER TABLE "workspace_video_generation_policies"
14
+ VALIDATE CONSTRAINT "workspace_video_generation_policies_funding_source_chk";
15
+
16
+ ALTER TABLE "video_generation_operations"
17
+ ADD COLUMN "funding_source" text NOT NULL DEFAULT 'workspace_gateway',
18
+ ADD COLUMN "priced_cost_micros" bigint NOT NULL DEFAULT 0,
19
+ ADD COLUMN "credit_state" text NOT NULL DEFAULT 'not_applicable';
20
+ ALTER TABLE "video_generation_operations"
21
+ ADD CONSTRAINT "video_generation_operations_funding_state_chk" CHECK (
22
+ ("funding_source" = 'workspace_gateway'
23
+ AND "connection_id" IS NOT NULL
24
+ AND "priced_cost_micros" = 0
25
+ AND "credit_state" = 'not_applicable')
26
+ OR ("funding_source" = 'opengeni_credits'
27
+ AND "connection_id" IS NULL
28
+ AND (("priced_cost_micros" = 0 AND "credit_state" = 'not_applicable')
29
+ OR ("priced_cost_micros" > 0
30
+ AND (("status" IN ('provider_failed','cancelled_before_submit','outcome_unknown','retention_failed')
31
+ AND "credit_state" = 'refunded')
32
+ OR ("status" NOT IN ('provider_failed','cancelled_before_submit','outcome_unknown','retention_failed')
33
+ AND "credit_state" = 'debited')))))
34
+ ) NOT VALID;
35
+ ALTER TABLE "video_generation_operations"
36
+ ADD CONSTRAINT "video_generation_operations_funding_values_chk" CHECK (
37
+ "funding_source" IN ('opengeni_credits', 'workspace_gateway')
38
+ AND "priced_cost_micros" BETWEEN 0 AND 1000000000
39
+ AND "credit_state" IN ('not_applicable', 'debited', 'refunded')
40
+ ) NOT VALID;
41
+ ALTER TABLE "video_generation_operations"
42
+ VALIDATE CONSTRAINT "video_generation_operations_funding_state_chk";
43
+ ALTER TABLE "video_generation_operations"
44
+ VALIDATE CONSTRAINT "video_generation_operations_funding_values_chk";