service-forge 0.1.11__py3-none-any.whl → 0.1.24__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.
Potentially problematic release.
This version of service-forge might be problematic. Click here for more details.
- service_forge/api/http_api.py +4 -0
- service_forge/api/routers/feedback/feedback_router.py +148 -0
- service_forge/api/routers/service/service_router.py +22 -32
- service_forge/current_service.py +14 -0
- service_forge/db/database.py +46 -32
- service_forge/db/migrations/feedback_migration.py +154 -0
- service_forge/db/models/__init__.py +0 -0
- service_forge/db/models/feedback.py +33 -0
- service_forge/llm/__init__.py +5 -0
- service_forge/model/feedback.py +30 -0
- service_forge/service.py +118 -126
- service_forge/service_config.py +42 -156
- service_forge/sft/cli.py +39 -0
- service_forge/sft/cmd/remote_deploy.py +160 -0
- service_forge/sft/cmd/remote_list_tars.py +111 -0
- service_forge/sft/config/injector.py +46 -24
- service_forge/sft/config/injector_default_files.py +1 -1
- service_forge/sft/config/sft_config.py +55 -8
- service_forge/storage/__init__.py +5 -0
- service_forge/storage/feedback_storage.py +245 -0
- service_forge/utils/default_type_converter.py +1 -1
- service_forge/utils/type_converter.py +5 -0
- service_forge/utils/workflow_clone.py +3 -2
- service_forge/workflow/node.py +8 -0
- service_forge/workflow/nodes/llm/query_llm_node.py +1 -1
- service_forge/workflow/trigger.py +4 -0
- service_forge/workflow/triggers/a2a_api_trigger.py +2 -0
- service_forge/workflow/triggers/fast_api_trigger.py +32 -0
- service_forge/workflow/triggers/kafka_api_trigger.py +3 -0
- service_forge/workflow/triggers/once_trigger.py +4 -1
- service_forge/workflow/triggers/period_trigger.py +4 -1
- service_forge/workflow/triggers/websocket_api_trigger.py +15 -11
- service_forge/workflow/workflow.py +74 -31
- service_forge/workflow/workflow_callback.py +3 -2
- service_forge/workflow/workflow_config.py +66 -0
- service_forge/workflow/workflow_factory.py +86 -85
- service_forge/workflow/workflow_group.py +33 -9
- {service_forge-0.1.11.dist-info → service_forge-0.1.24.dist-info}/METADATA +1 -1
- {service_forge-0.1.11.dist-info → service_forge-0.1.24.dist-info}/RECORD +41 -31
- service_forge/api/routers/service/__init__.py +0 -4
- {service_forge-0.1.11.dist-info → service_forge-0.1.24.dist-info}/WHEEL +0 -0
- {service_forge-0.1.11.dist-info → service_forge-0.1.24.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import yaml
|
|
4
|
+
from typing import Any
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
DEFAULT_WORKFLOW_VERSION = "0"
|
|
8
|
+
|
|
9
|
+
class WorkflowNodeOutputConfig(BaseModel):
|
|
10
|
+
name: str
|
|
11
|
+
port: str
|
|
12
|
+
|
|
13
|
+
class WorkflowNodeArgConfig(BaseModel):
|
|
14
|
+
name: str
|
|
15
|
+
value: Any | None = None
|
|
16
|
+
|
|
17
|
+
class WorkflowInputPortConfig(BaseModel):
|
|
18
|
+
name: str
|
|
19
|
+
port: str
|
|
20
|
+
value: Any | None = None
|
|
21
|
+
|
|
22
|
+
class WorkflowOutputPortConfig(BaseModel):
|
|
23
|
+
name: str
|
|
24
|
+
port: str
|
|
25
|
+
|
|
26
|
+
class WorkflowNodeSubWorkflowConfig(BaseModel):
|
|
27
|
+
name: str
|
|
28
|
+
version: str = DEFAULT_WORKFLOW_VERSION
|
|
29
|
+
|
|
30
|
+
class WorkflowNodeSubWorkflowInputPortConfig(BaseModel):
|
|
31
|
+
name: str
|
|
32
|
+
port: str
|
|
33
|
+
value: Any | None = None
|
|
34
|
+
|
|
35
|
+
class WorkflowNodeConfig(BaseModel):
|
|
36
|
+
name: str
|
|
37
|
+
type: str
|
|
38
|
+
args: dict | None = None
|
|
39
|
+
outputs: dict | None = None
|
|
40
|
+
sub_workflows: list[WorkflowNodeSubWorkflowConfig] | None = None
|
|
41
|
+
sub_workflows_input_ports: list[WorkflowNodeSubWorkflowInputPortConfig] | None = None
|
|
42
|
+
|
|
43
|
+
class WorkflowConfig(BaseModel):
|
|
44
|
+
name: str
|
|
45
|
+
version: str = DEFAULT_WORKFLOW_VERSION
|
|
46
|
+
description: str
|
|
47
|
+
nodes: list[WorkflowNodeConfig]
|
|
48
|
+
inputs: list[WorkflowInputPortConfig] | None = None
|
|
49
|
+
outputs: list[WorkflowOutputPortConfig] | None = None
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def from_yaml_file(cls, filepath: str) -> WorkflowConfig:
|
|
53
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
54
|
+
data = yaml.safe_load(f)
|
|
55
|
+
return cls(**data)
|
|
56
|
+
|
|
57
|
+
class WorkflowGroupConfig(BaseModel):
|
|
58
|
+
workflows: list[WorkflowConfig] | None
|
|
59
|
+
main_workflow_name: str | None
|
|
60
|
+
main_workflow_version: str | None = DEFAULT_WORKFLOW_VERSION
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
def from_yaml_file(cls, filepath: str) -> WorkflowGroupConfig:
|
|
64
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
65
|
+
data = yaml.safe_load(f)
|
|
66
|
+
return cls(**data)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import uuid
|
|
1
2
|
from omegaconf import OmegaConf
|
|
2
3
|
from typing import Callable, Awaitable, AsyncIterator, Any
|
|
3
4
|
from copy import deepcopy
|
|
4
5
|
|
|
5
6
|
from service_forge.workflow.workflow_callback import BuiltinWorkflowCallback
|
|
6
7
|
from .workflow import Workflow
|
|
7
|
-
from .workflow_group import WorkflowGroup
|
|
8
|
+
from .workflow_group import WorkflowGroup, WORKFLOW_DEFAULT_VERSION
|
|
8
9
|
from .node import Node
|
|
9
10
|
from .edge import Edge
|
|
10
11
|
from .port import Port, parse_port_name, create_workflow_input_port, create_sub_workflow_input_port
|
|
@@ -13,25 +14,27 @@ from .nodes import *
|
|
|
13
14
|
from .triggers import *
|
|
14
15
|
from .context import Context
|
|
15
16
|
from ..db.database import DatabaseManager
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
17
|
+
from .workflow_config import WorkflowConfig, WorkflowGroupConfig
|
|
18
|
+
|
|
19
|
+
# WORKFLOW_KEY_NAME = 'name'
|
|
20
|
+
# WORKFLOW_KEY_DESCRIPTION = 'description'
|
|
21
|
+
# WORKFLOW_KEY_VERSION = 'version'
|
|
22
|
+
# WORKFLOW_KEY_NODES = 'nodes'
|
|
23
|
+
# WORKFLOW_KEY_INPUTS = 'inputs'
|
|
24
|
+
# WORKFLOW_KEY_OUTPUTS = 'outputs'
|
|
25
|
+
|
|
26
|
+
# NODE_KEY_NAME = 'name'
|
|
27
|
+
# NODE_KEY_TYPE = 'type'
|
|
28
|
+
# NODE_KEY_ARGS = 'args'
|
|
29
|
+
# NODE_KEY_OUTPUTS = 'outputs'
|
|
30
|
+
# # NODE_KEY_INPUT_PORTS = 'input_ports'
|
|
31
|
+
# # NODE_KEY_OUTPUT_PORTS = 'output_ports'
|
|
32
|
+
# NODE_KEY_SUB_WORKFLOWS = 'sub_workflows'
|
|
33
|
+
# NODE_KEY_SUB_WORKFLOWS_INPUT_PORTS = 'sub_workflows_input_ports'
|
|
34
|
+
|
|
35
|
+
# PORT_KEY_NAME = 'name'
|
|
36
|
+
# PORT_KEY_PORT = 'port'
|
|
37
|
+
# PORT_KEY_VALUE = 'value'
|
|
35
38
|
|
|
36
39
|
def parse_argument(arg: Any, service_env: dict[str, Any] = None) -> Any:
|
|
37
40
|
# TODO: support import variables
|
|
@@ -44,30 +47,22 @@ def parse_argument(arg: Any, service_env: dict[str, Any] = None) -> Any:
|
|
|
44
47
|
|
|
45
48
|
def create_workflow(
|
|
46
49
|
config_path: str = None,
|
|
50
|
+
config: WorkflowConfig = None,
|
|
47
51
|
service_env: dict[str, Any] = None,
|
|
48
|
-
config: dict = None,
|
|
49
52
|
workflows: WorkflowGroup = None,
|
|
50
53
|
_handle_stream_output: Callable[[str, AsyncIterator[str]], Awaitable[None]] | None = None,
|
|
51
54
|
_handle_query_user: Callable[[str, str], Awaitable[str]] | None = None,
|
|
52
55
|
database_manager: DatabaseManager = None,
|
|
53
56
|
) -> Workflow:
|
|
54
57
|
if config is None:
|
|
55
|
-
if config_path is None:
|
|
56
|
-
|
|
57
|
-
config = OmegaConf.to_object(OmegaConf.load(config_path))
|
|
58
|
-
|
|
59
|
-
if WORKFLOW_KEY_NAME not in config:
|
|
60
|
-
if config_path is None:
|
|
61
|
-
raise ValueError(f"{WORKFLOW_KEY_NAME} is required in workflow config in {config}.")
|
|
58
|
+
if config_path is not None:
|
|
59
|
+
config = WorkflowConfig.from_yaml_file(config_path)
|
|
62
60
|
else:
|
|
63
|
-
raise ValueError(
|
|
61
|
+
raise ValueError("Either config_path or config must be provided")
|
|
64
62
|
|
|
65
|
-
if WORKFLOW_KEY_DESCRIPTION not in config:
|
|
66
|
-
config[WORKFLOW_KEY_DESCRIPTION] = ""
|
|
67
|
-
|
|
68
63
|
workflow = Workflow(
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
id = uuid.uuid4(),
|
|
65
|
+
config = config,
|
|
71
66
|
nodes = [],
|
|
72
67
|
input_ports = [],
|
|
73
68
|
output_ports = [],
|
|
@@ -76,17 +71,17 @@ def create_workflow(
|
|
|
76
71
|
database_manager = database_manager,
|
|
77
72
|
# TODO: max_concurrent_runs
|
|
78
73
|
callbacks = [BuiltinWorkflowCallback()],
|
|
74
|
+
global_context = Context(variables={}),
|
|
79
75
|
)
|
|
80
76
|
|
|
81
77
|
nodes: dict[str, Node] = {}
|
|
82
78
|
|
|
83
|
-
|
|
84
|
-
for node_config in config[WORKFLOW_KEY_NODES]:
|
|
79
|
+
for node_config in config.nodes:
|
|
85
80
|
params = {
|
|
86
|
-
"name": node_config
|
|
81
|
+
"name": node_config.name,
|
|
87
82
|
}
|
|
88
83
|
|
|
89
|
-
node: Node = node_register.instance(node_config
|
|
84
|
+
node: Node = node_register.instance(node_config.type, ignore_keys=['type'], kwargs=params)
|
|
90
85
|
|
|
91
86
|
# Context
|
|
92
87
|
node.context = Context(variables = {})
|
|
@@ -102,25 +97,25 @@ def create_workflow(
|
|
|
102
97
|
output_port.node = node
|
|
103
98
|
|
|
104
99
|
# Sub workflows
|
|
105
|
-
if
|
|
100
|
+
if node_config.sub_workflows is not None:
|
|
106
101
|
sub_workflows: WorkflowGroup = WorkflowGroup(workflows=[])
|
|
107
|
-
for sub_workflow_config in
|
|
108
|
-
sub_workflow = workflows.
|
|
102
|
+
for sub_workflow_config in node_config.sub_workflows:
|
|
103
|
+
sub_workflow = workflows.get_workflow_by_name(sub_workflow_config.name, sub_workflow_config.version)
|
|
109
104
|
sub_workflows.add_workflow(deepcopy(sub_workflow))
|
|
110
105
|
node.sub_workflows = sub_workflows
|
|
111
106
|
|
|
112
107
|
# Sub workflows input ports
|
|
113
|
-
if
|
|
114
|
-
for sub_workflow_input_port_config in
|
|
115
|
-
name = sub_workflow_input_port_config
|
|
116
|
-
sub_workflow_name, sub_workflow_port_name = parse_port_name(sub_workflow_input_port_config
|
|
117
|
-
sub_workflow = node.sub_workflows.
|
|
108
|
+
if node_config.sub_workflows_input_ports is not None:
|
|
109
|
+
for sub_workflow_input_port_config in node_config.sub_workflows_input_ports:
|
|
110
|
+
name = sub_workflow_input_port_config.name
|
|
111
|
+
sub_workflow_name, sub_workflow_port_name = parse_port_name(sub_workflow_input_port_config.port)
|
|
112
|
+
sub_workflow = node.sub_workflows.get_workflow_by_name(sub_workflow_name, sub_workflow_config.version)
|
|
118
113
|
if sub_workflow is None:
|
|
119
114
|
raise ValueError(f"{sub_workflow_name} is not a valid sub workflow.")
|
|
120
115
|
sub_workflow_port = sub_workflow.get_input_port_by_name(sub_workflow_port_name)
|
|
121
116
|
if sub_workflow_port is None:
|
|
122
117
|
raise ValueError(f"{sub_workflow_port_name} is not a valid input port.")
|
|
123
|
-
value = sub_workflow_input_port_config.
|
|
118
|
+
value = sub_workflow_input_port_config.value
|
|
124
119
|
node.input_ports.append(create_sub_workflow_input_port(name=name, node=node, port=sub_workflow_port, value=value))
|
|
125
120
|
|
|
126
121
|
# Sub workflows output ports
|
|
@@ -132,13 +127,13 @@ def create_workflow(
|
|
|
132
127
|
else:
|
|
133
128
|
node.query_user = _handle_query_user
|
|
134
129
|
|
|
135
|
-
nodes[node_config
|
|
130
|
+
nodes[node_config.name] = node
|
|
136
131
|
|
|
137
132
|
# Edges
|
|
138
|
-
for node_config in config
|
|
139
|
-
start_node = nodes[node_config
|
|
140
|
-
if
|
|
141
|
-
for key, value in node_config
|
|
133
|
+
for node_config in config.nodes:
|
|
134
|
+
start_node = nodes[node_config.name]
|
|
135
|
+
if node_config.outputs is not None:
|
|
136
|
+
for key, value in node_config.outputs.items():
|
|
142
137
|
if value is None:
|
|
143
138
|
continue
|
|
144
139
|
|
|
@@ -168,24 +163,24 @@ def create_workflow(
|
|
|
168
163
|
workflow.add_nodes(list(nodes.values()))
|
|
169
164
|
|
|
170
165
|
# Inputs
|
|
171
|
-
if
|
|
172
|
-
for port_config in
|
|
173
|
-
name = port_config
|
|
174
|
-
node_name, node_port_name = parse_port_name(port_config
|
|
166
|
+
if config.inputs is not None:
|
|
167
|
+
for port_config in config.inputs:
|
|
168
|
+
name = port_config.name
|
|
169
|
+
node_name, node_port_name = parse_port_name(port_config.port)
|
|
175
170
|
if node_name not in nodes:
|
|
176
171
|
raise ValueError(f"{node_name} is not a valid node.")
|
|
177
172
|
node = nodes[node_name]
|
|
178
173
|
port = node.get_input_port_by_name(node_port_name)
|
|
179
174
|
if port is None:
|
|
180
175
|
raise ValueError(f"{node_port_name} is not a valid input port.")
|
|
181
|
-
value = port_config.
|
|
176
|
+
value = port_config.value
|
|
182
177
|
workflow.input_ports.append(create_workflow_input_port(name=name, port=port, value=value))
|
|
183
178
|
|
|
184
179
|
# Outputs
|
|
185
|
-
if
|
|
186
|
-
for port_config in
|
|
187
|
-
name = port_config
|
|
188
|
-
node_name, node_port_name = parse_port_name(port_config
|
|
180
|
+
if config.outputs is not None:
|
|
181
|
+
for port_config in config.outputs:
|
|
182
|
+
name = port_config.name
|
|
183
|
+
node_name, node_port_name = parse_port_name(port_config.port)
|
|
189
184
|
if node_name not in nodes:
|
|
190
185
|
raise ValueError(f"{node_name} is not a valid node.")
|
|
191
186
|
node = nodes[node_name]
|
|
@@ -197,32 +192,34 @@ def create_workflow(
|
|
|
197
192
|
edge = Edge(node, None, port, output_port)
|
|
198
193
|
node.output_edges.append(edge)
|
|
199
194
|
|
|
200
|
-
for node_config in config
|
|
201
|
-
node = nodes[node_config
|
|
195
|
+
for node_config in config.nodes:
|
|
196
|
+
node = nodes[node_config.name]
|
|
202
197
|
# Arguments
|
|
203
|
-
if
|
|
204
|
-
for key, value in
|
|
198
|
+
if node_config.args is not None:
|
|
199
|
+
for key, value in node_config.args.items():
|
|
205
200
|
node.fill_input_by_name(key, parse_argument(value, service_env=service_env))
|
|
206
201
|
|
|
207
202
|
return workflow
|
|
208
203
|
|
|
209
|
-
def
|
|
204
|
+
def create_workflow_group(
|
|
210
205
|
config_path: str = None,
|
|
206
|
+
config: WorkflowConfig | WorkflowGroupConfig = None,
|
|
211
207
|
service_env: dict[str, Any] = None,
|
|
212
|
-
config: dict = None,
|
|
213
208
|
_handle_stream_output: Callable[[str, AsyncIterator[str]], Awaitable[None]] = None,
|
|
214
209
|
_handle_query_user: Callable[[str, str], Awaitable[str]] = None,
|
|
215
210
|
database_manager: DatabaseManager = None,
|
|
216
211
|
) -> WorkflowGroup:
|
|
217
|
-
WORKFLOW_KEY_WORKFLOWS = 'workflows'
|
|
218
|
-
WORKFLOW_KEY_MAIN_WORKFLOW_NAME = 'main'
|
|
219
212
|
|
|
220
213
|
if config is None:
|
|
221
|
-
if config_path is None:
|
|
214
|
+
if config_path is not None:
|
|
215
|
+
try:
|
|
216
|
+
config = WorkflowGroupConfig.from_yaml_file(config_path)
|
|
217
|
+
except:
|
|
218
|
+
config = WorkflowConfig.from_yaml_file(config_path)
|
|
219
|
+
else:
|
|
222
220
|
raise ValueError("Either config_path or config must be provided")
|
|
223
|
-
config = OmegaConf.to_object(OmegaConf.load(config_path))
|
|
224
221
|
|
|
225
|
-
if
|
|
222
|
+
if type(config) == WorkflowConfig:
|
|
226
223
|
workflow = create_workflow(
|
|
227
224
|
config_path=config_path if config_path else None,
|
|
228
225
|
config=config,
|
|
@@ -231,16 +228,20 @@ def create_workflows(
|
|
|
231
228
|
_handle_query_user=_handle_query_user,
|
|
232
229
|
database_manager=database_manager,
|
|
233
230
|
)
|
|
234
|
-
return WorkflowGroup(workflows=[workflow], main_workflow_name=workflow.name)
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
config
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
231
|
+
return WorkflowGroup(workflows=[workflow], main_workflow_name=workflow.name, main_workflow_version=workflow.version)
|
|
232
|
+
elif type(config) == WorkflowGroupConfig:
|
|
233
|
+
workflows = WorkflowGroup(
|
|
234
|
+
workflows=[],
|
|
235
|
+
main_workflow_name=config.main_workflow_name,
|
|
236
|
+
main_workflow_version=config.main_workflow_version,
|
|
237
|
+
)
|
|
238
|
+
for workflow_config in config.workflows:
|
|
239
|
+
workflows.add_workflow(create_workflow(
|
|
240
|
+
config=workflow_config,
|
|
241
|
+
workflows=workflows,
|
|
242
|
+
service_env=service_env,
|
|
243
|
+
_handle_stream_output=_handle_stream_output,
|
|
244
|
+
_handle_query_user=_handle_query_user,
|
|
245
|
+
database_manager=database_manager,
|
|
246
|
+
))
|
|
247
|
+
return workflows
|
|
@@ -1,27 +1,51 @@
|
|
|
1
|
+
import uuid
|
|
1
2
|
from service_forge.workflow.workflow import Workflow
|
|
2
3
|
|
|
4
|
+
WORKFLOW_DEFAULT_VERSION = "0"
|
|
5
|
+
WORKFLOW_MAIN_WORKFLOW_NAME = "main"
|
|
6
|
+
|
|
3
7
|
class WorkflowGroup:
|
|
4
|
-
def __init__(
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
workflows: list[Workflow],
|
|
11
|
+
main_workflow_name: str = WORKFLOW_MAIN_WORKFLOW_NAME,
|
|
12
|
+
main_workflow_version: str = WORKFLOW_DEFAULT_VERSION,
|
|
13
|
+
) -> None:
|
|
5
14
|
self.workflows = workflows
|
|
6
15
|
self.main_workflow_name = main_workflow_name
|
|
16
|
+
self.main_workflow_version = main_workflow_version
|
|
7
17
|
|
|
8
18
|
def add_workflow(self, workflow: Workflow) -> None:
|
|
9
19
|
self.workflows.append(workflow)
|
|
10
20
|
|
|
11
|
-
def
|
|
21
|
+
def get_workflow_by_name(self, name: str, version: str) -> Workflow | None:
|
|
22
|
+
for workflow in self.workflows:
|
|
23
|
+
if workflow.name == name and workflow.version == version:
|
|
24
|
+
return workflow
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
def get_workflow_by_id(self, id: uuid.UUID) -> Workflow | None:
|
|
12
28
|
for workflow in self.workflows:
|
|
13
|
-
|
|
29
|
+
print(workflow.name, workflow.id, id)
|
|
30
|
+
if workflow.id == id:
|
|
14
31
|
return workflow
|
|
15
32
|
return None
|
|
16
33
|
|
|
17
|
-
def get_main_workflow(self) -> Workflow:
|
|
18
|
-
|
|
34
|
+
def get_main_workflow(self, allow_none: bool = True) -> Workflow | None:
|
|
35
|
+
workflow = self.get_workflow_by_name(self.main_workflow_name, self.main_workflow_version)
|
|
36
|
+
if not allow_none and workflow is None:
|
|
37
|
+
raise ValueError(f"Main workflow with name {self.main_workflow_name} and version {self.main_workflow_version} not found in workflow group.")
|
|
38
|
+
return workflow
|
|
19
39
|
|
|
20
|
-
async def run(self, name: str = None) -> None:
|
|
21
|
-
if name is None:
|
|
40
|
+
async def run(self, name: str = None, version: str = None, id: uuid.UUID = None) -> None:
|
|
41
|
+
if name is None and id is None:
|
|
22
42
|
workflow = self.get_main_workflow()
|
|
43
|
+
elif name is not None:
|
|
44
|
+
workflow = self.get_workflow_by_name(name, version)
|
|
45
|
+
elif id is not None:
|
|
46
|
+
workflow = self.get_workflow_by_id(id)
|
|
23
47
|
else:
|
|
24
|
-
workflow =
|
|
48
|
+
workflow = None
|
|
25
49
|
if workflow is None:
|
|
26
|
-
raise ValueError(f"Workflow with name {name} not found in workflow group.")
|
|
50
|
+
raise ValueError(f"Workflow with name {name} and version {version} and id {id} not found in workflow group.")
|
|
27
51
|
await workflow.run()
|
|
@@ -1,32 +1,39 @@
|
|
|
1
|
-
service_forge/
|
|
2
|
-
service_forge/
|
|
1
|
+
service_forge/current_service.py,sha256=0YKm7nQiXzUUAc1ToCcbG1QPJfOSNKcOHUpyJ4E3xrY,342
|
|
2
|
+
service_forge/service.py,sha256=rZZ7-BXTTCrc6KqnONnKpg-bRs5JCfDTvMrl4K26vbE,12633
|
|
3
|
+
service_forge/service_config.py,sha256=zsTdCZ1peMAotjGEVypPos7d-gjwrYoB9x_12g95G4g,1242
|
|
3
4
|
service_forge/api/deprecated_websocket_api.py,sha256=E36-fpUPxzMJ2YGlCPeqwRbryk2FMMbQD_pbb8k1FYI,3343
|
|
4
5
|
service_forge/api/deprecated_websocket_manager.py,sha256=Xiwg3zwXRVi63sXmVH-TgbpL2XH_djyLeo96STm4cNM,16757
|
|
5
|
-
service_forge/api/http_api.py,sha256=
|
|
6
|
+
service_forge/api/http_api.py,sha256=XnEQ45zuWQV1zrSL9vd3USUh47ymkVc4w_1SoFlNdl8,5648
|
|
6
7
|
service_forge/api/http_api_doc.py,sha256=ASlxvsIiUzDcMhVoumRjt9CfEMbh0O1U4ZLC9eobLF8,20235
|
|
7
8
|
service_forge/api/kafka_api.py,sha256=PInx2ZzKJRON7EaJFWroXkiOt_UeZY7WE6qK03gq4ak,4599
|
|
8
9
|
service_forge/api/task_manager.py,sha256=9Lk-NV4cBnuv9b8V6GVLWJJ4MCiAwCp5TVAwmYgqXbs,5269
|
|
9
|
-
service_forge/api/routers/
|
|
10
|
-
service_forge/api/routers/service/service_router.py,sha256=
|
|
10
|
+
service_forge/api/routers/feedback/feedback_router.py,sha256=JOJI6kaQYapg4__iA6Eo26_9su48p7R2Kpn422nbsxw,5640
|
|
11
|
+
service_forge/api/routers/service/service_router.py,sha256=hGOT-ScnXR7agHp-F9OFGWiPFjG9f3gl7NBsnayW3JI,5088
|
|
11
12
|
service_forge/api/routers/websocket/websocket_manager.py,sha256=j1AFqzXQhZZyaLQwhvZefXAS-zCOPzLcRMDEuusv6V0,3605
|
|
12
13
|
service_forge/api/routers/websocket/websocket_router.py,sha256=V0B7eQP8toO94-WbTrGraadXD3qeZ9lnKFcxwx6kLgM,3777
|
|
13
14
|
service_forge/db/__init__.py,sha256=EWLhH8bYsMOvRF_YXF6FgL3irKA6GZeLxSGvWDRM6f8,85
|
|
14
|
-
service_forge/db/database.py,sha256=
|
|
15
|
-
service_forge/
|
|
15
|
+
service_forge/db/database.py,sha256=WKtZ0MoOnbMw54ohfs9zKsrOZ5_qenLvXkAV_Gr2WOs,10068
|
|
16
|
+
service_forge/db/migrations/feedback_migration.py,sha256=-zQ71TsOlWmQPQo1NKSIu3C1T47v3cfD6IAQ5HE_ffk,4845
|
|
17
|
+
service_forge/db/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
service_forge/db/models/feedback.py,sha256=gltX3y-nNhXSR9z1cd82Vg-zwjF0JhnGbOvUapkcWKQ,1253
|
|
19
|
+
service_forge/llm/__init__.py,sha256=x8--4XWqhCVR5n7U3iMvrL16mv-Altb_JgF4qdxSOGk,3170
|
|
16
20
|
service_forge/llm/llm.py,sha256=Sar99FkTPBJqkB6dwX81ww_hJp8cPYxlg7Go-zXPyg0,1865
|
|
17
21
|
service_forge/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
service_forge/model/feedback.py,sha256=Is5tkplzYkjChGb67o-Qjtbu4kSspVuaKi4Aua_QdRo,1318
|
|
18
23
|
service_forge/model/websocket.py,sha256=YIUCW32sbHIEFPHjk5FiDM_rDe2aVD6OpzBQul2R5IM,267
|
|
19
24
|
service_forge/proto/foo_input.py,sha256=-POJZSIFrGdBGz7FqZZ03r5uztpc5Apin9A0Yxbk6YI,90
|
|
20
|
-
service_forge/sft/cli.py,sha256=
|
|
25
|
+
service_forge/sft/cli.py,sha256=xcM6kiGPJeHEUqfJd4uFngVFpjfVkDxW4G_PbNRD9Xs,4265
|
|
21
26
|
service_forge/sft/cmd/config_command.py,sha256=I9t2HG28S6lCXpExHyZUc47b_1yB3i51tCFVk5J6TTU,2382
|
|
22
27
|
service_forge/sft/cmd/deploy_service.py,sha256=5IYbCVI0Nlry1KXBhm9leJmr2bzUEXrSY-2BympLR0c,4686
|
|
23
28
|
service_forge/sft/cmd/list_tars.py,sha256=Z3zvu2JLb_wNbTwi5TZXL5cZ8PxYrKks9AxkOzoUd_Q,1380
|
|
29
|
+
service_forge/sft/cmd/remote_deploy.py,sha256=AStAlbqGD7XeZFhL0fx2j12YWP_MVbdURbO5ZENEMgc,6510
|
|
30
|
+
service_forge/sft/cmd/remote_list_tars.py,sha256=mx6hkNnu0ySMyBX2Qi6blKMj5xnNnrmXq3VD_nERlmw,4176
|
|
24
31
|
service_forge/sft/cmd/service_command.py,sha256=69GMMN61KtuoEFuYzFJ74ivNt8RX8q0I6rbePfJfEwQ,5538
|
|
25
32
|
service_forge/sft/cmd/upload_service.py,sha256=86PvvJSXCZKH4BU6rLytuc45grX-sRnQnOHCo9zUaPY,1232
|
|
26
|
-
service_forge/sft/config/injector.py,sha256
|
|
27
|
-
service_forge/sft/config/injector_default_files.py,sha256=
|
|
33
|
+
service_forge/sft/config/injector.py,sha256=-eU21Ob09ond9pwHVkjklAd5_qLWWbbf0b91iCg2Kwk,6335
|
|
34
|
+
service_forge/sft/config/injector_default_files.py,sha256=f7mNJ5Y9yb4e9kjLn414WiQoZrOue9ok_hq_POG4I2o,2717
|
|
28
35
|
service_forge/sft/config/sf_metadata.py,sha256=Y9akhSCgOd11-oqRs3LIs8FL9pvWNw6hyy57fuFcBhc,866
|
|
29
|
-
service_forge/sft/config/sft_config.py,sha256
|
|
36
|
+
service_forge/sft/config/sft_config.py,sha256=MgurtgbcSmyXbGlVX3NG84KD4Hst1gZWHdF9a8zi-6U,7707
|
|
30
37
|
service_forge/sft/file/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
38
|
service_forge/sft/file/ignore_pattern.py,sha256=UrVmR83wOx51XHFcZDTPp15dGYcvMTE5W1m07-SvHpw,2521
|
|
32
39
|
service_forge/sft/file/sft_file_manager.py,sha256=poIM77tZZg7vfwBdCsdQctBbCczVLQePdTwVINEABvE,4337
|
|
@@ -35,41 +42,44 @@ service_forge/sft/util/assert_util.py,sha256=8HreVkOzs9_ClKiFqG4qsFn_yyDLo5uXYhY
|
|
|
35
42
|
service_forge/sft/util/logger.py,sha256=0Hi74IoxshE-wBgvBa2EZPXYj37tTrUYwlOBd9UMMMs,502
|
|
36
43
|
service_forge/sft/util/name_util.py,sha256=WSYHM6c7SZULXCFON7nmGqsvAPPs_wavd6QjCa4UbRQ,301
|
|
37
44
|
service_forge/sft/util/yaml_utils.py,sha256=9OhJNQlzj_C1NeQoUZVF8qpDovrE7RDWtNXe-H7tuNA,1703
|
|
45
|
+
service_forge/storage/__init__.py,sha256=8Jg4R9z2JHadheV1YrHtCsFxEL5aCl9n2dMQGHcJfvM,156
|
|
46
|
+
service_forge/storage/feedback_storage.py,sha256=wnuNTmEzpnS7iisiU9MrEJIgVa2G_HysqICWk_PxzfU,9124
|
|
38
47
|
service_forge/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
-
service_forge/utils/default_type_converter.py,sha256=
|
|
48
|
+
service_forge/utils/default_type_converter.py,sha256=KFWhlZJUrQc2e-Wm9-WfPUKp5UaI-fpVjzNLO6n37e8,625
|
|
40
49
|
service_forge/utils/register.py,sha256=nxiGQBCX238FoZZhsDoDdBMv_2QzeIZpM367HPNfaqM,874
|
|
41
|
-
service_forge/utils/type_converter.py,sha256=
|
|
42
|
-
service_forge/utils/workflow_clone.py,sha256=
|
|
50
|
+
service_forge/utils/type_converter.py,sha256=eGAAnqEr-va1PBwYOzuzzzExVJNtusn-yGRv7i9WjRY,3204
|
|
51
|
+
service_forge/utils/workflow_clone.py,sha256=K2Y4XXsGYQn4OTKcDYEa7UZHGXta_hztKW-pr4EYaDQ,4593
|
|
43
52
|
service_forge/workflow/__init__.py,sha256=9oh4qPyA33RugrUYRAlLmFtmQPUN2wxruFQE3omTJF8,49
|
|
44
53
|
service_forge/workflow/context.py,sha256=1PotSEN_l8Emd5p8_6mtXJngXGYd3NSbOs1EKHgvnlo,346
|
|
45
54
|
service_forge/workflow/edge.py,sha256=88Ex-9_dHAGD38OHgiqP0DrfxK0FrhvDAxThR3ilUi4,627
|
|
46
|
-
service_forge/workflow/node.py,sha256=
|
|
55
|
+
service_forge/workflow/node.py,sha256=hoO8TdfbB5inpu55YCwecnasi4RS-Bg9R8Sp-M5c2Ys,7841
|
|
47
56
|
service_forge/workflow/port.py,sha256=JVj0JrnQeOWCsp7n48Cm03bfmO8r3V5oTSEsC-HTGPE,2967
|
|
48
|
-
service_forge/workflow/trigger.py,sha256=
|
|
49
|
-
service_forge/workflow/workflow.py,sha256=
|
|
50
|
-
service_forge/workflow/workflow_callback.py,sha256=
|
|
57
|
+
service_forge/workflow/trigger.py,sha256=2OqiHi0dFcoC8g5GDqVpVEpHKlmqtDADb74Z7PRzHlo,879
|
|
58
|
+
service_forge/workflow/workflow.py,sha256=YsA_Yeh5XjYQflztqKWoWBt9euEoHVOJMGMTquIoO04,9788
|
|
59
|
+
service_forge/workflow/workflow_callback.py,sha256=MJBG_DTQGCgqCjpnBhuSteZmOxitYRdtkxXlFCOh930,5219
|
|
60
|
+
service_forge/workflow/workflow_config.py,sha256=Yih10b-utKIpaR-X-nfy7fPnmBNhRvlD8Bw2_mQ5lJI,1821
|
|
51
61
|
service_forge/workflow/workflow_event.py,sha256=QG1VFJwUUF1bTKKPKvqBICnYxkBwpfYDEoAuxwQYhhE,371
|
|
52
|
-
service_forge/workflow/workflow_factory.py,sha256=
|
|
53
|
-
service_forge/workflow/workflow_group.py,sha256=
|
|
62
|
+
service_forge/workflow/workflow_factory.py,sha256=KfIxjdQhsRC0KYrEkAhqlx3oY6tABoulQGhBwBBXLq0,9933
|
|
63
|
+
service_forge/workflow/workflow_group.py,sha256=c-Hcfb-nVKxCVddoEQNFV6nY4LVAku0iq7tTUef9fDM,2076
|
|
54
64
|
service_forge/workflow/workflow_type.py,sha256=zRc-gL2LBE-gOgTUCU5-VDWeGUzuQahkHIg98ipEvQg,1629
|
|
55
65
|
service_forge/workflow/nodes/__init__.py,sha256=AUOoFUAMgRwfLiHNkjnDnWToMSe2AeV5vJO3NCG1eLw,381
|
|
56
66
|
service_forge/workflow/nodes/control/if_node.py,sha256=fBRnSsz0SHW5Hcf4993Y1PsUOUt2Cg9I_zcduHUnMuI,643
|
|
57
67
|
service_forge/workflow/nodes/control/switch_node.py,sha256=27mxdcQijSawNM5Fx6LdC1MB66vAoLAAI74DQyfqPqI,708
|
|
58
68
|
service_forge/workflow/nodes/input/console_input_node.py,sha256=GhQjWRgYy3aRfYUfaEql-_Xi10cca75oz-vmSZkR54w,683
|
|
59
|
-
service_forge/workflow/nodes/llm/query_llm_node.py,sha256=
|
|
69
|
+
service_forge/workflow/nodes/llm/query_llm_node.py,sha256=rFSHsPsW2V-yhHSmjx60DcokKy5fdGhNNbt8GIgEIbk,1143
|
|
60
70
|
service_forge/workflow/nodes/nested/workflow_node.py,sha256=h5NXhRCUGaoNmqMV2PXR6JNwTCM8MCRVA6ocOjoDzhs,747
|
|
61
71
|
service_forge/workflow/nodes/output/kafka_output_node.py,sha256=mC6qRMGsuwU6qXAfXA-0ZFZudrlwmgRYOJRULUrtH40,682
|
|
62
72
|
service_forge/workflow/nodes/output/print_node.py,sha256=OSgeRQOd3dq88a1plx30g9-VB793RbXnIa5X8MF9fCo,656
|
|
63
73
|
service_forge/workflow/nodes/test/if_console_input_node.py,sha256=CtKHkFqr8PN974_iGP2VSBmNpXZ-KumRHCpoRR5RyF8,956
|
|
64
74
|
service_forge/workflow/nodes/test/time_consuming_node.py,sha256=gB2qw2DdjRf82z1158u36nSnCHrheHaxscAzPRnXNyk,1813
|
|
65
75
|
service_forge/workflow/triggers/__init__.py,sha256=iQ0WEYu6JgL191Y9XslMhZ7jS7JO8bL3SZ9YqIw5LCM,269
|
|
66
|
-
service_forge/workflow/triggers/a2a_api_trigger.py,sha256=
|
|
67
|
-
service_forge/workflow/triggers/fast_api_trigger.py,sha256=
|
|
68
|
-
service_forge/workflow/triggers/kafka_api_trigger.py,sha256=
|
|
69
|
-
service_forge/workflow/triggers/once_trigger.py,sha256=
|
|
70
|
-
service_forge/workflow/triggers/period_trigger.py,sha256=
|
|
71
|
-
service_forge/workflow/triggers/websocket_api_trigger.py,sha256=
|
|
72
|
-
service_forge-0.1.
|
|
73
|
-
service_forge-0.1.
|
|
74
|
-
service_forge-0.1.
|
|
75
|
-
service_forge-0.1.
|
|
76
|
+
service_forge/workflow/triggers/a2a_api_trigger.py,sha256=Oaw3vRLA8fWZUIQ-h33dYmojmjp4mwNF_0LHqQ_4mZQ,8583
|
|
77
|
+
service_forge/workflow/triggers/fast_api_trigger.py,sha256=8BF0A8gdcKeiP3cyF_dF0T3MH7bXnnZRCa_h5hx9kQ4,7513
|
|
78
|
+
service_forge/workflow/triggers/kafka_api_trigger.py,sha256=Zv8J75Rmg1-xqxHwpBMBhsm_TWX8p3_rqldk2RVSwVc,1561
|
|
79
|
+
service_forge/workflow/triggers/once_trigger.py,sha256=YmzSQBoKE-8liNFIoDCqi2UdqhHujizsXVDft81_8jA,572
|
|
80
|
+
service_forge/workflow/triggers/period_trigger.py,sha256=JFX3yBjKqoRP55jiulaSG_SPO-zWLMcwEb1BwcKsWUM,767
|
|
81
|
+
service_forge/workflow/triggers/websocket_api_trigger.py,sha256=JjRYb0VM_em90_w3QEErgxMDBCaBHCrSBhTaV4Fl4HY,6894
|
|
82
|
+
service_forge-0.1.24.dist-info/METADATA,sha256=tOQocyV5Smmw3sdoR6k-0MBwB-C0eaMGlG2hRDGj4AY,2308
|
|
83
|
+
service_forge-0.1.24.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
84
|
+
service_forge-0.1.24.dist-info/entry_points.txt,sha256=WHntHW7GAyKQUEeMcMvHDZ7_xAb0-cZeAK4iJeu9lm8,51
|
|
85
|
+
service_forge-0.1.24.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|