@agent-os-sdk/client 0.9.9 → 0.9.10

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 (58) hide show
  1. package/dist/client/AgentOsClient.d.ts +2 -0
  2. package/dist/client/AgentOsClient.d.ts.map +1 -1
  3. package/dist/client/AgentOsClient.js +4 -0
  4. package/dist/client/HttpRequestBuilder.d.ts +1 -0
  5. package/dist/client/HttpRequestBuilder.d.ts.map +1 -1
  6. package/dist/client/HttpRequestBuilder.js +6 -2
  7. package/dist/client/auth.d.ts +4 -0
  8. package/dist/client/auth.d.ts.map +1 -1
  9. package/dist/client/raw.d.ts +12 -0
  10. package/dist/client/raw.d.ts.map +1 -1
  11. package/dist/client/raw.js +67 -3
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/modules/agents.d.ts +29 -0
  16. package/dist/modules/agents.d.ts.map +1 -1
  17. package/dist/modules/agents.js +23 -0
  18. package/dist/modules/builder.d.ts +0 -4
  19. package/dist/modules/builder.d.ts.map +1 -1
  20. package/dist/modules/files.d.ts +34 -13
  21. package/dist/modules/files.d.ts.map +1 -1
  22. package/dist/modules/files.js +86 -19
  23. package/dist/modules/graphs.d.ts +1 -1
  24. package/dist/modules/graphs.d.ts.map +1 -1
  25. package/dist/modules/members.d.ts +0 -6
  26. package/dist/modules/members.d.ts.map +1 -1
  27. package/dist/modules/members.js +0 -6
  28. package/dist/modules/observability.d.ts +19 -0
  29. package/dist/modules/observability.d.ts.map +1 -0
  30. package/dist/modules/observability.js +14 -0
  31. package/dist/modules/runs.d.ts +2 -0
  32. package/dist/modules/runs.d.ts.map +1 -1
  33. package/dist/modules/runs.js +2 -2
  34. package/dist/modules/threads.js +2 -2
  35. package/dist/modules/vectorStores.d.ts +6 -3
  36. package/dist/modules/vectorStores.d.ts.map +1 -1
  37. package/dist/modules/vectorStores.js +86 -14
  38. package/package.json +2 -2
  39. package/src/client/AgentOsClient.ts +4 -0
  40. package/src/client/HttpRequestBuilder.ts +7 -2
  41. package/src/client/auth.ts +4 -0
  42. package/src/client/raw.ts +91 -4
  43. package/src/index.ts +1 -0
  44. package/src/modules/agents.ts +52 -0
  45. package/src/modules/builder.ts +0 -7
  46. package/src/modules/files.ts +125 -29
  47. package/src/modules/graphs.ts +1 -1
  48. package/src/modules/members.ts +0 -7
  49. package/src/modules/observability.ts +28 -0
  50. package/src/modules/runs.ts +4 -2
  51. package/src/modules/threads.ts +2 -2
  52. package/src/modules/vectorStores.ts +115 -18
  53. package/dist/modules/dlq.d.ts +0 -81
  54. package/dist/modules/dlq.d.ts.map +0 -1
  55. package/dist/modules/dlq.js +0 -66
  56. package/dist/modules/mcp.d.ts +0 -39
  57. package/dist/modules/mcp.d.ts.map +0 -1
  58. package/dist/modules/mcp.js +0 -38
package/src/client/raw.ts CHANGED
@@ -9,8 +9,9 @@ import createClient, { type Client } from "openapi-fetch";
9
9
  import type { components, paths } from "../generated/openapi.js";
10
10
  import { createErrorFromResponse } from "../errors/factory.js";
11
11
  import { AgentOsError, NetworkError, TimeoutError } from "../errors/index.js";
12
- import { httpRequestBuilder } from "./HttpRequestBuilder.js";
12
+ import { httpRequestBuilder, sanitizeValidCorrelationId } from "./HttpRequestBuilder.js";
13
13
  import type { OperationContext } from "./OperationContext.js";
14
+ import type { OperationContextProvider } from "./OperationContextProvider.js";
14
15
  import { mergeNetworkConfig, type NetworkConfig } from "./config.js";
15
16
  import { withRetry } from "./retry.js";
16
17
  import { withTimeout } from "./timeout.js";
