impact 0.1__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.
- impact/__init__.py +2 -0
- impact/sdk/__init__.py +196 -0
- impact/sdk/annotation/__init__.py +0 -0
- impact/sdk/annotation/base_annotation.py +71 -0
- impact/sdk/annotation/user_feedback.py +43 -0
- impact/sdk/client/__init__.py +1 -0
- impact/sdk/client/client.py +40 -0
- impact/sdk/client/http.py +45 -0
- impact/sdk/config/__init__.py +13 -0
- impact/sdk/decorators/__init__.py +149 -0
- impact/sdk/decorators/base.py +272 -0
- impact/sdk/fetcher.py +165 -0
- impact/sdk/images/image_uploader.py +55 -0
- impact/sdk/instruments.py +34 -0
- impact/sdk/prompts/__init__.py +5 -0
- impact/sdk/prompts/client.py +143 -0
- impact/sdk/prompts/model.py +77 -0
- impact/sdk/prompts/registry.py +15 -0
- impact/sdk/telemetry.py +19 -0
- impact/sdk/tracing/__init__.py +2 -0
- impact/sdk/tracing/content_allow_list.py +24 -0
- impact/sdk/tracing/context_manager.py +13 -0
- impact/sdk/tracing/manual.py +57 -0
- impact/sdk/tracing/tracing.py +1037 -0
- impact/sdk/utils/__init__.py +26 -0
- impact/sdk/utils/in_memory_span_exporter.py +61 -0
- impact/sdk/utils/json_encoder.py +23 -0
- impact/sdk/utils/package_check.py +15 -0
- impact/sdk/version.py +1 -0
- impact-0.1.dist-info/METADATA +61 -0
- impact-0.1.dist-info/RECORD +32 -0
- impact-0.1.dist-info/WHEEL +4 -0
impact/__init__.py
ADDED
impact/sdk/__init__.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from typing import Optional, Set
|
|
6
|
+
from colorama import Fore
|
|
7
|
+
from opentelemetry.sdk.trace import SpanProcessor
|
|
8
|
+
from opentelemetry.sdk.trace.export import SpanExporter
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from opentelemetry.sdk.resources import SERVICE_NAME
|
|
12
|
+
from opentelemetry.propagators.textmap import TextMapPropagator
|
|
13
|
+
from opentelemetry.util.re import parse_env_headers
|
|
14
|
+
|
|
15
|
+
from impact.sdk.images.image_uploader import ImageUploader
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
from impact.sdk.telemetry import Telemetry
|
|
19
|
+
from impact.sdk.instruments import Instruments
|
|
20
|
+
from impact.sdk.config import (
|
|
21
|
+
is_content_tracing_enabled,
|
|
22
|
+
is_tracing_enabled,
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
)
|
|
26
|
+
from impact.sdk.fetcher import Fetcher
|
|
27
|
+
from impact.sdk.tracing.tracing import (
|
|
28
|
+
TracerWrapper,
|
|
29
|
+
set_association_properties,
|
|
30
|
+
set_external_prompt_tracing_context,
|
|
31
|
+
)
|
|
32
|
+
from typing import Dict
|
|
33
|
+
from impact.sdk.client.client import Client
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Impact:
|
|
37
|
+
AUTO_CREATED_KEY_PATH = str(
|
|
38
|
+
Path.home() / ".cache" / "impact" / "auto_created_key"
|
|
39
|
+
)
|
|
40
|
+
AUTO_CREATED_URL = str(Path.home() / ".cache" / "impact" / "auto_created_url")
|
|
41
|
+
|
|
42
|
+
__tracer_wrapper: TracerWrapper
|
|
43
|
+
__fetcher: Optional[Fetcher] = None
|
|
44
|
+
__app_name: Optional[str] = None
|
|
45
|
+
__client: Optional[Client] = None
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def init(
|
|
49
|
+
app_name: str = sys.argv[0],
|
|
50
|
+
api_endpoint: str = "https://api.impact.ai",
|
|
51
|
+
api_key: Optional[str] = None,
|
|
52
|
+
enabled: bool = True,
|
|
53
|
+
headers: Dict[str, str] = {},
|
|
54
|
+
disable_batch=False,
|
|
55
|
+
telemetry_enabled: bool = False,
|
|
56
|
+
exporter: Optional[SpanExporter] = None,
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
processor: Optional[SpanProcessor] = None,
|
|
62
|
+
propagator: TextMapPropagator = None,
|
|
63
|
+
impact_sync_enabled: bool = False,
|
|
64
|
+
|
|
65
|
+
resource_attributes: dict = {},
|
|
66
|
+
instruments: Optional[Set[Instruments]] = None,
|
|
67
|
+
block_instruments: Optional[Set[Instruments]] = None,
|
|
68
|
+
image_uploader: Optional[ImageUploader] = None,
|
|
69
|
+
) -> Optional[Client]:
|
|
70
|
+
if not enabled:
|
|
71
|
+
TracerWrapper.set_disabled(True)
|
|
72
|
+
print(
|
|
73
|
+
Fore.YELLOW
|
|
74
|
+
+ "Impact instrumentation is disabled via init flag"
|
|
75
|
+
+ Fore.RESET
|
|
76
|
+
)
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
telemetry_enabled = (
|
|
80
|
+
telemetry_enabled
|
|
81
|
+
and (os.getenv("IMPACT_TELEMETRY") or "true").lower() == "true"
|
|
82
|
+
)
|
|
83
|
+
if telemetry_enabled:
|
|
84
|
+
Telemetry()
|
|
85
|
+
|
|
86
|
+
api_endpoint = os.getenv("IMPACT_BASE_URL") or api_endpoint
|
|
87
|
+
api_key = os.getenv("IMPACT_API_KEY") or api_key
|
|
88
|
+
Impact.__app_name = app_name
|
|
89
|
+
|
|
90
|
+
if not is_tracing_enabled():
|
|
91
|
+
print(Fore.YELLOW + "Tracing is disabled" + Fore.RESET)
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
enable_content_tracing = is_content_tracing_enabled()
|
|
95
|
+
|
|
96
|
+
if exporter or processor:
|
|
97
|
+
print(Fore.GREEN + "Impact exporting traces to a custom exporter")
|
|
98
|
+
|
|
99
|
+
headers = os.getenv("IMPACT_HEADERS") or headers
|
|
100
|
+
|
|
101
|
+
if isinstance(headers, str):
|
|
102
|
+
headers = parse_env_headers(headers)
|
|
103
|
+
|
|
104
|
+
if (
|
|
105
|
+
not exporter
|
|
106
|
+
and not processor
|
|
107
|
+
and api_endpoint == "https://api.impact.ai"
|
|
108
|
+
and not api_key
|
|
109
|
+
):
|
|
110
|
+
print(
|
|
111
|
+
Fore.RED
|
|
112
|
+
+ "Error: Missing Impact API key,"
|
|
113
|
+
+ " go to https://app.impact.ai/settings/api-keys to create one"
|
|
114
|
+
)
|
|
115
|
+
print("Set the IMPACT_API_KEY environment variable to the key")
|
|
116
|
+
print(Fore.RESET)
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
if not exporter and not processor and headers:
|
|
120
|
+
print(
|
|
121
|
+
Fore.GREEN
|
|
122
|
+
+ f"Impact exporting traces to {api_endpoint}, authenticating with custom headers"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if api_key and not exporter and not processor and not headers:
|
|
126
|
+
print(
|
|
127
|
+
Fore.GREEN
|
|
128
|
+
+ f"Impact exporting traces to {api_endpoint} authenticating with bearer token"
|
|
129
|
+
)
|
|
130
|
+
headers = {
|
|
131
|
+
"Authorization": f"Bearer {api_key}",
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
print(Fore.RESET)
|
|
135
|
+
|
|
136
|
+
# Tracer init
|
|
137
|
+
resource_attributes.update({SERVICE_NAME: app_name})
|
|
138
|
+
TracerWrapper.set_static_params(
|
|
139
|
+
resource_attributes, enable_content_tracing, api_endpoint, headers
|
|
140
|
+
)
|
|
141
|
+
Impact.__tracer_wrapper = TracerWrapper(
|
|
142
|
+
disable_batch=disable_batch,
|
|
143
|
+
processor=processor,
|
|
144
|
+
propagator=propagator,
|
|
145
|
+
exporter=exporter,
|
|
146
|
+
|
|
147
|
+
image_uploader=image_uploader or ImageUploader(api_endpoint, api_key),
|
|
148
|
+
instruments=instruments,
|
|
149
|
+
block_instruments=block_instruments,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
if (
|
|
155
|
+
api_endpoint.find("impact.ai") != -1
|
|
156
|
+
and api_key
|
|
157
|
+
and (exporter is None)
|
|
158
|
+
and (processor is None)
|
|
159
|
+
):
|
|
160
|
+
if impact_sync_enabled:
|
|
161
|
+
Impact.__fetcher = Fetcher(base_url=api_endpoint, api_key=api_key)
|
|
162
|
+
Impact.__fetcher.run()
|
|
163
|
+
print(
|
|
164
|
+
Fore.GREEN
|
|
165
|
+
+ "Impact syncing configuration and prompts"
|
|
166
|
+
+ Fore.RESET
|
|
167
|
+
)
|
|
168
|
+
Impact.__client = Client(
|
|
169
|
+
api_key=api_key, app_name=app_name, api_endpoint=api_endpoint
|
|
170
|
+
)
|
|
171
|
+
return Impact.__client
|
|
172
|
+
|
|
173
|
+
def set_association_properties(properties: dict) -> None:
|
|
174
|
+
set_association_properties(properties)
|
|
175
|
+
|
|
176
|
+
def set_prompt(template: str, variables: dict, version: int):
|
|
177
|
+
set_external_prompt_tracing_context(template, variables, version)
|
|
178
|
+
|
|
179
|
+
@staticmethod
|
|
180
|
+
def get():
|
|
181
|
+
"""
|
|
182
|
+
Returns the shared SDK client instance, using the current global configuration.
|
|
183
|
+
|
|
184
|
+
To use the SDK as a singleton, first make sure you have called :func:`Impact.init()`
|
|
185
|
+
at startup time. Then ``get()`` will return the same shared :class:`Impact.client.Client`
|
|
186
|
+
instance each time. The client will be initialized if it has not been already.
|
|
187
|
+
|
|
188
|
+
If you need to create multiple client instances with different configurations, instead of this
|
|
189
|
+
singleton approach you can call the :class:`Impact.client.Client` constructor directly instead.
|
|
190
|
+
"""
|
|
191
|
+
if not Impact.__client:
|
|
192
|
+
raise Exception(
|
|
193
|
+
"Client not initialized, you should call Impact.init() first. "
|
|
194
|
+
"If you are still getting this error - you are missing the api key"
|
|
195
|
+
)
|
|
196
|
+
return Impact.__client
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
|
|
3
|
+
from ..client.http import HTTPClient
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BaseAnnotation:
|
|
7
|
+
"""
|
|
8
|
+
Annotation class for creating annotations in Impact.
|
|
9
|
+
|
|
10
|
+
This class provides functionality to create annotations for specific tasks.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
_http: HTTPClient
|
|
14
|
+
_app_name: str
|
|
15
|
+
|
|
16
|
+
def __init__(self, http: HTTPClient, app_name: str, flow: str):
|
|
17
|
+
self._http = http
|
|
18
|
+
self._app_name = app_name
|
|
19
|
+
self._flow = flow
|
|
20
|
+
|
|
21
|
+
def create(
|
|
22
|
+
self,
|
|
23
|
+
annotation_task: str,
|
|
24
|
+
entity_id: str,
|
|
25
|
+
tags: Dict[str, Any],
|
|
26
|
+
) -> None:
|
|
27
|
+
"""Create an user feedback annotation for a specific task.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
annotation_task (str): The ID/slug of the annotation task to report to.
|
|
31
|
+
Can be found at app.impact.ai/annotation_tasks/:annotation_task_id
|
|
32
|
+
entity_id (str): The ID of the specific entity instance being annotated, should be reported
|
|
33
|
+
in the association properties
|
|
34
|
+
tags (Dict[str, Any]): Dictionary containing the tags to be reported.
|
|
35
|
+
Should match the tags defined in the annotation task
|
|
36
|
+
|
|
37
|
+
Example:
|
|
38
|
+
```python
|
|
39
|
+
client = Client(api_key="your-key")
|
|
40
|
+
client.annotation.create(
|
|
41
|
+
annotation_task="task_123",
|
|
42
|
+
entity_id="instance_456",
|
|
43
|
+
tags={
|
|
44
|
+
"sentiment": "positive",
|
|
45
|
+
"relevance": 0.95,
|
|
46
|
+
"tones": ["happy", "nice"]
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
if not annotation_task:
|
|
53
|
+
raise ValueError("annotation_task is required")
|
|
54
|
+
if not entity_id:
|
|
55
|
+
raise ValueError("entity_id is required")
|
|
56
|
+
if not tags:
|
|
57
|
+
raise ValueError("tags cannot be empty")
|
|
58
|
+
|
|
59
|
+
self._http.post(
|
|
60
|
+
f"annotation-tasks/{annotation_task}/annotations",
|
|
61
|
+
{
|
|
62
|
+
"entity_instance_id": entity_id,
|
|
63
|
+
"tags": tags,
|
|
64
|
+
"source": "sdk",
|
|
65
|
+
"flow": self._flow,
|
|
66
|
+
"actor": {
|
|
67
|
+
"type": "service",
|
|
68
|
+
"id": self._app_name,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import Any, Dict
|
|
2
|
+
|
|
3
|
+
from impact.sdk.client.http import HTTPClient
|
|
4
|
+
from .base_annotation import BaseAnnotation
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class UserFeedback(BaseAnnotation):
|
|
8
|
+
def __init__(self, http: HTTPClient, app_name: str):
|
|
9
|
+
super().__init__(http, app_name, "user_feedback")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def create(
|
|
13
|
+
self,
|
|
14
|
+
annotation_task: str,
|
|
15
|
+
entity_instance_id: str,
|
|
16
|
+
tags: Dict[str, Any],
|
|
17
|
+
) -> None:
|
|
18
|
+
"""Create an annotation for a specific task.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
annotation_task (str): The ID/slug of the annotation task to report to.
|
|
22
|
+
Can be found at app.impact.ai/annotation_tasks/:annotation_task_id
|
|
23
|
+
entity_instance_id (str): The ID of the specific entity instance being annotated, should be reported
|
|
24
|
+
in the association properties
|
|
25
|
+
tags (Dict[str, Any]): Dictionary containing the tags to be reported.
|
|
26
|
+
Should match the tags defined in the annotation task
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
```python
|
|
30
|
+
client = Client(api_key="your-key")
|
|
31
|
+
client.annotation.create(
|
|
32
|
+
annotation_task="task_123",
|
|
33
|
+
entity_instance_id="instance_456",
|
|
34
|
+
tags={
|
|
35
|
+
"sentiment": "positive",
|
|
36
|
+
"relevance": 0.95,
|
|
37
|
+
"tones": ["happy", "nice"]
|
|
38
|
+
},
|
|
39
|
+
)
|
|
40
|
+
```
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
return BaseAnnotation.create(self, annotation_task, entity_instance_id, tags)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .client import Client
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from impact.sdk.annotation.user_feedback import UserFeedback
|
|
4
|
+
from .http import HTTPClient
|
|
5
|
+
from impact.sdk.version import __version__
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Client:
|
|
9
|
+
"""
|
|
10
|
+
Impact Client for interacting with the Impact API.
|
|
11
|
+
|
|
12
|
+
Applications should configure the client at startup time and continue to use it throughout the lifetime
|
|
13
|
+
of the application, rather than creating instances on the fly. The best way to do this is with the
|
|
14
|
+
singleton methods :func:`Impact.init()` and :func:`Impact.get()`. However, you may also call
|
|
15
|
+
the constructor directly if you need to maintain multiple instances.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
app_name: str
|
|
19
|
+
api_endpoint: str
|
|
20
|
+
api_key: str
|
|
21
|
+
user_feedback: UserFeedback
|
|
22
|
+
_http: HTTPClient
|
|
23
|
+
|
|
24
|
+
def __init__(self, api_key: str, app_name: str = sys.argv[0], api_endpoint: str = "https://api.impact.ai"):
|
|
25
|
+
"""
|
|
26
|
+
Initialize a new Impact client.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
api_key (str): Your Impact API key
|
|
30
|
+
app_name (Optional[str], optional): The name of your application. Defaults to sys.argv[0].
|
|
31
|
+
api_endpoint (Optional[str], optional): Custom API endpoint. Defaults to https://api.impact.ai.
|
|
32
|
+
"""
|
|
33
|
+
if not api_key or not api_key.strip():
|
|
34
|
+
raise ValueError("API key is required")
|
|
35
|
+
|
|
36
|
+
self.app_name = app_name
|
|
37
|
+
self.api_endpoint = api_endpoint or "https://api.impact.ai"
|
|
38
|
+
self.api_key = api_key
|
|
39
|
+
self._http = HTTPClient(base_url=self.api_endpoint, api_key=self.api_key, version=__version__)
|
|
40
|
+
self.user_feedback = UserFeedback(self._http, self.app_name)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
from colorama import Fore
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class HTTPClient:
|
|
8
|
+
base_url: str
|
|
9
|
+
api_key: str
|
|
10
|
+
version: str
|
|
11
|
+
|
|
12
|
+
def __init__(self, base_url: str, api_key: str, version: str):
|
|
13
|
+
self.base_url = base_url.rstrip("/")
|
|
14
|
+
self.api_key = api_key
|
|
15
|
+
self.version = version
|
|
16
|
+
|
|
17
|
+
def _headers(self):
|
|
18
|
+
return {
|
|
19
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
20
|
+
"X-Impact-SDK-Version": self.version,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def post(self, path: str, data: Dict[str, Any]) -> Any:
|
|
24
|
+
"""
|
|
25
|
+
Make a POST request to the API
|
|
26
|
+
"""
|
|
27
|
+
try:
|
|
28
|
+
response = requests.post(f"{self.base_url}/v2/{path.lstrip('/')}", json=data, headers=self._headers())
|
|
29
|
+
response.raise_for_status()
|
|
30
|
+
return response.json()
|
|
31
|
+
except requests.exceptions.RequestException as e:
|
|
32
|
+
print(Fore.RED + f"Error making request to {path}: {str(e)}" + Fore.RESET)
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Any:
|
|
36
|
+
"""
|
|
37
|
+
Make a GET request to the API
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
response = requests.get(f"{self.base_url}/v2/{path.lstrip('/')}", params=params, headers=self._headers())
|
|
41
|
+
response.raise_for_status()
|
|
42
|
+
return response.json()
|
|
43
|
+
except requests.exceptions.RequestException as e:
|
|
44
|
+
print(Fore.RED + f"Error making request to {path}: {str(e)}" + Fore.RESET)
|
|
45
|
+
return None
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def is_tracing_enabled() -> bool:
|
|
5
|
+
return (os.getenv("IMPACT_TRACING_ENABLED") or "true").lower() == "true"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def is_content_tracing_enabled() -> bool:
|
|
9
|
+
return (os.getenv("IMPACT_TRACE_CONTENT") or "true").lower() == "true"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
import warnings
|
|
3
|
+
|
|
4
|
+
from opentelemetry.semconv_ai import ImpactSpanKindValues
|
|
5
|
+
|
|
6
|
+
from impact.sdk.decorators.base import (
|
|
7
|
+
entity_class,
|
|
8
|
+
entity_method,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def task(
|
|
13
|
+
name: Optional[str] = None,
|
|
14
|
+
version: Optional[int] = None,
|
|
15
|
+
method_name: Optional[str] = None,
|
|
16
|
+
tlp_span_kind: Optional[ImpactSpanKindValues] = ImpactSpanKindValues.TASK,
|
|
17
|
+
):
|
|
18
|
+
if method_name is None:
|
|
19
|
+
return entity_method(name=name, version=version, tlp_span_kind=tlp_span_kind)
|
|
20
|
+
else:
|
|
21
|
+
return entity_class(
|
|
22
|
+
name=name,
|
|
23
|
+
version=version,
|
|
24
|
+
method_name=method_name,
|
|
25
|
+
tlp_span_kind=tlp_span_kind,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def workflow(
|
|
30
|
+
name: Optional[str] = None,
|
|
31
|
+
version: Optional[int] = None,
|
|
32
|
+
method_name: Optional[str] = None,
|
|
33
|
+
tlp_span_kind: Optional[ImpactSpanKindValues] = ImpactSpanKindValues.WORKFLOW,
|
|
34
|
+
):
|
|
35
|
+
if method_name is None:
|
|
36
|
+
return entity_method(name=name, version=version, tlp_span_kind=tlp_span_kind)
|
|
37
|
+
else:
|
|
38
|
+
return entity_class(
|
|
39
|
+
name=name,
|
|
40
|
+
version=version,
|
|
41
|
+
method_name=method_name,
|
|
42
|
+
tlp_span_kind=tlp_span_kind,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def agent(
|
|
47
|
+
name: Optional[str] = None,
|
|
48
|
+
version: Optional[int] = None,
|
|
49
|
+
method_name: Optional[str] = None,
|
|
50
|
+
):
|
|
51
|
+
return workflow(
|
|
52
|
+
name=name,
|
|
53
|
+
version=version,
|
|
54
|
+
method_name=method_name,
|
|
55
|
+
tlp_span_kind=ImpactSpanKindValues.AGENT,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def tool(
|
|
60
|
+
name: Optional[str] = None,
|
|
61
|
+
version: Optional[int] = None,
|
|
62
|
+
method_name: Optional[str] = None,
|
|
63
|
+
):
|
|
64
|
+
return task(
|
|
65
|
+
name=name,
|
|
66
|
+
version=version,
|
|
67
|
+
method_name=method_name,
|
|
68
|
+
tlp_span_kind=ImpactSpanKindValues.TOOL,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# Async Decorators - Deprecated
|
|
73
|
+
def atask(
|
|
74
|
+
name: Optional[str] = None,
|
|
75
|
+
version: Optional[int] = None,
|
|
76
|
+
method_name: Optional[str] = None,
|
|
77
|
+
tlp_span_kind: Optional[ImpactSpanKindValues] = ImpactSpanKindValues.TASK,
|
|
78
|
+
):
|
|
79
|
+
warnings.warn(
|
|
80
|
+
"DeprecationWarning: The @atask decorator will be removed in a future version. "
|
|
81
|
+
"Please migrate to @task for both sync and async operations.",
|
|
82
|
+
DeprecationWarning,
|
|
83
|
+
stacklevel=2
|
|
84
|
+
)
|
|
85
|
+
if method_name is None:
|
|
86
|
+
return entity_method(name=name, version=version, tlp_span_kind=tlp_span_kind)
|
|
87
|
+
else:
|
|
88
|
+
return entity_class(name=name, version=version, method_name=method_name, tlp_span_kind=tlp_span_kind)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def aworkflow(
|
|
92
|
+
name: Optional[str] = None,
|
|
93
|
+
version: Optional[int] = None,
|
|
94
|
+
method_name: Optional[str] = None,
|
|
95
|
+
tlp_span_kind: Optional[ImpactSpanKindValues] = ImpactSpanKindValues.WORKFLOW,
|
|
96
|
+
):
|
|
97
|
+
warnings.warn(
|
|
98
|
+
"DeprecationWarning: The @aworkflow decorator will be removed in a future version. "
|
|
99
|
+
"Please migrate to @workflow for both sync and async operations.",
|
|
100
|
+
DeprecationWarning,
|
|
101
|
+
stacklevel=2
|
|
102
|
+
)
|
|
103
|
+
if method_name is None:
|
|
104
|
+
return entity_method(name=name, version=version, tlp_span_kind=tlp_span_kind)
|
|
105
|
+
else:
|
|
106
|
+
return entity_class(
|
|
107
|
+
name=name,
|
|
108
|
+
version=version,
|
|
109
|
+
method_name=method_name,
|
|
110
|
+
tlp_span_kind=tlp_span_kind,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def aagent(
|
|
115
|
+
name: Optional[str] = None,
|
|
116
|
+
version: Optional[int] = None,
|
|
117
|
+
method_name: Optional[str] = None,
|
|
118
|
+
):
|
|
119
|
+
warnings.warn(
|
|
120
|
+
"DeprecationWarning: The @aagent decorator will be removed in a future version. "
|
|
121
|
+
"Please migrate to @agent for both sync and async operations.",
|
|
122
|
+
DeprecationWarning,
|
|
123
|
+
stacklevel=2
|
|
124
|
+
)
|
|
125
|
+
return atask(
|
|
126
|
+
name=name,
|
|
127
|
+
version=version,
|
|
128
|
+
method_name=method_name,
|
|
129
|
+
tlp_span_kind=ImpactSpanKindValues.AGENT,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def atool(
|
|
134
|
+
name: Optional[str] = None,
|
|
135
|
+
version: Optional[int] = None,
|
|
136
|
+
method_name: Optional[str] = None,
|
|
137
|
+
):
|
|
138
|
+
warnings.warn(
|
|
139
|
+
"DeprecationWarning: The @atool decorator will be removed in a future version. "
|
|
140
|
+
"Please migrate to @tool for both sync and async operations.",
|
|
141
|
+
DeprecationWarning,
|
|
142
|
+
stacklevel=2
|
|
143
|
+
)
|
|
144
|
+
return atask(
|
|
145
|
+
name=name,
|
|
146
|
+
version=version,
|
|
147
|
+
method_name=method_name,
|
|
148
|
+
tlp_span_kind=ImpactSpanKindValues.TOOL,
|
|
149
|
+
)
|