feat(gateway): 地基③ 打通实时信号 producer→前端WS + loop 真流式 + 上行路由补全
打通前端 ws.ts 里那批死消费者事件(thinking/mood/tool_used/subagent_event/
task_output/device_update/reminder/backthink),并给 loop 接真 token 流式。
- wire.go:loop 建时传 OnStream(streamChunk 闭包把 delta 发 bus ws.stream_chunk);
gateway.Deps 注入 Scheduler/Tasks/Streaming;iot 接共享总线 iot.WithBus(a.bus)。
- ws_bridge.go:hub 额外订阅 iot.>/task.>/automation.>/reminder.>/cyrene.agent.*.event,
normalizeEvent 归一为 ws.*(device_update/task_output/task_done/automation_result/
reminder/subagent_event);不订阅 cyrene.agent.> 以免 ask/reply 内部事件进 relay。
- ws_route.go:voice_input→ws.voice_input;subagent_ask→Scheduler.AuditContext(真实
上下文审计,替换 pending stub);task_output_query→Manager.TaskOutput(真实输出,
替换空 {})。
- server.go:新增 SubagentAuditor/TaskOutputStore 接口 + Deps.Scheduler/Tasks/Streaming。
- orchestration/auditcontext.go:Scheduler.AuditContext(full/tail/keyword)。
- task/manager.go:Manager.TaskOutput(id)。
- backthink:record() 补发 ws.backthink 事件。
- json tag 修正(device_update/reminder/task output 结构体加小写 tag + DeviceUpdate
补 message),使前端分支能真正渲染。
实机验证:WS 握手 101、task manager ready、iot manager initialized(WithBus 生效)。
go build/vet/test 全绿;TestHubBridgeDeviceUpdate/TestHubBridgeSubagentProgress 覆盖
映射。dev 推至后续版本。
This commit is contained in:
1 parent
04bfa2c7a7
commit
9b207a31e8
14 files changed
+673
-109
No files matched your search
@@ -38,6 +38,8 @@ import (
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/loop"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/memory"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/orchestration"
|
||||
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/task"
|
||||
)
|
||||
|
||||
// source is the log provenance tag for every record this package emits.
|
||||
@@ -96,6 +98,18 @@ type IoTStore interface {
|
||||
List(ctx context.Context) ([]iot.Device, error)
|
||||
}
|
||||
|
||||
// SubagentAuditor audits a sub-agent's conversation context for the subagent_ask
|
||||
// WS route. *orchestration.Scheduler is the production implementation.
|
||||
type SubagentAuditor interface {
|
||||
AuditContext(ctx context.Context, id string, mode orchestration.AuditMode, n int, query string) (*orchestration.AuditResult, error)
|
||||
}
|
||||
|
||||
// TaskOutputStore queries a task's output for the task_output_query WS route.
|
||||
// *task.Manager is the production implementation.
|
||||
type TaskOutputStore interface {
|
||||
TaskOutput(ctx context.Context, id string) (task.OutputEvent, error)
|
||||
}
|
||||
|
||||
// Deps carries the gateway's injected dependencies. Every field is nil-tolerant
|
||||
// except Auth, which is required (authentication backs login and every RBAC
|
||||
// decision). Registry/Loop are satisfied by the concrete *capability.Registry and
|
||||
@@ -121,6 +135,16 @@ type Deps struct {
|
||||
Memories MemoryStore
|
||||
// IoT lists IoT devices. Optional.
|
||||
IoT IoTStore
|
||||
// Scheduler audits sub-agent context for the subagent_ask WS route.
|
||||
// Optional (subagent_ask returns a clear error when unset).
|
||||
Scheduler SubagentAuditor
|
||||
// Tasks queries task output for the task_output_query WS route.
|
||||
// Optional (task_output_query returns a clear error when unset).
|
||||
Tasks TaskOutputStore
|
||||
// Streaming marks the injected Loop as streaming-capable (its OnStream is
|
||||
// wired to publish ws.stream_chunk). When set the hub skips its own single
|
||||
// final stream_chunk emission, since deltas already stream through OnStream.
|
||||
Streaming bool
|
||||
// Frontend is the SPA filesystem served for all non-API, non-WS routes.
|
||||
// When nil the gateway serves no static assets (API and WS only). The
|
||||
// embedded dist (internal/webui) or an external dist directory is used.
|
||||
@@ -130,18 +154,21 @@ type Deps struct {
|
||||
// Server is the gateway. It owns a ServeMux aggregating REST + WS + admin and a
|
||||
// WebSocket hub. It is safe for concurrent use once constructed.
|
||||
type Server struct {
|
||||
cfg *config.Config
|
||||
auth Authenticator
|
||||
bus bus.Bus
|
||||
caps CapabilityStore
|
||||
runner Chatter
|
||||
sessions SessionStore
|
||||
personas PersonaStore
|
||||
memories MemoryStore
|
||||
iot IoTStore
|
||||
frontend fs.FS
|
||||
log *slog.Logger
|
||||
hub *hub
|
||||
cfg *config.Config
|
||||
auth Authenticator
|
||||
bus bus.Bus
|
||||
caps CapabilityStore
|
||||
runner Chatter
|
||||
sessions SessionStore
|
||||
personas PersonaStore
|
||||
memories MemoryStore
|
||||
iot IoTStore
|
||||
auditor SubagentAuditor
|
||||
taskOutputs TaskOutputStore
|
||||
streaming bool
|
||||
frontend fs.FS
|
||||
log *slog.Logger
|
||||
hub *hub
|
||||
}
|
||||
|
||||
// New validates cfg and deps and returns a ready Server. Auth is required; the
|
||||
@@ -155,17 +182,20 @@ func New(cfg *config.Config, deps Deps) (*Server, error) {
|
||||
return nil, fmt.Errorf("gateway: auth dependency required")
|
||||
}
|
||||
s := &Server{
|
||||
cfg: cfg,
|
||||
auth: deps.Auth,
|
||||
bus: deps.Bus,
|
||||
caps: deps.Registry,
|
||||
runner: deps.Loop,
|
||||
sessions: deps.Session,
|
||||
personas: deps.Personas,
|
||||
memories: deps.Memories,
|
||||
iot: deps.IoT,
|
||||
frontend: deps.Frontend,
|
||||
log: sourcedLog(deps.Log),
|
||||
cfg: cfg,
|
||||
auth: deps.Auth,
|
||||
bus: deps.Bus,
|
||||
caps: deps.Registry,
|
||||
runner: deps.Loop,
|
||||
sessions: deps.Session,
|
||||
personas: deps.Personas,
|
||||
memories: deps.Memories,
|
||||
iot: deps.IoT,
|
||||
auditor: deps.Scheduler,
|
||||
taskOutputs: deps.Tasks,
|
||||
streaming: deps.Streaming,
|
||||
frontend: deps.Frontend,
|
||||
log: sourcedLog(deps.Log),
|
||||
}
|
||||
s.hub = newHub(s)
|
||||
s.hub.start()
|
||||
|
||||
Reference in new issue
Block a user