mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-27 09:26:22 +02:00
Flow class / flow blueprint
This commit is contained in:
parent
99f17d1b9d
commit
95fd60b7bd
11 changed files with 118 additions and 116 deletions
|
|
@ -32,7 +32,9 @@ class Service(ToolService):
|
|||
|
||||
logger.info(f"Got config version {version}")
|
||||
|
||||
if "mcp" not in config: return
|
||||
if "mcp" not in config:
|
||||
self.mcp_services = {}
|
||||
return
|
||||
|
||||
self.mcp_services = {
|
||||
k: json.loads(v)
|
||||
|
|
|
|||
|
|
@ -13,26 +13,26 @@ class FlowConfig:
|
|||
# Cache for parameter type definitions to avoid repeated lookups
|
||||
self.param_type_cache = {}
|
||||
|
||||
async def resolve_parameters(self, flow_class, user_params):
|
||||
async def resolve_parameters(self, flow_blueprint, user_params):
|
||||
"""
|
||||
Resolve parameters by merging user-provided values with defaults.
|
||||
|
||||
Args:
|
||||
flow_class: The flow class definition dict
|
||||
flow_blueprint: The flow blueprint definition dict
|
||||
user_params: User-provided parameters dict (may be None or empty)
|
||||
|
||||
Returns:
|
||||
Complete parameter dict with user values and defaults merged (all values as strings)
|
||||
"""
|
||||
# If the flow class has no parameters section, return user params as-is (stringified)
|
||||
if "parameters" not in flow_class:
|
||||
# If the flow blueprint has no parameters section, return user params as-is (stringified)
|
||||
if "parameters" not in flow_blueprint:
|
||||
if not user_params:
|
||||
return {}
|
||||
# Ensure all values are strings
|
||||
return {k: str(v) for k, v in user_params.items()}
|
||||
|
||||
resolved = {}
|
||||
flow_params = flow_class["parameters"]
|
||||
flow_params = flow_blueprint["parameters"]
|
||||
user_params = user_params if user_params else {}
|
||||
|
||||
# First pass: resolve parameters with explicit values or defaults
|
||||
|
|
@ -92,7 +92,7 @@ class FlowConfig:
|
|||
else:
|
||||
resolved[param_name] = str(default_value)
|
||||
|
||||
# Include any extra parameters from user that weren't in flow class definition
|
||||
# Include any extra parameters from user that weren't in flow blueprint definition
|
||||
# This allows for forward compatibility (ensure they're strings)
|
||||
for key, value in user_params.items():
|
||||
if key not in resolved:
|
||||
|
|
@ -100,28 +100,28 @@ class FlowConfig:
|
|||
|
||||
return resolved
|
||||
|
||||
async def handle_list_classes(self, msg):
|
||||
async def handle_list_blueprints(self, msg):
|
||||
|
||||
names = list(await self.config.get("flow-classes").keys())
|
||||
names = list(await self.config.get("flow-blueprints").keys())
|
||||
|
||||
return FlowResponse(
|
||||
error = None,
|
||||
class_names = names,
|
||||
blueprint_names = names,
|
||||
)
|
||||
|
||||
async def handle_get_class(self, msg):
|
||||
async def handle_get_blueprint(self, msg):
|
||||
|
||||
return FlowResponse(
|
||||
error = None,
|
||||
class_definition = await self.config.get(
|
||||
"flow-classes"
|
||||
).get(msg.class_name),
|
||||
blueprint_definition = await self.config.get(
|
||||
"flow-blueprints"
|
||||
).get(msg.blueprint_name),
|
||||
)
|
||||
|
||||
async def handle_put_class(self, msg):
|
||||
async def handle_put_blueprint(self, msg):
|
||||
|
||||
await self.config.get("flow-classes").put(
|
||||
msg.class_name, msg.class_definition
|
||||
await self.config.get("flow-blueprints").put(
|
||||
msg.blueprint_name, msg.blueprint_definition
|
||||
)
|
||||
|
||||
await self.config.inc_version()
|
||||
|
|
@ -132,11 +132,11 @@ class FlowConfig:
|
|||
error = None,
|
||||
)
|
||||
|
||||
async def handle_delete_class(self, msg):
|
||||
async def handle_delete_blueprint(self, msg):
|
||||
|
||||
logger.debug(f"Flow config message: {msg}")
|
||||
|
||||
await self.config.get("flow-classes").delete(msg.class_name)
|
||||
await self.config.get("flow-blueprints").delete(msg.blueprint_name)
|
||||
|
||||
await self.config.inc_version()
|
||||
|
||||
|
|
@ -169,8 +169,8 @@ class FlowConfig:
|
|||
|
||||
async def handle_start_flow(self, msg):
|
||||
|
||||
if msg.class_name is None:
|
||||
raise RuntimeError("No class name")
|
||||
if msg.blueprint_name is None:
|
||||
raise RuntimeError("No blueprint name")
|
||||
|
||||
if msg.flow_id is None:
|
||||
raise RuntimeError("No flow ID")
|
||||
|
|
@ -181,11 +181,11 @@ class FlowConfig:
|
|||
if msg.description is None:
|
||||
raise RuntimeError("No description")
|
||||
|
||||
if msg.class_name not in await self.config.get("flow-classes").keys():
|
||||
raise RuntimeError("Class does not exist")
|
||||
if msg.blueprint_name not in await self.config.get("flow-blueprints").keys():
|
||||
raise RuntimeError("Blueprint does not exist")
|
||||
|
||||
cls = json.loads(
|
||||
await self.config.get("flow-classes").get(msg.class_name)
|
||||
await self.config.get("flow-blueprints").get(msg.blueprint_name)
|
||||
)
|
||||
|
||||
# Resolve parameters by merging user-provided values with defaults
|
||||
|
|
@ -200,7 +200,7 @@ class FlowConfig:
|
|||
def repl_template_with_params(tmp):
|
||||
|
||||
result = tmp.replace(
|
||||
"{class}", msg.class_name
|
||||
"{blueprint}", msg.blueprint_name
|
||||
).replace(
|
||||
"{id}", msg.flow_id
|
||||
)
|
||||
|
|
@ -210,7 +210,7 @@ class FlowConfig:
|
|||
|
||||
return result
|
||||
|
||||
for kind in ("class", "flow"):
|
||||
for kind in ("blueprint", "flow"):
|
||||
|
||||
for k, v in cls[kind].items():
|
||||
|
||||
|
|
@ -223,7 +223,7 @@ class FlowConfig:
|
|||
for k2, v2 in v.items()
|
||||
}
|
||||
|
||||
flac = await self.config.get("flows-active").get(processor)
|
||||
flac = await self.config.get("active-flow").get(processor)
|
||||
if flac is not None:
|
||||
target = json.loads(flac)
|
||||
else:
|
||||
|
|
@ -237,7 +237,7 @@ class FlowConfig:
|
|||
if variant not in target:
|
||||
target[variant] = v
|
||||
|
||||
await self.config.get("flows-active").put(
|
||||
await self.config.get("active-flow").put(
|
||||
processor, json.dumps(target)
|
||||
)
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ class FlowConfig:
|
|||
msg.flow_id,
|
||||
json.dumps({
|
||||
"description": msg.description,
|
||||
"class-name": msg.class_name,
|
||||
"blueprint-name": msg.blueprint_name,
|
||||
"interfaces": interfaces,
|
||||
"parameters": parameters,
|
||||
})
|
||||
|
|
@ -286,17 +286,17 @@ class FlowConfig:
|
|||
|
||||
flow = json.loads(await self.config.get("flows").get(msg.flow_id))
|
||||
|
||||
if "class-name" not in flow:
|
||||
raise RuntimeError("Internal error: flow has no flow class")
|
||||
if "blueprint-name" not in flow:
|
||||
raise RuntimeError("Internal error: flow has no flow blueprint")
|
||||
|
||||
class_name = flow["class-name"]
|
||||
blueprint_name = flow["blueprint-name"]
|
||||
parameters = flow.get("parameters", {})
|
||||
|
||||
cls = json.loads(await self.config.get("flow-classes").get(class_name))
|
||||
cls = json.loads(await self.config.get("flow-blueprints").get(blueprint_name))
|
||||
|
||||
def repl_template(tmp):
|
||||
result = tmp.replace(
|
||||
"{class}", class_name
|
||||
"{blueprint}", blueprint_name
|
||||
).replace(
|
||||
"{id}", msg.flow_id
|
||||
)
|
||||
|
|
@ -313,7 +313,7 @@ class FlowConfig:
|
|||
|
||||
variant = repl_template(variant)
|
||||
|
||||
flac = await self.config.get("flows-active").get(processor)
|
||||
flac = await self.config.get("active-flow").get(processor)
|
||||
|
||||
if flac is not None:
|
||||
target = json.loads(flac)
|
||||
|
|
@ -323,7 +323,7 @@ class FlowConfig:
|
|||
if variant in target:
|
||||
del target[variant]
|
||||
|
||||
await self.config.get("flows-active").put(
|
||||
await self.config.get("active-flow").put(
|
||||
processor, json.dumps(target)
|
||||
)
|
||||
|
||||
|
|
@ -342,14 +342,14 @@ class FlowConfig:
|
|||
|
||||
logger.debug(f"Handling flow message: {msg.operation}")
|
||||
|
||||
if msg.operation == "list-classes":
|
||||
resp = await self.handle_list_classes(msg)
|
||||
elif msg.operation == "get-class":
|
||||
resp = await self.handle_get_class(msg)
|
||||
elif msg.operation == "put-class":
|
||||
resp = await self.handle_put_class(msg)
|
||||
elif msg.operation == "delete-class":
|
||||
resp = await self.handle_delete_class(msg)
|
||||
if msg.operation == "list-blueprints":
|
||||
resp = await self.handle_list_blueprints(msg)
|
||||
elif msg.operation == "get-blueprint":
|
||||
resp = await self.handle_get_blueprint(msg)
|
||||
elif msg.operation == "put-blueprint":
|
||||
resp = await self.handle_put_blueprint(msg)
|
||||
elif msg.operation == "delete-blueprint":
|
||||
resp = await self.handle_delete_blueprint(msg)
|
||||
elif msg.operation == "list-flows":
|
||||
resp = await self.handle_list_flows(msg)
|
||||
elif msg.operation == "get-flow":
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class Processor(FlowProcessor):
|
|||
|
||||
self.prices = {}
|
||||
|
||||
self.config_key = "token-costs"
|
||||
self.config_key = "token-cost"
|
||||
|
||||
# Load token costs from the config service
|
||||
async def on_cost_config(self, config, version):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue