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.

Files changed (42) hide show
  1. service_forge/api/http_api.py +4 -0
  2. service_forge/api/routers/feedback/feedback_router.py +148 -0
  3. service_forge/api/routers/service/service_router.py +22 -32
  4. service_forge/current_service.py +14 -0
  5. service_forge/db/database.py +46 -32
  6. service_forge/db/migrations/feedback_migration.py +154 -0
  7. service_forge/db/models/__init__.py +0 -0
  8. service_forge/db/models/feedback.py +33 -0
  9. service_forge/llm/__init__.py +5 -0
  10. service_forge/model/feedback.py +30 -0
  11. service_forge/service.py +118 -126
  12. service_forge/service_config.py +42 -156
  13. service_forge/sft/cli.py +39 -0
  14. service_forge/sft/cmd/remote_deploy.py +160 -0
  15. service_forge/sft/cmd/remote_list_tars.py +111 -0
  16. service_forge/sft/config/injector.py +46 -24
  17. service_forge/sft/config/injector_default_files.py +1 -1
  18. service_forge/sft/config/sft_config.py +55 -8
  19. service_forge/storage/__init__.py +5 -0
  20. service_forge/storage/feedback_storage.py +245 -0
  21. service_forge/utils/default_type_converter.py +1 -1
  22. service_forge/utils/type_converter.py +5 -0
  23. service_forge/utils/workflow_clone.py +3 -2
  24. service_forge/workflow/node.py +8 -0
  25. service_forge/workflow/nodes/llm/query_llm_node.py +1 -1
  26. service_forge/workflow/trigger.py +4 -0
  27. service_forge/workflow/triggers/a2a_api_trigger.py +2 -0
  28. service_forge/workflow/triggers/fast_api_trigger.py +32 -0
  29. service_forge/workflow/triggers/kafka_api_trigger.py +3 -0
  30. service_forge/workflow/triggers/once_trigger.py +4 -1
  31. service_forge/workflow/triggers/period_trigger.py +4 -1
  32. service_forge/workflow/triggers/websocket_api_trigger.py +15 -11
  33. service_forge/workflow/workflow.py +74 -31
  34. service_forge/workflow/workflow_callback.py +3 -2
  35. service_forge/workflow/workflow_config.py +66 -0
  36. service_forge/workflow/workflow_factory.py +86 -85
  37. service_forge/workflow/workflow_group.py +33 -9
  38. {service_forge-0.1.11.dist-info → service_forge-0.1.24.dist-info}/METADATA +1 -1
  39. {service_forge-0.1.11.dist-info → service_forge-0.1.24.dist-info}/RECORD +41 -31
  40. service_forge/api/routers/service/__init__.py +0 -4
  41. {service_forge-0.1.11.dist-info → service_forge-0.1.24.dist-info}/WHEEL +0 -0
  42. {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
- WORKFLOW_KEY_NAME = 'name'
18
- WORKFLOW_KEY_DESCRIPTION = 'description'
19
- WORKFLOW_KEY_NODES = 'nodes'
20
- WORKFLOW_KEY_INPUTS = 'inputs'
21
- WORKFLOW_KEY_OUTPUTS = 'outputs'
22
-
23
- NODE_KEY_NAME = 'name'
24
- NODE_KEY_TYPE = 'type'
25
- NODE_KEY_ARGS = 'args'
26
- NODE_KEY_OUTPUTS = 'outputs'
27
- # NODE_KEY_INPUT_PORTS = 'input_ports'
28
- # NODE_KEY_OUTPUT_PORTS = 'output_ports'
29
- NODE_KEY_SUB_WORKFLOWS = 'sub_workflows'
30
- NODE_KEY_SUB_WORKFLOWS_INPUT_PORTS = 'sub_workflows_input_ports'
31
-
32
- PORT_KEY_NAME = 'name'
33
- PORT_KEY_PORT = 'port'
34
- PORT_KEY_VALUE = 'value'
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
- raise ValueError("Either config_path or config must be provided")
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(f"{WORKFLOW_KEY_NAME} is required in workflow config at {config_path}.")
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
- name = config[WORKFLOW_KEY_NAME],
70
- description = config[WORKFLOW_KEY_DESCRIPTION],
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
- # Nodes
84
- for node_config in config[WORKFLOW_KEY_NODES]:
79
+ for node_config in config.nodes:
85
80
  params = {
86
- "name": node_config[NODE_KEY_NAME],
81
+ "name": node_config.name,
87
82
  }
88
83
 
89
- node: Node = node_register.instance(node_config[NODE_KEY_TYPE], ignore_keys=['type'], kwargs=params)
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 node_key_sub_workflows := node_config.get(NODE_KEY_SUB_WORKFLOWS, None):
100
+ if node_config.sub_workflows is not None:
106
101
  sub_workflows: WorkflowGroup = WorkflowGroup(workflows=[])
107
- for sub_workflow_config in node_key_sub_workflows:
108
- sub_workflow = workflows.get_workflow(sub_workflow_config['name'])
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 node_key_sub_network_input_ports := node_config.get(NODE_KEY_SUB_WORKFLOWS_INPUT_PORTS, None):
114
- for sub_workflow_input_port_config in node_key_sub_network_input_ports:
115
- name = sub_workflow_input_port_config[PORT_KEY_NAME]
116
- sub_workflow_name, sub_workflow_port_name = parse_port_name(sub_workflow_input_port_config[PORT_KEY_PORT])
117
- sub_workflow = node.sub_workflows.get_workflow(sub_workflow_name)
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.get(PORT_KEY_VALUE, None)
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[NODE_KEY_NAME]] = node
130
+ nodes[node_config.name] = node
136
131
 
