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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: promptlayer
3
- Version: 1.0.35
3
+ Version: 1.0.37
4
4
  Summary: PromptLayer is a platform for prompt engineering and tracks your LLM requests.
5
5
  License: Apache-2.0
6
6
  Author: Magniv
@@ -1,4 +1,4 @@
1
1
  from .promptlayer import AsyncPromptLayer, PromptLayer
2
2
 
3
- __version__ = "1.0.35"
3
+ __version__ = "1.0.37"
4
4
  __all__ = ["PromptLayer", "AsyncPromptLayer", "__version__"]
@@ -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
- # If there's an active event loop, use `await` directly
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
- # If there's no active event loop, use `asyncio.run()`
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
- ) -> Dict[str, Any]:
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
- final_output = {}
115
+ results = None
116
116
  message_received_event = asyncio.Event()
117
117
 
118
118
  async def message_listener(message: Message):
119
- if message.name == "set_workflow_node_output":
120
- data = json.loads(message.data)
121
- if data.get("status") == "workflow_complete":
122
- final_output.update(data.get("final_output", {}))
123
- message_received_event.set()
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("set_workflow_node_output", message_listener)
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("set_workflow_node_output", message_listener)
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("set_workflow_node_output", message_listener)
138
+ channel.unsubscribe("SET_WORKFLOW_COMPLETE", message_listener)
138
139
  await ably_client.close()
139
140
 
140
- return final_output
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.35"
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