@agents24/node 0.1.0 → 0.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/dist/bff.js ADDED
@@ -0,0 +1,293 @@
1
+ import { randomUUID } from 'crypto';
2
+
3
+ // src/bff.ts
4
+
5
+ // src/errors.ts
6
+ var Agents24SDKError = class extends Error {
7
+ kind;
8
+ status;
9
+ details;
10
+ responseHeaders;
11
+ constructor(message, options) {
12
+ super(message, { cause: options.cause });
13
+ this.name = "Agents24SDKError";
14
+ this.kind = options.kind;
15
+ this.status = options.status;
16
+ this.details = options.details;
17
+ this.responseHeaders = options.responseHeaders;
18
+ }
19
+ };
20
+
21
+ // src/bff.ts
22
+ var JSON_LIMIT_BYTES = 1048576;
23
+ function normalized(value, field) {
24
+ const result = String(value || "").trim();
25
+ if (!result || /[\r\n\0]/.test(result)) throw new Error(`${field} is required.`);
26
+ return result;
27
+ }
28
+ function normalizeBasePath(value) {
29
+ const path = String(value || "/api/agents24").trim().replace(/\/+$/, "");
30
+ if (!path.startsWith("/") || /[\r\n\0?#]/.test(path)) throw new Error("basePath must be an absolute path.");
31
+ return path;
32
+ }
33
+ function publicError(status, code, message, retryable = false) {
34
+ return Response.json({ code, message, request_id: randomUUID(), retryable }, {
35
+ status,
36
+ headers: { "Cache-Control": "no-store", "Content-Type": "application/json; charset=utf-8" }
37
+ });
38
+ }
39
+ function errorResponse(error) {
40
+ if (error instanceof Agents24SDKError) {
41
+ const status = error.status && error.status >= 400 && error.status <= 599 ? error.status : 502;
42
+ return publicError(status, `UPSTREAM_${status}`, "The Agent request failed.", status >= 500);
43
+ }
44
+ return publicError(500, "BFF_REQUEST_FAILED", "The Agent request could not be completed.", true);
45
+ }
46
+ function mergeHeaders(response, additional) {
47
+ if (!additional) return response;
48
+ const headers = new Headers(response.headers);
49
+ const extras = new Headers(additional);
50
+ for (const [name, value] of extras) headers.append(name, value);
51
+ return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
52
+ }
53
+ function json(value, headers, status = 200) {
54
+ const responseHeaders = new Headers(headers);
55
+ responseHeaders.set("Cache-Control", "no-store");
56
+ responseHeaders.set("Content-Type", "application/json; charset=utf-8");
57
+ return new Response(JSON.stringify(value), { status, headers: responseHeaders });
58
+ }
59
+ async function requestJson(request) {
60
+ const contentLength = Number(request.headers.get("content-length") || 0);
61
+ if (contentLength > JSON_LIMIT_BYTES) throw new BffInputError(413, "REQUEST_TOO_LARGE", "The request body is too large.");
62
+ const value = await request.json().catch(() => null);
63
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
64
+ throw new BffInputError(400, "INVALID_JSON", "A JSON object is required.");
65
+ }
66
+ return value;
67
+ }
68
+ var BffInputError = class extends Error {
69
+ constructor(status, code, message) {
70
+ super(message);
71
+ this.status = status;
72
+ this.code = code;
73
+ }
74
+ status;
75
+ code;
76
+ };
77
+ function stringValue(value) {
78
+ const result = typeof value === "string" ? value.trim() : "";
79
+ return result || void 0;
80
+ }
81
+ function stringList(value) {
82
+ return Array.isArray(value) ? value.map(stringValue).filter((item) => Boolean(item)) : [];
83
+ }
84
+ function objectValue(value) {
85
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
86
+ }
87
+ function routeId(path, pattern, field) {
88
+ const match = pattern.exec(path);
89
+ if (!match?.[1]) throw new BffInputError(404, "NOT_FOUND", "The requested BFF route does not exist.");
90
+ try {
91
+ return normalized(decodeURIComponent(match[1]), field);
92
+ } catch {
93
+ throw new BffInputError(400, "INVALID_PATH", `${field} is invalid.`);
94
+ }
95
+ }
96
+ function sseHeaders(headers) {
97
+ const result = new Headers(headers);
98
+ result.set("Cache-Control", "no-cache, no-transform");
99
+ result.set("Content-Type", "text/event-stream; charset=utf-8");
100
+ result.set("X-Accel-Buffering", "no");
101
+ return result;
102
+ }
103
+ function sseResponse(execute, headers) {
104
+ const stream = new TransformStream();
105
+ const writer = stream.writable.getWriter();
106
+ const encoder = new TextEncoder();
107
+ const write = (value) => writer.write(encoder.encode(`data: ${JSON.stringify(value)}
108
+
109
+ `));
110
+ void execute(write).catch(async (error) => {
111
+ const message = "The Agent stream failed.";
112
+ const event = {
113
+ version: "run-stream.v2",
114
+ seq: Number.MAX_SAFE_INTEGER,
115
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
116
+ event: "run.failed",
117
+ run_id: "bff-stream-error",
118
+ stage: "run",
119
+ payload: { error: message },
120
+ diagnostics: [{ message }]
121
+ };
122
+ await write(event).catch(() => void 0);
123
+ }).finally(() => writer.close().catch(() => void 0));
124
+ return new Response(stream.readable, { headers: sseHeaders(headers) });
125
+ }
126
+ function bootstrapDocument(raw, agentVersionId) {
127
+ const selector = objectValue(raw.model_selector);
128
+ const selectable = Boolean(selector.selectable);
129
+ const resolvedVersionId = stringValue(raw.agent_version_id) || agentVersionId || "";
130
+ const versionNumber = Number(raw.agent_version_number || 0);
131
+ return {
132
+ version: String(raw.version || "agents24.embed.bootstrap.v1"),
133
+ deployment: {
134
+ id: "server-embed",
135
+ name: String(raw.agent_name || "Agents24 Agent"),
136
+ version_policy: agentVersionId ? { mode: "pinned", version_id: agentVersionId } : { mode: "latest_published" },
137
+ resolved_agent_version_id: resolvedVersionId,
138
+ resolved_agent_version_number: Number.isFinite(versionNumber) ? versionNumber : 0,
139
+ policy_epoch: 0
140
+ },
141
+ authentication: { modes: ["server_embed"], access_token_lifetime_seconds: 0, jwks_path: "" },
142
+ capabilities: ["attachments.write", ...selectable ? ["models.select"] : []],
143
+ features: { models: selector },
144
+ native_profiles: []
145
+ };
146
+ }
147
+ function createAgents24BffHandler(options) {
148
+ const agentId = normalized(options.agentId, "agentId");
149
+ const agentVersionId = stringValue(options.agentVersionId);
150
+ const basePath = normalizeBasePath(options.basePath);
151
+ const embed = options.client.embed;
152
+ return async (request) => {
153
+ const url = new URL(request.url);
154
+ if (url.pathname !== basePath && !url.pathname.startsWith(`${basePath}/`)) {
155
+ return publicError(404, "NOT_FOUND", "The requested BFF route does not exist.");
156
+ }
157
+ const path = url.pathname.slice(basePath.length) || "/";
158
+ let resolution;
159
+ try {
160
+ resolution = await options.resolvePrincipal(request);
161
+ resolution.principal.externalUserId = normalized(resolution.principal.externalUserId, "externalUserId");
162
+ } catch {
163
+ return publicError(401, "PRINCIPAL_REQUIRED", "A valid application session is required.");
164
+ }
165
+ const principal = resolution.principal;
166
+ const identity = {
167
+ external_user_id: principal.externalUserId,
168
+ ...principal.externalSessionId ? { external_session_id: principal.externalSessionId } : {}
169
+ };
170
+ const threadIdentity = {
171
+ externalUserId: principal.externalUserId,
172
+ ...principal.externalSessionId ? { externalSessionId: principal.externalSessionId } : {}
173
+ };
174
+ const idempotencyKey = stringValue(request.headers.get("idempotency-key"));
175
+ try {
176
+ let response;
177
+ if (request.method === "GET" && path === "/bootstrap") {
178
+ const raw = await embed.getRuntimeBootstrap(agentId, agentVersionId);
179
+ response = json(bootstrapDocument(raw, agentVersionId));
180
+ } else if (request.method === "POST" && path === "/chat/stream") {
181
+ const body = await requestJson(request);
182
+ const input = stringValue(body.input);
183
+ const attachmentIds = stringList(body.attachmentIds);
184
+ if (!input && attachmentIds.length === 0) throw new BffInputError(400, "INPUT_REQUIRED", "A message or attachment is required.");
185
+ response = sseResponse(async (write) => {
186
+ await embed.streamAgent(agentId, {
187
+ ...identity,
188
+ ...agentVersionId ? { agent_version_id: agentVersionId } : {},
189
+ ...input ? { input } : {},
190
+ attachment_ids: attachmentIds,
191
+ ...stringValue(body.threadId) ? { thread_id: stringValue(body.threadId) } : {},
192
+ ...stringValue(body.requestedModelId) ? { requested_model_id: stringValue(body.requestedModelId) } : {},
193
+ tool_inputs: objectValue(body.toolInputs),
194
+ metadata: objectValue(body.metadata),
195
+ client: objectValue(body.client)
196
+ }, (event) => write(event), { idempotencyKey, signal: request.signal });
197
+ });
198
+ } else if (request.method === "POST" && /^\/runs\/[^/]+\/attach$/.test(path)) {
199
+ const runId = routeId(path, /^\/runs\/([^/]+)\/attach$/, "runId");
200
+ response = sseResponse(async (write) => {
201
+ await embed.attachAgentRun(agentId, runId, identity, (event) => write(event), {
202
+ idempotencyKey,
203
+ signal: request.signal
204
+ });
205
+ });
206
+ } else if (request.method === "POST" && /^\/runs\/[^/]+\/cancel$/.test(path)) {
207
+ const runId = routeId(path, /^\/runs\/([^/]+)\/cancel$/, "runId");
208
+ response = json(await embed.cancelAgentRun(agentId, runId, threadIdentity));
209
+ } else if (request.method === "GET" && path === "/threads") {
210
+ const skip = Number(url.searchParams.get("skip") || 0);
211
+ const limit = Number(url.searchParams.get("limit") || 20);
212
+ response = json(await embed.listAgentThreads(agentId, {
213
+ ...threadIdentity,
214
+ skip: Number.isFinite(skip) ? skip : 0,
215
+ limit: Number.isFinite(limit) ? limit : 20
216
+ }));
217
+ } else if (request.method === "GET" && path === "/threads/events") {
218
+ const cursor = Number(url.searchParams.get("cursor"));
219
+ response = sseResponse(async (write) => {
220
+ await embed.subscribeAgentThreadEvents(agentId, {
221
+ ...threadIdentity,
222
+ ...Number.isFinite(cursor) ? { cursor } : {},
223
+ signal: request.signal
224
+ }, (event) => write(event));
225
+ });
226
+ } else if (/^\/threads\/[^/]+$/.test(path) && request.method === "GET") {
227
+ const threadId = routeId(path, /^\/threads\/([^/]+)$/, "threadId");
228
+ const before = Number(url.searchParams.get("before_turn_index"));
229
+ const limit = Number(url.searchParams.get("limit"));
230
+ response = json(await embed.getAgentThread(agentId, threadId, {
231
+ ...threadIdentity,
232
+ ...Number.isFinite(before) ? { beforeTurnIndex: before } : {},
233
+ ...Number.isFinite(limit) ? { limit } : {},
234
+ includeRunEvents: url.searchParams.get("include_run_events") === "true"
235
+ }));
236
+ } else if (/^\/threads\/[^/]+$/.test(path) && request.method === "DELETE") {
237
+ const threadId = routeId(path, /^\/threads\/([^/]+)$/, "threadId");
238
+ response = json(await embed.deleteAgentThread(agentId, threadId, threadIdentity));
239
+ } else if (request.method === "POST" && path === "/attachments/upload") {
240
+ const form = await request.formData();
241
+ const files = form.getAll("files").filter((entry) => entry instanceof File);
242
+ if (files.length === 0) throw new BffInputError(400, "ATTACHMENT_REQUIRED", "At least one attachment is required.");
243
+ response = json(await embed.uploadAgentAttachments(agentId, {
244
+ ...threadIdentity,
245
+ files,
246
+ ...stringValue(form.get("thread_id")) ? { threadId: stringValue(form.get("thread_id")) } : {},
247
+ idempotencyKey
248
+ }));
249
+ } else if (request.method === "POST" && /^\/runs\/[^/]+\/hitl\/[^/]+\/resume$/.test(path)) {
250
+ const match = /^\/runs\/([^/]+)\/hitl\/([^/]+)\/resume$/.exec(path);
251
+ const runId = routeId(path, /^\/runs\/([^/]+)\/hitl\//, "runId");
252
+ const interruptId = match?.[2] ? decodeURIComponent(match[2]) : "";
253
+ const body = await requestJson(request);
254
+ response = json(await embed.resumeAgentRun(agentId, runId, {
255
+ ...identity,
256
+ schema_version: "agents24.hitl.resume.v2",
257
+ interrupt_id: normalized(interruptId, "interruptId"),
258
+ action: normalized(String(body.action || ""), "action"),
259
+ ...stringValue(body.comment) ? { comment: stringValue(body.comment) } : {}
260
+ }, { idempotencyKey }));
261
+ } else if (request.method === "POST" && /^\/runs\/[^/]+\/mcp\/servers\/[^/]+\/auth\/start$/.test(path)) {
262
+ const match = /^\/runs\/([^/]+)\/mcp\/servers\/([^/]+)\/auth\/start$/.exec(path);
263
+ const runId = match?.[1] ? decodeURIComponent(match[1]) : "";
264
+ const serverId = match?.[2] ? decodeURIComponent(match[2]) : "";
265
+ const body = await requestJson(request);
266
+ const callbackOrigin = new URL(request.url).origin;
267
+ response = json(await embed.startAgentRunMcpAuth(agentId, normalized(runId, "runId"), normalized(serverId, "serverId"), {
268
+ ...identity,
269
+ interrupt_id: normalized(String(body.interruptId || ""), "interruptId"),
270
+ callback_origin: callbackOrigin,
271
+ popup_nonce: normalized(String(body.popupNonce || ""), "popupNonce")
272
+ }, { idempotencyKey }));
273
+ } else if (request.method === "POST" && path === "/mcp/callback/redeem") {
274
+ throw new BffInputError(409, "MCP_CALLBACK_DIRECT", "Server-embed MCP callbacks complete in the authorization popup.");
275
+ } else if (request.method === "POST" && path === "/session/revoke") {
276
+ const headers = await options.revokePrincipal?.(request, principal);
277
+ response = new Response(null, { status: 204, ...headers ? { headers } : {} });
278
+ } else {
279
+ response = publicError(404, "NOT_FOUND", "The requested BFF route does not exist.");
280
+ }
281
+ return mergeHeaders(response, resolution.responseHeaders);
282
+ } catch (error) {
283
+ if (error instanceof BffInputError) {
284
+ return mergeHeaders(publicError(error.status, error.code, error.message), resolution.responseHeaders);
285
+ }
286
+ return mergeHeaders(errorResponse(error), resolution.responseHeaders);
287
+ }
288
+ };
289
+ }
290
+
291
+ export { createAgents24BffHandler };
292
+ //# sourceMappingURL=bff.js.map
293
+ //# sourceMappingURL=bff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/bff.ts"],"names":[],"mappings":"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","file":"bff.js","sourcesContent":["export type Agents24SDKErrorKind = \"protocol\" | \"network\" | \"http\";\nexport type Agents24NodeErrorKind = Agents24SDKErrorKind;\n\nexport class Agents24SDKError extends Error {\n readonly kind: Agents24SDKErrorKind;\n readonly status?: number;\n readonly details?: unknown;\n readonly responseHeaders?: Readonly<Record<string, string>>;\n\n constructor(\n message: string,\n options: {\n kind: Agents24SDKErrorKind;\n status?: number;\n details?: unknown;\n responseHeaders?: Readonly<Record<string, string>>;\n cause?: unknown;\n },\n ) {\n super(message, { cause: options.cause });\n this.name = \"Agents24SDKError\";\n this.kind = options.kind;\n this.status = options.status;\n this.details = options.details;\n this.responseHeaders = options.responseHeaders;\n }\n}\n\nexport { Agents24SDKError as Agents24NodeError };\n","import { randomUUID } from \"node:crypto\";\n\nimport type { Agents24 } from \"./client.js\";\nimport { Agents24SDKError } from \"./errors.js\";\nimport type { RuntimeEvent, ThreadSummaryEvent, ToolInputOverrides } from \"./types.js\";\n\nexport interface AgentBffPrincipal {\n externalUserId: string;\n externalSessionId?: string;\n}\n\nexport interface AgentBffPrincipalResolution {\n principal: AgentBffPrincipal;\n responseHeaders?: HeadersInit;\n}\n\nexport interface Agents24BffHandlerOptions {\n client: Pick<Agents24, \"embed\">;\n agentId: string;\n agentVersionId?: string;\n basePath?: string;\n resolvePrincipal(request: Request): Promise<AgentBffPrincipalResolution> | AgentBffPrincipalResolution;\n revokePrincipal?(\n request: Request,\n principal: AgentBffPrincipal,\n ): Promise<HeadersInit | void> | HeadersInit | void;\n}\n\nexport type Agents24BffHandler = (request: Request) => Promise<Response>;\n\nconst JSON_LIMIT_BYTES = 1_048_576;\n\nfunction normalized(value: string, field: string): string {\n const result = String(value || \"\").trim();\n if (!result || /[\\r\\n\\0]/.test(result)) throw new Error(`${field} is required.`);\n return result;\n}\n\nfunction normalizeBasePath(value: string | undefined): string {\n const path = String(value || \"/api/agents24\").trim().replace(/\\/+$/, \"\");\n if (!path.startsWith(\"/\") || /[\\r\\n\\0?#]/.test(path)) throw new Error(\"basePath must be an absolute path.\");\n return path;\n}\n\nfunction publicError(status: number, code: string, message: string, retryable = false): Response {\n return Response.json({ code, message, request_id: randomUUID(), retryable }, {\n status,\n headers: { \"Cache-Control\": \"no-store\", \"Content-Type\": \"application/json; charset=utf-8\" },\n });\n}\n\nfunction errorResponse(error: unknown): Response {\n if (error instanceof Agents24SDKError) {\n const status = error.status && error.status >= 400 && error.status <= 599 ? error.status : 502;\n return publicError(status, `UPSTREAM_${status}`, \"The Agent request failed.\", status >= 500);\n }\n return publicError(500, \"BFF_REQUEST_FAILED\", \"The Agent request could not be completed.\", true);\n}\n\nfunction mergeHeaders(response: Response, additional: HeadersInit | undefined): Response {\n if (!additional) return response;\n const headers = new Headers(response.headers);\n const extras = new Headers(additional);\n for (const [name, value] of extras) headers.append(name, value);\n return new Response(response.body, { status: response.status, statusText: response.statusText, headers });\n}\n\nfunction json(value: unknown, headers?: HeadersInit, status = 200): Response {\n const responseHeaders = new Headers(headers);\n responseHeaders.set(\"Cache-Control\", \"no-store\");\n responseHeaders.set(\"Content-Type\", \"application/json; charset=utf-8\");\n return new Response(JSON.stringify(value), { status, headers: responseHeaders });\n}\n\nasync function requestJson(request: Request): Promise<Record<string, unknown>> {\n const contentLength = Number(request.headers.get(\"content-length\") || 0);\n if (contentLength > JSON_LIMIT_BYTES) throw new BffInputError(413, \"REQUEST_TOO_LARGE\", \"The request body is too large.\");\n const value = await request.json().catch(() => null);\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new BffInputError(400, \"INVALID_JSON\", \"A JSON object is required.\");\n }\n return value as Record<string, unknown>;\n}\n\nclass BffInputError extends Error {\n constructor(readonly status: number, readonly code: string, message: string) { super(message); }\n}\n\nfunction stringValue(value: unknown): string | undefined {\n const result = typeof value === \"string\" ? value.trim() : \"\";\n return result || undefined;\n}\n\nfunction stringList(value: unknown): string[] {\n return Array.isArray(value) ? value.map(stringValue).filter((item): item is string => Boolean(item)) : [];\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value) ? value as Record<string, unknown> : {};\n}\n\nfunction routeId(path: string, pattern: RegExp, field: string): string {\n const match = pattern.exec(path);\n if (!match?.[1]) throw new BffInputError(404, \"NOT_FOUND\", \"The requested BFF route does not exist.\");\n try { return normalized(decodeURIComponent(match[1]), field); }\n catch { throw new BffInputError(400, \"INVALID_PATH\", `${field} is invalid.`); }\n}\n\nfunction sseHeaders(headers?: HeadersInit): Headers {\n const result = new Headers(headers);\n result.set(\"Cache-Control\", \"no-cache, no-transform\");\n result.set(\"Content-Type\", \"text/event-stream; charset=utf-8\");\n result.set(\"X-Accel-Buffering\", \"no\");\n return result;\n}\n\nfunction sseResponse(\n execute: (write: (value: unknown) => Promise<void>) => Promise<void>,\n headers?: HeadersInit,\n): Response {\n const stream = new TransformStream<Uint8Array, Uint8Array>();\n const writer = stream.writable.getWriter();\n const encoder = new TextEncoder();\n const write = (value: unknown) => writer.write(encoder.encode(`data: ${JSON.stringify(value)}\\n\\n`));\n void execute(write)\n .catch(async (error: unknown) => {\n const message = \"The Agent stream failed.\";\n const event: RuntimeEvent = {\n version: \"run-stream.v2\",\n seq: Number.MAX_SAFE_INTEGER,\n ts: new Date().toISOString(),\n event: \"run.failed\",\n run_id: \"bff-stream-error\",\n stage: \"run\",\n payload: { error: message },\n diagnostics: [{ message }],\n };\n await write(event).catch(() => undefined);\n })\n .finally(() => writer.close().catch(() => undefined));\n return new Response(stream.readable, { headers: sseHeaders(headers) });\n}\n\nfunction bootstrapDocument(raw: Record<string, unknown>, agentVersionId: string | undefined): Record<string, unknown> {\n const selector = objectValue(raw.model_selector);\n const selectable = Boolean(selector.selectable);\n const resolvedVersionId = stringValue(raw.agent_version_id) || agentVersionId || \"\";\n const versionNumber = Number(raw.agent_version_number || 0);\n return {\n version: String(raw.version || \"agents24.embed.bootstrap.v1\"),\n deployment: {\n id: \"server-embed\",\n name: String(raw.agent_name || \"Agents24 Agent\"),\n version_policy: agentVersionId\n ? { mode: \"pinned\", version_id: agentVersionId }\n : { mode: \"latest_published\" },\n resolved_agent_version_id: resolvedVersionId,\n resolved_agent_version_number: Number.isFinite(versionNumber) ? versionNumber : 0,\n policy_epoch: 0,\n },\n authentication: { modes: [\"server_embed\"], access_token_lifetime_seconds: 0, jwks_path: \"\" },\n capabilities: [\"attachments.write\", ...(selectable ? [\"models.select\"] : [])],\n features: { models: selector },\n native_profiles: [],\n };\n}\n\nexport function createAgents24BffHandler(options: Agents24BffHandlerOptions): Agents24BffHandler {\n const agentId = normalized(options.agentId, \"agentId\");\n const agentVersionId = stringValue(options.agentVersionId);\n const basePath = normalizeBasePath(options.basePath);\n const embed = options.client.embed;\n\n return async (request) => {\n const url = new URL(request.url);\n if (url.pathname !== basePath && !url.pathname.startsWith(`${basePath}/`)) {\n return publicError(404, \"NOT_FOUND\", \"The requested BFF route does not exist.\");\n }\n const path = url.pathname.slice(basePath.length) || \"/\";\n let resolution: AgentBffPrincipalResolution;\n try {\n resolution = await options.resolvePrincipal(request);\n resolution.principal.externalUserId = normalized(resolution.principal.externalUserId, \"externalUserId\");\n } catch {\n return publicError(401, \"PRINCIPAL_REQUIRED\", \"A valid application session is required.\");\n }\n const principal = resolution.principal;\n const identity = {\n external_user_id: principal.externalUserId,\n ...(principal.externalSessionId ? { external_session_id: principal.externalSessionId } : {}),\n };\n const threadIdentity = {\n externalUserId: principal.externalUserId,\n ...(principal.externalSessionId ? { externalSessionId: principal.externalSessionId } : {}),\n };\n const idempotencyKey = stringValue(request.headers.get(\"idempotency-key\"));\n\n try {\n let response: Response;\n if (request.method === \"GET\" && path === \"/bootstrap\") {\n const raw = await embed.getRuntimeBootstrap(agentId, agentVersionId) as Record<string, unknown>;\n response = json(bootstrapDocument(raw, agentVersionId));\n } else if (request.method === \"POST\" && path === \"/chat/stream\") {\n const body = await requestJson(request);\n const input = stringValue(body.input);\n const attachmentIds = stringList(body.attachmentIds);\n if (!input && attachmentIds.length === 0) throw new BffInputError(400, \"INPUT_REQUIRED\", \"A message or attachment is required.\");\n response = sseResponse(async (write) => {\n await embed.streamAgent(agentId, {\n ...identity,\n ...(agentVersionId ? { agent_version_id: agentVersionId } : {}),\n ...(input ? { input } : {}),\n attachment_ids: attachmentIds,\n ...(stringValue(body.threadId) ? { thread_id: stringValue(body.threadId) } : {}),\n ...(stringValue(body.requestedModelId) ? { requested_model_id: stringValue(body.requestedModelId) } : {}),\n tool_inputs: objectValue(body.toolInputs) as ToolInputOverrides,\n metadata: objectValue(body.metadata),\n client: objectValue(body.client),\n }, (event) => write(event), { idempotencyKey, signal: request.signal });\n });\n } else if (request.method === \"POST\" && /^\\/runs\\/[^/]+\\/attach$/.test(path)) {\n const runId = routeId(path, /^\\/runs\\/([^/]+)\\/attach$/, \"runId\");\n response = sseResponse(async (write) => {\n await embed.attachAgentRun(agentId, runId, identity, (event) => write(event), {\n idempotencyKey,\n signal: request.signal,\n });\n });\n } else if (request.method === \"POST\" && /^\\/runs\\/[^/]+\\/cancel$/.test(path)) {\n const runId = routeId(path, /^\\/runs\\/([^/]+)\\/cancel$/, \"runId\");\n response = json(await embed.cancelAgentRun(agentId, runId, threadIdentity));\n } else if (request.method === \"GET\" && path === \"/threads\") {\n const skip = Number(url.searchParams.get(\"skip\") || 0);\n const limit = Number(url.searchParams.get(\"limit\") || 20);\n response = json(await embed.listAgentThreads(agentId, {\n ...threadIdentity,\n skip: Number.isFinite(skip) ? skip : 0,\n limit: Number.isFinite(limit) ? limit : 20,\n }));\n } else if (request.method === \"GET\" && path === \"/threads/events\") {\n const cursor = Number(url.searchParams.get(\"cursor\"));\n response = sseResponse(async (write) => {\n await embed.subscribeAgentThreadEvents(agentId, {\n ...threadIdentity,\n ...(Number.isFinite(cursor) ? { cursor } : {}),\n signal: request.signal,\n }, (event: ThreadSummaryEvent) => write(event));\n });\n } else if (/^\\/threads\\/[^/]+$/.test(path) && request.method === \"GET\") {\n const threadId = routeId(path, /^\\/threads\\/([^/]+)$/, \"threadId\");\n const before = Number(url.searchParams.get(\"before_turn_index\"));\n const limit = Number(url.searchParams.get(\"limit\"));\n response = json(await embed.getAgentThread(agentId, threadId, {\n ...threadIdentity,\n ...(Number.isFinite(before) ? { beforeTurnIndex: before } : {}),\n ...(Number.isFinite(limit) ? { limit } : {}),\n includeRunEvents: url.searchParams.get(\"include_run_events\") === \"true\",\n }));\n } else if (/^\\/threads\\/[^/]+$/.test(path) && request.method === \"DELETE\") {\n const threadId = routeId(path, /^\\/threads\\/([^/]+)$/, \"threadId\");\n response = json(await embed.deleteAgentThread(agentId, threadId, threadIdentity));\n } else if (request.method === \"POST\" && path === \"/attachments/upload\") {\n const form = await request.formData();\n const files = form.getAll(\"files\").filter((entry): entry is File => entry instanceof File);\n if (files.length === 0) throw new BffInputError(400, \"ATTACHMENT_REQUIRED\", \"At least one attachment is required.\");\n response = json(await embed.uploadAgentAttachments(agentId, {\n ...threadIdentity,\n files,\n ...(stringValue(form.get(\"thread_id\")) ? { threadId: stringValue(form.get(\"thread_id\")) } : {}),\n idempotencyKey,\n }));\n } else if (request.method === \"POST\" && /^\\/runs\\/[^/]+\\/hitl\\/[^/]+\\/resume$/.test(path)) {\n const match = /^\\/runs\\/([^/]+)\\/hitl\\/([^/]+)\\/resume$/.exec(path);\n const runId = routeId(path, /^\\/runs\\/([^/]+)\\/hitl\\//, \"runId\");\n const interruptId = match?.[2] ? decodeURIComponent(match[2]) : \"\";\n const body = await requestJson(request);\n response = json(await embed.resumeAgentRun(agentId, runId, {\n ...identity,\n schema_version: \"agents24.hitl.resume.v2\",\n interrupt_id: normalized(interruptId, \"interruptId\"),\n action: normalized(String(body.action || \"\"), \"action\") as \"approve\" | \"reject\" | \"connect\" | \"skip\",\n ...(stringValue(body.comment) ? { comment: stringValue(body.comment) } : {}),\n }, { idempotencyKey }));\n } else if (request.method === \"POST\" && /^\\/runs\\/[^/]+\\/mcp\\/servers\\/[^/]+\\/auth\\/start$/.test(path)) {\n const match = /^\\/runs\\/([^/]+)\\/mcp\\/servers\\/([^/]+)\\/auth\\/start$/.exec(path);\n const runId = match?.[1] ? decodeURIComponent(match[1]) : \"\";\n const serverId = match?.[2] ? decodeURIComponent(match[2]) : \"\";\n const body = await requestJson(request);\n const callbackOrigin = new URL(request.url).origin;\n response = json(await embed.startAgentRunMcpAuth(agentId, normalized(runId, \"runId\"), normalized(serverId, \"serverId\"), {\n ...identity,\n interrupt_id: normalized(String(body.interruptId || \"\"), \"interruptId\"),\n callback_origin: callbackOrigin,\n popup_nonce: normalized(String(body.popupNonce || \"\"), \"popupNonce\"),\n }, { idempotencyKey }));\n } else if (request.method === \"POST\" && path === \"/mcp/callback/redeem\") {\n throw new BffInputError(409, \"MCP_CALLBACK_DIRECT\", \"Server-embed MCP callbacks complete in the authorization popup.\");\n } else if (request.method === \"POST\" && path === \"/session/revoke\") {\n const headers = await options.revokePrincipal?.(request, principal);\n response = new Response(null, { status: 204, ...(headers ? { headers } : {}) });\n } else {\n response = publicError(404, \"NOT_FOUND\", \"The requested BFF route does not exist.\");\n }\n return mergeHeaders(response, resolution.responseHeaders);\n } catch (error) {\n if (error instanceof BffInputError) {\n return mergeHeaders(publicError(error.status, error.code, error.message), resolution.responseHeaders);\n }\n return mergeHeaders(errorResponse(error), resolution.responseHeaders);\n }\n };\n}\n"]}