137
132
  # Edges
138
- for node_config in config[WORKFLOW_KEY_NODES]:
139
- start_node = nodes[node_config[NODE_KEY_NAME]]
140
- if NODE_KEY_OUTPUTS in node_config and node_config[NODE_KEY_OUTPUTS]:
141
- for key, value in node_config[NODE_KEY_OUTPUTS].items():
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 workflow_key_inputs := config.get(WORKFLOW_KEY_INPUTS, None):
172
- for port_config in workflow_key_inputs:
173
- name = port_config[PORT_KEY_NAME]
174
- node_name, node_port_name = parse_port_name(port_config[PORT_KEY_PORT])
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.get(PORT_KEY_VALUE, None)
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 workflow_key_outputs := config.get(WORKFLOW_KEY_OUTPUTS, None):
186
- for port_config in workflow_key_outputs:
187
- name = port_config[PORT_KEY_NAME]
188
- node_name, node_port_name = parse_port_name(port_config[PORT_KEY_PORT])
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[WORKFLOW_KEY_NODES]:
201
- node = nodes[node_config[NODE_KEY_NAME]]
195
+ for node_config in config.nodes:
196
+ node = nodes[node_config.name]
202
197
  # Arguments
203
- if node_key_args := node_config.get(NODE_KEY_ARGS, None):
204
- for key, value in node_key_args.items():
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 create_workflows(
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 WORKFLOW_KEY_WORKFLOWS not in config:
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
- workflows = WorkflowGroup(workflows=[], main_workflow_name=config.get(WORKFLOW_KEY_MAIN_WORKFLOW_NAME, None))
237
- for workflow_config in config[WORKFLOW_KEY_WORKFLOWS]:
238
- workflows.add_workflow(create_workflow(
239
- config=workflow_config,
240
- workflows=workflows,
241
- service_env=service_env,
242
- _handle_stream_output=_handle_stream_output,
243
- _handle_query_user=_handle_query_user,
244
- database_manager=database_manager,
245
- ))
246
- return workflows
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__(self, workflows: list[Workflow], main_workflow_name: str = "main") -> None:
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 get_workflow(self, name: str) -> Workflow | None:
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
- if workflow.name == name:
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
- return self.get_workflow(self.main_workflow_name)
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 = self.get_workflow(name)
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: service-forge
3
- Version: 0.1.11
3
+ Version: 0.1.24
4
4
  Summary: Add your description here
5
5
  Author-email: euxcet <zcc.qwer@gmail.com>
6
6
  Requires-Python: >=3.11
@@ -1,32 +1,39 @@
1
- service_forge/service.py,sha256=D4lrpCrohUaG1lM2YdN1sfDVU_7EU1E01zonbZyktnk,12288
2
- service_forge/service_config.py,sha256=3r0uQeysCcAuiotQcs8zUhfNrKk1Aky2zIasbyGQLlc,5003
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=RePGdIpxxWj3ZDMgbxa7-tpCFuMmtgRefUpZXo6TBD0,5488
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/service/__init__.py,sha256=hnoXBAxOzqCxtDHwoFNd6F1Yg6oGR3EHZhzrwjg1Dq4,130
10
- service_forge/api/routers/service/service_router.py,sha256=E6mPMVx6dOn515h1m125n--fmAjb1z5ZatZDYjp7iNQ,5381
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=JrfBjvLZT7Op-rSqbRJgNDikVGVasQCmx3mzg_HtIxA,9850
15
- service_forge/llm/__init__.py,sha256=9sB5uqp2F8AboYV4jAvOQfMkVMWM811sUxBahJJ-_fE,2868
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=stB_YPhZ7gAQeOxIq03-tLyl5VfU-gnRacAT05GSMis,2904
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=T2MgQvrle6yDDDSFH8vQm6Yh_LbH-9C4nxAUA7QLrq8,5269
27
- service_forge/sft/config/injector_default_files.py,sha256=aTMQ2Tla3wdpvdaD_5VP2X6oeZbI0X414FM9NbirnO4,2716
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=-Wmsl0b2SE97yyWnPdv8SKyorV3Yc-DbGeOPU4fTIDY,5346
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=CuUZpMATdTwgcV1M3lbK64znwmEG85Zt3y_QGXr9tYQ,625
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=IRphYxyGA0ICwFvDMvqAnRnSUTpY2ZQXvTE5o99CKpo,3046
42
- service_forge/utils/workflow_clone.py,sha256=rajbRrEuSkxATWn1-jZiYn_S9OypGMKUSpXayl7n0cM,4563
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=jPzXuixmZBL6-_jjXikFZmierlu3SOBJOSdQxTyV0FY,7536
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=1XYY-zk_3ei53lA8UfBw6IQGfLkQDrSY4rhVrfhHEWA,796
49
- service_forge/workflow/workflow.py,sha256=KzfPhbJLkoIb6wBQLTPthVjJ5lYXaMF2QhmA3rb7PTk,7939
50
- service_forge/workflow/workflow_callback.py,sha256=S__F7s-7l5LgkIXcZMcG68qCyc8NgdWQX81F0hKWL1U,5135
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=ecaOI26KHdm2ho-niZcEnZpLacb3kML-6Pb4i9cDK1A,10202
53
- service_forge/workflow/workflow_group.py,sha256=ZZJpK92JyKjrLflNY0MRis1WUcB4Pkgde-UxWZW-IiY,977
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=uwcWO6Q-qAG16yJqEGLJau8YxcJBGsBJoGVUBQTBWZk,1155
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=TCFNRKlj6rXjPU2pjTD0HCpYgs_o6KcwCat9byxvq1s,8520
67
- service_forge/workflow/triggers/fast_api_trigger.py,sha256=uRlDAh5PmaLE3fGnXhs825HmLJ1oxCiQ93rIqe4orSc,6093
68
- service_forge/workflow/triggers/kafka_api_trigger.py,sha256=jGnb4dkvh01Jy3CIOvgcQQ3RjsCZCGyXp2NxzCUrd6Y,1498
69
- service_forge/workflow/triggers/once_trigger.py,sha256=X0MidqEDNATzYEQY_MwpwKEqgzBFn1lc9q8ci14Mpt8,508
70
- service_forge/workflow/triggers/period_trigger.py,sha256=WE55k5ZpCmu666MPPQC5XSP_L_OzGlwt7v8mAnw4Qas,703
71
- service_forge/workflow/triggers/websocket_api_trigger.py,sha256=a7rJpdEMcrkdsJ0FtFUJOeFf2sn93dEmH9hhvCj16CI,6731
72
- service_forge-0.1.11.dist-info/METADATA,sha256=45d_RyoVahkhRu_vqCdrfRANTAKtEAWanK58eJie2GM,2308
73
- service_forge-0.1.11.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
74
- service_forge-0.1.11.dist-info/entry_points.txt,sha256=WHntHW7GAyKQUEeMcMvHDZ7_xAb0-cZeAK4iJeu9lm8,51
75
- service_forge-0.1.11.dist-info/RECORD,,
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,,
@@ -1,4 +0,0 @@
1
- from .service_router import service_router, set_service, get_service
2
-
3
- __all__ = ["service_router", "set_service", "get_service"]
4
-