Repository navigation
Conversation
- mcp_server_pupper: make --mcp-transport actually take effect. The run
block tested the raw MCP_TRANSPORT env var against "http" (not one of
the argparse choices) and args.mcp_transport was never read, so
--mcp-transport sse/streamable-http silently ran stdio.
- puppy_interaction: call response.json() instead of binding the method.
- mcp_server_pupper: replace mutable default arguments with None in
publish_once() and publish_for_durations(); the guards now use falsy
checks, which accept the same inputs as the previous == {} / == []
comparisons.
- mcp_server_pupper: make zip() strictness explicit — strict=True where
equal lengths are already validated, strict=False where truncating a
malformed rosbridge typedef is preferable to raising.
- puppy-state-api, puppy-head: replace os.system() f-strings with
subprocess.run() argument lists, so sound paths containing spaces or
shell metacharacters are handled correctly.
Note: the MCP schema for publish_once.msg and publish_for_durations
messages/durations changes from {"type": ...,"default": {}/[]} to an
anyOf with null and "default": null, as a consequence of the Optional
type hints. Both shapes are rejected by the same validation guard.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mc57S5DG9vCz16a8g7Xxqi
|
The build dies at Evidence that it is independent of this PR:
This PR changes four Python files ( No fix exists yet to port into this PR, so I am not widening it — the fix belongs in #119, which needs a decision about the base image (move to bookworm, repoint at Everything else on this PR is green: Lint ✅ · REUSE ✅ · Markdown Link Check ✅ · WIP ✅, no open review threads. I will re-run the failed job once to confirm it reproduces rather than leaving it on a single observation. Generated by Claude Code |
Summary
Closes #116.
Clears the five code-quality items from that issue. No behaviour changes intended beyond the
--mcp-transportfix, which is the point of item 1.1.
--mcp-transportwas a no-opmcp_server_pupper/main.pyread the raw env var in the run block rather than the parsed argument:args.mcp_transportwas parsed and never used, and"http"isn't among the argparsechoices, so--mcp-transport sse/streamable-httpsilently ran stdio.MCP_TRANSPORTstill supplies the default. Worth noting: argparse does not validate defaults againstchoices, soMCP_TRANSPORT=httpstill reachesmcp.run(transport="http")exactly as before — this change doesn't break that path.2.
response.jsonmissing its call3. Mutable default arguments (
B006)publish_once(msg={})andpublish_for_durations(messages=[], durations=[])now default toNone, with the guards changed frommsg == {}/== []to falsy checks. Verified the guards accept exactly the same inputs:{}/[]None(new default)4.
zip()strictness made explicit (B905)publish_for_durations→strict=True; equal lengths are already validated immediately above, so it can't fire.get_message_details→strict=Falsewith a comment. A malformed rosbridge typedef keeps truncating rather than raising out of a tool call — deliberately preserving current behaviour.5.
os.system()→subprocess.run()In
puppy_state_manager.pyandpuppy_head.py:To be clear on severity, as noted in #116: these were not remotely injectable — both call sites allow-list the requested name against configuration first. The fix is about paths containing spaces or shell metacharacters.
check=Falsepreserves the previous ignore-the-exit-status behaviour.import osbecame unused inpuppy_head.pyand was dropped.Heads-up: MCP tool schema change
A consequence of item 3 — the schema the LLM sees for these parameters changes:
publish_once.msg{"type":"object","default":{}}{"anyOf":[{"type":"object"},{"type":"null"}],"default":null}publish_for_durations.messages{"type":"array","default":[]}{"anyOf":[{"type":"array"},{"type":"null"}],"default":null}Omitting the argument was rejected before and is still rejected, with the same error — so there's no functional difference. Flagging it because it's user-visible to the model. If you'd rather keep the original schema exactly,
Annotated[dict, Field(default_factory=dict)]also satisfiesB006; say the word and I'll switch.Verification
--mcp-transport stdio|sse|streamable-httpeach confirmed to reachargs.mcp_transport.zip()semantics verified against the old comparisons (table above).ruff --select B006,B905and--select S605→ clean. Repo-wide default ruleset (what Super-Linter runs) reports only two pre-existingF401s incode/training-yolo/*.ipynb, untouched here.python3.13 -m py_compileclean on all four files. (py_compileunder 3.11 fails onpuppy_state_manager.py— a pre-existing PEP 701 multi-line f-string at line 139, present onmainand unrelated to this PR; that package requires Python ≥ 3.13.)subprocess.run()audio changes need a robot with a sound device to exercise. They're mechanical translations, but worth a sanity check on a puppy before relying on them.Leaves #111, #112, #113, #114, #115 and #117 untouched.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Mc57S5DG9vCz16a8g7Xxqi
Generated by Claude Code