1616from sqlalchemy .orm import selectinload
1717
1818from app .constants import (
19+ BRIDGE_PROVIDER_TYPES ,
1920 REDIS_KEY_CHAT_CONTEXT_USAGE ,
2021 REDIS_KEY_CHAT_STREAM_LIVE ,
2122 SANDBOX_HOME_DIR ,
@@ -147,6 +148,7 @@ def __init__(
147148 self .session_container : dict [str , Any ] = {"session_id" : request .session_id }
148149 self .assistant_message_id = request .assistant_message_id
149150 self .model_id = request .model_id
151+ self .uses_bridge = request .uses_bridge
150152 self .context_window = request .context_window
151153 self .prompt = request .prompt
152154 self ._is_new_chat = request .session_id is None
@@ -168,6 +170,20 @@ def __init__(
168170 self ._cancelled : bool = False
169171 self ._send_now_pending : bool = False
170172
173+ @property
174+ def attachment_base_dir (self ) -> str :
175+ # Files are written to the sandbox home dir
176+ # (/home/user/ → {host_base}/{sandbox_id}/), so in host mode
177+ # point Claude at the real host path, not the workspace path.
178+ if self .chat .sandbox_provider == SandboxProviderType .HOST :
179+ sid = self .chat .sandbox_id
180+ if sid :
181+ host_base = (
182+ Path (settings .get_host_sandbox_base_dir ()).expanduser ().resolve ()
183+ )
184+ return str (host_base / sid )
185+ return SANDBOX_HOME_DIR
186+
171187 async def run (
172188 self ,
173189 ai_service : ClaudeAgentService ,
@@ -495,21 +511,34 @@ async def _write_send_now(self, ai_service: ClaudeAgentService) -> bool:
495511 self .model_id = resolved_model
496512 if self ._session :
497513 self ._session .current_model = resolved_model
514+ user_settings = await UserService (
515+ session_factory = self .session_factory
516+ ).get_user_settings (self .chat .user_id , db = None )
517+ provider , _ = ProviderService ().get_provider_for_model (
518+ user_settings , queued_model
519+ )
520+ self .uses_bridge = (
521+ provider .get ("provider_type" ) in BRIDGE_PROVIDER_TYPES
522+ if provider
523+ else False
524+ )
498525 queued_permission = queued_msg .get ("permission_mode" )
499526 if queued_permission :
500527 sdk_permission = SDK_PERMISSION_MODE_MAP .get (
501528 queued_permission , "acceptEdits"
502529 )
503530 await self .client .set_permission_mode (sdk_permission )
504531
505- prompt = ai_service .prepare_user_prompt (
532+ user_content = ai_service .build_user_message_content (
506533 queued_msg ["content" ],
507534 self .custom_instructions ,
508535 queued_msg .get ("attachments" ),
536+ self .attachment_base_dir ,
537+ uses_bridge = self .uses_bridge ,
509538 )
510539 injection = {
511540 "type" : "user" ,
512- "message" : {"role" : "user" , "content" : prompt },
541+ "message" : {"role" : "user" , "content" : user_content },
513542 "parent_tool_use_id" : None ,
514543 "session_id" : self .session_container .get ("session_id" ),
515544 }
@@ -848,9 +877,18 @@ def _build_queued_stream_request(
848877 user_settings ,
849878 selected_persona_name = selected_persona_name ,
850879 )
851- context_window = ProviderService ().get_model_context_window (
880+ provider_service = ProviderService ()
881+ context_window = provider_service .get_model_context_window (
852882 user_settings , queued_msg ["model_id" ]
853883 )
884+ provider , _ = provider_service .get_provider_for_model (
885+ user_settings , queued_msg ["model_id" ]
886+ )
887+ uses_bridge = (
888+ provider .get ("provider_type" ) in BRIDGE_PROVIDER_TYPES
889+ if provider
890+ else False
891+ )
854892 return ChatStreamRequest (
855893 prompt = queued_msg ["content" ],
856894 system_prompt = system_prompt ,
@@ -872,6 +910,7 @@ def _build_queued_stream_request(
872910 assistant_message_id = assistant_message_id ,
873911 thinking_mode = queued_msg .get ("thinking_mode" ),
874912 worktree = queued_msg .get ("worktree" , False ),
913+ uses_bridge = uses_bridge ,
875914 attachments = queued_msg .get ("attachments" ),
876915 selected_persona_name = selected_persona_name ,
877916 )
@@ -1117,20 +1156,6 @@ async def execute_chat(
11171156 params .options .permission_mode
11181157 )
11191158 stream_result = StreamResult ()
1120- attachment_base_dir = SANDBOX_HOME_DIR
1121- if runtime .chat .sandbox_provider == SandboxProviderType .HOST :
1122- # Files are written to the sandbox home dir
1123- # (/home/user/ → {host_base}/{sandbox_id}/), so
1124- # point Claude at the real host path, not the
1125- # workspace path.
1126- host_base = (
1127- Path (settings .get_host_sandbox_base_dir ())
1128- .expanduser ()
1129- .resolve ()
1130- )
1131- sid = runtime .chat .sandbox_id
1132- assert sid is not None
1133- attachment_base_dir = str (host_base / sid )
11341159 stream = ai_service .stream_response (
11351160 client = session .client ,
11361161 prompt = request .prompt ,
@@ -1139,7 +1164,8 @@ async def execute_chat(
11391164 result = stream_result ,
11401165 session_callback = session_callback ,
11411166 attachments = request .attachments ,
1142- attachment_base_dir = attachment_base_dir ,
1167+ attachment_base_dir = runtime .attachment_base_dir ,
1168+ uses_bridge = request .uses_bridge ,
11431169 )
11441170 return await runtime .run (ai_service , stream_result , stream )
11451171 except (
0 commit comments