diff --git a/nanobot/cli/commands.py b/nanobot/cli/commands.py index 235bfdc..affd421 100644 --- a/nanobot/cli/commands.py +++ b/nanobot/cli/commands.py @@ -292,7 +292,7 @@ def _make_provider(config: Config): if provider_name == "openai_codex" or model.startswith("openai-codex/"): return OpenAICodexProvider(default_model=model) - if not model.startswith("bedrock/") and not (p and p.api_key): + if not model.startswith("bedrock/") and not (p and p.api_key) and provider_name != "github_copilot": console.print("[red]Error: No API key configured.[/red]") console.print("Set one in ~/.nanobot/config.json under providers section") raise typer.Exit(1) diff --git a/nanobot/config/schema.py b/nanobot/config/schema.py index 15b6bb2..64609ec 100644 --- a/nanobot/config/schema.py +++ b/nanobot/config/schema.py @@ -193,6 +193,7 @@ class ProvidersConfig(BaseModel): minimax: ProviderConfig = Field(default_factory=ProviderConfig) aihubmix: ProviderConfig = Field(default_factory=ProviderConfig) # AiHubMix API gateway openai_codex: ProviderConfig = Field(default_factory=ProviderConfig) # OpenAI Codex (OAuth) + github_copilot: ProviderConfig = Field(default_factory=ProviderConfig) # Github Copilot (OAuth) class GatewayConfig(BaseModel): diff --git a/nanobot/providers/registry.py b/nanobot/providers/registry.py index 59af5e1..1e760d6 100644 --- a/nanobot/providers/registry.py +++ b/nanobot/providers/registry.py @@ -177,6 +177,25 @@ PROVIDERS: tuple[ProviderSpec, ...] = ( is_oauth=True, # OAuth-based authentication ), + # Github Copilot: uses OAuth, not API key. + ProviderSpec( + name="github_copilot", + keywords=("github_copilot", "copilot"), + env_key="", # OAuth-based, no API key + display_name="Github Copilot", + litellm_prefix="github_copilot", # github_copilot/model → github_copilot/model + skip_prefixes=("github_copilot/",), + env_extras=(), + is_gateway=False, + is_local=False, + detect_by_key_prefix="", + detect_by_base_keyword="", + default_api_base="", + strip_model_prefix=False, + model_overrides=(), + is_oauth=True, # OAuth-based authentication + ), + # DeepSeek: needs "deepseek/" prefix for LiteLLM routing. ProviderSpec( name="deepseek",