@anthropic-ai/sdk 0.117.1 → 0.118.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 (221) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/client.d.mts +2 -2
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +2 -2
  5. package/client.d.ts.map +1 -1
  6. package/client.js +1 -1
  7. package/client.js.map +1 -1
  8. package/client.mjs +1 -1
  9. package/client.mjs.map +1 -1
  10. package/core/api-promise.d.mts +1 -0
  11. package/core/api-promise.d.mts.map +1 -1
  12. package/core/api-promise.d.ts +1 -0
  13. package/core/api-promise.d.ts.map +1 -1
  14. package/core/api-promise.js +7 -2
  15. package/core/api-promise.js.map +1 -1
  16. package/core/api-promise.mjs +8 -3
  17. package/core/api-promise.mjs.map +1 -1
  18. package/core/error.d.mts +1 -0
  19. package/core/error.d.mts.map +1 -1
  20. package/core/error.d.ts +1 -0
  21. package/core/error.d.ts.map +1 -1
  22. package/core/error.js +1 -0
  23. package/core/error.js.map +1 -1
  24. package/core/error.mjs +1 -0
  25. package/core/error.mjs.map +1 -1
  26. package/core/middleware.js +1 -1
  27. package/core/middleware.js.map +1 -1
  28. package/core/middleware.mjs +2 -2
  29. package/core/middleware.mjs.map +1 -1
  30. package/helpers/beta/zod.d.mts.map +1 -1
  31. package/helpers/beta/zod.d.ts.map +1 -1
  32. package/helpers/beta/zod.js +1 -2
  33. package/helpers/beta/zod.js.map +1 -1
  34. package/helpers/beta/zod.mjs +1 -2
  35. package/helpers/beta/zod.mjs.map +1 -1
  36. package/helpers/zod.d.mts.map +1 -1
  37. package/helpers/zod.d.ts.map +1 -1
  38. package/helpers/zod.js +1 -2
  39. package/helpers/zod.js.map +1 -1
  40. package/helpers/zod.mjs +1 -2
  41. package/helpers/zod.mjs.map +1 -1
  42. package/internal/parse.d.mts +2 -1
  43. package/internal/parse.d.mts.map +1 -1
  44. package/internal/parse.d.ts +2 -1
  45. package/internal/parse.d.ts.map +1 -1
  46. package/internal/parse.js +6 -6
  47. package/internal/parse.js.map +1 -1
  48. package/internal/parse.mjs +5 -5
  49. package/internal/parse.mjs.map +1 -1
  50. package/lib/BetaMessageStream.d.mts +2 -0
  51. package/lib/BetaMessageStream.d.mts.map +1 -1
  52. package/lib/BetaMessageStream.d.ts +2 -0
  53. package/lib/BetaMessageStream.d.ts.map +1 -1
  54. package/lib/BetaMessageStream.js +8 -2
  55. package/lib/BetaMessageStream.js.map +1 -1
  56. package/lib/BetaMessageStream.mjs +8 -2
  57. package/lib/BetaMessageStream.mjs.map +1 -1
  58. package/lib/MessageStream.d.mts +2 -0
  59. package/lib/MessageStream.d.mts.map +1 -1
  60. package/lib/MessageStream.d.ts +2 -0
  61. package/lib/MessageStream.d.ts.map +1 -1
  62. package/lib/MessageStream.js +8 -2
  63. package/lib/MessageStream.js.map +1 -1
  64. package/lib/MessageStream.mjs +8 -2
  65. package/lib/MessageStream.mjs.map +1 -1
  66. package/lib/environments/worker.d.mts +10 -6
  67. package/lib/environments/worker.d.mts.map +1 -1
  68. package/lib/environments/worker.d.ts +10 -6
  69. package/lib/environments/worker.d.ts.map +1 -1
  70. package/lib/environments/worker.js +22 -15
  71. package/lib/environments/worker.js.map +1 -1
  72. package/lib/environments/worker.mjs +22 -15
  73. package/lib/environments/worker.mjs.map +1 -1
  74. package/lib/tools/BetaRunnableTool.d.mts +20 -42
  75. package/lib/tools/BetaRunnableTool.d.mts.map +1 -1
  76. package/lib/tools/BetaRunnableTool.d.ts +20 -42
  77. package/lib/tools/BetaRunnableTool.d.ts.map +1 -1
  78. package/lib/tools/BetaRunnableTool.js +3 -17
  79. package/lib/tools/BetaRunnableTool.js.map +1 -1
  80. package/lib/tools/BetaRunnableTool.mjs +3 -17
  81. package/lib/tools/BetaRunnableTool.mjs.map +1 -1
  82. package/lib/tools/BetaToolRunner.d.mts.map +1 -1
  83. package/lib/tools/BetaToolRunner.d.ts.map +1 -1
  84. package/lib/tools/BetaToolRunner.js +0 -12
  85. package/lib/tools/BetaToolRunner.js.map +1 -1
  86. package/lib/tools/BetaToolRunner.mjs +0 -12
  87. package/lib/tools/BetaToolRunner.mjs.map +1 -1
  88. package/lib/tools/SessionToolRunner.d.mts +6 -0
  89. package/lib/tools/SessionToolRunner.d.mts.map +1 -1
  90. package/lib/tools/SessionToolRunner.d.ts +6 -0
  91. package/lib/tools/SessionToolRunner.d.ts.map +1 -1
  92. package/lib/tools/SessionToolRunner.js +37 -8
  93. package/lib/tools/SessionToolRunner.js.map +1 -1
  94. package/lib/tools/SessionToolRunner.mjs +38 -9
  95. package/lib/tools/SessionToolRunner.mjs.map +1 -1
  96. package/package.json +1 -1
  97. package/resources/beta/agents/agents.d.mts +3 -3
  98. package/resources/beta/agents/agents.d.ts +3 -3
  99. package/resources/beta/agents/agents.js +1 -1
  100. package/resources/beta/agents/agents.mjs +1 -1
  101. package/resources/beta/beta.d.mts +3 -3
  102. package/resources/beta/beta.d.mts.map +1 -1
  103. package/resources/beta/beta.d.ts +3 -3
  104. package/resources/beta/beta.d.ts.map +1 -1
  105. package/resources/beta/beta.js.map +1 -1
  106. package/resources/beta/beta.mjs.map +1 -1
  107. package/resources/beta/dreams.d.mts +2 -2
  108. package/resources/beta/dreams.d.ts +2 -2
  109. package/resources/beta/environments/environments.d.mts +4 -3
  110. package/resources/beta/environments/environments.d.mts.map +1 -1
  111. package/resources/beta/environments/environments.d.ts +4 -3
  112. package/resources/beta/environments/environments.d.ts.map +1 -1
  113. package/resources/beta/environments/environments.js.map +1 -1
  114. package/resources/beta/environments/environments.mjs.map +1 -1
  115. package/resources/beta/index.d.mts +1 -1
  116. package/resources/beta/index.d.mts.map +1 -1
  117. package/resources/beta/index.d.ts +1 -1
  118. package/resources/beta/index.d.ts.map +1 -1
  119. package/resources/beta/index.js.map +1 -1
  120. package/resources/beta/index.mjs.map +1 -1
  121. package/resources/beta/memory-stores/index.d.mts +1 -1
  122. package/resources/beta/memory-stores/index.d.mts.map +1 -1
  123. package/resources/beta/memory-stores/index.d.ts +1 -1
  124. package/resources/beta/memory-stores/index.d.ts.map +1 -1
  125. package/resources/beta/memory-stores/index.js.map +1 -1
  126. package/resources/beta/memory-stores/index.mjs.map +1 -1
  127. package/resources/beta/memory-stores/memory-stores.d.mts +2 -2
  128. package/resources/beta/memory-stores/memory-stores.d.mts.map +1 -1
  129. package/resources/beta/memory-stores/memory-stores.d.ts +2 -2
  130. package/resources/beta/memory-stores/memory-stores.d.ts.map +1 -1
  131. package/resources/beta/memory-stores/memory-stores.js.map +1 -1
  132. package/resources/beta/memory-stores/memory-stores.mjs.map +1 -1
  133. package/resources/beta/memory-stores/memory-versions.d.mts +17 -2
  134. package/resources/beta/memory-stores/memory-versions.d.mts.map +1 -1
  135. package/resources/beta/memory-stores/memory-versions.d.ts +17 -2
  136. package/resources/beta/memory-stores/memory-versions.d.ts.map +1 -1
  137. package/resources/beta/messages/batches.d.mts +1 -1
  138. package/resources/beta/messages/batches.d.ts +1 -1
  139. package/resources/beta/messages/batches.js +1 -1
  140. package/resources/beta/messages/batches.mjs +1 -1
  141. package/resources/beta/messages/index.d.mts +1 -1
  142. package/resources/beta/messages/index.d.mts.map +1 -1
  143. package/resources/beta/messages/index.d.ts +1 -1
  144. package/resources/beta/messages/index.d.ts.map +1 -1
  145. package/resources/beta/messages/index.js.map +1 -1
  146. package/resources/beta/messages/index.mjs.map +1 -1
  147. package/resources/beta/messages/messages.d.mts +4 -22
  148. package/resources/beta/messages/messages.d.mts.map +1 -1
  149. package/resources/beta/messages/messages.d.ts +4 -22
  150. package/resources/beta/messages/messages.d.ts.map +1 -1
  151. package/resources/beta/messages/messages.js +1 -1
  152. package/resources/beta/messages/messages.js.map +1 -1
  153. package/resources/beta/messages/messages.mjs +1 -1
  154. package/resources/beta/messages/messages.mjs.map +1 -1
  155. package/resources/beta/sessions/sessions.d.mts +1 -1
  156. package/resources/beta/sessions/sessions.d.ts +1 -1
  157. package/resources/beta/user-profiles.d.mts +35 -9
  158. package/resources/beta/user-profiles.d.mts.map +1 -1
  159. package/resources/beta/user-profiles.d.ts +35 -9
  160. package/resources/beta/user-profiles.d.ts.map +1 -1
  161. package/resources/beta/user-profiles.js +5 -5
  162. package/resources/beta/user-profiles.mjs +5 -5
  163. package/resources/index.d.mts +1 -1
  164. package/resources/index.d.mts.map +1 -1
  165. package/resources/index.d.ts +1 -1
  166. package/resources/index.d.ts.map +1 -1
  167. package/resources/index.js.map +1 -1
  168. package/resources/index.mjs.map +1 -1
  169. package/resources/messages/batches.d.mts +1 -1
  170. package/resources/messages/batches.d.ts +1 -1
  171. package/resources/messages/batches.js +1 -1
  172. package/resources/messages/batches.mjs +1 -1
  173. package/resources/messages/index.d.mts +1 -1
  174. package/resources/messages/index.d.mts.map +1 -1
  175. package/resources/messages/index.d.ts +1 -1
  176. package/resources/messages/index.d.ts.map +1 -1
  177. package/resources/messages/index.js.map +1 -1
  178. package/resources/messages/index.mjs.map +1 -1
  179. package/resources/messages/messages.d.mts +4 -22
  180. package/resources/messages/messages.d.mts.map +1 -1
  181. package/resources/messages/messages.d.ts +4 -22
  182. package/resources/messages/messages.d.ts.map +1 -1
  183. package/resources/messages/messages.js +1 -1
  184. package/resources/messages/messages.js.map +1 -1
  185. package/resources/messages/messages.mjs +1 -1
  186. package/resources/messages/messages.mjs.map +1 -1
  187. package/src/client.ts +1 -3
  188. package/src/core/api-promise.ts +14 -4
  189. package/src/core/error.ts +2 -0
  190. package/src/core/middleware.ts +2 -2
  191. package/src/helpers/beta/zod.ts +1 -3
  192. package/src/helpers/zod.ts +1 -3
  193. package/src/internal/parse.ts +6 -6
  194. package/src/lib/BetaMessageStream.ts +8 -0
  195. package/src/lib/MessageStream.ts +8 -0
  196. package/src/lib/environments/worker.ts +28 -14
  197. package/src/lib/tools/BetaRunnableTool.ts +20 -44
  198. package/src/lib/tools/BetaToolRunner.ts +0 -12
  199. package/src/lib/tools/SessionToolRunner.ts +39 -6
  200. package/src/resources/beta/agents/agents.ts +3 -3
  201. package/src/resources/beta/beta.ts +1 -2
  202. package/src/resources/beta/dreams.ts +2 -2
  203. package/src/resources/beta/environments/environments.ts +4 -3
  204. package/src/resources/beta/index.ts +0 -1
  205. package/src/resources/beta/memory-stores/index.ts +1 -0
  206. package/src/resources/beta/memory-stores/memory-stores.ts +2 -0
  207. package/src/resources/beta/memory-stores/memory-versions.ts +21 -1
  208. package/src/resources/beta/messages/batches.ts +1 -1
  209. package/src/resources/beta/messages/index.ts +0 -1
  210. package/src/resources/beta/messages/messages.ts +2 -25
  211. package/src/resources/beta/sessions/sessions.ts +1 -1
  212. package/src/resources/beta/user-profiles.ts +44 -15
  213. package/src/resources/index.ts +0 -1
  214. package/src/resources/messages/batches.ts +1 -1
  215. package/src/resources/messages/index.ts +0 -1
  216. package/src/resources/messages/messages.ts +3 -26
  217. package/src/version.ts +1 -1
  218. package/version.d.mts +1 -1
  219. package/version.d.ts +1 -1
  220. package/version.js +1 -1
  221. package/version.mjs +1 -1
