Abigail/embedding OpenAI base url (#1068)

* fix(cli): write embedding base url in --setup

* feat(cli): surface local stack on the welcome screen
This commit is contained in:
ajspig 2026-08-25 17:14:53 -04:00 committed by GitHub
parent 9e60f73c7f
commit cccfa988f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 59 additions and 16 deletions

View File

@ -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

View File

@ -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 <command> \[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 <peer> -w <workspace>","query the Dialectic about a peer"),
("honcho peer inspect -p <peer> -w <workspace>","dashboard: peer card + recent conclusions + configuration"),
("honcho peer chat \"...\" -p <peer> -w <workspace>", "query the Dialectic about a peer"),
("honcho peer inspect -p <peer> -w <workspace>", "dashboard: peer card + recent conclusions + configuration"),
("honcho peer representation -p <peer> -w <workspace>", "global peer representation"),
("honcho peer representation -p <peer> -w <workspace> -s <session>", "session-scoped peer representation"),
("honcho peer card -p <peer> -w <workspace>", "synthesized identity: traits, preferences, instructions"),
("honcho conclusion list -p <peer> -w <workspace>", "browse peer conclusions"),
("honcho conclusion list -p <peer> -w <workspace>", "browse peer conclusions"),
("honcho session view / context -s <session>", "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))

View File

@ -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(

View File

@ -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(