Skip to content

Commit 9584136

Browse files
committed
fix: address code scanning findings from PR review
- fix uninitialized args and inconsistent return shape in prompt_parser - add explicit returns after exhaustive match statements in capi - narrow BaseException to Exception in mcp_transport thread - add comment for empty except in cleanup shutdown path - iterate over copy in mcp_lifecycle cleanup to avoid mutation during iteration - remove unused _ENGINE_SETTING_KEYS constant from runner - remove unused import in test_session - default TaskDefinition.name/description to empty string for per-index naming - use explicit re-export pattern (as X) in __main__ and cli
1 parent 9eac08b commit 9584136

9 files changed

Lines changed: 20 additions & 33 deletions

File tree

src/seclab_taskflow_agent/__main__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
load_dotenv(find_dotenv(usecwd=True))
1919

2020
# Re-export for backwards compatibility — some tests import from __main__
21-
from .prompt_parser import parse_prompt_args # noqa: E402, F401
22-
from .runner import deploy_task_agents, run_main # noqa: E402, F401
21+
from .prompt_parser import parse_prompt_args as parse_prompt_args # noqa: E402
22+
from .runner import deploy_task_agents as deploy_task_agents # noqa: E402
23+
from .runner import run_main as run_main # noqa: E402
2324

2425
if __name__ == "__main__":
2526
from .cli import app

src/seclab_taskflow_agent/capi.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ def to_url(self) -> str:
3737
return f"https://{self}/inference"
3838
case AI_API_ENDPOINT_ENUM.AI_API_OPENAI:
3939
return f"https://{self}/v1"
40-
case _:
41-
raise ValueError(f"Unsupported endpoint: {self}")
40+
raise ValueError(f"Unsupported endpoint: {self}")
4241

4342

4443
COPILOT_INTEGRATION_ID = "vscode-chat"
@@ -114,25 +113,18 @@ def list_capi_models(token: str) -> dict[str, dict]:
114113
def supports_tool_calls(model: str, models: dict[str, dict]) -> bool:
115114
"""Check whether the given model supports tool calls."""
116115
api_endpoint = get_AI_endpoint()
117-
match urlparse(api_endpoint).netloc:
116+
netloc = urlparse(api_endpoint).netloc
117+
match netloc:
118118
case AI_API_ENDPOINT_ENUM.AI_API_GITHUBCOPILOT:
119119
return models.get(model, {}).get("capabilities", {}).get("supports", {}).get("tool_calls", False)
120120
case AI_API_ENDPOINT_ENUM.AI_API_MODELS_GITHUB:
121121
return "tool-calling" in models.get(model, {}).get("capabilities", [])
122122
case AI_API_ENDPOINT_ENUM.AI_API_OPENAI:
123-
# OpenAI doesn't expose capabilities in the models list
124-
# Check if model name indicates function calling support
125-
model_lower = model.lower()
126-
return any(
127-
[
128-
"gpt-" in model_lower,
129-
]
130-
)
131-
case _:
132-
raise ValueError(
133-
f"Unsupported Model Endpoint: {api_endpoint}\n"
134-
f"Supported endpoints: {[e.to_url() for e in AI_API_ENDPOINT_ENUM]}"
135-
)
123+
return "gpt-" in model.lower()
124+
raise ValueError(
125+
f"Unsupported Model Endpoint: {api_endpoint}\n"
126+
f"Supported endpoints: {[e.to_url() for e in AI_API_ENDPOINT_ENUM]}"
127+
)
136128

137129

138130
def list_tool_call_models(token: str) -> dict[str, dict]:

src/seclab_taskflow_agent/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,4 @@ def main(
178178
# Legacy compatibility shim — implementation moved to prompt_parser.py
179179
# ---------------------------------------------------------------------------
180180

181-
from .prompt_parser import parse_prompt_args # noqa: F401, E402
181+
from .prompt_parser import parse_prompt_args as parse_prompt_args # noqa: E402

src/seclab_taskflow_agent/mcp_lifecycle.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ async def mcp_session_task(
145145
connected.set()
146146
await cleanup.wait()
147147

148-
for entry in reversed(entries):
148+
for entry in list(reversed(entries)):
149149
try:
150150
logging.debug(f"Starting cleanup for mcp server: {entry.server._name}")
151151
await entry.server.cleanup()
@@ -158,8 +158,6 @@ async def mcp_session_task(
158158
logging.warning(f"Streamable mcp server process exception: {e}")
159159
except asyncio.CancelledError:
160160
logging.exception(f"Timeout on cleanup for mcp server: {entry.server._name}")
161-
finally:
162-
entries.remove(entry)
163161
except RuntimeError:
164162
logging.exception("RuntimeError in mcp session task")
165163
except asyncio.CancelledError:

src/seclab_taskflow_agent/mcp_transport.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def run(self) -> None:
166166
if self.exit_code not in _EXPECTED_EXIT_CODES:
167167
self.exception = subprocess.CalledProcessError(self.exit_code, self.cmd)
168168

169-
except BaseException as e:
169+
except Exception as e:
170170
self.exception = e
171171

172172
def _read_stream(
@@ -248,7 +248,7 @@ async def cleanup(self, *args: Any, **kwargs: Any) -> None:
248248
try:
249249
asyncio.run_coroutine_threadsafe(super().cleanup(*args, **kwargs), self.t.loop).result()
250250
except asyncio.CancelledError:
251-
pass
251+
pass # Swallow cancellation during cleanup shutdown
252252
finally:
253253
self.t.loop.stop()
254254
self.t.join()

src/seclab_taskflow_agent/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ class TaskDefinition(BaseModel):
8181

8282
model_config = ConfigDict(extra="allow")
8383

84-
name: str = "taskflow"
85-
description: str = "taskflow"
84+
name: str = ""
85+
description: str = ""
8686
agents: list[str] = Field(default_factory=list)
8787
user_prompt: str = ""
8888
run: str = ""

src/seclab_taskflow_agent/prompt_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
def parse_prompt_args(
2424
available_tools: AvailableTools, user_prompt: str | None = None
25-
) -> tuple[str | None, str | None, bool, dict[str, str], str, str] | tuple[None, None, None, None, str]:
25+
) -> tuple[str | None, str | None, bool, dict[str, str], str, str] | tuple[None, None, None, None, str, str]:
2626
"""Legacy CLI parser kept for backwards compatibility with tests.
2727
2828
Returns:
@@ -53,7 +53,7 @@ def parse_prompt_args(
5353
except SystemExit as e:
5454
if e.code == 2:
5555
logging.exception(f"User provided incomplete prompt: {user_prompt}")
56-
return None, None, None, None, help_msg
56+
return None, None, None, None, "", help_msg
5757
p = args[0].p.strip() if args[0].p else None
5858
t = args[0].t.strip() if args[0].t else None
5959
list_models = args[0].l

src/seclab_taskflow_agent/runner.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,6 @@ def _merge_reusable_task(
119119
return TaskDefinition.model_validate(merged)
120120

121121

122-
# Keys in model_settings that are handled by the engine, not ModelSettings.
123-
_ENGINE_SETTING_KEYS = {"api_type", "endpoint", "token"}
124-
125-
126122
def _resolve_task_model(
127123
task: TaskDefinition,
128124
model_keys: list[str],

tests/test_session.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import pytest
77

8-
from seclab_taskflow_agent.session import CompletedTask, TaskflowSession, session_dir
8+
from seclab_taskflow_agent.session import CompletedTask, TaskflowSession
99

1010

1111
class TestTaskflowSession:

0 commit comments

Comments
 (0)