anthropic 0.72.0__py3-none-any.whl → 0.73.0__py3-none-any.whl

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 (43) hide show
  1. anthropic/__init__.py +2 -0
  2. anthropic/_compat.py +6 -0
  3. anthropic/_models.py +50 -16
  4. anthropic/_streaming.py +4 -6
  5. anthropic/_utils/_sync.py +3 -31
  6. anthropic/_utils/_transform.py +1 -1
  7. anthropic/_utils/_utils.py +1 -1
  8. anthropic/_version.py +1 -1
  9. anthropic/lib/_parse/_response.py +44 -0
  10. anthropic/lib/_parse/_transform.py +167 -0
  11. anthropic/lib/streaming/__init__.py +14 -4
  12. anthropic/lib/streaming/_beta_messages.py +82 -43
  13. anthropic/lib/streaming/_beta_types.py +21 -13
  14. anthropic/lib/tools/_beta_runner.py +102 -101
  15. anthropic/resources/beta/messages/batches.py +12 -12
  16. anthropic/resources/beta/messages/messages.py +365 -29
  17. anthropic/resources/messages/batches.py +12 -12
  18. anthropic/resources/messages/messages.py +14 -8
  19. anthropic/types/beta/__init__.py +1 -0
  20. anthropic/types/beta/beta_code_execution_tool_20250522_param.py +2 -0
  21. anthropic/types/beta/beta_code_execution_tool_20250825_param.py +2 -0
  22. anthropic/types/beta/beta_json_output_format_param.py +15 -0
  23. anthropic/types/beta/beta_memory_tool_20250818_param.py +2 -0
  24. anthropic/types/beta/beta_tool_bash_20241022_param.py +2 -0
  25. anthropic/types/beta/beta_tool_bash_20250124_param.py +2 -0
  26. anthropic/types/beta/beta_tool_computer_use_20241022_param.py +2 -0
  27. anthropic/types/beta/beta_tool_computer_use_20250124_param.py +2 -0
  28. anthropic/types/beta/beta_tool_param.py +2 -0
  29. anthropic/types/beta/beta_tool_text_editor_20241022_param.py +2 -0
  30. anthropic/types/beta/beta_tool_text_editor_20250124_param.py +2 -0
  31. anthropic/types/beta/beta_tool_text_editor_20250429_param.py +2 -0
  32. anthropic/types/beta/beta_tool_text_editor_20250728_param.py +2 -0
  33. anthropic/types/beta/beta_web_fetch_tool_20250910_param.py +2 -0
  34. anthropic/types/beta/beta_web_search_tool_20250305_param.py +2 -0
  35. anthropic/types/beta/message_count_tokens_params.py +4 -0
  36. anthropic/types/beta/message_create_params.py +24 -2
  37. anthropic/types/beta/messages/batch_create_params.py +8 -2
  38. anthropic/types/beta/parsed_beta_message.py +68 -0
  39. anthropic/types/messages/batch_create_params.py +0 -1
  40. {anthropic-0.72.0.dist-info → anthropic-0.73.0.dist-info}/METADATA +4 -5
  41. {anthropic-0.72.0.dist-info → anthropic-0.73.0.dist-info}/RECORD +43 -39
  42. {anthropic-0.72.0.dist-info → anthropic-0.73.0.dist-info}/WHEEL +0 -0
  43. {anthropic-0.72.0.dist-info → anthropic-0.73.0.dist-info}/licenses/LICENSE +0 -0
@@ -15,13 +15,14 @@ from typing import (
15
15
  Coroutine,
16
16
  AsyncIterator,
17
17
  )
18
+ from contextlib import contextmanager, asynccontextmanager
18
19
  from typing_extensions import TypedDict, override
19
20
 
20
21
  import httpx
21
22
 
22
23
  from ..._types import Body, Query, Headers, NotGiven
23
24
  from ..._utils import consume_sync_iterator, consume_async_iterator
