Skip to content

Commit 2b9e5a0

Browse files
committed
fix: reuse storage across runs
1 parent d17042c commit 2b9e5a0

2 files changed

Lines changed: 48 additions & 17 deletions

File tree

packages/uipath-openai-agents/src/uipath_openai_agents/runtime/factory.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,50 @@ def __init__(
4444
self._agent_loaders: dict[str, OpenAiAgentLoader] = {}
4545
self._agent_lock = asyncio.Lock()
4646

47+
self._storage: SqliteAgentStorage | None = None
48+
self._storage_lock = asyncio.Lock()
49+
4750
self._setup_instrumentation()
4851

4952
def _setup_instrumentation(self) -> None:
5053
"""Setup tracing and instrumentation."""
5154
OpenAIAgentsInstrumentor().instrument()
5255
UiPathSpanUtils.register_current_span_provider(get_current_span_wrapper)
5356

54-
def _get_storage_path(self, runtime_id: str) -> str | None:
57+
async def _get_or_create_storage(self) -> SqliteAgentStorage | None:
58+
"""Get or create the shared storage instance.
59+
60+
Returns:
61+
Shared storage instance, or None if storage is disabled
62+
"""
63+
async with self._storage_lock:
64+
if self._storage is None:
65+
storage_path = self._get_storage_path()
66+
if storage_path:
67+
self._storage = SqliteAgentStorage(storage_path)
68+
await self._storage.setup()
69+
return self._storage
70+
71+
def _get_storage_path(self) -> str | None:
72+
"""Get the storage path for agent state.
73+
74+
Returns:
75+
Path to SQLite database for storage, or None if storage is disabled
76+
"""
77+
if self.context.runtime_dir and self.context.state_file:
78+
path = os.path.join(self.context.runtime_dir, self.context.state_file)
79+
80+
if not self.context.resume and self.context.job_id is None:
81+
# If not resuming and no job id, delete the previous state file
82+
if os.path.exists(path):
83+
os.remove(path)
84+
85+
os.makedirs(self.context.runtime_dir, exist_ok=True)
86+
return path
87+
88+
return None
89+
90+
def _get_storage_path_legacy(self, runtime_id: str) -> str | None:
5591
"""
5692
Get the storage path for agent session state.
5793
@@ -230,13 +266,9 @@ async def _create_runtime_instance(
230266
Returns:
231267
Configured runtime instance
232268
"""
233-
storage_path = self._get_storage_path(runtime_id)
234-
235-
# Create storage instance if storage path is available
236-
storage: SqliteAgentStorage | None = None
237-
if storage_path:
238-
storage = SqliteAgentStorage(storage_path)
239-
await storage.setup()
269+
# Get shared storage instance
270+
storage = await self._get_or_create_storage()
271+
storage_path = storage.storage_path if storage else None
240272

241273
# Get the loaded object from the agent loader for schema inference
242274
loaded_object = None
@@ -282,3 +314,8 @@ async def dispose(self) -> None:
282314

283315
self._agent_loaders.clear()
284316
self._agent_cache.clear()
317+
318+
# Dispose shared storage
319+
if self._storage:
320+
await self._storage.dispose()
321+
self._storage = None

packages/uipath-openai-agents/src/uipath_openai_agents/runtime/runtime.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,6 @@ async def get_schema(self) -> UiPathRuntimeSchema:
619619

620620
async def dispose(self) -> None:
621621
"""Cleanup runtime resources."""
622-
# Clean up storage first (before event loop closes)
623-
if self.storage:
624-
try:
625-
await self.storage.dispose()
626-
except Exception:
627-
pass # Best effort cleanup
628-
629-
self._session = None
630-
self.storage = None
622+
# Storage is shared across runtimes and managed by the factory
623+
# Do not dispose it here
624+
pass

0 commit comments

Comments
 (0)