@blazingagents/sdk 0.42.1 → 0.43.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/README.md CHANGED
@@ -67,9 +67,10 @@ const sessionId = await chat.sessionId;
67
67
  return chat.toResponse();
68
68
  ```
69
69
 
70
- Keep API keys on the server. For browser chat applications, relay `chat()`
71
- through your backend and use `BlazingAgentsChatTransport` with AI SDK
72
- `useChat`.
70
+ Keep API keys on the server. For browser chat applications, serve
71
+ `createChatRelay` from your backend and use `BlazingAgentsChatTransport` with
72
+ AI SDK `useChat`. The relay runs each request as the signed-in End-user with
73
+ `client.forUser(userId)`.
73
74
 
74
75
  ## Documentation
75
76
 
@@ -74,7 +74,7 @@ const mcpConnectionUrlSchema = z
74
74
  message: "URL must use http(s) without credentials, query, or fragment",
75
75
  })
76
76
  .transform((value) => new URL(value).toString());
77
- const mcpConnectionUrlInputSchema = mcpConnectionUrlSchema.describe("Streamable HTTP URL of the MCP server. Use `http` or `https`, with no credentials, query, or fragment.");
77
+ const mcpConnectionUrlInputSchema = mcpConnectionUrlSchema.describe("Streamable HTTP URL of the MCP server. Use `https`, with no credentials, query, or fragment.");
78
78
  const authTypeDescription = "How Blazing Agents authenticates to the MCP server: `none`, `bearer`, `oauth_client_credentials`, or `oauth_authorization_code`. The other fields you send depend on it.";
79
79
  export const mcpConnectionResponseSchema = z
80
80
  .object({
@@ -129,11 +129,6 @@ export declare const merchantUsageEventStatusSchema: z.ZodEnum<{
129
129
  pending: "pending";
130
130
  }>;
131
131
  export type MerchantUsageEventStatus = z.infer<typeof merchantUsageEventStatusSchema>;
132
- export declare const merchantWorkflowIssueSchema: z.ZodEnum<{
133
- cancelled: "cancelled";
134
- error: "error";
135
- recovery_exhausted: "recovery_exhausted";
136
- }>;
137
132
  export declare const merchantUsageEventNextActionSchema: z.ZodEnum<{
138
133
  discard: "discard";
139
134
  investigate: "investigate";
@@ -186,11 +181,6 @@ export declare const merchantUsageEventSchema: z.ZodObject<{
186
181
  lastAttemptAt: z.ZodNullable<z.ZodISODateTime>;
187
182
  lastErrorCode: z.ZodNullable<z.ZodString>;
188
183
  acceptedAt: z.ZodNullable<z.ZodISODateTime>;
189
- workflowIssue: z.ZodNullable<z.ZodEnum<{
190
- cancelled: "cancelled";
191
- error: "error";
192
- recovery_exhausted: "recovery_exhausted";
193
- }>>;
194
184
  nextAction: z.ZodEnum<{
195
185
  discard: "discard";
196
186
  investigate: "investigate";
@@ -246,11 +236,6 @@ export declare const merchantUsageEventResponseSchema: z.ZodObject<{
246
236
  lastAttemptAt: z.ZodNullable<z.ZodISODateTime>;
247
237
  lastErrorCode: z.ZodNullable<z.ZodString>;
248
238
  acceptedAt: z.ZodNullable<z.ZodISODateTime>;
249
- workflowIssue: z.ZodNullable<z.ZodEnum<{
250
- cancelled: "cancelled";
251
- error: "error";
252
- recovery_exhausted: "recovery_exhausted";
253
- }>>;
254
239
  nextAction: z.ZodEnum<{
255
240
  discard: "discard";
256
241
  investigate: "investigate";
@@ -307,11 +292,6 @@ export declare const merchantUsageEventsResponseSchema: z.ZodObject<{
307
292
  lastAttemptAt: z.ZodNullable<z.ZodISODateTime>;
308
293
  lastErrorCode: z.ZodNullable<z.ZodString>;
309
294
  acceptedAt: z.ZodNullable<z.ZodISODateTime>;
310
- workflowIssue: z.ZodNullable<z.ZodEnum<{
311
- cancelled: "cancelled";
312
- error: "error";
313
- recovery_exhausted: "recovery_exhausted";
314
- }>>;
315
295
  nextAction: z.ZodEnum<{
316
296
  discard: "discard";
317
297
  investigate: "investigate";
@@ -386,10 +366,10 @@ export declare const merchantUsageSummaryResponseSchema: z.ZodObject<{
386
366
  }, z.core.$strip>;
387
367
  export type MerchantUsageSummaryResponse = z.infer<typeof merchantUsageSummaryResponseSchema>;
388
368
  /**
389
- * The operator-facing action derived from event state — computed at the
390
- * service seam, never persisted.
369
+ * The action a Tenant takes on an event. `automaticDeliveryStopped` is true
370
+ * when automatic delivery has given up on a `pending` event.
391
371
  */
392
372
  export declare function merchantUsageEventNextAction(event: {
373
+ automaticDeliveryStopped: boolean;
393
374
  status: MerchantUsageEventStatus;
394
- workflowIssue: z.infer<typeof merchantWorkflowIssueSchema> | null;
395
375
  }): z.infer<typeof merchantUsageEventNextActionSchema>;
@@ -99,11 +99,6 @@ export const merchantUsageEventStatusSchema = z.enum([
99
99
  "discarded",
100
100
  "expired",
101
101
  ]);
102
- export const merchantWorkflowIssueSchema = z.enum([
103
- "error",
104
- "cancelled",
105
- "recovery_exhausted",
106
- ]);
107
102
  export const merchantUsageEventNextActionSchema = z.enum([
108
103
  "none",
109
104
  "wait",
@@ -136,7 +131,6 @@ export const merchantUsageEventSchema = z
136
131
  lastAttemptAt: z.iso.datetime({ offset: true }).nullable(),
137
132
  lastErrorCode: z.string().nullable(),
138
133
  acceptedAt: z.iso.datetime({ offset: true }).nullable(),
139
- workflowIssue: merchantWorkflowIssueSchema.nullable(),
140
134
  nextAction: merchantUsageEventNextActionSchema,
141
135
  })
142
136
  .strip();
@@ -195,8 +189,8 @@ export const merchantUsageSummaryResponseSchema = z
195
189
  .object({ summary: merchantUsageSummarySchema })
196
190
  .strip();
197
191
  /**
198
- * The operator-facing action derived from event state — computed at the
199
- * service seam, never persisted.
192
+ * The action a Tenant takes on an event. `automaticDeliveryStopped` is true
193
+ * when automatic delivery has given up on a `pending` event.
200
194
  */
201
195
  export function merchantUsageEventNextAction(event) {
202
196
  switch (event.status) {
@@ -204,7 +198,7 @@ export function merchantUsageEventNextAction(event) {
204
198
  case "discarded":
205
199
  return "none";
206
200
  case "pending":
207
- return event.workflowIssue === null ? "wait" : "retry";
201
+ return event.automaticDeliveryStopped ? "retry" : "wait";
208
202
  case "failed":
209
203
  return "retry";
210
204
  case "incomplete":
@@ -15,7 +15,7 @@ export type { McpConnectionLiveDetails, McpConnectionTestErrorCode, } from "./en
15
15
  export { createMcpConnectionBodySchema, forwardedMetadataKeysSchema, mcpAttachmentResponseSchema, mcpAttachmentsResponseSchema, mcpConnectionAuthTypeSchema, mcpConnectionLiveDetailsSchema, mcpConnectionReconnectResultSchema, mcpConnectionResponseSchema, mcpConnectionStatusSchema, mcpConnectionsResponseSchema, mcpConnectionTestErrorCodeSchema, mcpConnectionTestResponseSchema, mcpOauthAuthorizationLaunchResponseSchema, reconnectMcpConnectionBodySchema, updateMcpAttachmentBodySchema, updateMcpConnectionBodySchema, } from "./entities/mcp-connections.ts";
16
16
  export type { CreateMemoryBody, Memory, UpdateMemoryBody, } from "./entities/memories.ts";
17
17
  export { createMemoryBodySchema, memoriesListResponseSchema, memoryResponseSchema, memorySchema, memoryTextSchema, updateMemoryBodySchema, } from "./entities/memories.ts";
18
- export { createMerchantConnectionBodySchema, merchantBindingResponseSchema, merchantBindingsResponseSchema, merchantConnectionResponseSchema, merchantConnectionSchema, merchantCustomerBindingSchema, merchantEnvironmentSchema, merchantGuardSchema, merchantProviderSchema, merchantUsageEventNextAction, merchantUsageEventNextActionSchema, merchantUsageEventResponseSchema, merchantUsageEventSchema, merchantUsageEventStatusSchema, merchantUsageEventsResponseSchema, merchantUsageSummaryQuerySchema, merchantUsageSummaryResponseSchema, merchantUsageSummarySchema, merchantWorkflowIssueSchema, updateMerchantConnectionBodySchema, upsertMerchantBindingBodySchema, } from "./entities/merchant.ts";
18
+ export { createMerchantConnectionBodySchema, merchantBindingResponseSchema, merchantBindingsResponseSchema, merchantConnectionResponseSchema, merchantConnectionSchema, merchantCustomerBindingSchema, merchantEnvironmentSchema, merchantGuardSchema, merchantProviderSchema, merchantUsageEventNextAction, merchantUsageEventNextActionSchema, merchantUsageEventResponseSchema, merchantUsageEventSchema, merchantUsageEventStatusSchema, merchantUsageEventsResponseSchema, merchantUsageSummaryQuerySchema, merchantUsageSummaryResponseSchema, merchantUsageSummarySchema, updateMerchantConnectionBodySchema, upsertMerchantBindingBodySchema, } from "./entities/merchant.ts";
19
19
  export { createPromptBodySchema, parsePromptVariables, promptResponseSchema, promptsListQuerySchema, promptsResponseSchema, promptTemplateSchema, renderPromptTemplate, updatePromptBodySchema, } from "./entities/prompts.ts";
20
20
  export { createProviderBodySchema, providerListItemSchema, providerModelsResponseSchema, providerResponseSchema, providersResponseSchema, providerTypeSchema, thinkingLevelsResponseSchema, updateProviderBodySchema, } from "./entities/providers.ts";
21
21
  export type { ChatSteerConsumedEvent, SessionActivity, SessionInput, SessionInputResponse, SessionInputState, SessionInputsQuery, SessionInputsResponse, StopSessionBody, StopSessionResponse, SubmitSessionInputBody, } from "./entities/session-inputs.ts";
@@ -10,7 +10,7 @@ export { blazingAgentsChatMessageMetadataSchema, chatFunctionCallEventSchema, ch
10
10
  export { chatConfigurationSchema, chatConnectionSchema, chatConnectionsResponseSchema, chatCredentialsSchema, chatHealthCheckSchema, chatHealthSchema, chatIdentitySchema, createChatConnectionBodySchema, rotateChatConnectionBodySchema, updateChatConnectionBodySchema, } from "./entities/chat-connections.js";
11
11
  export { createMcpConnectionBodySchema, forwardedMetadataKeysSchema, mcpAttachmentResponseSchema, mcpAttachmentsResponseSchema, mcpConnectionAuthTypeSchema, mcpConnectionLiveDetailsSchema, mcpConnectionReconnectResultSchema, mcpConnectionResponseSchema, mcpConnectionStatusSchema, mcpConnectionsResponseSchema, mcpConnectionTestErrorCodeSchema, mcpConnectionTestResponseSchema, mcpOauthAuthorizationLaunchResponseSchema, reconnectMcpConnectionBodySchema, updateMcpAttachmentBodySchema, updateMcpConnectionBodySchema, } from "./entities/mcp-connections.js";
12
12
  export { createMemoryBodySchema, memoriesListResponseSchema, memoryResponseSchema, memorySchema, memoryTextSchema, updateMemoryBodySchema, } from "./entities/memories.js";
13
- export { createMerchantConnectionBodySchema, merchantBindingResponseSchema, merchantBindingsResponseSchema, merchantConnectionResponseSchema, merchantConnectionSchema, merchantCustomerBindingSchema, merchantEnvironmentSchema, merchantGuardSchema, merchantProviderSchema, merchantUsageEventNextAction, merchantUsageEventNextActionSchema, merchantUsageEventResponseSchema, merchantUsageEventSchema, merchantUsageEventStatusSchema, merchantUsageEventsResponseSchema, merchantUsageSummaryQuerySchema, merchantUsageSummaryResponseSchema, merchantUsageSummarySchema, merchantWorkflowIssueSchema, updateMerchantConnectionBodySchema, upsertMerchantBindingBodySchema, } from "./entities/merchant.js";
13
+ export { createMerchantConnectionBodySchema, merchantBindingResponseSchema, merchantBindingsResponseSchema, merchantConnectionResponseSchema, merchantConnectionSchema, merchantCustomerBindingSchema, merchantEnvironmentSchema, merchantGuardSchema, merchantProviderSchema, merchantUsageEventNextAction, merchantUsageEventNextActionSchema, merchantUsageEventResponseSchema, merchantUsageEventSchema, merchantUsageEventStatusSchema, merchantUsageEventsResponseSchema, merchantUsageSummaryQuerySchema, merchantUsageSummaryResponseSchema, merchantUsageSummarySchema, updateMerchantConnectionBodySchema, upsertMerchantBindingBodySchema, } from "./entities/merchant.js";
14
14
  export { createPromptBodySchema, parsePromptVariables, promptResponseSchema, promptsListQuerySchema, promptsResponseSchema, promptTemplateSchema, renderPromptTemplate, updatePromptBodySchema, } from "./entities/prompts.js";
15
15
  export { createProviderBodySchema, providerListItemSchema, providerModelsResponseSchema, providerResponseSchema, providersResponseSchema, providerTypeSchema, thinkingLevelsResponseSchema, updateProviderBodySchema, } from "./entities/providers.js";
16
16
  export { chatSteerConsumedEventSchema, sessionActivitySchema, sessionInputRequestIdSchema, sessionInputResponseSchema, sessionInputSchema, sessionInputStateSchema, sessionInputsQuerySchema, sessionInputsResponseSchema, stopSessionBodySchema, stopSessionResponseSchema, submitSessionInputBodySchema, } from "./entities/session-inputs.js";
package/dist/index.d.ts CHANGED
@@ -27,7 +27,7 @@ export type { CreateWorkspaceBody, UpdateWorkspaceBody, Workspace, WorkspaceNetw
27
27
  export { BlazingAgentsDirectChatTransport, type BlazingAgentsDirectChatTransportOptions, } from "./direct-chat-transport.ts";
28
28
  export { BlazingAgentsError } from "./errors.ts";
29
29
  export { type ChatFunction, type ChatFunctionContext, type ChatFunctions, defineFunction, } from "./functions.ts";
30
- export { createChatRelay, createCompletionRelay, type RelayContext, type SessionOwnershipStore, } from "./relay.ts";
30
+ export { createChatRelay, createCompletionRelay, type RelayContext, } from "./relay.ts";
31
31
  export type { AgentsListOptions, AgentsResource, UserAgentsResource, } from "./resources/agents.ts";
32
32
  export type { ArtifactsResource } from "./resources/artifacts.ts";
33
33
  export type { ChatConnectionsResource } from "./resources/chat-connections.ts";
package/dist/relay.d.ts CHANGED
@@ -1,29 +1,26 @@
1
- import type { BlazingAgents } from "./client.ts";
2
1
  import type { ChatFunctions } from "./functions.ts";
2
+ import type { UserClient } from "./types.ts";
3
3
  export interface RelayContext {
4
+ /**
5
+ * Agent that serves this request. It must be owned by `userId`, and its
6
+ * Workspace must be owned by the same End-user; otherwise the API answers 404.
7
+ */
4
8
  agentId: string;
5
9
  /** Handlers for this authenticated request and its approved continuation. */
6
10
  functions?: ChatFunctions;
7
11
  metadata?: Record<string, unknown>;
8
- userId: string;
9
- }
10
- export interface SessionOwnershipStore {
11
12
  /**
12
- * Looks up the end user who owns the Session.
13
- * @param sessionId - Session to look up or record.
14
- * @returns The owner ID, or undefined when no owner is recorded.
13
+ * The signed-in End-user. The relay scopes every API request to this
14
+ * End-user with `client.forUser(userId)`, so the API only reaches that
15
+ * End-user's Agents, Sessions, and Workspaces. Follows the `forUser` rules:
16
+ * printable ASCII, at most 256 characters, no surrounding spaces.
15
17
  */
16
- ownerOf(sessionId: string): Promise<string | undefined>;
17
- /**
18
- * Records ownership of a newly created Session.
19
- * @param sessionId - Session to look up or record.
20
- * @param userId - End-user ID for request scope.
21
- * @returns Resolves after ownership is stored.
22
- */
23
- recordOwner(sessionId: string, userId: string): Promise<void>;
18
+ userId: string;
24
19
  }
25
- interface RelayOptions<Method extends keyof BlazingAgents> {
26
- client: Pick<BlazingAgents, Method>;
20
+ interface RelayOptions<Method extends keyof UserClient> {
21
+ client: {
22
+ forUser(userId: string): Pick<UserClient, Method>;
23
+ };
27
24
  /**
28
25
  * Resolves authenticated Agent and end-user context, or null for an unauthenticated request.
29
26
  * @param request - Incoming HTTP request.
@@ -32,18 +29,17 @@ interface RelayOptions<Method extends keyof BlazingAgents> {
32
29
  resolveContext(request: Request): Promise<RelayContext | null>;
33
30
  }
34
31
  /**
35
- * Relays useChat submissions. An assistant message carrying approval
36
- * responses submits the complete round and streams the continuation.
32
+ * Relays useChat submissions as the signed-in End-user. An assistant message
33
+ * carrying approval responses submits the complete round and streams the
34
+ * continuation.
37
35
  * @param options - Configuration for this operation.
38
- * @returns An HTTP handler that checks Session ownership before resuming.
36
+ * @returns An HTTP handler that runs each request through `client.forUser(context.userId)`, so the API answers 404 for a Session outside that End-user's scope.
39
37
  */
40
- export declare function createChatRelay(options: RelayOptions<"chat" | "continueChat"> & {
41
- sessions: SessionOwnershipStore;
42
- }): (request: Request) => Promise<Response>;
38
+ export declare function createChatRelay(options: RelayOptions<"chat" | "continueChat">): (request: Request) => Promise<Response>;
43
39
  /**
44
- * Creates an authenticated HTTP handler that validates prompts and relays text generation.
40
+ * Creates an authenticated HTTP handler that validates prompts and relays text generation as the signed-in End-user.
45
41
  * @param options - Configuration for this operation.
46
- * @returns An HTTP handler that validates prompts and relays text generation.
42
+ * @returns An HTTP handler that runs each request through `client.forUser(context.userId)`.
47
43
  */
48
44
  export declare function createCompletionRelay(options: RelayOptions<"completion">): (request: Request) => Promise<Response>;
49
45
  export {};
package/dist/relay.js CHANGED
@@ -13,10 +13,11 @@ const chatBodySchema = z.object({
13
13
  });
14
14
  const completionBodySchema = z.object({ prompt: z.string().trim().min(1) });
15
15
  /**
16
- * Relays useChat submissions. An assistant message carrying approval
17
- * responses submits the complete round and streams the continuation.
16
+ * Relays useChat submissions as the signed-in End-user. An assistant message
17
+ * carrying approval responses submits the complete round and streams the
18
+ * continuation.
18
19
  * @param options - Configuration for this operation.
19
- * @returns An HTTP handler that checks Session ownership before resuming.
20
+ * @returns An HTTP handler that runs each request through `client.forUser(context.userId)`, so the API answers 404 for a Session outside that End-user's scope.
20
21
  */
21
22
  export function createChatRelay(options) {
22
23
  return async (request) => {
@@ -25,6 +26,7 @@ export function createChatRelay(options) {
25
26
  if (!context) {
26
27
  return errorResponse(401, "unauthorized", "Authentication required.");
27
28
  }
29
+ const client = scopeTo(options.client, context.userId);
28
30
  const body = chatBodySchema.parse(await request.json());
29
31
  const validated = await safeValidateUIMessages({
30
32
  messages: [body.message],
@@ -32,13 +34,9 @@ export function createChatRelay(options) {
32
34
  if (!validated.success) {
33
35
  return errorResponse(400, "invalid_request", "Invalid chat message.");
34
36
  }
35
- if (body.sessionId !== undefined &&
36
- (await options.sessions.ownerOf(body.sessionId)) !== context.userId) {
37
- return errorResponse(403, "forbidden", "Session is not available.");
38
- }
39
37
  const message = validated.data[0];
40
38
  if (message.role === "assistant") {
41
- return await relayApprovalResponses(options.client, {
39
+ return await relayApprovalResponses(client, {
42
40
  agentId: context.agentId,
43
41
  functions: context.functions,
44
42
  message,
@@ -56,9 +54,8 @@ export function createChatRelay(options) {
56
54
  messageId: body.messageId,
57
55
  metadata: context.metadata,
58
56
  abortSignal: request.signal,
59
- userId: context.userId,
60
57
  };
61
- const result = await options.client.chat(body.sessionId === undefined
58
+ const result = await client.chat(body.sessionId === undefined
62
59
  ? {
63
60
  ...chatInput,
64
61
  trigger: "submit-message",
@@ -68,19 +65,6 @@ export function createChatRelay(options) {
68
65
  sessionId: body.sessionId,
69
66
  trigger: body.trigger,
70
67
  });
71
- const sessionId = await result.sessionId;
72
- if (body.sessionId === undefined) {
73
- try {
74
- await options.sessions.recordOwner(sessionId, context.userId);
75
- }
76
- catch (error) {
77
- await result
78
- .toResponse()
79
- .body?.cancel(error)
80
- .catch(() => undefined);
81
- throw error;
82
- }
83
- }
84
68
  return result.toResponse();
85
69
  }
86
70
  catch (error) {
@@ -89,7 +73,7 @@ export function createChatRelay(options) {
89
73
  };
90
74
  }
91
75
  /**
92
- * Validates the Session and forwards the last assistant approval round.
76
+ * Forwards the last assistant approval round to its Session.
93
77
  */
94
78
  async function relayApprovalResponses(client, { functions, message, request, ...input }) {
95
79
  if (input.sessionId === undefined) {
@@ -112,9 +96,9 @@ async function relayApprovalResponses(client, { functions, message, request, ...
112
96
  return continuation.toResponse();
113
97
  }
114
98
  /**
115
- * Creates an authenticated HTTP handler that validates prompts and relays text generation.
99
+ * Creates an authenticated HTTP handler that validates prompts and relays text generation as the signed-in End-user.
116
100
  * @param options - Configuration for this operation.
117
- * @returns An HTTP handler that validates prompts and relays text generation.
101
+ * @returns An HTTP handler that runs each request through `client.forUser(context.userId)`.
118
102
  */
119
103
  export function createCompletionRelay(options) {
120
104
  return async (request) => {
@@ -123,13 +107,13 @@ export function createCompletionRelay(options) {
123
107
  if (!context) {
124
108
  return errorResponse(401, "unauthorized", "Authentication required.");
125
109
  }
110
+ const client = scopeTo(options.client, context.userId);
126
111
  const body = completionBodySchema.parse(await request.json());
127
- const result = await options.client.completion({
112
+ const result = await client.completion({
128
113
  agentId: context.agentId,
129
114
  metadata: context.metadata,
130
115
  prompt: body.prompt,
131
116
  abortSignal: request.signal,
132
- userId: context.userId,
133
117
  });
134
118
  return result.toResponse();
135
119
  }
@@ -138,6 +122,19 @@ export function createCompletionRelay(options) {
138
122
  }
139
123
  };
140
124
  }
125
+ /**
126
+ * Scopes the client to the resolved End-user. An ID that `forUser` rejects is a
127
+ * Tenant resolver bug, not a browser error, so it becomes a plain error that
128
+ * the generic 500 response answers without the validation message.
129
+ */
130
+ function scopeTo(client, userId) {
131
+ try {
132
+ return client.forUser(userId);
133
+ }
134
+ catch (cause) {
135
+ throw new Error("The relay context has an invalid userId.", { cause });
136
+ }
137
+ }
141
138
  /**
142
139
  * Maps validation and SDK failures to safe public error responses.
143
140
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blazingagents/sdk",
3
- "version": "0.42.1",
3
+ "version": "0.43.0",
4
4
  "description": "TypeScript SDK for the Blazing Agents API",
5
5
  "homepage": "https://docs.blazingagents.com",
6
6
  "bugs": {