uipath-openai-agents 0.0.1__py3-none-any.whl → 0.0.2__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.
- uipath_openai_agents/__init__.py +24 -3
- uipath_openai_agents/_cli/_templates/AGENTS.md.template +1 -1
- uipath_openai_agents/_cli/_templates/main.py.template +13 -7
- uipath_openai_agents/_cli/cli_new.py +2 -6
- uipath_openai_agents/chat/__init__.py +30 -3
- uipath_openai_agents/chat/supported_models.py +42 -60
- uipath_openai_agents/runtime/__init__.py +34 -8
- uipath_openai_agents/runtime/_serialize.py +4 -4
- uipath_openai_agents/runtime/agent.py +0 -17
- uipath_openai_agents/runtime/factory.py +0 -120
- uipath_openai_agents/runtime/runtime.py +21 -205
- uipath_openai_agents/runtime/schema.py +11 -112
- uipath_openai_agents-0.0.2.dist-info/METADATA +146 -0
- uipath_openai_agents-0.0.2.dist-info/RECORD +23 -0
- uipath_openai_agents/runtime/_sqlite.py +0 -190
- uipath_openai_agents/runtime/_telemetry.py +0 -32
- uipath_openai_agents/runtime/storage.py +0 -357
- uipath_openai_agents-0.0.1.dist-info/METADATA +0 -53
- uipath_openai_agents-0.0.1.dist-info/RECORD +0 -26
- {uipath_openai_agents-0.0.1.dist-info → uipath_openai_agents-0.0.2.dist-info}/WHEEL +0 -0
- {uipath_openai_agents-0.0.1.dist-info → uipath_openai_agents-0.0.2.dist-info}/entry_points.txt +0 -0
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
"""Async SQLite connection manager with automatic serialization."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import asyncio
|
|
6
|
-
from collections.abc import Iterable
|
|
7
|
-
from contextlib import asynccontextmanager
|
|
8
|
-
from sqlite3 import Row
|
|
9
|
-
from typing import Any, AsyncIterator
|
|
10
|
-
|
|
11
|
-
import aiosqlite
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class AsyncSqlite:
|
|
15
|
-
"""Async SQLite wrapper with automatic serialization via locks.
|
|
16
|
-
|
|
17
|
-
Provides thread-safe access to a SQLite database using asyncio locks
|
|
18
|
-
to serialize operations. Maintains a single connection and ensures
|
|
19
|
-
proper WAL mode configuration.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
def __init__(self, db_path: str, timeout: float = 30.0):
|
|
23
|
-
"""
|
|
24
|
-
Initialize AsyncSQLite manager.
|
|
25
|
-
|
|
26
|
-
Args:
|
|
27
|
-
db_path: Path to the SQLite database file
|
|
28
|
-
timeout: Database connection timeout in seconds
|
|
29
|
-
"""
|
|
30
|
-
self.db_path = db_path
|
|
31
|
-
self.timeout = timeout
|
|
32
|
-
self.conn: aiosqlite.Connection | None = None
|
|
33
|
-
self.lock = asyncio.Lock()
|
|
34
|
-
self.is_setup = False
|
|
35
|
-
|
|
36
|
-
async def __aenter__(self) -> AsyncSqlite:
|
|
37
|
-
"""Async context manager entry."""
|
|
38
|
-
await self.connect()
|
|
39
|
-
return self
|
|
40
|
-
|
|
41
|
-
async def __aexit__(self, *args) -> None:
|
|
42
|
-
"""Async context manager exit."""
|
|
43
|
-
await self.close()
|
|
44
|
-
|
|
45
|
-
async def connect(self) -> None:
|
|
46
|
-
"""Establish database connection and apply initial pragmas."""
|
|
47
|
-
if self.conn is not None:
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
self.conn = await aiosqlite.connect(self.db_path, timeout=self.timeout)
|
|
51
|
-
await self._apply_connection_pragmas()
|
|
52
|
-
|
|
53
|
-
# WAL mode is persistent, set once
|
|
54
|
-
await self.conn.execute("PRAGMA journal_mode=WAL")
|
|
55
|
-
await self.conn.commit()
|
|
56
|
-
|
|
57
|
-
async def close(self) -> None:
|
|
58
|
-
"""Close database connection."""
|
|
59
|
-
if self.conn:
|
|
60
|
-
await self.conn.close()
|
|
61
|
-
self.conn = None
|
|
62
|
-
self.is_setup = False
|
|
63
|
-
|
|
64
|
-
async def execute(
|
|
65
|
-
self, query: str, parameters: tuple[Any, ...] | None = None
|
|
66
|
-
) -> aiosqlite.Cursor:
|
|
67
|
-
"""
|
|
68
|
-
Execute a single query with automatic locking.
|
|
69
|
-
|
|
70
|
-
Args:
|
|
71
|
-
query: SQL query to execute
|
|
72
|
-
parameters: Query parameters
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
Cursor with query results
|
|
76
|
-
"""
|
|
77
|
-
if self.conn is None:
|
|
78
|
-
await self.connect()
|
|
79
|
-
|
|
80
|
-
assert self.conn is not None
|
|
81
|
-
|
|
82
|
-
async with self.lock:
|
|
83
|
-
return await self.conn.execute(query, parameters or ())
|
|
84
|
-
|
|
85
|
-
async def executemany(
|
|
86
|
-
self, query: str, parameters_list: list[tuple[Any, ...]]
|
|
87
|
-
) -> None:
|
|
88
|
-
"""
|
|
89
|
-
Execute a query multiple times with different parameters.
|
|
90
|
-
|
|
91
|
-
Args:
|
|
92
|
-
query: SQL query to execute
|
|
93
|
-
parameters_list: List of parameter tuples
|
|
94
|
-
"""
|
|
95
|
-
if self.conn is None:
|
|
96
|
-
await self.connect()
|
|
97
|
-
|
|
98
|
-
assert self.conn is not None
|
|
99
|
-
|
|
100
|
-
async with self.lock:
|
|
101
|
-
await self.conn.executemany(query, parameters_list)
|
|
102
|
-
await self.conn.commit()
|
|
103
|
-
|
|
104
|
-
async def executescript(self, script: str) -> None:
|
|
105
|
-
"""
|
|
106
|
-
Execute a SQL script (multiple statements).
|
|
107
|
-
|
|
108
|
-
Args:
|
|
109
|
-
script: SQL script to execute
|
|
110
|
-
"""
|
|
111
|
-
if self.conn is None:
|
|
112
|
-
await self.connect()
|
|
113
|
-
|
|
114
|
-
assert self.conn is not None
|
|
115
|
-
|
|
116
|
-
async with self.lock:
|
|
117
|
-
await self.conn.executescript(script)
|
|
118
|
-
await self.conn.commit()
|
|
119
|
-
|
|
120
|
-
async def commit(self) -> None:
|
|
121
|
-
"""Commit the current transaction."""
|
|
122
|
-
if self.conn is None:
|
|
123
|
-
return
|
|
124
|
-
|
|
125
|
-
assert self.conn is not None
|
|
126
|
-
|
|
127
|
-
async with self.lock:
|
|
128
|
-
await self.conn.commit()
|
|
129
|
-
|
|
130
|
-
@asynccontextmanager
|
|
131
|
-
async def cursor(self) -> AsyncIterator[aiosqlite.Cursor]:
|
|
132
|
-
"""
|
|
133
|
-
Get a cursor with automatic locking.
|
|
134
|
-
|
|
135
|
-
Yields:
|
|
136
|
-
Database cursor
|
|
137
|
-
"""
|
|
138
|
-
if self.conn is None:
|
|
139
|
-
await self.connect()
|
|
140
|
-
|
|
141
|
-
assert self.conn is not None
|
|
142
|
-
|
|
143
|
-
async with self.lock:
|
|
144
|
-
cursor = await self.conn.cursor()
|
|
145
|
-
try:
|
|
146
|
-
yield cursor
|
|
147
|
-
finally:
|
|
148
|
-
await cursor.close()
|
|
149
|
-
|
|
150
|
-
async def fetchone(
|
|
151
|
-
self, query: str, parameters: tuple[Any, ...] | None = None
|
|
152
|
-
) -> Row | None:
|
|
153
|
-
"""
|
|
154
|
-
Execute query and fetch one result.
|
|
155
|
-
|
|
156
|
-
Args:
|
|
157
|
-
query: SQL query to execute
|
|
158
|
-
parameters: Query parameters
|
|
159
|
-
|
|
160
|
-
Returns:
|
|
161
|
-
Single row or None
|
|
162
|
-
"""
|
|
163
|
-
cursor = await self.execute(query, parameters)
|
|
164
|
-
return await cursor.fetchone()
|
|
165
|
-
|
|
166
|
-
async def fetchall(
|
|
167
|
-
self, query: str, parameters: tuple[Any, ...] | None = None
|
|
168
|
-
) -> Iterable[Row]:
|
|
169
|
-
"""
|
|
170
|
-
Execute query and fetch all results.
|
|
171
|
-
|
|
172
|
-
Args:
|
|
173
|
-
query: SQL query to execute
|
|
174
|
-
parameters: Query parameters
|
|
175
|
-
|
|
176
|
-
Returns:
|
|
177
|
-
List of rows
|
|
178
|
-
"""
|
|
179
|
-
cursor = await self.execute(query, parameters)
|
|
180
|
-
return await cursor.fetchall()
|
|
181
|
-
|
|
182
|
-
async def _apply_connection_pragmas(self) -> None:
|
|
183
|
-
"""Apply per-connection PRAGMA settings for optimal concurrency."""
|
|
184
|
-
if self.conn is None:
|
|
185
|
-
return
|
|
186
|
-
|
|
187
|
-
await self.conn.execute(f"PRAGMA busy_timeout={int(self.timeout * 1000)}")
|
|
188
|
-
await self.conn.execute("PRAGMA synchronous=NORMAL")
|
|
189
|
-
await self.conn.execute("PRAGMA cache_size=10000")
|
|
190
|
-
await self.conn.execute("PRAGMA temp_store=MEMORY")
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"""OpenInference tracing integration for OpenAI Agents."""
|
|
2
|
-
|
|
3
|
-
try:
|
|
4
|
-
from opentelemetry import trace
|
|
5
|
-
|
|
6
|
-
TELEMETRY_AVAILABLE = True
|
|
7
|
-
except ImportError:
|
|
8
|
-
TELEMETRY_AVAILABLE = False
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if TELEMETRY_AVAILABLE:
|
|
12
|
-
|
|
13
|
-
def get_current_span_wrapper():
|
|
14
|
-
"""Wrapper to get the current span from OpenTelemetry.
|
|
15
|
-
|
|
16
|
-
Returns:
|
|
17
|
-
The current OpenTelemetry span if available, None otherwise
|
|
18
|
-
"""
|
|
19
|
-
return trace.get_current_span()
|
|
20
|
-
|
|
21
|
-
else:
|
|
22
|
-
|
|
23
|
-
def get_current_span_wrapper():
|
|
24
|
-
"""Stub function when OpenTelemetry is not available.
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
None since telemetry dependencies are not available
|
|
28
|
-
"""
|
|
29
|
-
return None
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
__all__ = ["get_current_span_wrapper"]
|
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
"""Storage implementation for OpenAI Agents runtime.
|
|
2
|
-
|
|
3
|
-
Provides persistence for agent sessions, resume triggers, and key-value storage.
|
|
4
|
-
Based on the UiPath LlamaIndex storage implementation but adapted for OpenAI Agents.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import json
|
|
10
|
-
import os
|
|
11
|
-
from typing import Any, cast
|
|
12
|
-
|
|
13
|
-
from pydantic import BaseModel
|
|
14
|
-
from uipath.core.errors import ErrorCategory, UiPathFaultedTriggerError
|
|
15
|
-
from uipath.runtime import (
|
|
16
|
-
UiPathApiTrigger,
|
|
17
|
-
UiPathResumeTrigger,
|
|
18
|
-
UiPathResumeTriggerName,
|
|
19
|
-
UiPathResumeTriggerType,
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
from ._sqlite import AsyncSqlite
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class SqliteAgentStorage:
|
|
26
|
-
"""SQLite database storage for agent sessions, resume triggers, and state."""
|
|
27
|
-
|
|
28
|
-
def __init__(self, storage_path: str):
|
|
29
|
-
"""
|
|
30
|
-
Initialize SQLite storage.
|
|
31
|
-
|
|
32
|
-
Args:
|
|
33
|
-
storage_path: Path to the SQLite database file
|
|
34
|
-
"""
|
|
35
|
-
self.storage_path = storage_path
|
|
36
|
-
self._db: AsyncSqlite | None = None
|
|
37
|
-
|
|
38
|
-
async def _get_db(self) -> AsyncSqlite:
|
|
39
|
-
"""Get or create database connection."""
|
|
40
|
-
if self._db is None:
|
|
41
|
-
self._db = AsyncSqlite(self.storage_path, timeout=30.0)
|
|
42
|
-
await self._db.connect()
|
|
43
|
-
return self._db
|
|
44
|
-
|
|
45
|
-
async def dispose(self) -> None:
|
|
46
|
-
"""Dispose of the storage and close database connection."""
|
|
47
|
-
if self._db:
|
|
48
|
-
await self._db.close()
|
|
49
|
-
self._db = None
|
|
50
|
-
|
|
51
|
-
async def __aenter__(self) -> SqliteAgentStorage:
|
|
52
|
-
"""Async context manager entry."""
|
|
53
|
-
await self.setup()
|
|
54
|
-
return self
|
|
55
|
-
|
|
56
|
-
async def __aexit__(self, *args) -> None:
|
|
57
|
-
"""Async context manager exit."""
|
|
58
|
-
await self.dispose()
|
|
59
|
-
|
|
60
|
-
async def setup(self) -> None:
|
|
61
|
-
"""Ensure storage directory and database tables exist."""
|
|
62
|
-
dir_name = os.path.dirname(self.storage_path)
|
|
63
|
-
if dir_name:
|
|
64
|
-
os.makedirs(dir_name, exist_ok=True)
|
|
65
|
-
|
|
66
|
-
try:
|
|
67
|
-
db = await self._get_db()
|
|
68
|
-
|
|
69
|
-
# Table for agent state/metadata
|
|
70
|
-
await db.execute("""
|
|
71
|
-
CREATE TABLE IF NOT EXISTS agent_state (
|
|
72
|
-
runtime_id TEXT PRIMARY KEY,
|
|
73
|
-
state_data TEXT NOT NULL,
|
|
74
|
-
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
75
|
-
)
|
|
76
|
-
""")
|
|
77
|
-
|
|
78
|
-
# Table for resume triggers
|
|
79
|
-
await db.execute("""
|
|
80
|
-
CREATE TABLE IF NOT EXISTS resume_triggers (
|
|
81
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
82
|
-
runtime_id TEXT NOT NULL,
|
|
83
|
-
interrupt_id TEXT NOT NULL,
|
|
84
|
-
trigger_data TEXT NOT NULL,
|
|
85
|
-
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
86
|
-
)
|
|
87
|
-
""")
|
|
88
|
-
|
|
89
|
-
await db.execute(
|
|
90
|
-
"""
|
|
91
|
-
CREATE INDEX IF NOT EXISTS idx_resume_triggers_runtime_id
|
|
92
|
-
ON resume_triggers(runtime_id)
|
|
93
|
-
"""
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
# Table for key-value storage
|
|
97
|
-
await db.execute(
|
|
98
|
-
"""
|
|
99
|
-
CREATE TABLE IF NOT EXISTS runtime_kv (
|
|
100
|
-
runtime_id TEXT NOT NULL,
|
|
101
|
-
namespace TEXT NOT NULL,
|
|
102
|
-
key TEXT NOT NULL,
|
|
103
|
-
value TEXT,
|
|
104
|
-
timestamp DATETIME DEFAULT (strftime('%Y-%m-%d %H:%M:%S', 'now', 'utc')),
|
|
105
|
-
PRIMARY KEY (runtime_id, namespace, key)
|
|
106
|
-
)
|
|
107
|
-
"""
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
await db.commit()
|
|
111
|
-
except Exception as exc:
|
|
112
|
-
msg = f"Failed to initialize SQLite storage at {self.storage_path!r}: {exc}"
|
|
113
|
-
raise UiPathFaultedTriggerError(ErrorCategory.SYSTEM, msg) from exc
|
|
114
|
-
|
|
115
|
-
async def save_triggers(
|
|
116
|
-
self, runtime_id: str, triggers: list[UiPathResumeTrigger]
|
|
117
|
-
) -> None:
|
|
118
|
-
"""Save resume triggers to SQLite database."""
|
|
119
|
-
try:
|
|
120
|
-
db = await self._get_db()
|
|
121
|
-
|
|
122
|
-
# Delete all existing triggers for this runtime_id
|
|
123
|
-
await db.execute(
|
|
124
|
-
"""
|
|
125
|
-
DELETE FROM resume_triggers
|
|
126
|
-
WHERE runtime_id = ?
|
|
127
|
-
""",
|
|
128
|
-
(runtime_id,),
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
# Insert new triggers
|
|
132
|
-
for trigger in triggers:
|
|
133
|
-
trigger_dict = self._serialize_trigger(trigger)
|
|
134
|
-
trigger_json = json.dumps(trigger_dict)
|
|
135
|
-
await db.execute(
|
|
136
|
-
"INSERT INTO resume_triggers (runtime_id, interrupt_id, trigger_data) VALUES (?, ?, ?)",
|
|
137
|
-
(runtime_id, trigger.interrupt_id, trigger_json),
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
await db.commit()
|
|
141
|
-
except Exception as exc:
|
|
142
|
-
msg = f"Failed to save resume triggers to database {self.storage_path!r}: {exc}"
|
|
143
|
-
raise UiPathFaultedTriggerError(ErrorCategory.SYSTEM, msg) from exc
|
|
144
|
-
|
|
145
|
-
async def get_triggers(self, runtime_id: str) -> list[UiPathResumeTrigger] | None:
|
|
146
|
-
"""Get resume triggers from SQLite database."""
|
|
147
|
-
try:
|
|
148
|
-
db = await self._get_db()
|
|
149
|
-
rows = await db.fetchall(
|
|
150
|
-
"SELECT trigger_data FROM resume_triggers WHERE runtime_id = ? ORDER BY id ASC",
|
|
151
|
-
(runtime_id,),
|
|
152
|
-
)
|
|
153
|
-
except Exception as exc:
|
|
154
|
-
msg = f"Failed to retrieve resume triggers from database {self.storage_path!r}: {exc}"
|
|
155
|
-
raise UiPathFaultedTriggerError(ErrorCategory.SYSTEM, msg) from exc
|
|
156
|
-
|
|
157
|
-
if not rows:
|
|
158
|
-
return None
|
|
159
|
-
|
|
160
|
-
triggers = []
|
|
161
|
-
for row in rows:
|
|
162
|
-
trigger_dict = json.loads(row[0])
|
|
163
|
-
triggers.append(self._deserialize_trigger(trigger_dict))
|
|
164
|
-
return triggers
|
|
165
|
-
|
|
166
|
-
async def delete_trigger(
|
|
167
|
-
self, runtime_id: str, trigger: UiPathResumeTrigger
|
|
168
|
-
) -> None:
|
|
169
|
-
"""Delete resume trigger from storage."""
|
|
170
|
-
try:
|
|
171
|
-
db = await self._get_db()
|
|
172
|
-
await db.execute(
|
|
173
|
-
"""
|
|
174
|
-
DELETE FROM resume_triggers
|
|
175
|
-
WHERE runtime_id = ? AND interrupt_id = ?
|
|
176
|
-
""",
|
|
177
|
-
(runtime_id, trigger.interrupt_id),
|
|
178
|
-
)
|
|
179
|
-
await db.commit()
|
|
180
|
-
except Exception as exc:
|
|
181
|
-
msg = f"Failed to delete resume trigger from database {self.storage_path!r}: {exc}"
|
|
182
|
-
raise UiPathFaultedTriggerError(ErrorCategory.SYSTEM, msg) from exc
|
|
183
|
-
|
|
184
|
-
async def save_state(self, runtime_id: str, state_data: dict[str, Any]) -> None:
|
|
185
|
-
"""
|
|
186
|
-
Save agent state to SQLite database.
|
|
187
|
-
|
|
188
|
-
Args:
|
|
189
|
-
runtime_id: Unique identifier for the runtime instance
|
|
190
|
-
state_data: Serialized agent state dictionary
|
|
191
|
-
"""
|
|
192
|
-
state_json = json.dumps(state_data)
|
|
193
|
-
|
|
194
|
-
try:
|
|
195
|
-
db = await self._get_db()
|
|
196
|
-
await db.execute(
|
|
197
|
-
"""
|
|
198
|
-
INSERT INTO agent_state (runtime_id, state_data)
|
|
199
|
-
VALUES (?, ?)
|
|
200
|
-
ON CONFLICT(runtime_id) DO UPDATE SET
|
|
201
|
-
state_data = excluded.state_data,
|
|
202
|
-
timestamp = CURRENT_TIMESTAMP
|
|
203
|
-
""",
|
|
204
|
-
(runtime_id, state_json),
|
|
205
|
-
)
|
|
206
|
-
await db.commit()
|
|
207
|
-
except Exception as exc:
|
|
208
|
-
msg = f"Failed to save agent state to database {self.storage_path!r}: {exc}"
|
|
209
|
-
raise UiPathFaultedTriggerError(ErrorCategory.SYSTEM, msg) from exc
|
|
210
|
-
|
|
211
|
-
async def load_state(self, runtime_id: str) -> dict[str, Any] | None:
|
|
212
|
-
"""
|
|
213
|
-
Load agent state from SQLite database.
|
|
214
|
-
|
|
215
|
-
Args:
|
|
216
|
-
runtime_id: Unique identifier for the runtime instance
|
|
217
|
-
|
|
218
|
-
Returns:
|
|
219
|
-
Serialized agent state dictionary or None if not found
|
|
220
|
-
"""
|
|
221
|
-
try:
|
|
222
|
-
db = await self._get_db()
|
|
223
|
-
row = await db.fetchone(
|
|
224
|
-
"SELECT state_data FROM agent_state WHERE runtime_id = ?",
|
|
225
|
-
(runtime_id,),
|
|
226
|
-
)
|
|
227
|
-
except Exception as exc:
|
|
228
|
-
msg = (
|
|
229
|
-
f"Failed to load agent state from database {self.storage_path!r}: {exc}"
|
|
230
|
-
)
|
|
231
|
-
raise UiPathFaultedTriggerError(ErrorCategory.SYSTEM, msg) from exc
|
|
232
|
-
|
|
233
|
-
if not row:
|
|
234
|
-
return None
|
|
235
|
-
|
|
236
|
-
return json.loads(row[0])
|
|
237
|
-
|
|
238
|
-
async def set_value(
|
|
239
|
-
self,
|
|
240
|
-
runtime_id: str,
|
|
241
|
-
namespace: str,
|
|
242
|
-
key: str,
|
|
243
|
-
value: Any,
|
|
244
|
-
) -> None:
|
|
245
|
-
"""Save arbitrary key-value pair to database."""
|
|
246
|
-
if not (
|
|
247
|
-
isinstance(value, str)
|
|
248
|
-
or isinstance(value, dict)
|
|
249
|
-
or isinstance(value, BaseModel)
|
|
250
|
-
or value is None
|
|
251
|
-
):
|
|
252
|
-
raise TypeError("Value must be str, dict, BaseModel or None.")
|
|
253
|
-
|
|
254
|
-
value_text = self._dump_value(value)
|
|
255
|
-
|
|
256
|
-
db = await self._get_db()
|
|
257
|
-
await db.execute(
|
|
258
|
-
"""
|
|
259
|
-
INSERT INTO runtime_kv (runtime_id, namespace, key, value)
|
|
260
|
-
VALUES (?, ?, ?, ?)
|
|
261
|
-
ON CONFLICT(runtime_id, namespace, key)
|
|
262
|
-
DO UPDATE SET
|
|
263
|
-
value = excluded.value,
|
|
264
|
-
timestamp = (strftime('%Y-%m-%d %H:%M:%S', 'now', 'utc'))
|
|
265
|
-
""",
|
|
266
|
-
(runtime_id, namespace, key, value_text),
|
|
267
|
-
)
|
|
268
|
-
await db.commit()
|
|
269
|
-
|
|
270
|
-
async def get_value(self, runtime_id: str, namespace: str, key: str) -> Any:
|
|
271
|
-
"""Get arbitrary key-value pair from database (scoped by runtime_id + namespace)."""
|
|
272
|
-
db = await self._get_db()
|
|
273
|
-
row = await db.fetchone(
|
|
274
|
-
"""
|
|
275
|
-
SELECT value
|
|
276
|
-
FROM runtime_kv
|
|
277
|
-
WHERE runtime_id = ? AND namespace = ? AND key = ?
|
|
278
|
-
LIMIT 1
|
|
279
|
-
""",
|
|
280
|
-
(runtime_id, namespace, key),
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
if not row:
|
|
284
|
-
return None
|
|
285
|
-
|
|
286
|
-
return self._load_value(cast(str | None, row[0]))
|
|
287
|
-
|
|
288
|
-
def _serialize_trigger(self, trigger: UiPathResumeTrigger) -> dict[str, Any]:
|
|
289
|
-
"""Serialize a resume trigger to a dictionary."""
|
|
290
|
-
trigger_key = (
|
|
291
|
-
trigger.api_resume.inbox_id if trigger.api_resume else trigger.item_key
|
|
292
|
-
)
|
|
293
|
-
payload = (
|
|
294
|
-
json.dumps(trigger.payload)
|
|
295
|
-
if isinstance(trigger.payload, dict)
|
|
296
|
-
else str(trigger.payload)
|
|
297
|
-
if trigger.payload
|
|
298
|
-
else None
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
return {
|
|
302
|
-
"type": trigger.trigger_type.value,
|
|
303
|
-
"key": trigger_key,
|
|
304
|
-
"name": trigger.trigger_name.value,
|
|
305
|
-
"payload": payload,
|
|
306
|
-
"interrupt_id": trigger.interrupt_id,
|
|
307
|
-
"folder_path": trigger.folder_path,
|
|
308
|
-
"folder_key": trigger.folder_key,
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
def _deserialize_trigger(self, trigger_data: dict[str, Any]) -> UiPathResumeTrigger:
|
|
312
|
-
"""Deserialize a resume trigger from a dictionary."""
|
|
313
|
-
trigger_type = trigger_data["type"]
|
|
314
|
-
key = trigger_data["key"]
|
|
315
|
-
name = trigger_data["name"]
|
|
316
|
-
folder_path = trigger_data.get("folder_path")
|
|
317
|
-
folder_key = trigger_data.get("folder_key")
|
|
318
|
-
payload = trigger_data.get("payload")
|
|
319
|
-
interrupt_id = trigger_data.get("interrupt_id")
|
|
320
|
-
|
|
321
|
-
resume_trigger = UiPathResumeTrigger(
|
|
322
|
-
trigger_type=UiPathResumeTriggerType(trigger_type),
|
|
323
|
-
trigger_name=UiPathResumeTriggerName(name),
|
|
324
|
-
item_key=key,
|
|
325
|
-
folder_path=folder_path,
|
|
326
|
-
folder_key=folder_key,
|
|
327
|
-
payload=payload,
|
|
328
|
-
interrupt_id=interrupt_id,
|
|
329
|
-
)
|
|
330
|
-
|
|
331
|
-
if resume_trigger.trigger_type == UiPathResumeTriggerType.API:
|
|
332
|
-
resume_trigger.api_resume = UiPathApiTrigger(
|
|
333
|
-
inbox_id=resume_trigger.item_key, request=resume_trigger.payload
|
|
334
|
-
)
|
|
335
|
-
|
|
336
|
-
return resume_trigger
|
|
337
|
-
|
|
338
|
-
def _dump_value(self, value: str | dict[str, Any] | BaseModel | None) -> str | None:
|
|
339
|
-
if value is None:
|
|
340
|
-
return None
|
|
341
|
-
if isinstance(value, BaseModel):
|
|
342
|
-
return "j:" + json.dumps(value.model_dump())
|
|
343
|
-
if isinstance(value, dict):
|
|
344
|
-
return "j:" + json.dumps(value)
|
|
345
|
-
return "s:" + value
|
|
346
|
-
|
|
347
|
-
def _load_value(self, raw: str | None) -> Any:
|
|
348
|
-
if raw is None:
|
|
349
|
-
return None
|
|
350
|
-
if raw.startswith("s:"):
|
|
351
|
-
return raw[2:]
|
|
352
|
-
if raw.startswith("j:"):
|
|
353
|
-
return json.loads(raw[2:])
|
|
354
|
-
return raw
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
__all__ = ["SqliteAgentStorage"]
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: uipath-openai-agents
|
|
3
|
-
Version: 0.0.1
|
|
4
|
-
Summary: UiPath OpenAI Agents SDK
|
|
5
|
-
Project-URL: Homepage, https://uipath.com
|
|
6
|
-
Project-URL: Repository, https://github.com/UiPath/uipath-llamaindex-python
|
|
7
|
-
Maintainer-email: Marius Cosareanu <marius.cosareanu@uipath.com>, Cristian Pufu <cristian.pufu@uipath.com>
|
|
8
|
-
Classifier: Intended Audience :: Developers
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
-
Classifier: Topic :: Software Development :: Build Tools
|
|
13
|
-
Requires-Python: >=3.11
|
|
14
|
-
Requires-Dist: aiosqlite>=0.20.0
|
|
15
|
-
Requires-Dist: openai-agents>=0.6.5
|
|
16
|
-
Requires-Dist: openai>=1.0.0
|
|
17
|
-
Requires-Dist: openinference-instrumentation-openai-agents>=1.4.0
|
|
18
|
-
Requires-Dist: uipath-runtime<0.6.0,>=0.5.0
|
|
19
|
-
Requires-Dist: uipath<2.6.0,>=2.5.0
|
|
20
|
-
Description-Content-Type: text/markdown
|
|
21
|
-
|
|
22
|
-
# UiPath OpenAI Agents SDK
|
|
23
|
-
|
|
24
|
-
Build intelligent AI agents with OpenAI's Agents framework and UiPath.
|
|
25
|
-
|
|
26
|
-
## Installation
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
pip install uipath-openai-agents
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Quick Start
|
|
33
|
-
|
|
34
|
-
See the [main repository documentation](../../docs/) for getting started guides and examples.
|
|
35
|
-
|
|
36
|
-
## Features
|
|
37
|
-
|
|
38
|
-
- **OpenAI Agents Integration**: Build agents using OpenAI's native Agents framework
|
|
39
|
-
- **Agent Orchestration**: Multi-agent coordination and communication
|
|
40
|
-
- **State Management**: Persistent agent state with SQLite sessions
|
|
41
|
-
- **UiPath Integration**: Seamless integration with UiPath runtime and tooling
|
|
42
|
-
|
|
43
|
-
## Status
|
|
44
|
-
|
|
45
|
-
⚠️ **Early Development**: This package is in early development (v0.1.0). APIs may change as the OpenAI Agents framework evolves.
|
|
46
|
-
|
|
47
|
-
## Documentation
|
|
48
|
-
|
|
49
|
-
Full documentation is available in the [main repository](https://github.com/UiPath/uipath-llamaindex-python).
|
|
50
|
-
|
|
51
|
-
## License
|
|
52
|
-
|
|
53
|
-
See [LICENSE](../../LICENSE) in the repository root.
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
uipath_openai_agents/__init__.py,sha256=KOUmJ726xaYXE6QZ7uD_yeaZQym5VZpPmP4Yxy35I_0,190
|
|
2
|
-
uipath_openai_agents/middlewares.py,sha256=TMZAwdBh4gUMfgUZPhhxVDWf3pl-GBaeLlmCtipa-WM,299
|
|
3
|
-
uipath_openai_agents/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
uipath_openai_agents/_cli/__init__.py,sha256=juqd9PbXs4yg45zMJ7BHAOPQjb7sgEbWE9InBtGZhfo,24
|
|
5
|
-
uipath_openai_agents/_cli/cli_new.py,sha256=ZY2-DdlKiGEVh8GmDncGpxH-mzLsB_x9BdUudcjS7Yk,2967
|
|
6
|
-
uipath_openai_agents/_cli/_templates/AGENTS.md.template,sha256=5a40W58c3gH349sxuCOOmi_5UG5fLDrJWkWpdLQBAIA,1292
|
|
7
|
-
uipath_openai_agents/_cli/_templates/main.py.template,sha256=BwOcvHA-RAWUB49NtXA7bLhf3Kqzzhd36fjTjz-lZRg,681
|
|
8
|
-
uipath_openai_agents/_cli/_templates/openai_agents.json.template,sha256=MH1nK-wZ-GMfFmCW5-pD8zUNFaEmlQUfZKiNXDqUgGM,51
|
|
9
|
-
uipath_openai_agents/chat/__init__.py,sha256=gIb5QKN-N83_wfvkuhy5rHgvNztLeJv4VMQVSdGXwMk,103
|
|
10
|
-
uipath_openai_agents/chat/openai.py,sha256=KjbDKS_tUKYjuvjUYbouSsoJsOmzbtdHUzuDarDpFYM,8640
|
|
11
|
-
uipath_openai_agents/chat/supported_models.py,sha256=ieaUKL1Xl_e7XeIr6-mw2Wi3z9uwi-vXW0QKb8sChmc,2874
|
|
12
|
-
uipath_openai_agents/runtime/__init__.py,sha256=R08yyN_4dRX1ZUFhz3liqFcbT6wpCEeCBzXk9Ouxq0o,1102
|
|
13
|
-
uipath_openai_agents/runtime/_serialize.py,sha256=2PZZtDXjCONK78BeoK_MPAPmGYvBFG2VmkjHMQ5o-Bg,1462
|
|
14
|
-
uipath_openai_agents/runtime/_sqlite.py,sha256=SroeZowJPQw5j54lfxv1_J4k56S48YA0U9MeubD7IBw,5380
|
|
15
|
-
uipath_openai_agents/runtime/_telemetry.py,sha256=s_Ggb9rlwR-MLi-ssIayYLdGwkSRnRq9qFzrS5TzMwM,714
|
|
16
|
-
uipath_openai_agents/runtime/agent.py,sha256=ieDvHbkxJu9clExOnbE1OqQBUB-Er9fZN_siddr2hbU,7559
|
|
17
|
-
uipath_openai_agents/runtime/config.py,sha256=gtDCIMB1fcAry9Tj_xJSR1xVaARMNmrr5HmwSn4Nh-w,1808
|
|
18
|
-
uipath_openai_agents/runtime/errors.py,sha256=AgUmbikoM53O02CktbZAKVjVmK1ZCl9-EG0gWaYtrn0,1333
|
|
19
|
-
uipath_openai_agents/runtime/factory.py,sha256=WPhnYzjnVMhVP9SekZ6_Au7kzy4rMmZN-GMjS--XEwc,12354
|
|
20
|
-
uipath_openai_agents/runtime/runtime.py,sha256=GLnFeIrejIgke8mLg1wJOFc9pTedCAJxiRLwFyUYXVw,18605
|
|
21
|
-
uipath_openai_agents/runtime/schema.py,sha256=iM5mHgdlnFrW-jRreL-EYoOsG-qn0pmw364hml2m2gs,15565
|
|
22
|
-
uipath_openai_agents/runtime/storage.py,sha256=AxzhdNY4nMF3CSZkT2SJRxqvzxs37fHPbZlZmSwPka0,12197
|
|
23
|
-
uipath_openai_agents-0.0.1.dist-info/METADATA,sha256=gTqtBJSJfZjSBP9zmRQ2DH_aOOO2oAM22rGd0SeIos4,1815
|
|
24
|
-
uipath_openai_agents-0.0.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
25
|
-
uipath_openai_agents-0.0.1.dist-info/entry_points.txt,sha256=2tY1wvop4ulDwWMUXFZzOREIKyIf5cFYsefLWNA2-9w,183
|
|
26
|
-
uipath_openai_agents-0.0.1.dist-info/RECORD,,
|
|
File without changes
|
{uipath_openai_agents-0.0.1.dist-info → uipath_openai_agents-0.0.2.dist-info}/entry_points.txt
RENAMED
|
File without changes
|