@agent-os-sdk/client 0.7.12 → 0.8.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 (49) hide show
  1. package/dist/client/AgentOsClient.d.ts +25 -23
  2. package/dist/client/AgentOsClient.d.ts.map +1 -1
  3. package/dist/client/AgentOsClient.js +26 -22
  4. package/dist/client/HttpRequestBuilder.d.ts +48 -0
  5. package/dist/client/HttpRequestBuilder.d.ts.map +1 -0
  6. package/dist/client/HttpRequestBuilder.js +73 -0
  7. package/dist/client/OperationContext.d.ts +19 -0
  8. package/dist/client/OperationContext.d.ts.map +1 -0
  9. package/dist/client/OperationContext.js +13 -0
  10. package/dist/client/OperationContextProvider.d.ts +54 -0
  11. package/dist/client/OperationContextProvider.d.ts.map +1 -0
  12. package/dist/client/OperationContextProvider.js +71 -0
  13. package/dist/client/raw.d.ts +31 -0
  14. package/dist/client/raw.d.ts.map +1 -1
  15. package/dist/client/raw.js +11 -6
  16. package/dist/client/sanitize.d.ts +19 -0
  17. package/dist/client/sanitize.d.ts.map +1 -0
  18. package/dist/client/sanitize.js +28 -0
  19. package/dist/index.d.ts +6 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +4 -0
  22. package/dist/modules/agents.d.ts +22 -6
  23. package/dist/modules/agents.d.ts.map +1 -1
  24. package/dist/modules/agents.js +26 -7
  25. package/dist/modules/credentials.d.ts +1 -0
  26. package/dist/modules/credentials.d.ts.map +1 -1
  27. package/dist/modules/credentials.js +2 -1
  28. package/dist/modules/crons.d.ts +1 -0
  29. package/dist/modules/crons.d.ts.map +1 -1
  30. package/dist/modules/crons.js +2 -1
  31. package/dist/modules/presets.d.ts +32 -0
  32. package/dist/modules/presets.d.ts.map +1 -0
  33. package/dist/modules/presets.js +116 -0
  34. package/dist/modules/triggers.d.ts +11 -0
  35. package/dist/modules/triggers.d.ts.map +1 -1
  36. package/dist/modules/triggers.js +17 -2
  37. package/package.json +51 -49
  38. package/src/client/AgentOsClient.ts +27 -24
  39. package/src/client/HttpRequestBuilder.ts +102 -0
  40. package/src/client/OperationContext.ts +22 -0
  41. package/src/client/OperationContextProvider.ts +89 -0
  42. package/src/client/raw.ts +19 -8
  43. package/src/client/sanitize.ts +31 -0
  44. package/src/index.ts +15 -0
  45. package/src/modules/agents.ts +44 -14
  46. package/src/modules/credentials.ts +2 -1
  47. package/src/modules/crons.ts +2 -1
  48. package/src/modules/presets.ts +162 -0
  49. package/src/modules/triggers.ts +21 -2
