soprano-sdk 0.1.93__py3-none-any.whl → 0.1.95__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.
- soprano_sdk/__init__.py +10 -0
- soprano_sdk/agents/__init__.py +30 -0
- soprano_sdk/agents/adaptor.py +91 -0
- soprano_sdk/agents/factory.py +228 -0
- soprano_sdk/agents/structured_output.py +97 -0
- soprano_sdk/core/__init__.py +0 -0
- soprano_sdk/core/constants.py +59 -0
- soprano_sdk/core/engine.py +225 -0
- soprano_sdk/core/rollback_strategies.py +259 -0
- soprano_sdk/core/state.py +71 -0
- soprano_sdk/engine.py +381 -0
- soprano_sdk/nodes/__init__.py +0 -0
- soprano_sdk/nodes/base.py +57 -0
- soprano_sdk/nodes/call_function.py +108 -0
- soprano_sdk/nodes/collect_input.py +526 -0
- soprano_sdk/nodes/factory.py +46 -0
- soprano_sdk/routing/__init__.py +0 -0
- soprano_sdk/routing/router.py +97 -0
- soprano_sdk/tools.py +219 -0
- soprano_sdk/utils/__init__.py +0 -0
- soprano_sdk/utils/data.py +1 -0
- soprano_sdk/utils/function.py +35 -0
- soprano_sdk/utils/logger.py +6 -0
- soprano_sdk/utils/template.py +27 -0
- soprano_sdk/utils/tool.py +60 -0
- soprano_sdk/utils/tracing.py +71 -0
- soprano_sdk/validation/__init__.py +13 -0
- soprano_sdk/validation/schema.py +302 -0
- soprano_sdk/validation/validator.py +173 -0
- {soprano_sdk-0.1.93.dist-info → soprano_sdk-0.1.95.dist-info}/METADATA +1 -1
- soprano_sdk-0.1.95.dist-info/RECORD +33 -0
- soprano_sdk-0.1.93.dist-info/RECORD +0 -4
- {soprano_sdk-0.1.93.dist-info → soprano_sdk-0.1.95.dist-info}/WHEEL +0 -0
- {soprano_sdk-0.1.93.dist-info → soprano_sdk-0.1.95.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
WORKFLOW_SCHEMA = {
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"required": ["name", "description", "version", "data", "steps", "outcomes"],
|
|
5
|
+
"properties": {
|
|
6
|
+
"name": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"description": "Workflow name"
|
|
9
|
+
},
|
|
10
|
+
"description": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Workflow description"
|
|
13
|
+
},
|
|
14
|
+
"version": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"pattern": "^\\d+\\.\\d+(\\.\\d+)?$",
|
|
17
|
+
"description": "Semantic version (e.g., 1.0.0)"
|
|
18
|
+
},
|
|
19
|
+
"agent_framework": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"enum": ["langgraph", "crewai", "agno", "pydantic-ai"],
|
|
22
|
+
"default": "langgraph",
|
|
23
|
+
"description": "Agent framework to use for all agents in this workflow (default: langgraph)"
|
|
24
|
+
},
|
|
25
|
+
"data": {
|
|
26
|
+
"type": "array",
|
|
27
|
+
"description": "Data fields used in the workflow",
|
|
28
|
+
"items": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": ["name", "type", "description"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"name": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
35
|
+
"description": "Field name (must be valid Python identifier)"
|
|
36
|
+
},
|
|
37
|
+
"type": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"enum": ["text", "number", "boolean", "list", "dict", "any", "double"],
|
|
40
|
+
"description": "Field data type"
|
|
41
|
+
},
|
|
42
|
+
"description": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"description": "Field description"
|
|
45
|
+
},
|
|
46
|
+
"default": {
|
|
47
|
+
"description": "Default value for the field"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"inputs": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"description": "Input fields required to start the workflow (list of data field names)",
|
|
55
|
+
"items": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
58
|
+
"description": "Name of a field from the data array"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"steps": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"description": "Workflow steps",
|
|
64
|
+
"minItems": 1,
|
|
65
|
+
"items": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"required": ["id", "action"],
|
|
68
|
+
"properties": {
|
|
69
|
+
"id": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
72
|
+
"description": "Step ID (must be unique and valid Python identifier)"
|
|
73
|
+
},
|
|
74
|
+
"action": {
|
|
75
|
+
"type": "string",
|
|
76
|
+
"enum": ["collect_input_with_agent", "call_function"],
|
|
77
|
+
"description": "Action type"
|
|
78
|
+
},
|
|
79
|
+
"field": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"description": "Field to collect (for collect_input_with_agent)"
|
|
82
|
+
},
|
|
83
|
+
"validator": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "Optional data validator"
|
|
86
|
+
},
|
|
87
|
+
"max_attempts": {
|
|
88
|
+
"type": "integer",
|
|
89
|
+
"minimum": 1,
|
|
90
|
+
"maximum": 20,
|
|
91
|
+
"description": "Maximum attempts (for collect_input_with_agent)"
|
|
92
|
+
},
|
|
93
|
+
"agent": {
|
|
94
|
+
"type": "object",
|
|
95
|
+
"description": "Agent configuration (for collect_input_with_agent)",
|
|
96
|
+
"required": ["name", "instructions"],
|
|
97
|
+
"properties": {
|
|
98
|
+
"name": {
|
|
99
|
+
"type": "string"
|
|
100
|
+
},
|
|
101
|
+
"model": {
|
|
102
|
+
"type": "string"
|
|
103
|
+
},
|
|
104
|
+
"description": {
|
|
105
|
+
"type": "string"
|
|
106
|
+
},
|
|
107
|
+
"instructions": {
|
|
108
|
+
"type": "string"
|
|
109
|
+
},
|
|
110
|
+
"tools": {
|
|
111
|
+
"type": "array"
|
|
112
|
+
},
|
|
113
|
+
"base_url": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"format": "uri"
|
|
116
|
+
},
|
|
117
|
+
"api_key": {
|
|
118
|
+
"type": "string"
|
|
119
|
+
},
|
|
120
|
+
"structured_output": {
|
|
121
|
+
"type": "object",
|
|
122
|
+
"description": "Structured output configuration",
|
|
123
|
+
"required": ["enabled"],
|
|
124
|
+
"properties": {
|
|
125
|
+
"enabled": {
|
|
126
|
+
"type": "boolean",
|
|
127
|
+
"description": "Whether to enable structured output"
|
|
128
|
+
},
|
|
129
|
+
"fields": {
|
|
130
|
+
"type": "array",
|
|
131
|
+
"description": "Field definitions for structured output",
|
|
132
|
+
"items": {
|
|
133
|
+
"type": "object",
|
|
134
|
+
"required": ["name", "type", "description"],
|
|
135
|
+
"properties": {
|
|
136
|
+
"name": {
|
|
137
|
+
"type": "string",
|
|
138
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
139
|
+
"description": "Field name (must be valid Python identifier)"
|
|
140
|
+
},
|
|
141
|
+
"type": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"enum": ["text", "number", "boolean", "list", "dict", "double"],
|
|
144
|
+
"description": "Field data type"
|
|
145
|
+
},
|
|
146
|
+
"description": {
|
|
147
|
+
"type": "string",
|
|
148
|
+
"description": "Field description"
|
|
149
|
+
},
|
|
150
|
+
"required": {
|
|
151
|
+
"type": "boolean",
|
|
152
|
+
"description": "Whether the field is required",
|
|
153
|
+
"default": True
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"function": {
|
|
163
|
+
"type": "string",
|
|
164
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_.]*\\.[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
165
|
+
"description": "Function path (for call_function, format: module.function)"
|
|
166
|
+
},
|
|
167
|
+
"inputs": {
|
|
168
|
+
"type": "object",
|
|
169
|
+
"description": "Input mapping for function"
|
|
170
|
+
},
|
|
171
|
+
"output": {
|
|
172
|
+
"type": "string",
|
|
173
|
+
"description": "Output field name"
|
|
174
|
+
},
|
|
175
|
+
"next": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"description": "Next step ID (for simple routing)"
|
|
178
|
+
},
|
|
179
|
+
"transitions": {
|
|
180
|
+
"type": "array",
|
|
181
|
+
"description": "Conditional transitions",
|
|
182
|
+
"items": {
|
|
183
|
+
"type": "object",
|
|
184
|
+
"properties": {
|
|
185
|
+
"pattern": {
|
|
186
|
+
"type": "string",
|
|
187
|
+
"description": "Pattern to match in response (for non-structured output)"
|
|
188
|
+
},
|
|
189
|
+
"match": {
|
|
190
|
+
"description": "Value to match against a field (for structured output)"
|
|
191
|
+
},
|
|
192
|
+
"ref": {
|
|
193
|
+
"type": "string",
|
|
194
|
+
"description": "Field name to check when using 'match' (for structured output)"
|
|
195
|
+
},
|
|
196
|
+
"condition": {
|
|
197
|
+
"description": "Condition to evaluate (for call_function)"
|
|
198
|
+
},
|
|
199
|
+
"path": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"description": "Dot-notation path to the value for evaluation (optional)"
|
|
202
|
+
},
|
|
203
|
+
"next": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"description": "Next step or outcome ID"
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"oneOf": [
|
|
209
|
+
{"required": ["pattern", "next"]},
|
|
210
|
+
{"required": ["match", "next", "ref"]},
|
|
211
|
+
{"required": ["condition", "next"]}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"url": {
|
|
216
|
+
"type": "string",
|
|
217
|
+
"format": "uri",
|
|
218
|
+
"description": "Webhook URL (for webhook action)"
|
|
219
|
+
},
|
|
220
|
+
"method": {
|
|
221
|
+
"type": "string",
|
|
222
|
+
"enum": ["GET", "POST", "PUT", "PATCH", "DELETE"],
|
|
223
|
+
"description": "HTTP method (for webhook action)"
|
|
224
|
+
},
|
|
225
|
+
"headers": {
|
|
226
|
+
"type": "object",
|
|
227
|
+
"description": "HTTP headers (for webhook action)"
|
|
228
|
+
},
|
|
229
|
+
"timeout": {
|
|
230
|
+
"type": "integer",
|
|
231
|
+
"minimum": 1,
|
|
232
|
+
"maximum": 600,
|
|
233
|
+
"description": "Timeout in seconds"
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
"outcomes": {
|
|
239
|
+
"type": "array",
|
|
240
|
+
"description": "Workflow outcomes",
|
|
241
|
+
"minItems": 1,
|
|
242
|
+
"items": {
|
|
243
|
+
"type": "object",
|
|
244
|
+
"required": ["id", "type", "message"],
|
|
245
|
+
"properties": {
|
|
246
|
+
"id": {
|
|
247
|
+
"type": "string",
|
|
248
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
249
|
+
"description": "Outcome ID (must be unique)"
|
|
250
|
+
},
|
|
251
|
+
"type": {
|
|
252
|
+
"type": "string",
|
|
253
|
+
"enum": ["success", "failure"],
|
|
254
|
+
"description": "Outcome type"
|
|
255
|
+
},
|
|
256
|
+
"message": {
|
|
257
|
+
"type": "string",
|
|
258
|
+
"description": "Outcome message (supports {field} placeholders)"
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
"metadata": {
|
|
264
|
+
"type": "object",
|
|
265
|
+
"description": "Additional workflow metadata",
|
|
266
|
+
"properties": {
|
|
267
|
+
"author": {"type": "string"},
|
|
268
|
+
"tags": {"type": "array", "items": {"type": "string"}},
|
|
269
|
+
"documentation": {"type": "string"}
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"tool_config": {
|
|
273
|
+
"type": "object",
|
|
274
|
+
"description": "Tool configuration for the workflow",
|
|
275
|
+
"properties": {
|
|
276
|
+
"tools": {
|
|
277
|
+
"type": "array",
|
|
278
|
+
"description": "List of available tools",
|
|
279
|
+
"items": {
|
|
280
|
+
"type": "object",
|
|
281
|
+
"required": ["name", "description", "callable"],
|
|
282
|
+
"properties": {
|
|
283
|
+
"name": {
|
|
284
|
+
"type": "string",
|
|
285
|
+
"description": "Tool name"
|
|
286
|
+
},
|
|
287
|
+
"description": {
|
|
288
|
+
"type": "string",
|
|
289
|
+
"description": "Tool description"
|
|
290
|
+
},
|
|
291
|
+
"callable": {
|
|
292
|
+
"type": "string",
|
|
293
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_.]*\\.[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
294
|
+
"description": "Callable path (format: module.function)"
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
from typing import List, Set
|
|
2
|
+
|
|
3
|
+
import jsonschema
|
|
4
|
+
|
|
5
|
+
from .schema import WORKFLOW_SCHEMA
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ValidationResult:
|
|
9
|
+
def __init__(self, is_valid: bool, errors: List[str] = None):
|
|
10
|
+
self.is_valid = is_valid
|
|
11
|
+
self.errors = errors or []
|
|
12
|
+
|
|
13
|
+
def __bool__(self):
|
|
14
|
+
return self.is_valid
|
|
15
|
+
|
|
16
|
+
def __str__(self):
|
|
17
|
+
if self.is_valid:
|
|
18
|
+
return "Validation passed"
|
|
19
|
+
return f"Validation failed with {len(self.errors)} error(s):\n" + "\n".join(f" - {e}" for e in self.errors)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class WorkflowValidator:
|
|
23
|
+
def __init__(self, config: dict):
|
|
24
|
+
self.config = config
|
|
25
|
+
self.errors: List[str] = []
|
|
26
|
+
|
|
27
|
+
def validate(self) -> ValidationResult:
|
|
28
|
+
self.errors = []
|
|
29
|
+
self._validate_schema()
|
|
30
|
+
if not self.errors:
|
|
31
|
+
self._validate_step_ids()
|
|
32
|
+
self._validate_outcome_ids()
|
|
33
|
+
self._validate_transitions()
|
|
34
|
+
self._validate_data_fields()
|
|
35
|
+
self._validate_input_fields()
|
|
36
|
+
self._validate_function_references()
|
|
37
|
+
|
|
38
|
+
return ValidationResult(is_valid=len(self.errors) == 0, errors=self.errors)
|
|
39
|
+
|
|
40
|
+
def _validate_schema(self):
|
|
41
|
+
try:
|
|
42
|
+
jsonschema.validate(instance=self.config, schema=WORKFLOW_SCHEMA)
|
|
43
|
+
except jsonschema.ValidationError as e:
|
|
44
|
+
path = " -> ".join(str(p) for p in e.path) if e.path else "root"
|
|
45
|
+
self.errors.append(f"Schema validation error at '{path}': {e.message}")
|
|
46
|
+
except jsonschema.SchemaError as e:
|
|
47
|
+
self.errors.append(f"Invalid schema definition: {e.message}")
|
|
48
|
+
|
|
49
|
+
def _validate_input_fields(self):
|
|
50
|
+
"""Validate that all input field names reference valid data fields."""
|
|
51
|
+
input_fields = self.config.get('inputs', [])
|
|
52
|
+
data_fields = set([field.get('name') for field in self.config.get('data', [])])
|
|
53
|
+
|
|
54
|
+
for field_name in input_fields:
|
|
55
|
+
if field_name not in data_fields:
|
|
56
|
+
self.errors.append(f"Input field '{field_name}' is not defined in data fields")
|
|
57
|
+
|
|
58
|
+
def _validate_step_ids(self):
|
|
59
|
+
steps = self.config.get('steps', [])
|
|
60
|
+
step_ids: Set[str] = set()
|
|
61
|
+
|
|
62
|
+
for i, step in enumerate(steps):
|
|
63
|
+
step_id = step.get('id')
|
|
64
|
+
if not step_id:
|
|
65
|
+
self.errors.append(f"Step at index {i} is missing 'id' field")
|
|
66
|
+
continue
|
|
67
|
+
|
|
68
|
+
if step_id in step_ids:
|
|
69
|
+
self.errors.append(f"Duplicate step ID: '{step_id}'")
|
|
70
|
+
step_ids.add(step_id)
|
|
71
|
+
|
|
72
|
+
def _validate_outcome_ids(self):
|
|
73
|
+
outcomes = self.config.get('outcomes', [])
|
|
74
|
+
outcome_ids: Set[str] = set()
|
|
75
|
+
|
|
76
|
+
for i, outcome in enumerate(outcomes):
|
|
77
|
+
outcome_id = outcome.get('id')
|
|
78
|
+
if not outcome_id:
|
|
79
|
+
self.errors.append(f"Outcome at index {i} is missing 'id' field")
|
|
80
|
+
continue
|
|
81
|
+
|
|
82
|
+
if outcome_id in outcome_ids:
|
|
83
|
+
self.errors.append(f"Duplicate outcome ID: '{outcome_id}'")
|
|
84
|
+
outcome_ids.add(outcome_id)
|
|
85
|
+
|
|
86
|
+
def _validate_transitions(self):
|
|
87
|
+
steps = self.config.get('steps', [])
|
|
88
|
+
outcomes = self.config.get('outcomes', [])
|
|
89
|
+
|
|
90
|
+
step_ids = {step.get('id') for step in steps if step.get('id')}
|
|
91
|
+
outcome_ids = {outcome.get('id') for outcome in outcomes if outcome.get('id')}
|
|
92
|
+
valid_targets = step_ids | outcome_ids
|
|
93
|
+
|
|
94
|
+
for step in steps:
|
|
95
|
+
step_id = step.get('id', 'unknown')
|
|
96
|
+
|
|
97
|
+
next_step = step.get('next')
|
|
98
|
+
if next_step and next_step not in valid_targets:
|
|
99
|
+
self.errors.append(
|
|
100
|
+
f"Step '{step_id}' references unknown target in 'next': '{next_step}'"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
transitions = step.get('transitions', [])
|
|
104
|
+
for i, transition in enumerate(transitions):
|
|
105
|
+
next_target = transition.get('next')
|
|
106
|
+
if next_target and next_target not in valid_targets:
|
|
107
|
+
self.errors.append(
|
|
108
|
+
f"Step '{step_id}' transition {i} references unknown target: '{next_target}'"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
def _validate_data_fields(self):
|
|
112
|
+
data_fields = {field.get('name') for field in self.config.get('data', [])}
|
|
113
|
+
steps = self.config.get('steps', [])
|
|
114
|
+
|
|
115
|
+
for step in steps:
|
|
116
|
+
step_id = step.get('id', 'unknown')
|
|
117
|
+
action = step.get('action')
|
|
118
|
+
|
|
119
|
+
if action == 'collect_input_with_agent':
|
|
120
|
+
field = step.get('field')
|
|
121
|
+
if not field:
|
|
122
|
+
self.errors.append(f"Step '{step_id}' is missing 'field' property")
|
|
123
|
+
elif field not in data_fields:
|
|
124
|
+
self.errors.append(
|
|
125
|
+
f"Step '{step_id}' references unknown field: '{field}'"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
agent = step.get('agent')
|
|
129
|
+
if not agent:
|
|
130
|
+
self.errors.append(f"Step '{step_id}' is missing 'agent' configuration")
|
|
131
|
+
elif not agent.get('instructions'):
|
|
132
|
+
self.errors.append(f"Step '{step_id}' agent is missing 'instructions'")
|
|
133
|
+
|
|
134
|
+
elif action == 'call_function':
|
|
135
|
+
output = step.get('output')
|
|
136
|
+
function = step.get('function')
|
|
137
|
+
|
|
138
|
+
if not function:
|
|
139
|
+
self.errors.append(f"Step '{step_id}' is missing 'function' property")
|
|
140
|
+
|
|
141
|
+
if not output:
|
|
142
|
+
self.errors.append(f"Step '{step_id}' is missing 'output' property")
|
|
143
|
+
elif output not in data_fields:
|
|
144
|
+
self.errors.append(
|
|
145
|
+
f"Step '{step_id}' output field '{output}' not defined in data fields"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def _validate_function_references(self):
|
|
149
|
+
steps = self.config.get('steps', [])
|
|
150
|
+
|
|
151
|
+
for step in steps:
|
|
152
|
+
if step.get('action') == 'call_function':
|
|
153
|
+
step_id = step.get('id', 'unknown')
|
|
154
|
+
function_path = step.get('function', '')
|
|
155
|
+
|
|
156
|
+
if not function_path:
|
|
157
|
+
continue # Already caught by _validate_data_fields
|
|
158
|
+
|
|
159
|
+
if '.' not in function_path:
|
|
160
|
+
self.errors.append(
|
|
161
|
+
f"Step '{step_id}' function path '{function_path}' is invalid. "
|
|
162
|
+
f"Expected format: 'module.function'"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def validate_workflow(config: dict) -> ValidationResult:
|
|
167
|
+
validator = WorkflowValidator(config)
|
|
168
|
+
result = validator.validate()
|
|
169
|
+
|
|
170
|
+
if not result.is_valid:
|
|
171
|
+
raise RuntimeError(str(result))
|
|
172
|
+
|
|
173
|
+
return result
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
soprano_sdk/__init__.py,sha256=y3c4i7Q7SAPS2Tee7V0TzWdhgMxBWfDJJ98eqD1HxGI,188
|
|
2
|
+
soprano_sdk/engine.py,sha256=EFK91iTHjp72otLN6Kg-yeLye2J3CAKN0QH4FI2taL8,14838
|
|
3
|
+
soprano_sdk/tools.py,sha256=A0qFEwn208GCYc-_7ZbZKR7N3HG5-6TA3Ma1RPo6YnM,8029
|
|
4
|
+
soprano_sdk/agents/__init__.py,sha256=Yzbtv6iP_ABRgZo0IUjy9vDofEvLFbOjuABw758176A,636
|
|
5
|
+
soprano_sdk/agents/adaptor.py,sha256=IMMgo9_KLI82i1eenOaojw7UE0jjx9vjm8mjfsodKSM,3226
|
|
6
|
+
soprano_sdk/agents/factory.py,sha256=Aucfz4rZVKCXMAQtbGAqp1JR8aYwa66mokRmKkKGhYA,6699
|
|
7
|
+
soprano_sdk/agents/structured_output.py,sha256=LDBWCMJFclOvcFB3OJpu37tO0Ct_M-L2PIH5MCYSjLI,3262
|
|
8
|
+
soprano_sdk/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
soprano_sdk/core/constants.py,sha256=pEwW_NeHhxs7aG457uiBCs65czAapozY6r9JAegc01Y,1451
|
|
10
|
+
soprano_sdk/core/engine.py,sha256=WEyqGaBasGnSqlBAkFSQIZXJb7T6OEsN-DWznIBAzNs,8341
|
|
11
|
+
soprano_sdk/core/rollback_strategies.py,sha256=UZyDBRmbi4kS7D9cGJT_mzSZzfqgbUoeTnOGcW1WOc0,7798
|
|
12
|
+
soprano_sdk/core/state.py,sha256=h0Uo4uCwBAGTWrmzpDbcTwH6lI97-fXU9ek0tc3p2bM,2617
|
|
13
|
+
soprano_sdk/nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
soprano_sdk/nodes/base.py,sha256=H6wvvN3kUeXluZAt5Hf3iocO9NjTElAH4fTb2-1JKr0,2233
|
|
15
|
+
soprano_sdk/nodes/call_function.py,sha256=6M9QywYpitwDsbIbOSGw0YN_lH4kRFWa5UMxIIf393M,4346
|
|
16
|
+
soprano_sdk/nodes/collect_input.py,sha256=LhDsqtlBKK-uIz90QIODDoR5PZbnv4rWyj-hvTR64do,21987
|
|
17
|
+
soprano_sdk/nodes/factory.py,sha256=l-Gysfgnao-o2dphhnbjjxcH3ojZanZNYN3CBH9dDbA,1624
|
|
18
|
+
soprano_sdk/routing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
soprano_sdk/routing/router.py,sha256=SrNciTIXXdC9bAbbO5bX7PN9mlRbITjr4RZdNm4jEVA,3450
|
|
20
|
+
soprano_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
soprano_sdk/utils/data.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
22
|
+
soprano_sdk/utils/function.py,sha256=yqkY4MlHOenv-Q3NciiovK1lamyrGQljpy6Q41wviy8,1216
|
|
23
|
+
soprano_sdk/utils/logger.py,sha256=hMYaNHt5syGOXRkglTUKzkgfSbWerix_pHQntcYyep8,157
|
|
24
|
+
soprano_sdk/utils/template.py,sha256=EssXvRDWdyITVWp52weYNIwnqj9ilJaoQotWFIg4rGQ,678
|
|
25
|
+
soprano_sdk/utils/tool.py,sha256=hWN826HIKmLdswLCTURLH8hWlb2WU0MB8nIUErbpB-8,1877
|
|
26
|
+
soprano_sdk/utils/tracing.py,sha256=iSJlTAaiGzgBvZhLISCGAd9_7F2HRzhcIUNHuaFv_Zc,2059
|
|
27
|
+
soprano_sdk/validation/__init__.py,sha256=ImChmO86jYHU90xzTttto2-LmOUOmvY_ibOQaLRz5BA,262
|
|
28
|
+
soprano_sdk/validation/schema.py,sha256=uJJZRDgwzWT2W8amd_W8mUAULvDnHJhiMEl-5so1ZK0,13559
|
|
29
|
+
soprano_sdk/validation/validator.py,sha256=l2P24wiCWBNTZ9-dRbgWwK48BGaR1xIdnBxzSCu0RPM,6498
|
|
30
|
+
soprano_sdk-0.1.95.dist-info/METADATA,sha256=c8u9LFyCMo-p4U3A_2V0zh16dpK4BoRYBcVB0nckXIw,11269
|
|
31
|
+
soprano_sdk-0.1.95.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
32
|
+
soprano_sdk-0.1.95.dist-info/licenses/LICENSE,sha256=A1aBauSjPNtVehOXJe3WuvdU2xvM9H8XmigFMm6665s,1073
|
|
33
|
+
soprano_sdk-0.1.95.dist-info/RECORD,,
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
soprano_sdk-0.1.93.dist-info/METADATA,sha256=TmMcHnMXPkO1WEYt75D3N8I3ev5TtXZJKqDTWj8zRiY,11269
|
|
2
|
-
soprano_sdk-0.1.93.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
3
|
-
soprano_sdk-0.1.93.dist-info/licenses/LICENSE,sha256=A1aBauSjPNtVehOXJe3WuvdU2xvM9H8XmigFMm6665s,1073
|
|
4
|
-
soprano_sdk-0.1.93.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|