Skip to content

fix(gateway): bridge docker_volumes config to terminal env vars#430

Closed
manuelschipper wants to merge 1 commit into
NousResearch:mainfrom
manuelschipper:fix/gateway-docker-volumes
Closed

fix(gateway): bridge docker_volumes config to terminal env vars#430
manuelschipper wants to merge 1 commit into
NousResearch:mainfrom
manuelschipper:fix/gateway-docker-volumes

Conversation

@manuelschipper

Copy link
Copy Markdown
Contributor

Summary

The gateway's config.yaml → environment variable bridge (gateway/run.py) is missing docker_volumes from its _terminal_env_map, so terminal sandboxes created from gateway sessions (Telegram, Discord, WhatsApp) never receive user-configured volume mounts. CLI sessions work correctly because cli.py includes this key in its bridge map.

This also fixes list serialization: the gateway uses str() for all config values, which produces Python repr (single quotes) for lists instead of valid JSON. Since terminal_tool.py deserializes with json.loads(), this would fail even if the key were present. Now uses json.dumps() for list values, matching cli.py behavior.

Changes

  • Add "docker_volumes": "TERMINAL_DOCKER_VOLUMES" to _terminal_env_map in gateway/run.py
  • Fix list serialization: use json.dumps() instead of str() for list-type config values

How to reproduce

  1. Configure docker_volumes in config.yaml:
    terminal:
      backend: docker
      docker_image: my-sandbox
      docker_volumes:
        - "/host/path:/container/path:ro"
  2. Send a message via Telegram (gateway session)
  3. Agent runs a terminal command → sandbox container has no user volumes mounted
  4. Same command via hermes chat (CLI) → sandbox container has user volumes mounted

Reference

The gateway config.yaml to env var bridge was missing docker_volumes,
so terminal sandboxes from gateway sessions (Telegram, Discord, WhatsApp)
never received user-configured volume mounts. CLI sessions worked because
cli.py includes this key.

Also fix list serialization: gateway used str() which produces Python repr
(single quotes) instead of valid JSON. terminal_tool deserializes with
json.loads() so this would fail. Now uses json.dumps() for list values,
matching cli.py behavior.
@manuelschipper manuelschipper deleted the fix/gateway-docker-volumes branch March 5, 2026 14:11
rafe-walker added a commit to rafe-walker/kora that referenced this pull request May 24, 2026
…irst-run wizard + mobile sidebar polish (#205)

Two deliverables — primary is the operator-onboarding wizard CC#2
flagged in #202 (paired with CC#1 NousResearch#431 per-tenant cost ladder + CC#3
NousResearch#430 Marvin runnable plugin for the pip-installable Kora bundle
vision), secondary is the small mobile-sidebar follow-on from #202.

A) KR-FE-OPERATOR-FIRST-RUN-WIZARD
   * 5-step wizard: Welcome+tenant / Anthropic / IsoKron+Slack /
     Tutorial probe / Promotion intro. First-run detection
     combines marker-file absence + audit-log emptiness → swaps
     "/" to render WizardPage instead of DashboardPage.
   * 6 BE endpoints, each ≤30 LoC of substantive logic:
     - GET  /api/wizard/state (resume + first-run signal)
     - POST /api/wizard/validate-anthropic (1-token test inference)
     - POST /api/wizard/validate-substrate (PostgREST ping)
     - POST /api/wizard/validate-slack (auth.test)
     - POST /api/wizard/trigger-tutorial-probe (synthetic wake)
     - POST /api/wizard/complete (marker write + tenant_id persist)
   * Marker file at $KORA_HOME/wizard_config.json. Operator can
     re-open the wizard anytime at /wizard URL.
   * tenant_id wired through every step + the .env download +
     the tutorial probe — NOT hardcoded "default" — feeds CC#1
     NousResearch#431's per-tenant cost-ladder foundation.
   * .env download flow: wizard NEVER mutates operator shell;
     surfaces downloadable .env operator copies to $KORA_HOME/.env
     then restarts Kora. Per the security posture: never modify
     operator env without explicit consent.
   * Validation badges (success / auth_failure / network_failure /
     timeout) render inline so operator knows immediately why a
     credential failed.
   * Drift-guards: _WIZARD_STEPS + _WIZARD_VALIDATION_RESULTS
     allowlists pinned across BE/FE/page.

B) KR-FE-SIDEBAR-MOBILE-COLLAPSE-UX (small follow-on to #202)
   * Collapse-all / Expand-all shortcut at the top of the sidebar
     (mobile + desktop). Label flips with state (allCollapsed →
     "Expand all"; otherwise "Collapse all"). Tappable on the
     375px mobile overlay.
   * useSidebarGroupCollapse hook extended with allCollapsed +
     setAll public surface methods backing the shortcut.
   * Badge overflow: formatBadgeCount caps display at "99+" so a
     long backlog can't break the narrow mobile chip. Numeric
     aria-label keeps the exact count for screen readers.

Tests: 52 new tests covering wizard endpoints (5 state behaviours,
4 validation paths, tutorial-probe audit emission, complete-flow,
2 drift-guards + 5 FE source-pins) + sidebar overflow + collapse-all
(5 pins). Full kora_cli regression: 0 new failures (76 vs 76 on
base via stash — pre-existing PTY / cron / panel-view / engine
failures unchanged).

Screenshots: web/docs/operator-first-run-wizard-and-sidebar-mobile-ux/
(5 wizard steps + before/after mobile sidebar).

Co-authored-by: CC#2 Kora Web <kora-pm@stormhavenenterprises.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant