From cccfa988f886ed6ba60dc4bc1338c585907bf223 Mon Sep 17 00:00:00 2001 From: ajspig <46900795+ajspig@users.noreply.github.com> Date: Tue, 25 Aug 2026 17:14:53 -0400 Subject: [PATCH] Abigail/embedding OpenAI base url (#1068) * fix(cli): write embedding base url in --setup * feat(cli): surface local stack on the welcome screen --- honcho-cli/CHANGELOG.md | 4 ++++ honcho-cli/src/honcho_cli/_help.py | 23 ++++++++++++------- honcho-cli/src/honcho_cli/local/setup.py | 20 ++++++++++------- honcho-cli/tests/test_setup.py | 28 ++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/honcho-cli/CHANGELOG.md b/honcho-cli/CHANGELOG.md index a8c1b12f..1a1b50e3 100644 --- a/honcho-cli/CHANGELOG.md +++ b/honcho-cli/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed + +- `--setup` for openai-compatible writes `EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL` into the profile `.env` alongside `LLM_OPENAI_BASE_URL` + ## [0.1.3] - 2026-08-25 ### Added diff --git a/honcho-cli/src/honcho_cli/_help.py b/honcho-cli/src/honcho_cli/_help.py index 5e8b48be..936e26b7 100644 --- a/honcho-cli/src/honcho_cli/_help.py +++ b/honcho-cli/src/honcho_cli/_help.py @@ -59,16 +59,21 @@ def _welcome_panel(title: str, rows: list[tuple[str, str]]) -> Panel: def print_welcome(console: Console) -> None: - """Render the curated 3-panel welcome (banner + getting started / memory / commands).""" + """Render the curated welcome (banner + getting started / local stack / commands / memory).""" if use_json(): return console.print(f"[bold {BRAND}]{BANNER}[/bold {BRAND}]") console.print(f" [dim]v{__version__}[/dim]\n", highlight=False) start_rows = [ - ("honcho init", "configure API key and server URL"), - ("honcho start", "run a local Honcho stack (Docker)"), - ("honcho doctor", "verify connection and workspace health"), + ("honcho init", "configure API key and server URL"), + ("honcho start [--setup basic]", "run a local Honcho stack (Docker)"), + ("honcho doctor", "verify connection and workspace health"), + ] + stack_rows = [ + ("honcho start / status / stop", "lifecycle for the local Docker stack"), + ("honcho start --setup basic", "interactive LLM + feature wizard"), + ("HONCHO_BASE_URL=http://127.0.0.1:8000", "prefix any command — CLI stays on api.honcho.dev until you set this"), ] cmd_rows = [ ("[dim]pattern[/dim]", r"[dim]honcho \[args] \[-w workspace] \[-p peer] \[-s session][/dim]"), @@ -85,14 +90,15 @@ def print_welcome(console: Console) -> None: ("config", "inspect current configuration"), ] memory_rows = [ - ("honcho peer chat \"...\" -p -w ","query the Dialectic about a peer"), - ("honcho peer inspect -p -w ","dashboard: peer card + recent conclusions + configuration"), + ("honcho peer chat \"...\" -p -w ", "query the Dialectic about a peer"), + ("honcho peer inspect -p -w ", "dashboard: peer card + recent conclusions + configuration"), ("honcho peer representation -p -w ", "global peer representation"), ("honcho peer representation -p -w -s ", "session-scoped peer representation"), ("honcho peer card -p -w ", "synthesized identity: traits, preferences, instructions"), - ("honcho conclusion list -p -w ", "browse peer conclusions"), + ("honcho conclusion list -p -w ", "browse peer conclusions"), + ("honcho session view / context -s ", "transcript, or what an agent would see"), + ("honcho workspace queue-status", "is the deriver processing?"), ] - option_rows = [ ("-w / --workspace", "scope to a workspace"), ("-p / --peer", "scope to a peer"), @@ -102,6 +108,7 @@ def print_welcome(console: Console) -> None: ] console.print(_welcome_panel("getting started", start_rows)) + console.print(_welcome_panel("local stack", stack_rows)) console.print(_welcome_panel("commands", cmd_rows)) console.print(_welcome_panel("memory", memory_rows)) console.print(_welcome_panel("options", option_rows)) diff --git a/honcho-cli/src/honcho_cli/local/setup.py b/honcho-cli/src/honcho_cli/local/setup.py index 5b21728e..242f47d6 100644 --- a/honcho-cli/src/honcho_cli/local/setup.py +++ b/honcho-cli/src/honcho_cli/local/setup.py @@ -14,11 +14,7 @@ from pathlib import Path import typer from rich.console import Console -from honcho_cli.local.env import ( - is_placeholder_key, - read_env_file, - settings_from_environ, -) +from honcho_cli.local.env import is_placeholder_key, read_env_file, settings_from_environ from honcho_cli.output import print_error SETUP_MODES = ("basic", "advanced") @@ -145,6 +141,10 @@ def answers_to_env(answers: SetupAnswers) -> dict[str, str]: env[_PROVIDER_KEY_ENV[answers.provider]] = answers.api_key if answers.base_url: env["LLM_OPENAI_BASE_URL"] = answers.base_url + # Embeddings do not inherit this URL; write it so OpenRouter/vLLM + # keys are not sent to api.openai.com. + if (answers.embedding_transport or "openai") == "openai": + env["EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL"] = answers.base_url if answers.embedding_api_key and answers.embedding_key_transport: embed_key = ( @@ -188,9 +188,13 @@ def answers_to_env(answers: SetupAnswers) -> dict[str, str]: def answers_drop_keys(answers: SetupAnswers) -> tuple[str, ...]: """Keys to remove so a previous wizard run cannot leak into this one.""" - if answers.provider == "openai-compatible": - return () - return ("LLM_OPENAI_BASE_URL",) + drop: list[str] = [] + if answers.provider != "openai-compatible": + drop.append("LLM_OPENAI_BASE_URL") + embed_openai = (answers.embedding_transport or "openai") == "openai" + if answers.provider != "openai-compatible" or not embed_openai: + drop.append("EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL") + return tuple(drop) def run_setup( diff --git a/honcho-cli/tests/test_setup.py b/honcho-cli/tests/test_setup.py index 5a411946..6fa6ddad 100644 --- a/honcho-cli/tests/test_setup.py +++ b/honcho-cli/tests/test_setup.py @@ -5,6 +5,7 @@ from __future__ import annotations from honcho_cli.local.setup import ( DIALECTIC_LEVELS, SetupAnswers, + answers_drop_keys, answers_to_env, chat_model_default, load_toml_setup_defaults, @@ -46,6 +47,33 @@ def test_basic_anthropic_keeps_openai_embeddings_default(): assert "EMBEDDING_MODEL_CONFIG__TRANSPORT" not in env +def test_openai_compatible_copies_base_url_to_embeddings(): + env = answers_to_env( + SetupAnswers( + mode="basic", + provider="openai-compatible", + api_key="sk-or-test", + chat_model="gpt-test", + base_url="https://openrouter.ai/api/v1", + ) + ) + assert env["LLM_OPENAI_BASE_URL"] == "https://openrouter.ai/api/v1" + assert ( + env["EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL"] + == "https://openrouter.ai/api/v1" + ) + + +def test_leaving_openai_compatible_drops_proxy_urls(): + dropped = answers_drop_keys( + SetupAnswers( + mode="basic", provider="openai", api_key="sk", chat_model="gpt-test" + ) + ) + assert "LLM_OPENAI_BASE_URL" in dropped + assert "EMBEDDING_MODEL_CONFIG__OVERRIDES__BASE_URL" in dropped + + def test_chat_default_comes_from_image_toml(tmp_path): path = tmp_path / "config.toml" path.write_text(