产品与一次状态切换
先从用户视角出发:为什么这个像素办公室会“动起来”。
你看到的不是“动画”,而是状态可视化
把它想成机场大屏:每个航班状态变化,屏幕就更新。这里同理,AI 助手状态从 `idle` 变成 `writing` 时,角色就会移动到对应区域。状态可视化的关键是 single source of truth。
例如执行 `set_state.py writing`
并通过 `/status`、`/agents` 提供给前端
办公室中“谁在做什么”立刻可见
真实代码:状态映射规则
VALID_AGENT_STATES = frozenset({"idle", "writing", "researching", "executing", "syncing", "error"})
STATE_TO_AREA_MAP = {
"idle": "breakroom",
"writing": "writing",
"error": "error",
}
第一行定义了系统认可的合法状态词。
后面几行把“状态”翻译成“办公室区域”。
这样前后端就能用同一套字典说话。
UI 漂亮只是表层,真正有价值的是把“不可见的工作状态”变成可观察信号,这样你才能做协作管理。
应用测验
你想新增 `meeting` 状态,第一步最应该做什么?
前端像素办公室引擎
核心是 Phaser 场景 + 布局配置,不是把坐标硬写在每个函数里。
布局像“舞台调度表”
`layout.js` 像舞台总控表,统一定义画布、区域、家具、层级。这样你要调位置时,只改一处配置。这里的 depth 决定谁盖住谁。
const LAYOUT = {
game: { width: 1280, height: 720 },
areas: { writing: { x: 320, y: 360 }, error: { x: 1066, y: 180 } },
furniture: { desk: { x: 218, y: 417, depth: 1000 } }
};
先定义游戏舞台尺寸。
再定义“工作区/报错区”这些功能坐标。
最后定义家具位置和遮挡层级。
角色间对话动画
应用测验
你要整体右移工作区角色,最优先改哪类文件?
后端状态服务与接口
Flask 后端负责“状态可信”和“页面可供给”,前端只做呈现。
数据流动画:一次状态更新怎么走
真实代码:轮询与返回
const FETCH_INTERVAL = 2000;
const response = await fetch('/yesterday-memo?t=' + Date.now(), { cache: 'no-store' });
@app.route("/status", methods=["GET"])
def get_status():
state = load_state()
return jsonify(state)
前端每隔固定时间拉取最新数据。
请求参数带时间戳,减少缓存干扰。
后端 `/status` 把当前状态直接返回成 JSON。
应用测验
你看到 UI 一直显示“待命中”,排查第一步更应该看?
多 Agent 协作机制
这个项目最有意思的部分是“加入、鉴权、并发上限、离线回收”这一整套闭环。
像门禁系统一样控制加入
你可以把 join key 看成临时门票。后端会检查 key 是否有效、是否过期、当前并发是否超上限,再决定是否让新 Agent 进入办公室。这里的 concurrency limit 默认是 3。
max_concurrent = int(key_item.get("maxConcurrent", 3))
if active_count >= max_concurrent:
return jsonify({"ok": False, "msg": f"该接入密钥当前并发已达上限({max_concurrent})"}), 429
target["authStatus"] = "approved"
先读取这把 key 允许的并发人数。
如果当前活跃人数超限,直接拒绝并返回 429。
通过后才会把该 Agent 置为 approved。
协作角色对话
应用测验
团队反馈“第四个 Agent 总是进不来”,你先检查什么?
配置安全与稳定性
这个仓库不只会“展示状态”,还做了生产环境的安全护栏和超时策略。
生产模式会做硬校验
可以把它想成登机前的安检门:不合规就不能起飞。项目在生产模式下会检查密钥强度、抽屉密码强度。session cookie 也启用了基础加固。
app.config.update(
SESSION_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE="Lax",
SESSION_COOKIE_SECURE=is_production_mode(),
)
会话 Cookie 禁止被前端脚本随便读取。
跨站传递行为被限制,降低被滥用概率。
生产环境要求更严格的 HTTPS 传输。
稳定性不是“快”,而是“可恢复”
自动回 idle
状态长期不更新会自动回待命,避免界面“假忙碌”。
异步任务轮询
长任务走后台线程 + poll,减少网关超时问题。
备份与回滚
资产替换前保存 `.bak`,出问题能快速退回上一版。
应用测验
服务在生产环境启动即报错,最优先排查哪类配置?
部署与扩展路径
最后把“能在本地跑”升级成“能稳定分享和协作”。
从本地到公网的最小闭环
这套项目给了两条路线:Cloudflare Tunnel 快速分享、或自有域名/反向代理长期运行。对协作团队更重要的是可观测性:`/health`、`/agents`、`/status` 要能稳定响应。
GET /health看服务是否在线GET /agents看多 Agent 当前状态POST /set_state手动切换主状态用于演示/排障真实代码:状态脚本入口
state_name = sys.argv[1]
if state_name not in VALID_STATES:
print(f"无效状态: {state_name}")
state["state"] = state_name
state["updated_at"] = datetime.now().isoformat()
脚本先从命令行拿到状态参数。
再检查是不是允许的状态词。
最后写入状态和时间戳,供前端读取。
如果你要接入自己的 Agent 系统,只需要让它按约定周期调用 `/agent-push`,而不是改整套前端渲染逻辑。