run.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #!/usr/bin/env python3
  2. """
  3. agent67/run.py — Lambda 个人助理 🐂
  4. ====================================
  5. 一个能直接操控电脑的全能型 AI 助手,基于 lambdagent 构建。
  6. 使用 Claude Code Max Plan,无需 API Key。
  7. Lambda 演算解读:
  8. λ = Memory(Loop(Brain >> parse_action >> route_execute))
  9. 能力:
  10. 💻 终端命令执行 📁 文件管理
  11. 🌐 浏览器控制 🚀 应用启动/切换
  12. 📊 系统信息查询 📸 屏幕截图
  13. 用法:
  14. python run.py # 使用 Claude Code Max Plan (默认)
  15. python run.py --api # 使用 API Key 模式
  16. python run.py --model opus # 指定模型
  17. """
  18. from __future__ import annotations
  19. import argparse
  20. import sys
  21. import os
  22. from pathlib import Path
  23. # ── 路径设置 ──────────────────────────────────────────────
  24. PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent # Paper08/
  25. AGENT_DIR = Path(__file__).resolve().parent # agent67/
  26. sys.path.insert(0, str(PROJECT_ROOT))
  27. sys.path.insert(0, str(AGENT_DIR.parent)) # agentexample/
  28. from agent67.core.assistant import PersonalAssistant
  29. from agent67.core.config import detect_backend, BANNER, BACKEND_OLLAMA
  30. def main():
  31. parser = argparse.ArgumentParser(description="🐂 lambda — 个人助理")
  32. parser.add_argument("--api", action="store_true",
  33. help="使用 API Key 模式(而非 Claude Code CLI)")
  34. parser.add_argument("--claude", action="store_true",
  35. help="强制使用 Claude Code Max Plan (跳过 Ollama 检测)")
  36. parser.add_argument("--ollama", action="store_true",
  37. help="使用 Ollama 本地模型 (qwen2.5:7b)")
  38. parser.add_argument("--model", type=str, default=None,
  39. help="指定模型 (默认: 自动检测)")
  40. args = parser.parse_args()
  41. print(BANNER)
  42. # 检测后端
  43. model, use_api, backend = detect_backend()
  44. # 命令行覆盖
  45. if args.claude:
  46. from agent67.core.config import BACKEND_CLAUDE_CODE
  47. backend = BACKEND_CLAUDE_CODE
  48. model = args.model or "sonnet"
  49. use_api = False
  50. print("✅ 强制使用 Claude Code Max Plan")
  51. elif args.ollama:
  52. backend = BACKEND_OLLAMA
  53. model = args.model or "qwen2.5:7b"
  54. use_api = False
  55. elif args.api:
  56. use_api = True
  57. backend = "api"
  58. if not model:
  59. print("⚠️ --api 模式需要设置 API Key 环境变量:")
  60. print(" export ANTHROPIC_API_KEY=sk-ant-...")
  61. return
  62. if args.model and not args.ollama:
  63. model = args.model
  64. if not model and not backend:
  65. print("⚠️ 未找到可用的 LLM 后端。")
  66. print(" 方式 1: ollama serve && ollama pull qwen2.5:7b (本地模型)")
  67. print(" 方式 2: 安装 Claude Code: npm install -g @anthropic-ai/claude-code")
  68. print(" 方式 3: export ANTHROPIC_API_KEY=sk-ant-...")
  69. return
  70. assistant = PersonalAssistant(model=model, use_api=use_api, backend=backend)
  71. print()
  72. while True:
  73. try:
  74. user_input = input("You: ").strip()
  75. except (EOFError, KeyboardInterrupt):
  76. print("\n👋 lambda 下线了,再见!")
  77. break
  78. if not user_input:
  79. continue
  80. if user_input.lower() in ("exit", "quit", "bye", "再见"):
  81. print("👋 lambda 下线了,祝你有美好的一天!")
  82. break
  83. if user_input.lower() == "trace":
  84. assistant.print_trace()
  85. continue
  86. if user_input.lower() == "stats":
  87. assistant.print_stats()
  88. continue
  89. if user_input.lower() == "history":
  90. print("\n📜 对话历史:")
  91. for entry in assistant.conversation_history:
  92. print(f" [{entry['role']}] {entry['content'][:100]}")
  93. print()
  94. continue
  95. print()
  96. response = assistant.chat(user_input)
  97. # 如果是流式模式,response 已经在 chat() 中逐字显示过
  98. # 只有非流式模式才在这里打印
  99. if not (hasattr(assistant.brain, 'stream') and assistant.brain.stream):
  100. print(f"🐂 lambda: {response}")
  101. print()
  102. if __name__ == "__main__":
  103. main()