@@ -22,6 +23,8 @@ export type ClientOptions = {
22
23
  baseUrl: string;
23
24
  headers?: Record<string, string>;
24
25
  headerProvider?: () => Promise<Record<string, string>>;
26
+ /** Optional flow context provider (ALS/manual). */
27
+ contextProvider?: OperationContextProvider;
25
28
  /** Network behavior (timeouts/retries). Defaults to DEFAULT_NETWORK_CONFIG. */
26
29
  network?: Partial<NetworkConfig>;
27
30
  /** Hooks for observability (OTEL, Sentry, etc.) */
@@ -39,6 +42,8 @@ export interface SDKHooks {
39
42
  onResponse?: (context: HookResponseContext) => void | Promise<void>;
40
43
  /** Called on any error (network, timeout, HTTP error) */
41
44
  onError?: (context: HookErrorContext) => void | Promise<void>;
45
+ /** Optional logger bridge used by SDK internal warnings. */
46
+ logger?: { warn?: (message: string) => void };
42
47
  }
43
48
 
44
49
  export interface HookRequestContext {
@@ -106,8 +111,67 @@ export function createTypedClient(options: ClientOptions): TypedClient {
106
111
  * Wraps openapi-fetch to provide the old interface while maintaining types.
107
112
  */
108
113
  export function createRawClient(options: ClientOptions) {
109
- const { baseUrl, headers: defaultHeaders = {}, headerProvider } = options;
114
+ const { baseUrl, headers: defaultHeaders = {}, headerProvider, contextProvider } = options;
110
115
  const networkConfig = mergeNetworkConfig(options.network);
116
+ const warn = (message: string): void => {
117
+ const hookWarn = options.hooks?.logger?.warn;
118
+ if (typeof hookWarn === "function") {
119
+ hookWarn(message);
120
+ return;
121
+ }
122
+ if (typeof console !== "undefined" && typeof console.warn === "function") {
123
+ console.warn(message);
124
+ }
125
+ };
126
+ // Sticky fallback context for clients that don't provide per-operation context.
127
+ const fallbackContext: OperationContext = Object.freeze({
128
+ correlationId: crypto.randomUUID(),
129
+ });
130
+ let warnedStickyFallbackContext = false;
131
+ let warnedInvalidContextCorrelation = false;
132
+ const resolveEffectiveContext = (optsContext?: OperationContext): OperationContext => {
133
+ const providerContext = contextProvider?.get();
134
+ const usingStickyFallback = !optsContext && !providerContext;
135
+ if (usingStickyFallback && !contextProvider && !warnedStickyFallbackContext) {
136
+ warnedStickyFallbackContext = true;
137
+ warn(
138
+ "[AgentOS SDK] Using sticky fallback correlation context per client instance. " +
139
+ "For long-lived server clients, configure contextProvider (ALS/manual) to scope correlation per request."
140
+ );
141
+ }
142
+
143
+ const effectiveContext = optsContext ?? providerContext ?? fallbackContext;
144
+ const correlationProvidedByCaller =
145
+ effectiveContext !== fallbackContext
146
+ && typeof effectiveContext?.correlationId === "string";
147
+
148
+ if (correlationProvidedByCaller) {
149
+ const validCorrelation = sanitizeValidCorrelationId(effectiveContext.correlationId);
150
+ if (!validCorrelation) {
151
+ if (!warnedInvalidContextCorrelation) {
152
+ warnedInvalidContextCorrelation = true;
153
+ warn(
154
+ "[AgentOS SDK] Invalid correlationId in operation context ignored; generated fallback correlation id. " +
155
+ "Provide a valid correlationId (8-128 chars: A-Za-z0-9._:-)."
156
+ );
157
+ }
158
+ // Caller provided invalid flow id: use per-request fallback (not sticky fallback context).
159
+ return {
160
+ ...effectiveContext,
161
+ correlationId: crypto.randomUUID(),
162
+ };
163
+ }
164
+
165
+ if (validCorrelation !== effectiveContext.correlationId) {
166
+ return {
167
+ ...effectiveContext,
168
+ correlationId: validCorrelation,
169
+ };
170
+ }
171
+ }
172
+
173
+ return effectiveContext;
174
+ };
111
175
  type ErrorPayload = { code?: string; message?: string; details?: unknown } & Record<string, unknown>;
112
176
  type HttpAgentOsError = AgentOsError & {
113
177
  response?: Response;
@@ -173,9 +237,11 @@ export function createRawClient(options: ClientOptions) {
173
237
  headers["Content-Type"] = "application/json";
174
238
  }
175
239
 
240
+ const effectiveContext = resolveEffectiveContext(opts?.context);
241
+
176
242
  // Build standard headers via HttpRequestBuilder (single source of truth)
177
243
  const builderHeaders = httpRequestBuilder.build({
178
- context: opts?.context,
244
+ context: effectiveContext,
179
245
  idempotencyKey: opts?.idempotencyKey,
180
246
  requireFlow: opts?.requireFlow,
181
247
  });
@@ -357,7 +423,12 @@ export function createRawClient(options: ClientOptions) {
357
423
  */
358
424
  streamGet: async (
359
425
  path: string,
360
- opts?: { params?: { path?: Record<string, string>; query?: Record<string, unknown> }; headers?: Record<string, string> }
426
+ opts?: {
427
+ params?: { path?: Record<string, string>; query?: Record<string, unknown> };
428
+ headers?: Record<string, string>;
429
+ context?: OperationContext;
430
+ requireFlow?: boolean;
431
+ }
361
432
  ): Promise<Response> => {
362
433
  let url = path;
363
434
  if (opts?.params?.path) {
@@ -377,9 +448,15 @@ export function createRawClient(options: ClientOptions) {
377
448
  }
378
449
  const fullUrl = `${baseUrl}${url}`;
379
450
  const dynamicHeaders = headerProvider ? await headerProvider() : {};
451
+ const effectiveContext = resolveEffectiveContext(opts?.context);
452
+ const builderHeaders = httpRequestBuilder.build({
453
+ context: effectiveContext,
454
+ requireFlow: opts?.requireFlow,
455
+ });
380
456
  const headers: Record<string, string> = {
381
457
  ...defaultHeaders,
382
458
  ...dynamicHeaders,
459
+ ...builderHeaders,
383
460
  Accept: "text/event-stream",
384
461
  ...opts?.headers,
385
462
  };
@@ -397,6 +474,9 @@ export function createRawClient(options: ClientOptions) {
397
474
  body?: unknown;
398
475
  headers?: Record<string, string>;
399
476
  signal?: AbortSignal;
477
+ context?: OperationContext;
478
+ idempotencyKey?: string;
479
+ requireFlow?: boolean;
400
480
  }
401
481
  ): Promise<Response> => {
402
482
  let url = path;
@@ -407,9 +487,16 @@ export function createRawClient(options: ClientOptions) {
407
487
  }
408
488
  const fullUrl = `${baseUrl}${url}`;
409
489
  const dynamicHeaders = headerProvider ? await headerProvider() : {};
490
+ const effectiveContext = resolveEffectiveContext(opts?.context);
491
+ const builderHeaders = httpRequestBuilder.build({
492
+ context: effectiveContext,
493
+ idempotencyKey: opts?.idempotencyKey,
494
+ requireFlow: opts?.requireFlow,
495
+ });
410
496
  const headers: Record<string, string> = {
411
497
  ...defaultHeaders,
412
498
  ...dynamicHeaders,
499
+ ...builderHeaders,
413
500
  "Content-Type": "application/json",
414
501
  Accept: "text/event-stream",
415
502
  ...opts?.headers,
package/src/index.ts CHANGED
@@ -101,6 +101,7 @@ export * from "./modules/credentials.js";
101
101
  export * from "./modules/datasets.js";
102
102
  export * from "./modules/me.js";
103
103
  export * from "./modules/members.js";
104
+ export * from "./modules/observability.js";
104
105
  export * from "./modules/presets.js";
105
106
  export * from "./modules/prompts.js";
106
107
  export * from "./modules/roles.js";
@@ -53,6 +53,21 @@ export interface GraphValidationResponse {
53
53
  warnings?: string[];
54
54
  }
55
55
 
56
+ export interface UpsertAgentCredentialBindingRequest {
57
+ credential_id: string;
58
+ alias: string;
59
+ priority?: number;
60
+ }
61
+
62
+ export interface AgentCredentialBindingUpsertResponse {
63
+ id: string;
64
+ updated: boolean;
65
+ agent_id: string;
66
+ credential_id: string;
67
+ alias: string;
68
+ priority: number;
69
+ }
70
+
56
71
  export type AgentListResponse = PaginatedResponse<Agent>;
57
72
 
58
73
  export class AgentsModule {
@@ -259,6 +274,34 @@ export class AgentsModule {
259
274
  });
260
275
  }
261
276
 
277
+ /**
278
+ * Get Mermaid diagram for a specific bundle graph.
279
+ */
280
+ async getBundleMermaid(agentId: string, bundleId: string): Promise<APIResponse<BundleMermaidResponse>> {
281
+ return this.client.GET<BundleMermaidResponse>("/v1/api/agents/{agentId}/bundles/{bundleId}/graph/mermaid", {
282
+ params: { path: { agentId, bundleId } },
283
+ headers: this.headers(),
284
+ });
285
+ }
286
+
287
+ /**
288
+ * Creates or updates an agent credential binding by alias.
289
+ */
290
+ async upsertCredentialBinding(
291
+ agentId: string,
292
+ body: UpsertAgentCredentialBindingRequest
293
+ ): Promise<APIResponse<AgentCredentialBindingUpsertResponse>> {
294
+ return this.client.POST<AgentCredentialBindingUpsertResponse>("/v1/api/agents/{id}/credential-bindings", {
295
+ params: { path: { id: agentId } },
296
+ body: {
297
+ credential_id: body.credential_id,
298
+ alias: body.alias,
299
+ priority: body.priority ?? 0,
300
+ },
301
+ headers: this.headers(),
302
+ });
303
+ }
304
+
262
305
  }
263
306
 
264
307
  // Bundle manifest response type
@@ -274,3 +317,12 @@ export interface BundleManifestResponse {
274
317
  created_at?: string;
275
318
  graph_spec?: Record<string, unknown>;
276
319
  }
320
+
321
+ export interface BundleMermaidResponse {
322
+ bundle_id: string;
323
+ agent_id: string;
324
+ mermaid: string;
325
+ format?: string;
326
+ node_count?: number;
327
+ edge_count?: number;
328
+ }
@@ -118,11 +118,6 @@ export type HintModel = {
118
118
  };
119
119
 
120
120
  export type GraphUpdateAction = {
121
- // Legacy support
122
- action: string;
123
- // ... legacy fields omitted for brevity, keeping strict new protocol
124
- } | {
125
- // New protocol (WAVE-3)
126
121
  graph_spec: Record<string, unknown>;
127
122
  hints?: HintModel[];
128
123
  has_errors?: boolean;
@@ -166,8 +161,6 @@ export type PatchOp = {
166
161
  label?: string;
167
162
  data?: Record<string, unknown>;
168
163
  set?: Record<string, unknown>;
169
- source?: string;
170
- target?: string;
171
164
  from?: string;
172
165
  to?: string;
173
166
  entrypoint?: string;
@@ -4,21 +4,23 @@
4
4
 
5
5
  import type { RawClient, APIResponse, components } from "../client/raw.js";
6
6
 
7
+ type FileListItem = components["schemas"]["FileListItem"];
8
+ type FileDetail = components["schemas"]["FileDetail"];
7
9
  type CreatePresignedUploadRequest = components["schemas"]["CreatePresignedUploadRequest"];
8
10
  type PresignedUploadResponse = components["schemas"]["PresignedUploadResponse"];
9
11
  type ConfirmUploadRequest = components["schemas"]["ConfirmUploadRequest"];
12
+ type FileConfirmResponse = components["schemas"]["FileConfirmResponse"];
13
+ type PresignedDownloadResponse = components["schemas"]["PresignedDownloadResponse"];
10
14
 
11
15
  export interface StoredFile {
12
16
  id: string;
13
17
  filename: string;
14
18
  content_type: string;
15
19
  size_bytes: number;
16
- sha256: string;
17
- storage_uri: string;
18
- workspace_id: string;
19
- uploaded_by?: string;
20
+ sha256?: string;
20
21
  status: "pending" | "confirmed" | "deleted";
21
22
  created_at: string;
23
+ updated_at?: string;
22
24
  }
23
25
 
24
26
  export interface FileListResponse {
@@ -29,39 +31,109 @@ export interface FileListResponse {
29
31
  export interface PresignedUpload {
30
32
  file_id: string;
31
33
  upload_url: string;
32
- expires_at: string;
34
+ expires_in: number;
35
+ object_key: string;
36
+ }
37
+
38
+ export interface ConfirmedUpload {
39
+ file_id: string;
40
+ status: string;
41
+ size_bytes: number;
42
+ sha256?: string;
33
43
  }
34
44
 
35
45
  export interface PresignedDownload {
46
+ file_id: string;
36
47
  download_url: string;
37
- expires_at: string;
48
+ filename: string;
49
+ content_type: string;
50
+ size_bytes: number;
51
+ expires_in: number;
38
52
  }
39
53
 
40
54
  export class FilesModule {
41
55
  constructor(private client: RawClient, private headers: () => Record<string, string>) { }
42
56
 
57
+ private resolveWorkspaceId(workspaceId?: string): string {
58
+ if (workspaceId && workspaceId.trim().length > 0) {
59
+ return workspaceId.trim();
60
+ }
61
+
62
+ const headers = this.headers();
63
+ const fromHeader = headers["X-Workspace-Id"] ?? headers["x-workspace-id"];
64
+ if (fromHeader && fromHeader.trim().length > 0) {
65
+ return fromHeader.trim();
66
+ }
67
+
68
+ throw new Error("workspace_id is required (pass workspaceId or set X-Workspace-Id in client headers)");
69
+ }
70
+
71
+ private static toStoredFile(item: FileListItem | FileDetail): StoredFile {
72
+ return {
73
+ id: item.id ?? "",
74
+ filename: item.filename ?? "",
75
+ content_type: item.content_type ?? "application/octet-stream",
76
+ size_bytes: item.size_bytes ?? 0,
77
+ sha256: "sha256" in item ? item.sha256 ?? undefined : undefined,
78
+ status: (item.status ?? "pending") as StoredFile["status"],
79
+ created_at: item.created_at ?? "",
80
+ updated_at: "updated_at" in item ? item.updated_at ?? undefined : undefined,
81
+ };
82
+ }
83
+
43
84
  /**
44
- * List all files.
85
+ * List files in a workspace.
45
86
  */
46
87
  async list(params?: {
47
88
  workspace_id?: string;
89
+ status?: string;
48
90
  limit?: number;
49
91
  offset?: number;
50
92
  }): Promise<APIResponse<FileListResponse>> {
51
- return this.client.GET<FileListResponse>("/v1/api/files", {
52
- params: { query: params },
93
+ const workspaceId = this.resolveWorkspaceId(params?.workspace_id);
94
+ const response = await this.client.GET<FileListItem[]>("/v1/api/workspaces/{workspaceId}/files", {
95
+ params: {
96
+ path: { workspaceId },
97
+ query: {
98
+ status: params?.status,
99
+ limit: params?.limit,
100
+ offset: params?.offset,
101
+ },
102
+ },
53
103
  headers: this.headers(),
54
104
  });
105
+
106
+ const items = Array.isArray(response.data)
107
+ ? response.data.map((item) => FilesModule.toStoredFile(item))
108
+ : [];
109
+
110
+ return {
111
+ ...response,
112
+ data: {
113
+ items,
114
+ total: items.length,
115
+ },
116
+ };
55
117
  }
56
118
 
57
119
  /**
58
120
  * Get a file by ID.
59
121
  */
60
- async get(fileId: string): Promise<APIResponse<StoredFile>> {
61
- return this.client.GET<StoredFile>("/v1/api/files/{id}", {
62
- params: { path: { id: fileId } },
122
+ async get(fileId: string, workspaceId?: string): Promise<APIResponse<StoredFile>> {
123
+ const resolvedWorkspaceId = this.resolveWorkspaceId(workspaceId);
124
+ const response = await this.client.GET<FileDetail>("/v1/api/workspaces/{workspaceId}/files/{fileId}", {
125
+ params: { path: { workspaceId: resolvedWorkspaceId, fileId } },
63
126
  headers: this.headers(),
64
127
  });
128
+
129
+ if (!response.data) {
130
+ return response as APIResponse<StoredFile>;
131
+ }
132
+
133
+ return {
134
+ ...response,
135
+ data: FilesModule.toStoredFile(response.data),
136
+ };
65
137
  }
66
138
 
67
139
  /**
@@ -69,44 +141,68 @@ export class FilesModule {
69
141
  */
70
142
  async createUpload(body: {
71
143
  filename: string;
72
- content_type: string;
144
+ content_type?: string;
73
145
  size_bytes?: number;
74
146
  expected_sha256?: string;
75
- }): Promise<APIResponse<PresignedUpload>> {
76
- return this.client.POST<PresignedUpload>("/v1/api/files/upload", {
77
- body,
147
+ }, workspaceId?: string): Promise<APIResponse<PresignedUpload>> {
148
+ const resolvedWorkspaceId = this.resolveWorkspaceId(workspaceId);
149
+ const requestBody: CreatePresignedUploadRequest = {
150
+ filename: body.filename,
151
+ content_type: body.content_type,
152
+ size_bytes: body.size_bytes,
153
+ expected_sha256: body.expected_sha256,
154
+ };
155
+ return this.client.POST<PresignedUploadResponse>("/v1/api/workspaces/{workspaceId}/files/presign", {
156
+ params: { path: { workspaceId: resolvedWorkspaceId } },
157
+ body: requestBody,
78
158
  headers: this.headers(),
79
- });
159
+ }) as Promise<APIResponse<PresignedUpload>>;
80
160
  }
81
161
 
82
162
  /**
83
163
  * Confirm an upload.
84
164
  */
85
- async confirmUpload(fileId: string, sha256: string): Promise<APIResponse<StoredFile>> {
86
- return this.client.POST<StoredFile>("/v1/api/files/{id}/confirm", {
87
- params: { path: { id: fileId } },
88
- body: { sha256 },
165
+ async confirmUpload(fileId: string, sha256?: string, workspaceId?: string): Promise<APIResponse<ConfirmedUpload>> {
166
+ const resolvedWorkspaceId = this.resolveWorkspaceId(workspaceId);
167
+ const requestBody: ConfirmUploadRequest = { sha256 };
168
+ return this.client.POST<FileConfirmResponse>("/v1/api/workspaces/{workspaceId}/files/{fileId}/confirm", {
169
+ params: { path: { workspaceId: resolvedWorkspaceId, fileId } },
170
+ body: requestBody,
89
171
  headers: this.headers(),
90
- });
172
+ }) as Promise<APIResponse<ConfirmedUpload>>;
91
173
  }
92
174
 
93
175
  /**
94
176
  * Get a presigned download URL.
95
177
  */
96
- async getDownloadUrl(fileId: string): Promise<APIResponse<PresignedDownload>> {
97
- return this.client.GET<PresignedDownload>("/v1/api/files/{id}/download", {
98
- params: { path: { id: fileId } },
178
+ async getDownloadUrl(fileId: string, workspaceId?: string): Promise<APIResponse<PresignedDownload>> {
179
+ const resolvedWorkspaceId = this.resolveWorkspaceId(workspaceId);
180
+ return this.client.GET<PresignedDownloadResponse>("/v1/api/workspaces/{workspaceId}/files/{fileId}/download", {
181
+ params: { path: { workspaceId: resolvedWorkspaceId, fileId } },
99
182
  headers: this.headers(),
100
- });
183
+ }) as Promise<APIResponse<PresignedDownload>>;
101
184
  }
102
185
 
103
186
  /**
104
187
  * Delete a file.
105
188
  */
106
- async delete(fileId: string): Promise<APIResponse<void>> {
107
- return this.client.DELETE<void>("/v1/api/files/{id}", {
108
- params: { path: { id: fileId } },
189
+ async delete(fileId: string, workspaceId?: string): Promise<APIResponse<void>> {
190
+ const resolvedWorkspaceId = this.resolveWorkspaceId(workspaceId);
191
+ return this.client.DELETE<void>("/v1/api/workspaces/{workspaceId}/files/{fileId}", {
192
+ params: { path: { workspaceId: resolvedWorkspaceId, fileId } },
109
193
  headers: this.headers(),
110
194
  });
111
195
  }
196
+
197
+ /**
198
+ * Alias for createUpload with explicit semantic name.
199
+ */
200
+ async createPresignedUpload(body: {
201
+ filename: string;
202
+ content_type?: string;
203
+ size_bytes?: number;
204
+ expected_sha256?: string;
205
+ }, workspaceId?: string): Promise<APIResponse<PresignedUpload>> {
206
+ return this.createUpload(body, workspaceId);
207
+ }
112
208
  }
@@ -115,7 +115,7 @@ export interface GraphsIntrospectResponse {
115
115
  mermaid: string;
116
116
  nodes: string[];
117
117
  edges: [string, string][];
118
- graph_type?: string;
118
+ type?: string;
119
119
  }
120
120
 
121
121
  // ============ Module ============
@@ -159,7 +159,6 @@ export class MembersModule {
159
159
 
160
160
  /**
161
161
  * Remove a member from the tenant.
162
- * Note: Use delete() - remove() is provided as alias for backwards compatibility.
163
162
  */
164
163
  async delete(memberId: string): Promise<APIResponse<void>> {
165
164
  return this.client.DELETE<void>("/v1/api/members/{id}", {
@@ -168,12 +167,6 @@ export class MembersModule {
168
167
  });
169
168
  }
170
169
 
171
- /**
172
- * Alias for delete() (backwards compatibility)
173
- * @deprecated Use delete() instead
174
- */
175
- remove = (memberId: string) => this.delete(memberId);
176
-
177
170
  /**
178
171
  * Resend invitation email.
179
172
  */
@@ -0,0 +1,28 @@
1
+ import type { APIResponse, RawClient } from "../client/raw.js";
2
+
3
+ export type FrontendLogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";
4
+
5
+ export interface FrontendLogPayload {
6
+ level: FrontendLogLevel;
7
+ message: string;
8
+ stack?: string;
9
+ route?: string;
10
+ url?: string;
11
+ user_agent?: string;
12
+ session_id?: string;
13
+ context?: Record<string, unknown>;
14
+ }
15
+
16
+ export class ObservabilityModule {
17
+ constructor(
18
+ private client: RawClient,
19
+ private headers: () => Record<string, string>
20
+ ) { }
21
+
22
+ async logFrontend(payload: FrontendLogPayload): Promise<APIResponse<Record<string, unknown>>> {
23
+ return this.client.POST<Record<string, unknown>>("/v1/api/observability/frontend-log", {
24
+ body: payload,
25
+ headers: this.headers(),
26
+ });
27
+ }
28
+ }
@@ -110,13 +110,15 @@ export class RunsModule {
110
110
  agent_id: string;
111
111
  thread?: { thread_id?: string } | { new_thread: true };
112
112
  input?: unknown;
113
+ /** Optional bundle pinning (draft/published). When omitted, backend resolves live bundle. */
114
+ bundle_id?: string;
113
115
  /** Idempotency key for safe retries. When set, duplicate requests with the same key return the original response. */
114
116
  idempotency_key?: string;
115
117
  }): Promise<APIResponse<CreateRunResponse>> {
116
- // Send Idempotency-Key in HEADER (enterprise standard) + body (backend compat)
118
+ // Send canonical X-Idempotency-Key header + body idempotency_key for backend contract parity.
117
119
  const headers: Record<string, string> = {};
118
120
  if (body.idempotency_key) {
119
- headers["Idempotency-Key"] = body.idempotency_key;
121
+ headers["X-Idempotency-Key"] = body.idempotency_key;
120
122
  }
121
123
 
122
124
  return this.client.POST<CreateRunResponse>("/v1/api/runs", {
@@ -93,10 +93,10 @@ export class ThreadsModule {
93
93
  /** Idempotency key for safe retries. When set, duplicate requests with the same key return the original response. */
94
94
  idempotency_key?: string;
95
95
  }): Promise<APIResponse<Thread>> {
96
- // Send Idempotency-Key in HEADER (enterprise standard) + body (backend compat)
96
+ // Send canonical X-Idempotency-Key header + body idempotency_key for backend contract parity.
97
97
  const headers: Record<string, string> = { ...this.headers() };
98
98
  if (body?.idempotency_key) {
99
- headers["Idempotency-Key"] = body.idempotency_key;
99
+ headers["X-Idempotency-Key"] = body.idempotency_key;
100
100
  }
101
101
 
102
102
  return this.client.POST<Thread>("/v1/api/threads", {