mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
243 lines
11 KiB
Go
243 lines
11 KiB
Go
package agent
|
||
|
||
import (
|
||
"fmt"
|
||
"strings"
|
||
)
|
||
|
||
type modelProviderSpec struct {
|
||
ID string
|
||
DisplayName string
|
||
DefaultModel string
|
||
CredentialLabelZH string
|
||
CredentialLabelEN string
|
||
SupportsCustomAPIURL bool
|
||
SupportsCustomModel bool
|
||
UsesWalletCredential bool
|
||
Recommended bool
|
||
RecommendedModelHints []string
|
||
}
|
||
|
||
func supportedModelProviders() []modelProviderSpec {
|
||
return []modelProviderSpec{
|
||
{ID: "deepseek", DisplayName: "DeepSeek", DefaultModel: "deepseek-chat", CredentialLabelZH: "API Key", CredentialLabelEN: "API key", SupportsCustomAPIURL: true, SupportsCustomModel: true},
|
||
{ID: "qwen", DisplayName: "Qwen", DefaultModel: "qwen3-max", CredentialLabelZH: "API Key", CredentialLabelEN: "API key", SupportsCustomAPIURL: true, SupportsCustomModel: true},
|
||
{ID: "openai", DisplayName: "OpenAI", DefaultModel: "gpt-5.1", CredentialLabelZH: "API Key", CredentialLabelEN: "API key", SupportsCustomAPIURL: true, SupportsCustomModel: true},
|
||
{ID: "claude", DisplayName: "Claude", DefaultModel: "claude-opus-4-6", CredentialLabelZH: "API Key", CredentialLabelEN: "API key", SupportsCustomAPIURL: true, SupportsCustomModel: true},
|
||
{ID: "gemini", DisplayName: "Google Gemini", DefaultModel: "gemini-3-pro-preview", CredentialLabelZH: "API Key", CredentialLabelEN: "API key", SupportsCustomAPIURL: true, SupportsCustomModel: true},
|
||
{ID: "grok", DisplayName: "Grok (xAI)", DefaultModel: "grok-3-latest", CredentialLabelZH: "API Key", CredentialLabelEN: "API key", SupportsCustomAPIURL: true, SupportsCustomModel: true},
|
||
{ID: "kimi", DisplayName: "Kimi (Moonshot)", DefaultModel: "moonshot-v1-auto", CredentialLabelZH: "API Key", CredentialLabelEN: "API key", SupportsCustomAPIURL: true, SupportsCustomModel: true},
|
||
{ID: "minimax", DisplayName: "MiniMax", DefaultModel: "MiniMax-M2.5", CredentialLabelZH: "API Key", CredentialLabelEN: "API key", SupportsCustomAPIURL: true, SupportsCustomModel: true},
|
||
{
|
||
ID: "claw402",
|
||
DisplayName: "Claw402 (Base USDC)",
|
||
DefaultModel: "deepseek",
|
||
CredentialLabelZH: "钱包私钥",
|
||
CredentialLabelEN: "wallet private key",
|
||
SupportsCustomAPIURL: false,
|
||
SupportsCustomModel: true,
|
||
UsesWalletCredential: true,
|
||
Recommended: true,
|
||
RecommendedModelHints: []string{"deepseek", "glm-5", "gpt-5.4", "claude-opus", "qwen-max", "grok-4.1"},
|
||
},
|
||
{
|
||
ID: "blockrun-base",
|
||
DisplayName: "BlockRun (Base Wallet)",
|
||
DefaultModel: "auto",
|
||
CredentialLabelZH: "钱包私钥",
|
||
CredentialLabelEN: "wallet private key",
|
||
SupportsCustomAPIURL: false,
|
||
SupportsCustomModel: false,
|
||
UsesWalletCredential: true,
|
||
},
|
||
{
|
||
ID: "blockrun-sol",
|
||
DisplayName: "BlockRun (Solana Wallet)",
|
||
DefaultModel: "auto",
|
||
CredentialLabelZH: "钱包私钥",
|
||
CredentialLabelEN: "wallet private key",
|
||
SupportsCustomAPIURL: false,
|
||
SupportsCustomModel: false,
|
||
UsesWalletCredential: true,
|
||
},
|
||
}
|
||
}
|
||
|
||
func modelProviderSpecByID(provider string) (modelProviderSpec, bool) {
|
||
provider = strings.ToLower(strings.TrimSpace(provider))
|
||
for _, spec := range supportedModelProviders() {
|
||
if spec.ID == provider {
|
||
return spec, true
|
||
}
|
||
}
|
||
return modelProviderSpec{}, false
|
||
}
|
||
|
||
func supportedModelProviderIDs() []string {
|
||
specs := supportedModelProviders()
|
||
out := make([]string, 0, len(specs))
|
||
for _, spec := range specs {
|
||
out = append(out, spec.ID)
|
||
}
|
||
return out
|
||
}
|
||
|
||
func defaultModelNameForProvider(provider string) string {
|
||
spec, ok := modelProviderSpecByID(provider)
|
||
if !ok {
|
||
return ""
|
||
}
|
||
return strings.TrimSpace(spec.DefaultModel)
|
||
}
|
||
|
||
func defaultModelConfigName(provider string) string {
|
||
spec, ok := modelProviderSpecByID(provider)
|
||
if !ok {
|
||
provider = strings.TrimSpace(provider)
|
||
if provider == "" {
|
||
return ""
|
||
}
|
||
return provider + " AI"
|
||
}
|
||
return spec.DisplayName
|
||
}
|
||
|
||
func modelProviderSupportsCustomAPIURL(provider string) bool {
|
||
spec, ok := modelProviderSpecByID(provider)
|
||
return ok && spec.SupportsCustomAPIURL
|
||
}
|
||
|
||
func modelProviderSupportsCustomModel(provider string) bool {
|
||
spec, ok := modelProviderSpecByID(provider)
|
||
return ok && spec.SupportsCustomModel
|
||
}
|
||
|
||
func modelProviderCredentialLabel(lang, provider string) string {
|
||
spec, ok := modelProviderSpecByID(provider)
|
||
if !ok {
|
||
if lang == "zh" {
|
||
return "API Key"
|
||
}
|
||
return "API key"
|
||
}
|
||
if lang == "zh" {
|
||
return spec.CredentialLabelZH
|
||
}
|
||
return spec.CredentialLabelEN
|
||
}
|
||
|
||
func modelProviderSummaryList(lang string) string {
|
||
parts := make([]string, 0, len(supportedModelProviders()))
|
||
for _, spec := range supportedModelProviders() {
|
||
if lang == "zh" {
|
||
item := fmt.Sprintf("%s(默认 %s)", spec.ID, spec.DefaultModel)
|
||
if spec.Recommended {
|
||
item += " [推荐]"
|
||
}
|
||
parts = append(parts, item)
|
||
continue
|
||
}
|
||
item := fmt.Sprintf("%s (default %s)", spec.ID, spec.DefaultModel)
|
||
if spec.Recommended {
|
||
item += " [recommended]"
|
||
}
|
||
parts = append(parts, item)
|
||
}
|
||
if lang == "zh" {
|
||
return strings.Join(parts, "、")
|
||
}
|
||
return strings.Join(parts, ", ")
|
||
}
|
||
|
||
func modelProviderChoicePrompt(lang string) string {
|
||
if lang == "zh" {
|
||
return "可选模型 provider:" + modelProviderSummaryList(lang) + "。这些 provider 是并列可选的:你可以直接选 `claw402`、DeepSeek / OpenAI / Claude / Gemini / Qwen / Kimi / Grok / MiniMax 这类 API Key provider,或者选 `blockrun-base` / `blockrun-sol` 这类钱包 provider。我们优先推荐 `claw402`,因为它按次付费、用 Base USDC 钱包支付、默认配置更省事。对于第一次使用的新手,也可以直接去产品配置页的模型配置里选择 `claw402`:那里支持直接创建 Base 钱包,并且可以直接扫码充值/支付。请先告诉我你想用哪个 provider。"
|
||
}
|
||
return "Available model providers: " + modelProviderSummaryList(lang) + ". These providers are peer options: you can choose `claw402`, an API-key provider such as DeepSeek / OpenAI / Claude / Gemini / Qwen / Kimi / Grok / MiniMax, or a wallet-based provider such as `blockrun-base` / `blockrun-sol`. We recommend `claw402` first because it is pay-per-use, uses Base USDC wallet payment, and has the simplest default setup. If this is your first time, you can also open the product's model config page, choose `claw402`, create a Base wallet there directly, and pay by scanning the QR/deposit flow. Tell me which provider you want first."
|
||
}
|
||
|
||
func modelProviderDetailedGuidance(lang, provider string) string {
|
||
spec, ok := modelProviderSpecByID(provider)
|
||
if !ok {
|
||
return ""
|
||
}
|
||
if lang == "zh" {
|
||
lines := []string{
|
||
fmt.Sprintf("你现在选的是 %s。", spec.DisplayName),
|
||
fmt.Sprintf("- 默认模型名:%s", spec.DefaultModel),
|
||
fmt.Sprintf("- 凭证类型:%s", spec.CredentialLabelZH),
|
||
}
|
||
if spec.SupportsCustomModel {
|
||
lines = append(lines, "- `custom_model_name` 可选;留空时默认用上面的默认模型。")
|
||
} else {
|
||
lines = append(lines, "- 这个 provider 不需要单独填写 `custom_model_name`。")
|
||
}
|
||
if spec.SupportsCustomAPIURL {
|
||
lines = append(lines, "- `custom_api_url` 可选;留空时使用官方默认地址。")
|
||
} else {
|
||
lines = append(lines, "- 这个 provider 不需要 `custom_api_url`。")
|
||
}
|
||
if len(spec.RecommendedModelHints) > 0 {
|
||
lines = append(lines, "- 常见可选模型:"+strings.Join(spec.RecommendedModelHints, "、"))
|
||
}
|
||
if provider == "claw402" {
|
||
lines = append(lines, "- 这是我们优先推荐的 provider:按次付费、Base USDC 钱包支付,对新手最省事。")
|
||
lines = append(lines, "- 如果你是第一次用,也可以直接去配置页的模型配置里选择 `claw402`,那里支持直接创建 Base 钱包,并可直接扫码充值/支付。")
|
||
}
|
||
return strings.Join(lines, "\n")
|
||
}
|
||
lines := []string{
|
||
fmt.Sprintf("You selected %s.", spec.DisplayName),
|
||
fmt.Sprintf("- Default model: %s", spec.DefaultModel),
|
||
fmt.Sprintf("- Credential type: %s", spec.CredentialLabelEN),
|
||
}
|
||
if spec.SupportsCustomModel {
|
||
lines = append(lines, "- `custom_model_name` is optional; if omitted, the default model will be used.")
|
||
} else {
|
||
lines = append(lines, "- This provider does not need a separate `custom_model_name`.")
|
||
}
|
||
if spec.SupportsCustomAPIURL {
|
||
lines = append(lines, "- `custom_api_url` is optional; if omitted, the official default endpoint will be used.")
|
||
} else {
|
||
lines = append(lines, "- This provider does not need `custom_api_url`.")
|
||
}
|
||
if len(spec.RecommendedModelHints) > 0 {
|
||
lines = append(lines, "- Common model choices: "+strings.Join(spec.RecommendedModelHints, ", "))
|
||
}
|
||
if provider == "claw402" {
|
||
lines = append(lines, "- This is our recommended provider: pay-per-use, Base USDC wallet payment, and the easiest setup for first-time users.")
|
||
lines = append(lines, "- If this is your first time, you can also open the model config page, choose `claw402`, create a Base wallet there directly, and pay through the QR/deposit flow.")
|
||
}
|
||
return strings.Join(lines, "\n")
|
||
}
|
||
|
||
func modelProviderCredentialGuidance(lang, provider string) string {
|
||
spec, ok := modelProviderSpecByID(provider)
|
||
if !ok {
|
||
return ""
|
||
}
|
||
provider = strings.TrimSpace(spec.ID)
|
||
if lang == "zh" {
|
||
switch provider {
|
||
case "claw402":
|
||
return "claw402 这里要填的是 Base 链 EVM 钱包私钥。\n- 如果你是第一次用,最省事的方式是直接去配置页的模型配置里选择 `claw402`。\n- 那里可以一键快速创建钱包,界面会直接展示新钱包私钥,并且提供 Base USDC 充值入口。\n- 创建后请立刻备份私钥;系统会用它完成 claw402 支付和模型调用。\n- 如果你已经有 MetaMask、Rabby、Coinbase Wallet 这类 Base/EVM 钱包,也可以从钱包里导出现有私钥再发我。"
|
||
case "blockrun-base":
|
||
return "blockrun-base 这里要填的是 Base 链 EVM 钱包私钥。你可以从现有 EVM 钱包导出私钥后发我。"
|
||
case "blockrun-sol":
|
||
return "blockrun-sol 这里要填的是 Solana 钱包私钥。你可以从现有 Solana 钱包导出私钥后发我。"
|
||
default:
|
||
return fmt.Sprintf("%s 这里要填的是 %s。你把完整值发我就行,我会继续当前模型草稿。", spec.DisplayName, spec.CredentialLabelZH)
|
||
}
|
||
}
|
||
switch provider {
|
||
case "claw402":
|
||
return "For claw402, this field expects a Base-chain EVM wallet private key.\n- If this is your first time, the easiest path is to open the model config page and choose `claw402`.\n- That flow can quickly create a wallet for you, show the new private key, and provide a Base USDC deposit path.\n- Back up the key immediately after creation; the system uses it for claw402 payments and model access.\n- If you already use MetaMask, Rabby, or Coinbase Wallet, you can also export an existing Base/EVM wallet private key and send it to me."
|
||
case "blockrun-base":
|
||
return "For blockrun-base, this field expects a Base-chain EVM wallet private key. You can export it from an existing EVM wallet and send it to me."
|
||
case "blockrun-sol":
|
||
return "For blockrun-sol, this field expects a Solana wallet private key. You can export it from an existing Solana wallet and send it to me."
|
||
default:
|
||
return fmt.Sprintf("For %s, this field expects your %s. Send me the full value and I'll continue the current model draft.", spec.DisplayName, spec.CredentialLabelEN)
|
||
}
|
||
}
|