@agent-os-sdk/client 0.3.14 → 0.4.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 (66) hide show
  1. package/dist/client/AgentOsClient.d.ts.map +1 -1
  2. package/dist/client/AgentOsClient.js +4 -5
  3. package/dist/client/config.d.ts +49 -0
  4. package/dist/client/config.d.ts.map +1 -0
  5. package/dist/client/config.js +62 -0
  6. package/dist/client/pagination.d.ts +105 -0
  7. package/dist/client/pagination.d.ts.map +1 -0
  8. package/dist/client/pagination.js +117 -0
  9. package/dist/client/raw.d.ts +65 -0
  10. package/dist/client/raw.d.ts.map +1 -1
  11. package/dist/client/raw.js +78 -17
  12. package/dist/client/retry.d.ts +37 -0
  13. package/dist/client/retry.d.ts.map +1 -0
  14. package/dist/client/retry.js +108 -0
  15. package/dist/client/timeout.d.ts +26 -0
  16. package/dist/client/timeout.d.ts.map +1 -0
  17. package/dist/client/timeout.js +51 -0
  18. package/dist/errors/factory.d.ts +20 -0
  19. package/dist/errors/factory.d.ts.map +1 -0
  20. package/dist/errors/factory.js +97 -0
  21. package/dist/errors/index.d.ts +210 -0
  22. package/dist/errors/index.d.ts.map +1 -0
  23. package/dist/errors/index.js +283 -0
  24. package/dist/index.d.ts +11 -3
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +26 -0
  27. package/dist/modules/audit.d.ts +27 -4
  28. package/dist/modules/audit.d.ts.map +1 -1
  29. package/dist/modules/audit.js +58 -2
  30. package/dist/modules/catalog.d.ts +28 -4
  31. package/dist/modules/catalog.d.ts.map +1 -1
  32. package/dist/modules/catalog.js +15 -1
  33. package/dist/modules/checkpoints.d.ts +1 -1
  34. package/dist/modules/checkpoints.d.ts.map +1 -1
  35. package/dist/modules/info.d.ts +49 -0
  36. package/dist/modules/info.d.ts.map +1 -1
  37. package/dist/modules/info.js +66 -0
  38. package/dist/modules/runs.d.ts +103 -0
  39. package/dist/modules/runs.d.ts.map +1 -1
  40. package/dist/modules/runs.js +258 -0
  41. package/dist/modules/tenants.d.ts +4 -1
  42. package/dist/modules/tenants.d.ts.map +1 -1
  43. package/dist/modules/tenants.js +3 -0
  44. package/dist/modules/threads.d.ts +24 -0
  45. package/dist/modules/threads.d.ts.map +1 -1
  46. package/dist/modules/threads.js +48 -1
  47. package/dist/sse/client.d.ts.map +1 -1
  48. package/dist/sse/client.js +17 -5
  49. package/package.json +1 -1
  50. package/src/client/AgentOsClient.ts +4 -7
  51. package/src/client/config.ts +100 -0
  52. package/src/client/pagination.ts +218 -0
  53. package/src/client/raw.ts +138 -17
  54. package/src/client/retry.ts +150 -0
  55. package/src/client/timeout.ts +59 -0
  56. package/src/errors/factory.ts +135 -0
  57. package/src/errors/index.ts +365 -0
  58. package/src/index.ts +72 -2
  59. package/src/modules/audit.ts +77 -6
  60. package/src/modules/catalog.ts +38 -5
  61. package/src/modules/checkpoints.ts +1 -1
  62. package/src/modules/info.ts +108 -0
  63. package/src/modules/runs.ts +333 -0
  64. package/src/modules/tenants.ts +5 -2
  65. package/src/modules/threads.ts +57 -1
  66. package/src/sse/client.ts +21 -5
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Agent OS SDK - Typed Errors
3
+ *
4
+ * Enterprise-grade error classification for predictable error handling.
5
+ * All errors extend AgentOsError and include semantic information.
6
+ */
7
+
8
+ /**
9
+ * Options for constructing typed errors
10
+ */
11
+ export interface ErrorOptions {
12
+ /** Request ID from x-request-id header */
13
+ requestId?: string;
14
+ /** Original error code from backend (preserves backend semantics) */
15
+ backendCode?: string;
16
+ /** Raw details object from backend response */
17
+ details?: unknown;
18
+ }
19
+
20
+ /**
21
+ * Base class for all Agent OS SDK errors.
22
+ * Provides consistent structure for error handling and classification.
23
+ */
24
+ export abstract class AgentOsError extends Error {
25
+ /** Error code for programmatic handling */
26
+ abstract readonly code: string;
27
+
28
+ /** HTTP status code (0 for network/timeout errors) */
29
+ abstract readonly status: number;
30
+
31
+ /** Request ID from x-request-id header */
32
+ readonly requestId?: string;
33
+
34
+ /** Original error code from backend (preserves backend semantics) */
35
+ readonly backendCode?: string;
36
+
37
+ /** Raw details object from backend response */
38
+ readonly details?: unknown;
39
+
40
+ /** Timestamp when error occurred */
41
+ readonly timestamp: string = new Date().toISOString();
42
+
43
+ constructor(message: string, options?: ErrorOptions) {
44
+ super(message);
45
+ this.name = this.constructor.name;
46
+ this.requestId = options?.requestId;
47
+ this.backendCode = options?.backendCode;
48
+ this.details = options?.details;
49
+
50
+ // Maintains proper stack trace (V8 engines only)
51
+ if ("captureStackTrace" in Error && typeof Error.captureStackTrace === "function") {
52
+ Error.captureStackTrace(this, this.constructor);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Whether this error is retryable with the same request.
58
+ * Override in subclasses for specific behavior.
59
+ */
60
+ isRetryable(): boolean {
61
+ return false;
62
+ }
63
+
64
+ /** Convert to JSON for logging/serialization */
65
+ toJSON(): Record<string, unknown> {
66
+ return {
67
+ name: this.name,
68
+ code: this.code,
69
+ status: this.status,
70
+ message: this.message,
71
+ requestId: this.requestId,
72
+ backendCode: this.backendCode,
73
+ details: this.details,
74
+ timestamp: this.timestamp,
75
+ };
76
+ }
77
+ }
78
+
79
+ // ============================================================================
80
+ // Authentication & Authorization Errors
81
+ // ============================================================================
82
+
83
+ /**
84
+ * 401 Unauthorized - Invalid or missing authentication.
85
+ *
86
+ * @example
87
+ * if (error instanceof UnauthorizedError) {
88
+ * // Redirect to login
89
+ * }
90
+ */
91
+ export class UnauthorizedError extends AgentOsError {
92
+ readonly code = "UNAUTHORIZED";
93
+ readonly status = 401;
94
+
95
+ constructor(message = "Authentication required", options?: ErrorOptions) {
96
+ super(message, options);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * 403 Forbidden - Valid auth but insufficient permissions.
102
+ *
103
+ * @example
104
+ * if (error instanceof ForbiddenError) {
105
+ * showToast("You don't have permission to perform this action");
106
+ * }
107
+ */
108
+ export class ForbiddenError extends AgentOsError {
109
+ readonly code = "FORBIDDEN";
110
+ readonly status = 403;
111
+
112
+ constructor(message = "Access denied", options?: ErrorOptions) {
113
+ super(message, options);
114
+ }
115
+ }
116
+
117
+ // ============================================================================
118
+ // Resource Errors
119
+ // ============================================================================
120
+
121
+ /**
122
+ * 404 Not Found - Resource does not exist.
123
+ *
124
+ * @example
125
+ * if (error instanceof NotFoundError) {
126
+ * console.log(`Not found at: ${error.path}`);
127
+ * }
128
+ */
129
+ export class NotFoundError extends AgentOsError {
130
+ readonly code = "NOT_FOUND";
131
+ readonly status = 404;
132
+
133
+ constructor(
134
+ message = "Resource not found",
135
+ /** The request path that returned 404 */
136
+ readonly path?: string,
137
+ options?: ErrorOptions
138
+ ) {
139
+ super(message, options);
140
+ }
141
+ }
142
+
143
+ /**
144
+ * 409 Conflict - Resource already exists or state conflict.
145
+ *
146
+ * @example
147
+ * if (error instanceof ConflictError) {
148
+ * // Handle duplicate or version mismatch
149
+ * }
150
+ */
151
+ export class ConflictError extends AgentOsError {
152
+ readonly code = "CONFLICT";
153
+ readonly status = 409;
154
+
155
+ constructor(message = "Resource conflict", options?: ErrorOptions) {
156
+ super(message, options);
157
+ }
158
+ }
159
+
160
+ // ============================================================================
161
+ // Validation Errors
162
+ // ============================================================================
163
+
164
+ /**
165
+ * Field-level validation error detail.
166
+ */
167
+ export interface FieldError {
168
+ field: string;
169
+ message: string;
170
+ code?: string;
171
+ }
172
+
173
+ /**
174
+ * 400/422 Validation Error - Invalid request data.
175
+ *
176
+ * @example
177
+ * if (error instanceof ValidationError) {
178
+ * error.fieldErrors?.forEach(fe => {
179
+ * showFieldError(fe.field, fe.message);
180
+ * });
181
+ * }
182
+ */
183
+ export class ValidationError extends AgentOsError {
184
+ readonly code = "VALIDATION_ERROR";
185
+ readonly status: 400 | 422;
186
+
187
+ constructor(
188
+ message = "Validation failed",
189
+ status: 400 | 422 = 400,
190
+ readonly fieldErrors?: FieldError[],
191
+ options?: ErrorOptions
192
+ ) {
193
+ super(message, options);
194
+ this.status = status;
195
+ }
196
+
197
+ /** Get error message for a specific field */
198
+ getFieldError(field: string): string | undefined {
199
+ return this.fieldErrors?.find(fe => fe.field === field)?.message;
200
+ }
201
+
202
+ /** Check if a specific field has an error */
203
+ hasFieldError(field: string): boolean {
204
+ return this.fieldErrors?.some(fe => fe.field === field) ?? false;
205
+ }
206
+ }
207
+
208
+ // ============================================================================
209
+ // Rate Limiting
210
+ // ============================================================================
211
+
212
+ /**
213
+ * 429 Too Many Requests - Rate limit exceeded.
214
+ *
215
+ * @example
216
+ * if (error instanceof RateLimitError) {
217
+ * if (error.retryAfterMs) {
218
+ * await sleep(error.retryAfterMs);
219
+ * // Retry request
220
+ * }
221
+ * }
222
+ */
223
+ export class RateLimitError extends AgentOsError {
224
+ readonly code = "RATE_LIMITED";
225
+ readonly status = 429;
226
+
227
+ constructor(
228
+ message = "Rate limit exceeded",
229
+ /** Time to wait before retrying (milliseconds) */
230
+ readonly retryAfterMs?: number,
231
+ options?: ErrorOptions
232
+ ) {
233
+ super(message, options);
234
+ }
235
+
236
+ isRetryable(): boolean {
237
+ return true;
238
+ }
239
+
240
+ /** Get retry delay or default */
241
+ getRetryDelay(defaultMs = 1000): number {
242
+ return this.retryAfterMs ?? defaultMs;
243
+ }
244
+ }
245
+
246
+ // ============================================================================
247
+ // Server Errors
248
+ // ============================================================================
249
+
250
+ /**
251
+ * 5xx Server Error - Backend failure.
252
+ *
253
+ * @example
254
+ * if (error instanceof ServerError) {
255
+ * if (error.isRetryable()) {
256
+ * // Retry with backoff
257
+ * }
258
+ * }
259
+ */
260
+ export class ServerError extends AgentOsError {
261
+ readonly code = "SERVER_ERROR";
262
+
263
+ constructor(
264
+ message = "Internal server error",
265
+ readonly status: number = 500,
266
+ options?: ErrorOptions
267
+ ) {
268
+ super(message, options);
269
+ }
270
+
271
+ isRetryable(): boolean {
272
+ // 500, 502, 503, 504 are typically retryable
273
+ return [500, 502, 503, 504].includes(this.status);
274
+ }
275
+ }
276
+
277
+ // ============================================================================
278
+ // Network & Timeout Errors
279
+ // ============================================================================
280
+
281
+ /**
282
+ * Network Error - Fetch failed (no response received).
283
+ *
284
+ * @example
285
+ * if (error instanceof NetworkError) {
286
+ * showToast("Network connection failed. Check your internet.");
287
+ * }
288
+ */
289
+ export class NetworkError extends AgentOsError {
290
+ readonly code = "NETWORK_ERROR";
291
+ readonly status = 0;
292
+
293
+ constructor(
294
+ message = "Network request failed",
295
+ readonly cause?: Error
296
+ ) {
297
+ super(message);
298
+ }
299
+
300
+ isRetryable(): boolean {
301
+ return true;
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Timeout Error - Request exceeded time limit.
307
+ *
308
+ * @example
309
+ * if (error instanceof TimeoutError) {
310
+ * console.log(`Request timed out after ${error.timeoutMs}ms`);
311
+ * }
312
+ */
313
+ export class TimeoutError extends AgentOsError {
314
+ readonly code = "TIMEOUT";
315
+ readonly status = 0;
316
+
317
+ constructor(
318
+ /** Timeout duration in milliseconds */
319
+ readonly timeoutMs: number
320
+ ) {
321
+ super(`Request timed out after ${timeoutMs}ms`);
322
+ }
323
+
324
+ isRetryable(): boolean {
325
+ return true;
326
+ }
327
+ }
328
+
329
+ // ============================================================================
330
+ // Error Type Guards
331
+ // ============================================================================
332
+
333
+ /** Check if error is any Agent OS SDK error */
334
+ export function isAgentOsError(error: unknown): error is AgentOsError {
335
+ return error instanceof AgentOsError;
336
+ }
337
+
338
+ /** Check if error is retryable */
339
+ export function isRetryableError(error: unknown): boolean {
340
+ if (error instanceof AgentOsError) {
341
+ return error.isRetryable();
342
+ }
343
+ return false;
344
+ }
345
+
346
+ /** Check if error is an auth error (401 or 403) */
347
+ export function isAuthError(error: unknown): error is UnauthorizedError | ForbiddenError {
348
+ return error instanceof UnauthorizedError || error instanceof ForbiddenError;
349
+ }
350
+
351
+ /** Check if error is a client error (4xx) */
352
+ export function isClientError(error: unknown): boolean {
353
+ if (error instanceof AgentOsError) {
354
+ return error.status >= 400 && error.status < 500;
355
+ }
356
+ return false;
357
+ }
358
+
359
+ /** Check if error is a server error (5xx) */
360
+ export function isServerError(error: unknown): boolean {
361
+ if (error instanceof AgentOsError) {
362
+ return error.status >= 500 && error.status < 600;
363
+ }
364
+ return false;
365
+ }
package/src/index.ts CHANGED
@@ -64,6 +64,68 @@ export {
64
64
  type Unwrapped,
65
65
  } from "./client/helpers.js";
66
66
 
67
+ // ============================================================================
68
+ // Typed Errors (Enterprise)
69
+ // ============================================================================
70
+ export {
71
+ // Base class
72
+ AgentOsError,
73
+ type ErrorOptions,
74
+ // Error classes
75
+ UnauthorizedError,
76
+ ForbiddenError,
77
+ NotFoundError,
78
+ ConflictError,
79
+ ValidationError,
80
+ RateLimitError,
81
+ ServerError,
82
+ NetworkError,
83
+ TimeoutError,
84
+ // Field errors
85
+ type FieldError,
86
+ // Type guards
87
+ isAgentOsError,
88
+ isRetryableError,
89
+ isAuthError,
90
+ isClientError,
91
+ isServerError,
92
+ } from "./errors/index.js";
93
+
94
+ export { createErrorFromResponse } from "./errors/factory.js";
95
+
96
+ // ============================================================================
97
+ // Network Configuration
98
+ // ============================================================================
99
+ export {
100
+ type RetryConfig,
101
+ type NetworkConfig,
102
+ DEFAULT_NETWORK_CONFIG,
103
+ INTERACTIVE_NETWORK_CONFIG,
104
+ BACKGROUND_NETWORK_CONFIG,
105
+ mergeNetworkConfig,
106
+ } from "./client/config.js";
107
+
108
+ // ============================================================================
109
+ // Retry & Timeout Utilities
110
+ // ============================================================================
111
+ export { withRetry, type RetryContext, sleep } from "./client/retry.js";
112
+ export { withTimeout, createTimeoutController } from "./client/timeout.js";
113
+
114
+ // ============================================================================
115
+ // Pagination Utilities
116
+ // ============================================================================
117
+ export {
118
+ paginate,
119
+ collectAll,
120
+ getFirst,
121
+ type OffsetPaginatedResponse,
122
+ type CursorPaginatedResponse,
123
+ type OffsetParams,
124
+ type CursorParams,
125
+ type PaginateOptions,
126
+ } from "./client/pagination.js";
127
+
128
+
67
129
  // ============================================================================
68
130
  // Raw Client & Core Types
69
131
  // ============================================================================
@@ -74,6 +136,11 @@ export {
74
136
  type TypedClient,
75
137
  type ClientOptions,
76
138
  type APIResponse,
139
+ // SDK Hooks for observability (OTEL, Sentry, etc.)
140
+ type SDKHooks,
141
+ type HookRequestContext,
142
+ type HookResponseContext,
143
+ type HookErrorContext,
77
144
  } from "./client/raw.js";
78
145
 
79
146
  // Export OpenAPI types
@@ -85,7 +152,7 @@ export type { paths, components } from "./client/raw.js";
85
152
 
86
153
  // Core modules
87
154
  export { AgentsModule, type Agent, type AgentVersion, type AgentListResponse, type AgentGraphResponse } from "./modules/agents.js";
88
- export { RunsModule, type Run, type RunStatus, type RunEvent, type RunListResponse, type RunEventsResponse, type CreateRunResponse, type RunEventsPollResponse, type RunEventDto } from "./modules/runs.js";
155
+ export { RunsModule, type Run, type RunStatus, type RunEvent, type RunListResponse, type RunEventsResponse, type CreateRunResponse, type RunEventsPollResponse, type RunEventDto, type FollowOptions, type FollowEvent } from "./modules/runs.js";
89
156
  export { ThreadsModule, type Thread, type ThreadState, type ThreadMessage, type ThreadRun, type ThreadListResponse, type ThreadMessagesResponse } from "./modules/threads.js";
90
157
  export { ToolsModule, type Tool, type ToolListResponse } from "./modules/tools.js";
91
158
  export { KnowledgeModule, type KnowledgeDataset, type KnowledgeSearchResponse } from "./modules/knowledge.js";
@@ -112,7 +179,7 @@ export { UsageModule, type UsageResponse, type UsageQuota } from "./modules/usag
112
179
  export { McpModule, type McpServer } from "./modules/mcp.js";
113
180
  export { A2aModule, type JsonRpcRequest, type JsonRpcResponse, type A2aAgentCard } from "./modules/a2a.js";
114
181
  export { MeModule, type MeResponse } from "./modules/me.js";
115
- export { InfoModule, type ServerInfo } from "./modules/info.js";
182
+ export { InfoModule, type ServerInfo, type ServerCapabilities } from "./modules/info.js";
116
183
  export { MetricsModule, type MetricsResponse } from "./modules/metrics.js";
117
184
  export { GraphsModule, type GraphValidationResult, type GraphIntrospectionResult } from "./modules/graphs.js";
118
185
  export { CatalogModule, type CatalogVersions, type NodeCatalogResponse, type ToolCatalogResponse, type TriggerCatalogResponse, type NodeDefinition, type ToolDefinition, type TriggerTemplate } from "./modules/catalog.js";
@@ -120,6 +187,9 @@ export { CatalogModule, type CatalogVersions, type NodeCatalogResponse, type Too
120
187
  // Approvals is real (has backend implementation)
121
188
  export { ApprovalsModule, type Approval, type ApprovalStatus, type ApprovalDecision, type ApprovalListResponse, type ApprovalStatusResponse } from "./modules/approvals.js";
122
189
 
190
+ export { ApiTokensModule, type ApiToken, type ApiTokenSecret, type CreateTokenRequest, type RotateTokenResponse } from "./modules/apiTokens.js";
191
+ export { MembershipsModule, type MembershipResponse, type EnsureMembershipRequest } from "./modules/memberships.js";
192
+
123
193
  // ============================================================================
124
194
  // SSE Streaming
125
195
  // ============================================================================
@@ -37,11 +37,21 @@ export class AuditModule {
37
37
  workspace_id?: string;
38
38
  from?: string;
39
39
  to?: string;
40
- skip?: number;
41
- take?: number;
40
+ limit?: number;
41
+ offset?: number;
42
42
  }): Promise<APIResponse<AuditListResponse>> {
43
+ const queryParams: any = { ...params };
44
+ if (params?.limit !== undefined) {
45
+ queryParams.take = params.limit;
46
+ delete queryParams.limit;
47
+ }
48
+ if (params?.offset !== undefined) {
49
+ queryParams.skip = params.offset;
50
+ delete queryParams.offset;
51
+ }
52
+
43
53
  return this.client.GET<AuditListResponse>("/v1/api/audit", {
44
- params: { query: params },
54
+ params: { query: queryParams },
45
55
  headers: this.headers(),
46
56
  });
47
57
  }
@@ -63,12 +73,73 @@ export class AuditModule {
63
73
  query?: string;
64
74
  from?: string;
65
75
  to?: string;
66
- skip?: number;
67
- take?: number;
76
+ limit?: number;
77
+ offset?: number;
68
78
  }): Promise<APIResponse<AuditListResponse>> {
79
+ const queryParams: any = { ...params };
80
+ if (params?.limit !== undefined) {
81
+ queryParams.take = params.limit;
82
+ delete queryParams.limit;
83
+ }
84
+ if (params?.offset !== undefined) {
85
+ queryParams.skip = params.offset;
86
+ delete queryParams.offset;
87
+ }
88
+
69
89
  return this.client.GET<AuditListResponse>("/v1/api/audit/search", {
70
- params: { query: params },
90
+ params: { query: queryParams },
71
91
  headers: this.headers(),
72
92
  });
73
93
  }
94
+
95
+ /**
96
+ * Iterate through all audit logs with automatic pagination.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * // Get all audit logs for a specific action
101
+ * for await (const entry of client.audit.iterate({ action: "agent.created" })) {
102
+ * console.log(entry.actor, entry.action);
103
+ * }
104
+ * ```
105
+ */
106
+ async *iterate(
107
+ filters?: {
108
+ actor?: string;
109
+ action?: string;
110
+ resource?: string;
111
+ workspace_id?: string;
112
+ from?: string;
113
+ to?: string;
114
+ },
115
+ options?: { pageSize?: number; maxItems?: number; signal?: AbortSignal }
116
+ ): AsyncGenerator<AuditLogEntry, void, unknown> {
117
+ const pageSize = options?.pageSize ?? 100;
118
+ const maxItems = options?.maxItems ?? Infinity;
119
+ let offset = 0;
120
+ let yielded = 0;
121
+ let hasMore = true;
122
+
123
+ while (hasMore && yielded < maxItems) {
124
+ if (options?.signal?.aborted) return;
125
+
126
+ const response = await this.list({
127
+ ...filters,
128
+ limit: Math.min(pageSize, maxItems - yielded),
129
+ offset,
130
+ });
131
+
132
+ if (response.error) throw response.error;
133
+ const data = response.data!;
134
+
135
+ for (const entry of data.items) {
136
+ if (yielded >= maxItems) return;
137
+ yield entry;
138
+ yielded++;
139
+ }
140
+
141
+ offset += data.items.length;
142
+ hasMore = offset < data.total && data.items.length > 0;
143
+ }
144
+ }
74
145
  }
@@ -39,14 +39,17 @@ export interface CatalogMetadata {
39
39
  }
40
40
 
41
41
  export interface NodeCatalogResponse extends CatalogMetadata {
42
- nodes: Record<string, NodeDefinition>;
42
+ nodes: NodeDefinition[];
43
43
  }
44
44
 
45
45
  export interface NodeDefinition {
46
- kind: string;
46
+ id: string;
47
+ title: string;
47
48
  category: string;
48
- description: string;
49
+ description?: string;
50
+ ports?: { inputs?: string[]; outputs?: string[] };
49
51
  config_schema?: Record<string, unknown>;
52
+ default_config?: Record<string, unknown>;
50
53
  }
51
54
 
52
55
  export interface ToolCatalogResponse extends CatalogMetadata {
@@ -65,7 +68,7 @@ export interface ToolDefinition {
65
68
  }
66
69
 
67
70
  export interface TriggerCatalogResponse extends CatalogMetadata {
68
- triggers: TriggerTemplate[];
71
+ templates: TriggerTemplate[];
69
72
  }
70
73
 
71
74
  export interface TriggerTemplate {
@@ -75,6 +78,20 @@ export interface TriggerTemplate {
75
78
  run_input_schema?: Record<string, unknown>;
76
79
  }
77
80
 
81
+ export interface PresetCatalogResponse extends CatalogMetadata {
82
+ presets: PresetDefinition[];
83
+ }
84
+
85
+ export interface PresetDefinition {
86
+ preset_slug: string;
87
+ base_node_slug: string;
88
+ title: string;
89
+ description?: string;
90
+ default_config?: Record<string, unknown>;
91
+ locked_fields?: string[];
92
+ ui_variant?: string;
93
+ }
94
+
78
95
  export class CatalogModule {
79
96
  constructor(private client: RawClient) { }
80
97
 
@@ -115,6 +132,18 @@ export class CatalogModule {
115
132
  return response;
116
133
  }
117
134
 
135
+ /**
136
+ * Get the Node Presets Catalog.
137
+ * Returns pre-configured node variants with locked fields.
138
+ */
139
+ async getPresets(version: string = "1"): Promise<APIResponse<PresetCatalogResponse>> {
140
+ const response = await this.client.GET<PresetCatalogResponse>("/v1/api/catalog/presets", {
141
+ params: { query: { version } },
142
+ });
143
+
144
+ return response;
145
+ }
146
+
118
147
  /**
119
148
  * Get all catalogs at once for convenience.
120
149
  * Returns combined catalog data with versions.
@@ -124,25 +153,29 @@ export class CatalogModule {
124
153
  nodes: NodeCatalogResponse;
125
154
  tools: ToolCatalogResponse;
126
155
  triggers: TriggerCatalogResponse;
156
+ presets: PresetCatalogResponse;
127
157
  catalog_versions: CatalogVersions;
128
158
  };
129
159
  error?: { code: string; message: string; details?: unknown };
130
160
  }> {
131
- const [nodesRes, toolsRes, triggersRes] = await Promise.all([
161
+ const [nodesRes, toolsRes, triggersRes, presetsRes] = await Promise.all([
132
162
  this.getNodes(version),
133
163
  this.getTools(version),
134
164
  this.getTriggers(version),
165
+ this.getPresets(version),
135
166
  ]);
136
167
 
137
168
  if (nodesRes.error) return { data: undefined, error: nodesRes.error };
138
169
  if (toolsRes.error) return { data: undefined, error: toolsRes.error };
139
170
  if (triggersRes.error) return { data: undefined, error: triggersRes.error };
171
+ if (presetsRes.error) return { data: undefined, error: presetsRes.error };
140
172
 
141
173
  return {
142
174
  data: {
143
175
  nodes: nodesRes.data!,
144
176
  tools: toolsRes.data!,
145
177
  triggers: triggersRes.data!,
178
+ presets: presetsRes.data!,
146
179
  catalog_versions: {
147
180
  nodes: version,
148
181
  tools: version,
@@ -66,7 +66,7 @@ export class CheckpointsModule {
66
66
  * Replay from a checkpoint.
67
67
  */
68
68
  async replay(checkpointId: string, options?: {
69
- mode?: "best_effort" | "deterministic";
69
+ mode?: "best_effort" | "strict";
70
70
  modified_state?: unknown;
71
71
  }): Promise<APIResponse<ReplayResponse>> {
72
72
  return this.client.POST<ReplayResponse>("/v1/api/checkpoints/{id}/replay", {