agenta 0.15.0__py3-none-any.whl → 0.15.0a0__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.
Potentially problematic release.
This version of agenta might be problematic. Click here for more details.
- agenta/__init__.py +3 -6
- agenta/client/backend/client.py +6 -8
- agenta/client/backend/types/create_span.py +1 -1
- agenta/docker/docker-assets/Dockerfile.cloud.template +1 -1
- agenta/sdk/__init__.py +4 -6
- agenta/sdk/agenta_decorator.py +570 -0
- agenta/sdk/agenta_init.py +108 -120
- agenta/sdk/tracing/decorators.py +41 -0
- agenta/sdk/tracing/llm_tracing.py +103 -122
- agenta/sdk/tracing/logger.py +1 -1
- agenta/sdk/tracing/tasks_manager.py +3 -1
- agenta/sdk/types.py +67 -86
- agenta/sdk/utils/globals.py +1 -3
- {agenta-0.15.0.dist-info → agenta-0.15.0a0.dist-info}/METADATA +3 -3
- {agenta-0.15.0.dist-info → agenta-0.15.0a0.dist-info}/RECORD +17 -18
- agenta/sdk/decorators/base.py +0 -10
- agenta/sdk/decorators/llm_entrypoint.py +0 -499
- agenta/sdk/decorators/tracing.py +0 -98
- {agenta-0.15.0.dist-info → agenta-0.15.0a0.dist-info}/WHEEL +0 -0
- {agenta-0.15.0.dist-info → agenta-0.15.0a0.dist-info}/entry_points.txt +0 -0
|
@@ -1,79 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
from threading import Lock
|
|
1
|
+
# Stdlib Imports
|
|
3
2
|
from datetime import datetime, timezone
|
|
4
3
|
from typing import Optional, Dict, Any, List, Union
|
|
5
4
|
|
|
5
|
+
# Own Imports
|
|
6
6
|
from agenta.sdk.tracing.logger import llm_logger
|
|
7
7
|
from agenta.sdk.tracing.tasks_manager import TaskQueue
|
|
8
8
|
from agenta.client.backend.client import AsyncAgentaApi
|
|
9
9
|
from agenta.client.backend.client import AsyncObservabilityClient
|
|
10
10
|
from agenta.client.backend.types.create_span import CreateSpan, SpanKind, SpanStatusCode
|
|
11
11
|
|
|
12
|
+
# Third Party Imports
|
|
12
13
|
from bson.objectid import ObjectId
|
|
13
14
|
|
|
14
|
-
VARIANT_TRACKING_FEATURE_FLAG = False
|
|
15
15
|
|
|
16
|
+
class Tracing(object):
|
|
17
|
+
"""Agenta llm tracing object.
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
Thread-safe implementation of Singleton.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
_instances = {} # type: ignore
|
|
23
|
-
|
|
24
|
-
# We need the lock mechanism to synchronize threads \
|
|
25
|
-
# during the initial access to the Singleton object.
|
|
26
|
-
_lock: Lock = Lock()
|
|
27
|
-
|
|
28
|
-
def __call__(cls, *args, **kwargs):
|
|
29
|
-
"""
|
|
30
|
-
Ensures that changes to the `__init__` arguments do not affect the
|
|
31
|
-
returned instance.
|
|
32
|
-
|
|
33
|
-
Uses a lock to make this method thread-safe. If an instance of the class
|
|
34
|
-
does not already exist, it creates one. Otherwise, it returns the
|
|
35
|
-
existing instance.
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
with cls._lock:
|
|
39
|
-
if cls not in cls._instances:
|
|
40
|
-
instance = super().__call__(*args, **kwargs)
|
|
41
|
-
cls._instances[cls] = instance
|
|
42
|
-
return cls._instances[cls]
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class Tracing(metaclass=SingletonMeta):
|
|
46
|
-
"""The `Tracing` class is an agent for LLM tracing with specific initialization arguments.
|
|
47
|
-
|
|
48
|
-
__init__ args:
|
|
49
|
-
host (str): The URL of the backend host
|
|
19
|
+
Args:
|
|
20
|
+
base_url (str): The URL of the backend host
|
|
50
21
|
api_key (str): The API Key of the backend host
|
|
51
22
|
tasks_manager (TaskQueue): The tasks manager dedicated to handling asynchronous tasks
|
|
52
23
|
llm_logger (Logger): The logger associated with the LLM tracing
|
|
53
24
|
max_workers (int): The maximum number of workers to run tracing
|
|
54
25
|
"""
|
|
55
26
|
|
|
27
|
+
_instance = None
|
|
28
|
+
|
|
29
|
+
def __new__(cls, *args, **kwargs):
|
|
30
|
+
if not cls._instance:
|
|
31
|
+
cls._instance = super().__new__(cls)
|
|
32
|
+
return cls._instance
|
|
33
|
+
|
|
56
34
|
def __init__(
|
|
57
35
|
self,
|
|
58
|
-
|
|
36
|
+
base_url: str,
|
|
59
37
|
app_id: str,
|
|
38
|
+
variant_id: str,
|
|
39
|
+
variant_name: Optional[str] = None,
|
|
60
40
|
api_key: Optional[str] = None,
|
|
61
41
|
max_workers: Optional[int] = None,
|
|
62
42
|
):
|
|
63
|
-
self.
|
|
43
|
+
self.base_url = base_url + "/api"
|
|
64
44
|
self.api_key = api_key if api_key is not None else ""
|
|
65
45
|
self.llm_logger = llm_logger
|
|
66
46
|
self.app_id = app_id
|
|
47
|
+
self.variant_id = variant_id
|
|
48
|
+
self.variant_name = variant_name
|
|
67
49
|
self.tasks_manager = TaskQueue(
|
|
68
50
|
max_workers if max_workers else 4, logger=llm_logger
|
|
69
51
|
)
|
|
70
|
-
self.active_span
|
|
71
|
-
self.
|
|
72
|
-
self.
|
|
52
|
+
self.active_span = CreateSpan
|
|
53
|
+
self.active_trace = CreateSpan
|
|
54
|
+
self.recording_trace_id: Union[str, None] = None
|
|
55
|
+
self.recorded_spans: List[CreateSpan] = []
|
|
73
56
|
self.tags: List[str] = []
|
|
74
|
-
self.trace_config_cache: Dict[
|
|
75
|
-
str, Any
|
|
76
|
-
] = {} # used to save the trace configuration before starting the first span
|
|
77
57
|
self.span_dict: Dict[str, CreateSpan] = {} # type: ignore
|
|
78
58
|
|
|
79
59
|
@property
|
|
@@ -85,130 +65,131 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
85
65
|
"""
|
|
86
66
|
|
|
87
67
|
return AsyncAgentaApi(
|
|
88
|
-
base_url=self.
|
|
68
|
+
base_url=self.base_url, api_key=self.api_key, timeout=120 # type: ignore
|
|
89
69
|
).observability
|
|
90
70
|
|
|
91
71
|
def set_span_attribute(
|
|
72
|
+
self, parent_key: Optional[str] = None, attributes: Dict[str, Any] = {}
|
|
73
|
+
):
|
|
74
|
+
span = self.span_dict[self.active_span.id] # type: ignore
|
|
75
|
+
for key, value in attributes.items():
|
|
76
|
+
self.set_attribute(span.attributes, key, value, parent_key) # type: ignore
|
|
77
|
+
|
|
78
|
+
def set_attribute(
|
|
92
79
|
self,
|
|
93
|
-
|
|
80
|
+
span_attributes: Dict[str, Any],
|
|
81
|
+
key: str,
|
|
82
|
+
value: Any,
|
|
83
|
+
parent_key: Optional[str] = None,
|
|
94
84
|
):
|
|
95
|
-
if
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
85
|
+
if parent_key is not None:
|
|
86
|
+
model_config = span_attributes.get(parent_key, None)
|
|
87
|
+
if not model_config:
|
|
88
|
+
span_attributes[parent_key] = {}
|
|
89
|
+
span_attributes[parent_key][key] = value
|
|
100
90
|
else:
|
|
101
|
-
|
|
102
|
-
self.active_span.attributes[key] = value
|
|
91
|
+
span_attributes[key] = value
|
|
103
92
|
|
|
104
93
|
def set_trace_tags(self, tags: List[str]):
|
|
105
94
|
self.tags.extend(tags)
|
|
106
95
|
|
|
96
|
+
def start_parent_span(
|
|
97
|
+
self, name: str, inputs: Dict[str, Any], config: Dict[str, Any], **kwargs
|
|
98
|
+
):
|
|
99
|
+
trace_id = self._create_trace_id()
|
|
100
|
+
span_id = self._create_span_id()
|
|
101
|
+
self.llm_logger.info("Recording parent span...")
|
|
102
|
+
span = CreateSpan(
|
|
103
|
+
id=span_id,
|
|
104
|
+
app_id=self.app_id,
|
|
105
|
+
variant_id=self.variant_id,
|
|
106
|
+
variant_name=self.variant_name,
|
|
107
|
+
inputs=inputs,
|
|
108
|
+
name=name,
|
|
109
|
+
config=config,
|
|
110
|
+
environment=kwargs.get("environment"),
|
|
111
|
+
spankind=SpanKind.WORKFLOW.value,
|
|
112
|
+
status=SpanStatusCode.UNSET.value,
|
|
113
|
+
start_time=datetime.now(timezone.utc),
|
|
114
|
+
)
|
|
115
|
+
self.active_trace = span
|
|
116
|
+
self.recording_trace_id = trace_id
|
|
117
|
+
self.parent_span_id = span.id
|
|
118
|
+
self.llm_logger.info(
|
|
119
|
+
f"Recorded active_trace and setting parent_span_id: {span.id}"
|
|
120
|
+
)
|
|
121
|
+
|
|
107
122
|
def start_span(
|
|
108
123
|
self,
|
|
109
124
|
name: str,
|
|
110
125
|
spankind: str,
|
|
111
126
|
input: Dict[str, Any],
|
|
112
|
-
config:
|
|
113
|
-
**kwargs,
|
|
127
|
+
config: Dict[str, Any] = {},
|
|
114
128
|
) -> CreateSpan:
|
|
115
129
|
span_id = self._create_span_id()
|
|
116
|
-
self.llm_logger.info(
|
|
117
|
-
f"Recording {'parent' if spankind == 'workflow' else spankind} span..."
|
|
118
|
-
)
|
|
130
|
+
self.llm_logger.info(f"Recording {spankind} span...")
|
|
119
131
|
span = CreateSpan(
|
|
120
132
|
id=span_id,
|
|
121
133
|
inputs=input,
|
|
122
134
|
name=name,
|
|
123
135
|
app_id=self.app_id,
|
|
136
|
+
variant_id=self.variant_id,
|
|
137
|
+
variant_name=self.variant_name,
|
|
124
138
|
config=config,
|
|
139
|
+
environment=self.active_trace.environment,
|
|
140
|
+
parent_span_id=self.parent_span_id,
|
|
125
141
|
spankind=spankind.upper(),
|
|
126
142
|
attributes={},
|
|
127
143
|
status=SpanStatusCode.UNSET.value,
|
|
128
144
|
start_time=datetime.now(timezone.utc),
|
|
129
|
-
outputs=None,
|
|
130
|
-
tags=None,
|
|
131
|
-
user=None,
|
|
132
|
-
end_time=None,
|
|
133
|
-
tokens=None,
|
|
134
|
-
cost=None,
|
|
135
|
-
token_consumption=None,
|
|
136
|
-
parent_span_id=None,
|
|
137
145
|
)
|
|
138
146
|
|
|
139
|
-
if self.active_trace_id is None: # This is a parent span
|
|
140
|
-
self.active_trace_id = self._create_trace_id()
|
|
141
|
-
span.environment = (
|
|
142
|
-
self.trace_config_cache.get("environment")
|
|
143
|
-
if self.trace_config_cache is not None
|
|
144
|
-
else os.environ.get("environment", "unset")
|
|
145
|
-
)
|
|
146
|
-
span.config = (
|
|
147
|
-
self.trace_config_cache.get("config")
|
|
148
|
-
if not config and self.trace_config_cache is not None
|
|
149
|
-
else None
|
|
150
|
-
)
|
|
151
|
-
if VARIANT_TRACKING_FEATURE_FLAG:
|
|
152
|
-
# TODO: we should get the variant_id and variant_name (and environment) from the config object
|
|
153
|
-
span.variant_id = config.variant_id
|
|
154
|
-
span.variant_name = (config.variant_name,)
|
|
155
|
-
|
|
156
|
-
else:
|
|
157
|
-
span.parent_span_id = self.active_span.id
|
|
158
|
-
self.span_dict[span.id] = span
|
|
159
147
|
self.active_span = span
|
|
160
|
-
|
|
161
|
-
self.
|
|
148
|
+
self.span_dict[span.id] = span
|
|
149
|
+
self.parent_span_id = span.id
|
|
150
|
+
self.llm_logger.info(
|
|
151
|
+
f"Recorded active_span and setting parent_span_id: {span.id}"
|
|
152
|
+
)
|
|
162
153
|
return span
|
|
163
154
|
|
|
164
155
|
def update_span_status(self, span: CreateSpan, value: str):
|
|
165
|
-
span.status
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
self.active_span.tokens = outputs.get("usage", None)
|
|
156
|
+
updated_span = CreateSpan(**{**span.dict(), "status": value})
|
|
157
|
+
self.active_span = updated_span
|
|
158
|
+
|
|
159
|
+
def end_span(self, outputs: Dict[str, Any], span: CreateSpan, **kwargs):
|
|
160
|
+
updated_span = CreateSpan(
|
|
161
|
+
**span.dict(),
|
|
162
|
+
end_time=datetime.now(timezone.utc),
|
|
163
|
+
outputs=[outputs["message"]],
|
|
164
|
+
cost=outputs.get("cost", None),
|
|
165
|
+
tokens=outputs.get("usage"),
|
|
166
|
+
)
|
|
177
167
|
|
|
178
168
|
# Push span to list of recorded spans
|
|
179
|
-
self.
|
|
169
|
+
self.recorded_spans.append(updated_span)
|
|
180
170
|
self.llm_logger.info(
|
|
181
|
-
f"Pushed {
|
|
171
|
+
f"Pushed {updated_span.spankind} span {updated_span.id} to recorded spans."
|
|
182
172
|
)
|
|
183
|
-
if self.active_span.parent_span_id is None:
|
|
184
|
-
self.end_trace(parent_span=self.active_span)
|
|
185
|
-
else:
|
|
186
|
-
self.active_span = self.span_dict[self.active_span.parent_span_id]
|
|
187
173
|
|
|
188
|
-
def
|
|
174
|
+
def end_recording(self, outputs: Dict[str, Any], span: CreateSpan, **kwargs):
|
|
175
|
+
self.end_span(outputs=outputs, span=span, **kwargs)
|
|
189
176
|
if self.api_key == "":
|
|
190
177
|
return
|
|
191
178
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
self.llm_logger.info("Preparing to send recorded spans for processing.")
|
|
196
|
-
self.llm_logger.info(f"Recorded spans => {len(self.pending_spans)}")
|
|
179
|
+
self.llm_logger.info(f"Preparing to send recorded spans for processing.")
|
|
180
|
+
self.llm_logger.info(f"Recorded spans => {len(self.recorded_spans)}")
|
|
197
181
|
self.tasks_manager.add_task(
|
|
198
|
-
self.
|
|
182
|
+
self.active_trace.id,
|
|
199
183
|
"trace",
|
|
200
184
|
self.client.create_traces(
|
|
201
|
-
trace=self.
|
|
185
|
+
trace=self.recording_trace_id, spans=self.recorded_spans # type: ignore
|
|
202
186
|
),
|
|
203
187
|
self.client,
|
|
204
188
|
)
|
|
205
189
|
self.llm_logger.info(
|
|
206
|
-
f"Tracing for {
|
|
190
|
+
f"Tracing for {span.id} recorded successfully and sent for processing."
|
|
207
191
|
)
|
|
208
|
-
self.
|
|
209
|
-
self.active_trace_id = None
|
|
210
|
-
self.active_span = None
|
|
211
|
-
self.trace_config_cache.clear()
|
|
192
|
+
self._clear_recorded_spans()
|
|
212
193
|
|
|
213
194
|
def _create_trace_id(self) -> str:
|
|
214
195
|
"""Creates a unique mongo id for the trace object.
|
|
@@ -228,12 +209,12 @@ class Tracing(metaclass=SingletonMeta):
|
|
|
228
209
|
|
|
229
210
|
return str(ObjectId())
|
|
230
211
|
|
|
231
|
-
def
|
|
212
|
+
def _clear_recorded_spans(self) -> None:
|
|
232
213
|
"""
|
|
233
214
|
Clear the list of recorded spans to prepare for next batch processing.
|
|
234
215
|
"""
|
|
235
216
|
|
|
236
|
-
self.
|
|
217
|
+
self.recorded_spans = []
|
|
237
218
|
self.llm_logger.info(
|
|
238
|
-
f"Cleared all recorded spans from batch: {self.
|
|
219
|
+
f"Cleared all recorded spans from batch: {self.recorded_spans}"
|
|
239
220
|
)
|
agenta/sdk/tracing/logger.py
CHANGED
|
@@ -106,7 +106,9 @@ class TaskQueue(object):
|
|
|
106
106
|
future.result()
|
|
107
107
|
except Exception as exc:
|
|
108
108
|
self._logger.error(f"Error running task: {str(exc)}")
|
|
109
|
-
self._logger.error(
|
|
109
|
+
self._logger.error(
|
|
110
|
+
f"Recording trace {task.coroutine_type} status to ERROR."
|
|
111
|
+
)
|
|
110
112
|
break
|
|
111
113
|
finally:
|
|
112
114
|
self.tasks.task_done()
|
agenta/sdk/types.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Dict, List, Optional
|
|
3
3
|
|
|
4
|
-
from pydantic import
|
|
4
|
+
from pydantic import ConfigDict, BaseModel, HttpUrl
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class InFile:
|
|
@@ -24,87 +24,75 @@ class FuncResponse(BaseModel):
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class DictInput(dict):
|
|
27
|
-
def __new__(cls, default_keys=None):
|
|
27
|
+
def __new__(cls, default_keys: Optional[List[str]] = None):
|
|
28
28
|
instance = super().__new__(cls, default_keys)
|
|
29
29
|
if default_keys is None:
|
|
30
30
|
default_keys = []
|
|
31
|
-
instance.data = [key for key in default_keys]
|
|
31
|
+
instance.data = [key for key in default_keys] # type: ignore
|
|
32
32
|
return instance
|
|
33
33
|
|
|
34
34
|
@classmethod
|
|
35
|
-
def
|
|
36
|
-
|
|
35
|
+
def __schema_type_properties__(cls) -> dict:
|
|
36
|
+
return {"x-parameter": "dict"}
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
class TextParam(str):
|
|
40
40
|
@classmethod
|
|
41
|
-
def
|
|
42
|
-
|
|
41
|
+
def __schema_type_properties__(cls) -> dict:
|
|
42
|
+
return {"x-parameter": "text", "type": "string"}
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
class BinaryParam(int):
|
|
46
46
|
def __new__(cls, value: bool = False):
|
|
47
47
|
instance = super().__new__(cls, int(value))
|
|
48
|
-
instance.default = value
|
|
48
|
+
instance.default = value # type: ignore
|
|
49
49
|
return instance
|
|
50
50
|
|
|
51
51
|
@classmethod
|
|
52
|
-
def
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
)
|
|
52
|
+
def __schema_type_properties__(cls) -> dict:
|
|
53
|
+
return {
|
|
54
|
+
"x-parameter": "bool",
|
|
55
|
+
"type": "boolean",
|
|
56
|
+
}
|
|
59
57
|
|
|
60
58
|
|
|
61
59
|
class IntParam(int):
|
|
62
60
|
def __new__(cls, default: int = 6, minval: float = 1, maxval: float = 10):
|
|
63
61
|
instance = super().__new__(cls, default)
|
|
64
|
-
instance.minval = minval
|
|
65
|
-
instance.maxval = maxval
|
|
62
|
+
instance.minval = minval # type: ignore
|
|
63
|
+
instance.maxval = maxval # type: ignore
|
|
66
64
|
return instance
|
|
67
65
|
|
|
68
66
|
@classmethod
|
|
69
|
-
def
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
"x-parameter": "int",
|
|
73
|
-
"type": "integer",
|
|
74
|
-
"minimum": 1,
|
|
75
|
-
"maximum": 10,
|
|
76
|
-
}
|
|
77
|
-
)
|
|
67
|
+
def __schema_type_properties__(cls) -> dict:
|
|
68
|
+
return {"x-parameter": "int", "type": "integer"}
|
|
78
69
|
|
|
79
70
|
|
|
80
71
|
class FloatParam(float):
|
|
81
72
|
def __new__(cls, default: float = 0.5, minval: float = 0.0, maxval: float = 1.0):
|
|
82
73
|
instance = super().__new__(cls, default)
|
|
83
|
-
instance.
|
|
84
|
-
instance.
|
|
74
|
+
instance.default = default # type: ignore
|
|
75
|
+
instance.minval = minval # type: ignore
|
|
76
|
+
instance.maxval = maxval # type: ignore
|
|
85
77
|
return instance
|
|
86
78
|
|
|
87
79
|
@classmethod
|
|
88
|
-
def
|
|
89
|
-
|
|
90
|
-
{
|
|
91
|
-
"x-parameter": "float",
|
|
92
|
-
"type": "number",
|
|
93
|
-
"minimum": 0.0,
|
|
94
|
-
"maximum": 1.0,
|
|
95
|
-
}
|
|
96
|
-
)
|
|
80
|
+
def __schema_type_properties__(cls) -> dict:
|
|
81
|
+
return {"x-parameter": "float", "type": "number"}
|
|
97
82
|
|
|
98
83
|
|
|
99
84
|
class MultipleChoiceParam(str):
|
|
100
|
-
def __new__(
|
|
101
|
-
|
|
85
|
+
def __new__(
|
|
86
|
+
cls, default: Optional[str] = None, choices: Optional[List[str]] = None
|
|
87
|
+
):
|
|
88
|
+
if default is not None and type(default) is list:
|
|
102
89
|
raise ValueError(
|
|
103
90
|
"The order of the parameters for MultipleChoiceParam is wrong! It's MultipleChoiceParam(default, choices) and not the opposite"
|
|
104
91
|
)
|
|
105
|
-
|
|
92
|
+
|
|
93
|
+
if not default and choices is not None:
|
|
106
94
|
# if a default value is not provided,
|
|
107
|
-
#
|
|
95
|
+
# set the first value in the choices list
|
|
108
96
|
default = choices[0]
|
|
109
97
|
|
|
110
98
|
if default is None and not choices:
|
|
@@ -112,28 +100,25 @@ class MultipleChoiceParam(str):
|
|
|
112
100
|
raise ValueError("You must provide either a default value or choices")
|
|
113
101
|
|
|
114
102
|
instance = super().__new__(cls, default)
|
|
115
|
-
instance.choices = choices
|
|
116
|
-
instance.default = default
|
|
103
|
+
instance.choices = choices # type: ignore
|
|
104
|
+
instance.default = default # type: ignore
|
|
117
105
|
return instance
|
|
118
106
|
|
|
119
107
|
@classmethod
|
|
120
|
-
def
|
|
121
|
-
|
|
122
|
-
{
|
|
123
|
-
"x-parameter": "choice",
|
|
124
|
-
"type": "string",
|
|
125
|
-
"enum": [],
|
|
126
|
-
}
|
|
127
|
-
)
|
|
108
|
+
def __schema_type_properties__(cls) -> dict:
|
|
109
|
+
return {"x-parameter": "choice", "type": "string", "enum": []}
|
|
128
110
|
|
|
129
111
|
|
|
130
112
|
class GroupedMultipleChoiceParam(str):
|
|
131
|
-
def __new__(
|
|
113
|
+
def __new__(
|
|
114
|
+
cls,
|
|
115
|
+
default: Optional[str] = None,
|
|
116
|
+
choices: Optional[Dict[str, List[str]]] = None,
|
|
117
|
+
):
|
|
132
118
|
if choices is None:
|
|
133
119
|
choices = {}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
):
|
|
120
|
+
|
|
121
|
+
if default and not any(default in choices for choices in choices.values()):
|
|
137
122
|
if not choices:
|
|
138
123
|
print(
|
|
139
124
|
f"Warning: Default value {default} provided but choices are empty."
|
|
@@ -144,31 +129,23 @@ class GroupedMultipleChoiceParam(str):
|
|
|
144
129
|
)
|
|
145
130
|
|
|
146
131
|
if not default:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
132
|
+
default_selected_choice = next(
|
|
133
|
+
(choices for choices in choices.values()), None
|
|
134
|
+
)
|
|
135
|
+
if default_selected_choice:
|
|
136
|
+
default = default_selected_choice[0]
|
|
151
137
|
|
|
152
138
|
instance = super().__new__(cls, default)
|
|
153
|
-
instance.choices = choices
|
|
154
|
-
instance.default = default
|
|
139
|
+
instance.choices = choices # type: ignore
|
|
140
|
+
instance.default = default # type: ignore
|
|
155
141
|
return instance
|
|
156
142
|
|
|
157
143
|
@classmethod
|
|
158
|
-
def
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
"type": "string",
|
|
164
|
-
"choices": choices,
|
|
165
|
-
}
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
class Message(BaseModel):
|
|
170
|
-
role: str
|
|
171
|
-
content: str
|
|
144
|
+
def __schema_type_properties__(cls) -> dict:
|
|
145
|
+
return {
|
|
146
|
+
"x-parameter": "grouped_choice",
|
|
147
|
+
"type": "string",
|
|
148
|
+
}
|
|
172
149
|
|
|
173
150
|
|
|
174
151
|
class MessagesInput(list):
|
|
@@ -183,28 +160,32 @@ class MessagesInput(list):
|
|
|
183
160
|
|
|
184
161
|
"""
|
|
185
162
|
|
|
186
|
-
def __new__(cls, messages: List[Dict[str, str]] =
|
|
187
|
-
instance = super().__new__(cls
|
|
188
|
-
instance.default = messages
|
|
163
|
+
def __new__(cls, messages: List[Dict[str, str]] = []):
|
|
164
|
+
instance = super().__new__(cls)
|
|
165
|
+
instance.default = messages # type: ignore
|
|
189
166
|
return instance
|
|
190
167
|
|
|
191
168
|
@classmethod
|
|
192
|
-
def
|
|
193
|
-
|
|
169
|
+
def __schema_type_properties__(cls) -> dict:
|
|
170
|
+
return {"x-parameter": "messages", "type": "array"}
|
|
194
171
|
|
|
195
172
|
|
|
196
173
|
class FileInputURL(HttpUrl):
|
|
174
|
+
def __new__(cls, url: str):
|
|
175
|
+
instance = super().__new__(cls, url)
|
|
176
|
+
instance.default = url # type: ignore
|
|
177
|
+
return instance
|
|
178
|
+
|
|
197
179
|
@classmethod
|
|
198
|
-
def
|
|
199
|
-
|
|
180
|
+
def __schema_type_properties__(cls) -> dict:
|
|
181
|
+
return {"x-parameter": "file_url", "type": "string"}
|
|
200
182
|
|
|
201
183
|
|
|
202
184
|
class Context(BaseModel):
|
|
203
|
-
|
|
204
|
-
extra = Extra.allow
|
|
185
|
+
model_config = ConfigDict(extra="allow")
|
|
205
186
|
|
|
206
187
|
def to_json(self):
|
|
207
|
-
return self.
|
|
188
|
+
return self.model_dump()
|
|
208
189
|
|
|
209
190
|
@classmethod
|
|
210
191
|
def from_json(cls, json_str: str):
|
agenta/sdk/utils/globals.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import agenta
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
def set_global(setup=None, config=None
|
|
4
|
+
def set_global(setup=None, config=None):
|
|
5
5
|
"""Allows usage of agenta.config and agenta.setup in the user's code.
|
|
6
6
|
|
|
7
7
|
Args:
|
|
@@ -12,5 +12,3 @@ def set_global(setup=None, config=None, tracing=None):
|
|
|
12
12
|
agenta.setup = setup
|
|
13
13
|
if config is not None:
|
|
14
14
|
agenta.config = config
|
|
15
|
-
if tracing is not None:
|
|
16
|
-
agenta.tracing = tracing
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: agenta
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.0a0
|
|
4
4
|
Summary: The SDK for agenta is an open-source LLMOps platform.
|
|
5
5
|
Home-page: https://agenta.ai
|
|
6
6
|
Keywords: LLMOps,LLM,evaluation,prompt engineering
|
|
@@ -18,12 +18,12 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
18
18
|
Requires-Dist: cachetools (>=5.3.3,<6.0.0)
|
|
19
19
|
Requires-Dist: click (>=8.1.3,<9.0.0)
|
|
20
20
|
Requires-Dist: docker (>=6.1.1,<8.0.0)
|
|
21
|
-
Requires-Dist: fastapi (>=0.
|
|
21
|
+
Requires-Dist: fastapi (>=0.111.0,<0.112.0)
|
|
22
22
|
Requires-Dist: httpx (>=0.24,<0.28)
|
|
23
23
|
Requires-Dist: importlib-metadata (>=6.7,<8.0)
|
|
24
24
|
Requires-Dist: ipdb (>=0.13)
|
|
25
25
|
Requires-Dist: posthog (>=3.1.0,<4.0.0)
|
|
26
|
-
Requires-Dist: pydantic (
|
|
26
|
+
Requires-Dist: pydantic (>=2.7.1,<3.0.0)
|
|
27
27
|
Requires-Dist: pymongo (>=4.6.3,<5.0.0)
|
|
28
28
|
Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
|
|
29
29
|
Requires-Dist: python-multipart (>=0.0.6,<0.0.10)
|