@@ -27,54 +27,55 @@
27
27
  * ```
28
28
  */
29
29
 
30
- import { createRawClient, type RawClient } from "./raw.js";
31
30
  import {
32
31
  type AgentOsClientOptions,
33
32
  type AuthProvider,
34
33
  isApiTokenAuth,
35
- isJwtAuth,
36
34
  isBrowser,
35
+ isJwtAuth,
37
36
  } from "./auth.js";
37
+ import { createRawClient, type RawClient } from "./raw.js";
38
38
 
39
39
  import { AgentsModule } from "../modules/agents.js";
40
+ import { BuilderModule } from "../modules/builder.js";
41
+ import { CredentialsModule } from "../modules/credentials.js";
42
+ import { KnowledgeModule } from "../modules/knowledge.js";
43
+ import { MembersModule } from "../modules/members.js";
40
44
  import { RunsModule } from "../modules/runs.js";
45
+ import { TenantsModule } from "../modules/tenants.js";
41
46
  import { ThreadsModule } from "../modules/threads.js";
42
47
  import { ToolsModule } from "../modules/tools.js";
43
- import { KnowledgeModule } from "../modules/knowledge.js";
44
48
  import { TriggersModule } from "../modules/triggers.js";
45
- import { CredentialsModule } from "../modules/credentials.js";
46
- import { BuilderModule } from "../modules/builder.js";
47
- import { MembersModule } from "../modules/members.js";
48
- import { TenantsModule } from "../modules/tenants.js";
49
49
  import { WorkspacesModule } from "../modules/workspaces.js";
50
50
 
51
51
  // Platform modules
52
- import { PromptsModule } from "../modules/prompts.js";
53
- import { TracesModule } from "../modules/traces.js";
54
- import { FilesModule } from "../modules/files.js";
55
- import { VectorStoresModule } from "../modules/vectorStores.js";
56
- import { EvaluationModule } from "../modules/evaluation.js";
52
+ import { A2aModule } from "../modules/a2a.js";
53
+ import { ApiTokensModule } from "../modules/apiTokens.js";
54
+ import { ApprovalsModule } from "../modules/approvals.js";
55
+ import { AuditModule } from "../modules/audit.js";
56
+ import { CatalogModule } from "../modules/catalog.js";
57
57
  import { CheckpointsModule } from "../modules/checkpoints.js";
58
- import { PlaygroundModule } from "../modules/playground.js";
59
58
  import { CronsModule } from "../modules/crons.js";
60
59
  import { DlqModule } from "../modules/dlq.js";
61
- import { StoreModule } from "../modules/store.js";
62
- import { AuditModule } from "../modules/audit.js";
63
- import { UsageModule } from "../modules/usage.js";
60
+ import { EvaluationModule } from "../modules/evaluation.js";
61
+ import { FilesModule } from "../modules/files.js";
62
+ import { GraphsModule } from "../modules/graphs.js";
63
+ import { InfoModule } from "../modules/info.js";
64
64
  import { McpModule } from "../modules/mcp.js";
65
- import { A2aModule } from "../modules/a2a.js";
66
65
  import { MeModule } from "../modules/me.js";
67
- import { InfoModule } from "../modules/info.js";
68
- import { MetricsModule } from "../modules/metrics.js";
69
- import { GraphsModule } from "../modules/graphs.js";
70
- import { CatalogModule } from "../modules/catalog.js";
71
- import { ApprovalsModule } from "../modules/approvals.js";
72
- import { ApiTokensModule } from "../modules/apiTokens.js";
73
66
  import { MembershipsModule } from "../modules/memberships.js";
67
+ import { MetricsModule } from "../modules/metrics.js";
68
+ import { PlaygroundModule } from "../modules/playground.js";
69
+ import { PresetsModule } from "../modules/presets.js";
70
+ import { PromptsModule } from "../modules/prompts.js";
71
+ import { StoreModule } from "../modules/store.js";
72
+ import { TracesModule } from "../modules/traces.js";
73
+ import { UsageModule } from "../modules/usage.js";
74
+ import { VectorStoresModule } from "../modules/vectorStores.js";
74
75
 
75
76
  // Re-export auth types
76
- export type { AgentOsClientOptions, AuthProvider } from "./auth.js";
77
77
  export { isApiTokenAuth, isJwtAuth } from "./auth.js";
78
+ export type { AgentOsClientOptions, AuthProvider } from "./auth.js";
78
79
 
79
80
  export class AgentOsClient {
80
81
  private readonly _client: RawClient;
@@ -126,6 +127,7 @@ export class AgentOsClient {
126
127
 
127
128
  public readonly apiTokens: ApiTokensModule;
128
129
  public readonly memberships: MembershipsModule;
130
+ public readonly presets: PresetsModule;
129
131
 
130
132
 
131
133
 
@@ -192,6 +194,7 @@ export class AgentOsClient {
192
194
 
193
195
  this.apiTokens = new ApiTokensModule(this._client);
194
196
  this.memberships = new MembershipsModule(this._client);
197
+ this.presets = new PresetsModule(this._client, getHeaders);
195
198
 
196
199
  }
197
200
 
@@ -0,0 +1,102 @@
1
+ /**
2
+ * HttpRequestBuilder — Single source of truth for headers
3
+ *
4
+ * All header generation flows through this builder.
5
+ * raw.ts should NOT generate headers directly.
6
+ *
7
+ * Headers generated:
8
+ * - X-Request-Id: Per-request, always new (crypto.randomUUID)
9
+ * - X-Correlation-Id: Per-flow, immutable within flow
10
+ * - Authorization: Bearer token
11
+ * - X-Workspace-Id: Workspace binding (from context)
12
+ * - X-Idempotency-Key: Opt-in for POST requests
13
+ * - User-Agent: SDK version + runtime info
14
+ *
15
+ * @see sdk-upgrade.md Section 1.3
16
+ */
17
+
18
+ import type { OperationContext } from "./OperationContext.js";
19
+ import { sanitizeHeader, sanitizeHeaders } from "./sanitize.js";
20
+
21
+ // SDK version injected at build time, fallback for local dev
22
+ declare const __SDK_VERSION__: string | undefined;
23
+ const SDK_VERSION = typeof __SDK_VERSION__ !== "undefined" ? __SDK_VERSION__ : "0.7.12-dev";
24
+
25
+ /**
26
+ * Options for building request headers
27
+ */
28
+ export interface HttpRequestBuilderOptions {
29
+ /** Bearer token for Authorization header */
30
+ token?: string;
31
+ /** Operation context with correlationId and workspaceId */
32
+ context?: OperationContext;
33
+ /** Idempotency key for POST requests */
34
+ idempotencyKey?: string;
35
+ /** If true, throws if correlationId is missing */
36
+ requireFlow?: boolean;
37
+ }
38
+
39
+ /**
40
+ * Build headers for HTTP requests.
41
+ * This is the SINGLE SOURCE OF TRUTH for header generation.
42
+ */
43
+ export class HttpRequestBuilder {
44
+ /**
45
+ * Build headers from options.
46
+ *
47
+ * @throws Error if requireFlow is true and correlationId is missing
48
+ */
49
+ build(opts: HttpRequestBuilderOptions): Record<string, string> {
50
+ const headers: Record<string, string> = {};
51
+
52
+ // I2: X-Request-Id always exists (per request)
53
+ headers["X-Request-Id"] = crypto.randomUUID();
54
+
55
+ // User-Agent: Dynamic SDK version
56
+ headers["User-Agent"] = this.buildUserAgent();
57
+
58
+ // I3: X-Correlation-Id is per flow
59
+ if (opts.requireFlow && !opts.context?.correlationId) {
60
+ throw new Error("X-Correlation-Id required for flow-scoped operations");
61
+ }
62
+ if (opts.context?.correlationId) {
63
+ headers["X-Correlation-Id"] = opts.context.correlationId;
64
+ }
65
+
66
+ // Authorization
67
+ if (opts.token) {
68
+ headers["Authorization"] = `Bearer ${opts.token}`;
69
+ }
70
+
71
+ // X-Workspace-Id from context
72
+ if (opts.context?.workspaceId) {
73
+ headers["X-Workspace-Id"] = opts.context.workspaceId;
74
+ }
75
+
76
+ // I7: Idempotency is opt-in
77
+ if (opts.idempotencyKey) {
78
+ headers["X-Idempotency-Key"] = sanitizeHeader(opts.idempotencyKey);
79
+ }
80
+
81
+ return sanitizeHeaders(headers);
82
+ }
83
+
84
+ /**
85
+ * Build User-Agent string with SDK version and runtime info
86
+ */
87
+ private buildUserAgent(): string {
88
+ // Node.js environment
89
+ if (typeof process !== "undefined" && process.version) {
90
+ return `agent-os-sdk/${SDK_VERSION} (node/${process.version})`;
91
+ }
92
+ // Browser environment
93
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
94
+ return `agent-os-sdk/${SDK_VERSION} (browser)`;
95
+ }
96
+ // Unknown environment
97
+ return `agent-os-sdk/${SDK_VERSION}`;
98
+ }
99
+ }
100
+
101
+ // Singleton instance for convenience
102
+ export const httpRequestBuilder = new HttpRequestBuilder();
@@ -0,0 +1,22 @@
1
+ /**
2
+ * OperationContext — Immutable flow context
3
+ *
4
+ * Created at the start of a logical flow and never mutates.
5
+ *
6
+ * - correlationId: Tracks the entire logical operation (immutable per flow)
7
+ * - workspaceId: Optional workspace binding
8
+ *
9
+ * @see sdk-upgrade.md Section 1.1
10
+ */
11
+
12
+ export type OperationContext = Readonly<{
13
+ correlationId: string;
14
+ workspaceId?: string;
15
+ }>;
16
+
17
+ export function createOperationContext(input: {
18
+ correlationId: string;
19
+ workspaceId?: string;
20
+ }): OperationContext {
21
+ return Object.freeze({ ...input });
22
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * OperationContextProvider — Flow lifecycle management
3
+ *
4
+ * Provider defines the lifecycle of a flow context.
5
+ * Implementations can use AsyncLocalStorage or manual context passing.
6
+ *
7
+ * @see sdk-upgrade.md Section 1.2
8
+ */
9
+
10
+ import type { OperationContext } from "./OperationContext.js";
11
+
12
+ /**
13
+ * Interface for context providers
14
+ */
15
+ export interface OperationContextProvider {
16
+ get(): OperationContext | undefined;
17
+ }
18
+
19
+ /**
20
+ * Default provider that always returns undefined.
21
+ * Used when no flow context is established.
22
+ */
23
+ export class DefaultContextProvider implements OperationContextProvider {
24
+ get(): OperationContext | undefined {
25
+ return undefined;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * AsyncLocalStorage-based provider for Node.js environments.
31
+ * Automatically propagates context through async call chains.
32
+ *
33
+ * Note: This class requires Node.js async_hooks module.
34
+ * Import and use only in Node.js environments.
35
+ */
36
+ export class AsyncLocalStorageContextProvider implements OperationContextProvider {
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ private readonly storage: any;
39
+
40
+ constructor() {
41
+ // Dynamic import to avoid browser errors
42
+ try {
43
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
44
+ const asyncHooks = require("async_hooks");
45
+ this.storage = new asyncHooks.AsyncLocalStorage();
46
+ } catch {
47
+ throw new Error("AsyncLocalStorage requires Node.js environment");
48
+ }
49
+ }
50
+
51
+ get(): OperationContext | undefined {
52
+ return this.storage?.getStore();
53
+ }
54
+
55
+ /**
56
+ * Run a function within a context.
57
+ * The context is automatically available to all async operations within.
58
+ */
59
+ run<T>(context: OperationContext, fn: () => T): T {
60
+ return this.storage.run(context, fn);
61
+ }
62
+
63
+ /**
64
+ * Run an async function within a context.
65
+ */
66
+ runAsync<T>(context: OperationContext, fn: () => Promise<T>): Promise<T> {
67
+ return this.storage.run(context, fn);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Manual provider for environments without AsyncLocalStorage.
73
+ * Context must be explicitly set and cleared.
74
+ */
75
+ export class ManualContextProvider implements OperationContextProvider {
76
+ private context: OperationContext | undefined;
77
+
78
+ get(): OperationContext | undefined {
79
+ return this.context;
80
+ }
81
+
82
+ set(context: OperationContext): void {
83
+ this.context = context;
84
+ }
85
+
86
+ clear(): void {
87
+ this.context = undefined;
88
+ }
89
+ }
package/src/client/raw.ts CHANGED
@@ -7,6 +7,8 @@
7
7
 
8
8
  import createClient, { type Client } from "openapi-fetch";
9
9
  import type { components, paths } from "../generated/openapi.js";
10
+ import { httpRequestBuilder } from "./HttpRequestBuilder.js";
11
+ import type { OperationContext } from "./OperationContext.js";
10
12
 
11
13
  // Re-export types for external use
12
14
  export type { components, paths };
@@ -111,6 +113,12 @@ export function createRawClient(options: ClientOptions) {
111
113
  retry?: boolean;
112
114
  /** Override timeout for this request */
113
115
  timeoutMs?: number;
116
+ /** Operation context for flow tracing */
117
+ context?: OperationContext;
118
+ /** Idempotency key for POST requests */
119
+ idempotencyKey?: string;
120
+ /** Require correlation ID (throws if missing) */
121
+ requireFlow?: boolean;
114
122
  }
115
123
  ): Promise<APIResponse<T>> {
116
124
  // Replace path params
@@ -152,15 +160,18 @@ export function createRawClient(options: ClientOptions) {
152
160
  headers["Content-Type"] = "application/json";
153
161
  }
154
162
 
155
- // Detect idempotency from header or body
156
- const hasIdempotencyKey = Boolean(
157
- headers["Idempotency-Key"] ||
158
- headers["idempotency-key"] ||
159
- (opts?.body && typeof opts.body === "object" && (opts.body as Record<string, unknown>).idempotency_key)
160
- );
163
+ // Build standard headers via HttpRequestBuilder (single source of truth)
164
+ const builderHeaders = httpRequestBuilder.build({
165
+ context: opts?.context,
166
+ idempotencyKey: opts?.idempotencyKey,
167
+ requireFlow: opts?.requireFlow,
168
+ });
169
+
170
+ // Merge builder headers (X-Request-Id, X-Correlation-Id, X-Idempotency-Key, User-Agent)
171
+ Object.assign(headers, builderHeaders);
161
172
 
162
- // Generate client request ID for tracing
163
- const clientRequestId = `sdk_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
173
+ // Use X-Request-Id from builder as client request ID
174
+ const clientRequestId = headers["X-Request-Id"];
164
175
 
