7474 BetaCodeExecutionToolResultBlockContent ,
7575 BetaCodeExecutionToolResultBlockParam ,
7676 BetaCodeExecutionToolResultBlockParamContentParam ,
77+ BetaContainerParams ,
7778 BetaContentBlock ,
7879 BetaContentBlockParam ,
7980 BetaImageBlockParam ,
@@ -200,6 +201,16 @@ class AnthropicModelSettings(ModelSettings, total=False):
200201 See https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching for more information.
201202 """
202203
204+ anthropic_container : BetaContainerParams | Literal [False ]
205+ """Container configuration for multi-turn conversations.
206+
207+ By default, if previous messages contain a container_id (from a prior response),
208+ it will be reused automatically.
209+
210+ Set to `False` to force a fresh container (ignore any container_id from history).
211+ Set to a dict (e.g. `{'id': 'container_xxx'}`) to explicitly specify a container.
212+ """
213+
203214
204215@dataclass (init = False )
205216class AnthropicModel (Model ):
@@ -385,6 +396,7 @@ async def _messages_create(
385396 output_format = self ._native_output_format (model_request_parameters )
386397 betas , extra_headers = self ._get_betas_and_extra_headers (tools , model_request_parameters , model_settings )
387398 betas .update (builtin_tool_betas )
399+ container = self ._get_container (messages , model_settings )
388400 try :
389401 return await self .client .beta .messages .create (
390402 max_tokens = model_settings .get ('max_tokens' , 4096 ),
@@ -403,6 +415,7 @@ async def _messages_create(
403415 top_p = model_settings .get ('top_p' , OMIT ),
404416 timeout = model_settings .get ('timeout' , NOT_GIVEN ),
405417 metadata = model_settings .get ('anthropic_metadata' , OMIT ),
418+ container = container or OMIT ,
406419 extra_headers = extra_headers ,
407420 extra_body = model_settings .get ('extra_body' ),
408421 )
@@ -439,6 +452,18 @@ def _get_betas_and_extra_headers(
439452
440453 return betas , extra_headers
441454
455+ def _get_container (
456+ self , messages : list [ModelMessage ], model_settings : AnthropicModelSettings
457+ ) -> BetaContainerParams | None :
458+ """Get container config for the API request."""
459+ if (container := model_settings .get ('anthropic_container' )) is not None :
460+ return None if container is False else container
461+ for m in reversed (messages ):
462+ if isinstance (m , ModelResponse ) and m .provider_details :
463+ if cid := m .provider_details .get ('container_id' ):
464+ return BetaContainerParams (id = cid )
465+ return None
466+
442467 async def _messages_count_tokens (
443468 self ,
444469 messages : list [ModelMessage ],
@@ -526,6 +551,9 @@ def _process_response(self, response: BetaMessage) -> ModelResponse:
526551 if raw_finish_reason := response .stop_reason : # pragma: no branch
527552 provider_details = {'finish_reason' : raw_finish_reason }
528553 finish_reason = _FINISH_REASON_MAP .get (raw_finish_reason )
554+ if response .container :
555+ provider_details = provider_details or {}
556+ provider_details ['container_id' ] = response .container .id
529557
530558 return ModelResponse (
531559 parts = items ,
@@ -1125,6 +1153,9 @@ async def _get_event_iterator(self) -> AsyncIterator[ModelResponseStreamEvent]:
11251153 if isinstance (event , BetaRawMessageStartEvent ):
11261154 self ._usage = _map_usage (event , self ._provider_name , self ._provider_url , self ._model_name )
11271155 self .provider_response_id = event .message .id
1156+ if event .message .container :
1157+ self .provider_details = self .provider_details or {}
1158+ self .provider_details ['container_id' ] = event .message .container .id
11281159
11291160 elif isinstance (event , BetaRawContentBlockStartEvent ):
11301161 current_block = event .content_block
@@ -1239,7 +1270,7 @@ async def _get_event_iterator(self) -> AsyncIterator[ModelResponseStreamEvent]:
12391270 elif isinstance (event , BetaRawMessageDeltaEvent ):
12401271 self ._usage = _map_usage (event , self ._provider_name , self ._provider_url , self ._model_name , self ._usage )
12411272 if raw_finish_reason := event .delta .stop_reason : # pragma: no branch
1242- self .provider_details = {'finish_reason' : raw_finish_reason }
1273+ self .provider_details = {** ( self . provider_details or {}), 'finish_reason' : raw_finish_reason }
12431274 self .finish_reason = _FINISH_REASON_MAP .get (raw_finish_reason )
12441275
12451276 elif isinstance (event , BetaRawContentBlockStopEvent ): # pragma: no branch
0 commit comments