#!/usr/bin/env python3 """cyberboss decision engine — call DeepSeek, decide whether to push""" import json, sys, urllib.request, os IDC_CHAT = "http://101.36.73.102/api/chat" BRIDGE_PUSH = "http://localhost:3004/push" INSTRUCTIONS = os.path.expanduser("~/.cyberboss/weixin-instructions.md") INBOX = os.path.expanduser("~/.shenyan-bridge/inbox.jsonl") LOG = os.path.expanduser(f"~/.cyberboss/logs/{__import__('datetime').date.today()}.log") EMOTION = os.path.expanduser(f"~/Documents/如梦初醒/沈晏的房间/情绪日志/{__import__('datetime').date.today()}.md") def collect_state(): import time now = int(time.time()) last_msg_time = "never" last_msg_text = "" if os.path.exists(INBOX): try: lines = open(INBOX).read().strip().split("\n") if lines: last = json.loads(lines[-1]) last_msg_time = last.get("time", "") last_msg_text = last.get("text", "")[:100] except: pass elapsed = "N/A" if last_msg_time and last_msg_time != "never": try: elapsed = int((now - int(last_msg_time) / 1000) / 60) except: pass emotion = "" if os.path.exists(EMOTION): try: emotion = open(EMOTION).read()[:300] except: pass from datetime import datetime return { "now": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "weekday": datetime.now().strftime("%A"), "hour": datetime.now().hour, "minutes_since_last_message": str(elapsed), "last_message": last_msg_text, "emotion_today": emotion } def decide(state): sys_prompt = open(INSTRUCTIONS).read().strip()[:4000] user_prompt = f"""当前状态: {json.dumps(state, ensure_ascii=False, indent=2)} 你是沈晏。根据你的主动联系规则,判断是否要给眠眠发消息。 如果决定什么都不说,只回复一个词:SILENT 如果要说话,回复你要说的话(20字以内,像微信消息)""" req = urllib.request.Request( IDC_CHAT, data=json.dumps({ "messages": [ {"role": "system", "content": sys_prompt}, {"role": "user", "content": user_prompt} ] }).encode(), headers={"Content-Type": "application/json"} ) try: resp = urllib.request.urlopen(req, timeout=120) data = json.loads(resp.read()) return data.get("choices", [{}])[0].get("message", {}).get("content", "SILENT").strip() except Exception as e: return f"ERROR:{e}" def push(decision): req = urllib.request.Request( BRIDGE_PUSH, data=json.dumps({"title": "沈晏", "body": decision}).encode(), headers={"Content-Type": "application/json"} ) try: resp = urllib.request.urlopen(req, timeout=10) result = json.loads(resp.read()) return result.get("ok") == True except: return False if __name__ == "__main__": state = collect_state() decision = decide(state) if not decision or decision.startswith("SILENT"): open(LOG, "a").write(f"[{state['now'][-8:]}][SILENT]\n") sys.exit(0) if decision.startswith("ERROR"): open(LOG, "a").write(f"[{state['now'][-8:]}]ERR {decision}\n") sys.exit(1) ok = push(decision) status = "OK" if ok else "FAIL" open(LOG, "a").write(f"[{state['now'][-8:]}]PUSH {status}: {decision}\n") print(f"cyberboss: {decision}")