165
176
  // Call onRequest hook
166
177
  const startTime = Date.now();
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Header Sanitization — Security layer for HTTP headers
3
+ *
4
+ * Removes control characters and enforces size limits.
5
+ *
6
+ * @see sdk-upgrade.md Section 1.4
7
+ */
8
+
9
+ const MAX_LEN = 1024;
10
+
11
+ /**
12
+ * Sanitize a single header value.
13
+ * - Removes control characters (0x00-0x1F, 0x7F)
14
+ * - Truncates to MAX_LEN
15
+ */
16
+ export function sanitizeHeader(v: string): string {
17
+ return v.replace(/[\u0000-\u001F\u007F]/g, "").slice(0, MAX_LEN);
18
+ }
19
+
20
+ /**
21
+ * Sanitize all header values in a record.
22
+ * Mutates in place for performance.
23
+ */
24
+ export function sanitizeHeaders(h: Record<string, string>): Record<string, string> {
25
+ for (const k in h) {
26
+ if (Object.prototype.hasOwnProperty.call(h, k) && h[k] !== undefined) {
27
+ h[k] = sanitizeHeader(h[k]);
28
+ }
29
+ }
30
+ return h;
31
+ }
package/src/index.ts CHANGED
@@ -63,6 +63,21 @@ export {
63
63
  isRetryableError,
64
64
  } from "./errors/index.js";
