feat(presence): F-5b presence-sync — mirror sm.Machine into Fabric
Adds an internal/presence package that ticks every 30s (configurable
via presence_interval_seconds), reads each bound agent's sm.Machine
state through host.ReadAgentState, maps to Fabric's 6-status enum,
and PUTs diffs to /api/agents/:userId/presence on every guild the
agent belongs to.
Semantic mapping (the part flagged "needed" in the prior README):
idle → idle
working → on_call
busy → busy
offline → offline
exhausted/unknown reserved for backend-side fallbacks; we don't push.
Tick is mutex-guarded (avoids the upsert race the openclaw incident
called out in agent-presence.service.ts) and diff-gated so writes are
sparse. Token-cache invalidation on PUT failure handles guild JWT
rotation.
fabric.Client gains SetAgentPresence helper. README marks F-5b ✅.
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
"git.hangman-lab.top/hzhang/Plexum-fabric-channel-plugin/internal/fabric"
|
||||
"git.hangman-lab.top/hzhang/Plexum-fabric-channel-plugin/internal/identity"
|
||||
"git.hangman-lab.top/hzhang/Plexum-fabric-channel-plugin/internal/inbound"
|
||||
"git.hangman-lab.top/hzhang/Plexum-fabric-channel-plugin/internal/presence"
|
||||
"git.hangman-lab.top/hzhang/Plexum-fabric-channel-plugin/internal/subdisc"
|
||||
"git.hangman-lab.top/hzhang/Plexum-fabric-channel-plugin/internal/tokens"
|
||||
"git.hangman-lab.top/hzhang/Plexum-fabric-channel-plugin/internal/tools"
|
||||
@@ -43,9 +44,10 @@ import (
|
||||
// "sync_commands": ["new","stop"] // optional override; defaults to ["new","stop"]
|
||||
// }
|
||||
type HostConfig struct {
|
||||
CenterAPIBase string `json:"center_api_base"`
|
||||
CommandsSyncKey string `json:"commands_sync_key,omitempty"`
|
||||
SyncCommands []string `json:"sync_commands,omitempty"`
|
||||
CenterAPIBase string `json:"center_api_base"`
|
||||
CommandsSyncKey string `json:"commands_sync_key,omitempty"`
|
||||
SyncCommands []string `json:"sync_commands,omitempty"`
|
||||
PresenceIntervalSeconds int `json:"presence_interval_seconds,omitempty"` // F-5b; 0 → default 30s
|
||||
}
|
||||
|
||||
type fabricPlugin struct {
|
||||
@@ -237,6 +239,21 @@ func (p *fabricPlugin) Init(ctx context.Context, host plugin.HostAPI) error {
|
||||
}()
|
||||
host.Log("info", "fabric inbound supervisor started",
|
||||
map[string]any{"agents": sup.AgentIDs, "bindings": len(p.bindings)})
|
||||
|
||||
// F-5b: presence-sync. Shares the inbound supervisor's context
|
||||
// so it dies together. Tick interval honours config override.
|
||||
interval := time.Duration(p.cfg.PresenceIntervalSeconds) * time.Second
|
||||
ps := &presence.Sync{
|
||||
Host: host,
|
||||
Client: p.client,
|
||||
Tokens: p.tokens,
|
||||
Identities: p.identities,
|
||||
Bindings: p.bindings,
|
||||
Interval: interval,
|
||||
}
|
||||
ps.Start(ctxBg)
|
||||
host.Log("info", "fabric presence-sync started",
|
||||
map[string]any{"interval": ps.Interval.String()})
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user