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 ✅.
22 lines
400 B
Go
22 lines
400 B
Go
package presence
|
|
|
|
import "testing"
|
|
|
|
func TestStateToFabricMapping(t *testing.T) {
|
|
cases := []struct {
|
|
in, want string
|
|
}{
|
|
{"idle", "idle"},
|
|
{"working", "on_call"},
|
|
{"busy", "busy"},
|
|
{"offline", "offline"},
|
|
{"", ""},
|
|
{"weird", ""},
|
|
}
|
|
for _, c := range cases {
|
|
if got := StateToFabric(c.in); got != c.want {
|
|
t.Errorf("StateToFabric(%q) = %q, want %q", c.in, got, c.want)
|
|
}
|
|
}
|
|
}
|