mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-08-26 17:31:34 +00:00
chore: remove legacy TUI configurator; surface last config gap in GUI (#45)
Audit confirmed the Rich TUI (`meshai --config`) is a strict subset of the dashboard GUI (covers FEWER sections) and nothing depends on it for bootstrap. Strip it so the dashboard is the single config surface. - delete meshai/cli/configurator.py (~1435 lines); cli/__init__ minimal - main.py: drop --config + run_configurator dispatch (keep --config-file); bootstrap log now points to config.example.yaml / the dashboard - docker-entrypoint.sh: remove the ttyd `meshai --config` block on :7682 (default-config heredoc + bot exec loop untouched) - docker-compose.yml + Dockerfile: drop the 7682 port + ttyd install (EXPOSE 8080) - README / config.py header / config.example.yaml: de-reference the TUI - drop `rich` from pyproject + requirements (grep-verified unused) Close the only GUI config gap the audit found: - Config.tsx weather tab: add openmeteo.url + wttr.url inputs (backend already round-trips the nested WeatherConfig dataclasses) Bootstrap intact: config.example.yaml copy, entrypoint default-config write, and defaulted Config() when no file exists all remain. `python3 -m meshai` and `--config-file` unchanged. TS/import validated at Docker build. Co-authored-by: Matt Johnson <mj@k7zvx.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7ec0883b44
commit
5de683f7a7
12 changed files with 30 additions and 1483 deletions
|
|
@ -46,11 +46,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
curl \
|
curl \
|
||||||
# For process management
|
# For process management
|
||||||
procps \
|
procps \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
# Install ttyd for web-based config interface (arch-aware)
|
|
||||||
&& TTYD_ARCH=$(dpkg --print-architecture | sed 's/amd64/x86_64/' | sed 's/arm64/aarch64/') \
|
|
||||||
&& curl -sL "https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.${TTYD_ARCH}" -o /usr/local/bin/ttyd \
|
|
||||||
&& chmod +x /usr/local/bin/ttyd
|
|
||||||
|
|
||||||
# Create non-root user
|
# Create non-root user
|
||||||
RUN groupadd -g ${GID} meshai && \
|
RUN groupadd -g ${GID} meshai && \
|
||||||
|
|
@ -88,12 +84,12 @@ USER meshai
|
||||||
# Data volume mount point
|
# Data volume mount point
|
||||||
VOLUME ["/data"]
|
VOLUME ["/data"]
|
||||||
|
|
||||||
# Expose ttyd web config port
|
# Expose dashboard port
|
||||||
EXPOSE 7682 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
# Health check - verify bot process is alive via PID file
|
# Health check - verify bot process is alive via PID file
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||||
CMD test -f /tmp/meshai.pid && kill -0 $(cat /tmp/meshai.pid) 2>/dev/null && [ "$(cat /tmp/meshai.link 2>/dev/null)" = up ] || exit 1
|
CMD test -f /tmp/meshai.pid && kill -0 $(cat /tmp/meshai.pid) 2>/dev/null && [ "$(cat /tmp/meshai.link 2>/dev/null)" = up ] || exit 1
|
||||||
|
|
||||||
# Entrypoint handles config and ttyd
|
# Entrypoint writes default config on first run, then starts the bot
|
||||||
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ Everything is driven from the web UI, organized into **General**, **Meshtastic**
|
||||||
git clone https://github.com/zvx-echo6/meshai.git
|
git clone https://github.com/zvx-echo6/meshai.git
|
||||||
cd meshai
|
cd meshai
|
||||||
pip install -e .
|
pip install -e .
|
||||||
meshai --config # interactive setup TUI
|
cp config.example.yaml config.yaml # then edit config.yaml (or use the dashboard)
|
||||||
meshai
|
meshai
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,8 @@ knowledge:
|
||||||
|
|
||||||
# === MESH DATA SOURCES ===
|
# === MESH DATA SOURCES ===
|
||||||
# Connect to Meshview and/or MeshMonitor instances for live mesh
|
# Connect to Meshview and/or MeshMonitor instances for live mesh
|
||||||
# network analysis. Supports multiple sources. Configure via TUI
|
# network analysis. Supports multiple sources. Configure via the
|
||||||
# with meshai --config (Mesh Sources menu).
|
# dashboard (Mesh Sources) or by editing this file directly.
|
||||||
#
|
#
|
||||||
# mesh_sources:
|
# mesh_sources:
|
||||||
# - name: "my-meshview"
|
# - name: "my-meshview"
|
||||||
|
|
|
||||||
|
|
@ -1137,6 +1137,20 @@ function WeatherSection({ data, onChange }: { data: WeatherConfig; onChange: (d:
|
||||||
placeholder="Your city, state"
|
placeholder="Your city, state"
|
||||||
helper="Location when none specified"
|
helper="Location when none specified"
|
||||||
/>
|
/>
|
||||||
|
<TextInput
|
||||||
|
label="Open-Meteo base URL (advanced)"
|
||||||
|
value={data.openmeteo.url}
|
||||||
|
onChange={(v) => onChange({ ...data, openmeteo: { ...data.openmeteo, url: v } })}
|
||||||
|
placeholder="https://api.open-meteo.com/v1"
|
||||||
|
helper="Override the Open-Meteo API endpoint (leave default unless self-hosting)"
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
label="wttr.in base URL (advanced)"
|
||||||
|
value={data.wttr.url}
|
||||||
|
onChange={(v) => onChange({ ...data, wttr: { ...data.wttr, url: v } })}
|
||||||
|
placeholder="https://wttr.in"
|
||||||
|
helper="Override the wttr.in endpoint (leave default unless self-hosting)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
# MeshAI Docker Compose Configuration
|
# MeshAI Docker Compose Configuration
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# docker compose up -d # Start bot + web config
|
# docker compose up -d # Start the bot + dashboard
|
||||||
# docker compose logs -f # View logs
|
# docker compose logs -f # View logs
|
||||||
#
|
#
|
||||||
# Web config: http://localhost:7682 (TUI in browser)
|
# Dashboard: http://localhost:8080
|
||||||
#
|
#
|
||||||
# Config is stored in the meshai_data volume at /data/config.yaml
|
# Config is stored in the meshai_data volume at /data/config.yaml
|
||||||
#
|
#
|
||||||
# For serial connection (USB), uncomment the devices section below
|
# For serial connection (USB), uncomment the devices section below
|
||||||
# For TCP connection, configure via web interface
|
# For TCP connection, edit config.yaml or use the dashboard
|
||||||
|
|
||||||
services:
|
services:
|
||||||
meshai:
|
meshai:
|
||||||
|
|
@ -41,8 +41,6 @@ services:
|
||||||
# - /dev/ttyACM0:/dev/ttyACM0
|
# - /dev/ttyACM0:/dev/ttyACM0
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
# Web-based config interface (ttyd)
|
|
||||||
- "7682:7682"
|
|
||||||
# Dashboard API
|
# Dashboard API
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
|
|
||||||
|
|
@ -50,7 +48,7 @@ services:
|
||||||
# Persistent data (database, config)
|
# Persistent data (database, config)
|
||||||
- meshai_data:/data
|
- meshai_data:/data
|
||||||
|
|
||||||
# Run interactively for first-time setup wizard
|
# Allocate a TTY for cleaner log output
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
tty: true
|
tty: true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# MeshAI Docker Entrypoint
|
# MeshAI Docker Entrypoint
|
||||||
# Runs ttyd for web config access and the bot
|
# Writes a default config on first run, then runs the bot
|
||||||
|
|
||||||
export MESHAI_CONFIG="/data/config.yaml"
|
export MESHAI_CONFIG="/data/config.yaml"
|
||||||
export TERM="${TERM:-xterm-256color}"
|
export TERM="${TERM:-xterm-256color}"
|
||||||
|
|
@ -10,7 +10,7 @@ if [ ! -f "$MESHAI_CONFIG" ]; then
|
||||||
mkdir -p /data
|
mkdir -p /data
|
||||||
cat > "$MESHAI_CONFIG" << 'EOF'
|
cat > "$MESHAI_CONFIG" << 'EOF'
|
||||||
# MeshAI Configuration
|
# MeshAI Configuration
|
||||||
# Configure via http://localhost:7682
|
# Edit this file directly, or configure via the dashboard
|
||||||
|
|
||||||
bot:
|
bot:
|
||||||
name: ai
|
name: ai
|
||||||
|
|
@ -66,22 +66,10 @@ meshmonitor:
|
||||||
enabled: false
|
enabled: false
|
||||||
inject_into_prompt: true
|
inject_into_prompt: true
|
||||||
EOF
|
EOF
|
||||||
echo "Default config created. Configure via http://localhost:7682"
|
echo "Default config created at $MESHAI_CONFIG. Edit it or configure via the dashboard."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Start ttyd for web-based config access
|
|
||||||
echo "Starting web config interface on port 7682..."
|
|
||||||
ttyd -W -p 7682 \
|
|
||||||
-t enableClipboard=true \
|
|
||||||
-t titleFixed="MeshAI Config" \
|
|
||||||
-t 'theme={"background":"#0d1117","foreground":"#c9d1d9","cursor":"#58a6ff","selectionBackground":"#388bfd"}' \
|
|
||||||
-t fontSize=14 \
|
|
||||||
/bin/bash -c 'while true; do python3 -m meshai --config-file "$MESHAI_CONFIG" --config; sleep 1; done' &
|
|
||||||
|
|
||||||
# Keep ttyd running even if bot fails
|
|
||||||
trap "kill %1 2>/dev/null" EXIT
|
|
||||||
|
|
||||||
# Kill bot gracefully with SIGKILL fallback
|
# Kill bot gracefully with SIGKILL fallback
|
||||||
kill_bot() {
|
kill_bot() {
|
||||||
local pid=$1
|
local pid=$1
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1 @@
|
||||||
"""CLI tools for MeshAI."""
|
"""CLI tools for MeshAI."""
|
||||||
|
|
||||||
from .configurator import run_configurator
|
|
||||||
|
|
||||||
__all__ = ["run_configurator"]
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1090,7 +1090,7 @@ def save_config(config: Config, config_path: Optional[Path] = None) -> None:
|
||||||
data = _dataclass_to_dict(config)
|
data = _dataclass_to_dict(config)
|
||||||
|
|
||||||
# Add header comment
|
# Add header comment
|
||||||
header = "# MeshAI Configuration\n# Generated by meshai --config\n\n"
|
header = "# MeshAI Configuration\n# Generated by meshai\n\n"
|
||||||
|
|
||||||
with open(config_path, "w") as f:
|
with open(config_path, "w") as f:
|
||||||
f.write(header)
|
f.write(header)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ from typing import Optional
|
||||||
|
|
||||||
from . import __version__
|
from . import __version__
|
||||||
from .backends import AnthropicBackend, GoogleBackend, LLMBackend, OpenAIBackend
|
from .backends import AnthropicBackend, GoogleBackend, LLMBackend, OpenAIBackend
|
||||||
from .cli import run_configurator
|
|
||||||
from .commands import CommandDispatcher
|
from .commands import CommandDispatcher
|
||||||
from .commands.dispatcher import create_dispatcher
|
from .commands.dispatcher import create_dispatcher
|
||||||
from .commands.status import set_start_time
|
from .commands.status import set_start_time
|
||||||
|
|
@ -876,9 +875,6 @@ def main() -> None:
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--version", "-V", action="version", version=f"%(prog)s {__version__}"
|
"--version", "-V", action="version", version=f"%(prog)s {__version__}"
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
|
||||||
"--config", "-c", action="store_true", help="Launch configuration tool"
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--config-file",
|
"--config-file",
|
||||||
"-f",
|
"-f",
|
||||||
|
|
@ -892,11 +888,6 @@ def main() -> None:
|
||||||
|
|
||||||
setup_logging(args.verbose)
|
setup_logging(args.verbose)
|
||||||
|
|
||||||
# Launch configurator if requested
|
|
||||||
if args.config:
|
|
||||||
run_configurator(args.config_file)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Load config - support both old (/data/config.yaml) and new (/data/config/) layouts
|
# Load config - support both old (/data/config.yaml) and new (/data/config/) layouts
|
||||||
config_path = args.config_file
|
config_path = args.config_file
|
||||||
config_dir = get_config_dir_from_path(config_path)
|
config_dir = get_config_dir_from_path(config_path)
|
||||||
|
|
@ -912,7 +903,7 @@ def main() -> None:
|
||||||
config = legacy_load(config_path)
|
config = legacy_load(config_path)
|
||||||
else:
|
else:
|
||||||
logger.warning(f"Config not found at {config_path} or {config_dir}")
|
logger.warning(f"Config not found at {config_path} or {config_dir}")
|
||||||
logger.info("Run 'meshai --config' to create one, or copy config.example.yaml")
|
logger.info("Copy config.example.yaml to get started, or configure via the dashboard")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Create and run bot
|
# Create and run bot
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ dependencies = [
|
||||||
"openai>=1.0.0",
|
"openai>=1.0.0",
|
||||||
"anthropic>=0.18.0",
|
"anthropic>=0.18.0",
|
||||||
"google-genai>=1.0.0",
|
"google-genai>=1.0.0",
|
||||||
"rich>=13.0.0",
|
|
||||||
"httpx>=0.25.0",
|
"httpx>=0.25.0",
|
||||||
"fastapi>=0.110.0",
|
"fastapi>=0.110.0",
|
||||||
"uvicorn[standard]>=0.27.0",
|
"uvicorn[standard]>=0.27.0",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ aiosqlite>=0.19.0
|
||||||
openai>=1.0.0
|
openai>=1.0.0
|
||||||
anthropic>=0.18.0
|
anthropic>=0.18.0
|
||||||
google-genai>=1.0.0
|
google-genai>=1.0.0
|
||||||
rich>=13.0.0
|
|
||||||
httpx>=0.25.0
|
httpx>=0.25.0
|
||||||
fastembed>=0.3.0
|
fastembed>=0.3.0
|
||||||
sqlite-vec>=0.1.0
|
sqlite-vec>=0.1.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue