[bug] [presence] poll-mode workspaces show awaiting_agent — platform-side presence tracker should count activity polls #24
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
External user reported v0.4.0-gitea.1 channel plugin (delivery_mode=poll) workspaces show
status: awaiting_agentin canvas instead ofonline, even though plugin is actively polling/workspaces/:id/activityand auth is valid.Filed as companion to molecule-mcp-claude-channel#? (presence ping on plugin side).
Platform-side question
Should the platform's presence tracker count
/workspaces/:id/activityGETs from delivery_mode=poll workspaces as keepalive ticks?Today the tracker likely only counts explicit heartbeat POSTs (which the legacy server-mode plugin makes). Poll-mode plugins skip that POST since they're already long-polling activity. Net result: poll-mode workspaces look offline even when actively running.
Proposed fix paths
/workspaces/:id/activityGET from a registered workspace counts as last_seen_at update. Fixes ALL future poll-mode plugins without per-plugin changes.Recommendation
Path 1 is cleaner — single source of truth for presence; plugins don't have to know about it. But platform team should evaluate based on existing presence-tracker semantics.
Investigation handoff
/workspaces/:idGET handler or a separate presence reconciler.last_seen_atvslast_heartbeat_atvsagent_attached_at.Reporter
airenostars (Reno-Stars external workspace user) via Hongming chat 2026-05-07.
Out of scope
Closing as won't-fix — plugin-side fix landed in molecule-mcp-claude-channel#7 (tag v0.4.0-gitea.2).
Why platform-side change skipped
Path 1 (count
/workspaces/:id/activityGETs as keepalives) is interesting but a deeper semantic change to a hot read endpoint. Risks:last_heartbeat_atbecomes ambiguous between "agent alive" and "someone read activity" — the column documentation in models/workspace.go would need to change.UPDATE workspaces SET last_heartbeat_at = now()per GET would multiply DB writes by the poll cadence (5s default) across every poll-mode workspace.The plugin-side fix is the smaller blast radius and matches the existing Python runtime + legacy server-mode plugin contract: a real
/registry/heartbeatPOST is the source of truth for presence. The platform contract stays unchanged.Plugin fix details
setIntervalposting{workspace_id: id}to/registry/heartbeatevery 30s (three ticks inside the platform's 90sREMOTE_LIVENESS_STALE_AFTERstale window).internal/registry/healthsweep.go:166whereexternalruntime workspaces with stale heartbeat get flipped toawaiting_agent.If future poll-mode plugins ship without their own heartbeat path, we can revisit Path 1 with proper guard rails (e.g. only count GETs as keepalives within a narrower window). Until then, closing this issue.