Commit Graph

3 Commits

Author SHA1 Message Date
7911cc6320 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 .
2026-06-01 08:40:17 +01:00
d6bea46d00 feat: Phase F-3 + F-4 — exp backoff + agent tool surface (batch 1)
F-3 refinements:
- internal/inbound: replace fixed 3s reconnect wait with exponential
  backoff (1s → 60s, ×2, reset when prior session lasted >30s); proxy
  for "healthy" vs "flapping" and avoids hot reconnect loops when the
  server is sick

F-4 agent tool surface (port of openclaw plugin's tools.ts):
- internal/tools/tools.go (~370 LOC): Registry binds Deps {Client,
  Tokens, Identities} and exposes 8 agent-facing tools:
    fabric-send-message     post a normal message to any channel
    fabric-send-sys-msg     post a kind=sys message (bypasses turn engine)
    fabric-channel-list     list channels visible in a guild
    fabric-guild-list       list guilds the agent is in
    fabric-message-history  paginate channel messages by seq
    fabric-channel-set-purpose  PATCH the channel's purpose
    fabric-channel          fetch metadata + members for one channel
    fabric-canvas           get/share/update/remove channel canvas
- internal/tools/contracts.go: static ToolContract list — kept in sync
  with install.sh's manifest emitter
- Every agent-scoped tool requires agent_id in input args (Plexum SDK
  doesn't propagate calling agent id through CallTool today)
- guild_node_id defaults to agent's first guild for fabric-send-message

internal/fabric/client.go: new REST methods needed by tools —
PostSystemMessage, CreateChannel, CloseChannel, JoinChannel,
LeaveChannel, SetChannelPurpose, GetCanvas, ShareCanvas, UpdateCanvas,
RemoveCanvas, SyncCommands.

cmd/plexum-fabric-channel-plugin/main.go:
- Manifest declares the tool surface via tools.New(...).Contracts()
- CallTool dispatches "send" to handleSend (outbound for channel
  manager), everything else to tools.Registry.Handler(name)

scripts/install.sh:
- Manifest tools[] now lists all 9 tools with schemas — matches what
  internal/tools/contracts.go advertises

Live verified against running Fabric stack:
  $ plexum plugin-call fabric-guild-list '{"agent_id":"fabrictester"}'
    → "guilds for agent fabrictester (1): test-guild2 @ http://localhost:7003"
  $ plexum plugin-call fabric-channel-list '{...,"guild_node_id":"test-guild2"}'
    → 2 channels listed
  $ plexum plugin-call fabric-message-history '{...,"limit":5}'
    → 5 messages with timestamps + authors

F-5+ deferred:
- create-{chat,work,report,discussion}-channel (batch 2)
- sub-discussion family (state store + 3 tools)
- presence-sync + command-sync
- attachments

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 15:35:39 +01:00
f8d43ae70e feat: Phase F-1 — Plexum-fabric-channel-plugin foundation
Ports the foundation of Fabric.OpenclawPlugin to a native Plexum
channel plugin (Go). F-2+ phases (socket.io inbound, wakeup gate,
tools, presence, etc.) follow.

Layout:
  internal/identity/      — fabric-identity.json registry (agent → API key)
  internal/fabric/        — REST client (Center auth + Guild messaging)
  internal/config/        — channels/<name>.json fabric extension parser
  cmd/plexum-fabric-register/      — agent registration CLI
  cmd/plexum-fabric-channel-plugin/— Plexum SDK plugin entry
  scripts/install.sh      — build + install + manifest generator

Plugin behavior (F-1):
- Reads <profile>/channels/*.json, filters plugin=plexum-fabric-channel,
  builds (plexum-channel-name → fabric channel-id) index
- Validates each bound agent's API key against Center at init
  (warmSessions); logs warning but doesn't refuse init on bad keys
- `send` MCP tool: POST plain text to the bound Fabric channel as the
  agent user; selects guild endpoint+token from cached session
- Manifest channels[] is generated by install.sh from current
  channels/*.json — re-run with --reset-manifest after adding bindings
- Plugin-private config at
  <profile>/plugins/plexum-fabric-channel/config.json
  (center_api_base, default http://localhost:7001/api)

Live smoke verified:
- plexum-fabric-register against running Fabric Center (port 7001):
  validated fak_..., wrote identity file with user_id + email captured

Tests: identity (5) + config (6) = 11 unit tests.

F-2 will hook socket.io for inbound + wakeup gating + token refresh.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 15:13:34 +01:00