langwatch 0.2.18__py3-none-any.whl → 0.3.0__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.
Files changed (27) hide show
  1. langwatch/__init__.py +5 -5
  2. langwatch/__version__.py +1 -1
  3. langwatch/generated/langwatch_rest_api_client/models/__init__.py +2 -18
  4. langwatch/generated/langwatch_rest_api_client/models/post_api_scenario_events_body_type_2.py +7 -115
  5. langwatch/generated/langwatch_rest_api_client/models/{post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item_function.py → post_api_scenario_events_body_type_2_messages_item.py} +23 -22
  6. langwatch/prompts/__init__.py +2 -2
  7. langwatch/prompts/decorators/prompt_service_tracing.py +6 -4
  8. langwatch/prompts/local_loader.py +170 -0
  9. langwatch/prompts/prompt.py +41 -43
  10. langwatch/prompts/{service.py → prompt_api_service.py} +23 -33
  11. langwatch/prompts/prompt_facade.py +139 -0
  12. langwatch/prompts/types/__init__.py +27 -0
  13. langwatch/prompts/types/prompt_data.py +93 -0
  14. langwatch/prompts/types/structures.py +37 -0
  15. langwatch/prompts/types.py +16 -24
  16. langwatch/utils/initialization.py +8 -2
  17. langwatch/utils/transformation.py +16 -5
  18. {langwatch-0.2.18.dist-info → langwatch-0.3.0.dist-info}/METADATA +1 -1
  19. {langwatch-0.2.18.dist-info → langwatch-0.3.0.dist-info}/RECORD +20 -22
  20. langwatch/generated/langwatch_rest_api_client/models/post_api_scenario_events_body_type_2_messages_item_type_0.py +0 -88
  21. langwatch/generated/langwatch_rest_api_client/models/post_api_scenario_events_body_type_2_messages_item_type_1.py +0 -88
  22. langwatch/generated/langwatch_rest_api_client/models/post_api_scenario_events_body_type_2_messages_item_type_2.py +0 -120
  23. langwatch/generated/langwatch_rest_api_client/models/post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item.py +0 -87
  24. langwatch/generated/langwatch_rest_api_client/models/post_api_scenario_events_body_type_2_messages_item_type_3.py +0 -88
  25. langwatch/generated/langwatch_rest_api_client/models/post_api_scenario_events_body_type_2_messages_item_type_4.py +0 -85
  26. langwatch/prompts/formatter.py +0 -31
  27. {langwatch-0.2.18.dist-info → langwatch-0.3.0.dist-info}/WHEEL +0 -0
@@ -1,88 +0,0 @@
1
- from collections.abc import Mapping
2
- from typing import Any, Literal, TypeVar, Union, cast
3
-
4
- from attrs import define as _attrs_define
5
- from attrs import field as _attrs_field
6
-
7
- from ..types import UNSET, Unset
8
-
9
- T = TypeVar("T", bound="PostApiScenarioEventsBodyType2MessagesItemType0")
10
-
11
-
12
- @_attrs_define
13
- class PostApiScenarioEventsBodyType2MessagesItemType0:
14
- """
15
- Attributes:
16
- id (str):
17
- role (Literal['developer']):
18
- content (str):
19
- name (Union[Unset, str]):
20
- """
21
-
22
- id: str
23
- role: Literal["developer"]
24
- content: str
25
- name: Union[Unset, str] = UNSET
26
- additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
27
-
28
- def to_dict(self) -> dict[str, Any]:
29
- id = self.id
30
-
31
- role = self.role
32
-
33
- content = self.content
34
-
35
- name = self.name
36
-
37
- field_dict: dict[str, Any] = {}
38
- field_dict.update(self.additional_properties)
39
- field_dict.update(
40
- {
41
- "id": id,
42
- "role": role,
43
- "content": content,
44
- }
45
- )
46
- if name is not UNSET:
47
- field_dict["name"] = name
48
-
49
- return field_dict
50
-
51
- @classmethod
52
- def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
53
- d = dict(src_dict)
54
- id = d.pop("id")
55
-
56
- role = cast(Literal["developer"], d.pop("role"))
57
- if role != "developer":
58
- raise ValueError(f"role must match const 'developer', got '{role}'")
59
-
60
- content = d.pop("content")
61
-
62
- name = d.pop("name", UNSET)
63
-
64
- post_api_scenario_events_body_type_2_messages_item_type_0 = cls(
65
- id=id,
66
- role=role,
67
- content=content,
68
- name=name,
69
- )
70
-
71
- post_api_scenario_events_body_type_2_messages_item_type_0.additional_properties = d
72
- return post_api_scenario_events_body_type_2_messages_item_type_0
73
-
74
- @property
75
- def additional_keys(self) -> list[str]:
76
- return list(self.additional_properties.keys())
77
-
78
- def __getitem__(self, key: str) -> Any:
79
- return self.additional_properties[key]
80
-
81
- def __setitem__(self, key: str, value: Any) -> None:
82
- self.additional_properties[key] = value
83
-
84
- def __delitem__(self, key: str) -> None:
85
- del self.additional_properties[key]
86
-
87
- def __contains__(self, key: str) -> bool:
88
- return key in self.additional_properties
@@ -1,88 +0,0 @@
1
- from collections.abc import Mapping
2
- from typing import Any, Literal, TypeVar, Union, cast
3
-
4
- from attrs import define as _attrs_define
5
- from attrs import field as _attrs_field
6
-
7
- from ..types import UNSET, Unset
8
-
9
- T = TypeVar("T", bound="PostApiScenarioEventsBodyType2MessagesItemType1")
10
-
11
-
12
- @_attrs_define
13
- class PostApiScenarioEventsBodyType2MessagesItemType1:
14
- """
15
- Attributes:
16
- id (str):
17
- role (Literal['system']):
18
- content (str):
19
- name (Union[Unset, str]):
20
- """
21
-
22
- id: str
23
- role: Literal["system"]
24
- content: str
25
- name: Union[Unset, str] = UNSET
26
- additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
27
-
28
- def to_dict(self) -> dict[str, Any]:
29
- id = self.id
30
-
31
- role = self.role
32
-
33
- content = self.content
34
-
35
- name = self.name
36
-
37
- field_dict: dict[str, Any] = {}
38
- field_dict.update(self.additional_properties)
39
- field_dict.update(
40
- {
41
- "id": id,
42
- "role": role,
43
- "content": content,
44
- }
45
- )
46
- if name is not UNSET:
47
- field_dict["name"] = name
48
-
49
- return field_dict
50
-
51
- @classmethod
52
- def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
53
- d = dict(src_dict)
54
- id = d.pop("id")
55
-
56
- role = cast(Literal["system"], d.pop("role"))
57
- if role != "system":
58
- raise ValueError(f"role must match const 'system', got '{role}'")
59
-
60
- content = d.pop("content")
61
-
62
- name = d.pop("name", UNSET)
63
-
64
- post_api_scenario_events_body_type_2_messages_item_type_1 = cls(
65
- id=id,
66
- role=role,
67
- content=content,
68
- name=name,
69
- )
70
-
71
- post_api_scenario_events_body_type_2_messages_item_type_1.additional_properties = d
72
- return post_api_scenario_events_body_type_2_messages_item_type_1
73
-
74
- @property
75
- def additional_keys(self) -> list[str]:
76
- return list(self.additional_properties.keys())
77
-
78
- def __getitem__(self, key: str) -> Any:
79
- return self.additional_properties[key]
80
-
81
- def __setitem__(self, key: str, value: Any) -> None:
82
- self.additional_properties[key] = value
83
-
84
- def __delitem__(self, key: str) -> None:
85
- del self.additional_properties[key]
86
-
87
- def __contains__(self, key: str) -> bool:
88
- return key in self.additional_properties
@@ -1,120 +0,0 @@
1
- from collections.abc import Mapping
2
- from typing import TYPE_CHECKING, Any, Literal, TypeVar, Union, cast
3
-
4
- from attrs import define as _attrs_define
5
- from attrs import field as _attrs_field
6
-
7
- from ..types import UNSET, Unset
8
-
9
- if TYPE_CHECKING:
10
- from ..models.post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item import (
11
- PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItem,
12
- )
13
-
14
-
15
- T = TypeVar("T", bound="PostApiScenarioEventsBodyType2MessagesItemType2")
16
-
17
-
18
- @_attrs_define
19
- class PostApiScenarioEventsBodyType2MessagesItemType2:
20
- """
21
- Attributes:
22
- id (str):
23
- role (Literal['assistant']):
24
- content (Union[Unset, str]):
25
- name (Union[Unset, str]):
26
- tool_calls (Union[Unset, list['PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItem']]):
27
- """
28
-
29
- id: str
30
- role: Literal["assistant"]
31
- content: Union[Unset, str] = UNSET
32
- name: Union[Unset, str] = UNSET
33
- tool_calls: Union[Unset, list["PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItem"]] = UNSET
34
- additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
35
-
36
- def to_dict(self) -> dict[str, Any]:
37
- id = self.id
38
-
39
- role = self.role
40
-
41
- content = self.content
42
-
43
- name = self.name
44
-
45
- tool_calls: Union[Unset, list[dict[str, Any]]] = UNSET
46
- if not isinstance(self.tool_calls, Unset):
47
- tool_calls = []
48
- for tool_calls_item_data in self.tool_calls:
49
- tool_calls_item = tool_calls_item_data.to_dict()
50
- tool_calls.append(tool_calls_item)
51
-
52
- field_dict: dict[str, Any] = {}
53
- field_dict.update(self.additional_properties)
54
- field_dict.update(
55
- {
56
- "id": id,
57
- "role": role,
58
- }
59
- )
60
- if content is not UNSET:
61
- field_dict["content"] = content
62
- if name is not UNSET:
63
- field_dict["name"] = name
64
- if tool_calls is not UNSET:
65
- field_dict["toolCalls"] = tool_calls
66
-
67
- return field_dict
68
-
69
- @classmethod
70
- def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
71
- from ..models.post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item import (
72
- PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItem,
73
- )
74
-
75
- d = dict(src_dict)
76
- id = d.pop("id")
77
-
78
- role = cast(Literal["assistant"], d.pop("role"))
79
- if role != "assistant":
80
- raise ValueError(f"role must match const 'assistant', got '{role}'")
81
-
82
- content = d.pop("content", UNSET)
83
-
84
- name = d.pop("name", UNSET)
85
-
86
- tool_calls = []
87
- _tool_calls = d.pop("toolCalls", UNSET)
88
- for tool_calls_item_data in _tool_calls or []:
89
- tool_calls_item = PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItem.from_dict(
90
- tool_calls_item_data
91
- )
92
-
93
- tool_calls.append(tool_calls_item)
94
-
95
- post_api_scenario_events_body_type_2_messages_item_type_2 = cls(
96
- id=id,
97
- role=role,
98
- content=content,
99
- name=name,
100
- tool_calls=tool_calls,
101
- )
102
-
103
- post_api_scenario_events_body_type_2_messages_item_type_2.additional_properties = d
104
- return post_api_scenario_events_body_type_2_messages_item_type_2
105
-
106
- @property
107
- def additional_keys(self) -> list[str]:
108
- return list(self.additional_properties.keys())
109
-
110
- def __getitem__(self, key: str) -> Any:
111
- return self.additional_properties[key]
112
-
113
- def __setitem__(self, key: str, value: Any) -> None:
114
- self.additional_properties[key] = value
115
-
116
- def __delitem__(self, key: str) -> None:
117
- del self.additional_properties[key]
118
-
119
- def __contains__(self, key: str) -> bool:
120
- return key in self.additional_properties
@@ -1,87 +0,0 @@
1
- from collections.abc import Mapping
2
- from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast
3
-
4
- from attrs import define as _attrs_define
5
- from attrs import field as _attrs_field
6
-
7
- if TYPE_CHECKING:
8
- from ..models.post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item_function import (
9
- PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItemFunction,
10
- )
11
-
12
-
13
- T = TypeVar("T", bound="PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItem")
14
-
15
-
16
- @_attrs_define
17
- class PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItem:
18
- """
19
- Attributes:
20
- id (str):
21
- type_ (Literal['function']):
22
- function (PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItemFunction):
23
- """
24
-
25
- id: str
26
- type_: Literal["function"]
27
- function: "PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItemFunction"
28
- additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
29
-
30
- def to_dict(self) -> dict[str, Any]:
31
- id = self.id
32
-
33
- type_ = self.type_
34
-
35
- function = self.function.to_dict()
36
-
37
- field_dict: dict[str, Any] = {}
38
- field_dict.update(self.additional_properties)
39
- field_dict.update(
40
- {
41
- "id": id,
42
- "type": type_,
43
- "function": function,
44
- }
45
- )
46
-
47
- return field_dict
48
-
49
- @classmethod
50
- def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
51
- from ..models.post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item_function import (
52
- PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItemFunction,
53
- )
54
-
55
- d = dict(src_dict)
56
- id = d.pop("id")
57
-
58
- type_ = cast(Literal["function"], d.pop("type"))
59
- if type_ != "function":
60
- raise ValueError(f"type must match const 'function', got '{type_}'")
61
-
62
- function = PostApiScenarioEventsBodyType2MessagesItemType2ToolCallsItemFunction.from_dict(d.pop("function"))
63
-
64
- post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item = cls(
65
- id=id,
66
- type_=type_,
67
- function=function,
68
- )
69
-
70
- post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item.additional_properties = d
71
- return post_api_scenario_events_body_type_2_messages_item_type_2_tool_calls_item
72
-
73
- @property
74
- def additional_keys(self) -> list[str]:
75
- return list(self.additional_properties.keys())
76
-
77
- def __getitem__(self, key: str) -> Any:
78
- return self.additional_properties[key]
79
-
80
- def __setitem__(self, key: str, value: Any) -> None:
81
- self.additional_properties[key] = value
82
-
83
- def __delitem__(self, key: str) -> None:
84
- del self.additional_properties[key]
85
-
86
- def __contains__(self, key: str) -> bool:
87
- return key in self.additional_properties
@@ -1,88 +0,0 @@
1
- from collections.abc import Mapping
2
- from typing import Any, Literal, TypeVar, Union, cast
3
-
4
- from attrs import define as _attrs_define
5
- from attrs import field as _attrs_field
6
-
7
- from ..types import UNSET, Unset
8
-
9
- T = TypeVar("T", bound="PostApiScenarioEventsBodyType2MessagesItemType3")
10
-
11
-
12
- @_attrs_define
13
- class PostApiScenarioEventsBodyType2MessagesItemType3:
14
- """
15
- Attributes:
16
- id (str):
17
- role (Literal['user']):
18
- content (str):
19
- name (Union[Unset, str]):
20
- """
21
-
22
- id: str
23
- role: Literal["user"]
24
- content: str
25
- name: Union[Unset, str] = UNSET
26
- additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
27
-
28
- def to_dict(self) -> dict[str, Any]:
29
- id = self.id
30
-
31
- role = self.role
32
-
33
- content = self.content
34
-
35
- name = self.name
36
-
37
- field_dict: dict[str, Any] = {}
38
- field_dict.update(self.additional_properties)
39
- field_dict.update(
40
- {
41
- "id": id,
42
- "role": role,
43
- "content": content,
44
- }
45
- )
46
- if name is not UNSET:
47
- field_dict["name"] = name
48
-
49
- return field_dict
50
-
51
- @classmethod
52
- def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
53
- d = dict(src_dict)
54
- id = d.pop("id")
55
-
56
- role = cast(Literal["user"], d.pop("role"))
57
- if role != "user":
58
- raise ValueError(f"role must match const 'user', got '{role}'")
59
-
60
- content = d.pop("content")
61
-
62
- name = d.pop("name", UNSET)
63
-
64
- post_api_scenario_events_body_type_2_messages_item_type_3 = cls(
65
- id=id,
66
- role=role,
67
- content=content,
68
- name=name,
69
- )
70
-
71
- post_api_scenario_events_body_type_2_messages_item_type_3.additional_properties = d
72
- return post_api_scenario_events_body_type_2_messages_item_type_3
73
-
74
- @property
75
- def additional_keys(self) -> list[str]:
76
- return list(self.additional_properties.keys())
77
-
78
- def __getitem__(self, key: str) -> Any:
79
- return self.additional_properties[key]
80
-
81
- def __setitem__(self, key: str, value: Any) -> None:
82
- self.additional_properties[key] = value
83
-
84
- def __delitem__(self, key: str) -> None:
85
- del self.additional_properties[key]
86
-
87
- def __contains__(self, key: str) -> bool:
88
- return key in self.additional_properties
@@ -1,85 +0,0 @@
1
- from collections.abc import Mapping
2
- from typing import Any, Literal, TypeVar, cast
3
-
4
- from attrs import define as _attrs_define
5
- from attrs import field as _attrs_field
6
-
7
- T = TypeVar("T", bound="PostApiScenarioEventsBodyType2MessagesItemType4")
8
-
9
-
10
- @_attrs_define
11
- class PostApiScenarioEventsBodyType2MessagesItemType4:
12
- """
13
- Attributes:
14
- id (str):
15
- content (str):
16
- role (Literal['tool']):
17
- tool_call_id (str):
18
- """
19
-
20
- id: str
21
- content: str
22
- role: Literal["tool"]
23
- tool_call_id: str
24
- additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
25
-
26
- def to_dict(self) -> dict[str, Any]:
27
- id = self.id
28
-
29
- content = self.content
30
-
31
- role = self.role
32
-
33
- tool_call_id = self.tool_call_id
34
-
35
- field_dict: dict[str, Any] = {}
36
- field_dict.update(self.additional_properties)
37
- field_dict.update(
38
- {
39
- "id": id,
40
- "content": content,
41
- "role": role,
42
- "toolCallId": tool_call_id,
43
- }
44
- )
45
-
46
- return field_dict
47
-
48
- @classmethod
49
- def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
50
- d = dict(src_dict)
51
- id = d.pop("id")
52
-
53
- content = d.pop("content")
54
-
55
- role = cast(Literal["tool"], d.pop("role"))
56
- if role != "tool":
57
- raise ValueError(f"role must match const 'tool', got '{role}'")
58
-
59
- tool_call_id = d.pop("toolCallId")
60
-
61
- post_api_scenario_events_body_type_2_messages_item_type_4 = cls(
62
- id=id,
63
- content=content,
64
- role=role,
65
- tool_call_id=tool_call_id,
66
- )
67
-
68
- post_api_scenario_events_body_type_2_messages_item_type_4.additional_properties = d
69
- return post_api_scenario_events_body_type_2_messages_item_type_4
70
-
71
- @property
72
- def additional_keys(self) -> list[str]:
73
- return list(self.additional_properties.keys())
74
-
75
- def __getitem__(self, key: str) -> Any:
76
- return self.additional_properties[key]
77
-
78
- def __setitem__(self, key: str, value: Any) -> None:
79
- self.additional_properties[key] = value
80
-
81
- def __delitem__(self, key: str) -> None:
82
- del self.additional_properties[key]
83
-
84
- def __contains__(self, key: str) -> bool:
85
- return key in self.additional_properties
@@ -1,31 +0,0 @@
1
- import re
2
- from typing import Dict, Any, List
3
-
4
-
5
- class MissingPromptVariableError(Exception):
6
- def __init__(self, missing_vars: List[str]):
7
- super().__init__(f"Missing variables for prompt: {', '.join(missing_vars)}")
8
- self.missing_vars = missing_vars
9
-
10
-
11
- class PromptFormatter:
12
- """Formats prompt templates with provided variables using {{ var }} syntax."""
13
-
14
- def format(self, template: str, variables: Dict[str, Any]) -> str:
15
- # First check for any missing variables
16
- missing_vars = []
17
- for match in re.finditer(r"{{\s*(\w+)\s*}}", template):
18
- var_name = match.group(1)
19
- if var_name not in variables:
20
- missing_vars.append(var_name)
21
-
22
- if missing_vars:
23
- raise MissingPromptVariableError(missing_vars)
24
-
25
- # Replace all variables with their values
26
- result = template
27
- for var, value in variables.items():
28
- # Replace {{ var }} with the value
29
- result = re.sub(r"{{\s*" + re.escape(var) + r"\s*}}", str(value), result)
30
-
31
- return result