9 Commits
Author SHA1 Message Date
AskaEth 4adfc9a2df feat(config): 新增 LLM_MULTIMODAL —— 让 env-only 部署能声明「主模型自身能收图」(默认 false,行为不变)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- 起因(Android 会话质询):其测到生效配置 multimodal:false 却与 DeepSeek 视觉文档矛盾。核实结论:
  **既非设计选择也非漏配,而是 env 路径的表达力限制** —— `data/models.json` 不存在 ⇒ 走 `GroupFromEnv`,
  而它此前硬编 false(理由:不得声称端点可能不具备的能力);该标志的正式载体只有 models.json 组(面板写入)。
  后果:env-only 部署里图像**恒走 KindVisionTool**(每回合多一次完整模型调用 + 模型只见文字描述=有损)。
- 修法:`LLMConfig.Multimodal`(`env:"LLM_MULTIMODAL" default:"false"`)+ `GroupFromEnv` 两个 provider 分叉都接入;
  **只对 env 合成组生效**(有有效 models.json 时组文件优先,与 LLM_REASONING_KIND 同口径);非 bool **启动报错**不静默
- 复核:config 包测试绿(5 条:默认不变 / 显式 true 生效且组仍 Validate / 进程 env 端到端 / 非法值 fail-fast /
  组文件优先两方向);**变异 3 条**(分叉写死 false、default 改 true、env 覆盖组文件)均已还原
- 交付给主人的动作:**在 `.env` 写 `LLM_MULTIMODAL=true`** 即可让图直进主模型上下文(改完需重启后端生效)
2026-10-04 16:30:25 +08:00
AskaEth 7e7f53bb41 fix(orchestration,loop): 子代理现在真的收到任务(P0)+ 工具白名单 + 超时可配(裁决 02.4.2/02.4.1/02.4.4)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
执行方案阶段 2 · P2-1。**02.4.2 是最伤的一条 P0**:`spawntool` 从不填 `AgentSpec.Context`、
`scheduler` 把 nil 交给 loop ⇒ 子代理模型上下文 = 角色 system + 记忆召回 + **0 条消息**,
goal/attach_info/data 一个字都到不了模型(此前测试用 mock adapter 恒答固定文本,测不出)。

- **02.4.2**:新增 `taskContext/taskUserMessage`(`spec.go`)把 **goal 正文 + attach_info + data
  渲染成同一条 user 消息**(`[任务目标]/[附加信息]/[任务数据]` 独立段落);`Spawn()` 设
  `Context: taskContext(spec)`;**system 只保留角色指令**,任务绝不进 system。
  真断言(捕获请求体的 adapter + 真 loop/agent):首请求恰好 **1 条 user 消息**、同时含 goal 与
  attach_info,且**所有 system 消息不含 goal 文本**。
- **02.4.1**:`AgentSpec.ToolWhitelist`(nil/空 = 继承全量);schema 增 `tool_whitelist`
  (顶层 + 每 task 条目,task 未带时继承批次级);`scheduler.run()` 经 ctx 传递 +
  `scopedRunner` 派生;`loop/options.go` **纯增量(+75 / −0)**:`WithToolWhitelist`/
  `ToolWhitelistFrom` + `(*Loop).WithToolWhitelist` 派生副本(浅拷贝仅替换 `hooks.CallAdmit`,
  链式保留原钩子),名单外调用否决为**软结果**回灌模型。
- **02.4.4**:`SUBAGENT_TIMEOUT_SEC`(默认 600)入 `internal/config` + `.env.example`;
  优先级 = 按调用 `timeout_seconds`(1s–24h 校验)> `WithSpawnTimeout`(生产由 cfg 填充)>
  调度器 `PerAgentTimeout`(`wire*.go` 仍是 10min 常量,未动);迟到 span 续根由测试锁定。

验证:**全树 `go build`/`go vet`/`go test ./... -count=1` = 58 包 ok / 0 FAIL**;
`GOOS=linux/amd64` + `GOOS=darwin/arm64` 交叉编译绿;前端 `tsc --noEmit` + `npm run build` 绿;
本批文件全部 ≤500 行、函数 ≤80 行。
变异验证(四条,均带还原证明):① `Context` 改回 `cloneMessages(spec.Context)` →
「1 条 user 消息」断言 FAIL(`user messages = 0`,即 P0 症状);② `WithToolWhitelist` 原样返回 →
显式白名单测试 FAIL(`alpha executed 1 times despite not being whitelisted`);
③ `subCtx` 改回全局默认 → 3 个超时测试 FAIL;④ `foldSpanFinish` 丢掉 `SpanFinished` →
迟到 span 状态断言 FAIL。

