mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-09-14 16:08:41 +00:00
* fix(sandbox): isolate concurrent subagent shell sessions * fix(sandbox): make execution acquire idempotent * fix(sandbox): close execution lifecycle gaps * fix(sandbox): serialize retained client lifecycle * fix(sandbox): close remaining client lifecycle gaps * fix(sandbox): unwind failed client lookup * fix(sandbox): protect internal lease identities * fix(sandbox): make cancellation reconciliation durable * fix(sandbox): fence cancelled workers and IM uploads
44 lines
1.3 KiB
Python
44 lines
1.3 KiB
Python
"""Shared lifecycle-safe synchronization for inbound channel attachments."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from deerflow.sandbox.lease import acquire_sandbox_client_lease
|
|
|
|
|
|
async def sync_file_to_thread_sandbox(
|
|
sandbox_provider,
|
|
*,
|
|
thread_id: str,
|
|
user_id: str,
|
|
virtual_path: str,
|
|
content: bytes,
|
|
owner_prefix: str,
|
|
) -> bool:
|
|
"""Copy one attachment while holding a non-releasing sandbox client lease.
|
|
|
|
Thread-data mount providers already see the persisted upload. Other
|
|
providers need a unique holder so a parallel run cannot close their client
|
|
during ``update_file``. The blocking transport worker is drained even when
|
|
the channel handler is repeatedly cancelled, and only then is the holder
|
|
released.
|
|
"""
|
|
if getattr(sandbox_provider, "uses_thread_data_mounts", False):
|
|
return True
|
|
|
|
lease = await acquire_sandbox_client_lease(
|
|
sandbox_provider,
|
|
thread_id,
|
|
user_id=user_id,
|
|
owner_prefix=owner_prefix,
|
|
release_on_last=False,
|
|
)
|
|
try:
|
|
if lease.sandbox_id == "local" or lease.sandbox_id.startswith("local:"):
|
|
return True
|
|
if lease.sandbox is None:
|
|
return False
|
|
await lease.run_sync(lease.sandbox.update_file, virtual_path, content)
|
|
return True
|
|
finally:
|
|
await lease.release()
|