diff --git a/src/fireflyframework_genai/studio/api/oracle.py b/src/fireflyframework_genai/studio/api/oracle.py index 8860e5af..963715f3 100644 --- a/src/fireflyframework_genai/studio/api/oracle.py +++ b/src/fireflyframework_genai/studio/api/oracle.py @@ -319,9 +319,9 @@ def _get_canvas() -> dict[str, Any]: # Send response in chunks for frontend streaming effect import asyncio - _CHUNK_SIZE = 12 - for i in range(0, len(full_text), _CHUNK_SIZE): - chunk = full_text[i : i + _CHUNK_SIZE] + _chunk_size = 12 + for i in range(0, len(full_text), _chunk_size): + chunk = full_text[i : i + _chunk_size] await websocket.send_json( {"type": "oracle_token", "content": chunk} ) diff --git a/src/fireflyframework_genai/studio/api/settings.py b/src/fireflyframework_genai/studio/api/settings.py index 0d4ab31d..7b76cea0 100644 --- a/src/fireflyframework_genai/studio/api/settings.py +++ b/src/fireflyframework_genai/studio/api/settings.py @@ -262,8 +262,8 @@ async def add_service(req: dict) -> dict: # Preserve existing secret values when the incoming value is the # mask placeholder ("***") sent by list_services. - _MASK = "***" - _SECRET_FIELDS = ("password", "connection_url", "api_key", "token") + _mask = "***" + _secret_fields = ("password", "connection_url", "api_key", "token") incoming_id = req.get("id") if incoming_id: old_sc = next( @@ -271,8 +271,8 @@ async def add_service(req: dict) -> dict: None, ) if old_sc is not None: - for field in _SECRET_FIELDS: - if req.get(field) == _MASK: + for field in _secret_fields: + if req.get(field) == _mask: existing_val = getattr(old_sc, field, None) if existing_val is not None: req[field] = ( diff --git a/src/fireflyframework_genai/studio/assistant/agent.py b/src/fireflyframework_genai/studio/assistant/agent.py index 0cd19c0c..895a6351 100644 --- a/src/fireflyframework_genai/studio/assistant/agent.py +++ b/src/fireflyframework_genai/studio/assistant/agent.py @@ -110,29 +110,29 @@ async def add_node( if node_type not in _VALID_NODE_TYPES: raise ValueError(f"Invalid node_type '{node_type}'. Must be one of: {', '.join(sorted(_VALID_NODE_TYPES))}") - H_GAP = 300 - V_GAP = 150 - START_X = 250 - START_Y = 250 + h_gap = 300 + v_gap = 150 + start_x = 250 + start_y = 250 if x == 0.0 and y == 0.0: if not canvas.nodes: - x, y = START_X, START_Y + x, y = start_x, start_y else: occupied = { (int(n.position.get("x", 0)), int(n.position.get("y", 0))) for n in canvas.nodes } rightmost = max(canvas.nodes, key=lambda n: n.position.get("x", 0)) - x = rightmost.position.get("x", 0) + H_GAP - y = rightmost.position.get("y", START_Y) + x = rightmost.position.get("x", 0) + h_gap + y = rightmost.position.get("y", start_y) # Avoid vertical collision: offset downward if position is taken while any( abs(ox - x) < 100 and abs(oy - y) < 80 for ox, oy in occupied ): - y += V_GAP + y += v_gap node = CanvasNode( id=canvas.next_id(node_type), @@ -376,10 +376,10 @@ async def auto_layout() -> str: if not canvas.nodes: return "Canvas is empty." - H_GAP = 300 - V_GAP = 150 - START_X = 250 - START_Y = 250 + h_gap = 300 + v_gap = 150 + start_x = 250 + start_y = 250 node_ids = {n.id for n in canvas.nodes} @@ -412,16 +412,16 @@ async def auto_layout() -> str: if remaining: layers.append(sorted(remaining)) - # Assign positions: x = layer index * H_GAP, y centered in layer + # Assign positions: x = layer index * h_gap, y centered in layer node_map = {n.id: n for n in canvas.nodes} for layer_idx, layer in enumerate(layers): - x = START_X + layer_idx * H_GAP - total_height = (len(layer) - 1) * V_GAP - start_y = START_Y - total_height / 2 + x = start_x + layer_idx * h_gap + total_height = (len(layer) - 1) * v_gap + layer_y = start_y - total_height / 2 for pos_idx, nid in enumerate(layer): node = node_map.get(nid) if node: - node.position = {"x": float(x), "y": float(start_y + pos_idx * V_GAP)} + node.position = {"x": float(x), "y": float(layer_y + pos_idx * v_gap)} return json.dumps({ "status": "layout_complete", @@ -635,7 +635,7 @@ async def get_tool_status() -> str: settings = load_settings() tc = settings.tool_credentials - _TOOL_CREDENTIAL_MAP: dict[str, list[str]] = { + _tool_credential_map: dict[str, list[str]] = { "search": ["serpapi_api_key", "serper_api_key", "tavily_api_key"], "database": ["database_url"], "custom:slack": ["slack_bot_token"], @@ -643,7 +643,7 @@ async def get_tool_status() -> str: } results = [] - for tool_name, required_creds in _TOOL_CREDENTIAL_MAP.items(): + for tool_name, required_creds in _tool_credential_map.items(): configured = [ c for c in required_creds if getattr(tc, c, None) diff --git a/src/fireflyframework_genai/studio/assistant/oracle.py b/src/fireflyframework_genai/studio/assistant/oracle.py index 6ef3863c..9f4688a9 100644 --- a/src/fireflyframework_genai/studio/assistant/oracle.py +++ b/src/fireflyframework_genai/studio/assistant/oracle.py @@ -334,11 +334,11 @@ async def get_pipeline_stats() -> str: for n in nodes: data = n.get("data", n.get("config", {})) ntype = n.get("type", "") - if ntype == "agent" and data.get("model"): - configured += 1 - elif ntype == "tool" and data.get("tool_name"): - configured += 1 - elif ntype not in ("agent", "tool"): + if ( + (ntype == "agent" and data.get("model")) + or (ntype == "tool" and data.get("tool_name")) + or ntype not in ("agent", "tool") + ): configured += 1 return json.dumps({ diff --git a/src/fireflyframework_genai/studio/codegen/generator.py b/src/fireflyframework_genai/studio/codegen/generator.py index e01be1ac..3e686e47 100644 --- a/src/fireflyframework_genai/studio/codegen/generator.py +++ b/src/fireflyframework_genai/studio/codegen/generator.py @@ -571,11 +571,7 @@ def _step_expression(node: GraphNode) -> str: return f"CallableStep({name}_validate)" elif node.type == NodeType.CUSTOM_CODE: return f"CallableStep({name}_execute)" - elif node.type == NodeType.INPUT: - return f"CallableStep({name}_step)" - elif node.type == NodeType.OUTPUT: - return f"CallableStep({name}_step)" - elif node.type == NodeType.PIPELINE_STEP: + elif node.type in (NodeType.INPUT, NodeType.OUTPUT, NodeType.PIPELINE_STEP): return f"CallableStep({name}_step)" else: return f"# Unknown node type: {node.type}" diff --git a/src/fireflyframework_genai/studio/execution/compiler.py b/src/fireflyframework_genai/studio/execution/compiler.py index 52cd6e02..abf1644a 100644 --- a/src/fireflyframework_genai/studio/execution/compiler.py +++ b/src/fireflyframework_genai/studio/execution/compiler.py @@ -79,7 +79,7 @@ def compile_graph( if input_nodes: if len(input_nodes) > 1: raise CompilationError( - "Pipeline must have exactly one Input node, found {}.".format(len(input_nodes)) + f"Pipeline must have exactly one Input node, found {len(input_nodes)}." ) if not output_nodes: raise CompilationError( diff --git a/tests/test_studio/test_dynamic_model.py b/tests/test_studio/test_dynamic_model.py index 79edf87a..67f45f29 100644 --- a/tests/test_studio/test_dynamic_model.py +++ b/tests/test_studio/test_dynamic_model.py @@ -4,9 +4,7 @@ import json -import pytest - -from fireflyframework_genai.studio.codegen.generator import generate_python, _get_default_model +from fireflyframework_genai.studio.codegen.generator import _get_default_model, generate_python from fireflyframework_genai.studio.codegen.models import GraphModel, GraphNode, NodeType diff --git a/tests/test_studio/test_graphql.py b/tests/test_studio/test_graphql.py index c8584363..35edc64d 100644 --- a/tests/test_studio/test_graphql.py +++ b/tests/test_studio/test_graphql.py @@ -23,11 +23,10 @@ pytest.importorskip("fastapi", reason="fastapi not installed") pytest.importorskip("httpx", reason="httpx not installed") -import httpx - -from fireflyframework_genai.studio.config import StudioConfig -from fireflyframework_genai.studio.server import create_studio_app +import httpx # noqa: E402 +from fireflyframework_genai.studio.config import StudioConfig # noqa: E402 +from fireflyframework_genai.studio.server import create_studio_app # noqa: E402 # --------------------------------------------------------------------------- # Fixtures @@ -229,9 +228,10 @@ def _mock_import(name: str, *args: object, **kwargs: object) -> object: reload(gql_mod) - from fireflyframework_genai.studio.projects import ProjectManager - from pathlib import Path import tempfile + from pathlib import Path + + from fireflyframework_genai.studio.projects import ProjectManager with tempfile.TemporaryDirectory() as td: pm = ProjectManager(Path(td)) diff --git a/tests/test_studio/test_pipeline_events.py b/tests/test_studio/test_pipeline_events.py index ca21f1ce..4040ce15 100644 --- a/tests/test_studio/test_pipeline_events.py +++ b/tests/test_studio/test_pipeline_events.py @@ -23,10 +23,6 @@ from unittest.mock import AsyncMock, MagicMock -import pytest - -from fireflyframework_genai.agents.registry import agent_registry -from fireflyframework_genai.pipeline.engine import PipelineEngine from fireflyframework_genai.studio.codegen.models import ( GraphEdge, GraphModel, @@ -217,7 +213,7 @@ async def test_node_error_event(self): graph = _make_graph([node]) engine = compile_graph(graph, event_handler=handler) - result = await engine.run(inputs="") + await engine.run(inputs="") events = handler.drain_events() error_events = [e for e in events if e["type"] == "node_error"] diff --git a/tests/test_studio/test_pipeline_integration.py b/tests/test_studio/test_pipeline_integration.py index e5b27149..2d6b7440 100644 --- a/tests/test_studio/test_pipeline_integration.py +++ b/tests/test_studio/test_pipeline_integration.py @@ -23,8 +23,6 @@ from unittest.mock import AsyncMock, MagicMock, patch -import pytest - from fireflyframework_genai.agents.registry import agent_registry from fireflyframework_genai.pipeline.context import PipelineContext from fireflyframework_genai.pipeline.engine import PipelineEngine @@ -43,10 +41,7 @@ GraphNode, NodeType, ) -from fireflyframework_genai.studio.execution.compiler import ( - CompilationError, - compile_graph, -) +from fireflyframework_genai.studio.execution.compiler import compile_graph from fireflyframework_genai.tools.registry import tool_registry # --------------------------------------------------------------------------- diff --git a/tests/test_studio/test_project_api.py b/tests/test_studio/test_project_api.py index 1f41f09b..1396ac56 100644 --- a/tests/test_studio/test_project_api.py +++ b/tests/test_studio/test_project_api.py @@ -27,7 +27,6 @@ from fireflyframework_genai.studio.config import StudioConfig from fireflyframework_genai.studio.server import create_studio_app - # --------------------------------------------------------------------------- # Fixtures # ---------------------------------------------------------------------------