mirror of
https://github.com/usestrix/strix.git
synced 2026-08-22 02:58:39 +02:00
Sign in with a ChatGPT subscription for inference (#854)
Co-authored-by: Jonathan Singer <jonathansinger@Jonathans-MacBook-Pro.local> Co-authored-by: Jonathan Singer <jonathansinger@Mac-3004.lan> Co-authored-by: Ahmed Allam <ahmed39652003@gmail.com>
This commit is contained in:
co-authored by
Jonathan Singer
Jonathan Singer
Ahmed Allam
parent
93af2b94a2
commit
cd8270c98b
+66
-10
@@ -20,6 +20,7 @@ from rich.text import Text
|
||||
|
||||
from strix.config import (
|
||||
apply_config_override,
|
||||
codex,
|
||||
load_settings,
|
||||
persist_current,
|
||||
)
|
||||
@@ -92,6 +93,16 @@ def validate_environment() -> None:
|
||||
|
||||
settings = load_settings()
|
||||
|
||||
if codex.subscription_model(settings.llm.model):
|
||||
if not codex.is_authenticated():
|
||||
console.print(
|
||||
f"[red]STRIX_LLM={settings.llm.model} uses your ChatGPT subscription, "
|
||||
"but you're not signed in.[/] Run [cyan]strix auth login chatgpt[/] first."
|
||||
)
|
||||
sys.exit(1)
|
||||
logger.info("Environment OK (ChatGPT subscription)")
|
||||
return
|
||||
|
||||
if not settings.llm.model:
|
||||
missing_required_vars.append("STRIX_LLM")
|
||||
|
||||
@@ -274,6 +285,29 @@ def _provider_import_hint(exc: BaseException, model: str) -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
def _subscription_error_hint(exc: BaseException) -> str | None:
|
||||
"""Return an actionable hint for a known ChatGPT-subscription error, or None."""
|
||||
if not codex.subscription_model(load_settings().llm.model):
|
||||
return None
|
||||
joined = " ".join(_exception_messages(exc)).lower()
|
||||
if "not supported when using codex with a chatgpt account" in joined:
|
||||
return (
|
||||
"This model isn't available on your ChatGPT subscription. "
|
||||
"Set STRIX_LLM to a model your plan includes (e.g. chatgpt/gpt-5.4)."
|
||||
)
|
||||
if (
|
||||
"error code: 401" in joined
|
||||
or "http 401" in joined
|
||||
or "unauthorized" in joined
|
||||
or "invalid_grant" in joined
|
||||
):
|
||||
return (
|
||||
"Your ChatGPT sign-in has expired or was revoked. Sign in again:\n"
|
||||
" strix auth login chatgpt"
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
async def warm_up_llm(show_model_warning: bool = True) -> None:
|
||||
console = Console()
|
||||
logger.info("Warming up LLM connection")
|
||||
@@ -283,8 +317,8 @@ async def warm_up_llm(show_model_warning: bool = True) -> None:
|
||||
settings = load_settings()
|
||||
configure_sdk_model_defaults(settings)
|
||||
llm = settings.llm
|
||||
|
||||
raw_model = (llm.model or "").strip()
|
||||
|
||||
if (
|
||||
raw_model
|
||||
and "/" not in raw_model
|
||||
@@ -363,20 +397,33 @@ async def warm_up_llm(show_model_warning: bool = True) -> None:
|
||||
except Exception as e:
|
||||
logger.exception("LLM warm-up failed")
|
||||
error_text = Text()
|
||||
error_text.append("LLM CONNECTION FAILED", style="bold red")
|
||||
error_text.append("\n\n", style="white")
|
||||
error_text.append("Could not establish connection to the language model.\n", style="white")
|
||||
error_text.append("Please check your configuration and try again.\n", style="white")
|
||||
hint = _provider_import_hint(e, raw_model)
|
||||
if hint is not None:
|
||||
error_text.append(f"\n{hint}\n", style="bold yellow")
|
||||
error_text.append(f"\nError: {e}", style="dim white")
|
||||
sub_hint = _subscription_error_hint(e)
|
||||
if sub_hint is not None:
|
||||
# The model/backend answered with a clear, actionable rejection —
|
||||
# show that instead of a generic "connection failed".
|
||||
border_style = "yellow"
|
||||
error_text.append("MODEL NOT AVAILABLE ON SUBSCRIPTION", style="bold yellow")
|
||||
error_text.append("\n\n", style="white")
|
||||
error_text.append(f"{sub_hint}\n", style="white")
|
||||
error_text.append(f"\nDetails: {e}", style="dim white")
|
||||
else:
|
||||
border_style = "red"
|
||||
error_text.append("LLM CONNECTION FAILED", style="bold red")
|
||||
error_text.append("\n\n", style="white")
|
||||
error_text.append(
|
||||
"Could not establish connection to the language model.\n", style="white"
|
||||
)
|
||||
error_text.append("Please check your configuration and try again.\n", style="white")
|
||||
hint = _provider_import_hint(e, raw_model)
|
||||
if hint is not None:
|
||||
error_text.append(f"\n{hint}\n", style="bold yellow")
|
||||
error_text.append(f"\nError: {e}", style="dim white")
|
||||
|
||||
panel = Panel(
|
||||
error_text,
|
||||
title="[bold white]STRIX",
|
||||
title_align="left",
|
||||
border_style="red",
|
||||
border_style=border_style,
|
||||
padding=(1, 2),
|
||||
)
|
||||
|
||||
@@ -682,6 +729,7 @@ def _persist_run_record(args: argparse.Namespace) -> None:
|
||||
"status": "running",
|
||||
"start_time": datetime.now(UTC).isoformat(),
|
||||
"end_time": None,
|
||||
"auth_mode": codex.auth_mode(load_settings().llm.model),
|
||||
"targets_info": args.targets_info,
|
||||
"scan_mode": args.scan_mode,
|
||||
"instruction": args.instruction,
|
||||
@@ -882,6 +930,13 @@ def main() -> None:
|
||||
run_view(sys.argv[2:])
|
||||
return
|
||||
|
||||
# `strix auth …` manages model-subscription sign-in and exits; it needs no
|
||||
# target, Docker, or scan setup.
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "auth":
|
||||
from strix.interface.auth_cli import run_auth
|
||||
|
||||
sys.exit(run_auth(sys.argv[2:]))
|
||||
|
||||
args = parse_arguments()
|
||||
|
||||
if args.config:
|
||||
@@ -949,6 +1004,7 @@ def main() -> None:
|
||||
|
||||
_telemetry_start_kwargs = {
|
||||
"model": load_settings().llm.model,
|
||||
"auth_mode": codex.auth_mode(load_settings().llm.model),
|
||||
"scan_mode": args.scan_mode,
|
||||
"is_whitebox": is_whitebox_scan(args.targets_info),
|
||||
"interactive": not args.non_interactive,
|
||||
|
||||
Reference in New Issue
Block a user