65
65
 
66
+ // ============================================================
67
+ // Auth Hardening (Pedra Sólida)
68
+ // ============================================================
69
+
70
+ export type { OperationContext } from "./client/OperationContext.js";
71
+ export { createOperationContext } from "./client/OperationContext.js";
72
+ export type { OperationContextProvider } from "./client/OperationContextProvider.js";
73
+ export {
74
+ DefaultContextProvider,
75
+ AsyncLocalStorageContextProvider,
76
+ ManualContextProvider,
77
+ } from "./client/OperationContextProvider.js";
78
+ export { HttpRequestBuilder, httpRequestBuilder } from "./client/HttpRequestBuilder.js";
79
+ export { sanitizeHeader, sanitizeHeaders } from "./client/sanitize.js";
80
+
66
81
  // ============================================================
67
82
  // Utilities
68
83
  // ============================================================
@@ -20,12 +20,17 @@ type AgentBundleSchema = components["schemas"]["AgentExportBundle"];
20
20
  export interface Agent {
21
21
  id: string;
22
22
  name: string;
23
- description?: string;
24
23
  workspace_id: string;
25
24
  tenant_id: string;
26
25
  created_at: string;
27
26
  updated_at: string;
28
27
  live_bundle_id?: string | null;
28
+ // Dashboard fields (P1 fix)
29
+ status?: "live" | "draft";
30
+ has_draft?: boolean;
31
+ last_run_id?: string | null;
32
+ last_run_status?: string | null;
33
+ last_run_at?: string | null;
29
34
  }
