@consiliency/agent-board-schema 1.2.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/LICENSE +202 -0
- package/NOTICE +11 -0
- package/README.md +55 -0
- package/bin/agent-board-schema.js +97 -0
- package/fixtures/already-applied.json +181 -0
- package/fixtures/divergent-history.json +173 -0
- package/fixtures/production-history.json +173 -0
- package/migrations/20260501000001_agent_board_schema_version.sql +12 -0
- package/migrations/20260502000000_agent_board_schema.sql +180 -0
- package/migrations/20260503000000_agent_board_rpcs.sql +422 -0
- package/migrations/20260503000001_agent_board_coordination_rpcs.sql +229 -0
- package/migrations/20260504000000_agent_board_read_models.sql +206 -0
- package/migrations/20260505000000_agent_board_inbox_schema.sql +341 -0
- package/migrations/20260506000000_agent_board_inbox_delivery_rpcs.sql +1200 -0
- package/migrations/20260506000001_agent_board_inbox_callback_rpcs.sql +330 -0
- package/migrations/20260507000000_agent_board_inbox_reads.sql +334 -0
- package/migrations/20260508000000_agent_board_callback_runtime.sql +453 -0
- package/migrations/20260508000001_agent_board_inbox_service_role_reads.sql +10 -0
- package/migrations/20260510000000_agent_board_dblint_repairs.sql +413 -0
- package/migrations/20260511000000_agent_board_auth_schema.sql +146 -0
- package/migrations/20260511000001_agent_board_auth_credentials.sql +39 -0
- package/migrations/20260512000000_agent_board_auth_provisioning_rpcs.sql +622 -0
- package/migrations/20260512000001_agent_board_auth_v1_rpcs.sql +798 -0
- package/migrations/20260512000002_agent_board_auth_v2_rpcs.sql +1243 -0
- package/migrations/20260512000003_agent_board_auth_rls.sql +484 -0
- package/migrations/20260513000000_agent_board_backup_ops.sql +34 -0
- package/migrations/20260513000001_agent_board_retention.sql +160 -0
- package/migrations/20260513000002_agent_board_monitoring_views.sql +227 -0
- package/migrations/20260514000000_agent_board_auth_rls_id_qualification.sql +150 -0
- package/migrations/20260515000000_agent_board_boardopt.sql +493 -0
- package/migrations/20260516000000_agent_board_callbackcap.sql +113 -0
- package/migrations/20260517000000_agent_board_addressing.sql +542 -0
- package/migrations/20260628000000_agent_board_signing_store.sql +174 -0
- package/migrations/20260628000001_agent_board_signing_proof_rpcs.sql +215 -0
- package/migrations/20260628000002_agent_board_signature_rls_reads.sql +300 -0
- package/migrations/20260628000003_agent_board_signed_write_gateway.sql +288 -0
- package/migrations/20260628000004_agent_board_fleet_registry.sql +411 -0
- package/migrations/20260628000005_agent_board_fleet_policy.sql +509 -0
- package/migrations/20260628000006_agent_board_fleet_read_models.sql +170 -0
- package/migrations/20260629000100_agent_board_fleet_registry_repair.sql +411 -0
- package/migrations/20260629000101_agent_board_fleet_policy_refresh.sql +509 -0
- package/migrations/20260629000102_agent_board_fleet_read_models_refresh.sql +170 -0
- package/migrations/20260630000100_agent_board_harness_kind_open_vocab.sql +15 -0
- package/migrations/20260710000000_agent_board_authbound_boundary.sql +155 -0
- package/migrations/20260710000100_agent_board_schema_version_rpc.sql +14 -0
- package/migrations/20260710000400_agent_board_nonfleet_identity.sql +87 -0
- package/migrations/20260710000401_agent_board_workload_providers.sql +39 -0
- package/migrations/20260711000000_agent_board_provision_system_fail_closed.sql +242 -0
- package/migrations/20260711000100_canary_signed_fleet_enforcement.sql +234 -0
- package/migrations/20260712000000_agent_board_bundle_endpoint_compat.sql +97 -0
- package/migrations/20260713000000_agent_board_rls_reassert_board_scoping.sql +90 -0
- package/package.json +42 -0
- package/provenance.json +580 -0
- package/schema-manifest.json +458 -0
- package/src/check.js +23 -0
- package/src/index.js +50 -0
- package/src/materialize.js +73 -0
- package/src/plan.js +44 -0
- package/src/tooling.test.mjs +97 -0
- package/tests/agent_board_addressing.test.sql +166 -0
- package/tests/agent_board_auth_rls.test.sql +243 -0
- package/tests/agent_board_auth_rls_id_qualification.test.sql +225 -0
- package/tests/agent_board_auth_rpcs.test.sql +311 -0
- package/tests/agent_board_auth_schema.test.sql +411 -0
- package/tests/agent_board_authbound_boundary.test.sql +148 -0
- package/tests/agent_board_boardopt.test.sql +170 -0
- package/tests/agent_board_bundle_endpoint_compat.test.sql +49 -0
- package/tests/agent_board_callback_runtime.test.sql +425 -0
- package/tests/agent_board_callbackcap.test.sql +222 -0
- package/tests/agent_board_canary_signed_fleet_enforcement.test.sql +60 -0
- package/tests/agent_board_dblint_rpcs.test.sql +247 -0
- package/tests/agent_board_fleet_policy.test.sql +370 -0
- package/tests/agent_board_fleet_read_models.test.sql +158 -0
- package/tests/agent_board_fleet_registry.test.sql +149 -0
- package/tests/agent_board_inbox_reads.test.sql +471 -0
- package/tests/agent_board_inbox_rpcs.test.sql +452 -0
- package/tests/agent_board_inbox_schema.test.sql +355 -0
- package/tests/agent_board_nonfleet_identity.test.sql +26 -0
- package/tests/agent_board_rls_reassert_board_scoping.test.sql +39 -0
- package/tests/agent_board_schema_version.test.sql +24 -0
- package/tests/agent_board_schema_version_rpc.test.sql +40 -0
- package/tests/agent_board_signature_rls_reads.test.sql +133 -0
- package/tests/agent_board_signed_write_gateway.test.sql +219 -0
- package/tests/agent_board_signing_proof_rpcs.test.sql +143 -0
- package/tests/agent_board_signing_store.test.sql +183 -0
- package/tests/agent_board_smoke.test.sql +12 -0
- package/tests/agent_board_v1_invariants.test.sql +298 -0
- package/tests/agent_board_v2_invariants.test.sql +753 -0
- package/tests/agent_board_workload_providers.test.sql +15 -0
- package/tests/fixtures/adopter-base.sql +19 -0
- package/tests/fixtures/operator-hardening.sql +27 -0
- package/tests/fixtures/test-prereqs.sql +84 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
create or replace function agent_board._addressing_descriptors_array(p_descriptors jsonb)
|
|
2
|
+
returns jsonb
|
|
3
|
+
language sql
|
|
4
|
+
immutable
|
|
5
|
+
set search_path = ''
|
|
6
|
+
as $$
|
|
7
|
+
select case
|
|
8
|
+
when p_descriptors is null then '[]'::jsonb
|
|
9
|
+
when jsonb_typeof(p_descriptors) = 'array' then p_descriptors
|
|
10
|
+
else jsonb_build_array(p_descriptors)
|
|
11
|
+
end;
|
|
12
|
+
$$;
|
|
13
|
+
|
|
14
|
+
create or replace function agent_board._resolve_addressing_recipient_rows(
|
|
15
|
+
p_actor_agent_id uuid,
|
|
16
|
+
p_recipient_descriptors jsonb
|
|
17
|
+
)
|
|
18
|
+
returns table(
|
|
19
|
+
ordinal integer,
|
|
20
|
+
recipient_agent_id uuid,
|
|
21
|
+
handle text,
|
|
22
|
+
display_name text,
|
|
23
|
+
descriptor jsonb,
|
|
24
|
+
warning text,
|
|
25
|
+
denied_reason text
|
|
26
|
+
)
|
|
27
|
+
language plpgsql
|
|
28
|
+
security definer
|
|
29
|
+
set search_path = agent_board, public
|
|
30
|
+
as $$
|
|
31
|
+
declare
|
|
32
|
+
v_descriptor jsonb;
|
|
33
|
+
v_kind text;
|
|
34
|
+
v_index integer := 0;
|
|
35
|
+
v_match_count integer;
|
|
36
|
+
v_group_alias text;
|
|
37
|
+
v_role text;
|
|
38
|
+
begin
|
|
39
|
+
for v_descriptor in
|
|
40
|
+
select value
|
|
41
|
+
from jsonb_array_elements(agent_board._addressing_descriptors_array(p_recipient_descriptors))
|
|
42
|
+
loop
|
|
43
|
+
v_index := v_index + 1;
|
|
44
|
+
v_kind := v_descriptor ->> 'kind';
|
|
45
|
+
|
|
46
|
+
if v_kind = 'explicit_set' then
|
|
47
|
+
return query
|
|
48
|
+
select v_index * 100000 + nested.ordinal,
|
|
49
|
+
nested.recipient_agent_id,
|
|
50
|
+
nested.handle,
|
|
51
|
+
nested.display_name,
|
|
52
|
+
nested.descriptor,
|
|
53
|
+
nested.warning,
|
|
54
|
+
nested.denied_reason
|
|
55
|
+
from agent_board._resolve_addressing_recipient_rows(
|
|
56
|
+
p_actor_agent_id,
|
|
57
|
+
coalesce(v_descriptor -> 'recipients', '[]'::jsonb)
|
|
58
|
+
) nested;
|
|
59
|
+
elsif v_kind = 'agent_id' then
|
|
60
|
+
select count(*) into v_match_count
|
|
61
|
+
from agent_board.agents a
|
|
62
|
+
where a.id = (v_descriptor ->> 'agentId')::uuid
|
|
63
|
+
and a.status = 'active';
|
|
64
|
+
|
|
65
|
+
if v_match_count = 1 then
|
|
66
|
+
return query
|
|
67
|
+
select v_index, a.id, a.handle, a.display_name, v_descriptor, null::text, null::text
|
|
68
|
+
from agent_board.agents a
|
|
69
|
+
where a.id = (v_descriptor ->> 'agentId')::uuid
|
|
70
|
+
and a.status = 'active';
|
|
71
|
+
else
|
|
72
|
+
return query select v_index, null::uuid, null::text, null::text, v_descriptor, null::text, 'unknown agent_id'::text;
|
|
73
|
+
end if;
|
|
74
|
+
elsif v_kind in ('agent_handle', 'human_handle') then
|
|
75
|
+
select count(*) into v_match_count
|
|
76
|
+
from agent_board.agents a
|
|
77
|
+
where a.handle = v_descriptor ->> 'handle'
|
|
78
|
+
and a.status = 'active'
|
|
79
|
+
and (
|
|
80
|
+
(v_kind = 'agent_handle' and a.agent_type <> 'human')
|
|
81
|
+
or (v_kind = 'human_handle' and a.agent_type = 'human')
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if v_match_count = 1 then
|
|
85
|
+
return query
|
|
86
|
+
select v_index, a.id, a.handle, a.display_name, v_descriptor, null::text, null::text
|
|
87
|
+
from agent_board.agents a
|
|
88
|
+
where a.handle = v_descriptor ->> 'handle'
|
|
89
|
+
and a.status = 'active'
|
|
90
|
+
and (
|
|
91
|
+
(v_kind = 'agent_handle' and a.agent_type <> 'human')
|
|
92
|
+
or (v_kind = 'human_handle' and a.agent_type = 'human')
|
|
93
|
+
);
|
|
94
|
+
elsif v_match_count = 0 then
|
|
95
|
+
return query select v_index, null::uuid, null::text, null::text, v_descriptor, null::text, 'unknown handle'::text;
|
|
96
|
+
else
|
|
97
|
+
return query select v_index, null::uuid, null::text, null::text, v_descriptor, null::text, 'ambiguous handle'::text;
|
|
98
|
+
end if;
|
|
99
|
+
elsif v_kind = 'group_alias' then
|
|
100
|
+
v_group_alias := nullif(trim(v_descriptor ->> 'groupAlias'), '');
|
|
101
|
+
return query
|
|
102
|
+
select v_index,
|
|
103
|
+
a.id,
|
|
104
|
+
a.handle,
|
|
105
|
+
a.display_name,
|
|
106
|
+
v_descriptor,
|
|
107
|
+
null::text,
|
|
108
|
+
null::text
|
|
109
|
+
from agent_board.agents a
|
|
110
|
+
where a.status = 'active'
|
|
111
|
+
and (
|
|
112
|
+
a.metadata ->> 'groupAlias' = v_group_alias
|
|
113
|
+
or a.metadata ->> 'group_alias' = v_group_alias
|
|
114
|
+
or coalesce(a.metadata -> 'groupAliases', '[]'::jsonb) ? v_group_alias
|
|
115
|
+
or coalesce(a.metadata -> 'group_aliases', '[]'::jsonb) ? v_group_alias
|
|
116
|
+
)
|
|
117
|
+
order by a.handle, a.id;
|
|
118
|
+
|
|
119
|
+
if not found then
|
|
120
|
+
return query select v_index, null::uuid, null::text, null::text, v_descriptor, null::text, 'unknown group_alias'::text;
|
|
121
|
+
end if;
|
|
122
|
+
elsif v_kind = 'role_selector' then
|
|
123
|
+
v_role := nullif(trim(v_descriptor ->> 'role'), '');
|
|
124
|
+
return query
|
|
125
|
+
select v_index,
|
|
126
|
+
a.id,
|
|
127
|
+
a.handle,
|
|
128
|
+
a.display_name,
|
|
129
|
+
v_descriptor,
|
|
130
|
+
null::text,
|
|
131
|
+
null::text
|
|
132
|
+
from agent_board.agents a
|
|
133
|
+
where a.status = 'active'
|
|
134
|
+
and (
|
|
135
|
+
a.agent_type = v_role
|
|
136
|
+
or a.kind::text = v_role
|
|
137
|
+
or a.metadata ->> 'role' = v_role
|
|
138
|
+
or coalesce(a.metadata -> 'roles', '[]'::jsonb) ? v_role
|
|
139
|
+
or coalesce(a.metadata -> 'scopes', '[]'::jsonb) ? v_role
|
|
140
|
+
)
|
|
141
|
+
order by a.handle, a.id;
|
|
142
|
+
|
|
143
|
+
if not found then
|
|
144
|
+
return query select v_index, null::uuid, null::text, null::text, v_descriptor, null::text, 'unknown role_selector'::text;
|
|
145
|
+
end if;
|
|
146
|
+
else
|
|
147
|
+
return query select v_index, null::uuid, null::text, null::text, v_descriptor, null::text, 'unsupported descriptor kind'::text;
|
|
148
|
+
end if;
|
|
149
|
+
end loop;
|
|
150
|
+
end;
|
|
151
|
+
$$;
|
|
152
|
+
|
|
153
|
+
create or replace function agent_board.resolve_recipients(
|
|
154
|
+
p_actor_agent_id uuid default null,
|
|
155
|
+
p_recipient_descriptors jsonb default '[]'::jsonb
|
|
156
|
+
)
|
|
157
|
+
returns table("resolvedRecipients" jsonb, warnings jsonb, "deniedRecipients" jsonb, "idempotentThreadReuse" boolean)
|
|
158
|
+
language plpgsql
|
|
159
|
+
security definer
|
|
160
|
+
set search_path = agent_board, public
|
|
161
|
+
as $$
|
|
162
|
+
begin
|
|
163
|
+
return query
|
|
164
|
+
with resolved as (
|
|
165
|
+
select *
|
|
166
|
+
from agent_board._resolve_addressing_recipient_rows(p_actor_agent_id, p_recipient_descriptors)
|
|
167
|
+
),
|
|
168
|
+
accepted as (
|
|
169
|
+
select distinct on (recipient_agent_id)
|
|
170
|
+
recipient_agent_id,
|
|
171
|
+
handle,
|
|
172
|
+
display_name,
|
|
173
|
+
descriptor,
|
|
174
|
+
ordinal
|
|
175
|
+
from resolved
|
|
176
|
+
where recipient_agent_id is not null
|
|
177
|
+
order by recipient_agent_id, ordinal
|
|
178
|
+
),
|
|
179
|
+
ordered_accepted as (
|
|
180
|
+
select *
|
|
181
|
+
from accepted
|
|
182
|
+
order by ordinal, handle, recipient_agent_id
|
|
183
|
+
),
|
|
184
|
+
duplicate_count as (
|
|
185
|
+
select greatest(count(*) - count(distinct recipient_agent_id), 0) as collapsed
|
|
186
|
+
from resolved
|
|
187
|
+
where recipient_agent_id is not null
|
|
188
|
+
)
|
|
189
|
+
select coalesce(
|
|
190
|
+
jsonb_agg(
|
|
191
|
+
jsonb_build_object(
|
|
192
|
+
'agentId', ordered_accepted.recipient_agent_id::text,
|
|
193
|
+
'handle', ordered_accepted.handle,
|
|
194
|
+
'displayName', ordered_accepted.display_name,
|
|
195
|
+
'descriptor', ordered_accepted.descriptor
|
|
196
|
+
)
|
|
197
|
+
order by ordered_accepted.ordinal, ordered_accepted.handle, ordered_accepted.recipient_agent_id
|
|
198
|
+
) filter (where ordered_accepted.recipient_agent_id is not null),
|
|
199
|
+
'[]'::jsonb
|
|
200
|
+
) as "resolvedRecipients",
|
|
201
|
+
case
|
|
202
|
+
when (select collapsed from duplicate_count) > 0
|
|
203
|
+
then jsonb_build_array((select collapsed::text || ' duplicate recipient(s) collapsed' from duplicate_count))
|
|
204
|
+
else '[]'::jsonb
|
|
205
|
+
end as warnings,
|
|
206
|
+
coalesce(
|
|
207
|
+
jsonb_agg(
|
|
208
|
+
jsonb_build_object('descriptor', denied.descriptor, 'reason', denied.denied_reason)
|
|
209
|
+
order by denied.ordinal
|
|
210
|
+
) filter (where denied.denied_reason is not null),
|
|
211
|
+
'[]'::jsonb
|
|
212
|
+
) as "deniedRecipients",
|
|
213
|
+
false as "idempotentThreadReuse"
|
|
214
|
+
from ordered_accepted
|
|
215
|
+
full join resolved denied on false;
|
|
216
|
+
end;
|
|
217
|
+
$$;
|
|
218
|
+
|
|
219
|
+
create or replace function agent_board.expand_recipients_dry_run(
|
|
220
|
+
p_actor_agent_id uuid default null,
|
|
221
|
+
p_recipient_descriptors jsonb default '[]'::jsonb,
|
|
222
|
+
p_thread_idempotency_key text default null
|
|
223
|
+
)
|
|
224
|
+
returns table("resolvedRecipients" jsonb, warnings jsonb, "deniedRecipients" jsonb, "idempotentThreadReuse" boolean)
|
|
225
|
+
language plpgsql
|
|
226
|
+
security definer
|
|
227
|
+
set search_path = agent_board, public
|
|
228
|
+
as $$
|
|
229
|
+
begin
|
|
230
|
+
return query
|
|
231
|
+
select r."resolvedRecipients",
|
|
232
|
+
r.warnings,
|
|
233
|
+
r."deniedRecipients",
|
|
234
|
+
exists (
|
|
235
|
+
select 1
|
|
236
|
+
from agent_board.threads t
|
|
237
|
+
where t.created_by_agent_id = coalesce(p_actor_agent_id, agent_board.current_agent_id())
|
|
238
|
+
and t.metadata ->> 'addressingThreadKey' = nullif(trim(p_thread_idempotency_key), '')
|
|
239
|
+
) as "idempotentThreadReuse"
|
|
240
|
+
from agent_board.resolve_recipients(p_actor_agent_id, p_recipient_descriptors) r;
|
|
241
|
+
end;
|
|
242
|
+
$$;
|
|
243
|
+
|
|
244
|
+
create or replace function agent_board.create_or_find_thread(
|
|
245
|
+
p_created_by_agent_id uuid,
|
|
246
|
+
p_subject text,
|
|
247
|
+
p_idempotency_key text,
|
|
248
|
+
p_thread_type text default 'coordination',
|
|
249
|
+
p_metadata jsonb default '{}'::jsonb
|
|
250
|
+
)
|
|
251
|
+
returns table(thread_id uuid, thread_type text, subject text, status text, last_message_sequence bigint, created_at timestamptz, updated_at timestamptz, reused boolean)
|
|
252
|
+
language plpgsql
|
|
253
|
+
security definer
|
|
254
|
+
set search_path = agent_board, public
|
|
255
|
+
as $$
|
|
256
|
+
declare
|
|
257
|
+
v_actor_agent_id uuid;
|
|
258
|
+
v_key text := nullif(trim(p_idempotency_key), '');
|
|
259
|
+
v_thread agent_board.threads%rowtype;
|
|
260
|
+
begin
|
|
261
|
+
v_actor_agent_id := agent_board._resolved_actor_agent_id(p_created_by_agent_id, 'p_created_by_agent_id');
|
|
262
|
+
if nullif(trim(p_subject), '') is null or v_key is null then
|
|
263
|
+
raise exception 'subject and idempotency key are required' using errcode = '22023';
|
|
264
|
+
end if;
|
|
265
|
+
|
|
266
|
+
select *
|
|
267
|
+
into v_thread
|
|
268
|
+
from agent_board.threads t
|
|
269
|
+
where t.created_by_agent_id = v_actor_agent_id
|
|
270
|
+
and t.metadata ->> 'addressingThreadKey' = v_key
|
|
271
|
+
order by t.created_at desc
|
|
272
|
+
limit 1
|
|
273
|
+
for update;
|
|
274
|
+
|
|
275
|
+
if v_thread.id is not null then
|
|
276
|
+
return query select v_thread.id, v_thread.thread_type, v_thread.subject, v_thread.status, v_thread.last_message_sequence, v_thread.created_at, v_thread.updated_at, true;
|
|
277
|
+
return;
|
|
278
|
+
end if;
|
|
279
|
+
|
|
280
|
+
insert into agent_board.threads(thread_type, created_by_agent_id, subject, metadata)
|
|
281
|
+
values (
|
|
282
|
+
coalesce(nullif(trim(p_thread_type), ''), 'coordination'),
|
|
283
|
+
v_actor_agent_id,
|
|
284
|
+
trim(p_subject),
|
|
285
|
+
coalesce(p_metadata, '{}'::jsonb) || jsonb_build_object('addressingThreadKey', v_key)
|
|
286
|
+
)
|
|
287
|
+
returning * into v_thread;
|
|
288
|
+
|
|
289
|
+
return query select v_thread.id, v_thread.thread_type, v_thread.subject, v_thread.status, v_thread.last_message_sequence, v_thread.created_at, v_thread.updated_at, false;
|
|
290
|
+
end;
|
|
291
|
+
$$;
|
|
292
|
+
|
|
293
|
+
create or replace function agent_board._addressing_agent_ids_or_raise(
|
|
294
|
+
p_actor_agent_id uuid,
|
|
295
|
+
p_recipient_descriptors jsonb
|
|
296
|
+
)
|
|
297
|
+
returns uuid[]
|
|
298
|
+
language plpgsql
|
|
299
|
+
security definer
|
|
300
|
+
set search_path = agent_board, public
|
|
301
|
+
as $$
|
|
302
|
+
declare
|
|
303
|
+
v_result record;
|
|
304
|
+
v_ids uuid[];
|
|
305
|
+
begin
|
|
306
|
+
select * into v_result
|
|
307
|
+
from agent_board.resolve_recipients(p_actor_agent_id, p_recipient_descriptors);
|
|
308
|
+
|
|
309
|
+
if jsonb_array_length(v_result."deniedRecipients") > 0 then
|
|
310
|
+
raise exception 'recipient descriptor resolution failed' using errcode = '22023', detail = v_result."deniedRecipients"::text;
|
|
311
|
+
end if;
|
|
312
|
+
|
|
313
|
+
select array_agg((value ->> 'agentId')::uuid)
|
|
314
|
+
into v_ids
|
|
315
|
+
from jsonb_array_elements(v_result."resolvedRecipients") as value;
|
|
316
|
+
|
|
317
|
+
if v_ids is null or cardinality(v_ids) = 0 then
|
|
318
|
+
raise exception 'recipient descriptors resolved no recipients' using errcode = '22023';
|
|
319
|
+
end if;
|
|
320
|
+
|
|
321
|
+
return v_ids;
|
|
322
|
+
end;
|
|
323
|
+
$$;
|
|
324
|
+
|
|
325
|
+
drop function if exists agent_board.send_direct_message(uuid, uuid, jsonb, text, text, text, text, text, jsonb);
|
|
326
|
+
drop function if exists agent_board.send_direct_message(uuid, uuid, jsonb, text, text, text, text, text, text, jsonb);
|
|
327
|
+
|
|
328
|
+
create or replace function agent_board.send_direct_message(
|
|
329
|
+
p_thread_id uuid,
|
|
330
|
+
p_author_agent_id uuid,
|
|
331
|
+
p_recipient_descriptor jsonb,
|
|
332
|
+
p_addressing_mode text,
|
|
333
|
+
p_subject text,
|
|
334
|
+
p_body text,
|
|
335
|
+
p_message_type text,
|
|
336
|
+
p_priority text,
|
|
337
|
+
p_idempotency_key text,
|
|
338
|
+
p_metadata jsonb
|
|
339
|
+
)
|
|
340
|
+
returns table(message_id uuid, delivery_recipient_id uuid, inbox_item_id uuid, callback_outbox_count integer, created_at timestamptz)
|
|
341
|
+
language plpgsql
|
|
342
|
+
security definer
|
|
343
|
+
set search_path = agent_board, public
|
|
344
|
+
as $$
|
|
345
|
+
declare
|
|
346
|
+
v_recipients uuid[];
|
|
347
|
+
begin
|
|
348
|
+
if p_addressing_mode <> 'addressing_v1' then
|
|
349
|
+
raise exception 'invalid addressing mode' using errcode = '22023';
|
|
350
|
+
end if;
|
|
351
|
+
v_recipients := agent_board._addressing_agent_ids_or_raise(p_author_agent_id, jsonb_build_array(p_recipient_descriptor));
|
|
352
|
+
if cardinality(v_recipients) <> 1 then
|
|
353
|
+
raise exception 'direct message requires exactly one recipient' using errcode = '22023';
|
|
354
|
+
end if;
|
|
355
|
+
|
|
356
|
+
return query
|
|
357
|
+
select *
|
|
358
|
+
from agent_board.send_direct_message(
|
|
359
|
+
p_thread_id,
|
|
360
|
+
p_author_agent_id,
|
|
361
|
+
v_recipients[1],
|
|
362
|
+
p_subject,
|
|
363
|
+
p_body,
|
|
364
|
+
p_message_type,
|
|
365
|
+
p_priority,
|
|
366
|
+
p_idempotency_key,
|
|
367
|
+
p_metadata
|
|
368
|
+
);
|
|
369
|
+
end;
|
|
370
|
+
$$;
|
|
371
|
+
|
|
372
|
+
drop function if exists agent_board.send_multicast_message(uuid, uuid, jsonb, text, text, text, text, text, jsonb);
|
|
373
|
+
drop function if exists agent_board.send_multicast_message(uuid, uuid, jsonb, text, text, text, text, text, text, jsonb);
|
|
374
|
+
|
|
375
|
+
create or replace function agent_board.send_multicast_message(
|
|
376
|
+
p_thread_id uuid,
|
|
377
|
+
p_author_agent_id uuid,
|
|
378
|
+
p_recipient_descriptors jsonb,
|
|
379
|
+
p_addressing_mode text,
|
|
380
|
+
p_subject text,
|
|
381
|
+
p_body text,
|
|
382
|
+
p_message_type text,
|
|
383
|
+
p_priority text,
|
|
384
|
+
p_idempotency_key text,
|
|
385
|
+
p_metadata jsonb
|
|
386
|
+
)
|
|
387
|
+
returns table(message_id uuid, delivered_recipient_count integer, inbox_item_count integer, callback_outbox_count integer, created_at timestamptz)
|
|
388
|
+
language plpgsql
|
|
389
|
+
security definer
|
|
390
|
+
set search_path = agent_board, public
|
|
391
|
+
as $$
|
|
392
|
+
begin
|
|
393
|
+
if p_addressing_mode <> 'addressing_v1' then
|
|
394
|
+
raise exception 'invalid addressing mode' using errcode = '22023';
|
|
395
|
+
end if;
|
|
396
|
+
|
|
397
|
+
return query
|
|
398
|
+
select *
|
|
399
|
+
from agent_board.send_multicast_message(
|
|
400
|
+
p_thread_id,
|
|
401
|
+
p_author_agent_id,
|
|
402
|
+
agent_board._addressing_agent_ids_or_raise(p_author_agent_id, p_recipient_descriptors),
|
|
403
|
+
p_subject,
|
|
404
|
+
p_body,
|
|
405
|
+
p_message_type,
|
|
406
|
+
p_priority,
|
|
407
|
+
p_idempotency_key,
|
|
408
|
+
p_metadata
|
|
409
|
+
);
|
|
410
|
+
end;
|
|
411
|
+
$$;
|
|
412
|
+
|
|
413
|
+
drop function if exists agent_board.post_board_message(uuid, uuid, text, text, text, text, text, text, jsonb);
|
|
414
|
+
drop function if exists agent_board.post_board_message(uuid, uuid, text, text, text, text, text, text, text, jsonb);
|
|
415
|
+
|
|
416
|
+
create or replace function agent_board.post_board_message(
|
|
417
|
+
p_thread_id uuid,
|
|
418
|
+
p_author_agent_id uuid,
|
|
419
|
+
p_board_slug text,
|
|
420
|
+
p_addressing_mode text,
|
|
421
|
+
p_subject text,
|
|
422
|
+
p_body text,
|
|
423
|
+
p_message_type text,
|
|
424
|
+
p_priority text,
|
|
425
|
+
p_idempotency_key text,
|
|
426
|
+
p_metadata jsonb
|
|
427
|
+
)
|
|
428
|
+
returns table(message_id uuid, board_id uuid, delivered_recipient_count integer, callback_outbox_count integer, created_at timestamptz)
|
|
429
|
+
language plpgsql
|
|
430
|
+
security definer
|
|
431
|
+
set search_path = agent_board, public
|
|
432
|
+
as $$
|
|
433
|
+
declare
|
|
434
|
+
v_board_id uuid;
|
|
435
|
+
begin
|
|
436
|
+
if p_addressing_mode <> 'addressing_v1' then
|
|
437
|
+
raise exception 'invalid addressing mode' using errcode = '22023';
|
|
438
|
+
end if;
|
|
439
|
+
|
|
440
|
+
select b.id into v_board_id
|
|
441
|
+
from agent_board.boards b
|
|
442
|
+
where b.slug = nullif(trim(p_board_slug), '')
|
|
443
|
+
and b.status = 'active';
|
|
444
|
+
if v_board_id is null then
|
|
445
|
+
raise exception 'board slug not found' using errcode = 'P0002';
|
|
446
|
+
end if;
|
|
447
|
+
|
|
448
|
+
return query
|
|
449
|
+
select *
|
|
450
|
+
from agent_board.post_board_message(
|
|
451
|
+
p_thread_id,
|
|
452
|
+
p_author_agent_id,
|
|
453
|
+
v_board_id,
|
|
454
|
+
p_subject,
|
|
455
|
+
p_body,
|
|
456
|
+
p_message_type,
|
|
457
|
+
p_priority,
|
|
458
|
+
p_idempotency_key,
|
|
459
|
+
p_metadata
|
|
460
|
+
);
|
|
461
|
+
end;
|
|
462
|
+
$$;
|
|
463
|
+
|
|
464
|
+
drop function if exists agent_board.create_tasking_delivery(uuid, uuid, text, text, jsonb, text, text, text, text, jsonb);
|
|
465
|
+
drop function if exists agent_board.create_tasking_delivery(uuid, uuid, text, text, jsonb, text, text, text, text, text, jsonb);
|
|
466
|
+
|
|
467
|
+
create or replace function agent_board.create_tasking_delivery(
|
|
468
|
+
p_thread_id uuid,
|
|
469
|
+
p_created_by_agent_id uuid,
|
|
470
|
+
p_title text,
|
|
471
|
+
p_details text,
|
|
472
|
+
p_recipient_descriptors jsonb,
|
|
473
|
+
p_board_slug text,
|
|
474
|
+
p_addressing_mode text,
|
|
475
|
+
p_priority text,
|
|
476
|
+
p_orchestration_mode text,
|
|
477
|
+
p_idempotency_key text,
|
|
478
|
+
p_metadata jsonb
|
|
479
|
+
)
|
|
480
|
+
returns table(task_id uuid, created_event_id uuid, delivered_recipient_count integer, inbox_item_count integer, callback_outbox_count integer, created_at timestamptz, updated_at timestamptz)
|
|
481
|
+
language plpgsql
|
|
482
|
+
security definer
|
|
483
|
+
set search_path = agent_board, public
|
|
484
|
+
as $$
|
|
485
|
+
declare
|
|
486
|
+
v_recipient_ids uuid[];
|
|
487
|
+
v_board_id uuid;
|
|
488
|
+
begin
|
|
489
|
+
if p_addressing_mode <> 'addressing_v1' then
|
|
490
|
+
raise exception 'invalid addressing mode' using errcode = '22023';
|
|
491
|
+
end if;
|
|
492
|
+
|
|
493
|
+
if p_recipient_descriptors is not null then
|
|
494
|
+
v_recipient_ids := agent_board._addressing_agent_ids_or_raise(p_created_by_agent_id, p_recipient_descriptors);
|
|
495
|
+
end if;
|
|
496
|
+
if nullif(trim(p_board_slug), '') is not null then
|
|
497
|
+
select b.id into v_board_id
|
|
498
|
+
from agent_board.boards b
|
|
499
|
+
where b.slug = trim(p_board_slug)
|
|
500
|
+
and b.status = 'active';
|
|
501
|
+
if v_board_id is null then
|
|
502
|
+
raise exception 'board slug not found' using errcode = 'P0002';
|
|
503
|
+
end if;
|
|
504
|
+
end if;
|
|
505
|
+
|
|
506
|
+
return query
|
|
507
|
+
select result.task_id,
|
|
508
|
+
result.created_event_id,
|
|
509
|
+
result.delivered_recipient_count,
|
|
510
|
+
result.inbox_item_count,
|
|
511
|
+
result.callback_outbox_count,
|
|
512
|
+
result.created_at,
|
|
513
|
+
result.updated_at
|
|
514
|
+
from agent_board.create_tasking_delivery(
|
|
515
|
+
p_thread_id,
|
|
516
|
+
p_created_by_agent_id,
|
|
517
|
+
p_title,
|
|
518
|
+
p_details,
|
|
519
|
+
v_recipient_ids,
|
|
520
|
+
v_board_id,
|
|
521
|
+
p_priority,
|
|
522
|
+
p_orchestration_mode,
|
|
523
|
+
p_idempotency_key,
|
|
524
|
+
p_metadata
|
|
525
|
+
) result;
|
|
526
|
+
end;
|
|
527
|
+
$$;
|
|
528
|
+
|
|
529
|
+
revoke all on function agent_board.resolve_recipients(uuid, jsonb) from public, anon;
|
|
530
|
+
revoke all on function agent_board.expand_recipients_dry_run(uuid, jsonb, text) from public, anon;
|
|
531
|
+
revoke all on function agent_board.create_or_find_thread(uuid, text, text, text, jsonb) from public, anon;
|
|
532
|
+
revoke all on function agent_board.send_direct_message(uuid, uuid, jsonb, text, text, text, text, text, text, jsonb) from public, anon;
|
|
533
|
+
revoke all on function agent_board.send_multicast_message(uuid, uuid, jsonb, text, text, text, text, text, text, jsonb) from public, anon;
|
|
534
|
+
revoke all on function agent_board.post_board_message(uuid, uuid, text, text, text, text, text, text, text, jsonb) from public, anon;
|
|
535
|
+
revoke all on function agent_board.create_tasking_delivery(uuid, uuid, text, text, jsonb, text, text, text, text, text, jsonb) from public, anon;
|
|
536
|
+
grant execute on function agent_board.resolve_recipients(uuid, jsonb) to authenticated, service_role;
|
|
537
|
+
grant execute on function agent_board.expand_recipients_dry_run(uuid, jsonb, text) to authenticated, service_role;
|
|
538
|
+
grant execute on function agent_board.create_or_find_thread(uuid, text, text, text, jsonb) to authenticated, service_role;
|
|
539
|
+
grant execute on function agent_board.send_direct_message(uuid, uuid, jsonb, text, text, text, text, text, text, jsonb) to authenticated, service_role;
|
|
540
|
+
grant execute on function agent_board.send_multicast_message(uuid, uuid, jsonb, text, text, text, text, text, text, jsonb) to authenticated, service_role;
|
|
541
|
+
grant execute on function agent_board.post_board_message(uuid, uuid, text, text, text, text, text, text, text, jsonb) to authenticated, service_role;
|
|
542
|
+
grant execute on function agent_board.create_tasking_delivery(uuid, uuid, text, text, jsonb, text, text, text, text, text, jsonb) to authenticated, service_role;
|