lmnr 0.1.3__py3-none-any.whl → 0.2.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.
lmnr/__init__.py CHANGED
@@ -1,5 +1,7 @@
1
1
  from .sdk.endpoint import Laminar
2
2
  from .types import (
3
- ChatMessage, EndpointRunError, EndpointRunResponse,
4
- NodeInput, SDKError,
5
- )
3
+ ChatMessage,
4
+ EndpointRunError,
5
+ EndpointRunResponse,
6
+ NodeInput
7
+ )
lmnr/cli/__init__.py ADDED
File without changes
lmnr/cli/cli.py CHANGED
@@ -56,7 +56,7 @@ def pull(pipeline_name, pipeline_version_name, project_api_key, loglevel):
56
56
  "pipelineVersionName": pipeline_version_name,
57
57
  }
58
58
  res = requests.get(
59
- "https://api.lmnr.ai/v1/pipeline-version-by-name",
59
+ "https://api.lmnr.ai/v2/pipeline-version-by-name",
60
60
  headers=headers,
61
61
  params=params,
62
62
  )
@@ -73,7 +73,7 @@ def pull(pipeline_name, pipeline_version_name, project_api_key, loglevel):
73
73
 
74
74
  pipeline_version = res.json()
75
75
 
76
- class_name = to_pascal(pipeline_name.replace(" ", "_"))
76
+ class_name = to_pascal(pipeline_name.replace(" ", "_").replace("-", "_"))
77
77
 
78
78
  context = {
79
79
  "pipeline_name": pipeline_name,
@@ -91,7 +91,7 @@ def pull(pipeline_name, pipeline_version_name, project_api_key, loglevel):
91
91
  output_dir=".",
92
92
  config_file=None,
93
93
  extra_context=context,
94
- directory="cli",
94
+ directory="cli/",
95
95
  no_input=True,
96
96
  overwrite_if_exists=True,
97
97
  )
@@ -5,6 +5,7 @@ from lmnr.cli.parser.nodes import Handle, HandleType, NodeFunctions
5
5
  from lmnr.cli.parser.utils import map_handles
6
6
  from lmnr.types import NodeInput, ChatMessage
7
7
 
8
+
8
9
  def node_input_from_json(json_val: Any) -> NodeInput:
9
10
  if isinstance(json_val, str):
10
11
  return json_val
@@ -3,7 +3,7 @@ from dataclasses import dataclass
3
3
  import logging
4
4
  from typing import Optional, Union
5
5
 
6
- from lmnr_engine.types import ChatMessageList, ChatMessage
6
+ from lmnr.types import ChatMessage
7
7
  from lmnr_engine.engine import Engine
8
8
  {% set function_names = cookiecutter._tasks.values() | selectattr('node_type', '!=', 'Input') | map(attribute='function_name') | join(', ') %}
9
9
  from .nodes.functions import {{ function_names }}
@@ -19,7 +19,7 @@ class PipelineRunnerError(Exception):
19
19
 
20
20
  @dataclass
21
21
  class PipelineRunOutput:
22
- value: Union[str, ChatMessageList]
22
+ value: Union[str, list[ChatMessage]]
23
23
 
24
24
 
25
25
  # This class is not imported in other files and can be renamed to desired name
@@ -55,7 +55,7 @@ class {{ cookiecutter.class_name }}:
55
55
  run_inputs[inp_name] = inp
56
56
  else:
57
57
  assert isinstance(inp, list), f"Invalid input type: {type(inp)}"
58
- run_inputs[inp_name] = [ChatMessage.from_dict(msg) for msg in inp]
58
+ run_inputs[inp_name] = [ChatMessage.model_validate(msg) for msg in inp]
59
59
 
60
60
  tasks = []
61
61
  {% for task in cookiecutter._tasks.values() %}
@@ -2,22 +2,7 @@ from dataclasses import dataclass
2
2
  from typing import Union
3
3
  import uuid
4
4
  import datetime
5
-
6
-
7
- @dataclass
8
- class ChatMessage:
9
- role: str
10
- content: str
11
-
12
- @classmethod
13
- def from_dict(cls, data: dict) -> "ChatMessage":
14
- return cls(
15
- role=data["role"],
16
- content=data["content"],
17
- )
18
-
19
-
20
- NodeInput = Union[str, list[ChatMessage]] # TODO: Add conditioned value
5
+ from lmnr.types import NodeInput, ChatMessage
21
6
 
22
7
 
23
8
  @dataclass
lmnr/sdk/endpoint.py CHANGED
@@ -2,7 +2,7 @@ import json
2
2
  from pydantic.alias_generators import to_snake
3
3
  import pydantic
4
4
  import requests
