feat: add Zhipu API support and set glm-4.7-flash as default model
This commit is contained in:
parent
959c4dadf8
commit
2dd284661d
@ -68,7 +68,7 @@ def onboard():
|
|||||||
console.print(f"\n{__logo__} nanobot is ready!")
|
console.print(f"\n{__logo__} nanobot is ready!")
|
||||||
console.print("\nNext steps:")
|
console.print("\nNext steps:")
|
||||||
console.print(" 1. Add your API key to [cyan]~/.nanobot/config.json[/cyan]")
|
console.print(" 1. Add your API key to [cyan]~/.nanobot/config.json[/cyan]")
|
||||||
console.print(" Get one at: https://openrouter.ai/keys")
|
console.print(" Get one at: https://openrouter.ai/keys or https://bigmodel.cn/ (Zhipu AI)")
|
||||||
console.print(" 2. Chat: [cyan]nanobot agent -m \"Hello!\"[/cyan]")
|
console.print(" 2. Chat: [cyan]nanobot agent -m \"Hello!\"[/cyan]")
|
||||||
console.print("\n[dim]Want Telegram/WhatsApp? See: https://github.com/HKUDS/nanobot#-chat-apps[/dim]")
|
console.print("\n[dim]Want Telegram/WhatsApp? See: https://github.com/HKUDS/nanobot#-chat-apps[/dim]")
|
||||||
|
|
||||||
@ -624,10 +624,12 @@ def status():
|
|||||||
has_openrouter = bool(config.providers.openrouter.api_key)
|
has_openrouter = bool(config.providers.openrouter.api_key)
|
||||||
has_anthropic = bool(config.providers.anthropic.api_key)
|
has_anthropic = bool(config.providers.anthropic.api_key)
|
||||||
has_openai = bool(config.providers.openai.api_key)
|
has_openai = bool(config.providers.openai.api_key)
|
||||||
|
has_zhipu = bool(config.providers.zhipu.api_key)
|
||||||
|
|
||||||
console.print(f"OpenRouter API: {'[green]✓[/green]' if has_openrouter else '[dim]not set[/dim]'}")
|
console.print(f"OpenRouter API: {'[green]✓[/green]' if has_openrouter else '[dim]not set[/dim]'}")
|
||||||
console.print(f"Anthropic API: {'[green]✓[/green]' if has_anthropic else '[dim]not set[/dim]'}")
|
console.print(f"Anthropic API: {'[green]✓[/green]' if has_anthropic else '[dim]not set[/dim]'}")
|
||||||
console.print(f"OpenAI API: {'[green]✓[/green]' if has_openai else '[dim]not set[/dim]'}")
|
console.print(f"OpenAI API: {'[green]✓[/green]' if has_openai else '[dim]not set[/dim]'}")
|
||||||
|
console.print(f"Zhipu AI API: {'[green]✓[/green]' if has_zhipu else '[dim]not set[/dim]'}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@ -28,7 +28,7 @@ class ChannelsConfig(BaseModel):
|
|||||||
class AgentDefaults(BaseModel):
|
class AgentDefaults(BaseModel):
|
||||||
"""Default agent configuration."""
|
"""Default agent configuration."""
|
||||||
workspace: str = "~/.nanobot/workspace"
|
workspace: str = "~/.nanobot/workspace"
|
||||||
model: str = "anthropic/claude-opus-4-5"
|
model: str = "glm-4.7-flash"
|
||||||
max_tokens: int = 8192
|
max_tokens: int = 8192
|
||||||
temperature: float = 0.7
|
temperature: float = 0.7
|
||||||
max_tool_iterations: int = 20
|
max_tool_iterations: int = 20
|
||||||
@ -50,6 +50,7 @@ class ProvidersConfig(BaseModel):
|
|||||||
anthropic: ProviderConfig = Field(default_factory=ProviderConfig)
|
anthropic: ProviderConfig = Field(default_factory=ProviderConfig)
|
||||||
openai: ProviderConfig = Field(default_factory=ProviderConfig)
|
openai: ProviderConfig = Field(default_factory=ProviderConfig)
|
||||||
openrouter: ProviderConfig = Field(default_factory=ProviderConfig)
|
openrouter: ProviderConfig = Field(default_factory=ProviderConfig)
|
||||||
|
zhipu: ProviderConfig = Field(default_factory=ProviderConfig)
|
||||||
|
|
||||||
|
|
||||||
class GatewayConfig(BaseModel):
|
class GatewayConfig(BaseModel):
|
||||||
@ -88,18 +89,21 @@ class Config(BaseSettings):
|
|||||||
return Path(self.agents.defaults.workspace).expanduser()
|
return Path(self.agents.defaults.workspace).expanduser()
|
||||||
|
|
||||||
def get_api_key(self) -> str | None:
|
def get_api_key(self) -> str | None:
|
||||||
"""Get API key in priority order: OpenRouter > Anthropic > OpenAI."""
|
"""Get API key in priority order: OpenRouter > Anthropic > OpenAI > Zhipu."""
|
||||||
return (
|
return (
|
||||||
self.providers.openrouter.api_key or
|
self.providers.openrouter.api_key or
|
||||||
self.providers.anthropic.api_key or
|
self.providers.anthropic.api_key or
|
||||||
self.providers.openai.api_key or
|
self.providers.openai.api_key or
|
||||||
|
self.providers.zhipu.api_key or
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_api_base(self) -> str | None:
|
def get_api_base(self) -> str | None:
|
||||||
"""Get API base URL if using OpenRouter."""
|
"""Get API base URL if using OpenRouter or Zhipu."""
|
||||||
if self.providers.openrouter.api_key:
|
if self.providers.openrouter.api_key:
|
||||||
return self.providers.openrouter.api_base or "https://openrouter.ai/api/v1"
|
return self.providers.openrouter.api_base or "https://openrouter.ai/api/v1"
|
||||||
|
if self.providers.zhipu.api_key:
|
||||||
|
return self.providers.zhipu.api_base
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
|||||||
@ -21,7 +21,7 @@ class LiteLLMProvider(LLMProvider):
|
|||||||
self,
|
self,
|
||||||
api_key: str | None = None,
|
api_key: str | None = None,
|
||||||
api_base: str | None = None,
|
api_base: str | None = None,
|
||||||
default_model: str = "anthropic/claude-opus-4-5"
|
default_model: str = "glm-4.7-flash"
|
||||||
):
|
):
|
||||||
super().__init__(api_key, api_base)
|
super().__init__(api_key, api_base)
|
||||||
self.default_model = default_model
|
self.default_model = default_model
|
||||||
@ -41,6 +41,8 @@ class LiteLLMProvider(LLMProvider):
|
|||||||
os.environ.setdefault("ANTHROPIC_API_KEY", api_key)
|
os.environ.setdefault("ANTHROPIC_API_KEY", api_key)
|
||||||
elif "openai" in default_model or "gpt" in default_model:
|
elif "openai" in default_model or "gpt" in default_model:
|
||||||
os.environ.setdefault("OPENAI_API_KEY", api_key)
|
os.environ.setdefault("OPENAI_API_KEY", api_key)
|
||||||
|
elif "zhipu" in default_model or "glm" in default_model or "zai" in default_model:
|
||||||
|
os.environ.setdefault("ZHIPUAI_API_KEY", api_key)
|
||||||
|
|
||||||
if api_base:
|
if api_base:
|
||||||
litellm.api_base = api_base
|
litellm.api_base = api_base
|
||||||
@ -75,6 +77,15 @@ class LiteLLMProvider(LLMProvider):
|
|||||||
if self.is_openrouter and not model.startswith("openrouter/"):
|
if self.is_openrouter and not model.startswith("openrouter/"):
|
||||||
model = f"openrouter/{model}"
|
model = f"openrouter/{model}"
|
||||||
|
|
||||||
|
# For Zhipu/Z.ai, ensure prefix is present
|
||||||
|
# Handle cases like "glm-4.7-flash" -> "zhipu/glm-4.7-flash"
|
||||||
|
if ("glm" in model.lower() or "zhipu" in model.lower()) and not (
|
||||||
|
model.startswith("zhipu/") or
|
||||||
|
model.startswith("zai/") or
|
||||||
|
model.startswith("openrouter/")
|
||||||
|
):
|
||||||
|
model = f"zhipu/{model}"
|
||||||
|
|
||||||
kwargs: dict[str, Any] = {
|
kwargs: dict[str, Any] = {
|
||||||
"model": model,
|
"model": model,
|
||||||
"messages": messages,
|
"messages": messages,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user