package/src/core/error.ts CHANGED
@@ -18,6 +18,7 @@ export class APIError<
18
18
  readonly error: TError;
19
19
 
20
20
  readonly requestID: string | null | undefined;
21
+ readonly workspaceID: string | null | undefined;
21
22
 
22
23
  /** The `error.type` from the API response body, e.g. `"rate_limit_error"` */
23
24
  readonly type: ErrorType | null;
@@ -33,6 +34,7 @@ export class APIError<
33
34
  this.status = status;
34
35
  this.headers = headers;
35
36
  this.requestID = headers?.get('request-id');
37
+ this.workspaceID = headers?.get('anthropic-workspace-id');
36
38
  this.error = error;
37
39
  this.type = type ?? null;
38
40
  }
@@ -1,7 +1,7 @@
1
1
  import type { BaseAnthropic } from '../client';
2
2
  import type { Fetch } from '../internal/builtin-types';
3
3
  import { castToError, isAbortError } from '../internal/errors';
4
- import { addRequestID } from '../internal/parse';
4
+ import { addResponseIDs } from '../internal/parse';
5
5
  import type { FinalRequestOptions } from '../internal/request-options';
6
6
  import { defaultLogger, loggerFor, type Logger } from '../internal/utils/log';
7
7
  import type { APIRequest } from './api';
