feat: openclaw-style secrets (env.vars + \) and per-task model routing

- Replace python-dotenv with config.json env.vars block + \ substitution
- Add models section for per-task model routing (heartbeat, subagent, default)
- Heartbeat/subagent tasks can use different models/providers than main chat
- Remove python-dotenv from dependencies
- Update all docs to reflect new config approach
- Reorganize docs into project/ and research/ subdirectories
This commit is contained in:
2026-02-20 23:49:05 -05:00
parent 55c6767e69
commit 82c2640481
35 changed files with 2904 additions and 422 deletions

30
cli.py
View File

@@ -82,10 +82,6 @@ def chat(message):
"""One-shot chat with the AI."""
import logging
from dotenv import load_dotenv
load_dotenv()
save_default_config()
cfg = load_config()
@@ -125,10 +121,6 @@ def chat(message):
@cli.command()
def status():
"""Show runtime status."""
from dotenv import load_dotenv
load_dotenv()
save_default_config()
cfg = load_config()
@@ -167,10 +159,6 @@ def cron():
@cron.command("list")
def cron_list():
"""List scheduled jobs."""
from dotenv import load_dotenv
load_dotenv()
save_default_config()
try:
@@ -195,10 +183,6 @@ def cron_list():
@click.argument("job_id")
def cron_remove(job_id):
"""Remove a scheduled job."""
from dotenv import load_dotenv
load_dotenv()
save_default_config()
try:
@@ -278,10 +262,6 @@ def memory_search(query):
import asyncio
import logging
from dotenv import load_dotenv
load_dotenv()
save_default_config()
cfg = load_config()
@@ -315,10 +295,6 @@ def memory_sync():
import asyncio
import logging
from dotenv import load_dotenv
load_dotenv()
save_default_config()
cfg = load_config()
@@ -353,10 +329,6 @@ def doctor():
"""Run diagnostics."""
import shutil
from dotenv import load_dotenv
load_dotenv()
click.echo("🩺 Aetheel Doctor")
click.echo()
@@ -373,7 +345,7 @@ def doctor():
click.echo(f" ⚠️ No config file at {CONFIG_PATH}")
# Check workspace
cfg = load_config()
cfg = load_config() # also applies env.vars to process env
workspace = os.path.expanduser(cfg.memory.workspace)
if os.path.isdir(workspace):
click.echo(f" ✅ Workspace: {workspace}")