vellum-ai 0.12.7__py3-none-any.whl → 0.12.8__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.
- vellum/client/core/client_wrapper.py +1 -1
- vellum/evaluations/resources.py +1 -1
- vellum/prompts/__init__.py +0 -0
- vellum/prompts/blocks/__init__.py +0 -0
- vellum/prompts/blocks/compilation.py +190 -0
- vellum/prompts/blocks/exceptions.py +2 -0
- vellum/prompts/blocks/tests/__init__.py +0 -0
- vellum/prompts/blocks/tests/test_compilation.py +110 -0
- vellum/prompts/blocks/types.py +36 -0
- vellum/utils/__init__.py +0 -0
- vellum/utils/templating/__init__.py +0 -0
- vellum/utils/templating/constants.py +28 -0
- vellum/{workflows/nodes/core/templating_node → utils/templating}/render.py +1 -1
- vellum/workflows/nodes/core/templating_node/node.py +5 -31
- vellum/workflows/nodes/experimental/README.md +6 -0
- vellum/workflows/nodes/experimental/__init__.py +0 -0
- vellum/workflows/nodes/experimental/openai_chat_completion_node/__init__.py +5 -0
- vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py +260 -0
- vellum/workflows/sandbox.py +3 -0
- {vellum_ai-0.12.7.dist-info → vellum_ai-0.12.8.dist-info}/METADATA +2 -1
- {vellum_ai-0.12.7.dist-info → vellum_ai-0.12.8.dist-info}/RECORD +27 -13
- /vellum/{workflows/nodes/core/templating_node → utils/templating}/custom_filters.py +0 -0
- /vellum/{workflows/nodes/core/templating_node → utils/templating}/exceptions.py +0 -0
- /vellum/{evaluations/utils → utils}/typing.py +0 -0
- {vellum_ai-0.12.7.dist-info → vellum_ai-0.12.8.dist-info}/LICENSE +0 -0
- {vellum_ai-0.12.7.dist-info → vellum_ai-0.12.8.dist-info}/WHEEL +0 -0
- {vellum_ai-0.12.7.dist-info → vellum_ai-0.12.8.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@ class BaseClientWrapper:
|
|
18
18
|
headers: typing.Dict[str, str] = {
|
19
19
|
"X-Fern-Language": "Python",
|
20
20
|
"X-Fern-SDK-Name": "vellum-ai",
|
21
|
-
"X-Fern-SDK-Version": "0.12.
|
21
|
+
"X-Fern-SDK-Version": "0.12.8",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
vellum/evaluations/resources.py
CHANGED
@@ -12,7 +12,6 @@ from vellum.evaluations.constants import DEFAULT_MAX_POLLING_DURATION_MS, DEFAUL
|
|
12
12
|
from vellum.evaluations.exceptions import TestSuiteRunResultsException
|
13
13
|
from vellum.evaluations.utils.env import get_api_key
|
14
14
|
from vellum.evaluations.utils.paginator import PaginatedResults, get_all_results
|
15
|
-
from vellum.evaluations.utils.typing import cast_not_optional
|
16
15
|
from vellum.evaluations.utils.uuid import is_valid_uuid
|
17
16
|
from vellum.types import (
|
18
17
|
ExternalTestCaseExecutionRequest,
|
@@ -24,6 +23,7 @@ from vellum.types import (
|
|
24
23
|
TestSuiteRunMetricOutput,
|
25
24
|
TestSuiteRunState,
|
26
25
|
)
|
26
|
+
from vellum.utils.typing import cast_not_optional
|
27
27
|
|
28
28
|
logger = logging.getLogger(__name__)
|
29
29
|
|
File without changes
|
File without changes
|
@@ -0,0 +1,190 @@
|
|
1
|
+
import json
|
2
|
+
from typing import Optional, cast
|
3
|
+
|
4
|
+
from vellum import (
|
5
|
+
ChatMessage,
|
6
|
+
JsonVellumValue,
|
7
|
+
PromptBlock,
|
8
|
+
PromptRequestInput,
|
9
|
+
RichTextPromptBlock,
|
10
|
+
StringVellumValue,
|
11
|
+
VellumVariable,
|
12
|
+
)
|
13
|
+
from vellum.prompts.blocks.exceptions import PromptCompilationError
|
14
|
+
from vellum.prompts.blocks.types import CompiledChatMessagePromptBlock, CompiledPromptBlock, CompiledValuePromptBlock
|
15
|
+
from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS
|
16
|
+
from vellum.utils.templating.render import render_sandboxed_jinja_template
|
17
|
+
from vellum.utils.typing import cast_not_optional
|
18
|
+
|
19
|
+
|
20
|
+
def compile_prompt_blocks(
|
21
|
+
blocks: list[PromptBlock],
|
22
|
+
inputs: list[PromptRequestInput],
|
23
|
+
input_variables: list[VellumVariable],
|
24
|
+
) -> list[CompiledPromptBlock]:
|
25
|
+
"""Compiles a list of Prompt Blocks, performing all variable substitutions and Jinja templating needed."""
|
26
|
+
|
27
|
+
sanitized_inputs = _sanitize_inputs(inputs)
|
28
|
+
|
29
|
+
compiled_blocks: list[CompiledPromptBlock] = []
|
30
|
+
for block in blocks:
|
31
|
+
if block.state == "DISABLED":
|
32
|
+
continue
|
33
|
+
|
34
|
+
if block.block_type == "CHAT_MESSAGE":
|
35
|
+
chat_role = cast_not_optional(block.chat_role)
|
36
|
+
inner_blocks = cast_not_optional(block.blocks)
|
37
|
+
unterminated = block.chat_message_unterminated or False
|
38
|
+
|
39
|
+
inner_prompt_blocks = compile_prompt_blocks(
|
40
|
+
inner_blocks,
|
41
|
+
sanitized_inputs,
|
42
|
+
input_variables,
|
43
|
+
)
|
44
|
+
if not inner_prompt_blocks:
|
45
|
+
continue
|
46
|
+
|
47
|
+
compiled_blocks.append(
|
48
|
+
CompiledChatMessagePromptBlock(
|
49
|
+
role=chat_role,
|
50
|
+
unterminated=unterminated,
|
51
|
+
source=block.chat_source,
|
52
|
+
blocks=[inner for inner in inner_prompt_blocks if inner.block_type == "VALUE"],
|
53
|
+
cache_config=block.cache_config,
|
54
|
+
)
|
55
|
+
)
|
56
|
+
|
57
|
+
elif block.block_type == "JINJA":
|
58
|
+
if block.template is None:
|
59
|
+
continue
|
60
|
+
|
61
|
+
rendered_template = render_sandboxed_jinja_template(
|
62
|
+
template=block.template,
|
63
|
+
input_values={input_.key: input_.value for input_ in sanitized_inputs},
|
64
|
+
jinja_custom_filters=DEFAULT_JINJA_CUSTOM_FILTERS,
|
65
|
+
jinja_globals=DEFAULT_JINJA_CUSTOM_FILTERS,
|
66
|
+
)
|
67
|
+
jinja_content = StringVellumValue(value=rendered_template)
|
68
|
+
|
69
|
+
compiled_blocks.append(
|
70
|
+
CompiledValuePromptBlock(
|
71
|
+
content=jinja_content,
|
72
|
+
cache_config=block.cache_config,
|
73
|
+
)
|
74
|
+
)
|
75
|
+
|
76
|
+
elif block.block_type == "VARIABLE":
|
77
|
+
compiled_input: Optional[PromptRequestInput] = next(
|
78
|
+
(input_ for input_ in sanitized_inputs if input_.key == str(block.input_variable)), None
|
79
|
+
)
|
80
|
+
if compiled_input is None:
|
81
|
+
raise PromptCompilationError(f"Input variable '{block.input_variable}' not found")
|
82
|
+
|
83
|
+
if compiled_input.type == "CHAT_HISTORY":
|
84
|
+
history = cast(list[ChatMessage], compiled_input.value)
|
85
|
+
chat_message_blocks = _compile_chat_messages_as_prompt_blocks(history)
|
86
|
+
compiled_blocks.extend(chat_message_blocks)
|
87
|
+
continue
|
88
|
+
|
89
|
+
if compiled_input.type == "STRING":
|
90
|
+
compiled_blocks.append(
|
91
|
+
CompiledValuePromptBlock(
|
92
|
+
content=StringVellumValue(value=compiled_input.value),
|
93
|
+
cache_config=block.cache_config,
|
94
|
+
)
|
95
|
+
)
|
96
|
+
elif compiled_input == "JSON":
|
97
|
+
compiled_blocks.append(
|
98
|
+
CompiledValuePromptBlock(
|
99
|
+
content=JsonVellumValue(value=compiled_input.value),
|
100
|
+
cache_config=block.cache_config,
|
101
|
+
)
|
102
|
+
)
|
103
|
+
elif compiled_input.type == "CHAT_HISTORY":
|
104
|
+
chat_message_blocks = _compile_chat_messages_as_prompt_blocks(compiled_input.value)
|
105
|
+
compiled_blocks.extend(chat_message_blocks)
|
106
|
+
else:
|
107
|
+
raise ValueError(f"Invalid input type for variable block: {compiled_input.type}")
|
108
|
+
|
109
|
+
elif block.block_type == "RICH_TEXT":
|
110
|
+
value_block = _compile_rich_text_block_as_value_block(block=block, inputs=sanitized_inputs)
|
111
|
+
compiled_blocks.append(value_block)
|
112
|
+
|
113
|
+
elif block.block_type == "FUNCTION_DEFINITION":
|
114
|
+
raise ValueError("Function definitions shouldn't go through compilation process")
|
115
|
+
else:
|
116
|
+
raise ValueError(f"Unknown block_type: {block.block_type}")
|
117
|
+
|
118
|
+
return compiled_blocks
|
119
|
+
|
120
|
+
|
121
|
+
def _compile_chat_messages_as_prompt_blocks(chat_messages: list[ChatMessage]) -> list[CompiledChatMessagePromptBlock]:
|
122
|
+
blocks: list[CompiledChatMessagePromptBlock] = []
|
123
|
+
for chat_message in chat_messages:
|
124
|
+
if chat_message.content is None:
|
125
|
+
continue
|
126
|
+
|
127
|
+
chat_message_blocks = (
|
128
|
+
[
|
129
|
+
CompiledValuePromptBlock(
|
130
|
+
content=item,
|
131
|
+
)
|
132
|
+
for item in chat_message.content.value
|
133
|
+
]
|
134
|
+
if chat_message.content.type == "ARRAY"
|
135
|
+
else [
|
136
|
+
CompiledValuePromptBlock(
|
137
|
+
content=chat_message.content,
|
138
|
+
)
|
139
|
+
]
|
140
|
+
)
|
141
|
+
|
142
|
+
blocks.append(
|
143
|
+
CompiledChatMessagePromptBlock(
|
144
|
+
role=chat_message.role,
|
145
|
+
unterminated=False,
|
146
|
+
blocks=chat_message_blocks,
|
147
|
+
source=chat_message.source,
|
148
|
+
)
|
149
|
+
)
|
150
|
+
|
151
|
+
return blocks
|
152
|
+
|
153
|
+
|
154
|
+
def _compile_rich_text_block_as_value_block(
|
155
|
+
block: RichTextPromptBlock,
|
156
|
+
inputs: list[PromptRequestInput],
|
157
|
+
) -> CompiledValuePromptBlock:
|
158
|
+
value: str = ""
|
159
|
+
for child_block in block.blocks:
|
160
|
+
if child_block.block_type == "PLAIN_TEXT":
|
161
|
+
value += child_block.text
|
162
|
+
elif child_block.block_type == "VARIABLE":
|
163
|
+
variable = next((input_ for input_ in inputs if input_.key == str(child_block.input_variable)), None)
|
164
|
+
if variable is None:
|
165
|
+
raise PromptCompilationError(f"Input variable '{child_block.input_variable}' not found")
|
166
|
+
elif variable.type == "STRING":
|
167
|
+
value += str(variable.value)
|
168
|
+
elif variable.type == "JSON":
|
169
|
+
value += json.dumps(variable.value, indent=4)
|
170
|
+
else:
|
171
|
+
raise PromptCompilationError(
|
172
|
+
f"Input variable '{child_block.input_variable}' must be of type STRING or JSON"
|
173
|
+
)
|
174
|
+
else:
|
175
|
+
raise ValueError(f"Invalid child block_type for RICH_TEXT: {child_block.block_type}")
|
176
|
+
|
177
|
+
return CompiledValuePromptBlock(content=StringVellumValue(value=value), cache_config=block.cache_config)
|
178
|
+
|
179
|
+
|
180
|
+
def _sanitize_inputs(inputs: list[PromptRequestInput]) -> list[PromptRequestInput]:
|
181
|
+
sanitized_inputs: list[PromptRequestInput] = []
|
182
|
+
for input_ in inputs:
|
183
|
+
if input_.type == "CHAT_HISTORY" and input_.value is None:
|
184
|
+
sanitized_inputs.append(input_.model_copy(update={"value": cast(list[ChatMessage], [])}))
|
185
|
+
elif input_.type == "STRING" and input_.value is None:
|
186
|
+
sanitized_inputs.append(input_.model_copy(update={"value": ""}))
|
187
|
+
else:
|
188
|
+
sanitized_inputs.append(input_)
|
189
|
+
|
190
|
+
return sanitized_inputs
|
File without changes
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from vellum import (
|
4
|
+
ChatMessagePromptBlock,
|
5
|
+
JinjaPromptBlock,
|
6
|
+
PlainTextPromptBlock,
|
7
|
+
PromptRequestStringInput,
|
8
|
+
RichTextPromptBlock,
|
9
|
+
StringVellumValue,
|
10
|
+
VariablePromptBlock,
|
11
|
+
VellumVariable,
|
12
|
+
)
|
13
|
+
from vellum.prompts.blocks.compilation import compile_prompt_blocks
|
14
|
+
from vellum.prompts.blocks.types import CompiledChatMessagePromptBlock, CompiledValuePromptBlock
|
15
|
+
|
16
|
+
|
17
|
+
@pytest.mark.parametrize(
|
18
|
+
["blocks", "inputs", "input_variables", "expected"],
|
19
|
+
[
|
20
|
+
# Empty
|
21
|
+
([], [], [], []),
|
22
|
+
# Jinja
|
23
|
+
(
|
24
|
+
[JinjaPromptBlock(template="Hello, world!")],
|
25
|
+
[],
|
26
|
+
[],
|
27
|
+
[
|
28
|
+
CompiledValuePromptBlock(content=StringVellumValue(value="Hello, world!")),
|
29
|
+
],
|
30
|
+
),
|
31
|
+
(
|
32
|
+
[JinjaPromptBlock(template="Repeat back to me {{ echo }}")],
|
33
|
+
[PromptRequestStringInput(key="echo", value="Hello, world!")],
|
34
|
+
[VellumVariable(id="1", type="STRING", key="echo")],
|
35
|
+
[
|
36
|
+
CompiledValuePromptBlock(content=StringVellumValue(value="Repeat back to me Hello, world!")),
|
37
|
+
],
|
38
|
+
),
|
39
|
+
# Rich Text
|
40
|
+
(
|
41
|
+
[
|
42
|
+
RichTextPromptBlock(
|
43
|
+
blocks=[
|
44
|
+
PlainTextPromptBlock(text="Hello, world!"),
|
45
|
+
]
|
46
|
+
)
|
47
|
+
],
|
48
|
+
[],
|
49
|
+
[],
|
50
|
+
[
|
51
|
+
CompiledValuePromptBlock(content=StringVellumValue(value="Hello, world!")),
|
52
|
+
],
|
53
|
+
),
|
54
|
+
(
|
55
|
+
[
|
56
|
+
RichTextPromptBlock(
|
57
|
+
blocks=[
|
58
|
+
PlainTextPromptBlock(text='Repeat back to me "'),
|
59
|
+
VariablePromptBlock(input_variable="echo"),
|
60
|
+
PlainTextPromptBlock(text='".'),
|
61
|
+
]
|
62
|
+
)
|
63
|
+
],
|
64
|
+
[PromptRequestStringInput(key="echo", value="Hello, world!")],
|
65
|
+
[VellumVariable(id="901ec2d6-430c-4341-b963-ca689006f5cc", type="STRING", key="echo")],
|
66
|
+
[
|
67
|
+
CompiledValuePromptBlock(content=StringVellumValue(value='Repeat back to me "Hello, world!".')),
|
68
|
+
],
|
69
|
+
),
|
70
|
+
# Chat Message
|
71
|
+
(
|
72
|
+
[
|
73
|
+
ChatMessagePromptBlock(
|
74
|
+
chat_role="USER",
|
75
|
+
blocks=[
|
76
|
+
RichTextPromptBlock(
|
77
|
+
blocks=[
|
78
|
+
PlainTextPromptBlock(text='Repeat back to me "'),
|
79
|
+
VariablePromptBlock(input_variable="echo"),
|
80
|
+
PlainTextPromptBlock(text='".'),
|
81
|
+
]
|
82
|
+
)
|
83
|
+
],
|
84
|
+
)
|
85
|
+
],
|
86
|
+
[PromptRequestStringInput(key="echo", value="Hello, world!")],
|
87
|
+
[VellumVariable(id="901ec2d6-430c-4341-b963-ca689006f5cc", type="STRING", key="echo")],
|
88
|
+
[
|
89
|
+
CompiledChatMessagePromptBlock(
|
90
|
+
role="USER",
|
91
|
+
blocks=[
|
92
|
+
CompiledValuePromptBlock(content=StringVellumValue(value='Repeat back to me "Hello, world!".'))
|
93
|
+
],
|
94
|
+
),
|
95
|
+
],
|
96
|
+
),
|
97
|
+
],
|
98
|
+
ids=[
|
99
|
+
"empty",
|
100
|
+
"jinja-no-variables",
|
101
|
+
"jinja-with-variables",
|
102
|
+
"rich-text-no-variables",
|
103
|
+
"rich-text-with-variables",
|
104
|
+
"chat-message",
|
105
|
+
],
|
106
|
+
)
|
107
|
+
def test_compile_prompt_blocks__happy(blocks, inputs, input_variables, expected):
|
108
|
+
actual = compile_prompt_blocks(blocks=blocks, inputs=inputs, input_variables=input_variables)
|
109
|
+
|
110
|
+
assert actual == expected
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Annotated, Literal, Optional, Union
|
4
|
+
|
5
|
+
from vellum import ArrayVellumValue, ChatMessageRole, EphemeralPromptCacheConfig, VellumValue
|
6
|
+
from vellum.client.core import UniversalBaseModel
|
7
|
+
|
8
|
+
|
9
|
+
class BaseCompiledPromptBlock(UniversalBaseModel):
|
10
|
+
cache_config: Optional[EphemeralPromptCacheConfig] = None
|
11
|
+
|
12
|
+
|
13
|
+
class CompiledValuePromptBlock(BaseCompiledPromptBlock):
|
14
|
+
block_type: Literal["VALUE"] = "VALUE"
|
15
|
+
content: VellumValue
|
16
|
+
|
17
|
+
|
18
|
+
class CompiledChatMessagePromptBlock(BaseCompiledPromptBlock):
|
19
|
+
block_type: Literal["CHAT_MESSAGE"] = "CHAT_MESSAGE"
|
20
|
+
role: ChatMessageRole = "ASSISTANT"
|
21
|
+
unterminated: bool = False
|
22
|
+
blocks: list[CompiledValuePromptBlock] = []
|
23
|
+
source: Optional[str] = None
|
24
|
+
|
25
|
+
|
26
|
+
CompiledPromptBlock = Annotated[
|
27
|
+
Union[
|
28
|
+
CompiledValuePromptBlock,
|
29
|
+
CompiledChatMessagePromptBlock,
|
30
|
+
],
|
31
|
+
"block_type",
|
32
|
+
]
|
33
|
+
|
34
|
+
ArrayVellumValue.model_rebuild()
|
35
|
+
|
36
|
+
CompiledValuePromptBlock.model_rebuild()
|
vellum/utils/__init__.py
ADDED
File without changes
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import datetime
|
2
|
+
import itertools
|
3
|
+
import json
|
4
|
+
import random
|
5
|
+
import re
|
6
|
+
from typing import Any, Callable, Dict, Union
|
7
|
+
|
8
|
+
import dateutil
|
9
|
+
import pydash
|
10
|
+
import pytz
|
11
|
+
import yaml
|
12
|
+
|
13
|
+
from vellum.utils.templating.custom_filters import is_valid_json_string
|
14
|
+
|
15
|
+
DEFAULT_JINJA_GLOBALS: Dict[str, Any] = {
|
16
|
+
"datetime": datetime,
|
17
|
+
"dateutil": dateutil,
|
18
|
+
"itertools": itertools,
|
19
|
+
"json": json,
|
20
|
+
"pydash": pydash,
|
21
|
+
"pytz": pytz,
|
22
|
+
"random": random,
|
23
|
+
"re": re,
|
24
|
+
"yaml": yaml,
|
25
|
+
}
|
26
|
+
DEFAULT_JINJA_CUSTOM_FILTERS: Dict[str, Callable[[Union[str, bytes]], bool]] = {
|
27
|
+
"is_valid_json_string": is_valid_json_string,
|
28
|
+
}
|
@@ -3,7 +3,7 @@ from typing import Any, Callable, Dict, Optional, Union
|
|
3
3
|
|
4
4
|
from jinja2.sandbox import SandboxedEnvironment
|
5
5
|
|
6
|
-
from vellum.
|
6
|
+
from vellum.utils.templating.exceptions import JinjaTemplateError
|
7
7
|
from vellum.workflows.state.encoder import DefaultStateEncoder
|
8
8
|
|
9
9
|
|
@@ -1,42 +1,16 @@
|
|
1
|
-
import datetime
|
2
|
-
import itertools
|
3
|
-
import json
|
4
|
-
import random
|
5
|
-
import re
|
6
1
|
from typing import Any, Callable, ClassVar, Dict, Generic, Mapping, Tuple, Type, TypeVar, Union, get_args
|
7
2
|
|
8
|
-
import
|
9
|
-
import
|
10
|
-
import
|
11
|
-
import yaml
|
12
|
-
|
3
|
+
from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS, DEFAULT_JINJA_GLOBALS
|
4
|
+
from vellum.utils.templating.exceptions import JinjaTemplateError
|
5
|
+
from vellum.utils.templating.render import render_sandboxed_jinja_template
|
13
6
|
from vellum.workflows.errors import WorkflowErrorCode
|
14
7
|
from vellum.workflows.exceptions import NodeException
|
15
8
|
from vellum.workflows.nodes.bases import BaseNode
|
16
9
|
from vellum.workflows.nodes.bases.base import BaseNodeMeta
|
17
|
-
from vellum.workflows.nodes.core.templating_node.custom_filters import is_valid_json_string
|
18
|
-
from vellum.workflows.nodes.core.templating_node.exceptions import JinjaTemplateError
|
19
|
-
from vellum.workflows.nodes.core.templating_node.render import render_sandboxed_jinja_template
|
20
10
|
from vellum.workflows.types.core import EntityInputsInterface
|
21
11
|
from vellum.workflows.types.generics import StateType
|
22
12
|
from vellum.workflows.types.utils import get_original_base
|
23
13
|
|
24
|
-
_DEFAULT_JINJA_GLOBALS: Dict[str, Any] = {
|
25
|
-
"datetime": datetime,
|
26
|
-
"dateutil": dateutil,
|
27
|
-
"itertools": itertools,
|
28
|
-
"json": json,
|
29
|
-
"pydash": pydash,
|
30
|
-
"pytz": pytz,
|
31
|
-
"random": random,
|
32
|
-
"re": re,
|
33
|
-
"yaml": yaml,
|
34
|
-
}
|
35
|
-
|
36
|
-
_DEFAULT_JINJA_CUSTOM_FILTERS: Dict[str, Callable[[Union[str, bytes]], bool]] = {
|
37
|
-
"is_valid_json_string": is_valid_json_string,
|
38
|
-
}
|
39
|
-
|
40
14
|
_OutputType = TypeVar("_OutputType")
|
41
15
|
|
42
16
|
|
@@ -78,8 +52,8 @@ class TemplatingNode(BaseNode[StateType], Generic[StateType, _OutputType], metac
|
|
78
52
|
# The inputs to render the template with.
|
79
53
|
inputs: ClassVar[EntityInputsInterface]
|
80
54
|
|
81
|
-
jinja_globals: Dict[str, Any] =
|
82
|
-
jinja_custom_filters: Mapping[str, Callable[[Union[str, bytes]], bool]] =
|
55
|
+
jinja_globals: Dict[str, Any] = DEFAULT_JINJA_GLOBALS
|
56
|
+
jinja_custom_filters: Mapping[str, Callable[[Union[str, bytes]], bool]] = DEFAULT_JINJA_CUSTOM_FILTERS
|
83
57
|
|
84
58
|
class Outputs(BaseNode.Outputs):
|
85
59
|
"""
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# 🧪 Experimental
|
2
|
+
|
3
|
+
This section is a proofing ground for new ideas and concepts. It's not meant to be used in production and is
|
4
|
+
subject to breaking changes at any time.
|
5
|
+
|
6
|
+
If a concept within is sufficiently interesting and validated, then it may be introduced as a first-class node.
|
File without changes
|
@@ -0,0 +1,260 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
import os
|
4
|
+
from uuid import uuid4
|
5
|
+
from typing import Any, Iterable, Iterator, List, Literal, Union, cast
|
6
|
+
|
7
|
+
from openai import OpenAI
|
8
|
+
from openai.types.chat import (
|
9
|
+
ChatCompletionAssistantMessageParam,
|
10
|
+
ChatCompletionContentPartImageParam,
|
11
|
+
ChatCompletionContentPartInputAudioParam,
|
12
|
+
ChatCompletionContentPartParam,
|
13
|
+
ChatCompletionContentPartRefusalParam,
|
14
|
+
ChatCompletionContentPartTextParam,
|
15
|
+
ChatCompletionMessageParam,
|
16
|
+
ChatCompletionSystemMessageParam,
|
17
|
+
ChatCompletionUserMessageParam,
|
18
|
+
)
|
19
|
+
from openai.types.chat.chat_completion_chunk import Choice
|
20
|
+
|
21
|
+
from vellum import (
|
22
|
+
AdHocExecutePromptEvent,
|
23
|
+
FulfilledAdHocExecutePromptEvent,
|
24
|
+
InitiatedAdHocExecutePromptEvent,
|
25
|
+
RejectedAdHocExecutePromptEvent,
|
26
|
+
StreamingAdHocExecutePromptEvent,
|
27
|
+
StringVellumValue,
|
28
|
+
VellumAudio,
|
29
|
+
VellumError,
|
30
|
+
)
|
31
|
+
from vellum.prompts.blocks.compilation import compile_prompt_blocks
|
32
|
+
from vellum.prompts.blocks.types import CompiledChatMessagePromptBlock
|
33
|
+
from vellum.workflows.errors import WorkflowErrorCode
|
34
|
+
from vellum.workflows.exceptions import NodeException
|
35
|
+
from vellum.workflows.nodes import InlinePromptNode
|
36
|
+
from vellum.workflows.types.generics import StateType
|
37
|
+
|
38
|
+
logger = logging.getLogger(__name__)
|
39
|
+
|
40
|
+
|
41
|
+
class OpenAIChatCompletionNode(InlinePromptNode[StateType]):
|
42
|
+
"""
|
43
|
+
Used to execute a Prompt using the OpenAI API.
|
44
|
+
"""
|
45
|
+
|
46
|
+
# Override
|
47
|
+
def _get_prompt_event_stream(self) -> Iterator[AdHocExecutePromptEvent]:
|
48
|
+
client = self._get_client()
|
49
|
+
|
50
|
+
execution_id = str(uuid4())
|
51
|
+
|
52
|
+
yield InitiatedAdHocExecutePromptEvent(
|
53
|
+
execution_id=execution_id,
|
54
|
+
)
|
55
|
+
|
56
|
+
try:
|
57
|
+
stream = client.chat.completions.create(
|
58
|
+
messages=self._get_messages(),
|
59
|
+
model=self.ml_model,
|
60
|
+
# TODO: Add support for additional parameters
|
61
|
+
stream=True,
|
62
|
+
)
|
63
|
+
except Exception as exc:
|
64
|
+
yield RejectedAdHocExecutePromptEvent(
|
65
|
+
error=VellumError(
|
66
|
+
code=WorkflowErrorCode.PROVIDER_ERROR,
|
67
|
+
message=exc.args[0],
|
68
|
+
),
|
69
|
+
execution_id=execution_id,
|
70
|
+
)
|
71
|
+
return
|
72
|
+
|
73
|
+
combined_delta_content = ""
|
74
|
+
for chunk in stream:
|
75
|
+
choices: List[Choice] = chunk.choices
|
76
|
+
if len(choices) != 1:
|
77
|
+
yield RejectedAdHocExecutePromptEvent(
|
78
|
+
error=VellumError(
|
79
|
+
code=WorkflowErrorCode.PROVIDER_ERROR,
|
80
|
+
message="Expected one choice per chunk, but found more than one.",
|
81
|
+
),
|
82
|
+
execution_id=execution_id,
|
83
|
+
)
|
84
|
+
return
|
85
|
+
|
86
|
+
choice = choices[0]
|
87
|
+
delta = choice.delta
|
88
|
+
|
89
|
+
if delta.tool_calls:
|
90
|
+
# TODO: Add support for tool calls
|
91
|
+
raise NotImplementedError("This node hasn't been extended to support tool calling yet.")
|
92
|
+
|
93
|
+
if delta.content:
|
94
|
+
combined_delta_content += delta.content
|
95
|
+
|
96
|
+
StreamingAdHocExecutePromptEvent(
|
97
|
+
output=StringVellumValue(value=delta.content),
|
98
|
+
# TODO: Add support for multiple outputs
|
99
|
+
output_index=1,
|
100
|
+
execution_id=execution_id,
|
101
|
+
)
|
102
|
+
|
103
|
+
yield FulfilledAdHocExecutePromptEvent(
|
104
|
+
# TODO: Add support for multiple outputs
|
105
|
+
outputs=[
|
106
|
+
StringVellumValue(value=combined_delta_content),
|
107
|
+
],
|
108
|
+
execution_id=execution_id,
|
109
|
+
)
|
110
|
+
|
111
|
+
def _get_client(self) -> OpenAI:
|
112
|
+
"""Used to retrieve an API client for interacting with the OpenAI API.
|
113
|
+
|
114
|
+
Note: This method can be overridden if you'd like to use your own API client that conforms to the same
|
115
|
+
interfaces as that of OpenAI.
|
116
|
+
"""
|
117
|
+
|
118
|
+
openai_api_key = os.environ.get("OPENAI_API_KEY")
|
119
|
+
|
120
|
+
if not openai_api_key:
|
121
|
+
raise NodeException(
|
122
|
+
code=WorkflowErrorCode.INTERNAL_ERROR,
|
123
|
+
message="Unable to determine an OpenAI API key.",
|
124
|
+
)
|
125
|
+
|
126
|
+
client = OpenAI(api_key=openai_api_key)
|
127
|
+
return client
|
128
|
+
|
129
|
+
def _get_messages(self) -> Iterable[ChatCompletionMessageParam]:
|
130
|
+
input_variables, input_values = self._compile_prompt_inputs()
|
131
|
+
|
132
|
+
compiled_blocks = compile_prompt_blocks(
|
133
|
+
blocks=self.blocks, inputs=input_values, input_variables=input_variables
|
134
|
+
)
|
135
|
+
|
136
|
+
chat_message_blocks: list[CompiledChatMessagePromptBlock] = [
|
137
|
+
block for block in compiled_blocks if block.block_type == "CHAT_MESSAGE"
|
138
|
+
]
|
139
|
+
messages = [self._create_message(block) for block in chat_message_blocks]
|
140
|
+
|
141
|
+
return messages
|
142
|
+
|
143
|
+
@classmethod
|
144
|
+
def _create_message(cls, chat_message_block: CompiledChatMessagePromptBlock) -> ChatCompletionMessageParam:
|
145
|
+
name = chat_message_block.source
|
146
|
+
content = cls._create_message_content(chat_message_block)
|
147
|
+
|
148
|
+
if chat_message_block.role == "SYSTEM":
|
149
|
+
relevant_system_content = [
|
150
|
+
cast(ChatCompletionContentPartTextParam, c) for c in content if c["type"] == "text"
|
151
|
+
]
|
152
|
+
system_message: ChatCompletionSystemMessageParam = {
|
153
|
+
"content": relevant_system_content,
|
154
|
+
"role": "system",
|
155
|
+
}
|
156
|
+
if name:
|
157
|
+
system_message["name"] = name
|
158
|
+
|
159
|
+
return system_message
|
160
|
+
elif chat_message_block.role == "USER":
|
161
|
+
user_message: ChatCompletionUserMessageParam = {
|
162
|
+
"content": content,
|
163
|
+
"role": "user",
|
164
|
+
}
|
165
|
+
if name:
|
166
|
+
user_message["name"] = name
|
167
|
+
|
168
|
+
return user_message
|
169
|
+
elif chat_message_block.role == "ASSISTANT":
|
170
|
+
relevant_assistant_content = [
|
171
|
+
cast(Union[ChatCompletionContentPartTextParam, ChatCompletionContentPartRefusalParam], c)
|
172
|
+
for c in content
|
173
|
+
if c["type"] in ["text", "refusal"]
|
174
|
+
]
|
175
|
+
assistant_message: ChatCompletionAssistantMessageParam = {
|
176
|
+
"content": relevant_assistant_content,
|
177
|
+
"role": "assistant",
|
178
|
+
}
|
179
|
+
if name:
|
180
|
+
assistant_message["name"] = name
|
181
|
+
|
182
|
+
return assistant_message
|
183
|
+
else:
|
184
|
+
logger.error(f"Unexpected role: {chat_message_block.role}")
|
185
|
+
raise NodeException(
|
186
|
+
code=WorkflowErrorCode.INTERNAL_ERROR, message="Unexpected role found when compiling prompt blocks"
|
187
|
+
)
|
188
|
+
|
189
|
+
@classmethod
|
190
|
+
def _create_message_content(
|
191
|
+
cls,
|
192
|
+
chat_message_block: CompiledChatMessagePromptBlock,
|
193
|
+
) -> List[ChatCompletionContentPartParam]:
|
194
|
+
content: List[ChatCompletionContentPartParam] = []
|
195
|
+
for block in chat_message_block.blocks:
|
196
|
+
if block.content.type == "STRING":
|
197
|
+
string_value = cast(str, block.content.value)
|
198
|
+
string_content_item: ChatCompletionContentPartTextParam = {"type": "text", "text": string_value}
|
199
|
+
content.append(string_content_item)
|
200
|
+
elif block.content.type == "JSON":
|
201
|
+
json_value = cast(Any, block.content.value)
|
202
|
+
json_content_item: ChatCompletionContentPartTextParam = {"type": "text", "text": json.dumps(json_value)}
|
203
|
+
content.append(json_content_item)
|
204
|
+
elif block.content.type == "IMAGE":
|
205
|
+
image_value = cast(VellumAudio, block.content.value)
|
206
|
+
image_content_item: ChatCompletionContentPartImageParam = {
|
207
|
+
"type": "image_url",
|
208
|
+
"image_url": {"url": image_value.src},
|
209
|
+
}
|
210
|
+
if image_value.metadata and image_value.metadata.get("detail"):
|
211
|
+
detail = image_value.metadata["detail"]
|
212
|
+
|
213
|
+
if detail not in ["auto", "low", "high"]:
|
214
|
+
raise NodeException(
|
215
|
+
code=WorkflowErrorCode.INTERNAL_ERROR,
|
216
|
+
message="Image detail must be one of 'auto', 'low', or 'high.",
|
217
|
+
)
|
218
|
+
|
219
|
+
image_content_item["image_url"]["detail"] = cast(Literal["auto", "low", "high"], detail)
|
220
|
+
|
221
|
+
content.append(image_content_item)
|
222
|
+
elif block.content.type == "AUDIO":
|
223
|
+
audio_value = cast(VellumAudio, block.content.value)
|
224
|
+
audio_value_src_parts = audio_value.src.split(",")
|
225
|
+
if len(audio_value_src_parts) != 2:
|
226
|
+
raise NodeException(
|
227
|
+
code=WorkflowErrorCode.INTERNAL_ERROR, message="Audio data is not properly encoded."
|
228
|
+
)
|
229
|
+
_, cleaned_audio_value = audio_value_src_parts
|
230
|
+
if not audio_value.metadata:
|
231
|
+
raise NodeException(
|
232
|
+
code=WorkflowErrorCode.INTERNAL_ERROR, message="Audio metadata is required for audio input."
|
233
|
+
)
|
234
|
+
audio_format = audio_value.metadata.get("format")
|
235
|
+
if not audio_format:
|
236
|
+
raise NodeException(
|
237
|
+
code=WorkflowErrorCode.INTERNAL_ERROR, message="Audio format is required for audio input."
|
238
|
+
)
|
239
|
+
if audio_format not in {"wav", "mp3"}:
|
240
|
+
raise NodeException(
|
241
|
+
code=WorkflowErrorCode.INTERNAL_ERROR,
|
242
|
+
message="Audio format must be one of 'wav' or 'mp3'.",
|
243
|
+
)
|
244
|
+
|
245
|
+
audio_content_item: ChatCompletionContentPartInputAudioParam = {
|
246
|
+
"type": "input_audio",
|
247
|
+
"input_audio": {
|
248
|
+
"data": cleaned_audio_value,
|
249
|
+
"format": cast(Literal["wav", "mp3"], audio_format),
|
250
|
+
},
|
251
|
+
}
|
252
|
+
|
253
|
+
content.append(audio_content_item)
|
254
|
+
else:
|
255
|
+
raise NodeException(
|
256
|
+
code=WorkflowErrorCode.INTERNAL_ERROR,
|
257
|
+
message=f"Failed to parse chat message block {block.content.type}",
|
258
|
+
)
|
259
|
+
|
260
|
+
return content
|
vellum/workflows/sandbox.py
CHANGED
@@ -49,3 +49,6 @@ class SandboxRunner(Generic[WorkflowType]):
|
|
49
49
|
self._logger.info(f"Just started Node: {event.node_definition.__name__}")
|
50
50
|
elif event.name == "node.execution.fulfilled":
|
51
51
|
self._logger.info(f"Just finished Node: {event.node_definition.__name__}")
|
52
|
+
elif event.name == "node.execution.rejected":
|
53
|
+
self._logger.debug(f"Error: {event.error}")
|
54
|
+
self._logger.error(f"Failed to run Node: {event.node_definition.__name__}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: vellum-ai
|
3
|
-
Version: 0.12.
|
3
|
+
Version: 0.12.8
|
4
4
|
Summary:
|
5
5
|
License: MIT
|
6
6
|
Requires-Python: >=3.9,<4.0
|
@@ -25,6 +25,7 @@ Requires-Dist: cdktf (>=0.20.5,<0.21.0)
|
|
25
25
|
Requires-Dist: click (==8.1.7)
|
26
26
|
Requires-Dist: docker (==7.1.0)
|
27
27
|
Requires-Dist: httpx (>=0.21.2)
|
28
|
+
Requires-Dist: openai (>=1.0.0)
|
28
29
|
Requires-Dist: orderly-set (>=5.2.2,<6.0.0)
|
29
30
|
Requires-Dist: publication (==0.0.3)
|
30
31
|
Requires-Dist: pydantic (>=1.9.2)
|
@@ -76,7 +76,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
|
|
76
76
|
vellum/client/__init__.py,sha256=o4m7iRZWEV8rP3GkdaztHAjNmjxjWERlarviFoHzuKI,110927
|
77
77
|
vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
|
78
78
|
vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
|
79
|
-
vellum/client/core/client_wrapper.py,sha256=
|
79
|
+
vellum/client/core/client_wrapper.py,sha256=oWk19_A_3mvqQM_W3wJgQnObX6YIE918NEp9olVAuEo,1868
|
80
80
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
81
81
|
vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
|
82
82
|
vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
|
@@ -649,17 +649,23 @@ vellum/errors/not_found_error.py,sha256=gC71YBdPyHR46l3RNTs0v9taVvAY0gWRFrcKpKzb
|
|
649
649
|
vellum/evaluations/__init__.py,sha256=hNsLoHSykqXDJP-MwFvu2lExImxo9KEyEJjt_fdAzpE,77
|
650
650
|
vellum/evaluations/constants.py,sha256=Vteml4_csZsMgo_q3-71E3JRCAoN6308TXLu5nfLhmU,116
|
651
651
|
vellum/evaluations/exceptions.py,sha256=6Xacoyv43fJvVf6Dt6Io5a-f9vF12Tx51jzsQRNSqhY,56
|
652
|
-
vellum/evaluations/resources.py,sha256=
|
652
|
+
vellum/evaluations/resources.py,sha256=33IDRHOjrRsC20JHs0BtRlaSYCY9Gg-AkA6qkPjBrWo,12676
|
653
653
|
vellum/evaluations/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
654
654
|
vellum/evaluations/utils/env.py,sha256=Xj_nxsoU5ox06EOTjRopR4lrigQI6Le6qbWGltYoEGU,276
|
655
655
|
vellum/evaluations/utils/exceptions.py,sha256=dXMAkzqbHV_AP5FjjbegPlfUE0zQDlpA3qOsoOJUxfg,49
|
656
656
|
vellum/evaluations/utils/paginator.py,sha256=rEED_BJAXAM6tM1yMwHePNzszjq_tTq4NbQvi1jWQ_Q,697
|
657
|
-
vellum/evaluations/utils/typing.py,sha256=wx_daFqD69cYkuJTVnvNrpjhqC3uuhbnyJ9_bIwC9OU,327
|
658
657
|
vellum/evaluations/utils/uuid.py,sha256=Ch6wWRgwICxLxJCTl5iE3EdRlZj2zADR-zUMUtjcMWM,214
|
659
658
|
vellum/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
660
659
|
vellum/plugins/pydantic.py,sha256=EbI0pJMhUS9rLPSkzmAELfnCHrWCJzOrU06T8ommwdw,2334
|
661
660
|
vellum/plugins/utils.py,sha256=U9ZY9KdE3RRvbcG01hXxu9CvfJD6Fo7nJDgcHjQn0FI,606
|
662
661
|
vellum/plugins/vellum_mypy.py,sha256=VC15EzjTsXOb9uF1bky4rcxePP-0epMVmCsLB2z4Dh8,24816
|
662
|
+
vellum/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
663
|
+
vellum/prompts/blocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
664
|
+
vellum/prompts/blocks/compilation.py,sha256=hBN_ajq77tSkVyUIcDlO-Qu77PSeJ1OzVhp70NmQd2k,7458
|
665
|
+
vellum/prompts/blocks/exceptions.py,sha256=vmk5PV6Vyw9nKjZYQDUDW0LH8MfQNIgFvFb_mFWdIRI,50
|
666
|
+
vellum/prompts/blocks/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
667
|
+
vellum/prompts/blocks/tests/test_compilation.py,sha256=0DhMoc4huHR6YnNL-0aBLmWSyUfw2BpRq_gEdKsQmAc,3693
|
668
|
+
vellum/prompts/blocks/types.py,sha256=6aSJQco-5kKeadfKVVXF_SrQPlIJgMYVNc-C7so1sY8,975
|
663
669
|
vellum/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
664
670
|
vellum/resources/__init__.py,sha256=sQWK7g_Z4EM7pa7fy6vy3d_DMdTJ4wVcozBn3Lx4Qpo,141
|
665
671
|
vellum/resources/ad_hoc/__init__.py,sha256=UD01D9nS_M7sRKmMbEg4Tv9SlfFj3cWahVxwUEaSLAY,148
|
@@ -1197,6 +1203,13 @@ vellum/types/workflow_result_event_output_data_search_results.py,sha256=UNfCHLQ0
|
|
1197
1203
|
vellum/types/workflow_result_event_output_data_string.py,sha256=rHEVbN0nyf-xoDoSIUEKlUKh6DDoguer4w0iN18JQ2I,178
|
1198
1204
|
vellum/types/workflow_stream_event.py,sha256=PjHGgN0eJm5w-5FJ6__ASC1FU94Gsav_ko5JWkpVvK8,159
|
1199
1205
|
vellum/types/workspace_secret_read.py,sha256=Z6QNXHxVHRdrLXSI31KxngePRwJTVoJYMXVbtPQwrxs,159
|
1206
|
+
vellum/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1207
|
+
vellum/utils/templating/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1208
|
+
vellum/utils/templating/constants.py,sha256=XTNmDsKa7byjw4GMZmzx2dUeYUTeMLZrPgRHcc80Kvc,613
|
1209
|
+
vellum/utils/templating/custom_filters.py,sha256=Q0DahYRHP4KfaUXDt9XxN-DFLBrAxlv90yaVqxScoUw,264
|
1210
|
+
vellum/utils/templating/exceptions.py,sha256=cDp140PP4OnInW4qAvg3KqiSiF70C71UyEAKRBR1Abo,46
|
1211
|
+
vellum/utils/templating/render.py,sha256=0vgkwhu2A6o64aT4fUdTSLFCEMbeRjAKAuvv2k2LYGY,1772
|
1212
|
+
vellum/utils/typing.py,sha256=wx_daFqD69cYkuJTVnvNrpjhqC3uuhbnyJ9_bIwC9OU,327
|
1200
1213
|
vellum/version.py,sha256=jq-1PlAYxN9AXuaZqbYk9ak27SgE2lw9Ia5gx1b1gVI,76
|
1201
1214
|
vellum/workflows/README.md,sha256=MLNm-ihc0ao6I8gwwOhXQQBf0jOf-EsA9C519ALYI1o,3610
|
1202
1215
|
vellum/workflows/__init__.py,sha256=CssPsbNvN6rDhoLuqpEv7MMKGa51vE6dvAh6U31Pcio,71
|
@@ -1278,10 +1291,7 @@ vellum/workflows/nodes/core/retry_node/node.py,sha256=IjNcpzFmHyBUjOHEoULLbKf85B
|
|
1278
1291
|
vellum/workflows/nodes/core/retry_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1279
1292
|
vellum/workflows/nodes/core/retry_node/tests/test_node.py,sha256=QXTnHwmJHISxXjvZMeuuEo0iVugVMJyaJoggI8yKXfI,3132
|
1280
1293
|
vellum/workflows/nodes/core/templating_node/__init__.py,sha256=GmyuYo81_A1_Bz6id69ozVFS6FKiuDsZTiA3I6MaL2U,70
|
1281
|
-
vellum/workflows/nodes/core/templating_node/
|
1282
|
-
vellum/workflows/nodes/core/templating_node/exceptions.py,sha256=cDp140PP4OnInW4qAvg3KqiSiF70C71UyEAKRBR1Abo,46
|
1283
|
-
vellum/workflows/nodes/core/templating_node/node.py,sha256=Q5U5lAW1nhGFJPc94Gxnq1s5RWrbOo7G_AY4n-ABmGg,4504
|
1284
|
-
vellum/workflows/nodes/core/templating_node/render.py,sha256=OpJp0NAH6qcEL6K9lxR0qjpFb75TYNttJR5iCos8tmg,1792
|
1294
|
+
vellum/workflows/nodes/core/templating_node/node.py,sha256=mWNzsa6TLosrD3higKIsiqEv54OIfNY7YzFDkuQgm6k,3964
|
1285
1295
|
vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py,sha256=0BtXeSix7KGIuKzlPFTMLATpNnFPhut1UV_srGptkt0,1120
|
1286
1296
|
vellum/workflows/nodes/core/try_node/__init__.py,sha256=JVD4DrldTIqFQQFrubs9KtWCCc0YCAc7Fzol5ZWIWeM,56
|
1287
1297
|
vellum/workflows/nodes/core/try_node/node.py,sha256=_xkpUNIfHXuwjivMBxdU5DegsNge2ITW5nBifWmBPTY,6670
|
@@ -1331,6 +1341,10 @@ vellum/workflows/nodes/displayable/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
|
|
1331
1341
|
vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py,sha256=UI_RMmXn9qwB-StnFPvkDd9FctBQAg43wrfouqvPepk,4701
|
1332
1342
|
vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py,sha256=4CMwDtXwTaEvFfDpA6j2iLqc7S6IICSkvVZOobEpeps,6954
|
1333
1343
|
vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py,sha256=KqKJtJ0vuNoPuUPMdILmBTt4a2fBBxxun-nmOI7T8jo,2585
|
1344
|
+
vellum/workflows/nodes/experimental/README.md,sha256=eF6DfIL8t-HbF9-mcofOMymKrraiBHDLKTlnBa51ZiE,284
|
1345
|
+
vellum/workflows/nodes/experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1346
|
+
vellum/workflows/nodes/experimental/openai_chat_completion_node/__init__.py,sha256=lsyD9laR9p7kx5-BXGH2gUTM242UhKy8SMV0SR6S2iE,90
|
1347
|
+
vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py,sha256=1EGeiaT-Zoo6pttQFKKBcdf3dmhAbjKGaErYD5FFwlc,10185
|
1334
1348
|
vellum/workflows/nodes/utils.py,sha256=EZt7CzJmgQBR_GWFpZr8d-oaoti3tolTd2Cv9wm7dKo,1087
|
1335
1349
|
vellum/workflows/outputs/__init__.py,sha256=AyZ4pRh_ACQIGvkf0byJO46EDnSix1ZCAXfvh-ms1QE,94
|
1336
1350
|
vellum/workflows/outputs/base.py,sha256=a7W6rNSDSawwGAXYjNTF2iHb9lnZu7WFSOagZIyy__k,7976
|
@@ -1353,7 +1367,7 @@ vellum/workflows/resolvers/__init__.py,sha256=eH6hTvZO4IciDaf_cf7aM2vs-DkBDyJPyc
|
|
1353
1367
|
vellum/workflows/resolvers/base.py,sha256=WHra9LRtlTuB1jmuNqkfVE2JUgB61Cyntn8f0b0WZg4,411
|
1354
1368
|
vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
|
1355
1369
|
vellum/workflows/runner/runner.py,sha256=RXnLEmSJFbp0u4vKF7rvD2fscuYfcRYkspIJINnvFAI,27607
|
1356
|
-
vellum/workflows/sandbox.py,sha256=
|
1370
|
+
vellum/workflows/sandbox.py,sha256=1aL5BoUgJX6dbIN3pqui20Wk3VyzXV16BUaZz-clmFs,2269
|
1357
1371
|
vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
|
1358
1372
|
vellum/workflows/state/base.py,sha256=jpSzF1OQd3-fqi6dMGlNsQl-7JnJxCdzWIigmX8Wz-I,14425
|
1359
1373
|
vellum/workflows/state/context.py,sha256=oXiEdNsWJi1coRB85IreTgUeR6_CrWWBXndtLff9S7M,1272
|
@@ -1384,8 +1398,8 @@ vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528
|
|
1384
1398
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
1385
1399
|
vellum/workflows/workflows/base.py,sha256=zpspOEdO5Ye_0ZvN-Wkzv9iQSiF1sD201ba8lhbnPbs,17086
|
1386
1400
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
1387
|
-
vellum_ai-0.12.
|
1388
|
-
vellum_ai-0.12.
|
1389
|
-
vellum_ai-0.12.
|
1390
|
-
vellum_ai-0.12.
|
1391
|
-
vellum_ai-0.12.
|
1401
|
+
vellum_ai-0.12.8.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1402
|
+
vellum_ai-0.12.8.dist-info/METADATA,sha256=FI7BG5Gx3Dd3exq5uqBWnHu8kuqFrVpE_9tcdUuYwdk,5160
|
1403
|
+
vellum_ai-0.12.8.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1404
|
+
vellum_ai-0.12.8.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1405
|
+
vellum_ai-0.12.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|