@opengeni/db 0.28.1 → 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.
- package/dist/attached-browser-devices.d.ts +42 -0
- package/dist/attempt-tool-catalogs.d.ts +16 -0
- package/dist/browser-auth.d.ts +91 -0
- package/dist/browser-identities.d.ts +128 -0
- package/dist/browser-sessions.d.ts +272 -0
- package/dist/browser-state-artifacts.d.ts +17 -0
- package/dist/capability-components.d.ts +37 -0
- package/dist/capability-integrations.d.ts +192 -0
- package/dist/chunk-F5FT7BEZ.js +3535 -0
- package/dist/chunk-F5FT7BEZ.js.map +1 -0
- package/dist/chunk-ISI2TIUG.js +639 -0
- package/dist/chunk-ISI2TIUG.js.map +1 -0
- package/dist/chunk-MWDVXQOL.js +11639 -0
- package/dist/chunk-MWDVXQOL.js.map +1 -0
- package/dist/chunk-NBE6CHRI.js +955 -0
- package/dist/chunk-NBE6CHRI.js.map +1 -0
- package/dist/{chunk-DBS5HPEW.js → chunk-YHZXQ7HP.js} +760 -11
- package/dist/chunk-YHZXQ7HP.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 +52 -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/environment-crypto.d.ts +8 -4
- package/dist/generated-images.d.ts +139 -0
- package/dist/index.d.ts +958 -126
- package/dist/index.js +31204 -12172
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +51 -4
- package/dist/integration-bindings.d.ts +70 -0
- package/dist/integration-features.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +3 -0
- package/dist/interaction-schema.d.ts +5372 -0
- package/dist/knowledge-source-sync-schema.d.ts +1679 -0
- package/dist/knowledge-source-sync.d.ts +274 -0
- package/dist/lossless-columns.d.ts +58 -0
- package/dist/lossless-json.d.ts +39 -0
- package/dist/memory-domain.d.ts +3 -6
- 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 +7 -14
- 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 +18 -6
- package/dist/schema.d.ts +19122 -8731
- package/dist/schema.js +173 -1
- package/dist/scoped-knowledge.d.ts +97 -1
- package/dist/session-control.d.ts +4 -4
- 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 +8 -1
- package/dist/session-realtime.d.ts +7 -7
- package/dist/session-tool-call-settlement.d.ts +1 -1
- package/dist/slack-user-link-access.d.ts +54 -0
- package/dist/transcription-recordings-schema.d.ts +44 -6
- package/dist/transcription-recordings.d.ts +3 -3
- package/dist/turn-initiator.d.ts +2 -2
- package/dist/video-generation.d.ts +216 -0
- package/dist/video-generation.js +66 -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/drizzle/0065_enrollment_credential_generation.sql +10 -0
- package/drizzle/0140_retained_screenshot_artifacts.sql +192 -0
- package/drizzle/0176_lossless_canonical_json.sql +975 -0
- package/drizzle/0177_session_events_workspace_turn_type_index.sql +5 -0
- package/drizzle/0178_permissioned_secret_reads.sql +14 -0
- package/drizzle/0179_slack_private_shortcut_delivery_gate.sql +85 -0
- package/drizzle/0180_retained_screenshot_lifecycle_fences.sql +273 -0
- package/drizzle/0181_connected_machine_removal.sql +52 -0
- package/drizzle/0182_connected_machine_remove_session_default.sql +77 -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_slack_installation_bindings.sql +348 -0
- package/drizzle/0213_slack_user_link_access_requests.sql +177 -0
- package/drizzle/0214_session_activity_commit_gate.sql +262 -0
- package/drizzle/0215_capabilities_platform.sql +980 -0
- package/drizzle/0216_pack_component_ownership.sql +235 -0
- package/drizzle/0217_capability_definition_delete_authority.sql +32 -0
- package/package.json +18 -5
- package/src/attached-browser-devices.ts +371 -0
- package/src/attempt-tool-catalogs.ts +131 -0
- package/src/browser-auth.ts +1896 -0
- package/src/browser-identities.ts +1168 -0
- package/src/browser-sessions.ts +2005 -0
- package/src/browser-state-artifacts.ts +59 -0
- package/src/capability-components.ts +166 -0
- package/src/capability-integrations.ts +1663 -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 +434 -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/environment-crypto.ts +22 -9
- package/src/generated-images.ts +740 -0
- package/src/index.ts +10117 -2730
- package/src/insights.ts +160 -13
- package/src/integration-bindings.ts +455 -0
- package/src/integration-features.ts +859 -0
- package/src/interaction-revisions.ts +40 -0
- package/src/interaction-schema.ts +1303 -0
- package/src/knowledge-source-sync-schema.ts +192 -0
- package/src/knowledge-source-sync.ts +1922 -0
- package/src/lossless-columns.ts +35 -0
- package/src/lossless-json.ts +322 -0
- package/src/memory-domain.ts +5 -44
- package/src/memory-slack-delivery.ts +801 -0
- package/src/pack-components.ts +954 -0
- package/src/pack-installations.ts +929 -0
- package/src/persistence-errors.ts +26 -34
- package/src/plugin-packages.ts +1186 -0
- package/src/provision-roles.ts +302 -1
- package/src/runtime-posture-cli.ts +9 -0
- package/src/runtime-posture.ts +514 -5
- package/src/schema.ts +5177 -2957
- package/src/scoped-knowledge-schema.ts +1 -1
- package/src/scoped-knowledge.ts +655 -3
- package/src/session-control.ts +133 -81
- package/src/session-queue-commands.ts +511 -247
- package/src/session-realtime-context.ts +20 -7
- package/src/session-realtime-ledger.ts +32 -10
- package/src/session-realtime-mirror.ts +4 -2
- package/src/session-realtime-terminal.ts +89 -21
- package/src/session-realtime.ts +10 -9
- package/src/session-tool-call-settlement.ts +38 -15
- package/src/slack-user-link-access.ts +702 -0
- package/src/transcription-recordings-schema.ts +5 -2
- package/src/transcription-recordings.ts +70 -40
- package/src/video-generation.ts +1452 -0
- package/src/workspace-learning-policy-schema.ts +139 -0
- package/src/workspace-learning-policy.ts +595 -0
- package/dist/chunk-DBS5HPEW.js.map +0 -1
- package/dist/chunk-HT5T62CC.js +0 -6803
- package/dist/chunk-HT5T62CC.js.map +0 -1
- package/dist/event-payload-sanitizer.d.ts +0 -32
- package/src/event-payload-sanitizer.ts +0 -377
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Existing managed workspace administrators receive explicit new permissions.
|
|
3
|
+
-- API keys and frozen session grants are deliberately untouched: an old
|
|
4
|
+
-- workspace:admin wildcard must never acquire plaintext secret reads.
|
|
5
|
+
UPDATE "workspace_memberships"
|
|
6
|
+
SET "permissions" =
|
|
7
|
+
"permissions"
|
|
8
|
+
|| CASE WHEN "permissions" ? 'variable-sets:list' THEN '[]'::jsonb ELSE '["variable-sets:list"]'::jsonb END
|
|
9
|
+
|| CASE WHEN "permissions" ? 'variable-sets:read' THEN '[]'::jsonb ELSE '["variable-sets:read"]'::jsonb END
|
|
10
|
+
|| CASE WHEN "permissions" ? 'variable-sets:write' THEN '[]'::jsonb ELSE '["variable-sets:write"]'::jsonb END
|
|
11
|
+
|| CASE WHEN "permissions" ? 'secrets:list' THEN '[]'::jsonb ELSE '["secrets:list"]'::jsonb END
|
|
12
|
+
|| CASE WHEN "permissions" ? 'secrets:read' THEN '[]'::jsonb ELSE '["secrets:read"]'::jsonb END
|
|
13
|
+
|| CASE WHEN "permissions" ? 'secrets:write' THEN '[]'::jsonb ELSE '["secrets:write"]'::jsonb END
|
|
14
|
+
WHERE "permissions" ? 'workspace:admin';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- A private human-DM shortcut is initially keyed to a source conversation the
|
|
3
|
+
-- workspace bot cannot join. Delivery becomes eligible only after the durable
|
|
4
|
+
-- acknowledgement has rekeyed the route to the invoking user's bot-DM thread.
|
|
5
|
+
|
|
6
|
+
SET lock_timeout = '5s';
|
|
7
|
+
SET statement_timeout = '10min';
|
|
8
|
+
|
|
9
|
+
DO $migration$
|
|
10
|
+
DECLARE data_schema text := current_schema();
|
|
11
|
+
BEGIN
|
|
12
|
+
EXECUTE format($ddl$
|
|
13
|
+
CREATE OR REPLACE FUNCTION opengeni_private.claim_slack_interaction_delivery(
|
|
14
|
+
p_holder uuid,
|
|
15
|
+
p_lease_ms integer
|
|
16
|
+
)
|
|
17
|
+
RETURNS SETOF %1$I.slack_interactions
|
|
18
|
+
LANGUAGE plpgsql
|
|
19
|
+
SECURITY DEFINER
|
|
20
|
+
SET search_path = pg_catalog
|
|
21
|
+
AS $function$
|
|
22
|
+
BEGIN
|
|
23
|
+
IF p_lease_ms < 1000 OR p_lease_ms > 300000 THEN
|
|
24
|
+
RAISE EXCEPTION 'invalid Slack delivery claim lease';
|
|
25
|
+
END IF;
|
|
26
|
+
RETURN QUERY
|
|
27
|
+
WITH candidate AS (
|
|
28
|
+
SELECT I.id
|
|
29
|
+
FROM %1$I.slack_interactions I
|
|
30
|
+
WHERE I.session_id IS NOT NULL
|
|
31
|
+
AND I.terminal_delivery_state = 'open'
|
|
32
|
+
AND (I.delivery_retry_at IS NULL OR I.delivery_retry_at <= now())
|
|
33
|
+
AND (I.delivery_claim_holder_id IS NULL OR I.delivery_claim_expires_at <= now())
|
|
34
|
+
AND NOT (
|
|
35
|
+
I.visibility = 'private'
|
|
36
|
+
AND I.triggering_provider_event_id LIKE 'shortcut:%%'
|
|
37
|
+
AND I.ack_slack_message_ts IS NULL
|
|
38
|
+
)
|
|
39
|
+
AND EXISTS (
|
|
40
|
+
SELECT 1
|
|
41
|
+
FROM %1$I.session_events E
|
|
42
|
+
WHERE E.workspace_id = I.workspace_id
|
|
43
|
+
AND E.session_id = I.session_id
|
|
44
|
+
AND E.sequence > I.last_delivered_session_event_sequence
|
|
45
|
+
AND E.type IN (
|
|
46
|
+
'agent.message.completed',
|
|
47
|
+
'session.humanInput.requested',
|
|
48
|
+
'turn.completed',
|
|
49
|
+
'turn.failed',
|
|
50
|
+
'turn.cancelled',
|
|
51
|
+
'session.status.changed'
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
ORDER BY I.delivery_retry_at NULLS FIRST, I.updated_at, I.id
|
|
55
|
+
FOR UPDATE SKIP LOCKED
|
|
56
|
+
LIMIT 1
|
|
57
|
+
)
|
|
58
|
+
UPDATE %1$I.slack_interactions I
|
|
59
|
+
SET delivery_claim_holder_id = p_holder,
|
|
60
|
+
delivery_claim_expires_at = now() + make_interval(secs => p_lease_ms::double precision / 1000),
|
|
61
|
+
delivery_attempt_count = I.delivery_attempt_count + 1,
|
|
62
|
+
updated_at = now()
|
|
63
|
+
FROM candidate C
|
|
64
|
+
WHERE I.id = C.id
|
|
65
|
+
RETURNING I.*;
|
|
66
|
+
END
|
|
67
|
+
$function$
|
|
68
|
+
$ddl$, data_schema);
|
|
69
|
+
END
|
|
70
|
+
$migration$;
|
|
71
|
+
|
|
72
|
+
REVOKE ALL ON FUNCTION opengeni_private.claim_slack_interaction_delivery(uuid, integer)
|
|
73
|
+
FROM PUBLIC;
|
|
74
|
+
|
|
75
|
+
DO $grants$
|
|
76
|
+
BEGIN
|
|
77
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
78
|
+
GRANT EXECUTE ON FUNCTION opengeni_private.claim_slack_interaction_delivery(uuid, integer)
|
|
79
|
+
TO opengeni_app;
|
|
80
|
+
END IF;
|
|
81
|
+
END
|
|
82
|
+
$grants$;
|
|
83
|
+
|
|
84
|
+
RESET statement_timeout;
|
|
85
|
+
RESET lock_timeout;
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Preserve retained screenshot cleanup/accounting authority across parent
|
|
3
|
+
-- deletion, make quota release explicit and idempotent, and fence provider
|
|
4
|
+
-- deletion with one durable maintenance claim.
|
|
5
|
+
|
|
6
|
+
ALTER TABLE "retained_screenshot_artifacts"
|
|
7
|
+
ALTER COLUMN "session_id" DROP NOT NULL,
|
|
8
|
+
ALTER COLUMN "turn_id" DROP NOT NULL,
|
|
9
|
+
ALTER COLUMN "attempt_id" DROP NOT NULL,
|
|
10
|
+
ADD COLUMN "quota_state" text NOT NULL DEFAULT 'reserved',
|
|
11
|
+
ADD COLUMN "maintenance_claim_id" uuid,
|
|
12
|
+
ADD COLUMN "maintenance_claimed_at" timestamptz;
|
|
13
|
+
|
|
14
|
+
ALTER TABLE "retained_screenshot_artifacts"
|
|
15
|
+
DROP CONSTRAINT "retained_screenshot_artifacts_workspace_session_fk",
|
|
16
|
+
DROP CONSTRAINT "retained_screenshot_artifacts_workspace_turn_fk",
|
|
17
|
+
DROP CONSTRAINT "retained_screenshot_artifacts_workspace_attempt_fk",
|
|
18
|
+
DROP CONSTRAINT "retained_screenshot_artifacts_workspace_file_fk",
|
|
19
|
+
DROP CONSTRAINT "retained_screenshot_artifacts_status_chk",
|
|
20
|
+
DROP CONSTRAINT "retained_screenshot_artifacts_ready_shape_chk",
|
|
21
|
+
DROP CONSTRAINT "retained_screenshot_artifacts_terminal_cleanup_chk";
|
|
22
|
+
|
|
23
|
+
-- Claims created by migration 0140 carried no owner token. Return them to an
|
|
24
|
+
-- unclaimed state before the ownership constraint is installed.
|
|
25
|
+
UPDATE "retained_screenshot_artifacts"
|
|
26
|
+
SET
|
|
27
|
+
"status" = CASE
|
|
28
|
+
WHEN "status" = 'reconciling' THEN 'pending'
|
|
29
|
+
WHEN "status" = 'cleanup_pending' THEN 'cleanup_queued'
|
|
30
|
+
ELSE "status"
|
|
31
|
+
END,
|
|
32
|
+
"quota_state" = CASE
|
|
33
|
+
WHEN "status" IN ('failed', 'expired', 'deleted') THEN 'released'
|
|
34
|
+
WHEN "status" = 'ready' OR "ready_at" IS NOT NULL THEN 'ready'
|
|
35
|
+
ELSE 'reserved'
|
|
36
|
+
END,
|
|
37
|
+
"cleanup_reason" = CASE
|
|
38
|
+
WHEN "status" = 'cleanup_pending' THEN coalesce("cleanup_reason", 'orphaned')
|
|
39
|
+
WHEN "status" IN ('failed', 'expired', 'deleted')
|
|
40
|
+
THEN coalesce("cleanup_reason", "status")
|
|
41
|
+
ELSE "cleanup_reason"
|
|
42
|
+
END,
|
|
43
|
+
"maintenance_claim_id" = NULL,
|
|
44
|
+
"maintenance_claimed_at" = NULL;
|
|
45
|
+
|
|
46
|
+
ALTER TABLE "retained_screenshot_artifacts"
|
|
47
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_session_fk"
|
|
48
|
+
FOREIGN KEY ("session_id") REFERENCES "sessions"("id") ON DELETE SET NULL,
|
|
49
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_turn_fk"
|
|
50
|
+
FOREIGN KEY ("turn_id") REFERENCES "session_turns"("id") ON DELETE SET NULL,
|
|
51
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_attempt_fk"
|
|
52
|
+
FOREIGN KEY ("attempt_id") REFERENCES "session_turn_attempts"("id") ON DELETE SET NULL,
|
|
53
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_workspace_file_fk"
|
|
54
|
+
FOREIGN KEY ("workspace_id", "artifact_id")
|
|
55
|
+
REFERENCES "files"("workspace_id", "id") ON DELETE RESTRICT,
|
|
56
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_status_chk"
|
|
57
|
+
CHECK (
|
|
58
|
+
"status" IN (
|
|
59
|
+
'pending', 'reconciling', 'ready', 'cleanup_queued',
|
|
60
|
+
'cleanup_pending', 'failed', 'expired', 'deleted'
|
|
61
|
+
)
|
|
62
|
+
),
|
|
63
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_quota_state_chk"
|
|
64
|
+
CHECK ("quota_state" IN ('reserved', 'ready', 'released')),
|
|
65
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_status_quota_chk"
|
|
66
|
+
CHECK (
|
|
67
|
+
("status" IN ('pending', 'reconciling') AND "quota_state" = 'reserved')
|
|
68
|
+
OR ("status" = 'ready' AND "quota_state" = 'ready')
|
|
69
|
+
OR (
|
|
70
|
+
"status" IN ('cleanup_queued', 'cleanup_pending')
|
|
71
|
+
AND "quota_state" IN ('reserved', 'ready')
|
|
72
|
+
)
|
|
73
|
+
OR (
|
|
74
|
+
"status" IN ('failed', 'expired', 'deleted')
|
|
75
|
+
AND "quota_state" = 'released'
|
|
76
|
+
)
|
|
77
|
+
),
|
|
78
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_ready_shape_chk"
|
|
79
|
+
CHECK (
|
|
80
|
+
("status" = 'ready' AND "ready_at" IS NOT NULL)
|
|
81
|
+
OR ("status" IN ('pending', 'reconciling') AND "ready_at" IS NULL)
|
|
82
|
+
OR "status" IN ('cleanup_queued', 'cleanup_pending', 'failed', 'expired', 'deleted')
|
|
83
|
+
),
|
|
84
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_cleanup_reason_chk"
|
|
85
|
+
CHECK (
|
|
86
|
+
("status" IN ('pending', 'reconciling', 'ready') AND "cleanup_reason" IS NULL)
|
|
87
|
+
OR (
|
|
88
|
+
"status" IN ('cleanup_queued', 'cleanup_pending', 'failed', 'expired', 'deleted')
|
|
89
|
+
AND "cleanup_reason" IS NOT NULL
|
|
90
|
+
)
|
|
91
|
+
),
|
|
92
|
+
ADD CONSTRAINT "retained_screenshot_artifacts_claim_shape_chk"
|
|
93
|
+
CHECK (
|
|
94
|
+
(
|
|
95
|
+
"status" IN ('reconciling', 'cleanup_pending')
|
|
96
|
+
AND "maintenance_claim_id" IS NOT NULL
|
|
97
|
+
AND "maintenance_claimed_at" IS NOT NULL
|
|
98
|
+
)
|
|
99
|
+
OR (
|
|
100
|
+
"status" NOT IN ('reconciling', 'cleanup_pending')
|
|
101
|
+
AND "maintenance_claim_id" IS NULL
|
|
102
|
+
AND "maintenance_claimed_at" IS NULL
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
DROP INDEX "retained_screenshot_artifacts_pending_reconcile_idx";
|
|
107
|
+
CREATE INDEX "retained_screenshot_artifacts_pending_reconcile_idx"
|
|
108
|
+
ON "retained_screenshot_artifacts" ("updated_at", "artifact_id")
|
|
109
|
+
WHERE "status" IN ('pending', 'reconciling', 'cleanup_queued', 'cleanup_pending');
|
|
110
|
+
|
|
111
|
+
-- Make the aggregate counters a projection of explicit artifact quota state.
|
|
112
|
+
-- This also clears quota leaked by an old parent/file cascade whose lifecycle
|
|
113
|
+
-- row no longer exists.
|
|
114
|
+
INSERT INTO "workspace_screenshot_quotas" ("workspace_id", "account_id")
|
|
115
|
+
SELECT DISTINCT "workspace_id", "account_id"
|
|
116
|
+
FROM "retained_screenshot_artifacts"
|
|
117
|
+
ON CONFLICT ("workspace_id") DO NOTHING;
|
|
118
|
+
|
|
119
|
+
UPDATE "workspace_screenshot_quotas" Q
|
|
120
|
+
SET
|
|
121
|
+
"reserved_bytes" = COALESCE((
|
|
122
|
+
SELECT sum(A."size_bytes")
|
|
123
|
+
FROM "retained_screenshot_artifacts" A
|
|
124
|
+
WHERE A."workspace_id" = Q."workspace_id" AND A."quota_state" = 'reserved'
|
|
125
|
+
), 0),
|
|
126
|
+
"ready_bytes" = COALESCE((
|
|
127
|
+
SELECT sum(A."size_bytes")
|
|
128
|
+
FROM "retained_screenshot_artifacts" A
|
|
129
|
+
WHERE A."workspace_id" = Q."workspace_id" AND A."quota_state" = 'ready'
|
|
130
|
+
), 0),
|
|
131
|
+
"updated_at" = clock_timestamp();
|
|
132
|
+
|
|
133
|
+
CREATE OR REPLACE FUNCTION opengeni_private.queue_detached_retained_screenshot()
|
|
134
|
+
RETURNS trigger
|
|
135
|
+
LANGUAGE plpgsql
|
|
136
|
+
AS $$
|
|
137
|
+
DECLARE
|
|
138
|
+
v_reason text;
|
|
139
|
+
BEGIN
|
|
140
|
+
IF NOT (
|
|
141
|
+
(OLD.session_id IS NOT NULL AND NEW.session_id IS NULL)
|
|
142
|
+
OR (OLD.turn_id IS NOT NULL AND NEW.turn_id IS NULL)
|
|
143
|
+
OR (OLD.attempt_id IS NOT NULL AND NEW.attempt_id IS NULL)
|
|
144
|
+
) THEN
|
|
145
|
+
RETURN NEW;
|
|
146
|
+
END IF;
|
|
147
|
+
|
|
148
|
+
IF NEW.status IN ('failed', 'expired', 'deleted') THEN
|
|
149
|
+
RETURN NEW;
|
|
150
|
+
END IF;
|
|
151
|
+
|
|
152
|
+
v_reason := CASE
|
|
153
|
+
WHEN NEW.session_id IS NULL THEN 'session_deleted'
|
|
154
|
+
WHEN NEW.turn_id IS NULL THEN 'turn_deleted'
|
|
155
|
+
ELSE 'attempt_deleted'
|
|
156
|
+
END;
|
|
157
|
+
NEW.cleanup_reason := v_reason;
|
|
158
|
+
NEW.updated_at := clock_timestamp();
|
|
159
|
+
|
|
160
|
+
IF NEW.status IN ('pending', 'reconciling', 'ready', 'cleanup_queued') THEN
|
|
161
|
+
NEW.status := 'cleanup_queued';
|
|
162
|
+
NEW.maintenance_claim_id := NULL;
|
|
163
|
+
NEW.maintenance_claimed_at := NULL;
|
|
164
|
+
END IF;
|
|
165
|
+
RETURN NEW;
|
|
166
|
+
END;
|
|
167
|
+
$$;
|
|
168
|
+
|
|
169
|
+
DROP TRIGGER IF EXISTS "retained_screenshot_detachment_queue_trg"
|
|
170
|
+
ON "retained_screenshot_artifacts";
|
|
171
|
+
CREATE TRIGGER "retained_screenshot_detachment_queue_trg"
|
|
172
|
+
BEFORE UPDATE OF "session_id", "turn_id", "attempt_id"
|
|
173
|
+
ON "retained_screenshot_artifacts"
|
|
174
|
+
FOR EACH ROW
|
|
175
|
+
EXECUTE FUNCTION opengeni_private.queue_detached_retained_screenshot();
|
|
176
|
+
|
|
177
|
+
DROP FUNCTION opengeni_private.claim_retained_screenshot_maintenance(bigint, bigint, integer);
|
|
178
|
+
|
|
179
|
+
DO $migration$
|
|
180
|
+
DECLARE target_schema text := current_schema();
|
|
181
|
+
BEGIN
|
|
182
|
+
EXECUTE format($create$
|
|
183
|
+
CREATE FUNCTION opengeni_private.claim_retained_screenshot_maintenance(
|
|
184
|
+
p_pending_grace_ms bigint,
|
|
185
|
+
p_claim_timeout_ms bigint,
|
|
186
|
+
p_limit integer
|
|
187
|
+
)
|
|
188
|
+
RETURNS TABLE (
|
|
189
|
+
action text,
|
|
190
|
+
claim_id uuid,
|
|
191
|
+
artifact_id uuid,
|
|
192
|
+
account_id uuid,
|
|
193
|
+
workspace_id uuid,
|
|
194
|
+
session_id uuid,
|
|
195
|
+
object_key text,
|
|
196
|
+
media_type text,
|
|
197
|
+
size_bytes bigint,
|
|
198
|
+
sha256 text,
|
|
199
|
+
width integer,
|
|
200
|
+
height integer,
|
|
201
|
+
retention_expires_at timestamptz,
|
|
202
|
+
cleanup_reason text
|
|
203
|
+
)
|
|
204
|
+
LANGUAGE sql
|
|
205
|
+
SECURITY DEFINER
|
|
206
|
+
SET search_path = pg_catalog
|
|
207
|
+
AS $function$
|
|
208
|
+
WITH candidates AS (
|
|
209
|
+
SELECT
|
|
210
|
+
A.artifact_id,
|
|
211
|
+
gen_random_uuid() AS claim_id,
|
|
212
|
+
CASE
|
|
213
|
+
WHEN A.status IN ('pending', 'reconciling') THEN 'reconcile'
|
|
214
|
+
ELSE 'delete'
|
|
215
|
+
END AS action,
|
|
216
|
+
CASE
|
|
217
|
+
WHEN A.status = 'ready' THEN 'expired'
|
|
218
|
+
WHEN A.status IN ('cleanup_queued', 'cleanup_pending')
|
|
219
|
+
THEN coalesce(A.cleanup_reason, 'orphaned')
|
|
220
|
+
ELSE NULL
|
|
221
|
+
END AS cleanup_reason
|
|
222
|
+
FROM %1$I.retained_screenshot_artifacts A
|
|
223
|
+
WHERE
|
|
224
|
+
(A.status = 'ready' AND A.retention_expires_at <= clock_timestamp())
|
|
225
|
+
OR A.status = 'cleanup_queued'
|
|
226
|
+
OR (
|
|
227
|
+
A.status = 'pending'
|
|
228
|
+
AND A.updated_at <= clock_timestamp() - (
|
|
229
|
+
greatest(p_pending_grace_ms, 0)::double precision * interval '1 millisecond'
|
|
230
|
+
)
|
|
231
|
+
)
|
|
232
|
+
OR (
|
|
233
|
+
A.status IN ('reconciling', 'cleanup_pending')
|
|
234
|
+
AND A.maintenance_claimed_at <= clock_timestamp() - (
|
|
235
|
+
greatest(p_claim_timeout_ms, 0)::double precision * interval '1 millisecond'
|
|
236
|
+
)
|
|
237
|
+
)
|
|
238
|
+
ORDER BY A.retention_expires_at, A.artifact_id
|
|
239
|
+
LIMIT least(greatest(p_limit, 0), 1000)
|
|
240
|
+
FOR UPDATE SKIP LOCKED
|
|
241
|
+
), claimed AS (
|
|
242
|
+
UPDATE %1$I.retained_screenshot_artifacts A
|
|
243
|
+
SET
|
|
244
|
+
status = CASE WHEN C.action = 'reconcile' THEN 'reconciling' ELSE 'cleanup_pending' END,
|
|
245
|
+
cleanup_reason = C.cleanup_reason,
|
|
246
|
+
maintenance_claim_id = C.claim_id,
|
|
247
|
+
maintenance_claimed_at = clock_timestamp(),
|
|
248
|
+
updated_at = clock_timestamp()
|
|
249
|
+
FROM candidates C
|
|
250
|
+
WHERE A.artifact_id = C.artifact_id
|
|
251
|
+
RETURNING A.*, C.action, C.claim_id
|
|
252
|
+
)
|
|
253
|
+
SELECT C.action, C.claim_id, C.artifact_id, C.account_id, C.workspace_id, C.session_id,
|
|
254
|
+
F.object_key, C.media_type, C.size_bytes, C.sha256, C.width, C.height,
|
|
255
|
+
C.retention_expires_at, C.cleanup_reason
|
|
256
|
+
FROM claimed C
|
|
257
|
+
JOIN %1$I.files F
|
|
258
|
+
ON F.workspace_id = C.workspace_id
|
|
259
|
+
AND F.id = C.artifact_id;
|
|
260
|
+
$function$;
|
|
261
|
+
$create$, target_schema);
|
|
262
|
+
END $migration$;
|
|
263
|
+
|
|
264
|
+
REVOKE ALL ON FUNCTION opengeni_private.claim_retained_screenshot_maintenance(bigint, bigint, integer)
|
|
265
|
+
FROM PUBLIC;
|
|
266
|
+
|
|
267
|
+
DO $$
|
|
268
|
+
BEGIN
|
|
269
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
270
|
+
GRANT EXECUTE ON FUNCTION opengeni_private.claim_retained_screenshot_maintenance(bigint, bigint, integer)
|
|
271
|
+
TO opengeni_app;
|
|
272
|
+
END IF;
|
|
273
|
+
END $$;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
|
|
3
|
+
-- Connected-machine removal is a control-plane operation. The enrollment row
|
|
4
|
+
-- remains durable evidence; this receipt table makes retries deterministic and
|
|
5
|
+
-- preserves blocked dependency explanations without storing credentials.
|
|
6
|
+
CREATE TABLE "machine_removal_operations" (
|
|
7
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
8
|
+
"account_id" uuid NOT NULL REFERENCES "managed_accounts"("id") ON DELETE CASCADE,
|
|
9
|
+
"workspace_id" uuid NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
|
|
10
|
+
"enrollment_id" uuid NOT NULL REFERENCES "enrollments"("id") ON DELETE RESTRICT,
|
|
11
|
+
"operation_key" text NOT NULL,
|
|
12
|
+
"request_fingerprint" text NOT NULL,
|
|
13
|
+
"outcome" text NOT NULL,
|
|
14
|
+
"result" jsonb NOT NULL DEFAULT '{}'::jsonb,
|
|
15
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
16
|
+
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
17
|
+
CONSTRAINT "machine_removal_operations_request_fingerprint_chk"
|
|
18
|
+
CHECK ("request_fingerprint" ~ '^[0-9a-f]{64}$'),
|
|
19
|
+
CONSTRAINT "machine_removal_operations_operation_key_chk"
|
|
20
|
+
CHECK (length(btrim("operation_key")) BETWEEN 1 AND 200
|
|
21
|
+
AND "operation_key" = btrim("operation_key")),
|
|
22
|
+
CONSTRAINT "machine_removal_operations_outcome_chk"
|
|
23
|
+
CHECK ("outcome" IN ('removed', 'already_removed', 'blocked')),
|
|
24
|
+
CONSTRAINT "machine_removal_operations_workspace_account_fk"
|
|
25
|
+
FOREIGN KEY ("workspace_id", "account_id")
|
|
26
|
+
REFERENCES "workspaces"("id", "account_id") ON DELETE CASCADE
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE UNIQUE INDEX "machine_removal_operations_workspace_operation_uq"
|
|
30
|
+
ON "machine_removal_operations" ("workspace_id", "operation_key");
|
|
31
|
+
CREATE UNIQUE INDEX "machine_removal_operations_workspace_id_uq"
|
|
32
|
+
ON "machine_removal_operations" ("workspace_id", "id");
|
|
33
|
+
CREATE INDEX "machine_removal_operations_enrollment_created_idx"
|
|
34
|
+
ON "machine_removal_operations" ("workspace_id", "enrollment_id", "created_at");
|
|
35
|
+
|
|
36
|
+
ALTER TABLE "machine_removal_operations" ENABLE ROW LEVEL SECURITY;
|
|
37
|
+
ALTER TABLE "machine_removal_operations" FORCE ROW LEVEL SECURITY;
|
|
38
|
+
CREATE POLICY workspace_isolation ON "machine_removal_operations"
|
|
39
|
+
USING (opengeni_private.workspace_rls_visible("account_id", "workspace_id"))
|
|
40
|
+
WITH CHECK (opengeni_private.workspace_rls_visible("account_id", "workspace_id"));
|
|
41
|
+
|
|
42
|
+
DO $grants$
|
|
43
|
+
DECLARE target_schema text := current_schema();
|
|
44
|
+
BEGIN
|
|
45
|
+
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
|
|
46
|
+
EXECUTE format(
|
|
47
|
+
'GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE %I.machine_removal_operations TO opengeni_app',
|
|
48
|
+
target_schema
|
|
49
|
+
);
|
|
50
|
+
END IF;
|
|
51
|
+
END
|
|
52
|
+
$grants$;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Migration 0172 is already deployed and immutable. Keep its database-owned
|
|
3
|
+
-- fallback default aligned with the connected-machine removal tool through a
|
|
4
|
+
-- forward migration; application session creation still writes its exact
|
|
5
|
+
-- frozen tool selection explicitly.
|
|
6
|
+
|
|
7
|
+
ALTER TABLE "sessions"
|
|
8
|
+
ALTER COLUMN "first_party_mcp_tools"
|
|
9
|
+
SET DEFAULT '[
|
|
10
|
+
"set_session_title",
|
|
11
|
+
"goal_set",
|
|
12
|
+
"goal_update",
|
|
13
|
+
"goal_complete",
|
|
14
|
+
"goal_pause",
|
|
15
|
+
"memory_search",
|
|
16
|
+
"memory_save",
|
|
17
|
+
"memory_correct",
|
|
18
|
+
"preference_registry_summary",
|
|
19
|
+
"preference_registry_get",
|
|
20
|
+
"sandboxes_list",
|
|
21
|
+
"sandbox_attach",
|
|
22
|
+
"sandbox_swap",
|
|
23
|
+
"run_on",
|
|
24
|
+
"sandbox_provision",
|
|
25
|
+
"connected_machine_remove",
|
|
26
|
+
"rig_list",
|
|
27
|
+
"rig_get",
|
|
28
|
+
"rig_propose_change",
|
|
29
|
+
"rig_verify",
|
|
30
|
+
"rig_promote",
|
|
31
|
+
"sessions_list",
|
|
32
|
+
"session_get",
|
|
33
|
+
"session_events",
|
|
34
|
+
"session_create",
|
|
35
|
+
"session_send_message",
|
|
36
|
+
"session_pause",
|
|
37
|
+
"session_resume",
|
|
38
|
+
"session_steer",
|
|
39
|
+
"set_other_session_title",
|
|
40
|
+
"variable_set_list",
|
|
41
|
+
"environment_list",
|
|
42
|
+
"variable_set_set_variable",
|
|
43
|
+
"environment_set_variable",
|
|
44
|
+
"github_connect_link",
|
|
45
|
+
"github_repositories_list",
|
|
46
|
+
"social_connections_list",
|
|
47
|
+
"social_posts_recent",
|
|
48
|
+
"social_daily_analysis_context",
|
|
49
|
+
"social_search_live",
|
|
50
|
+
"social_mentions_live",
|
|
51
|
+
"social_thread_fetch",
|
|
52
|
+
"social_posts_sync",
|
|
53
|
+
"social_post_reply",
|
|
54
|
+
"scheduled_tasks_list",
|
|
55
|
+
"scheduled_tasks_get",
|
|
56
|
+
"scheduled_tasks_create",
|
|
57
|
+
"scheduled_tasks_update",
|
|
58
|
+
"scheduled_tasks_pause",
|
|
59
|
+
"scheduled_tasks_resume",
|
|
60
|
+
"scheduled_tasks_trigger",
|
|
61
|
+
"scheduled_tasks_delete",
|
|
62
|
+
"scheduled_task_runs_list",
|
|
63
|
+
"slack_bot_list_channels",
|
|
64
|
+
"slack_bot_channel_history",
|
|
65
|
+
"slack_bot_thread_replies",
|
|
66
|
+
"slack_bot_list_users",
|
|
67
|
+
"slack_bot_list_files",
|
|
68
|
+
"slack_bot_file_info",
|
|
69
|
+
"slack_bot_file_content",
|
|
70
|
+
"slack_bot_post_message",
|
|
71
|
+
"slack_bot_delete_message",
|
|
72
|
+
"artifacts_list",
|
|
73
|
+
"artifacts_get_source",
|
|
74
|
+
"artifacts_create",
|
|
75
|
+
"artifacts_publish",
|
|
76
|
+
"artifacts_rollback"
|
|
77
|
+
]'::jsonb;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- Preserve the captured provider-rate comparison separately from the OpenGeni
|
|
3
|
+
-- credit price. Existing facts remain unknown rather than being rewritten with
|
|
4
|
+
-- today's rates or incorrectly treating credit markup as provider cost.
|
|
5
|
+
|
|
6
|
+
SET LOCAL lock_timeout = '5s';
|
|
7
|
+
SET LOCAL statement_timeout = '5min';
|
|
8
|
+
|
|
9
|
+
ALTER TABLE "model_call_facts"
|
|
10
|
+
ADD COLUMN IF NOT EXISTS "estimated_provider_cost_micros" bigint,
|
|
11
|
+
ADD COLUMN IF NOT EXISTS "pricing_source" text;
|
|
12
|
+
|
|
13
|
+
ALTER TABLE "model_call_facts"
|
|
14
|
+
DROP CONSTRAINT IF EXISTS "model_call_facts_estimated_provider_cost_check",
|
|
15
|
+
ADD CONSTRAINT "model_call_facts_estimated_provider_cost_check"
|
|
16
|
+
CHECK (
|
|
17
|
+
"estimated_provider_cost_micros" IS NULL
|
|
18
|
+
OR "estimated_provider_cost_micros" >= 0
|
|
19
|
+
) NOT VALID;
|
|
20
|
+
|
|
21
|
+
ALTER TABLE "model_call_facts"
|
|
22
|
+
VALIDATE CONSTRAINT "model_call_facts_estimated_provider_cost_check";
|
|
23
|
+
|
|
24
|
+
ALTER TABLE "model_call_facts"
|
|
25
|
+
DROP CONSTRAINT IF EXISTS "model_call_facts_pricing_source_check",
|
|
26
|
+
ADD CONSTRAINT "model_call_facts_pricing_source_check"
|
|
27
|
+
CHECK (
|
|
28
|
+
("estimated_provider_cost_micros" IS NULL AND "pricing_source" IS NULL)
|
|
29
|
+
OR (
|
|
30
|
+
"estimated_provider_cost_micros" IS NOT NULL
|
|
31
|
+
AND "pricing_source" IN ('configured_list_price', 'gateway_reported')
|
|
32
|
+
)
|
|
33
|
+
) NOT VALID;
|
|
34
|
+
|
|
35
|
+
ALTER TABLE "model_call_facts"
|
|
36
|
+
VALIDATE CONSTRAINT "model_call_facts_pricing_source_check";
|
|
37
|
+
|
|
38
|
+
RESET statement_timeout;
|
|
39
|
+
RESET lock_timeout;
|