forked from molecule-ai/molecule-core
Comprehensive sweep follow-up to the MCP server path fix. Audited every /app/ reference in the runtime source against the live claude-code template image and confirmed the actual /app/ contents post-#87 are ONLY: __init__.py, adapter.py, claude_sdk_executor.py, requirements.txt — every other workspace module ships in the wheel under site-packages/molecule_runtime/. Two more leaks found: 1. executor_helpers.py:_A2A_INSTRUCTIONS_CLI — inter-agent system prompt for non-MCP runtimes (Ollama, custom) had 5 lines telling the model `python3 /app/a2a_cli.py X`. Models copy these examples verbatim, so every CLI-runtime delegation would fail at the shell layer (no such file). Replaced with `python3 -m molecule_runtime.a2a_cli` form, which works regardless of where the wheel is installed. 2. molecule_ai_status.py docstring — usage examples invoked `python3 /app/molecule_ai_status.py` and claimed a `molecule-monorepo-status` shell alias. Both broken in current templates: the file's at site-packages, and `which molecule-monorepo-status` errors (the legacy symlink only existed in the dev-only workspace/Dockerfile base image, not in the standalone template Dockerfiles that ship to production). Updated docstring + the __main__ usage banner + the stderr error prefix to use the same `python3 -m molecule_runtime.X` form. Plugins audited and clean: WORKSPACE_PLUGINS_DIR=/configs/plugins, SHARED_PLUGINS_DIR=$PLUGINS_DIR fallback /plugins. No /app/ assumptions. Regression test: `test_a2a_cli_instructions_use_module_invocation_not_legacy_app_path` asserts the legacy /app/a2a_cli.py path can't drift back into the CLI system prompt and that the canonical module form is present. The legacy workspace/Dockerfile + workspace/entrypoint.sh + workspace/scripts/ still contain /app/-shaped paths but are dev-only base-image scaffolding (per workspace/build-all.sh's own header comment) — not shipped to the standalone template images. Out of scope here; can be cleaned up in a separate dead-code pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
72 lines
2.2 KiB
Python
72 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Update workspace task status on the canvas.
|
|
|
|
Usage (from any script, cron job, or shell inside the container):
|
|
|
|
# Set current task (shows on canvas card)
|
|
python3 -m molecule_runtime.molecule_ai_status "Running weekly SEO audit..."
|
|
|
|
# Clear task (removes banner from canvas)
|
|
python3 -m molecule_runtime.molecule_ai_status ""
|
|
|
|
The status appears as an amber banner on the workspace card in the canvas,
|
|
visible to the project owner in real-time.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
|
|
import httpx
|
|
|
|
_WORKSPACE_ID_raw = os.environ.get("WORKSPACE_ID")
|
|
if not _WORKSPACE_ID_raw:
|
|
raise RuntimeError("WORKSPACE_ID environment variable is required but not set")
|
|
WORKSPACE_ID = _WORKSPACE_ID_raw
|
|
PLATFORM_URL = os.environ.get("PLATFORM_URL", "http://host.docker.internal:8080")
|
|
|
|
|
|
def set_status(task: str):
|
|
"""Push current_task to platform via heartbeat."""
|
|
try:
|
|
try:
|
|
from platform_auth import auth_headers as _auth
|
|
_headers = _auth()
|
|
except Exception:
|
|
_headers = {}
|
|
httpx.post(
|
|
f"{PLATFORM_URL}/registry/heartbeat",
|
|
json={
|
|
"workspace_id": WORKSPACE_ID,
|
|
"current_task": task,
|
|
"active_tasks": 1 if task else 0,
|
|
"error_rate": 0,
|
|
"sample_error": "",
|
|
"uptime_seconds": 0,
|
|
},
|
|
headers=_headers,
|
|
timeout=5.0,
|
|
)
|
|
if task:
|
|
# Also log as activity for traceability
|
|
httpx.post(
|
|
f"{PLATFORM_URL}/workspaces/{WORKSPACE_ID}/activity",
|
|
json={
|
|
"activity_type": "task_update",
|
|
"source_id": WORKSPACE_ID,
|
|
"summary": task,
|
|
"status": "ok",
|
|
},
|
|
timeout=5.0,
|
|
)
|
|
except Exception as e:
|
|
print(f"molecule_ai_status: failed to update: {e}", file=sys.stderr)
|
|
|
|
|
|
if __name__ == "__main__": # pragma: no cover
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python3 -m molecule_runtime.molecule_ai_status 'task description'")
|
|
print(" python3 -m molecule_runtime.molecule_ai_status '' # clear")
|
|
sys.exit(1)
|
|
|
|
set_status(sys.argv[1])
|