Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Thumbs.db
*.swo
*~

.qodana-reports/

# Environment
.env
.env.local
Expand Down
6 changes: 3 additions & 3 deletions backend/openmlr/services/session_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@

session = Session(config=config, conversation_id=conversation_id)

# Determine effective compute node
effective_node = None
ops = None
if user_id and db:
try:
from ..db import operations as ops
from openmlr.db import operations as ops_module
ops = ops_module.operations
# Check conversation override
conv = await ops.get_conversation_by_id(db, conversation_id)
if conv and conv.extra:
Expand All @@ -99,11 +99,11 @@
effective_node = await ops.get_compute_node_by_id(db, override_node_id, user_id)

# Fall back to user default
if not effective_node:

Check warning on line 102 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unbound local variables

Local variable 'effective_node' might be referenced before assignment
effective_node = await ops.get_default_compute_node(db, user_id)

if effective_node:

Check warning on line 105 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unbound local variables

Local variable 'effective_node' might be referenced before assignment
log.info(f"Session {conversation_id}: using compute node '{effective_node.name}' ({effective_node.type})")

Check warning on line 106 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unbound local variables

Local variable 'effective_node' might be referenced before assignment
except Exception as e:
log.warning(f"Session {conversation_id}: failed to load compute node - {e}")

Expand All @@ -118,7 +118,7 @@
# If a compute node is configured, activate it
if effective_node:
try:
await sandbox_manager.create(effective_node.type, effective_node.config)

Check warning on line 121 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unbound local variables

Local variable 'effective_node' might be referenced before assignment
except Exception as e:
log.warning(f"Session {conversation_id}: failed to create sandbox for node '{effective_node.name}' - {e}")

Expand Down Expand Up @@ -149,7 +149,7 @@
# Build compute environment info for system prompt
compute_env = ""
if effective_node:
caps = effective_node.capabilities or {}

Check warning on line 152 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unbound local variables

Local variable 'effective_node' might be referenced before assignment
lines = [f"\n## Active Compute Environment: {effective_node.name} ({effective_node.type})"]
if caps.get("platform"):
lines.append(f"- Platform: {caps['platform']}")
Expand All @@ -176,7 +176,7 @@
if user_id and db:
try:
all_nodes = await ops.get_compute_nodes(db, user_id)
except Exception:

Check notice on line 179 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unclear exception clauses

Too broad exception clause
pass
if len(all_nodes) > 1:
lines.append("\n### Other Available Nodes")
Expand Down Expand Up @@ -226,16 +226,16 @@
try:
if not active.session.pending_answers.done():
active.session.pending_answers.cancel()
except Exception:

Check notice on line 229 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unclear exception clauses

Too broad exception clause
pass
try:
await active.sandbox_manager.destroy()
except Exception:

Check notice on line 233 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unclear exception clauses

Too broad exception clause
pass
# Disconnect MCP servers
try:
await active.mcp_manager.disconnect_all()
except Exception:

Check notice on line 238 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unclear exception clauses

Too broad exception clause
pass
if self.current_conversation_id == conversation_id:
self.current_conversation_id = None
Expand Down Expand Up @@ -287,7 +287,7 @@
return None
try:
return await LLMProvider.generate_title(messages, active.session.config)
except Exception:

Check notice on line 290 in backend/openmlr/services/session_manager.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unclear exception clauses

Too broad exception clause
return None

@property
Expand Down
4 changes: 3 additions & 1 deletion backend/openmlr/tools/compute_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
return target, None


async def _handle_list(user_id: int = None, db=None, **kwargs):

Check notice on line 23 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'kwargs' value is not used
"""List all compute nodes with capabilities."""
if not db:
return "Database connection required for compute_list", False
Expand Down Expand Up @@ -53,7 +53,7 @@
return "\n".join(lines), True


async def _handle_probe(node_name: str, user_id: int = None, db=None, **kwargs):

Check notice on line 56 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'kwargs' value is not used
"""Probe a compute node for capabilities."""
if not db:
return "Database connection required for compute_probe", False
Expand All @@ -69,6 +69,7 @@

try:
wm = WorkspaceManager()
sm: SandboxManager | None = None
sm = SandboxManager(workspace_manager=wm)
await sm.create(node.type, node.config)
sandbox = sm.get_active()
Expand All @@ -88,7 +89,7 @@
await sm.destroy()

# Format response
lines = [f"## {node.name} Capabilities\n"]

Check notice on line 92 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Non-optimal list declaration

Multi-step list initialization can be replaced with a list literal
lines.append(f"Platform: {caps.platform}")
lines.append(f"CPU: {caps.cpu_cores} cores ({caps.cpu_arch})")
lines.append(f"RAM: {caps.available_ram_gb:.1f} GB available / {caps.total_ram_gb:.1f} GB total")
Expand All @@ -115,8 +116,9 @@

except Exception as e:
try:
await sm.destroy()
if sm is not None:

Check warning on line 119 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unbound local variables

Local variable 'sm' might be referenced before assignment
await sm.destroy()

Check warning on line 120 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unbound local variables

Local variable 'sm' might be referenced before assignment
except Exception:

Check notice on line 121 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unclear exception clauses