5
- from ..types import (
5
+ from lmnr.types import (
6
6
  EndpointRunError, EndpointRunResponse, NodeInput, EndpointRunRequest,
7
7
  ToolCall, SDKError
8
8
  )
@@ -21,7 +21,7 @@ class Laminar:
21
21
  """
22
22
  self.project_api_key = project_api_key
23
23
  self.url = 'https://api.lmnr.ai/v2/endpoint/run'
24
- self.ws_url = 'ws://api.lmnr.ai/v2/endpoint/ws'
24
+ self.ws_url = 'wss://api.lmnr.ai/v2/endpoint/ws'
25
25
 
26
26
  def run (
27
27
  self,
@@ -120,7 +120,7 @@ class Laminar:
120
120
  raise ValueError(f'Invalid request: {e}')
121
121
 
122
122
  with connect(
123
- "ws://localhost:8000/v2/endpoint/ws",
123
+ self.ws_url,
124
124
  additional_headers={
125
125
  'Authorization': f'Bearer {self.project_api_key}'
126
126
  }
lmnr/types.py CHANGED
@@ -1,21 +1,12 @@
1
+
1
2
  import requests
2
3
  import pydantic
3
- from typing import Any, Union, Optional
4
+ from typing import Union, Optional
4
5
 
5
6
  class ChatMessage(pydantic.BaseModel):
6
- """Chat message object
7
-
8
- Attributes:
9
- role (str):
10
- Role of the message sender.
11
- Can be 'user', 'assistant', or 'system'.
12
- content (str): Message content
13
- """
14
7
  role: str
15
8
  content: str
16
9
 
17
- """NodeInput is a common type for values shared
18
- between nodes in Laminar pipelines."""
19
10
  NodeInput = Union[str, list[ChatMessage]] # TypeAlias
20
11
 
21
12
  class EndpointRunRequest(pydantic.BaseModel):
@@ -25,30 +16,9 @@ class EndpointRunRequest(pydantic.BaseModel):
25
16
  metadata: dict[str, str] = pydantic.Field(default_factory=dict)
26
17
 
27
18
  class EndpointRunResponse(pydantic.BaseModel):
28
- """Response object from endpoint run
29
-
30
- Attributes:
31
- outputs (dict[str, dict[str, NodeInput]]):
32
- Dictionary of output names and their values.
33
- Each value is a dictionary with the following keys:
34
- - 'value': Output value
35
- run_id (str): Stringified UUID of the run. Useful to find traces.
36
- """
37
19
  outputs: dict[str, dict[str, NodeInput]]
38
20
  run_id: str
39
21
 
40
- def get_output(self, output_name: str) -> Optional[NodeInput]:
41
- """utility to extract the output value by node name
42
-
43
- Args:
44
- output_name (str): must match the output node name
45
-
46
- Returns:
47
- Optional[NodeInput]: value of the output node if found
48
- """
49
- output = self.outputs.get(output_name)
50
- return output.get('value') if output else None
51
-
52
22
  class EndpointRunError(Exception):
53
23
  error_code: str
54
24
  error_message: str
@@ -64,30 +34,19 @@ class EndpointRunError(Exception):
64
34
 
65
35
  def __str__(self) -> str:
66
36
  try:
67
- return str({
68
- 'error_code': self.error_code,
69
- 'error_message': self.error_message
70
- })
37
+ return str({'error_code': self.error_code, 'error_message': self.error_message})
71
38
  except:
72
39
  return super().__str__()
73
-
40
+
74
41
  class SDKError(Exception):
75
- error_message: str
76
-
77
- def __init__(self, error_message: str):
78
- self.error_message = error_message
79
- super().__init__(self.error_message)
80
-
81
- def __str__(self) -> str:
82
- return super().__str__()
42
+ def __init__(self, error_mesasge: str):
43
+ super().__init__(error_mesasge)
83
44
 
84
- class ToolFunctionCall(pydantic.BaseModel):
45
+ class ToolCallRequest(pydantic.BaseModel):
85
46
  name: str
86
47
  arguments: str
87
48
 
88
49
  class ToolCall(pydantic.BaseModel):
89
- id: str
90
- type: str
91
- function: ToolFunctionCall
92
-
93
- ToolResponse = NodeInput # TypeAlias
50
+ id: Optional[str]
51
+ type: Optional[str]
52
+ function: ToolCallRequest
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  Apache License
2
4
  Version 2.0, January 2004
3
5
  http://www.apache.org/licenses/
@@ -51,7 +53,8 @@ You may add Your own copyright statement to Your modifications and may provide a
51
53
 
52
54
  END OF TERMS AND CONDITIONS
53
55
 
54
- APPENDIX: How to apply the Apache License to your work.
56
+
57
+ APPENDIX: How to apply the Apache License to your work
55
58
 
56
59
  Include a copy of the Apache License, typically in a file called LICENSE, in your work, and consider also including a NOTICE file that references the License.
57
60
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lmnr
3
- Version: 0.1.3
3
+ Version: 0.2.1
4
4
  Summary: Python SDK for Laminar AI
5
5
  License: Apache-2.0
6
6
  Author: lmnr.ai
@@ -1,10 +1,11 @@
1
- lmnr/__init__.py,sha256=FWUUXOnLBJdG1dHR0shVQsf9WDVppCvB9ibkN0fSfMQ,138
1
+ lmnr/__init__.py,sha256=fUbQpFuP1eK1dymP72SH5tFn-zggGVJkqIPU8X9Iq6w,134
2
+ lmnr/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
3
  lmnr/cli/__main__.py,sha256=8hDtWlaFZK24KhfNq_ZKgtXqYHsDQDetukOCMlsbW0Q,59
3
- lmnr/cli/cli.py,sha256=6RwhSPcT9BpppC9Mbs6H01AV7ILqCLcBM5TRAU6-9F4,2828
4
+ lmnr/cli/cli.py,sha256=pzr5LUILi7TcaJIkC-CzmT7RG7-HWApQmUpgK9bc7mI,2847
4
5
  lmnr/cli/cookiecutter.json,sha256=PeiMMzCPzDhsapqYoAceYGPI5lOUNimvFzh5KeQv5QE,359
5
6
  lmnr/cli/parser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
7
  lmnr/cli/parser/nodes/__init__.py,sha256=BNbbfn0WwbFDA6TNhLOaT_Ji69rCL5voUibqMD7Knng,1163
7
- lmnr/cli/parser/nodes/types.py,sha256=dA3xUARy-SGz-PKENqCsExxoPN3HfS0lNHVjt_qV1dg,5080
8
+ lmnr/cli/parser/nodes/types.py,sha256=fqw_0-szpcZ8G3bADjgG97gCng2DRIkL72nLV11gTP4,5081
8
9
  lmnr/cli/parser/parser.py,sha256=UtuupKj2Dh-47HVcYU4PI2s4Erh1gTjKiuGCcc-nkbM,2163
9
10
  lmnr/cli/parser/utils.py,sha256=wVaqHVOR9VXl8Og9nkVyCVgHIcgbtYGkDOEGPtmjZ8g,715
10
11
  lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -15,12 +16,12 @@ lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/engine/state.py,sha256=wTx7jAv
15
16
  lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/engine/task.py,sha256=ware5VIrZvluHH3mpH6h7G0YDk5L0buSQ7s09za4Fro,1200
16
17
  lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/pipelines/{{cookiecutter.pipeline_dir_name}}/__init__.py,sha256=bsfbNUBYtKv37qzc_GLhSAzBam2lnowP_dlr8pubhcg,80
17
18
  lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/pipelines/{{cookiecutter.pipeline_dir_name}}/nodes/functions.py,sha256=2fLTN6PbhlSPEcrHBSSJESmg__UNMk4Ivs5mz0LqnG8,5169
18
- lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/pipelines/{{cookiecutter.pipeline_dir_name}}/{{cookiecutter.pipeline_dir_name}}.py,sha256=jlQhZKJOoWaH0rouuj4gDUJlZRK08-xYPZMPVCrgD0g,2875
19
- lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/types.py,sha256=khctWhiUhNfTDnWGimI3es1RcK6DYINtmjOyhzNgSXE,1258
20
- lmnr/sdk/endpoint.py,sha256=_WYouHOULQurYmc_CkKVQuZ8QF5gFLV6TrXJs4SKNbE,6380
21
- lmnr/types.py,sha256=HmYAP4ATNjOU1hDwEVx3Ihlan0ePUHO1ENNWmjOhGu8,2708
22
- lmnr-0.1.3.dist-info/LICENSE,sha256=lLTMLT6LFx2zRc2EBXE04hvY9ujHZrHxN3sLZJS7U00,10409
23
- lmnr-0.1.3.dist-info/METADATA,sha256=4TzGh5G_7bNiiVcD3JDJhIH1ARIXT3GFUAuLRlQua64,2258
24
- lmnr-0.1.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
25
- lmnr-0.1.3.dist-info/entry_points.txt,sha256=Qg7ZRax4k-rcQsZ26XRYQ8YFSBiyY2PNxYfq4a6PYXI,41
26
- lmnr-0.1.3.dist-info/RECORD,,
19
+ lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/pipelines/{{cookiecutter.pipeline_dir_name}}/{{cookiecutter.pipeline_dir_name}}.py,sha256=WG-ZMofPpGXCx5jdWVry3_XBzcKjqn8ZycFSiWEOBPg,2858
20
+ lmnr/cli/{{cookiecutter.lmnr_pipelines_dir_name}}/types.py,sha256=iWuflMV7TiaBPs6-B-BlrovvWpZgHGGHK0v8rSqER7A,997
21
+ lmnr/sdk/endpoint.py,sha256=tT6-w-mwbh4BAwnj5G0pCVE_Sz8EUzZmpBtacm_T2pE,6359
22
+ lmnr/types.py,sha256=SECA2thlH3pO1F6UvvpyffnwHSdjho4RE2hPYJQH-jE,1444
23
+ lmnr-0.2.1.dist-info/LICENSE,sha256=67b_wJHVV1CBaWkrKFWU1wyqTPSdzH77Ls-59631COg,10411
24
+ lmnr-0.2.1.dist-info/METADATA,sha256=aTT3pJgKV_4wxQ6kyjhhk7GuI1xBNTbK-MFviSn3iGo,2258
25
+ lmnr-0.2.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
26
+ lmnr-0.2.1.dist-info/entry_points.txt,sha256=Qg7ZRax4k-rcQsZ26XRYQ8YFSBiyY2PNxYfq4a6PYXI,41
27
+ lmnr-0.2.1.dist-info/RECORD,,
File without changes