⚠️ 已知缺口(**登记,未假装已解决**):① 无真实模型端到端(全部捕获请求体 mock);
② 白名单**只挡执行、不过滤工具广告面**(模型仍能看见未列工具,调用即被拒并拿到可读原因;
过滤需改 `loop/request.go`);③ **迟到 span 的"新一轮已开始"窗口未修**(`loop/flow.go` 的
`StartRound` 会整体替换 `graphs[session]` ⇒ 新轮开始后迟到的 span 仍落进新轮图;需按轮键控图,
属后续);④ per-role 超时覆盖未实现(需 persona 旋钮管道)。
2026-10-04 11:30:39 +08:00
AskaEth 2dee372fb2 feat(backthink/admin): ③b — rag/delete 真实现 + D1 推送出口钩子(自建优先→个推兜底) + api-reference 补 D2/D3/D5 补丁
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- B5: POST /admin/rag/delete 真做(DeleteDocument→DeleteProject 级联删章节+索引清理, owner+审计, 200/404/500, 500降级兜底); users/iot scenarios+rules 诚实501(无用户表/IoT场景规则模型, 消息写明缺什么, 不伪造), 锁住 501+not_implemented
- D1: backthink/push_outlet.go PushExporter{Export}; pushOutlet 自建HTTP(2xx=送达, token仅Authorization头+error脱敏)优先→Getui兜底(未接入, 诚实日志'getui not integrated'+(false,nil)); backthink.Deps.Exporter → pusher.withExporter, Push 在WS/IM后 exportAsync(detached+5s超时, 失败仅日志, 不破坏现有投递, 限流不上报); config PushOutletConfig(PUSH_EXPORTER_* + GETUI_*占位)
- 前端 Rag.tsx/api.ts 删除后 reload + 类型; Docs/api-client v0.31 + api-reference(#23 owner/200-404, §8.4, 端点表PATCH/DELETE messages + pinned + messages?q=)
- 测试(push_outlet/admin_rag_delete/admin_honest501/knowledge store), 后端+前端build全绿+3平台交叉编译
- 刻意: Getui SDK 未接入(无SDK不硬造), 主人自建服务填 PUSH_EXPORTER_URL/TOKEN 即可
2026-09-09 00:08:29 +08:00
AskaEth 53002f1e11 feat(model): LLM token 预算可配置化 — models.json每模型maxTokens + LLM_FALLBACK_MAX_TOKENS回退兜底
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- config.go: LLMConfig.FallbackMaxTokens(LLM_FALLBACK_MAX_TOKENS, 默认8192)
- runtimeconfig/models.go: Group.MaxTokens(models.json每模型独立预算, 负值拒绝)
- model/fallback.go: Chain.WithTokenBudget + applyBudget; runtime.go buildSnapshot接入(active.MaxTokens, env.FallbackMaxTokens)
- 优先级: 显式Request.MaxTokens > 组maxTokens > 仅多步链末端的LLM_FALLBACK_MAX_TOKENS > 适配器默认8192; 单步链不动env兜底(避免OpenAI主模型行为回归)
- gateway admin: AdminLlmProvider.MaxTokens 透传/回显/负值400
- .env.example + .env(LLM_FALLBACK_MAX_TOKENS=8192); Docs/api-client v0.27 + api-reference + design/04
- 新增测试(config/runtimeconfig/budget_test/admin_write), build/vet/test绿+3平台交叉编译
2026-09-08 22:42:27 +08:00
AskaEth 026b27b310 feat(auth): refresh token 续期(B2) — 不透明哈希+单次旋转+/auth/refresh+/auth/logout
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- auth/refresh.go: RefreshStore(Issue/Rotate/Revoke/RevokeAll/RevokeByUser), SHA-256哈希256-bit随机串, 单次旋转事务(并发重放fail-closed)
- 迁移0008_refresh_tokens(id/user_id/role/token_hash UNIQUE/expires_at/revoked_at + 索引)
- gateway: POST /v1/auth/refresh(旋转/续期) + /v1/auth/logout(单/全设备); login响应增refreshToken
- config: AUTH_REFRESH_TTL(720h)/AUTH_REFRESH_ROTATE_DISABLED; decode.go 支持time.Duration
- rotate-jwt成功后RevokeAll(响应refreshTokensRevoked), revoke-keys不动refresh
- 14测试+真实二进制e2e, build/vet/test绿+交叉编译
- Docs/api-client v0.25 + api-reference §2.3/2.4 同步
2026-09-08 21:45:00 +08:00
Aska 03d7050e1e feat(voice): 百炼声音复刻create_voice + TTS instruction情绪驱动(主TTS-昔涟复刻音色)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
2026-09-08 06:48:15 +08:00
Aska 73dabb9dde feat(voice): 阿里百炼 STT/TTS 主链路接通(base64 STT + cosyvoice TTS按voice_id + REST /audio/* + voice_input.deviceId)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- voice/dashscope.go 新建:DashscopeSTT(qwen-audio-3.0-asr-flash, base64 data URI→text) + DashscopeTTS(cosyvoice 按 voice_id, 取非流式 24h URL 下载字节)
- cloud.go newDashboardSTT/TTS 由空 endpoint stub 改为真实百炼 adapter
- chain.go gating 从 DashscopeAPIKey!="" 改为 voiceConfigured(cfg); silent 兜底保留
- config.VoiceConfig 扩展 DASHSCOPE_BASE_URL/VOICE_STT_*/VOICE_TTS_* 字段(必填 DASHSCOPE_API_KEY)
- gateway: POST /api/v1/audio/{transcribe,speech} (owner+审计+MaxBytesReader); voiceInputRequest 增 deviceId 并透传 runner.Run
- 实测: cosyvoice-v3.5-plus+longxiaochun 回 418(引擎拒绝), 改用 cosyvoice-v3-flash+longxiaochun_v3; TTS 你好我是昔涟->106124B wav -> STT 回 你好我是西联, 链返回真实字节/文本
- 单测: dashscope_test/config voice defaults/gateway audio_test; go build/vet/test 全绿
- 声音复刻(响昔涟音色)待公网参考音频; 不做 create_voice
2026-09-08 06:06:02 +08:00
Aska 6dbb4a2e18 feat: 唤醒式架构批次——capacity/L4/会话编排/管理面板写CRUD/前端集成(77-81)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
【capacity 唤醒式核心(77)】internal/runtime/capacity:(Decider L1启发式+L2上下文+人格覆盖→三态静息/唤醒/全能→允许工具集+capacity_awaken事件)。loop 外围允许集过滤(不硬阻断=能力≠边界红线)。config 加 Capacity(Enabled/MinConfidence/ToolSets)。wire buildCapacity 接入 loop。

【L4 记忆驱动意图(80)】recall.go:从记忆召回用户习惯(搞一下xx=办事)→唤醒L1/L2漏掉/升置信;群聊陌生人不读owner习惯(隔离红线);RecordIntent闭环(判定写回记忆越用越准);默认保守静息。

【会话消息编排(78)】gateway/session_orchestrator.go:每会话(模式/pending有界5/tail上下文尾巴20);Submit非阻塞(idle立即/busy入队ack/满拒绝);完成回调按序续接(tail+新消息合并增量注入非全量重放);Interrupt中断;REST 202/409+WS session_busy/pending_ack事件;不重造任务引擎复用loop。

【前端集成(79)】ws.ts 加 capacity_awaken/session_busy/pending_ack 解析;store 加 awakenState/sessionBusy;TopBar/ChatShell 加唤醒态徽标+忙态提示(不阻塞输入框);状态组件 status.tsx;Miuix风格。

【管理面板写CRUD(81)】20个写端点(POST/PUT/DELETE /admin/*,owner+审计落库):personas(真持久化YAML)/users apikey(签发掩码+撤销)/iot控制(真下发)/automations(建/触发/删)/llm(test真调用+临时)/channels(connect/close/身份测试actor白名单)/plugins(卸载)/memories(search真检索)/sessions(export)。无存储如实501不伪造。拆4文件满足≤500红线。前端9模块接真写。

【wire收口】buildCapacity接入loop+OnCapacity事件;server.go newOrchestrator接hub。

实机验证:iot ac.living control 200 真实改变 on:true;observability/metrics 200、health ok;全仓 build/vet/test 47包绿+前端tsc/vite。
2026-09-06 21:54:40 +08:00
Aska efed5f05b1 feat(config): 配置加载与 schema 校验(.env/env 注入 + 反射解码 + 校验) 2026-09-06 04:15:31 +08:00