Too broad exception clause
pass
await ops.update_compute_node(
db, node.id, user_id,
Expand All @@ -125,7 +127,7 @@
return f"Probe failed for {node_name}: {str(e)}", False


async def _handle_select(node_name: str, user_id: int = None, db=None, session=None, **kwargs):

Check notice on line 130 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'kwargs' value is not used
"""Select a compute node as active for this conversation."""
if not db:
return "Database connection required for compute_select", False
Expand All @@ -149,7 +151,7 @@
return f"Active compute switched to: {node.name} ({node.type})", True


async def _handle_plan(task: str, requirements: dict = None, user_id: int = None, db=None, **kwargs):

Check notice on line 154 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'kwargs' value is not used
"""Recommend the best compute node for a task."""
if not db:
return "Database connection required for compute_plan", False
Expand Down Expand Up @@ -224,7 +226,7 @@
scores.sort(key=lambda x: x["score"], reverse=True)
best = scores[0]

lines = [f"## Recommended Compute for: {task}\n"]

Check notice on line 229 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Non-optimal list declaration

Multi-step list initialization can be replaced with a list literal
lines.append(f"**Best choice: {best['node'].name}** ({best['node'].type})")
lines.append(f"Score: {best['score']:.1f}")
lines.append(f"Reasons: {', '.join(best['reasons'])}")
Expand All @@ -237,7 +239,7 @@
return "\n".join(lines), True


async def _get_sync_context(user_id, db, session):

Check notice on line 242 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'user_id' value is not used
"""Helper: resolve conversation UUID and workspace path for sync ops."""
from ..db import operations as ops
conv_uuid = None
Expand All @@ -253,7 +255,7 @@
return conv_uuid, local_ws, None


async def _handle_sync_up(paths: list, node_name: str, user_id: int = None, db=None, session=None, **kwargs):

Check notice on line 258 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'kwargs' value is not used
"""Sync files from local workspace to remote compute node."""
if not db:
return "Database connection required", False
Expand Down Expand Up @@ -301,7 +303,7 @@
await ssh_sandbox.execute(f"mkdir -p '{dst_dir}'", timeout=5)
content = src.read_bytes()
await asyncio.to_thread(
lambda d=dst, c=content: ssh_sandbox._sftp.putfo(io.BytesIO(c), d)

Check notice on line 306 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _sftp of a class
)
transferred += 1
else:
Expand All @@ -311,7 +313,7 @@
await ssh_sandbox.execute(f"mkdir -p '{dst_dir}'", timeout=5)
content = local_path.read_bytes()
await asyncio.to_thread(
lambda d=dst, c=content: ssh_sandbox._sftp.putfo(io.BytesIO(c), d)

Check notice on line 316 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _sftp of a class
)
transferred += 1

Expand All @@ -327,7 +329,7 @@
return "Unsupported node type", False


async def _handle_sync_down(paths: list, node_name: str, user_id: int = None, db=None, session=None, **kwargs):

Check notice on line 332 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'kwargs' value is not used
"""Sync files from remote compute node to local workspace."""
if not db:
return "Database connection required", False
Expand Down Expand Up @@ -377,7 +379,7 @@

def _do_get(rpath=rp):
buf = io.BytesIO()
ssh_sandbox._sftp.getfo(rpath, buf)

Check notice on line 382 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _sftp of a class
buf.seek(0)
return buf.read()

Expand All @@ -400,7 +402,7 @@
# Bind rf in default arg to avoid closure-in-loop bug
def _do_get_file(rpath=rf):
buf = io.BytesIO()
ssh_sandbox._sftp.getfo(rpath, buf)

Check notice on line 405 in backend/openmlr/tools/compute_tools.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _sftp of a class
buf.seek(0)
return buf.read()

Expand Down
2 changes: 0 additions & 2 deletions backend/tests/test_agent_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

from openmlr.agent.context import ContextManager
from openmlr.agent.loop import (
_compact,

Check notice on line 9 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _compact of a class
_compact_llm_call,

Check notice on line 10 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _compact_llm_call of a class
_execute_tool,

Check notice on line 11 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _execute_tool of a class
_handle_approval,

Check notice on line 12 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _handle_approval of a class
_non_stream_llm_call,

Check notice on line 13 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _non_stream_llm_call of a class
_run_agent,

Check notice on line 14 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _run_agent of a class
_stream_llm_call,

Check notice on line 15 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _stream_llm_call of a class
_undo,

Check notice on line 16 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Accessing a protected member of a class or a module

Access to a protected member _undo of a class
run_agent_turn,
submission_loop,
)
Expand Down Expand Up @@ -326,7 +326,7 @@
mock_session.is_cancelled.return_value = False
mock_session.config = AgentConfig(model_name="test", stream=True)

async def mock_stream(messages, config, tools):

Check notice on line 329 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'config' value is not used

Check notice on line 329 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'messages' value is not used

Check notice on line 329 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'tools' value is not used
yield "Hello"
yield " world"

Expand All @@ -341,10 +341,8 @@
async def test_cancelled_returns_none(self, mock_session):
mock_session.is_cancelled.return_value = True

async def mock_stream(messages, config, tools):

Check notice on line 344 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'tools' value is not used

Check notice on line 344 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'messages' value is not used

Check notice on line 344 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'config' value is not used
yield "Hello"
if False:
yield

with patch("openmlr.agent.loop.LLMProvider.generate_stream") as mock_str:
mock_str.return_value = mock_stream(None, None, None)
Expand All @@ -357,7 +355,7 @@
mock_session.config = AgentConfig(model_name="test", stream=True)
tc = ToolCall(id="call_1", name="search", arguments={"query": "test"})

async def mock_stream(messages, config, tools):

Check notice on line 358 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'tools' value is not used

Check notice on line 358 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'config' value is not used

Check notice on line 358 in backend/tests/test_agent_loop.py

View workflow job for this annotation

GitHub Actions / Qodana for Python

Unused local symbols

Parameter 'messages' value is not used
yield "Finding..."
yield tc

Expand Down
2 changes: 2 additions & 0 deletions qodana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ profile:
name: qodana.recommended
include:
- name: CheckDependencyLicenses
exclude:
- name: PyTypeHintsInspection
Loading