fix: refactor lazy imports to use common.py correctly.

This commit is contained in:
ajspig 2026-04-14 11:04:45 -04:00
parent dad75c2d37
commit 3485f9e474
10 changed files with 65 additions and 138 deletions

2
.gitignore vendored
View File

@ -182,7 +182,7 @@ docs/node_modules
timing_logs.csv
config.toml
config.json
.aider*
CRUSH.md

View File

@ -11,7 +11,7 @@ from honcho_cli.commands.workspace import _handle_error
from honcho_cli.output import print_error, print_result, status, use_json
from honcho_cli.validation import validate_resource_id
from honcho_cli.common import add_common_options
from honcho_cli.common import add_common_options, get_client, handle_cmd_flags
app = typer.Typer(help="Conclusion (observation) operations.")
add_common_options(app)
@ -27,8 +27,6 @@ def list_conclusions(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""List conclusions."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
client, config = get_client()
@ -76,8 +74,6 @@ def search(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Semantic search over conclusions."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
client, config = get_client()
@ -125,8 +121,6 @@ def create(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Create a conclusion."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
client, config = get_client()
@ -184,8 +178,6 @@ def delete(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Delete a conclusion."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
validate_resource_id(conclusion_id, "conclusion")

View File

@ -10,6 +10,7 @@ from __future__ import annotations
import typer
from honcho_cli.common import handle_cmd_flags
from honcho_cli.config import CLIConfig
from honcho_cli.output import print_result
@ -24,8 +25,6 @@ def config(
"""Show current config (api key redacted)."""
if ctx.invoked_subcommand is not None:
return
from honcho_cli.common import handle_cmd_flags
handle_cmd_flags(json_output=json_output)
cfg = CLIConfig.load()
print_result(cfg.redacted())

View File

@ -11,7 +11,7 @@ from honcho_cli.commands.workspace import _handle_error
from honcho_cli.output import print_result, status
from honcho_cli.validation import validate_resource_id
from honcho_cli.common import add_common_options
from honcho_cli.common import add_common_options, get_client, handle_cmd_flags
app = typer.Typer(help="Message operations.")
add_common_options(app)
@ -29,8 +29,6 @@ def list_messages(
) -> None:
"""List messages in a session."""
from honcho_cli.commands.session import _get_session_id
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -94,8 +92,6 @@ def get_message(
) -> None:
"""Get a single message by ID."""
from honcho_cli.commands.session import _get_session_id
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace)
validate_resource_id(message_id, "message")

View File

@ -11,14 +11,13 @@ from honcho_cli.commands.workspace import _config_to_dict, _handle_error
from honcho_cli.output import print_result, use_json
from honcho_cli.validation import validate_resource_id
from honcho_cli.common import add_common_options
from honcho_cli.common import add_common_options, get_client, get_resolved_config, handle_cmd_flags
app = typer.Typer(help="Peer debugging operations.")
add_common_options(app)
def _get_peer_id(peer_id: str | None) -> str:
from honcho_cli.main import get_resolved_config
config = get_resolved_config()
pid = peer_id or config.peer_id
@ -37,8 +36,6 @@ def list_peers(
) -> None:
"""List all peers in the workspace."""
from honcho_cli.commands.workspace import _raw_list
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace)
client, config = get_client()
@ -67,8 +64,6 @@ def inspect(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Inspect a peer: card, session count, recent conclusions."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
pid = _get_peer_id(peer_id)
@ -112,8 +107,6 @@ def card(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Get raw peer card content."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
pid = _get_peer_id(peer_id)
@ -136,8 +129,6 @@ def chat(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Query the dialectic about a peer."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
pid = _get_peer_id(None)
@ -162,8 +153,6 @@ def search(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Search a peer's messages."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
pid = _get_peer_id(None)
@ -195,8 +184,6 @@ def create_peer(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Create or get a peer."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
from honcho.api_types import PeerConfig
handle_cmd_flags(json_output=json_output, workspace=workspace)
@ -237,8 +224,6 @@ def get_metadata(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Get metadata for a peer."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
pid = _get_peer_id(peer_id)
@ -260,8 +245,6 @@ def set_metadata(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Set metadata for a peer."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
pid = _get_peer_id(None)
@ -294,8 +277,6 @@ def representation(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Get the formatted representation for a peer."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, peer=peer)
pid = _get_peer_id(peer_id)

View File

@ -11,14 +11,13 @@ from honcho_cli.commands.workspace import _config_to_dict, _handle_error
from honcho_cli.output import print_result, status, use_json
from honcho_cli.validation import validate_resource_id
from honcho_cli.common import add_common_options
from honcho_cli.common import add_common_options, get_client, get_resolved_config, handle_cmd_flags
app = typer.Typer(help="Session debugging operations.")
add_common_options(app)
def _get_session_id(session_id: str | None) -> str:
from honcho_cli.main import get_resolved_config
config = get_resolved_config()
sid = session_id or config.session_id
@ -38,8 +37,6 @@ def list_sessions(
) -> None:
"""List sessions in the workspace."""
from honcho_cli.commands.workspace import _raw_list
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace)
client, config = get_client()
@ -73,8 +70,6 @@ def inspect(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Inspect a session: peers, message count, summaries, config."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -112,8 +107,6 @@ def context(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Get session context (what an agent would see)."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -136,8 +129,6 @@ def summaries(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Get session summaries (short + long)."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -165,8 +156,6 @@ def delete(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Delete a session and all its data. Destructive — requires --yes or interactive confirm."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -217,8 +206,6 @@ def session_peers(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""List peers in a session."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -241,8 +228,6 @@ def add_peers(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Add peers to a session."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace)
sid = _get_session_id(session_id)
@ -264,8 +249,6 @@ def remove_peers(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Remove peers from a session."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace)
sid = _get_session_id(session_id)
@ -289,8 +272,6 @@ def search(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Search messages in a session."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -325,8 +306,6 @@ def representation(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Get the representation of a peer within a session."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -353,8 +332,6 @@ def get_metadata(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Get metadata for a session."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)
@ -377,8 +354,6 @@ def set_metadata(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Set metadata for a session."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace, session=session)
sid = _get_session_id(session_id)

View File

@ -20,6 +20,7 @@ from honcho_cli.config import (
CLIConfig,
)
from honcho_cli.branding import BANNER, BRAND, ICON_FAIL, ICON_OK, ICON_RUN
from honcho_cli.common import get_resolved_config
from honcho_cli.output import print_error, print_result
_console = Console(stderr=True)
@ -206,8 +207,6 @@ def doctor(
if not use_json():
_console.print(f"\n[bold {BRAND}]Honcho Doctor[/bold {BRAND}]\n")
from honcho_cli.main import get_resolved_config
config = get_resolved_config()
_add("Config file", CONFIG_FILE.exists(),
str(CONFIG_FILE) if CONFIG_FILE.exists() else f"{CONFIG_FILE} not found")

View File

@ -9,14 +9,13 @@ import typer
from honcho_cli.output import print_error, print_result, status, use_json
from honcho_cli.validation import validate_resource_id
from honcho_cli.common import add_common_options
from honcho_cli.common import add_common_options, get_client, get_resolved_config, handle_cmd_flags
app = typer.Typer(help="Workspace operations.")
add_common_options(app)
def _get_workspace_id(workspace_id: str | None) -> str:
from honcho_cli.main import get_resolved_config
config = get_resolved_config()
wid = workspace_id or config.workspace_id
@ -42,8 +41,6 @@ def list_workspaces(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""List all accessible workspaces."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output)
client, config = get_client(require_workspace=False)
@ -63,8 +60,6 @@ def inspect(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Inspect a workspace: peers, sessions, config."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace)
@ -116,8 +111,6 @@ def delete(
Requires --yes to skip confirmation, or will prompt interactively.
If sessions exist, requires --cascade to delete them first.
"""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output)
@ -175,8 +168,6 @@ def search(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Search messages across workspace."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace)
@ -208,8 +199,6 @@ def queue_status(
json_output: bool = typer.Option(False, "--json", help="Force JSON output"),
) -> None:
"""Get queue processing status."""
from honcho_cli.common import handle_cmd_flags
from honcho_cli.main import get_client
handle_cmd_flags(json_output=json_output, workspace=workspace)

View File

@ -1,4 +1,4 @@
"""Shared callback and command-level flag helpers.
"""Shared runtime state, client factory, and command-level flag helpers.
Flags like --json, -w, -p, -s work in TWO positions:
1. Group-level (before subcommand): honcho workspace --json list
@ -16,18 +16,70 @@ import typer
from honcho_cli.output import set_json_mode
# Global overrides from flags (commands read these)
_global_overrides: dict[str, str | None] = {
"workspace": None,
"peer": None,
"session": None,
}
def get_resolved_config():
"""Get config with global flag overrides applied.
Overrides flow through ``validate_resource_id`` so that a malformed
``-w``/``-p``/``-s`` value fails fast with a structured error rather than
reaching the API and surfacing as an opaque ``UNKNOWN_ERROR``.
"""
from honcho_cli.config import CLIConfig
from honcho_cli.validation import validate_resource_id
config = CLIConfig.load()
if _global_overrides["workspace"]:
config.workspace_id = validate_resource_id(_global_overrides["workspace"], "workspace")
if _global_overrides["peer"]:
config.peer_id = validate_resource_id(_global_overrides["peer"], "peer")
if _global_overrides["session"]:
config.session_id = validate_resource_id(_global_overrides["session"], "session")
return config
def get_client(*, require_workspace: bool = True):
"""Create a Honcho client from resolved config.
By default, refuses to build a client when no workspace is scoped the
SDK's get-or-create semantics would otherwise silently operate on an empty
workspace. Commands that legitimately run without a workspace (e.g.
``workspace list``) pass ``require_workspace=False``.
"""
from honcho import Honcho
from honcho_cli.config import get_client_kwargs
from honcho_cli.output import print_error
config = get_resolved_config()
if require_workspace and not config.workspace_id:
print_error(
"NO_WORKSPACE",
"No workspace scoped. Pass --workspace/-w or set HONCHO_WORKSPACE_ID.",
)
raise typer.Exit(1)
return Honcho(**get_client_kwargs(config)), config
def handle_cmd_flags(
json_output: bool = False,
workspace: str | None = None,
peer: str | None = None,
session: str | None = None,
**_kwargs,
) -> None:
"""Apply command-level flags. Idempotent if already set by group callback."""
if json_output:
set_json_mode(True)
from honcho_cli.main import _global_overrides
if workspace:
_global_overrides["workspace"] = workspace
if peer:
@ -50,8 +102,6 @@ def add_common_options(app: typer.Typer) -> None:
if json_output:
set_json_mode(True)
from honcho_cli.main import _global_overrides
if workspace:
_global_overrides["workspace"] = workspace
if peer:
@ -60,4 +110,4 @@ def add_common_options(app: typer.Typer) -> None:
_global_overrides["session"] = session
if ctx.invoked_subcommand is None:
ctx.get_help()
typer.echo(ctx.get_help())

View File

@ -11,6 +11,7 @@ import typer
from honcho_cli import __version__
from honcho_cli.branding import BANNER, BRAND
from honcho_cli.common import _global_overrides
from honcho_cli.output import set_json_mode
app = typer.Typer(
@ -75,61 +76,6 @@ def main(
raise typer.Exit()
# Global overrides from flags (commands read these)
_global_overrides: dict[str, str | None] = {
"workspace": None,
"peer": None,
"session": None,
}
def get_resolved_config():
"""Get config with global flag overrides applied.
Overrides flow through ``validate_resource_id`` so that a malformed
``-w``/``-p``/``-s`` value fails fast with a structured error rather than
reaching the API and surfacing as an opaque ``UNKNOWN_ERROR``.
"""
from honcho_cli.config import CLIConfig
from honcho_cli.validation import validate_resource_id
config = CLIConfig.load()
if _global_overrides["workspace"]:
config.workspace_id = validate_resource_id(_global_overrides["workspace"], "workspace")
if _global_overrides["peer"]:
config.peer_id = validate_resource_id(_global_overrides["peer"], "peer")
if _global_overrides["session"]:
config.session_id = validate_resource_id(_global_overrides["session"], "session")
return config
def get_client(*, require_workspace: bool = True):
"""Create a Honcho client from resolved config.
By default, refuses to build a client when no workspace is scoped the
SDK's get-or-create semantics would otherwise silently operate on an empty
workspace. Commands that legitimately run without a workspace (e.g.
``workspace list``) pass ``require_workspace=False``.
"""
import typer
from honcho import Honcho
from honcho_cli.config import get_client_kwargs
from honcho_cli.output import print_error
config = get_resolved_config()
if require_workspace and not config.workspace_id:
print_error(
"NO_WORKSPACE",
"No workspace scoped. Pass --workspace/-w or set HONCHO_WORKSPACE_ID.",
)
raise typer.Exit(1)
return Honcho(**get_client_kwargs(config)), config
# Register top-level commands
from honcho_cli.commands.setup import doctor, init