@creatornader/agent-bridge 0.5.2 → 0.6.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +41 -1
  2. package/README.md +34 -31
  3. package/ROADMAP.md +56 -15
  4. package/SECURITY.md +6 -5
  5. package/dist/archive.d.ts +2 -2
  6. package/dist/{bridge-service-CNBKdYXh.d.ts → bridge-service-DjSYfjKt.d.ts} +4 -2
  7. package/dist/{bridge-store-ByJ6CaJk.d.ts → bridge-store-Bi_LCX8e.d.ts} +5 -1
  8. package/dist/bridge.d.ts +9 -37
  9. package/dist/bridge.js +6 -10
  10. package/dist/chunk-23UDQZMT.js +54 -0
  11. package/dist/chunk-23UDQZMT.js.map +1 -0
  12. package/dist/{chunk-AWE3DFZV.js → chunk-4V2PFJEF.js} +11 -4
  13. package/dist/chunk-4V2PFJEF.js.map +1 -0
  14. package/dist/{chunk-E4OWHGUE.js → chunk-62C63PIE.js} +8 -8
  15. package/dist/chunk-62C63PIE.js.map +1 -0
  16. package/dist/{chunk-HUHG7XTB.js → chunk-AIALYLGQ.js} +30 -193
  17. package/dist/chunk-AIALYLGQ.js.map +1 -0
  18. package/dist/{chunk-JUTJRAMA.js → chunk-FGERNG4X.js} +3 -3
  19. package/dist/{chunk-7VJI2MXI.js → chunk-IF5OKPBK.js} +32 -14
  20. package/dist/chunk-IF5OKPBK.js.map +1 -0
  21. package/dist/{chunk-QPC6JHA3.js → chunk-IMJ47WO4.js} +12 -16
  22. package/dist/chunk-IMJ47WO4.js.map +1 -0
  23. package/dist/{chunk-2EVLG3YA.js → chunk-UKFRCP6X.js} +10 -7
  24. package/dist/chunk-UKFRCP6X.js.map +1 -0
  25. package/dist/chunk-WQ4I5XGF.js +242 -0
  26. package/dist/chunk-WQ4I5XGF.js.map +1 -0
  27. package/dist/{chunk-SN7PIVDF.js → chunk-ZUZ7TCIH.js} +13 -1
  28. package/dist/{chunk-SN7PIVDF.js.map → chunk-ZUZ7TCIH.js.map} +1 -1
  29. package/dist/cli.js +41 -34
  30. package/dist/cli.js.map +1 -1
  31. package/dist/client-config.d.ts +1 -1
  32. package/dist/client-config.js +1 -1
  33. package/dist/client-runtime.d.ts +3 -3
  34. package/dist/client-runtime.js +5 -5
  35. package/dist/contracts/generate.js +2 -3
  36. package/dist/contracts/generate.js.map +1 -1
  37. package/dist/dr.d.ts +8 -0
  38. package/dist/dr.js +1 -1
  39. package/dist/{gateway-CW-61lvs.d.ts → gateway-BqmcKam8.d.ts} +2 -2
  40. package/dist/gateway-main.js +3 -3
  41. package/dist/gateway.d.ts +3 -3
  42. package/dist/gateway.js +3 -3
  43. package/dist/index.js +8 -7
  44. package/dist/index.js.map +1 -1
  45. package/dist/{postgres-bridge-store-C9KG9Z69.d.ts → postgres-bridge-store-ChoOuFEY.d.ts} +1 -1
  46. package/dist/server.d.ts +0 -2
  47. package/dist/server.js +8 -7
  48. package/dist/{sqlite-edge-store-CdMIOrho.d.ts → sqlite-edge-store-BAFUeysk.d.ts} +1 -1
  49. package/dist/sqlite.d.ts +7 -3
  50. package/dist/sqlite.js +1 -1
  51. package/docs/architecture-v2.md +22 -14
  52. package/docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md +2 -1
  53. package/docs/decisions/0002-canonical-operation-contract-registry.md +6 -1
  54. package/docs/decisions/0005-retire-direct-supabase-runtime.md +52 -0
  55. package/docs/deployment.md +17 -12
  56. package/docs/ecosystem.md +6 -4
  57. package/docs/troubleshooting.md +15 -0
  58. package/llms.txt +3 -3
  59. package/openapi/agent-bridge-v2.openapi.json +3 -6
  60. package/package.json +3 -3
  61. package/schemas/agent-bridge-v2.capabilities.json +4 -5
  62. package/schemas/agent-bridge-v2.mcp.json +6 -12
  63. package/schemas/agent-bridge-v2.schema.json +12 -24
  64. package/dist/chunk-2EVLG3YA.js.map +0 -1
  65. package/dist/chunk-7VJI2MXI.js.map +0 -1
  66. package/dist/chunk-AWE3DFZV.js.map +0 -1
  67. package/dist/chunk-E4OWHGUE.js.map +0 -1
  68. package/dist/chunk-HUHG7XTB.js.map +0 -1
  69. package/dist/chunk-QPC6JHA3.js.map +0 -1
  70. package/dist/chunk-Z6JP6MYD.js +0 -584
  71. package/dist/chunk-Z6JP6MYD.js.map +0 -1
  72. /package/dist/{chunk-JUTJRAMA.js.map → chunk-FGERNG4X.js.map} +0 -0
