@opengeni/db 0.17.1 → 0.18.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/{chunk-TLAC622R.js → chunk-YKWJ7QJ2.js} +11 -1
- package/dist/chunk-YKWJ7QJ2.js.map +1 -0
- package/dist/index.d.ts +70 -2
- package/dist/index.js +176 -6
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +87 -2
- package/dist/schema.js +1 -1
- package/drizzle/0141_social_connection_credentials.sql +8 -0
- package/drizzle/0151_slack_delivery_backoff.sql +134 -0
- package/package.json +3 -3
- package/src/index.ts +294 -6
- package/src/schema.ts +10 -0
- package/dist/chunk-TLAC622R.js.map +0 -1
package/dist/schema.d.ts
CHANGED
|
@@ -3834,6 +3834,23 @@ export declare const slackInteractionInbox: import("drizzle-orm/pg-core").PgTabl
|
|
|
3834
3834
|
identity: undefined;
|
|
3835
3835
|
generated: undefined;
|
|
3836
3836
|
}, {}, {}>;
|
|
3837
|
+
retryAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
3838
|
+
name: "retry_at";
|
|
3839
|
+
tableName: "slack_interaction_inbox";
|
|
3840
|
+
dataType: "date";
|
|
3841
|
+
columnType: "PgTimestamp";
|
|
3842
|
+
data: Date;
|
|
3843
|
+
driverParam: string;
|
|
3844
|
+
notNull: false;
|
|
3845
|
+
hasDefault: false;
|
|
3846
|
+
isPrimaryKey: false;
|
|
3847
|
+
isAutoincrement: false;
|
|
3848
|
+
hasRuntimeDefault: false;
|
|
3849
|
+
enumValues: undefined;
|
|
3850
|
+
baseColumn: never;
|
|
3851
|
+
identity: undefined;
|
|
3852
|
+
generated: undefined;
|
|
3853
|
+
}, {}, {}>;
|
|
3837
3854
|
lastErrorCode: import("drizzle-orm/pg-core").PgColumn<{
|
|
3838
3855
|
name: "last_error_code";
|
|
3839
3856
|
tableName: "slack_interaction_inbox";
|
|
@@ -4183,6 +4200,57 @@ export declare const slackInteractions: import("drizzle-orm/pg-core").PgTableWit
|
|
|
4183
4200
|
identity: undefined;
|
|
4184
4201
|
generated: undefined;
|
|
4185
4202
|
}, {}, {}>;
|
|
4203
|
+
deliveryAttemptCount: import("drizzle-orm/pg-core").PgColumn<{
|
|
4204
|
+
name: "delivery_attempt_count";
|
|
4205
|
+
tableName: "slack_interactions";
|
|
4206
|
+
dataType: "number";
|
|
4207
|
+
columnType: "PgInteger";
|
|
4208
|
+
data: number;
|
|
4209
|
+
driverParam: string | number;
|
|
4210
|
+
notNull: true;
|
|
4211
|
+
hasDefault: true;
|
|
4212
|
+
isPrimaryKey: false;
|
|
4213
|
+
isAutoincrement: false;
|
|
4214
|
+
hasRuntimeDefault: false;
|
|
4215
|
+
enumValues: undefined;
|
|
4216
|
+
baseColumn: never;
|
|
4217
|
+
identity: undefined;
|
|
4218
|
+
generated: undefined;
|
|
4219
|
+
}, {}, {}>;
|
|
4220
|
+
deliveryRetryAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
4221
|
+
name: "delivery_retry_at";
|
|
4222
|
+
tableName: "slack_interactions";
|
|
4223
|
+
dataType: "date";
|
|
4224
|
+
columnType: "PgTimestamp";
|
|
4225
|
+
data: Date;
|
|
4226
|
+
driverParam: string;
|
|
4227
|
+
notNull: false;
|
|
4228
|
+
hasDefault: false;
|
|
4229
|
+
isPrimaryKey: false;
|
|
4230
|
+
isAutoincrement: false;
|
|
4231
|
+
hasRuntimeDefault: false;
|
|
4232
|
+
enumValues: undefined;
|
|
4233
|
+
baseColumn: never;
|
|
4234
|
+
identity: undefined;
|
|
4235
|
+
generated: undefined;
|
|
4236
|
+
}, {}, {}>;
|
|
4237
|
+
deliveryLastErrorCode: import("drizzle-orm/pg-core").PgColumn<{
|
|
4238
|
+
name: "delivery_last_error_code";
|
|
4239
|
+
tableName: "slack_interactions";
|
|
4240
|
+
dataType: "string";
|
|
4241
|
+
columnType: "PgText";
|
|
4242
|
+
data: string;
|
|
4243
|
+
driverParam: string;
|
|
4244
|
+
notNull: false;
|
|
4245
|
+
hasDefault: false;
|
|
4246
|
+
isPrimaryKey: false;
|
|
4247
|
+
isAutoincrement: false;
|
|
4248
|
+
hasRuntimeDefault: false;
|
|
4249
|
+
enumValues: [string, ...string[]];
|
|
4250
|
+
baseColumn: never;
|
|
4251
|
+
identity: undefined;
|
|
4252
|
+
generated: undefined;
|
|
4253
|
+
}, {}, {}>;
|
|
4186
4254
|
ackSlackMessageTs: import("drizzle-orm/pg-core").PgColumn<{
|
|
4187
4255
|
name: "ack_slack_message_ts";
|
|
4188
4256
|
tableName: "slack_interactions";
|
|
@@ -6401,7 +6469,7 @@ export declare const sessions: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
6401
6469
|
tableName: "sessions";
|
|
6402
6470
|
dataType: "json";
|
|
6403
6471
|
columnType: "PgJsonb";
|
|
6404
|
-
data: ("artifacts_create" | "artifacts_get_source" | "artifacts_list" | "artifacts_publish" | "artifacts_rollback" | "environment_list" | "environment_set_variable" | "github_connect_link" | "github_repositories_list" | "github_token" | "goal_complete" | "goal_pause" | "goal_set" | "goal_update" | "memory_correct" | "memory_save" | "memory_search" | "preference_registry_get" | "preference_registry_summary" | "rig_get" | "rig_list" | "rig_promote" | "rig_propose_change" | "rig_verify" | "run_on" | "sandbox_attach" | "sandbox_provision" | "sandbox_swap" | "sandboxes_list" | "scheduled_task_runs_list" | "scheduled_tasks_create" | "scheduled_tasks_delete" | "scheduled_tasks_get" | "scheduled_tasks_list" | "scheduled_tasks_pause" | "scheduled_tasks_resume" | "scheduled_tasks_trigger" | "scheduled_tasks_update" | "session_create" | "session_events" | "session_get" | "session_pause" | "session_resume" | "session_send_message" | "session_steer" | "sessions_list" | "set_other_session_title" | "set_session_title" | "slack_bot_channel_history" | "slack_bot_delete_message" | "slack_bot_file_content" | "slack_bot_file_info" | "slack_bot_list_channels" | "slack_bot_list_files" | "slack_bot_list_users" | "slack_bot_post_message" | "slack_bot_thread_replies" | "social_connections_list" | "social_daily_analysis_context" | "social_posts_recent" | "variable_set_list" | "variable_set_set_variable")[];
|
|
6472
|
+
data: ("artifacts_create" | "artifacts_get_source" | "artifacts_list" | "artifacts_publish" | "artifacts_rollback" | "environment_list" | "environment_set_variable" | "github_connect_link" | "github_repositories_list" | "github_token" | "goal_complete" | "goal_pause" | "goal_set" | "goal_update" | "memory_correct" | "memory_save" | "memory_search" | "preference_registry_get" | "preference_registry_summary" | "rig_get" | "rig_list" | "rig_promote" | "rig_propose_change" | "rig_verify" | "run_on" | "sandbox_attach" | "sandbox_provision" | "sandbox_swap" | "sandboxes_list" | "scheduled_task_runs_list" | "scheduled_tasks_create" | "scheduled_tasks_delete" | "scheduled_tasks_get" | "scheduled_tasks_list" | "scheduled_tasks_pause" | "scheduled_tasks_resume" | "scheduled_tasks_trigger" | "scheduled_tasks_update" | "session_create" | "session_events" | "session_get" | "session_pause" | "session_resume" | "session_send_message" | "session_steer" | "sessions_list" | "set_other_session_title" | "set_session_title" | "slack_bot_channel_history" | "slack_bot_delete_message" | "slack_bot_file_content" | "slack_bot_file_info" | "slack_bot_list_channels" | "slack_bot_list_files" | "slack_bot_list_users" | "slack_bot_post_message" | "slack_bot_thread_replies" | "social_connections_list" | "social_daily_analysis_context" | "social_mentions_live" | "social_post_reply" | "social_posts_recent" | "social_posts_sync" | "social_search_live" | "social_thread_fetch" | "variable_set_list" | "variable_set_set_variable")[];
|
|
6405
6473
|
driverParam: unknown;
|
|
6406
6474
|
notNull: true;
|
|
6407
6475
|
hasDefault: false;
|
|
@@ -6413,7 +6481,7 @@ export declare const sessions: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
6413
6481
|
identity: undefined;
|
|
6414
6482
|
generated: undefined;
|
|
6415
6483
|
}, {}, {
|
|
6416
|
-
$type: ("artifacts_create" | "artifacts_get_source" | "artifacts_list" | "artifacts_publish" | "artifacts_rollback" | "environment_list" | "environment_set_variable" | "github_connect_link" | "github_repositories_list" | "github_token" | "goal_complete" | "goal_pause" | "goal_set" | "goal_update" | "memory_correct" | "memory_save" | "memory_search" | "preference_registry_get" | "preference_registry_summary" | "rig_get" | "rig_list" | "rig_promote" | "rig_propose_change" | "rig_verify" | "run_on" | "sandbox_attach" | "sandbox_provision" | "sandbox_swap" | "sandboxes_list" | "scheduled_task_runs_list" | "scheduled_tasks_create" | "scheduled_tasks_delete" | "scheduled_tasks_get" | "scheduled_tasks_list" | "scheduled_tasks_pause" | "scheduled_tasks_resume" | "scheduled_tasks_trigger" | "scheduled_tasks_update" | "session_create" | "session_events" | "session_get" | "session_pause" | "session_resume" | "session_send_message" | "session_steer" | "sessions_list" | "set_other_session_title" | "set_session_title" | "slack_bot_channel_history" | "slack_bot_delete_message" | "slack_bot_file_content" | "slack_bot_file_info" | "slack_bot_list_channels" | "slack_bot_list_files" | "slack_bot_list_users" | "slack_bot_post_message" | "slack_bot_thread_replies" | "social_connections_list" | "social_daily_analysis_context" | "social_posts_recent" | "variable_set_list" | "variable_set_set_variable")[];
|
|
6484
|
+
$type: ("artifacts_create" | "artifacts_get_source" | "artifacts_list" | "artifacts_publish" | "artifacts_rollback" | "environment_list" | "environment_set_variable" | "github_connect_link" | "github_repositories_list" | "github_token" | "goal_complete" | "goal_pause" | "goal_set" | "goal_update" | "memory_correct" | "memory_save" | "memory_search" | "preference_registry_get" | "preference_registry_summary" | "rig_get" | "rig_list" | "rig_promote" | "rig_propose_change" | "rig_verify" | "run_on" | "sandbox_attach" | "sandbox_provision" | "sandbox_swap" | "sandboxes_list" | "scheduled_task_runs_list" | "scheduled_tasks_create" | "scheduled_tasks_delete" | "scheduled_tasks_get" | "scheduled_tasks_list" | "scheduled_tasks_pause" | "scheduled_tasks_resume" | "scheduled_tasks_trigger" | "scheduled_tasks_update" | "session_create" | "session_events" | "session_get" | "session_pause" | "session_resume" | "session_send_message" | "session_steer" | "sessions_list" | "set_other_session_title" | "set_session_title" | "slack_bot_channel_history" | "slack_bot_delete_message" | "slack_bot_file_content" | "slack_bot_file_info" | "slack_bot_list_channels" | "slack_bot_list_files" | "slack_bot_list_users" | "slack_bot_post_message" | "slack_bot_thread_replies" | "social_connections_list" | "social_daily_analysis_context" | "social_mentions_live" | "social_post_reply" | "social_posts_recent" | "social_posts_sync" | "social_search_live" | "social_thread_fetch" | "variable_set_list" | "variable_set_set_variable")[];
|
|
6417
6485
|
}>;
|
|
6418
6486
|
toolPolicy: import("drizzle-orm/pg-core").PgColumn<{
|
|
6419
6487
|
name: "tool_policy";
|
|
@@ -24387,6 +24455,23 @@ export declare const socialConnections: import("drizzle-orm/pg-core").PgTableWit
|
|
|
24387
24455
|
identity: undefined;
|
|
24388
24456
|
generated: undefined;
|
|
24389
24457
|
}, {}, {}>;
|
|
24458
|
+
credentialEncrypted: import("drizzle-orm/pg-core").PgColumn<{
|
|
24459
|
+
name: "credential_encrypted";
|
|
24460
|
+
tableName: "social_connections";
|
|
24461
|
+
dataType: "string";
|
|
24462
|
+
columnType: "PgText";
|
|
24463
|
+
data: string;
|
|
24464
|
+
driverParam: string;
|
|
24465
|
+
notNull: false;
|
|
24466
|
+
hasDefault: false;
|
|
24467
|
+
isPrimaryKey: false;
|
|
24468
|
+
isAutoincrement: false;
|
|
24469
|
+
hasRuntimeDefault: false;
|
|
24470
|
+
enumValues: [string, ...string[]];
|
|
24471
|
+
baseColumn: never;
|
|
24472
|
+
identity: undefined;
|
|
24473
|
+
generated: undefined;
|
|
24474
|
+
}, {}, {}>;
|
|
24390
24475
|
tokenMetadata: import("drizzle-orm/pg-core").PgColumn<{
|
|
24391
24476
|
name: "token_metadata";
|
|
24392
24477
|
tableName: "social_connections";
|
package/dist/schema.js
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
-- First-party social connectors (X / Reddit): OAuth token storage.
|
|
3
|
+
-- credential_encrypted holds the AES-256-GCM envelope (environment-crypto v1
|
|
4
|
+
-- format) with the provider token bundle {access_token, refresh_token, ...}.
|
|
5
|
+
-- It is deliberately separate from credential_ref (a free-text external
|
|
6
|
+
-- reference) and never surfaced by the SocialConnection contract mapper.
|
|
7
|
+
|
|
8
|
+
ALTER TABLE "social_connections" ADD COLUMN IF NOT EXISTS "credential_encrypted" text;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
-- deployment-mode: rolling
|
|
2
|
+
SET lock_timeout = '5s';
|
|
3
|
+
SET statement_timeout = '30s';
|
|
4
|
+
|
|
5
|
+
ALTER TABLE slack_interactions
|
|
6
|
+
ADD COLUMN delivery_attempt_count integer NOT NULL DEFAULT 0,
|
|
7
|
+
ADD COLUMN delivery_retry_at timestamptz,
|
|
8
|
+
ADD COLUMN delivery_last_error_code text;
|
|
9
|
+
|
|
10
|
+
ALTER TABLE slack_interactions
|
|
11
|
+
ADD CONSTRAINT slack_interactions_delivery_attempt_check
|
|
12
|
+
CHECK (delivery_attempt_count >= 0),
|
|
13
|
+
ADD CONSTRAINT slack_interactions_delivery_error_check
|
|
14
|
+
CHECK (
|
|
15
|
+
delivery_last_error_code IS NULL
|
|
16
|
+
OR octet_length(delivery_last_error_code) BETWEEN 1 AND 128
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
ALTER TABLE slack_interaction_inbox
|
|
20
|
+
ADD COLUMN retry_at timestamptz;
|
|
21
|
+
|
|
22
|
+
DROP INDEX slack_interaction_inbox_pending_idx;
|
|
23
|
+
CREATE INDEX slack_interaction_inbox_pending_idx
|
|
24
|
+
ON slack_interaction_inbox (status, retry_at, created_at, id)
|
|
25
|
+
WHERE status IN ('pending', 'processing');
|
|
26
|
+
|
|
27
|
+
DROP INDEX slack_interactions_delivery_idx;
|
|
28
|
+
CREATE INDEX slack_interactions_delivery_idx
|
|
29
|
+
ON slack_interactions (terminal_delivery_state, delivery_retry_at, updated_at, id)
|
|
30
|
+
WHERE session_id IS NOT NULL AND terminal_delivery_state = 'open';
|
|
31
|
+
|
|
32
|
+
DO $privileged_functions$
|
|
33
|
+
DECLARE data_schema text := current_schema();
|
|
34
|
+
BEGIN
|
|
35
|
+
EXECUTE format($ddl$
|
|
36
|
+
CREATE OR REPLACE FUNCTION opengeni_private.claim_slack_interaction_inbox(
|
|
37
|
+
p_holder uuid,
|
|
38
|
+
p_lease_ms integer
|
|
39
|
+
)
|
|
40
|
+
RETURNS SETOF %1$I.slack_interaction_inbox
|
|
41
|
+
LANGUAGE plpgsql
|
|
42
|
+
SECURITY DEFINER
|
|
43
|
+
SET search_path = pg_catalog
|
|
44
|
+
AS $function$
|
|
45
|
+
BEGIN
|
|
46
|
+
IF p_lease_ms < 1000 OR p_lease_ms > 300000 THEN
|
|
47
|
+
RAISE EXCEPTION 'invalid Slack inbox claim lease';
|
|
48
|
+
END IF;
|
|
49
|
+
RETURN QUERY
|
|
50
|
+
WITH candidate AS (
|
|
51
|
+
SELECT I.id
|
|
52
|
+
FROM %1$I.slack_interaction_inbox I
|
|
53
|
+
WHERE (
|
|
54
|
+
I.status = 'pending'
|
|
55
|
+
AND (I.retry_at IS NULL OR I.retry_at <= now())
|
|
56
|
+
) OR (
|
|
57
|
+
I.status = 'processing'
|
|
58
|
+
AND I.claim_expires_at <= now()
|
|
59
|
+
)
|
|
60
|
+
ORDER BY I.retry_at NULLS FIRST, I.created_at, I.id
|
|
61
|
+
FOR UPDATE SKIP LOCKED
|
|
62
|
+
LIMIT 1
|
|
63
|
+
)
|
|
64
|
+
UPDATE %1$I.slack_interaction_inbox I
|
|
65
|
+
SET status = 'processing',
|
|
66
|
+
claim_holder_id = p_holder,
|
|
67
|
+
claim_expires_at = now() + make_interval(secs => p_lease_ms::double precision / 1000),
|
|
68
|
+
retry_at = NULL,
|
|
69
|
+
attempt_count = I.attempt_count + 1,
|
|
70
|
+
updated_at = now()
|
|
71
|
+
FROM candidate C
|
|
72
|
+
WHERE I.id = C.id
|
|
73
|
+
RETURNING I.*;
|
|
74
|
+
END
|
|
75
|
+
$function$
|
|
76
|
+
$ddl$, data_schema);
|
|
77
|
+
|
|
78
|
+
EXECUTE format($ddl$
|
|
79
|
+
CREATE OR REPLACE FUNCTION opengeni_private.claim_slack_interaction_delivery(
|
|
80
|
+
p_holder uuid,
|
|
81
|
+
p_lease_ms integer
|
|
82
|
+
)
|
|
83
|
+
RETURNS SETOF %1$I.slack_interactions
|
|
84
|
+
LANGUAGE plpgsql
|
|
85
|
+
SECURITY DEFINER
|
|
86
|
+
SET search_path = pg_catalog
|
|
87
|
+
AS $function$
|
|
88
|
+
BEGIN
|
|
89
|
+
IF p_lease_ms < 1000 OR p_lease_ms > 300000 THEN
|
|
90
|
+
RAISE EXCEPTION 'invalid Slack delivery claim lease';
|
|
91
|
+
END IF;
|
|
92
|
+
RETURN QUERY
|
|
93
|
+
WITH candidate AS (
|
|
94
|
+
SELECT I.id
|
|
95
|
+
FROM %1$I.slack_interactions I
|
|
96
|
+
WHERE I.session_id IS NOT NULL
|
|
97
|
+
AND I.terminal_delivery_state = 'open'
|
|
98
|
+
AND (I.delivery_retry_at IS NULL OR I.delivery_retry_at <= now())
|
|
99
|
+
AND (I.delivery_claim_holder_id IS NULL OR I.delivery_claim_expires_at <= now())
|
|
100
|
+
AND EXISTS (
|
|
101
|
+
SELECT 1
|
|
102
|
+
FROM %1$I.session_events E
|
|
103
|
+
WHERE E.workspace_id = I.workspace_id
|
|
104
|
+
AND E.session_id = I.session_id
|
|
105
|
+
AND E.sequence > I.last_delivered_session_event_sequence
|
|
106
|
+
AND E.type IN (
|
|
107
|
+
'agent.message.completed',
|
|
108
|
+
'session.humanInput.requested',
|
|
109
|
+
'turn.completed',
|
|
110
|
+
'turn.failed',
|
|
111
|
+
'turn.cancelled',
|
|
112
|
+
'session.status.changed'
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
ORDER BY I.delivery_retry_at NULLS FIRST, I.updated_at, I.id
|
|
116
|
+
FOR UPDATE SKIP LOCKED
|
|
117
|
+
LIMIT 1
|
|
118
|
+
)
|
|
119
|
+
UPDATE %1$I.slack_interactions I
|
|
120
|
+
SET delivery_claim_holder_id = p_holder,
|
|
121
|
+
delivery_claim_expires_at = now() + make_interval(secs => p_lease_ms::double precision / 1000),
|
|
122
|
+
delivery_attempt_count = I.delivery_attempt_count + 1,
|
|
123
|
+
updated_at = now()
|
|
124
|
+
FROM candidate C
|
|
125
|
+
WHERE I.id = C.id
|
|
126
|
+
RETURNING I.*;
|
|
127
|
+
END
|
|
128
|
+
$function$
|
|
129
|
+
$ddl$, data_schema);
|
|
130
|
+
END
|
|
131
|
+
$privileged_functions$;
|
|
132
|
+
|
|
133
|
+
RESET statement_timeout;
|
|
134
|
+
RESET lock_timeout;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/db",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "OpenGeni persistence: Drizzle schema, RLS-scoped query layer, the SQL migration runner, and role provisioning.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@opengeni/codex": "^0.2.9",
|
|
54
|
-
"@opengeni/config": "^0.
|
|
55
|
-
"@opengeni/contracts": "^0.
|
|
54
|
+
"@opengeni/config": "^0.9.1",
|
|
55
|
+
"@opengeni/contracts": "^0.28.1",
|
|
56
56
|
"@opengeni/network": "^0.1.1",
|
|
57
57
|
"drizzle-orm": "^0.45.2",
|
|
58
58
|
"postgres": "^3.4.7"
|