@agent-os-sdk/client 0.9.8 → 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 (77) hide show
  1. package/dist/client/AgentOsClient.d.ts +6 -2
  2. package/dist/client/AgentOsClient.d.ts.map +1 -1
  3. package/dist/client/AgentOsClient.js +10 -3
  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/generated/openapi.d.ts +115 -186
  13. package/dist/generated/openapi.d.ts.map +1 -1
  14. package/dist/index.d.ts +4 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +4 -0
  17. package/dist/modules/agents.d.ts +30 -0
  18. package/dist/modules/agents.d.ts.map +1 -1
  19. package/dist/modules/agents.js +25 -1
  20. package/dist/modules/builder.d.ts +0 -4
  21. package/dist/modules/builder.d.ts.map +1 -1
  22. package/dist/modules/credentials.d.ts +4 -1
  23. package/dist/modules/credentials.d.ts.map +1 -1
  24. package/dist/modules/credentials.js +36 -1
  25. package/dist/modules/datasets.d.ts +80 -0
  26. package/dist/modules/datasets.d.ts.map +1 -0
  27. package/dist/modules/datasets.js +91 -0
  28. package/dist/modules/files.d.ts +34 -13
  29. package/dist/modules/files.d.ts.map +1 -1
  30. package/dist/modules/files.js +86 -19
  31. package/dist/modules/graphs.d.ts +1 -1
  32. package/dist/modules/graphs.d.ts.map +1 -1
  33. package/dist/modules/members.d.ts +0 -6
  34. package/dist/modules/members.d.ts.map +1 -1
  35. package/dist/modules/members.js +0 -6
  36. package/dist/modules/observability.d.ts +19 -0
  37. package/dist/modules/observability.d.ts.map +1 -0
  38. package/dist/modules/observability.js +14 -0
  39. package/dist/modules/roles.d.ts +64 -0
  40. package/dist/modules/roles.d.ts.map +1 -0
  41. package/dist/modules/roles.js +79 -0
  42. package/dist/modules/runs.d.ts +2 -0
  43. package/dist/modules/runs.d.ts.map +1 -1
  44. package/dist/modules/runs.js +2 -2
  45. package/dist/modules/threads.js +2 -2
  46. package/dist/modules/triggers.d.ts +51 -5
  47. package/dist/modules/triggers.d.ts.map +1 -1
  48. package/dist/modules/triggers.js +39 -0
  49. package/dist/modules/usage.d.ts +68 -9
  50. package/dist/modules/usage.d.ts.map +1 -1
  51. package/dist/modules/usage.js +27 -3
  52. package/dist/modules/vectorStores.d.ts +6 -3
  53. package/dist/modules/vectorStores.d.ts.map +1 -1
  54. package/dist/modules/vectorStores.js +86 -14
  55. package/package.json +1 -1
  56. package/src/client/AgentOsClient.ts +10 -3
  57. package/src/client/HttpRequestBuilder.ts +7 -2
  58. package/src/client/auth.ts +4 -0
  59. package/src/client/raw.ts +91 -4
  60. package/src/generated/openapi.ts +115 -186
  61. package/src/generated/swagger.json +96 -180
  62. package/src/index.ts +4 -1
  63. package/src/modules/agents.ts +56 -2
  64. package/src/modules/builder.ts +0 -7
  65. package/src/modules/credentials.ts +44 -2
  66. package/src/modules/datasets.ts +142 -0
  67. package/src/modules/files.ts +125 -29
  68. package/src/modules/graphs.ts +1 -1
  69. package/src/modules/members.ts +0 -7
  70. package/src/modules/observability.ts +28 -0
  71. package/src/modules/roles.ts +112 -0
  72. package/src/modules/runs.ts +4 -2
  73. package/src/modules/threads.ts +2 -2
  74. package/src/modules/triggers.ts +87 -6
  75. package/src/modules/usage.ts +94 -9
  76. package/src/modules/vectorStores.ts +115 -18
  77. package/src/modules/knowledge.ts +0 -147
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Datasets Module — Evaluation datasets and examples.
3
+ *
4
+ * Endpoints: /v1/api/datasets
5
+ */
6
+
7
+ import type { RawClient, APIResponse } from "../client/raw.js";
8
+
9
+ // =============================================================================
10
+ // Types
11
+ // =============================================================================
12
+
13
+ export interface Dataset {
14
+ id: string;
15
+ name: string;
16
+ description?: string;
17
+ agent_id?: string;
18
+ example_count: number;
19
+ created_at: string;
20
+ updated_at: string;
21
+ }
22
+
23
+ export interface DatasetExample {
24
+ id: string;
25
+ dataset_id: string;
26
+ input: unknown;
27
+ expected_output?: unknown;
28
+ metadata?: unknown;
29
+ created_at: string;
30
+ }
31
+
32
+ export interface ExampleInput {
33
+ input: unknown;
34
+ expected_output?: unknown;
35
+ metadata?: unknown;
36
+ }
37
+
38
+ // =============================================================================
39
+ // Module
40
+ // =============================================================================
41
+
42
+ export class DatasetsModule {
43
+ constructor(private client: RawClient, private headers: () => Record<string, string>) { }
44
+
45
+ /**
46
+ * List datasets in the workspace.
47
+ */
48
+ async list(params?: {
49
+ skip?: number;
50
+ take?: number;
51
+ }): Promise<APIResponse<Dataset[]>> {
52
+ return this.client.GET<Dataset[]>("/v1/api/datasets", {
53
+ params: { query: params },
54
+ headers: this.headers(),
55
+ });
56
+ }
57
+
58
+ /**
59
+ * Get a specific dataset by ID.
60
+ */
61
+ async get(datasetId: string): Promise<APIResponse<Dataset>> {
62
+ return this.client.GET<Dataset>("/v1/api/datasets/{id}", {
63
+ params: { path: { id: datasetId } },
64
+ headers: this.headers(),
65
+ });
66
+ }
67
+
68
+ /**
69
+ * Create a new evaluation dataset.
70
+ */
71
+ async create(body: {
72
+ name: string;
73
+ description?: string;
74
+ agent_id?: string;
75
+ }): Promise<APIResponse<Dataset>> {
76
+ return this.client.POST<Dataset>("/v1/api/datasets", {
77
+ body,
78
+ headers: this.headers(),
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Update a dataset (partial update).
84
+ */
85
+ async update(datasetId: string, body: {
86
+ name?: string;
87
+ description?: string;
88
+ agent_id?: string;
89
+ }): Promise<APIResponse<Dataset>> {
90
+ return this.client.PATCH<Dataset>("/v1/api/datasets/{id}", {
91
+ params: { path: { id: datasetId } },
92
+ body,
93
+ headers: this.headers(),
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Soft delete a dataset.
99
+ */
100
+ async delete(datasetId: string): Promise<APIResponse<void>> {
101
+ return this.client.DELETE<void>("/v1/api/datasets/{id}", {
102
+ params: { path: { id: datasetId } },
103
+ headers: this.headers(),
104
+ });
105
+ }
106
+
107
+ // ======================== Examples ========================
108
+
109
+ /**
110
+ * List examples for a dataset.
111
+ */
112
+ async listExamples(datasetId: string, params?: {
113
+ skip?: number;
114
+ take?: number;
115
+ }): Promise<APIResponse<DatasetExample[]>> {
116
+ return this.client.GET<DatasetExample[]>("/v1/api/datasets/{id}/examples", {
117
+ params: { path: { id: datasetId }, query: params },
118
+ headers: this.headers(),
119
+ });
120
+ }
121
+
122
+ /**
123
+ * Add examples to a dataset (batch).
124
+ */
125
+ async addExamples(datasetId: string, examples: ExampleInput[]): Promise<APIResponse<DatasetExample[]>> {
126
+ return this.client.POST<DatasetExample[]>("/v1/api/datasets/{id}/examples", {
127
+ params: { path: { id: datasetId } },
128
+ body: { examples },
129
+ headers: this.headers(),
130
+ });
131
+ }
132
+
133
+ /**
134
+ * Delete a specific example.
135
+ */
136
+ async deleteExample(datasetId: string, exampleId: string): Promise<APIResponse<void>> {
137
+ return this.client.DELETE<void>("/v1/api/datasets/{id}/examples/{exampleId}", {
138
+ params: { path: { id: datasetId, exampleId } },
139
+ headers: this.headers(),
140
+ });
141
+ }
142
+ }
@@ -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
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Roles Module — Tenant role and permission management.
3
+ *
4
+ * Endpoints: /v1/api/roles
5
+ */
6
+
7
+ import type { RawClient, APIResponse } from "../client/raw.js";
8
+
9
+ // =============================================================================
10
+ // Types
11
+ // =============================================================================
12
+
13
+ export interface TenantRole {
14
+ id: string;
15
+ name: string;
16
+ is_system: boolean;
17
+ permissions: string[];
18
+ created_at: string;
19
+ members_count: number;
20
+ }
21
+
22
+ export interface RoleListResponse {
23
+ items: TenantRole[];
24
+ }
25
+
26
+ export interface PermissionsListResponse {
27
+ items: string[];
28
+ }
29
+
30
+ // =============================================================================
31
+ // Module
32
+ // =============================================================================
33
+
34
+ export class RolesModule {
35
+ constructor(private client: RawClient, private headers: () => Record<string, string>) { }
36
+
37
+ /**
38
+ * List all roles available in the tenant.
39
+ */
40
+ async list(): Promise<APIResponse<RoleListResponse>> {
41
+ return this.client.GET<RoleListResponse>("/v1/api/roles", {
42
+ headers: this.headers(),
43
+ });
44
+ }
45
+
46
+ /**
47
+ * Get a specific role by ID.
48
+ */
49
+ async get(roleId: string): Promise<APIResponse<TenantRole>> {
50
+ return this.client.GET<TenantRole>("/v1/api/roles/{id}", {
51
+ params: { path: { id: roleId } },
52
+ headers: this.headers(),
53
+ });
54
+ }
55
+
56
+ /**
57
+ * List all available system permissions.
58
+ */
59
+ async getPermissions(): Promise<APIResponse<PermissionsListResponse>> {
60
+ return this.client.GET<PermissionsListResponse>("/v1/api/roles/permissions", {
61
+ headers: this.headers(),
62
+ });
63
+ }
64
+
65
+ /**
66
+ * Create a new custom role.
67
+ */
68
+ async create(body: {
69
+ name: string;
70
+ permissions?: string[];
71
+ }): Promise<APIResponse<TenantRole>> {
72
+ return this.client.POST<TenantRole>("/v1/api/roles", {
73
+ body,
74
+ headers: this.headers(),
75
+ });
76
+ }
77
+
78
+ /**
79
+ * Update an existing custom role.
80
+ * System roles cannot be updated.
81
+ */
82
+ async update(roleId: string, body: {
83
+ name?: string;
84
+ permissions?: string[];
85
+ }): Promise<APIResponse<TenantRole>> {
86
+ return this.client.PUT<TenantRole>("/v1/api/roles/{id}", {
87
+ params: { path: { id: roleId } },
88
+ body,
89
+ headers: this.headers(),
90
+ });
91
+ }
92
+
93
+ /**
94
+ * Delete a custom role.
95
+ * System roles and roles assigned to members cannot be deleted.
96
+ */
97
+ async delete(roleId: string): Promise<APIResponse<void>> {
98
+ return this.client.DELETE<void>("/v1/api/roles/{id}", {
99
+ params: { path: { id: roleId } },
100
+ headers: this.headers(),
101
+ });
102
+ }
103
+
104
+ /**
105
+ * Seed default permissions for all roles in the tenant.
106
+ */
107
+ async seedDefaults(): Promise<APIResponse<{ message: string }>> {
108
+ return this.client.POST<{ message: string }>("/v1/api/roles/seed-defaults", {
109
+ headers: this.headers(),
110
+ });
111
+ }
112
+ }
@@ -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", {