feat(runner): add global /feedback slash command for all sessions#687
feat(runner): add global /feedback slash command for all sessions#687jeremyeder wants to merge 2 commits intomainfrom
Conversation
Introduces the `submit_feedback` MCP tool registered in every session so users can signal satisfaction or dissatisfaction with agent output. The tool logs a BOOLEAN score to Langfuse and is exposed alongside the existing `log_correction` and `restart_session` tools. - Add `feedback_tool.py` with `create_feedback_mcp_tool` factory and `_log_feedback_to_langfuse` helper (follows corrections.py pattern) - Register a `feedback` MCP server in `build_mcp_servers()` (mcp.py) - Add `FEEDBACK_INSTRUCTIONS` prompt constant and include it in the workspace context prompt when Langfuse is enabled (prompts.py) - Add 15 unit tests covering schema, tool creation, Langfuse logging, trace ID fallback, comment truncation, and error paths Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add shared feedback.md command file so users can type /feedback in any session. The command collects a rating and comment, then calls the submit_feedback MCP tool (added in prior commit). When Langfuse is not configured, the tool now logs feedback to stdout instead of returning an error, so feedback always succeeds from the user's perspective. - Create components/runners/commands/feedback.md (shared across runners) - COPY commands/ into runner image via Dockerfile - Add platform/commands.py helper to inject commands at startup - Call inject_platform_commands() from bridge._setup_platform() - Remove LANGFUSE_ENABLED gate from prompt instructions - Update tests for fallback behavior Closes #678 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude Code ReviewSummaryThis PR introduces a Issues by Severity🚫 Blocker Issues1. Corrections tool regression:
# corrections.py:407-408
if not langfuse_enabled:
return False, "Langfuse not enabled."This causes
Fix options:
🔴 Critical Issues2. Rating value not validated before boolean conversion
rating = args.get("rating", "")
# ...
value = rating == "positive" # "thumbs_up", "ok", "" all silently map to FalseThe JSON schema enum constrains the model, but defensive validation in the tool itself is standard practice. An unexpected value silently records a Fix: Add a warning before the conversion: if rating not in FEEDBACK_RATINGS:
logger.warning("Unexpected rating value %r; treating as negative", rating)🟡 Major Issues3. Tautological assertion in
assert (
"submit_feedback" not in description or FEEDBACK_TOOL_DESCRIPTION in description
)
Fix: Replace with direct content assertions: assert "positive" in description
assert "rating" in description
assert "comment" in description4. No test invokes the returned async tool function end-to-end All 15 Fix: Add at least one async test that calls the returned tool function and validates 5. The module header says "Copy bundled command 🔵 Minor Issues6. Redundant
7. Raw exception string in
Positive Highlights
Recommendations
🤖 Reviewed by Claude Code (claude-sonnet-4-6) 🔍 View AI decision process (logs available for 90 days) 📋 View memory system files loaded (click to expand)What Amber Loaded for Code ReviewAmber automatically loaded these repository standards from the memory system:
Impact: This review used your repository's specific code quality standards, security patterns, and best practices from the memory system (PRs #359, #360) - not just generic code review guidelines. |
Summary
/feedbackslash command available in every session, backed by thesubmit_feedbackMCP tool that logs to Langfusecommands/directory at the runner level so future runners get/feedbackfor freeChanges
components/runners/commands/feedback.md— shared slash command file with frontmatter metadata; instructs Claude to collect rating + comment and callsubmit_feedbackDockerfile—COPY commands/ /app/commands/to bake commands into the runner imageplatform/commands.py— reusable helper that copies bundled commands into.claude/commands/at startupbridge.py— callsinject_platform_commands()during_setup_platform()before Claude Code launchesfeedback_tool.py— MCP tool with graceful fallback: logs to stdout when Langfuse is unavailable (not enabled, missing creds, or package not installed)prompts.py— removedLANGFUSE_ENABLEDgate from feedback/correction prompt instructions (tools handle degradation themselves)Architecture
Test plan
pytest tests/test_feedback_tool.py tests/test_commands.py— 20/20 passingmake build-runner CONTAINER_ENGINE=dockerdocker run --rm --entrypoint="" vteam_claude_runner:latest ls /app/commands//feedbackappears as slash commandCloses #678
🤖 Generated with Claude Code