Files
sundynix-agentix/sundynix-dispatcher/internal/eino/board_serde.go
T
Blizzard aec7ad949c feat(model): 工作模型与 JARVIS 语音模型分开配置 + 语音任务路由到快模型
模型配置加"用途"维度:工作主力(chat,要强)与 JARVIS 语音(voice,要快/低时延)各配各激活,
语音任务走语音模型池,未配置则透明回落工作模型——不影响现有功能。

- contract: ConfigKindVoice="voice" + Meta[model_profile]=voice(与 intent==report 同类路由)
- gateway: ServeConfig/broadcastActive 循环纳入 voice;submitVoiceTask 打 model_profile=voice 标记
- dispatcher: 第二个 llm.Pool(voicePool)吃 voice 配置热更新;board.useVoice 从 Meta 派生(含快照);
  Orchestrator.agentPool(b) 按黑板选池——语音且语音池就绪→语音池,否则工作池;
  agent 生成路径(graph/react/coordinator/compose)全改走 agentPool(b),报告/护栏/记忆固定工作池
- admin: 模型页三 Tab(工作主力/JARVIS语音/向量化),复用 ModelManager;api Kind 加 voice

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-22 11:39:17 +08:00

79 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package eino
import (
"encoding/json"
"github.com/cloudwego/eino/schema"
)
// board 的字段全是未导出的,而 Eino 的 checkpoint 序列化器只认导出字段——若直接让 compose
// 持久化 board,会落成空、resume 丢全部执行态。Eino 对「同时实现 json.Marshaler+Unmarshaler」
// 的类型改走自定义 JSON(见 internal/serialization checkMarshaler),故给 *board 实现一对 JSON
// 方法、映射到导出 DTO,即可把整个黑板按需持久化,而无需把 board 字段全导出(牵连几十处调用点)。
//
// 不持久化 fatalErrerrortransient——中断点处必为 nil):审批中断时图尚未失败,
// 它是单次 Invoke 内的致命错标志,跨 resume 无意义。rejected 同理在中断点为 false
// 但仍带上以求快照完整、零歧义。
type boardSnapshot struct {
UID string `json:"uid,omitempty"`
SID string `json:"sid,omitempty"`
Query string `json:"query,omitempty"`
UseVoice bool `json:"use_voice,omitempty"`
Profile string `json:"profile,omitempty"`
History []*schema.Message `json:"history,omitempty"`
KB string `json:"kb,omitempty"`
Refs []string `json:"refs,omitempty"`
ToolOut []string `json:"tool_out,omitempty"`
Sections []reportSection `json:"sections,omitempty"`
Answer string `json:"answer,omitempty"`
AgentOut []string `json:"agent_out,omitempty"`
Rejected bool `json:"rejected,omitempty"`
}
// MarshalJSON 把黑板序列化为快照(Eino checkpoint 经此持久化整图执行态)。
func (b *board) MarshalJSON() ([]byte, error) {
return json.Marshal(boardSnapshot{
UID: b.uid,
SID: b.sid,
Query: b.query,
UseVoice: b.useVoice,
Profile: b.profile,
History: b.history,
KB: b.kb,
Refs: b.refs,
ToolOut: b.toolOut,
Sections: b.sections,
Answer: b.answer,
AgentOut: b.agentOut,
Rejected: b.rejected,
})
}
// UnmarshalJSON 从快照还原黑板(resume 时 Eino 据此重建中断前的执行态)。
func (b *board) UnmarshalJSON(data []byte) error {
var s boardSnapshot
if err := json.Unmarshal(data, &s); err != nil {
return err
}
b.uid = s.UID
b.sid = s.SID
b.query = s.Query
b.useVoice = s.UseVoice
b.profile = s.Profile
b.history = s.History
b.kb = s.KB
b.refs = s.Refs
b.toolOut = s.ToolOut
b.sections = s.Sections
b.answer = s.Answer
b.agentOut = s.AgentOut
b.rejected = s.Rejected
return nil
}
// 注册 *board 的序列化类型名:Eino checkpoint 的 State 是 any,持久化时记类型名、
// resume 时据名还原具体类型再走 UnmarshalJSON。名字一经上线不可改(旧 checkpoint 据此解码)。
func init() {
schema.RegisterName[*board]("sundynix_board")
}