config.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. """
  2. agent67.core.config — 配置与常量
  3. """
  4. from __future__ import annotations
  5. import os
  6. import shutil
  7. BANNER = """
  8. ╔══════════════════════════════════════════════════════════╗
  9. ║ 🐂 lambda v3 — Java/Python 全栈 + ML 专家 ║
  10. ║ powered by lambdagent (42 tools + PaaS services) ║
  11. ╠══════════════════════════════════════════════════════════╣
  12. ║ ║
  13. ║ 📁 文件/代码编辑 🔍 代码搜索 (6种语言) ║
  14. ║ 💻 Shell + Git 🌐 Web 搜索/获取 ║
  15. ║ 📓 Notebook/文档生成 🧠 知识库 + OCR ║
  16. ║ 🧪 自动化测试 💾 持久记忆 + 学习 ║
  17. ║ 📋 任务/调度/通知 🖥️ 系统/浏览器/截屏 ║
  18. ║ ║
  19. ║ exit 退出 | trace 追踪 | stats 统计 | history 历史 ║
  20. ╚══════════════════════════════════════════════════════════╝
  21. """
  22. WAKE_WORD = "lambda"
  23. # 后端类型常量
  24. BACKEND_CLAUDE_CODE = "claude_code"
  25. BACKEND_OLLAMA = "ollama"
  26. BACKEND_API = "api"
  27. def detect_backend() -> tuple[str, bool, str]:
  28. """
  29. 检测可用的 LLM 后端。
  30. 返回: (model_name, use_api, backend_type)
  31. - backend_type="ollama" → 本地 Ollama 大模型 (≥30B, 首选)
  32. - backend_type="claude_code" → Claude Code CLI (Max Plan, 无需 API Key)
  33. - backend_type="api" → 云端 API (Anthropic/DashScope/OpenAI)
  34. - backend_type="ollama" → 本地 Ollama 小模型 (fallback)
  35. 优先级: Ollama 大模型(≥30B) > Claude Code > API > Ollama 小模型
  36. """
  37. # 强模型名单(≥30B 参数,本地运行优先)
  38. STRONG_MODELS = [
  39. "qwen2.5-coder:32b", "qwen2.5:32b", "qwen2.5:72b",
  40. "deepseek-coder-v2:33b", "codellama:34b",
  41. "llama3.1:70b", "mixtral:8x7b",
  42. ]
  43. # 弱模型名单(fallback)
  44. WEAK_MODELS = [
  45. "qwen2.5-coder:7b", "qwen2.5:14b", "qwen2.5:7b",
  46. "glm4:9b", "llama3.1:8b", "deepseek-coder:6.7b",
  47. ]
  48. # 1. 检测 Ollama 大模型(本地、隐私、免费、够强)
  49. try:
  50. from .ollama_lam import ollama_available
  51. models = ollama_available()
  52. if models:
  53. for m in STRONG_MODELS:
  54. if m in models:
  55. print("✅ 使用 Ollama 本地大模型 ({})".format(m))
  56. print(" 可用模型: {}".format(", ".join(models[:5])))
  57. return m, False, BACKEND_OLLAMA
  58. except Exception:
  59. pass
  60. # 2. Claude Code CLI
  61. if shutil.which("claude"):
  62. print("✅ 使用 Claude Code Max Plan (无需 API Key)")
  63. print(" 模型: claude sonnet (通过 claude CLI)")
  64. return "sonnet", False, BACKEND_CLAUDE_CODE
  65. # 3. 云端 API
  66. if os.environ.get("ANTHROPIC_API_KEY"):
  67. model = "claude-sonnet-4-20250514"
  68. print("✅ 使用 Anthropic API ({})".format(model))
  69. return model, True, BACKEND_API
  70. elif os.environ.get("DASHSCOPE_API_KEY"):
  71. model = "qwen-max"
  72. print("✅ 使用 DashScope API ({})".format(model))
  73. return model, True, BACKEND_API
  74. elif os.environ.get("OPENAI_API_KEY"):
  75. model = "gpt-4o"
  76. print("✅ 使用 OpenAI API ({})".format(model))
  77. return model, True, BACKEND_API
  78. # 4. Ollama 小模型 (fallback)
  79. try:
  80. from .ollama_lam import ollama_available
  81. models = ollama_available()
  82. if models:
  83. selected = None
  84. for m in WEAK_MODELS:
  85. if m in models:
  86. selected = m
  87. break
  88. if not selected:
  89. selected = models[0]
  90. print("⚠️ 使用 Ollama 小模型 ({}) — 能力有限".format(selected))
  91. print(" 可用模型: {}".format(", ".join(models[:5])))
  92. return selected, False, BACKEND_OLLAMA
  93. except Exception:
  94. pass
  95. return "", False, ""