@@ -299,7 +299,7 @@ async function parseMiddlewareResponse(
299
299
  // if there is no content we can't do anything
300
300
  return undefined;
301
301
  }
302
- return addRequestID(await response.clone().json(), response);
302
+ return addResponseIDs(await response.clone().json(), response);
303
303
  }
304
304
 
305
305
  return await response.clone().text();
@@ -16,9 +16,7 @@ import { BetaToolResultContentBlockParam } from '../../resources/beta';
16
16
  export function betaZodOutputFormat<ZodInput extends z.ZodType>(
17
17
  zodObject: ZodInput,
18
18
  ): AutoParseableBetaOutputFormat<z.infer<ZodInput>> {
19
- let jsonSchema = z.toJSONSchema(zodObject, { reused: 'ref' });
20
-
21
- jsonSchema = transformJSONSchema(jsonSchema);
19
+ const jsonSchema = transformJSONSchema(z.toJSONSchema(zodObject, { reused: 'ref' }));
22
20
 
23
21
  return {
24
22
  type: 'json_schema',
@@ -15,9 +15,7 @@ import { AutoParseableOutputFormat } from '../lib/parser';
15
15
  export function zodOutputFormat<ZodInput extends z.ZodType>(
16
16
  zodObject: ZodInput,
17
17
  ): AutoParseableOutputFormat<z.infer<ZodInput>> {
18
- let jsonSchema = z.toJSONSchema(zodObject, { reused: 'ref' });
19
-
20
- jsonSchema = transformJSONSchema(jsonSchema);
18
+ const jsonSchema = transformJSONSchema(z.toJSONSchema(zodObject, { reused: 'ref' }));
21
19
 
22
20
  return {
23
21
  type: 'json_schema',
@@ -51,7 +51,7 @@ export async function defaultParseResponse<T>(
51
51
  }
52
52
 
53
53
  const json = await response.json();
54
- return addRequestID(json as T, response);
54
+ return addResponseIDs(json as T, response);
55
55
  }
56
56
 
57
57
  const text = await response.text();
@@ -80,16 +80,16 @@ export async function defaultParseResponse<T>(
80
80
 
81
81
  export type WithRequestID<T> =
82
82
  T extends Array<any> | Response | AbstractPage<any> ? T
83
- : T extends Record<string, any> ? T & { _request_id?: string | null }
83
+ : T extends Record<string, any> ? T & { _request_id?: string | null; _workspace_id?: string | null }
84
84
  : T;
85
85
 
86
- export function addRequestID<T>(value: T, response: Response): WithRequestID<T> {
86
+ export function addResponseIDs<T>(value: T, response: Response): WithRequestID<T> {
87
87
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
88
88
  return value as WithRequestID<T>;
89
89
  }
90
90
 
91
- return Object.defineProperty(value, '_request_id', {
92
- value: response.headers.get('request-id'),
93
- enumerable: false,
91
+ return Object.defineProperties(value, {
92
+ _request_id: { value: response.headers.get('request-id'), enumerable: false },
93
+ _workspace_id: { value: response.headers.get('anthropic-workspace-id'), enumerable: false },
94
94
  }) as WithRequestID<T>;
95
95
  }
@@ -74,6 +74,7 @@ export class BetaMessageStream<ParsedT = null> implements AsyncIterable<BetaMess
74
74
  #catchingPromiseCreated = false;
75
75
  #response: Response | null | undefined;
76
76
  #request_id: string | null | undefined;
77
+ #workspace_id: string | null | undefined;
77
78
  #logger: Logger;
78
79
 
79
80
  constructor(params: MessageCreateParamsBase | null, opts?: { logger?: Logger | undefined }) {
@@ -106,6 +107,10 @@ export class BetaMessageStream<ParsedT = null> implements AsyncIterable<BetaMess
106
107
  return this.#request_id;
107
108
  }
108
109
 
110
+ get workspace_id(): string | null | undefined {
111
+ return this.#workspace_id;
112
+ }
113
+
109
114
  /**
110
115
  * Returns the `MessageStream` data, the raw `Response` instance and the ID of the request,
111
116
  * returned vie the `request-id` header which is useful for debugging requests and resporting
@@ -120,6 +125,7 @@ export class BetaMessageStream<ParsedT = null> implements AsyncIterable<BetaMess
120
125
  data: BetaMessageStream<ParsedT>;
121
126
  response: Response;
122
127
  request_id: string | null | undefined;
128
+ workspace_id: string | null | undefined;
123
129
  }> {
124
130
  this.#catchingPromiseCreated = true;
125
131
 
@@ -132,6 +138,7 @@ export class BetaMessageStream<ParsedT = null> implements AsyncIterable<BetaMess
132
138
  data: this,
133
139
  response,
134
140
  request_id: response.headers.get('request-id'),
141
+ workspace_id: response.headers.get('anthropic-workspace-id'),
135
142
  };
136
143
  }
137
144
 
@@ -223,6 +230,7 @@ export class BetaMessageStream<ParsedT = null> implements AsyncIterable<BetaMess
223
230
  if (this.ended) return;
224
231
  this.#response = response;
225
232
  this.#request_id = response?.headers.get('request-id');
233
+ this.#workspace_id = response?.headers.get('anthropic-workspace-id');
226
234
  this.#resolveConnectedPromise(response);
227
235
  this._emit('connect');
228
236
  }
@@ -73,6 +73,7 @@ export class MessageStream<ParsedT = null> implements AsyncIterable<MessageStrea
73
73
  #catchingPromiseCreated = false;
74
74
  #response: Response | null | undefined;
75
75
  #request_id: string | null | undefined;
76
+ #workspace_id: string | null | undefined;
76
77
  #logger: Logger;
77
78
 
78
79
  constructor(params: MessageCreateParamsBase | null, opts?: { logger?: Logger | undefined }) {
@@ -105,6 +106,10 @@ export class MessageStream<ParsedT = null> implements AsyncIterable<MessageStrea
105
106
  return this.#request_id;
106
107
  }
107
108
 
109
+ get workspace_id(): string | null | undefined {
110
+ return this.#workspace_id;
111
+ }
112
+
108
113
  /**
109
114
  * Returns the `MessageStream` data, the raw `Response` instance and the ID of the request,
110
115
  * returned vie the `request-id` header which is useful for debugging requests and resporting
@@ -119,6 +124,7 @@ export class MessageStream<ParsedT = null> implements AsyncIterable<MessageStrea
119
124
  data: MessageStream<ParsedT>;
120
125
  response: Response;
121
126
  request_id: string | null | undefined;
127
+ workspace_id: string | null | undefined;
122
128
  }> {
123
129
  this.#catchingPromiseCreated = true;
124
130
 
@@ -131,6 +137,7 @@ export class MessageStream<ParsedT = null> implements AsyncIterable<MessageStrea
131
137
  data: this,
132
138
  response,
133
139
  request_id: response.headers.get('request-id'),
140
+ workspace_id: response.headers.get('anthropic-workspace-id'),
134
141
  };
135
142
  }
136
143
 
@@ -222,6 +229,7 @@ export class MessageStream<ParsedT = null> implements AsyncIterable<MessageStrea
222
229
  if (this.ended) return;
223
230
  this.#response = response;
224
231
  this.#request_id = response?.headers.get('request-id');
232
+ this.#workspace_id = response?.headers.get('anthropic-workspace-id');
225
233
  this.#resolveConnectedPromise(response);
226
234
  this._emit('connect');
227
235
  }
@@ -52,6 +52,10 @@ export interface EnvironmentWorkerOptions {
52
52
  * Tools to expose to each claimed session. Defaults to
53
53
  * `betaAgentToolset20260401(ctx)` (the standard `agent_toolset_20260401` set
54
54
  * bound to the per-session {@link AgentToolContext}).
55
+ *
56
+ * A `run` that blocks the event loop synchronously also stalls the lease
57
+ * heartbeat, and the worker can lose the lease; keep tools non-blocking (see
58
+ * {@link BetaRunnableTool.run}).
55
59
  */
56
60
  tools?: EnvironmentWorkerTools;
57
61
  /** Base directory for the per-session {@link AgentToolContext}. Defaults to `process.cwd()`. */
@@ -110,10 +114,10 @@ type ClaimedWork = Pick<BetaSelfHostedWork, 'id' | 'environment_id' | 'data'>;
110
114
  * For each claimed `session` work item it: builds the per-session
111
115
  * {@link AgentToolContext}, downloads the session agent's skills
112
116
  * (`setupSkills`), then runs a {@link SessionToolRunner} for the session
113
- * *while* heartbeating the work-item lease in parallel; on exit it force-stops
114
- * the work item, cleans up the downloaded skills, and loops to the next one. The
115
- * lease heartbeat reports `state === "stopping"` / a lost lease back into the run
116
- * by aborting the session runner.
117
+ * while heartbeating the work-item lease on the same event loop; on exit it
118
+ * force-stops the work item, cleans up the downloaded skills, and loops to the
119
+ * next one. The lease heartbeat reports `state === "stopping"` / a lost lease
120
+ * back into the run by aborting the session runner.
117
121
  *
118
122
  * Use {@link EnvironmentWorker.handleItem} if you already hold a claimed work
119
123
  * item (e.g. a `worker poll --on-work` script handed one to a fresh process) and
@@ -196,8 +200,8 @@ export class EnvironmentWorker {
196
200
  * per-session {@link AgentToolContext} (workdir from this worker's options),
197
201
  * download the session agent's skills (`setupSkills`), run a
198
202
  * {@link SessionToolRunner} for the session while heartbeating the work-item
199
- * lease in parallel, and force-stop the work item on exit (whether the runner
200
- * finishes normally, throws, or the heartbeat loop signals shutdown).
203
+ * lease, and force-stop the work item on exit (whether the runner finishes
204
+ * normally, throws, or the heartbeat loop signals shutdown).
201
205
  *
202
206
  * Use this when something else does the claiming — e.g. a `worker poll
203
207
  * --on-work` script that hands an already-claimed item to a fresh process. The
@@ -293,19 +297,26 @@ export class EnvironmentWorker {
293
297
  const ctrl = new AbortController();
294
298
  const detachExternal = linkAbort(externalSignal, ctrl);
295
299
 
296
- const heartbeatPromise = heartbeatLoop(sessionClient, work, ctrl, log, this.requestOptions).catch((e) => {
300
+ // Inert until iterated below.
301
+ const runner = new SessionToolRunner(sessionId, {
302
+ client: sessionClient,
303
+ tools,
304
+ ...(this.maxIdleMs !== undefined ? { maxIdleMs: this.maxIdleMs } : {}),
305
+ ...(this.requestOptions !== undefined ? { requestOptions: this.requestOptions } : {}),
306
+ signal: ctrl.signal,
307
+ });
308
+
309
+ // Each heartbeat reports the lease TTL the server is enforcing; it becomes
310
+ // the runner's tool-result send retry window so a send keeps retrying
311
+ // exactly as long as the lease could still be live.
312
+ const heartbeatPromise = heartbeatLoop(sessionClient, work, ctrl, log, this.requestOptions, (ttlMs) =>
313
+ runner._setSendRetryWindow(ttlMs),
314
+ ).catch((e) => {
297
315
  if (!ctrl.signal.aborted) log.error('heartbeat loop failed', { work_id: work.id, error: String(e) });
298
316
  ctrl.abort();
299
317
  });
300
318
 
301
319
  try {
302
- const runner = new SessionToolRunner(sessionId, {
303
- client: sessionClient,
304
- tools,
305
- ...(this.maxIdleMs !== undefined ? { maxIdleMs: this.maxIdleMs } : {}),
306
- ...(this.requestOptions !== undefined ? { requestOptions: this.requestOptions } : {}),
307
- signal: ctrl.signal,
308
- });
309
320
  for await (const _ of runner) {
310
321
  // Drive the runner to completion; per-call observability is not part
311
322
  // of this composition's surface — use `SessionToolRunner` directly
@@ -360,6 +371,8 @@ async function heartbeatLoop(
360
371
  ctrl: AbortController,
361
372
  logger: Logger,
362
373
  requestOptions?: BetaToolRunnerRequestOptions,
374
+ /** Called with the server-reported lease TTL after every successful beat. */
375
+ onLeaseTtl?: (ttlMs: number) => void,
363
376
  ): Promise<void> {
364
377
  let intervalMs = HEARTBEAT_DEFAULT_MS;
365
378
  let ttlMs = HEARTBEAT_TTL_DEFAULT_MS;
@@ -382,6 +395,7 @@ async function heartbeatLoop(
382
395
  if (resp.ttl_seconds > 0) {
383
396
  ttlMs = resp.ttl_seconds * 1000;
384
397
  intervalMs = Math.max(1_000, Math.min(ttlMs / 2, HEARTBEAT_DEFAULT_MS));
398
+ onLeaseTtl?.(ttlMs);
385
399
  }
386
400
  if (resp.state === 'stopping' || resp.state === 'stopped') {
387
401
  logger.info('heartbeat signals shutdown', { work_id: work.id, state: resp.state });
@@ -22,10 +22,7 @@ import { ToolError } from './ToolError';
22
22
 
23
23
  export type Promisable<T> = T | Promise<T>;
24
24
 
25
- /**
26
- * Tool types that can be implemented on the client.
27
- * Excludes server-side tools like code execution, web search, and MCP toolsets.
28
- */
25
+ /** Tools that run on the client. Server-side tools (code execution, web search, MCP toolsets) are not included. */
29
26
  export type BetaClientRunnableToolType =
30
27
  | BetaTool
31
28
  | BetaMemoryTool20250818
@@ -40,15 +37,9 @@ export type BetaClientRunnableToolType =
40
37
  | BetaToolTextEditor20250728;
41
38
 
42
39
  /**
43
- * The tool-use that triggered a {@link BetaRunnableTool.run}:
44
- *
45
- * - from `client.beta.messages.toolRunner`, a Messages `tool_use` content block;
46
- * - from `client.beta.sessions.events.toolRunner`, the `agent.tool_use` /
47
- * `agent.custom_tool_use` session event.
48
- *
49
- * The shapes overlap on the common fields (`id`, `name`, `input`), so code that
50
- * only reads those works without narrowing; narrow on the shape (e.g. `'type' in
51
- * x`) when you need surface-specific properties.
40
+ * The tool call being served: a Messages `tool_use` block, or a session
41
+ * `agent.tool_use` / `agent.custom_tool_use` event. All three carry `id`,
42
+ * `name` and `input`.
52
43
  */
53
44
  export type BetaToolUse =
54
45
  | BetaToolUseBlock
@@ -56,65 +47,50 @@ export type BetaToolUse =
56
47
  | BetaManagedAgentsAgentCustomToolUseEvent;
57
48
 
58
49
  export type BetaToolRunContext = {
59
- /** The tool-use that triggered this run. See {@link BetaToolUse}. */
60
50
  toolUse: BetaToolUse;
51
+ /** @deprecated Use `toolUse`. */
52
+ toolUseBlock: BetaToolUse;
61
53
  /**
62
- * @deprecated Renamed to `toolUse`. Also note that for
63
- * `client.beta.sessions.events.toolRunner` this is the `agent.tool_use` /
64
- * `agent.custom_tool_use` *event*, not a Messages content block, despite the
65
- * name — which is why it was renamed.
54
+ * Aborted when the runner is aborted or, in the session runner, when the
55
+ * per-tool timeout fires. The runner still waits for `run` to return, so
56
+ * check it in long-running work.
66
57
  */
67
- toolUseBlock: BetaToolUse;
68
58
  signal?: AbortSignal | null | undefined;
69
59
  };
70
60
 
71
- // this type is just an extension of BetaTool with a run and parse method
72
- // that will be called by `toolRunner()` helpers
61
+ /** A tool definition plus the `run` and `parse` the tool runners call. */
73
62
  export type BetaRunnableTool<Input = any> = BetaClientRunnableToolType & {
63
+ /**
64
+ * Runs on the event loop: a body that blocks synchronously stalls the runner
65
+ * and, in an `EnvironmentWorker`, the lease heartbeat. Await async work or
66
+ * move it to a worker thread.
67
+ */
74
68
  run: (
75
69
  args: Input,
76
70
  context?: BetaToolRunContext,
77
71
  ) => Promisable<string | Array<BetaToolResultContentBlockParam>>;
78
72
  parse: (content: unknown) => Input;
79
- /**
80
- * Optional cleanup hook for tools that hold process-level resources (e.g. a
81
- * persistent shell). `SessionToolRunner` (`client.beta.sessions.events.toolRunner`)
82
- * calls it once when iteration ends.
83
- */
73
+ /** Called once by the session runner when it stops. Release held resources here (e.g. a shell). */
84
74
  close?: () => Promisable<void>;
85
75
  };
86
76
 
87
- /**
88
- * Resolve the registry key for a tool — the name the model addresses it by.
89
- * MCP toolsets are keyed on `mcp_server_name`; every other tool on `name`.
90
- * Shared so the tool-name lookup is identical across `toolRunner()` surfaces.
91
- */
77
+ /** The name the model calls a tool by: `mcp_server_name` for MCP toolsets, `name` for everything else. */
92
78
  export function toolName(tool: BetaToolUnion | BetaRunnableTool): string {
93
79
  return 'name' in tool ? tool.name : tool.mcp_server_name;
94
80
  }
95
81
 
96
- /**
97
- * Format a thrown value into tool-result content: a {@link ToolError} carries
98
- * its own structured content, anything else becomes an `Error: <message>`
99
- * string. Shared so every `toolRunner()` surface reports tool failures the
100
- * same way to the model.
101
- */
82
+ /** Tool-result content for a thrown value: a {@link ToolError}'s own content, otherwise `Error: <message>`. */
102
83
  export function toolErrorContent(e: unknown): string | Array<BetaToolResultContentBlockParam> {
103
84
  return e instanceof ToolError ? e.content : `Error: ${e instanceof Error ? e.message : String(e)}`;
104
85
  }
105
86
 
106
- /** Outcome of {@link runRunnableTool}: the content to post back and whether it is an error. */
87
+ /** What a tool run produced, and whether it failed. */
107
88
  export interface RunnableToolOutcome {
108
89
  content: string | Array<BetaToolResultContentBlockParam>;
109
90
  isError: boolean;
110
91
  }
111
92
 
112
- /**
113
- * Run a {@link BetaRunnableTool} end-to-end: parse the raw input, invoke `run`,
114
- * and format any thrown value via {@link toolErrorContent}. Shared so the
115
- * parse → run → catch → format pipeline is identical across `toolRunner()`
116
- * surfaces.
117
- */
93
+ /** Parse the input, run the tool, and turn anything thrown into an error result. */
118
94
  export async function runRunnableTool(
119
95
  tool: BetaRunnableTool,
120
96
  rawInput: unknown,
@@ -578,18 +578,6 @@ function applyToolChange(block: BetaContentBlockParam, available: Set<string>):
578
578
  case 'tool_addition':
579
579
  applyToolReference(block, available);
580
580
  break;
581
- case 'mid_conv_system':
582
- // A `mid_conv_system` block's content is limited by the API schema to
583
- // text / tool_addition / tool_removal, so we walk exactly one level — no recursion.
584
- for (const inner of block.content) {
585
- if (inner.type === 'tool_removal' || inner.type === 'tool_addition') {
586
- applyToolReference(inner, available);
587
- }
588
- }
589
- break;
590
- default:
591
- // Other and unknown/newer block types leave the set untouched (forward compatibility).
592
- break;
593
581
  }
594
582
  }
595
583
 
@@ -11,7 +11,7 @@ import type {
11
11
  import type { BetaToolResultContentBlockParam } from '../../resources/beta';
12
12
  import { loggerFor, type Logger } from '../../internal/utils/log';
13
13
  import { sleep } from '../../internal/utils/sleep';
14
- import { isFatal4xx } from '../../internal/utils/backoff';
14
+ import { applyJitter, backoff, isFatal4xx } from '../../internal/utils/backoff';
15
15
  import { linkAbort } from '../../internal/utils/abort';
16
16
  import { AsyncQueue } from '../../internal/utils/async-queue';
17
17
  import { buildHeaders } from '../../internal/headers';
@@ -27,7 +27,16 @@ const STREAM_BACKOFF_START_MS = 500;
27
27
  const STREAM_BACKOFF_CAP_MS = 10_000;
28
28
  const TOOL_TIMEOUT_MS = 120_000;
29
29
  const DRAIN_TIMEOUT_MS = 30_000;
30
- const SEND_RETRIES = 3;
30
+ const SEND_BACKOFF_START_MS = 1_000;
31
+ const SEND_BACKOFF_CAP_MS = 30_000;
32
+ /**
33
+ * How long a transiently failing tool-result send keeps retrying when the
34
+ * runner is used on its own: the server's default work-item lease TTL.
35
+ * `EnvironmentWorker` overrides it with the live TTL from each lease heartbeat
36
+ * (`_setSendRetryWindow`), so a send is only abandoned once the lease can no
37
+ * longer be ours.
38
+ */
39
+ const SEND_RETRY_WINDOW_MS = 5 * 60_000;
31
40
 
32
41
  /** Block type accepted in a `user.tool_result` event's content — codegen'd, stays in sync with the API. */
33
42
  type SessionContentBlock = NonNullable<BetaManagedAgentsUserToolResultEventParams['content']>[number];
@@ -310,6 +319,7 @@ export class SessionToolRunner implements AsyncIterable<DispatchedToolCall> {
310
319
  readonly #awaitingConfirmation = new Map<string, DispatchedToolUseEvent>();
311
320
  readonly #results = new AsyncQueue<DispatchedToolCall>();
312
321
  #inFlightCount = 0;
322
+ #sendRetryWindowMs = SEND_RETRY_WINDOW_MS;
313
323
  #onIdle: (() => void) | null = null;
314
324
  readonly #idleClock: IdleClock;
315
325
 
@@ -343,6 +353,15 @@ export class SessionToolRunner implements AsyncIterable<DispatchedToolCall> {
343
353
  this.#controller.abort();
344
354
  }
345
355
 
356
+ /**
357
+ * @internal
358
+ * `EnvironmentWorker` keeps this equal to the lease TTL each heartbeat
359
+ * reports; applies to a send already retrying.
360
+ */
361
+ _setSendRetryWindow(ms: number): void {
362
+ this.#sendRetryWindowMs = ms;
363
+ }
364
+
346
365
  async *[Symbol.asyncIterator](): AsyncIterator<DispatchedToolCall> {
347
366
  if (this.#consumed) {
348
367
  throw new AnthropicError('Cannot iterate over a consumed SessionToolRunner');
@@ -764,8 +783,11 @@ export class SessionToolRunner implements AsyncIterable<DispatchedToolCall> {
764
783
 
765
784
  async #sendResult(result: DispatchedToolResultParams, toolUseId: string): Promise<boolean> {
766
785
  const ctrl = this.#controller;
786
+ const start = Date.now();
767
787
  let lastErr: unknown;
768
- for (let i = 0; i < SEND_RETRIES; i++) {
788
+ let attempt = 0;
789
+ while (true) {
790
+ attempt++;
769
791
  // An abort throws to unwind the caller rather than returning a
770
792
  // `posted: false` result the iterator would carry on past.
771
793
  ctrl.signal.throwIfAborted();
@@ -782,13 +804,24 @@ export class SessionToolRunner implements AsyncIterable<DispatchedToolCall> {
782
804
  // Only short-circuit on a permanent 4xx; 408/409/429 deserve the
783
805
  // remaining retries (aligned with the core client's retry policy).
784
806
  if (isFatal4xx(e)) break;
785
- // Back off only *between* attempts never after the final one, since
786
- // there is no further try left to wait for.
787
- if (i < SEND_RETRIES - 1) await sleep((i + 1) * 1000, ctrl.signal);
807
+ const remainingMs = this.#sendRetryWindowMs - (Date.now() - start);
808
+ if (remainingMs <= 0) break;
809
+ const waitMs = Math.min(
810
+ applyJitter(backoff(attempt - 1, SEND_BACKOFF_START_MS, SEND_BACKOFF_CAP_MS)),
811
+ remainingMs,
812
+ );
813
+ this.#logger.warn('tool result send failed; retrying', {
814
+ tool_use_id: toolUseId,
815
+ attempt,
816
+ backoff_ms: waitMs,
817
+ error: String(e),
818
+ });
819
+ await sleep(waitMs, ctrl.signal);
788
820
  }
789
821
  }
790
822
  this.#logger.error('failed to send tool result', {
791
823
  tool_use_id: toolUseId,
824
+ attempts: attempt,
792
825
  error: String(lastErr),
793
826
  });
794
827
  return false;
@@ -21,7 +21,7 @@ export class Agents extends APIResource {
21
21
  * ```ts
22
22
  * const betaManagedAgentsAgent =
23
23
  * await client.beta.agents.create({
24
- * model: 'claude-sonnet-4-6',
24
+ * model: 'claude-opus-5',
25
25
  * name: 'My First Agent',
26
26
  * });
27
27
  * ```
@@ -915,7 +915,7 @@ export interface AgentCreateParams {
915
915
  /**
916
916
  * Body param: Model identifier. Accepts the
917
917
  * [model string](https://platform.claude.com/docs/en/about-claude/models/overview#latest-models-comparison),
918
- * e.g. `claude-opus-4-6`, or a `model_config` object for additional configuration
918
+ * e.g. `claude-opus-5`, or a `model_config` object for additional configuration
919
919
  * control
920
920
  */
921
921
  model: BetaManagedAgentsModel | BetaManagedAgentsModelConfigParams;
@@ -1015,7 +1015,7 @@ export interface AgentUpdateParams {
1015
1015
  /**
1016
1016
  * Body param: Model identifier. Accepts the
1017
1017
  * [model string](https://platform.claude.com/docs/en/about-claude/models/overview#latest-models-comparison),
1018
- * e.g. `claude-opus-4-6`, or a `model_config` object for additional configuration
1018
+ * e.g. `claude-opus-5`, or a `model_config` object for additional configuration
1019
1019
  * control. Omit to preserve. Cannot be cleared.
1020
1020
  */
1021
1021
  model?: BetaManagedAgentsModel | BetaManagedAgentsModelConfigParams;
@@ -403,7 +403,6 @@ import {
403
403
  BetaMessageParam,
404
404
  BetaMessageTokensCount,
405
405
  BetaMetadata,
406
- BetaMidConversationSystemBlockParam,
407
406
  BetaOutputConfig,
408
407
  BetaOutputTokensDetails,
409
408
  BetaPlainTextSource,
@@ -646,6 +645,7 @@ export type AnthropicBeta =
646
645
  | 'fast-mode-2026-02-01'
647
646
  | 'output-300k-2026-03-24'
648
647
  | 'user-profiles-2026-03-24'
648
+ | 'user-profiles-2026-08-18'
649
649
  | 'advisor-tool-2026-03-01'
650
650
  | 'managed-agents-2026-04-01'
651
651
  | 'cache-diagnosis-2026-04-07'
@@ -924,7 +924,6 @@ export declare namespace Beta {
924
924
  type BetaMessageParam as BetaMessageParam,
925
925
  type BetaMessageTokensCount as BetaMessageTokensCount,
926
926
  type BetaMetadata as BetaMetadata,
927
- type BetaMidConversationSystemBlockParam as BetaMidConversationSystemBlockParam,
928
927
  type BetaOutputConfig as BetaOutputConfig,
929
928
  type BetaOutputTokensDetails as BetaOutputTokensDetails,
930
929
  type BetaPlainTextSource as BetaPlainTextSource,
@@ -243,7 +243,7 @@ export interface BetaDreamMemoryStoreOutput {
243
243
  */
244
244
  export interface BetaDreamModelConfig {
245
245
  /**
246
- * Model identifier, e.g. "claude-opus-4-7". 1-256 characters.
246
+ * Model identifier, e.g. "claude-opus-5". 1-256 characters.
247
247
  */
248
248
  id: string;
249
249
 
@@ -260,7 +260,7 @@ export interface BetaDreamModelConfig {
260
260
  */
261
261
  export interface BetaDreamModelConfigParam {
262
262
  /**
263
- * Model identifier, e.g. "claude-opus-4-7". 1-256 characters.
263
+ * Model identifier, e.g. "claude-opus-5". 1-256 characters.
264
264
  */
265
265
  id: string;
266
266
 
@@ -260,9 +260,9 @@ export interface BetaEnvironment {
260
260
  created_at: string;
261
261
 
262
262
  /**
263
- * User-provided description for the environment
263
+ * User-provided description for the environment; null when unset
264
264
  */
265
- description: string;
265
+ description: string | null;
266
266
 
267
267
  /**
268
268
  * User-provided metadata key-value pairs
@@ -525,7 +525,8 @@ export interface EnvironmentUpdateParams {
525
525
  config?: BetaCloudConfigParams | BetaSelfHostedConfigParams | null;
526
526
 
527
527
  /**
528
- * Body param: Updated description of the environment
528
+ * Body param: Updated description of the environment. Omit to preserve; null
529
+ * clears to null; an empty string is stored as an empty string.
529
530
  */
530
531
  description?: string | null;
531
532
 
@@ -336,7 +336,6 @@ export {
336
336
  type BetaMessageParam,
337
337
  type BetaMessageTokensCount,
338
338
  type BetaMetadata,
339
- type BetaMidConversationSystemBlockParam,
340
339
  type BetaOutputConfig,
341
340
  type BetaOutputTokensDetails,
342
341
  type BetaPlainTextSource,
@@ -38,6 +38,7 @@ export {
38
38
  type BetaManagedAgentsAPIActor,
39
39
  type BetaManagedAgentsMemoryVersion,
40
40
  type BetaManagedAgentsMemoryVersionOperation,
41
+ type BetaManagedAgentsServiceAccountActor,
41
42
  type BetaManagedAgentsSessionActor,
42
43
  type BetaManagedAgentsUserActor,
43
44
  type MemoryVersionRetrieveParams,
@@ -30,6 +30,7 @@ import {
30
30
  BetaManagedAgentsMemoryVersion,
31
31
  BetaManagedAgentsMemoryVersionOperation,
32
32
  BetaManagedAgentsMemoryVersionsPageCursor,
33
+ BetaManagedAgentsServiceAccountActor,
33
34
  BetaManagedAgentsSessionActor,
34
35
  BetaManagedAgentsUserActor,
35
36
  MemoryVersionListParams,
@@ -408,6 +409,7 @@ export declare namespace MemoryStores {
408
409
  type BetaManagedAgentsAPIActor as BetaManagedAgentsAPIActor,
409
410
  type BetaManagedAgentsMemoryVersion as BetaManagedAgentsMemoryVersion,
410
411
  type BetaManagedAgentsMemoryVersionOperation as BetaManagedAgentsMemoryVersionOperation,
412
+ type BetaManagedAgentsServiceAccountActor as BetaManagedAgentsServiceAccountActor,
411
413
  type BetaManagedAgentsSessionActor as BetaManagedAgentsSessionActor,
412
414
  type BetaManagedAgentsUserActor as BetaManagedAgentsUserActor,
413
415
  type BetaManagedAgentsMemoryVersionsPageCursor as BetaManagedAgentsMemoryVersionsPageCursor,