30
35
 
31
36
  export interface AgentBundle extends AgentBundleSchema { }
@@ -87,35 +92,44 @@ export class AgentsModule {
87
92
 
88
93
  /**
89
94
  * Create a new agent.
95
+ * Backend only accepts `name` per CreateAgentRequest DTO.
90
96
  * @example
91
97
  * ```ts
92
- * const { data: agent } = await client.agents.create({
93
- * name: "My Agent",
94
- * description: "Does cool stuff"
98
+ * const { data: agent } = await client.agents.create({ name: "My Agent" });
99
+ *
100
+ * // With idempotency (safe to retry)
101
+ * const { data: agent } = await client.agents.create({
102
+ * name: "My Agent",
103
+ * idempotency_key: "unique-key"
95
104
  * });
96
105
  * ```
97
106
  */
98
107
  async create(body: {
99
108
  name: string;
100
- description?: string;
101
- graph_json?: unknown;
109
+ /** Idempotency key for safe retries. When set, duplicate requests with the same key return 409 Conflict. */
110
+ idempotency_key?: string;
102
111
  }): Promise<APIResponse<Agent>> {
112
+ const headers: Record<string, string> = { ...this.headers() };
113
+ if (body.idempotency_key) {
114
+ headers["X-Idempotency-Key"] = body.idempotency_key;
115
+ }
116
+
103
117
  return this.client.POST<Agent>("/v1/api/agents", {
104
- body,
105
- headers: this.headers(),
118
+ body: { name: body.name },
119
+ headers,
106
120
  });
107
121
  }
108
122
 
109
123
  /**
110
124
  * Update an existing agent.
125
+ * Uses PATCH per backend AgentsController.
111
126
  */
112
127
  async update(agentId: string, body: {
113
128
  name?: string;
114
- description?: string;
115
129
  live_bundle_id?: string;
116
130
  }): Promise<APIResponse<Agent>> {
117
- return this.client.PUT<Agent>("/v1/api/agents/{agentId}", {
118
- params: { path: { agentId } },
131
+ return this.client.PATCH<Agent>("/v1/api/agents/{id}", {
132
+ params: { path: { id: agentId } },
119
133
  body,
120
134
  headers: this.headers(),
121
135
  });
@@ -184,14 +198,30 @@ export class AgentsModule {
184
198
  * Publish a new version (bundle) of the agent.
185
199
  * @param agentId The agent UUID
186
200
  * @param graph_spec The graph specification to publish
187
- * @param options Optional settings: version_label for tagging, set_as_live to make this the active version
201
+ * @param options Optional settings: version_label for tagging, set_as_live to make this the active version, idempotency_key for safe retries
188
202
  * @returns Bundle response with version details
203
+ * @example
204
+ * ```ts
205
+ * const { data: bundle } = await client.agents.publish(agentId, graphSpec, {
206
+ * idempotency_key: "publish-unique-key"
207
+ * });
208
+ * ```
189
209
  */
190
210
  async publish(
191
211
  agentId: string,
192
212
  graph_spec: Record<string, unknown>,
193
- options?: { version_label?: string | null; set_as_live?: boolean }
213
+ options?: {
214
+ version_label?: string | null;
215
+ set_as_live?: boolean;
216
+ /** Idempotency key for safe retries */
217
+ idempotency_key?: string;
218
+ }
194
219
  ): Promise<APIResponse<components["schemas"]["BundleResponse"]>> {
220
+ const headers: Record<string, string> = { ...this.headers() };
221
+ if (options?.idempotency_key) {
222
+ headers["X-Idempotency-Key"] = options.idempotency_key;
223
+ }
224
+
195
225
  return this.client.POST<components["schemas"]["BundleResponse"]>("/v1/api/agents/{id}/publish", {
196
226
  params: { path: { id: agentId } },
197
227
  body: {
@@ -199,7 +229,7 @@ export class AgentsModule {
199
229
  version_label: options?.version_label ?? null,
200
230
  set_as_live: options?.set_as_live ?? true
201
231
  },
202
- headers: this.headers()
232
+ headers
203
233
  });
204
234
  }
205
235
 
@@ -99,6 +99,7 @@ export class CredentialsModule {
99
99
 
100
100
  /**
101
101
  * Update a credential.
102
+ * Uses PATCH per backend CredentialsController.
102
103
  */
103
104
  async update(credentialId: string, body: {
104
105
  name?: string;
@@ -106,7 +107,7 @@ export class CredentialsModule {
106
107
  status?: string;
107
108
  sharing_mode?: string;
108
109
  }): Promise<APIResponse<Credential>> {
109
- return this.client.PUT<Credential>("/v1/api/credentials/{id}", {
110
+ return this.client.PATCH<Credential>("/v1/api/credentials/{id}", {
110
111
  params: { path: { id: credentialId } },
111
112
  body,
112
113
  headers: this.headers(),
@@ -79,13 +79,14 @@ export class CronsModule {
79
79
 
80
80
  /**
81
81
  * Update a cron job.
82
+ * Uses PATCH per backend CronsController.
82
83
  */
83
84
  async update(cronId: string, body: {
84
85
  schedule?: string;
85
86
  enabled?: boolean;
86
87
  input?: unknown;
87
88
  }): Promise<APIResponse<CronJob>> {
88
- return this.client.PUT<CronJob>("/v1/api/crons/{id}", {
89
+ return this.client.PATCH<CronJob>("/v1/api/crons/{id}", {
89
90
  params: { path: { id: cronId } },
90
91
  body,
91
92
  headers: this.headers(),