@@ -1,584 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- assertIdempotentReplay
4
- } from "./chunk-VOQIDTCJ.js";
5
- import {
6
- ContractResponseError,
7
- PROTOCOL_HEADER,
8
- PROTOCOL_VERSION,
9
- SUPPORTED_PROTOCOL_HEADER,
10
- SUPPORTED_PROTOCOL_VERSIONS,
11
- parseResponse
12
- } from "./chunk-E4OWHGUE.js";
13
- import {
14
- cursorScope,
15
- decodeCursor,
16
- encodeCursor
17
- } from "./chunk-BZLMF5O5.js";
18
-
19
- // src/legacy-compat.ts
20
- function legacyMessageIdFromSequence(value) {
21
- const text = String(value);
22
- if (!/^-?\d+$/.test(text)) throw new Error("legacy message ID must be an integer");
23
- if (typeof value === "number" && !Number.isSafeInteger(value)) {
24
- throw new Error("legacy message ID must be decoded without precision loss");
25
- }
26
- const numeric = BigInt(text);
27
- if (numeric >= 0n && numeric <= 0xffffffffffffn) {
28
- return `00000000-0000-8000-8000-${numeric.toString(16).padStart(12, "0")}`;
29
- }
30
- if (numeric < -0x8000000000000000n || numeric > 0x7fffffffffffffffn) {
31
- throw new Error("legacy message ID exceeds bigint range");
32
- }
33
- const unsigned = numeric < 0 ? numeric + 0x10000000000000000n : numeric;
34
- const encoded = unsigned.toString(16).padStart(16, "0").padStart(18, "0");
35
- return `00000000-0000-8${encoded.slice(0, 3)}-9${encoded.slice(3, 6)}-${encoded.slice(6)}`;
36
- }
37
- function legacySequenceFromMessageId(value) {
38
- const small = value.match(/^00000000-0000-8000-8000-([0-9a-f]{12})$/i);
39
- if (small) return BigInt(`0x${small[1]}`).toString();
40
- const large = value.match(/^00000000-0000-8([0-9a-f]{3})-9([0-9a-f]{3})-([0-9a-f]{12})$/i);
41
- if (!large) return void 0;
42
- const encoded = `${large[1]}${large[2]}${large[3]}`;
43
- if (!encoded.startsWith("00")) return void 0;
44
- const unsigned = BigInt(`0x${encoded.slice(2)}`);
45
- return (unsigned >= 0x8000000000000000n ? unsigned - 0x10000000000000000n : unsigned).toString();
46
- }
47
- function legacyNumericMessageId(value) {
48
- const text = String(value);
49
- return /^-?\d+$/.test(text) ? legacyMessageIdFromSequence(value) : text;
50
- }
51
- function legacyContextMetadata(message) {
52
- const metadata = message.metadata && typeof message.metadata === "object" && !Array.isArray(message.metadata) ? message.metadata : {};
53
- const existingEnvelope = metadata.message_envelope && typeof metadata.message_envelope === "object" && !Array.isArray(metadata.message_envelope) ? metadata.message_envelope : {};
54
- const envelope = {
55
- ...existingEnvelope,
56
- schema: "agent-bridge.message-envelope.v1",
57
- message_id: message.id,
58
- source_agent: message.source,
59
- kind: message.type,
60
- priority: message.priority,
61
- target_agents: message.targets,
62
- payload_mime: message.contentType
63
- };
64
- if (message.project) envelope.project = message.project;
65
- if (message.threadId) envelope.thread_id = message.threadId;
66
- if (message.replyToId) envelope.reply_to_id = message.replyToId;
67
- if (message.correlationId) envelope.correlation_id = message.correlationId;
68
- if (message.causationId) envelope.causation_id = message.causationId;
69
- if (message.data !== void 0) envelope.payload = message.data;
70
- if (message.expiresAt) envelope.expires_at = message.expiresAt;
71
- if (message.atribReceiptId) envelope.atrib_receipt_id = message.atribReceiptId;
72
- if (message.informedBy?.length) envelope.informed_by = message.informedBy;
73
- return { ...metadata, message_envelope: envelope };
74
- }
75
-
76
- // src/legacy-supabase-store.ts
77
- var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
78
- var LegacySupabaseError = class extends Error {
79
- constructor(status, code) {
80
- super(`Legacy Supabase request failed: ${code}`);
81
- this.status = status;
82
- this.code = code;
83
- }
84
- };
85
- function messageId(row) {
86
- const envelopeId = row.metadata?.message_envelope?.message_id;
87
- return typeof envelopeId === "string" && UUID_RE.test(envelopeId) ? envelopeId : legacyMessageIdFromSequence(String(row.id));
88
- }
89
- function isVisible(row, principal, query) {
90
- const envelope = row.metadata?.message_envelope;
91
- const targets = Array.isArray(envelope?.target_agents) ? envelope.target_agents : [];
92
- const inbox = !targets.length || targets.includes(principal.agent);
93
- const sent = row.source === principal.agent;
94
- const mailbox = query.mailbox ?? "inbox";
95
- if (mailbox === "inbox" && !inbox) return false;
96
- if (query.mailbox === "sent" && !sent) return false;
97
- if (query.mailbox === "all" && !inbox && !sent) return false;
98
- if (!["inbox", "sent", "all"].includes(mailbox) && !inbox) return false;
99
- const type = envelope?.kind ?? row.category;
100
- if (query.types?.length && !query.types.includes(type)) return false;
101
- if (query.threadId && envelope?.thread_id !== query.threadId) return false;
102
- const expiresAt = envelope?.expires_at;
103
- if (!query.includeExpired && expiresAt && new Date(expiresAt).getTime() <= Date.now()) return false;
104
- return true;
105
- }
106
- function asMessage(row, principal) {
107
- const envelope = row.metadata?.message_envelope;
108
- return {
109
- id: messageId(row),
110
- sequence: String(row.id),
111
- workspace: principal.workspace,
112
- project: row.project ?? void 0,
113
- source: row.source,
114
- type: envelope?.kind ?? row.category,
115
- content: row.content,
116
- contentType: envelope?.payload_mime ?? "text/plain",
117
- data: envelope?.payload,
118
- targets: envelope?.target_agents ?? [],
119
- threadId: envelope?.thread_id,
120
- replyToId: envelope?.reply_to_id,
121
- correlationId: envelope?.correlation_id,
122
- causationId: envelope?.causation_id,
123
- priority: row.priority ?? "info",
124
- expiresAt: envelope?.expires_at,
125
- idempotencyKey: envelope?.idempotency_key,
126
- atribReceiptId: row.atrib_receipt_id ?? envelope?.atrib_receipt_id,
127
- informedBy: envelope?.informed_by,
128
- metadata: row.metadata,
129
- deliveryPolicy: { mode: "mailbox" },
130
- createdAt: row.created_at
131
- };
132
- }
133
- var LegacySupabaseRestStore = class {
134
- constructor(url, key, fetchImpl = fetch, timeoutMs = 1e4) {
135
- this.url = url;
136
- this.key = key;
137
- this.fetchImpl = fetchImpl;
138
- this.timeoutMs = timeoutMs;
139
- this.legacyIds = /* @__PURE__ */ new Map();
140
- this.initialized = false;
141
- const parsed = new URL(url);
142
- const loopback = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]";
143
- if (parsed.protocol !== "https:" && !(parsed.protocol === "http:" && loopback)) {
144
- throw new Error("Agent Bridge requires HTTPS for non-loopback legacy providers");
145
- }
146
- }
147
- async initialize(options = {}) {
148
- if (options.mode === "passive") return;
149
- if (this.initialized) return;
150
- await this.request("/shared_context?select=id&limit=1");
151
- this.initialized = true;
152
- }
153
- async request(path, init = {}) {
154
- try {
155
- const response = await this.fetchImpl(`${this.url.replace(/\/$/, "")}/rest/v1${path}`, {
156
- ...init,
157
- signal: init.signal ?? AbortSignal.timeout(this.timeoutMs),
158
- headers: {
159
- apikey: this.key,
160
- Authorization: `Bearer ${this.key}`,
161
- "Content-Type": "application/json",
162
- Prefer: "return=representation",
163
- ...init.headers ?? {}
164
- }
165
- });
166
- if (!response.ok) {
167
- throw new LegacySupabaseError(response.status, "provider_error");
168
- }
169
- const text = await response.text();
170
- return text ? JSON.parse(text) : null;
171
- } catch (error) {
172
- if (error instanceof LegacySupabaseError) throw error;
173
- if (error instanceof Error && (error.name === "TimeoutError" || error.name === "AbortError")) {
174
- throw new LegacySupabaseError(504, "request_timeout");
175
- }
176
- throw new LegacySupabaseError(0, "network_error");
177
- }
178
- }
179
- async visibleReceiptIds(entryIds, principal) {
180
- if (!entryIds.length || entryIds.length > 200) {
181
- throw new Error("legacy receipt IDs must contain between 1 and 200 entries");
182
- }
183
- const uniqueIds = [...new Set(entryIds)];
184
- const rows = await this.request(
185
- `/shared_context?select=id,source,metadata&id=in.(${uniqueIds.join(",")})`
186
- );
187
- const visible = new Set(
188
- Array.isArray(rows) ? rows.filter((row) => isVisible(row, principal, { mailbox: "inbox" })).map((row) => String(row.id)) : []
189
- );
190
- return entryIds.filter((entryId) => visible.has(entryId));
191
- }
192
- async insertMessage(input) {
193
- if (input.idempotencyKey) {
194
- throw new Error(
195
- "legacy Supabase mode cannot enforce idempotency keys; migrate to shared mode"
196
- );
197
- }
198
- if (input.deliveryPolicy?.mode === "leased") {
199
- throw Object.assign(new Error("leased delivery policy is not supported in legacy mode"), { code: "delivery_not_supported", status: 400 });
200
- }
201
- const existingMetadata = input.metadata && typeof input.metadata === "object" && !Array.isArray(input.metadata) ? input.metadata : {};
202
- const existingEnvelope = existingMetadata.message_envelope && typeof existingMetadata.message_envelope === "object" ? existingMetadata.message_envelope : {};
203
- const storedMetadata = JSON.parse(JSON.stringify({
204
- ...existingMetadata,
205
- message_envelope: {
206
- ...existingEnvelope,
207
- schema: "agent-bridge.message-envelope.v1",
208
- message_id: input.id,
209
- source_agent: input.source,
210
- kind: input.type,
211
- payload_mime: input.contentType,
212
- payload: input.data,
213
- target_agents: input.targets,
214
- thread_id: input.threadId,
215
- reply_to_id: input.replyToId,
216
- correlation_id: input.correlationId,
217
- causation_id: input.causationId,
218
- expires_at: input.expiresAt,
219
- informed_by: input.informedBy
220
- }
221
- }));
222
- const body = {
223
- source: input.source,
224
- category: input.type,
225
- content: input.content,
226
- priority: input.priority,
227
- project: input.project ?? null,
228
- metadata: storedMetadata,
229
- atrib_receipt_id: input.atribReceiptId
230
- };
231
- const lookup = encodeURIComponent(
232
- JSON.stringify({ message_envelope: { message_id: input.id } })
233
- );
234
- const existing = await this.request(
235
- `/shared_context?metadata=cs.${lookup}&order=id.asc&limit=1`
236
- );
237
- if (existing[0]) {
238
- const message = asMessage(existing[0], { workspace: input.workspace, agent: input.source });
239
- assertIdempotentReplay(message, { ...input, metadata: storedMetadata });
240
- this.legacyIds.set(message.id, String(existing[0].id));
241
- return { created: false, message };
242
- }
243
- const rows = await this.request("/shared_context", {
244
- method: "POST",
245
- body: JSON.stringify(body)
246
- });
247
- const row = rows[0];
248
- this.legacyIds.set(input.id, String(row.id));
249
- return {
250
- created: true,
251
- message: { ...input, sequence: String(row.id), createdAt: row.created_at }
252
- };
253
- }
254
- async listMessages(principal, query = {}) {
255
- const limit = query.limit ?? 50;
256
- const scope = cursorScope(principal, query);
257
- let after = decodeCursor(query.cursor, scope) ?? "0";
258
- let before;
259
- let latestCursor;
260
- const messages = [];
261
- while (messages.length < limit) {
262
- const batchLimit = Math.min(Math.max(limit * 2, 50), 200);
263
- const workspaceFilter = query.project ? `&project=eq.${encodeURIComponent(query.project)}` : "";
264
- const effectiveSource = query.source ?? (query.mailbox === "sent" ? principal.agent : void 0);
265
- const sourceFilter = effectiveSource ? `&source=eq.${encodeURIComponent(effectiveSource)}` : "";
266
- const sinceFilter = query.since ? `&created_at=gte.${encodeURIComponent(query.since)}` : "";
267
- const receiptFilter = query.receiptState === "unread" ? `&acked_by=not.cs.%7B${encodeURIComponent(principal.agent)}%7D` : query.receiptState === "read" ? `&acked_by=cs.%7B${encodeURIComponent(principal.agent)}%7D` : "";
268
- const cursorFilter = query.latest ? before ? `&id=lt.${encodeURIComponent(before)}` : "" : `&id=gt.${encodeURIComponent(after)}`;
269
- const rows = await this.request(
270
- `/shared_context?select=*${cursorFilter}${workspaceFilter}${sourceFilter}${sinceFilter}${receiptFilter}&order=id.${query.latest ? "desc" : "asc"}&limit=${batchLimit}`
271
- );
272
- if (!rows.length) break;
273
- if (query.latest && latestCursor === void 0) latestCursor = String(rows[0].id);
274
- for (const row of rows) {
275
- after = String(row.id);
276
- const id = messageId(row);
277
- this.legacyIds.set(id, after);
278
- if (isVisible(row, principal, query)) messages.push(asMessage(row, principal));
279
- if (messages.length === limit) break;
280
- }
281
- if (query.latest) before = String(rows[rows.length - 1].id);
282
- if (rows.length < batchLimit || messages.length === limit) break;
283
- }
284
- const next = query.latest ? latestCursor : after === "0" ? void 0 : after;
285
- return { messages, cursor: next ? encodeCursor(next, scope) : query.cursor };
286
- }
287
- async recordReceipt(principal, ids) {
288
- if (!ids.length || ids.length > 200) {
289
- throw new Error("message IDs must contain between 1 and 200 entries");
290
- }
291
- const entryIds = await Promise.all(ids.map(async (id) => {
292
- const mapped = this.legacyIds.get(id);
293
- if (mapped) return mapped;
294
- const lookup = encodeURIComponent(JSON.stringify({ message_envelope: { message_id: id } }));
295
- const rows = await this.request(`/shared_context?select=id,metadata&metadata=cs.${lookup}&limit=2`);
296
- if (Array.isArray(rows) && rows.length === 1) {
297
- const sequence = String(rows[0].id);
298
- this.legacyIds.set(id, sequence);
299
- return sequence;
300
- }
301
- if (Array.isArray(rows) && rows.length > 1) {
302
- throw new LegacySupabaseError(409, "ambiguous_message_id");
303
- }
304
- const decodedSequence = legacySequenceFromMessageId(id);
305
- if (decodedSequence !== void 0) return decodedSequence;
306
- throw new LegacySupabaseError(404, "message_not_found");
307
- }));
308
- const visibleIds = await this.visibleReceiptIds(entryIds, principal);
309
- if (!visibleIds.length) return 0;
310
- return this.request("/rpc/ack_context", {
311
- method: "POST",
312
- body: JSON.stringify({ entry_ids: visibleIds, agent_name: principal.agent })
313
- });
314
- }
315
- async recordLegacyReceipt(ids, principal) {
316
- if (!ids.length || ids.length > 200) {
317
- throw new Error("legacy receipt IDs must contain between 1 and 200 entries");
318
- }
319
- const entryIds = ids.map((id) => {
320
- if (!/^\d+$/.test(id)) throw new Error("legacy receipt IDs must be numeric");
321
- const value = BigInt(id);
322
- if (value > 0x7fffffffffffffffn) throw new Error("legacy receipt ID exceeds bigint range");
323
- return value.toString();
324
- });
325
- const visibleIds = await this.visibleReceiptIds(entryIds, {
326
- workspace: "*",
327
- agent: principal
328
- });
329
- if (!visibleIds.length) return 0;
330
- return this.request("/rpc/ack_context", {
331
- method: "POST",
332
- body: JSON.stringify({ entry_ids: visibleIds, agent_name: principal })
333
- });
334
- }
335
- async claimDelivery(_principal, _options) {
336
- throw new Error("legacy Supabase adapter does not support deliveries");
337
- }
338
- async renewDelivery(_principal, _deliveryId, _leaseToken, _leaseMs) {
339
- throw new Error("legacy Supabase adapter does not support deliveries");
340
- }
341
- async settleDelivery(_principal, _deliveryId, _leaseToken, _state, _error, _retryPolicy) {
342
- throw new Error("legacy Supabase adapter does not support deliveries");
343
- }
344
- async diagnostics(_principal) {
345
- return { schemaVersion: "legacy-v1", deliverySupported: false, pending: null, claimed: null, retrying: null, dead: null };
346
- }
347
- };
348
-
349
- // src/http-bridge-store.ts
350
- var BridgeHttpError = class extends Error {
351
- constructor(status, code, requestId, details, message = `Agent Bridge request failed: ${code}`) {
352
- super(message);
353
- this.status = status;
354
- this.code = code;
355
- this.requestId = requestId;
356
- this.details = details;
357
- }
358
- };
359
- var HttpBridgeStore = class {
360
- constructor(options) {
361
- this.options = options;
362
- this.closeController = new AbortController();
363
- this.closed = false;
364
- const url = new URL(options.baseUrl);
365
- const loopback = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
366
- if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback) && !options.allowInsecureRemoteHttp) {
367
- throw new Error("Agent Bridge requires HTTPS for non-loopback gateways");
368
- }
369
- this.fetchImpl = options.fetch ?? fetch;
370
- }
371
- async initialize(options = {}) {
372
- if (options.mode === "passive") return;
373
- await this.request(void 0, "/readyz", { authenticated: false, signal: options.signal });
374
- const status = await this.request("status", "/v2/status", { signal: options.signal });
375
- this.assertBoundPrincipal(status);
376
- }
377
- assertBoundPrincipal(status) {
378
- const principal = status?.principal;
379
- if (!principal || principal.workspace !== this.options.principal.workspace || principal.agent !== this.options.principal.agent) {
380
- throw new BridgeHttpError(403, "principal_mismatch");
381
- }
382
- }
383
- async request(operationId, path, options = {}) {
384
- if (options.method === "POST" && !options.skipProtocolProbe) await this.ensureProtocol(options.signal);
385
- if (this.closed) throw new BridgeHttpError(0, "store_closed");
386
- if (options.signal?.aborted) throw new BridgeHttpError(0, "request_cancelled");
387
- const requestController = new AbortController();
388
- const abort = () => requestController.abort(this.closeController.signal.reason);
389
- const abortRequest = () => requestController.abort(options.signal?.reason);
390
- this.closeController.signal.addEventListener("abort", abort, { once: true });
391
- options.signal?.addEventListener("abort", abortRequest, { once: true });
392
- let timedOut = false;
393
- const timeout = setTimeout(() => {
394
- timedOut = true;
395
- requestController.abort(new Error("request timeout"));
396
- }, this.options.timeoutMs ?? 1e4);
397
- timeout.unref?.();
398
- try {
399
- const response = await this.fetchImpl(`${this.options.baseUrl.replace(/\/$/, "")}${path}`, {
400
- method: options.method ?? "GET",
401
- signal: requestController.signal,
402
- headers: {
403
- [PROTOCOL_HEADER]: this.selectedProtocolVersion ?? PROTOCOL_VERSION,
404
- ...options.authenticated === false ? {} : { authorization: `Bearer ${this.options.token}` },
405
- ...this.options.principal.instance ? { "x-agent-bridge-instance": this.options.principal.instance } : {},
406
- ...options.body === void 0 ? {} : { "content-type": "application/json" }
407
- },
408
- body: options.body === void 0 ? void 0 : JSON.stringify(options.body)
409
- });
410
- const requestId = response.headers.get("x-request-id") ?? void 0;
411
- const selectedHeader = response.headers.get(PROTOCOL_HEADER);
412
- const supportedHeader = response.headers.get(SUPPORTED_PROTOCOL_HEADER);
413
- const supportedProtocols = supportedHeader?.split(",").map((value) => value.trim()).filter(Boolean) ?? [];
414
- const inconsistentProtocol = selectedHeader === null || supportedHeader === null || !SUPPORTED_PROTOCOL_VERSIONS.includes(selectedHeader) || !supportedProtocols.includes(selectedHeader) || selectedHeader !== PROTOCOL_VERSION;
415
- if (operationId && inconsistentProtocol) {
416
- throw new BridgeHttpError(502, "protocol_mismatch", requestId, {
417
- expected: PROTOCOL_VERSION,
418
- selected: selectedHeader,
419
- supported: supportedHeader
420
- });
421
- }
422
- const contentType = response.headers.get("content-type") ?? "";
423
- const payload = contentType.startsWith("application/json") ? await response.json().catch(() => ({})) : await response.text();
424
- if (!response.ok) {
425
- const envelope = payload && typeof payload === "object" ? payload.error : void 0;
426
- throw new BridgeHttpError(
427
- response.status,
428
- envelope?.code ?? "request_failed",
429
- envelope?.requestId ?? requestId,
430
- envelope?.details ?? envelope,
431
- envelope?.message ?? `Agent Bridge request failed: ${envelope?.code ?? "request_failed"}`
432
- );
433
- }
434
- if (operationId) this.selectedProtocolVersion = PROTOCOL_VERSION;
435
- if (!operationId) return payload;
436
- return parseResponse(operationId, payload);
437
- } catch (error) {
438
- if (error instanceof BridgeHttpError) throw error;
439
- if (error instanceof ContractResponseError) {
440
- throw new BridgeHttpError(error.status, error.code, void 0, {
441
- operation: error.operation,
442
- issues: error.issues
443
- }, error.message);
444
- }
445
- if (this.closed) throw new BridgeHttpError(0, "store_closed");
446
- if (options.signal?.aborted) throw new BridgeHttpError(0, "request_cancelled");
447
- if (timedOut) throw new BridgeHttpError(504, "request_timeout");
448
- if (error instanceof Error && (error.name === "TimeoutError" || error.name === "AbortError")) {
449
- throw new BridgeHttpError(504, "request_timeout");
450
- }
451
- throw new BridgeHttpError(0, "network_error");
452
- } finally {
453
- clearTimeout(timeout);
454
- this.closeController.signal.removeEventListener("abort", abort);
455
- options.signal?.removeEventListener("abort", abortRequest);
456
- }
457
- }
458
- ensureProtocol(signal) {
459
- if (this.selectedProtocolVersion) return Promise.resolve(this.selectedProtocolVersion);
460
- if (!this.protocolProbe) {
461
- this.protocolProbe = this.request("status", "/v2/status", { signal, skipProtocolProbe: true }).then(() => this.selectedProtocolVersion).finally(() => {
462
- this.protocolProbe = void 0;
463
- });
464
- }
465
- return this.protocolProbe;
466
- }
467
- async capabilities() {
468
- return this.request("capabilities", "/v2/capabilities");
469
- }
470
- assertPrincipal(principal, includeInstance = true) {
471
- const expected = this.options.principal;
472
- if (principal.workspace !== expected.workspace || principal.agent !== expected.agent || includeInstance && principal.instance !== expected.instance) {
473
- throw new BridgeHttpError(403, "principal_mismatch");
474
- }
475
- }
476
- async insertMessage(message, options = {}) {
477
- this.assertPrincipal({ workspace: message.workspace, agent: message.source }, false);
478
- await this.ensureProtocol(options.signal);
479
- const { workspace: _workspace, source: _source, ...draft } = message;
480
- return this.request("publish_message", "/v2/messages", { method: "POST", body: draft, signal: options.signal });
481
- }
482
- async listMessages(principal, query = {}, options = {}) {
483
- this.assertPrincipal(principal);
484
- const requestQuery = query;
485
- const params = new URLSearchParams();
486
- if (requestQuery.cursor) params.set("cursor", requestQuery.cursor);
487
- if (requestQuery.mailbox) params.set("mailbox", requestQuery.mailbox);
488
- if (requestQuery.receiptState) params.set("receiptState", requestQuery.receiptState);
489
- if (requestQuery.limit) params.set("limit", String(requestQuery.limit));
490
- if (requestQuery.includeExpired) params.set("includeExpired", "true");
491
- if (requestQuery.source) params.set("source", requestQuery.source);
492
- if (requestQuery.project) params.set("project", requestQuery.project);
493
- if (requestQuery.since) params.set("since", requestQuery.since);
494
- if (requestQuery.threadId) params.set("threadId", requestQuery.threadId);
495
- if (requestQuery.latest) params.set("latest", "true");
496
- for (const type of requestQuery.types ?? []) params.append("type", type);
497
- return this.request("history", `/v2/history${params.size ? `?${params}` : ""}`, { signal: options.signal });
498
- }
499
- async recordReceipt(principal, ids) {
500
- this.assertPrincipal(principal, false);
501
- return (await this.request("record_receipt", "/v2/receipts", { method: "POST", body: { messageIds: ids } })).recorded;
502
- }
503
- async diagnostics(principal) {
504
- this.assertPrincipal(principal);
505
- const status = await this.request("status", "/v2/status");
506
- this.assertBoundPrincipal(status);
507
- return status;
508
- }
509
- async claimDelivery(principal, options) {
510
- this.assertPrincipal(principal);
511
- return (await this.request("claim_delivery", "/v2/deliveries/claim", { method: "POST", body: options }))?.delivery ?? null;
512
- }
513
- async listDeliveries(principal, query = {}) {
514
- this.assertPrincipal(principal);
515
- const params = new URLSearchParams();
516
- if (query.cursor) params.set("cursor", query.cursor);
517
- if (query.limit) params.set("limit", String(query.limit));
518
- if (query.role) params.set("role", query.role);
519
- if (query.messageId) params.set("messageId", query.messageId);
520
- if (query.recipient) params.set("recipient", query.recipient);
521
- for (const state of query.states ?? []) params.append("state", state);
522
- return this.request("list_deliveries", `/v2/deliveries${params.size ? `?${params}` : ""}`);
523
- }
524
- async listDeliveryEvents(principal, id, query = {}) {
525
- this.assertPrincipal(principal);
526
- const params = new URLSearchParams();
527
- if (query.cursor) params.set("cursor", query.cursor);
528
- if (query.limit) params.set("limit", String(query.limit));
529
- return this.request("list_delivery_events", `/v2/deliveries/${id}/events${params.size ? `?${params}` : ""}`);
530
- }
531
- async cancelDelivery(principal, id) {
532
- this.assertPrincipal(principal);
533
- return (await this.request("cancel_delivery", `/v2/deliveries/${id}/cancel`, { method: "POST", body: {} })).delivery;
534
- }
535
- async requeueDelivery(principal, id) {
536
- this.assertPrincipal(principal);
537
- return (await this.request("requeue_delivery", `/v2/deliveries/${id}/requeue`, { method: "POST", body: {} })).delivery;
538
- }
539
- async renewDelivery(principal, id, token, leaseMs) {
540
- this.assertPrincipal(principal);
541
- try {
542
- return (await this.request("extend_delivery", `/v2/deliveries/${id}/extend`, { method: "POST", body: { leaseToken: token, leaseMs } })).delivery;
543
- } catch (error) {
544
- if (error instanceof BridgeHttpError && error.status === 409) return null;
545
- throw error;
546
- }
547
- }
548
- async settleDelivery(principal, id, token, state, error, _retryPolicy) {
549
- this.assertPrincipal(principal);
550
- await this.ensureProtocol();
551
- const action = state === "acked" ? "ack" : "nack";
552
- try {
553
- const operationId = action === "ack" ? "acknowledge_delivery" : "negative_acknowledge_delivery";
554
- const nackBody = { leaseToken: token, error, disposition: state === "dead" ? "dead" : "retry" };
555
- return (await this.request(operationId, `/v2/deliveries/${id}/${action}`, { method: "POST", body: action === "ack" ? { leaseToken: token } : nackBody })).delivery;
556
- } catch (caught) {
557
- if (caught instanceof BridgeHttpError && caught.status === 409) return null;
558
- throw caught;
559
- }
560
- }
561
- async heartbeat(principal, leaseMs, runtimeType, capabilities = []) {
562
- this.assertPrincipal(principal);
563
- return this.request("heartbeat", "/v2/presence/heartbeat", { method: "POST", body: { leaseMs, runtimeType, capabilities } });
564
- }
565
- async listPresence(principal) {
566
- this.assertPrincipal(principal);
567
- return (await this.request("presence", "/v2/presence")).agents;
568
- }
569
- async close() {
570
- if (this.closed) return;
571
- this.closed = true;
572
- this.closeController.abort(new Error("store closed"));
573
- }
574
- };
575
-
576
- export {
577
- legacyNumericMessageId,
578
- legacyContextMetadata,
579
- LegacySupabaseError,
580
- LegacySupabaseRestStore,
581
- BridgeHttpError,
582
- HttpBridgeStore
583
- };
584
- //# sourceMappingURL=chunk-Z6JP6MYD.js.map