AskaEth
|
f347681034
|
fix(loop): 原生工具调用从 Response.ToolCalls 解码 + 逐次回填工具结果 — 修复工具消息无回复
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- 根因: loop/agent.decodeToolCalls 只读 resp.Message.ToolCallName/resp.Content JSON信封, 从不看 api 原生解析出的 resp.ToolCalls(Anthropic tool_use / OpenAI tool_calls)
→ 模型返回 thinking+tool_use(无text) 被判定'无工具调用' → 空 Content 当最终 text → res.Text="" → no reply produced; 纯聊天消息不调工具直接出 text, 故表现为'部分消息无回复'
- agent/step.go: ToolCall 增 ID; ExtractToolCalls 导出并优先 resp.ToolCalls(保留原生id+归一化nil Args), 回落两旧约定
- loop/request.go: decodeToolCalls 委托 agent.ExtractToolCalls(流式/非流式共用)
- loop/tool_history.go(新): 原生批次回填 assistant tool_use + 带tool_use_id的tool_result; 旧JSON信封批次保持 RoleTool 纯文本(向后兼容)
- openai.go: tool_call parts 编成 tool_calls + tool_call_id
- 新增 native_toolcall_test + native_toolcall_http_test(httptest假Anthropic SSE: round1 tool_use(无text)→round2含tool_use_id/tool_result→res.Text非空)
- build/vet/test绿+交叉编译
|
2026-09-08 22:37:05 +08:00 |
|
Aska
|
44e7a5c2c5
|
feat(flow): 实时全链路流程可视化 P1——trace→graph_update→前端全链路流程页(design/19)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
后端: trace/graph.go(RunGraph 图构建器,kind/status 映射,父子优先连线,脱敏白名单+截断);
loop/flow.go(FlowPublisher 按会话增量发布 ws.graph_update,仅主人web会话); loop span
start/finish 折入图; run.go StartRound/EndRound; wire.go 组装+注入.
前端: Flow.tsx(全链路流程页:FlowGraphView+会话/节点/开始/耗时卡片+状态计数+节点点开日志);
FlowGraph 组件加 onNodeClick; types/wsParse 扩展; router/sections/AdminApp 注册 flow;
api-client.md §3.5 graph_update 契约.
验证: 后端 build/vet/test 全绿+flow_test.go 集成(span→graph→ws.graph_update主干); 前端 build 绿.
红线: 单二进制零新依赖; 工具参数/结果脱敏; 仅主人web会话; 身份靠actor元数据; 只读不虚构.
P2(并行子代理分支/泳道/节点实时日志)后置.
|
2026-09-07 19:10:57 +08:00 |
|
Aska
|
7e39153a69
|
feat: 修复审计落差 #1/#2/#3/#6 + 管理面板移动端适配
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
#1 工具布尔标记生效(agent-106, 安全红线): loop toolSchemas/runToolCalls 加 allow-set 安全门 restrictSchemas/applyToolSecurityGate——群聊/陌生人只暴露允许工具(默认关), 被拒not_allowed软提示+AuditEvent, owner全工具不变; 身份靠 ActorEnv(非提示词)
#2 checkpoint 恢复(agent-109): run.go LoadLatest + resumableStopReason门控(只恢复in-flight工具循环,不出答案不续跑), 幂等不重放副作用, 新会话不误恢复; resume_test 4用例
#3 tool_result(agent-108, 协议层): Anthropic 原生tool_result块(tool_use_id/is_error)非user纯文本 + OpenAI tool消息补tool_call_id; Content加ToolCallID/IsError等; (loop接线层2处留待,见备注)
#6 capacity_awaken推送(agent-107): onCapacity从只Debug改推WS hub(BroadcastCapacityAwaken, sessionId定向+payload对齐前端AwakenPayload)
管理面板移动端(agent-110): AdminApp 汉堡菜单+抽屉侧栏+标题truncate防换行, RBAC守卫不受影响
全仓 build/vet/test绿 + 前端build绿; 前端无涉差异已对齐
备注: #3 loop接线层2处(assistant工具轮append历史 + Message.ToolCallID/IsError)留给后续; #4代审/#5子代理触发/#7拆文件后置(主人说后三不急)
|
2026-09-07 13:43:18 +08:00 |
|
Aska
|
7455d09d05
|
feat: 角色视觉体系(头像按角色取)+ 时间注入(loop 每轮当前时间)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
【角色视觉体系(红线:每个角色自己的头像/背景,绝不串用昔涟)】
- persona.go:Persona 加 Visual{avatar, chatBackground{landscape,portrait}} + DefaultAvatar;每个角色各自配。
- cyrene.yaml:昔涟配 avatar(3F-Q-Happy-1) + chatBackground(横/竖屏)。
- PersonaStore 加 Persona(id);PersonaSummary 加 avatar/chatBackground;collectPersonas 按角色取
Persona(id) 视觉(无视觉→空,前端回退默认占位,绝不串角色)。
- 前端:types PersonaRecord 加 avatar/chatBackground;persona.ts personaAvatar(p)=p?.avatar||默认占位
(殊无昔涟 fallback);store 加 currentPersona;App 挂载 fetchPersonas 取默认角色;
TopBar/chat 头像改 personaAvatar(currentPersona)(写死昔涟头像已清除)。
【时间注入(她自然知道现在几点,深夜催睡交给人格/capacity)】
- options.go Options 加 Timezone;loop.go Loop 加 timeLocation/timeZoneName + New 解析 + loadTimezone;
time.go currentTimeBlock()(当前时间+周几+时区,每轮刷新);memory.go assembleContext 在「工作记忆」
前注入时间 system(keyed 在 timeLocation!=nil,无时区不注入不破坏测试);wire.go Timezone=a.cfg.Timezone。
go build/vet/test 全绿(gateway/loop/persona);前端 tsc/vite build 75模块绿。红线无写死昔涟头像。
|
2026-09-07 02:46:40 +08:00 |
|
Aska
|
33eeadfc38
|
fix(backthink): 后台思考静默广播——不再把内部推理泄到聊天思维链 + XML 动作/旁白解析
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
【静默广播修复(bug:思维链露出 backthink 推理)】
- 根因:LoopThinker.Think 复用同一 loop.Loop 且 loop 全局带 OnStream,backthink 后台思考时
把 [background autonomous reflection] 的 thinking/流式事件广播到前端,被当聊天思维链显示。
- loop/mute_ctx.go:WithMutedBroadcast(ctx) + isMutedBroadcast(ctx)——context 上静默标志。
- loop 四处广播抑制(stream.go 流式 / step.go 静默走非流式 agentStep / request.go capacity 事件 /
tools.go tool_execution),静默时跳过 UI 广播,推理照常返回结论。
- thinker.go LoopThinker.Think 用 loop.WithMutedBroadcast(ctx),backthink 不再泄 thinking。
【XML 动作/旁白结构化解析】
- cyrene.yaml systemPrompt 加「表达方式:动作与旁白」——动作 <action>…</action>、
旁白 <narration>…</narration>;克制≤1-2个/段、贴合唤醒态、重要信息不加、朗读正文忽略标签。
- 前端 parseContent.ts:ContentPart[](text/action/narration),非贪婪+反向引用、跨行、非法/
未闭合兜底纯文本不崩;summarizeContent 供思维导图/状态。
- 前端 renderContent.tsx:action/narration → 灰斜体(mu-text-lo italic)句中原位渲染。
- 应用到 chat.tsx UserBubble/AssistantBubble + messages 各 mode body。
go build/vet/test(loop/backthink)绿 + 前端 tsc/vite 绿。
|
2026-09-06 22:09:51 +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
|
adad4e1f62
|
fix(session): 群聊/陌生人记忆隔离——MemWritable 贯穿 loop(AGENTS.md 红线)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
群聊/陌生人查记忆只读不写、不泄露主人敏感;owner 默认行为完全不变。
- loop/sessionenv.go:SessionEnv 类型 + WithSessionEnv/sessionEnvFrom/OwnerEnv——每次 Run 携带会话
隔离上下文,经 context.Context 传递(不改 Run 签名、不存 Loop/Options 字段,避免 16 并发渠道
消息共享 Loop 的数据竞争;Chatter 接口与测试桩签名不变)。
- loop/memory.go 门控:injectMemory 读——MemWritable=true(owner)走原 Retriever.Inject 全量不变;
false(群聊/陌生人)改 Retrieve 后只留 ScopeProject(人人可读)、剔除 ScopeUser(owner习惯私有)与
ScopePersona(角色日常=owner敏感),块首加「群聊隔离」标记,无项目记忆不注入;extractMemory 写
false 直接 return 跳过(不调用 extractor 不落库)。
- 渠道入站(Channelbridge)传真实会话 MemWritable/Env;Web/REST/WS/voice chat 绑 OwnerEnv(JWT=owner
行为不变);backthink/automations/orchestration 默认 owner 全量。
- 测试:memory_gating_test 6 用例(owner/群聊只读不写/陌生人受限/无项目记忆不注入/默认owner全量)全绿;
loop/session/gateway 既有测试无回归。go build/vet/test 47 包全绿。
遗留:ScopeProject 过滤在 loop 内后处理实现(未改 memory 包),若后续允许可在 Retriever 加 scope
过滤选项消除与 Inject 模板的重复(2处)。
|
2026-09-06 20:34:06 +08:00 |
|
Aska
|
518bd0a230
|
feat: admin 端点补齐 + 视觉真推理 + 语音链路 + wire.go 收口(A+B+第3步)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
批次A admin 端点(原本 404 变 200 真实数据):
- GET /admin/llm:读 s.cfg.LLM 组 openai+anthropic 两 provider(enabled=当前 Provider、multimodal=配 VisionModel),APIKey 不进 wire 零泄露。
- GET /admin/automations:*automations.Service.List()(reminders+event rules+cron schedules,cron 加只读登记)。
- GET /admin/users:cfg.AdminUser + *auth.APIKey.List()(密钥掩码);无用户存储,恒先返回当前 admin 账号。
- GET /admin/backthink:*backthink.Backthink.List(ctx,50)。均只读、owner/admin RBAC、{data} 信封。
批次B 视觉真推理 + 语音:
- rest.go chatRequest 加 Image?;流式 publishChatStream 带 image;userChatMessages 构造 ImageMessage(model.go:71)。
- loop/vision.go:ImageResolver 可注入(MVP 先看图再对话);run.go Run 开头 resolveImages,无 resolver 透传直交主模型。
- vision/resolver.go:MessageResolver 调 vision.Router.Route——KindMain 保留图片交主模型多模态、KindVisionTool/OCRTool 经 dispatcher.Invoke 折叠成 [图片内容] 文本、KindUnsupported 记日志保留原图不崩。
- gateway/voice.go:VoiceService 接口 + SetVoice 注入点 + handleVoiceInput(未注入回 error 不崩)+ runVoiceTurn 异步 STT→loop chat→TTS→定向 voice_output 帧。
- ws_hub/ws_route:voice_input 接 handleVoiceInput;前端 ws.ts decodeBase64/playVoiceAudio/case voice_output。
第3步 wire.go 收口(唯一碰 wire.go 的一步):
- Deps 补传 Automations:a.automation / Backthink:a.backthink / Users:auth.NewAPIKey(a.cfg.Auth)(*auth.APIKey 原生满足 UserStore,避免 admin 重复的复合类型)。
- gw.SetVoice(a.voice);loop.Options.Vision = vision.NewMessageResolver(router, info, dispatcher.Invoke)(router=NewRouter(WithVisionTool/WithOCRTool)、info=cfg.LLM.VisionModel)。
实机验证:四 admin 端点 200 真实数据(llm 双 provider 脱敏、users=admin,yeij0942,owner);WS 握手正常。go build/vet/test 全绿 + 前端 tsc。wire.go 557 行。
|
2026-09-06 18:54:05 +08:00 |
|
Aska
|
648292d035
|
feat(loop): Top5#5 上下文溢出压缩 + 每轮 assemble(对齐 OpenClaw context-engine)——Top5 全完成
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- 每轮 assemble(transformContext 等价):run.go 每 step 前 assembleContext——依次 Inject(每轮
重新 Retriever.Inject 不缓存首轮)、WorkingMemory 前置 Summarize、可插拔 TransformContext 投影/
过滤;生成的 view 交 step,msgs 保持纯对话供工具结果追加,记忆不重复注入、不写回 checkpoint。
- Compactor:结构分支感知压缩——estimateContextTokens 启发式超 MaxContextTokens 且消息≥3 才动;
findKeepStart 按 user 消息切整轮从后往前累加(至少保留最后一整轮→尾随工具结果绝不切片/不跨轮);
旧轮 user/assistant 对压成一条 RoleSystem 摘要置顶,既有摘要前缀识别合并防叠;capSummary 上限
4000 rune;ctx 即 abortSignal(取消返回 ctx.Err,压缩失败仅记日志不中断 run)。
- 选项:Options 增 MaxContextTokens/Compactor/TransformContext,均 nil-tolerant(默认=现有行为,
零值不压缩);DefaultMaxContextTokens=32768。Compactor 接口预留注入 LLM 摘要。
go build/vet/test -count=1 全绿 + windows/darwin 交叉编译。12 断言覆盖尾随工具结果保留/不跨轮切割/
摘要上限/摘要合并/ctx 取消/每轮重检索/TransformContext 逐轮/超限压缩/默认关闭。-race 受宿主
TSan VMA 限制无法运行(与代码无关)。
**至此 Top5(1~5) 全部完成并推库。**
|
2026-09-06 18:08:55 +08:00 |
|
Aska
|
35cb2d3942
|
feat(loop): Top5#4 工具循环增强(对齐 OpenClaw agent-loop)——重复检测/并行串行/钩子/errorKind/repair
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- 重复调用安全网(critical-tool-loop):指纹=name+canonical JSON(args);批内重复第二次跳过回喂
「duplicate call」;跨轮关键重复(同指纹重现)→首次 block+criticalSeen,再次连续重复→终止整轮
StopReasonToolLoopTerminated(替代裸 8 轮针对同调用的硬截止)。
- 并行/串行混合:invokeParallel 默认并行,信号量(ToolParallelism 默认4)限并发,结果按调用索引
写回按原序渲染;串行触发=Options.ToolExecution:sequential 或 SetToolExecutionMode(name,sequential)
(对齐 OpenClaw「一个 sequential 标记→整组串行」);goroutine 不泄漏、ctx 取消快速返回。
- 工具钩子:ToolLoopHooks(BatchAdmit/CallAdmit/AfterCall/AfterOutcome) 经 Options.Hooks 注入,
均 nil-tolerant;供后续敏感操作代审复用(design/11)。terminate 用 every 语义。
- status 分类:ToolError.Kind() 区分 argument-validation(JSON-Schema 失败)/execution;
失败消息渲染 {kind,message} 让模型区分重发参数 vs 执行失败。
- tool-call-repair:LenientJSONUnmarshal 修 fence 包裹/尾逗号畸形;agent.extractToolCalls 与
loop.decodeToolCalls 走它;不可修复退化为文本不崩整轮。意图调用未区分回喂提示(后置)。
- tool_execution_update:流式路径 emitToolExecution 发 StreamKindToolExecution(start/end/end:error)。
go build/vet/test 全绿(46包)。TestRun_MaxRounds 改每轮不同参(原同 echo 被安全网拦,预期新行为)。
-race 受宿主 TSan VMA 限制无法运行(与代码无关)。
|
2026-09-06 17:57:18 +08:00 |
|
Aska
|
24d5924cee
|
feat(model): Top5#1 结构化流事件 + WS 事件体系(对齐 OpenClaw AssistantMessageEvent)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
- 新增 model/stream.go:StreamKind(text/thinking/tool_call 各 start/delta/end + tool_execution)
+ StreamEvent{Kind,Delta,Index,ID}。
- ChatStream 签名 onChunk func(delta string)→onEvent func(StreamEvent);loop OnStream 同改;
streamStep 转发结构化事件。
- openai:text_delta + text_start/text_end(正文三段式);anthropic:文本块 text_*/tool_call_*
按块 Index(content_block_stop 分支)真分段;fallback:有事件即交付。
- ws_hub:wsEvent 壳补 turnId/seq;新增 broadcastStream;streamChat 每帧打 turnId+seq;
stream.go 把事件 publish 到 bus ws.stream。
- ws_bridge:streamEventData 映射 text_*→message.start/delta/end、thinking_*→thinking.*、
tool_call_*→tool_call.*、tool_execution_update→tool_execution.update,未知回退 stream_chunk。
- 前端 ws.ts:解析 message.start/delta/end、thinking.start/delta/end(pendingThinking)、
tool_call.start/end→addTool、tool_execution.update;保留旧 stream_chunk/thinking/tool_used 兼容;
types.ts 补 turnId/seq。Docs/api-client.md 增 §3.1 v0.4。
已知限制(注释/文档标注):turnId 在 OnStream→bus→relay 路径暂为空(StreamEvent 无 turnId 字段,
bus ws.stream 载荷不带 turn);OpenAI adapter 未解析 tool_call 段;thinking 段两 adapter 暂不发;
tool_execution.update 是保留项(随工具循环钩子后置)。go build/vet/test + 前端 tsc 全绿。
|
2026-09-06 16:31:28 +08:00 |
|
Aska
|
71697ca4f8
|
feat(loop): agent loop(8 轮 + checkpoint + 流式 + 记忆注入/提取 + trace + 工具超时回喂)
|
2026-09-06 05:33:38 +08:00 |
|