24
- from ...types.beta import BetaMessage, BetaContentBlock, BetaMessageParam
25
+ from ...types.beta import BetaMessage, BetaMessageParam
25
26
  from ._beta_functions import (
26
27
  BetaFunctionTool,
27
28
  BetaRunnableTool,
@@ -31,7 +32,8 @@ from ._beta_functions import (
31
32
  BetaAsyncBuiltinFunctionTool,
32
33
  )
33
34
  from ..streaming._beta_messages import BetaMessageStream, BetaAsyncMessageStream
34
- from ...types.beta.message_create_params import MessageCreateParamsBase
35
+ from ...types.beta.parsed_beta_message import ResponseFormatT, ParsedBetaMessage, ParsedBetaContentBlock
36
+ from ...types.beta.message_create_params import ParseMessageCreateParamsBase
35
37
  from ...types.beta.beta_tool_result_block_param import BetaToolResultBlockParam
36
38
 
37
39
  if TYPE_CHECKING:
@@ -56,17 +58,17 @@ class RequestOptions(TypedDict, total=False):
56
58
  timeout: float | httpx.Timeout | None | NotGiven
57
59
 
58
60
 
59
- class BaseToolRunner(Generic[AnyFunctionToolT]):
61
+ class BaseToolRunner(Generic[AnyFunctionToolT, ResponseFormatT]):
60
62
  def __init__(
61
63
  self,
62
64
  *,
63
- params: MessageCreateParamsBase,
65
+ params: ParseMessageCreateParamsBase[ResponseFormatT],
64
66
  options: RequestOptions,
65
67
  tools: Iterable[AnyFunctionToolT],
66
68
  max_iterations: int | None = None,
67
69
  ) -> None:
68
70
  self._tools_by_name = {tool.name: tool for tool in tools}
69
- self._params: MessageCreateParamsBase = {
71
+ self._params: ParseMessageCreateParamsBase[ResponseFormatT] = {
70
72
  **params,
71
73
  "messages": [message for message in params["messages"]],
72
74
  }
@@ -77,19 +79,21 @@ class BaseToolRunner(Generic[AnyFunctionToolT]):
77
79
  self._iteration_count = 0
78
80
 
79
81
  def set_messages_params(
80
- self, params: MessageCreateParamsBase | Callable[[MessageCreateParamsBase], MessageCreateParamsBase]
82
+ self,
83
+ params: ParseMessageCreateParamsBase[ResponseFormatT]
84
+ | Callable[[ParseMessageCreateParamsBase[ResponseFormatT]], ParseMessageCreateParamsBase[ResponseFormatT]],
81
85
  ) -> None:
82
86
  """
83
87
  Update the parameters for the next API call. This invalidates any cached tool responses.
84
88
 
85
89
  Args:
86
- params (MessageCreateParamsBase | Callable): Either new parameters or a function to mutate existing parameters
90
+ params (ParsedMessageCreateParamsBase[ResponseFormatT] | Callable): Either new parameters or a function to mutate existing parameters
87
91
  """
88
92
  if callable(params):
89
93
  params = params(self._params)
90
94
  self._params = params
91
95
 
92
- def append_messages(self, *messages: BetaMessageParam | BetaMessage) -> None:
96
+ def append_messages(self, *messages: BetaMessageParam | ParsedBetaMessage[ResponseFormatT]) -> None:
93
97
  """Add one or more messages to the conversation history.
94
98
 
95
99
  This invalidates the cached tool response, i.e. if tools were already called, then they will
@@ -109,11 +113,11 @@ class BaseToolRunner(Generic[AnyFunctionToolT]):
109
113
  return False
110
114
 
111
115
 
112
- class BaseSyncToolRunner(BaseToolRunner[BetaRunnableTool], Generic[RunnerItemT], ABC):
116
+ class BaseSyncToolRunner(BaseToolRunner[BetaRunnableTool, ResponseFormatT], Generic[RunnerItemT, ResponseFormatT], ABC):
113
117
  def __init__(
114
118
  self,
115
119
  *,
116
- params: MessageCreateParamsBase,
120
+ params: ParseMessageCreateParamsBase[ResponseFormatT],
117
121
  options: RequestOptions,
118
122
  tools: Iterable[BetaRunnableTool],
119
123
  client: Anthropic,
@@ -122,7 +126,9 @@ class BaseSyncToolRunner(BaseToolRunner[BetaRunnableTool], Generic[RunnerItemT],
122
126
  super().__init__(params=params, options=options, tools=tools, max_iterations=max_iterations)
123
127
  self._client = client
124
128
  self._iterator = self.__run__()
125
- self._last_message: Callable[[], BetaMessage] | BetaMessage | None = None
129
+ self._last_message: (
130
+ Callable[[], ParsedBetaMessage[ResponseFormatT]] | ParsedBetaMessage[ResponseFormatT] | None
131
+ ) = None
126
132
 
127
133
  def __next__(self) -> RunnerItemT:
128
134
  return self._iterator.__next__()
@@ -132,10 +138,37 @@ class BaseSyncToolRunner(BaseToolRunner[BetaRunnableTool], Generic[RunnerItemT],
132
138
  yield item
133
139
 
134
140
  @abstractmethod
135
- def __run__(self) -> Iterator[RunnerItemT]:
141
+ @contextmanager
142
+ def _handle_request(self) -> Iterator[RunnerItemT]:
136
143
  raise NotImplementedError()
144
+ yield # type: ignore[unreachable]
145
+
146
+ def __run__(self) -> Iterator[RunnerItemT]:
147
+ with self._handle_request() as item:
148
+ yield item
149
+ message = self._get_last_message()
150
+ assert message is not None
151
+ self._iteration_count += 1
137
152
 
138
- def until_done(self) -> BetaMessage:
153
+ while not self._should_stop():
154
+ response = self.generate_tool_call_response()
155
+ if response is None:
156
+ log.debug("Tool call was not requested, exiting from tool runner loop.")
157
+ return
158
+
159
+ if not self._messages_modified:
160
+ self.append_messages(message, response)
161
+
162
+ self._iteration_count += 1
163
+ self._messages_modified = False
164
+ self._cached_tool_call_response = None
165
+
166
+ with self._handle_request() as item:
167
+ yield item
168
+ message = self._get_last_message()
169
+ assert message is not None
170
+
171
+ def until_done(self) -> ParsedBetaMessage[ResponseFormatT]:
139
172
  """
140
173
  Consumes the tool runner stream and returns the last message if it has not been consumed yet.
141
174
  If it has, it simply returns the last message.
@@ -199,12 +232,12 @@ class BaseSyncToolRunner(BaseToolRunner[BetaRunnableTool], Generic[RunnerItemT],
199
232
 
200
233
  return {"role": "user", "content": results}
201
234
 
202
- def _get_last_message(self) -> BetaMessage | None:
235
+ def _get_last_message(self) -> ParsedBetaMessage[ResponseFormatT] | None:
203
236
  if callable(self._last_message):
204
237
  return self._last_message()
205
238
  return self._last_message
206
239
 
207
- def _get_last_assistant_message_content(self) -> list[BetaContentBlock] | None:
240
+ def _get_last_assistant_message_content(self) -> list[ParsedBetaContentBlock[ResponseFormatT]] | None:
208
241
  last_message = self._get_last_message()
209
242
  if last_message is None or last_message.role != "assistant" or not last_message.content:
210
243
  return None
@@ -212,61 +245,31 @@ class BaseSyncToolRunner(BaseToolRunner[BetaRunnableTool], Generic[RunnerItemT],
212
245
  return last_message.content
213
246
 
214
247
 
215
- class BetaToolRunner(BaseSyncToolRunner[BetaMessage]):
248
+ class BetaToolRunner(BaseSyncToolRunner[ParsedBetaMessage[ResponseFormatT], ResponseFormatT]):
216
249
  @override
217
- def __run__(self) -> Iterator[BetaMessage]:
218
- self._last_message = message = self._client.beta.messages.create(**self._params, **self._options)
250
+ @contextmanager
251
+ def _handle_request(self) -> Iterator[ParsedBetaMessage[ResponseFormatT]]:
252
+ message = self._client.beta.messages.parse(**self._params, **self._options)
253
+ self._last_message = message
219
254
  yield message
220
- self._iteration_count += 1
221
-
222
- while not self._should_stop():
223
- response = self.generate_tool_call_response()
224
- if response is None:
225
- log.debug("Tool call was not requested, exiting from tool runner loop.")
226
- return
227
-
228
- if not self._messages_modified:
229
- self.append_messages(message, response)
230
-
231
- self._iteration_count += 1
232
- self._messages_modified = False
233
- self._cached_tool_call_response = None
234
- self._last_message = message = self._client.beta.messages.create(**self._params, **self._options)
235
- yield message
236
255
 
237
256
 
238
- class BetaStreamingToolRunner(BaseSyncToolRunner[BetaMessageStream]):
257
+ class BetaStreamingToolRunner(BaseSyncToolRunner[BetaMessageStream[ResponseFormatT], ResponseFormatT]):
239
258
  @override
240
- def __run__(self) -> Iterator[BetaMessageStream]:
259
+ @contextmanager
260
+ def _handle_request(self) -> Iterator[BetaMessageStream[ResponseFormatT]]:
241
261
  with self._client.beta.messages.stream(**self._params, **self._options) as stream:
242
262
  self._last_message = stream.get_final_message
243
263
  yield stream
244
- message = stream.get_final_message()
245
- self._iteration_count += 1
246
-
247
- while not self._should_stop():
248
- response = self.generate_tool_call_response()
249
- if response is None:
250
- log.debug("Tool call was not requested, exiting from tool runner loop.")
251
- return
252
-
253
- if not self._messages_modified:
254
- self.append_messages(message, response)
255
- self._iteration_count += 1
256
- self._messages_modified = False
257
-
258
- with self._client.beta.messages.stream(**self._params, **self._options) as stream:
259
- self._cached_tool_call_response = None
260
- self._last_message = stream.get_final_message
261
- yield stream
262
- message = stream.get_final_message()
263
264
 
264
265
 
265
- class BaseAsyncToolRunner(BaseToolRunner[BetaAsyncRunnableTool], Generic[RunnerItemT], ABC):
266
+ class BaseAsyncToolRunner(
267
+ BaseToolRunner[BetaAsyncRunnableTool, ResponseFormatT], Generic[RunnerItemT, ResponseFormatT], ABC
268
+ ):
266
269
  def __init__(
267
270
  self,
268
271
  *,
269
- params: MessageCreateParamsBase,
272
+ params: ParseMessageCreateParamsBase[ResponseFormatT],
270
273
  options: RequestOptions,
271
274
  tools: Iterable[BetaAsyncRunnableTool],
272
275
  client: AsyncAnthropic,
@@ -275,7 +278,11 @@ class BaseAsyncToolRunner(BaseToolRunner[BetaAsyncRunnableTool], Generic[RunnerI
275
278
  super().__init__(params=params, options=options, tools=tools, max_iterations=max_iterations)
276
279
  self._client = client
277
280
  self._iterator = self.__run__()
278
- self._last_message: Callable[[], Coroutine[None, None, BetaMessage]] | BetaMessage | None = None
281
+ self._last_message: (
282
+ Callable[[], Coroutine[None, None, ParsedBetaMessage[ResponseFormatT]]]
283
+ | ParsedBetaMessage[ResponseFormatT]
284
+ | None
285
+ ) = None
279
286
 
280
287
  async def __anext__(self) -> RunnerItemT:
281
288
  return await self._iterator.__anext__()
@@ -285,11 +292,36 @@ class BaseAsyncToolRunner(BaseToolRunner[BetaAsyncRunnableTool], Generic[RunnerI
285
292
  yield item
286
293
 
287
294
  @abstractmethod
288
- async def __run__(self) -> AsyncIterator[RunnerItemT]:
295
+ @asynccontextmanager
296
+ async def _handle_request(self) -> AsyncIterator[RunnerItemT]:
289
297
  raise NotImplementedError()
290
298
  yield # type: ignore[unreachable]
291
299
 
292
- async def until_done(self) -> BetaMessage:
300
+ async def __run__(self) -> AsyncIterator[RunnerItemT]:
301
+ async with self._handle_request() as item:
302
+ yield item
303
+ message = await self._get_last_message()
304
+ assert message is not None
305
+ self._iteration_count += 1
306
+
307
+ while not self._should_stop():
308
+ response = await self.generate_tool_call_response()
309
+ if response is None:
310
+ log.debug("Tool call was not requested, exiting from tool runner loop.")
311
+ return
312
+
313
+ if not self._messages_modified:
314
+ self.append_messages(message, response)
315
+ self._iteration_count += 1
316
+ self._messages_modified = False
317
+ self._cached_tool_call_response = None
318
+
319
+ async with self._handle_request() as item:
320
+ yield item
321
+ message = await self._get_last_message()
322
+ assert message is not None
323
+
324
+ async def until_done(self) -> ParsedBetaMessage[ResponseFormatT]:
293
325
  """
294
326
  Consumes the tool runner stream and returns the last message if it has not been consumed yet.
295
327
  If it has, it simply returns the last message.
@@ -314,12 +346,12 @@ class BaseAsyncToolRunner(BaseToolRunner[BetaAsyncRunnableTool], Generic[RunnerI
314
346
  self._cached_tool_call_response = response
315
347
  return response
316
348
 
317
- async def _get_last_message(self) -> BetaMessage | None:
349
+ async def _get_last_message(self) -> ParsedBetaMessage[ResponseFormatT] | None:
318
350
  if callable(self._last_message):
319
351
  return await self._last_message()
320
352
  return self._last_message
321
353
 
322
- async def _get_last_assistant_message_content(self) -> list[BetaContentBlock] | None:
354
+ async def _get_last_assistant_message_content(self) -> list[ParsedBetaContentBlock[ResponseFormatT]] | None:
323
355
  last_message = await self._get_last_message()
324
356
  if last_message is None or last_message.role != "assistant" or not last_message.content:
325
357
  return None
@@ -367,50 +399,19 @@ class BaseAsyncToolRunner(BaseToolRunner[BetaAsyncRunnableTool], Generic[RunnerI
367
399
  return {"role": "user", "content": results}
368
400
 
369
401
 
370
- class BetaAsyncToolRunner(BaseAsyncToolRunner[BetaMessage]):
402
+ class BetaAsyncToolRunner(BaseAsyncToolRunner[ParsedBetaMessage[ResponseFormatT], ResponseFormatT]):
371
403
  @override
372
- async def __run__(self) -> AsyncIterator[BetaMessage]:
373
- self._last_message = message = await self._client.beta.messages.create(**self._params, **self._options)
404
+ @asynccontextmanager
405
+ async def _handle_request(self) -> AsyncIterator[ParsedBetaMessage[ResponseFormatT]]:
406
+ message = await self._client.beta.messages.parse(**self._params, **self._options)
407
+ self._last_message = message
374
408
  yield message
375
- self._iteration_count += 1
376
-
377
- while not self._should_stop():
378
- response = await self.generate_tool_call_response()
379
- if response is None:
380
- log.debug("Tool call was not requested, exiting from tool runner loop.")
381
- return
382
-
383
- if not self._messages_modified:
384
- self.append_messages(message, response)
385
- self._iteration_count += 1
386
- self._messages_modified = False
387
- self._cached_tool_call_response = None
388
- self._last_message = message = await self._client.beta.messages.create(**self._params, **self._options)
389
- yield message
390
409
 
391
410
 
392
- class BetaAsyncStreamingToolRunner(BaseAsyncToolRunner[BetaAsyncMessageStream]):
411
+ class BetaAsyncStreamingToolRunner(BaseAsyncToolRunner[BetaAsyncMessageStream[ResponseFormatT], ResponseFormatT]):
393
412
  @override
394
- async def __run__(self) -> AsyncIterator[BetaAsyncMessageStream]:
413
+ @asynccontextmanager
414
+ async def _handle_request(self) -> AsyncIterator[BetaAsyncMessageStream[ResponseFormatT]]:
395
415
  async with self._client.beta.messages.stream(**self._params, **self._options) as stream:
396
416
  self._last_message = stream.get_final_message
397
417
  yield stream
398
- message = await stream.get_final_message()
399
- self._iteration_count += 1
400
-
401
- while not self._should_stop():
402
- response = await self.generate_tool_call_response()
403
- if response is None:
404
- log.debug("Tool call was not requested, exiting from tool runner loop.")
405
- return
406
-
407
- if not self._messages_modified:
408
- self.append_messages(message, response)
409
- self._iteration_count += 1
410
- self._messages_modified = False
411
-
412
- async with self._client.beta.messages.stream(**self._params, **self._options) as stream:
413
- self._last_message = stream.get_final_message
414
- self._cached_tool_call_response = None
415
- yield stream
416
- message = await stream.get_final_message()
@@ -66,7 +66,7 @@ class Batches(SyncAPIResource):
66
66
  can take up to 24 hours to complete.
67
67
 
68
68
  Learn more about the Message Batches API in our
69
- [user guide](/en/docs/build-with-claude/batch-processing)
69
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
70
70
 
71
71
  Args:
72
72
  requests: List of requests for prompt completion. Each is an individual request to create
@@ -121,7 +121,7 @@ class Batches(SyncAPIResource):
121
121
  `results_url` field in the response.
122
122
 
123
123
  Learn more about the Message Batches API in our
124
- [user guide](/en/docs/build-with-claude/batch-processing)
124
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
125
125
 
126
126
  Args:
127
127
  message_batch_id: ID of the Message Batch.
@@ -177,7 +177,7 @@ class Batches(SyncAPIResource):
177
177
  returned first.
178
178
 
179
179
  Learn more about the Message Batches API in our
180
- [user guide](/en/docs/build-with-claude/batch-processing)
180
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
181
181
 
182
182
  Args:
183
183
  after_id: ID of the object to use as a cursor for pagination. When provided, returns the
@@ -250,7 +250,7 @@ class Batches(SyncAPIResource):
250
250
  like to delete an in-progress batch, you must first cancel it.
251
251
 
252
252
  Learn more about the Message Batches API in our
253
- [user guide](/en/docs/build-with-claude/batch-processing)
253
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
254
254
 
255
255
  Args:
256
256
  message_batch_id: ID of the Message Batch.
@@ -311,7 +311,7 @@ class Batches(SyncAPIResource):
311
311
  non-interruptible.
312
312
 
313
313
  Learn more about the Message Batches API in our
314
- [user guide](/en/docs/build-with-claude/batch-processing)
314
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
315
315
 
316
316
  Args:
317
317
  message_batch_id: ID of the Message Batch.
@@ -367,7 +367,7 @@ class Batches(SyncAPIResource):
367
367
  requests. Use the `custom_id` field to match results to requests.
368
368
 
369
369
  Learn more about the Message Batches API in our
370
- [user guide](/en/docs/build-with-claude/batch-processing)
370
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
371
371
 
372
372
  Args:
373
373
  message_batch_id: ID of the Message Batch.
@@ -453,7 +453,7 @@ class AsyncBatches(AsyncAPIResource):
453
453
  can take up to 24 hours to complete.
454
454
 
455
455
  Learn more about the Message Batches API in our
456
- [user guide](/en/docs/build-with-claude/batch-processing)
456
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
457
457
 
458
458
  Args:
459
459
  requests: List of requests for prompt completion. Each is an individual request to create
@@ -508,7 +508,7 @@ class AsyncBatches(AsyncAPIResource):
508
508
  `results_url` field in the response.
509
509
 
510
510
  Learn more about the Message Batches API in our
511
- [user guide](/en/docs/build-with-claude/batch-processing)
511
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
512
512
 
513
513
  Args:
514
514
  message_batch_id: ID of the Message Batch.
@@ -564,7 +564,7 @@ class AsyncBatches(AsyncAPIResource):
564
564
  returned first.
565
565
 
566
566
  Learn more about the Message Batches API in our
567
- [user guide](/en/docs/build-with-claude/batch-processing)
567
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
568
568
 
569
569
  Args:
570
570
  after_id: ID of the object to use as a cursor for pagination. When provided, returns the
@@ -637,7 +637,7 @@ class AsyncBatches(AsyncAPIResource):
637
637
  like to delete an in-progress batch, you must first cancel it.
638
638
 
639
639
  Learn more about the Message Batches API in our
640
- [user guide](/en/docs/build-with-claude/batch-processing)
640
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
641
641
 
642
642
  Args:
643
643
  message_batch_id: ID of the Message Batch.
@@ -698,7 +698,7 @@ class AsyncBatches(AsyncAPIResource):
698
698
  non-interruptible.
699
699
 
700
700
  Learn more about the Message Batches API in our
701
- [user guide](/en/docs/build-with-claude/batch-processing)
701
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
702
702
 
703
703
  Args:
704
704
  message_batch_id: ID of the Message Batch.
@@ -754,7 +754,7 @@ class AsyncBatches(AsyncAPIResource):
754
754
  requests. Use the `custom_id` field to match results to requests.
755
755
 
756
756
  Learn more about the Message Batches API in our
757
- [user guide](/en/docs/build-with-claude/batch-processing)
757
+ [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing)
758
758
 
759
759
  Args:
760
760
  message_batch_id: ID of the Message Batch.