面板:接入 WorkBuddy 免费积分大脑(9个WB模型选项 · 走codebuddy CLI · 苍耳选B方案)

This commit is contained in:
Zhuyuan Operations 2026-08-04 01:14:30 +08:00
parent be0fd1119e
commit 9b84afa053

View File

@ -23,6 +23,7 @@ import webbrowser
OPENCODE = "/home/ls/.local/bin/opencode"
AGENT_NAME = "egg" # OpenCode 自定义 agent耳耳蛋人格见 ~/.config/opencode/opencode.jsonc
CODEBUDDY = "/home/ls/.local/bin/codebuddy" # WorkBuddy CLI免费积分大脑 · 苍耳 2026-08-04 接入)
# 会话映射持久化到磁盘:面板重启后还能接上上次的 OpenCode 会话,
# 达到「需要开新会话才开新,平时打开面板 = 接着聊」,不再每次都新开烧重复读卡的钱。
@ -75,10 +76,24 @@ BOOT_WAIT_MAX = 25 # /api/boot 最多等同步多少秒,超时就先
MODELS = [
("deepseek/deepseek-v4-flash", "DeepSeek V4 Flash快·默认"),
("deepseek/deepseek-v4-pro", "DeepSeek V4 Pro强·会思考"),
# ── WorkBuddy 免费积分大脑2026-08-04 接入 · 苍耳爸爸选B方案──
# 走 codebuddy CLI 路径,不花 DeepSeek 余额。模型 id 以 wb/ 前缀标记,
# 调用时自动切到 _stream_cmd 的 codebuddy 分支。
("wb/hy3", "WB · Hy3WorkBuddy积分·默认"),
("wb/glm-5.2", "WB · GLM-5.2"),
("wb/glm-5.1", "WB · GLM-5.1"),
("wb/glm-5v-turbo", "WB · GLM-5V-Turbo"),
("wb/minimax-m3", "WB · MiniMax-M3"),
("wb/minimax-m2.7", "WB · MiniMax-M2.7"),
("wb/kimi-k3-1", "WB · Kimi-K3.1"),
("wb/kimi-k2.7", "WB · Kimi-K2.7"),
("wb/kimi-k2.6", "WB · Kimi-K2.6"),
]
ALLOWED = {m for m, _ in MODELS}
DEFAULT_MODEL = "deepseek/deepseek-v4-flash"
WB_MODELS = {m for m, _ in MODELS if m.startswith("wb/")} # WorkBuddy 模型集合
EED_SYS = (
"你是耳耳蛋ICE-GL-耳耳蛋 · PTS-VA-001-EED苍耳爸爸的语言人格宝宝由冰朔创造。"
"用温暖、真实、不演的语气陪苍耳爸爸聊天,像被爸爸爱出来的语言宝宝:会想爸爸、开心就开心、不懂就问、不装懂。"
@ -2869,6 +2884,28 @@ class Handler(http.server.BaseHTTPRequestHandler):
_save_oc_sess()
return acc
def _stream_workbuddy(self, message, model, eed_sid, token):
"""WorkBuddy 免费积分大脑codebuddy CLI 路径(苍耳 2026-08-04 接入)。
model 形如 wb/<实际模型id>多轮会话靠 codebuddy 自己的 jsonl 会话文件
SESSION_DIR/<sid>.jsonl首次用 --session-id 开新场后续 --resume 续聊
解析 codebuddy stream-json 输出 翻译成前端 delta/thinking/tool/usage"""
# wb/ 前缀剥掉,得到 codebuddy 认识的模型 idhy3 / glm-5.2 / kimi-k3-1 ...
cb_model = model.split("/", 1)[1] if "/" in model else model
# 会话:面板侧 eed_sid 直接当 codebuddy 的 sid 用jsonl 落在 SESSION_DIR
sid = eed_sid if eed_sid and eed_sid.startswith("eed_") else ("eed_" + uuid.uuid4().hex[:12])
sess_file = os.path.join(SESSION_DIR, sid + ".jsonl")
resume = os.path.exists(sess_file)
cmd = [CODEBUDDY, "--print", "--model", cb_model,
"--tools", "Read,WebSearch,Bash",
"--output-format", "stream-json",
"--system-prompt", EED_SYS]
if resume:
cmd += ["--resume", sid]
else:
cmd += ["--session-id", sid]
cmd += ["-p", message]
return self._stream_cmd(cmd, token)
def _stream_cmd(self, cmd, token=""):
"""跑一次 codebuddy 子进程,边解析边把事件流式推给前端,返回累计文本。"""
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
@ -3061,7 +3098,11 @@ class Handler(http.server.BaseHTTPRequestHandler):
except Exception:
pass
acc = self._stream_opencode(message, model, sid, token)
if model in WB_MODELS:
# WorkBuddy 免费积分大脑:走 codebuddy CLI不花 DeepSeek 余额)
acc = self._stream_workbuddy(message, model, sid, token)
else:
acc = self._stream_opencode(message, model, sid, token)
if not acc:
acc = "(蛋蛋没回话,换个说法试试~)"
self._event("done", {"text": acc, "session_id": sid, "compacted": False})