promptlayer 1.0.35__tar.gz → 1.0.37__tar.gz
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 promptlayer might be problematic. Click here for more details.
- {promptlayer-1.0.35 → promptlayer-1.0.37}/PKG-INFO +1 -1
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/__init__.py +1 -1
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/promptlayer.py +44 -8
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/utils.py +12 -11
- {promptlayer-1.0.35 → promptlayer-1.0.37}/pyproject.toml +2 -2
- {promptlayer-1.0.35 → promptlayer-1.0.37}/LICENSE +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/README.md +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/groups/__init__.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/groups/groups.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/promptlayer_base.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/promptlayer_mixins.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/span_exporter.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/templates.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/track/__init__.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/track/track.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/types/__init__.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/types/prompt_template.py +0 -0
- {promptlayer-1.0.35 → promptlayer-1.0.37}/promptlayer/types/request_log.py +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import json
|
|
2
3
|
import os
|
|
3
4
|
from typing import Any, Dict, List, Literal, Optional, Union
|
|
4
5
|
|
|
@@ -21,6 +22,27 @@ from promptlayer.utils import (
|
|
|
21
22
|
)
|
|
22
23
|
|
|
23
24
|
|
|
25
|
+
def is_workflow_results_dict(obj: Any) -> bool:
|
|
26
|
+
if not isinstance(obj, dict):
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
required_keys = {
|
|
30
|
+
"status",
|
|
31
|
+
"value",
|
|
32
|
+
"error_message",
|
|
33
|
+
"raw_error_message",
|
|
34
|
+
"is_output_node",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for val in obj.values():
|
|
38
|
+
if not isinstance(val, dict):
|
|
39
|
+
return False
|
|
40
|
+
if not required_keys.issubset(val.keys()):
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
return True
|
|
44
|
+
|
|
45
|
+
|
|
24
46
|
class PromptLayer(PromptLayerMixin):
|
|
25
47
|
def __init__(
|
|
26
48
|
self,
|
|
@@ -225,11 +247,9 @@ class PromptLayer(PromptLayerMixin):
|
|
|
225
247
|
input_variables: Optional[Dict[str, Any]] = None,
|
|
226
248
|
metadata: Optional[Dict[str, str]] = None,
|
|
227
249
|
workflow_label_name: Optional[str] = None,
|
|
228
|
-
workflow_version: Optional[
|
|
229
|
-
int
|
|
230
|
-
] = None, # This is the version number, not the version ID
|
|
250
|
+
workflow_version: Optional[int] = None,
|
|
231
251
|
return_all_outputs: Optional[bool] = False,
|
|
232
|
-
) -> Dict[str, Any]:
|
|
252
|
+
) -> Union[Dict[str, Any], Any]:
|
|
233
253
|
try:
|
|
234
254
|
try:
|
|
235
255
|
# Check if we're inside a running event loop
|
|
@@ -239,8 +259,7 @@ class PromptLayer(PromptLayerMixin):
|
|
|
239
259
|
|
|
240
260
|
if loop and loop.is_running():
|
|
241
261
|
nest_asyncio.apply()
|
|
242
|
-
|
|
243
|
-
return asyncio.run(
|
|
262
|
+
results = asyncio.run(
|
|
244
263
|
arun_workflow_request(
|
|
245
264
|
workflow_name=workflow_name,
|
|
246
265
|
input_variables=input_variables or {},
|
|
@@ -252,8 +271,7 @@ class PromptLayer(PromptLayerMixin):
|
|
|
252
271
|
)
|
|
253
272
|
)
|
|
254
273
|
else:
|
|
255
|
-
|
|
256
|
-
return asyncio.run(
|
|
274
|
+
results = asyncio.run(
|
|
257
275
|
arun_workflow_request(
|
|
258
276
|
workflow_name=workflow_name,
|
|
259
277
|
input_variables=input_variables or {},
|
|
@@ -264,6 +282,24 @@ class PromptLayer(PromptLayerMixin):
|
|
|
264
282
|
return_all_outputs=return_all_outputs,
|
|
265
283
|
)
|
|
266
284
|
)
|
|
285
|
+
|
|
286
|
+
if not return_all_outputs:
|
|
287
|
+
if is_workflow_results_dict(results):
|
|
288
|
+
output_nodes = [
|
|
289
|
+
node_data
|
|
290
|
+
for node_data in results.values()
|
|
291
|
+
if node_data.get("is_output_node")
|
|
292
|
+
]
|
|
293
|
+
|
|
294
|
+
if not output_nodes:
|
|
295
|
+
raise Exception(json.dumps(results, indent=4))
|
|
296
|
+
|
|
297
|
+
if not any(
|
|
298
|
+
node.get("status") == "SUCCESS" for node in output_nodes
|
|
299
|
+
):
|
|
300
|
+
raise Exception(json.dumps(results, indent=4))
|
|
301
|
+
|
|
302
|
+
return results
|
|
267
303
|
except Exception as e:
|
|
268
304
|
raise Exception(f"Error running workflow: {str(e)}")
|
|
269
305
|
|
|
@@ -50,7 +50,7 @@ async def arun_workflow_request(
|
|
|
50
50
|
api_key: str,
|
|
51
51
|
return_all_outputs: Optional[bool] = False,
|
|
52
52
|
timeout: Optional[int] = 120,
|
|
53
|
-
)
|
|
53
|
+
):
|
|
54
54
|
payload = {
|
|
55
55
|
"input_variables": input_variables,
|
|
56
56
|
"metadata": metadata,
|
|
@@ -112,32 +112,33 @@ async def arun_workflow_request(
|
|
|
112
112
|
# Subscribe to the channel named after the execution ID
|
|
113
113
|
channel = ably_client.channels.get(channel_name)
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
results = None
|
|
116
116
|
message_received_event = asyncio.Event()
|
|
117
117
|
|
|
118
118
|
async def message_listener(message: Message):
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
nonlocal results
|
|
120
|
+
|
|
121
|
+
if message.name == "SET_WORKFLOW_COMPLETE":
|
|
122
|
+
message_data = json.loads(message.data)
|
|
123
|
+
results = message_data["final_output"]
|
|
124
|
+
message_received_event.set()
|
|
124
125
|
|
|
125
126
|
# Subscribe to the channel
|
|
126
|
-
await channel.subscribe("
|
|
127
|
+
await channel.subscribe("SET_WORKFLOW_COMPLETE", message_listener)
|
|
127
128
|
|
|
128
129
|
# Wait for the message or timeout
|
|
129
130
|
try:
|
|
130
131
|
await asyncio.wait_for(message_received_event.wait(), timeout)
|
|
131
132
|
except asyncio.TimeoutError:
|
|
132
|
-
channel.unsubscribe("
|
|
133
|
+
channel.unsubscribe("SET_WORKFLOW_COMPLETE", message_listener)
|
|
133
134
|
await ably_client.close()
|
|
134
135
|
raise Exception("Workflow execution did not complete properly")
|
|
135
136
|
|
|
136
137
|
# Unsubscribe from the channel and close the client
|
|
137
|
-
channel.unsubscribe("
|
|
138
|
+
channel.unsubscribe("SET_WORKFLOW_COMPLETE", message_listener)
|
|
138
139
|
await ably_client.close()
|
|
139
140
|
|
|
140
|
-
return
|
|
141
|
+
return results
|
|
141
142
|
|
|
142
143
|
|
|
143
144
|
def promptlayer_api_handler(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "promptlayer"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.37"
|
|
4
4
|
description = "PromptLayer is a platform for prompt engineering and tracks your LLM requests."
|
|
5
5
|
authors = ["Magniv <hello@magniv.io>"]
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -21,9 +21,9 @@ langchain = "^0.0.260"
|
|
|
21
21
|
behave = "^1.2.6"
|
|
22
22
|
pytest = "^8.2.0"
|
|
23
23
|
pytest-asyncio = "^0.23.6"
|
|
24
|
-
openai = "^1.26.0"
|
|
25
24
|
anyio = "^4.3.0"
|
|
26
25
|
anthropic = "^0.25.8"
|
|
26
|
+
openai = "^1.60.1"
|
|
27
27
|
|
|
28
28
|
[build-system]
|
|
29
29
|
requires = ["poetry-core"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|