Skip to content

feat: query device state with CEL discovery predicates - #64

Merged
soupat merged 4 commits into
mainfrom
feat/discovery-state-predicate
Sep 15, 2026
Merged

soupat merged 4 commits into
mainfrom
feat/discovery-state-predicate

Conversation

@soupat

@soupat soupat commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Agents can now ask state questions over devices with no callable functions using discover(selector, where=...). The registry evaluates the same CEL dialect as broadcast over stored status, identity, and device labels before pagination; device-only tool results contain ids, types, and locations plus the match count and label histogram. Calls without where keep their existing behavior.

Both registry clients forward predicates. State queries bypass the edge SDK's fleet cache, malformed predicates return JSON-RPC -32602 / tool invalid_predicate, and clients reject older servers that ignore the filter. Predicate pagination and counts include only ACL-visible matches. CEL is installed by both the server package and registry Docker image, and the discovery guide documents bindings, freshness, and compatibility.

Installing CEL also activates the broadcast predicate scale test. Its first CI run exposed idle predicate workers timing out before submission because an unnecessary semaphore-task yield let other devices consume their deadline. Idle slots are now acquired directly; the 50 ms deadline, four-worker cap and contended timeout behavior are preserved, with a deterministic regression test. The scale test gets a simulation-only timeout budget because its devices share one interpreter/event loop; Python 3.12 can otherwise reject already-computed results while other simulated devices occupy that loop. Production timeout tests retain their original limits.

Validation:

  • Linux integration CI: 250 passed, including the previously failing large-fleet predicate case. Unit, lint, and both fuzz jobs also pass on fbc5ccb.
  • Edge, server, and agent-tools unit suites, including regressions for 5,000 function-less devices, malformed predicates, pagination, cache isolation, old-server handling, and hidden-device counts.
  • After the broadcast scheduling fix: all 561 edge tests and all 18 NATS broadcast integration tests pass locally (the 14 Zenoh variants are excluded by --backend=nats).
  • Python 3.12 container: all six predicate-runtime tests pass; the simulated CEL fleet returns 50/50 expected matches at 200 devices and 250/250 at 1,000 devices. The final large-fleet NATS/etcd integration case also passes locally.
  • ruff check packages/ tests/ and git diff --check pass; all three package wheels build.
  • Live local NATS with the real registry handler, SDK and agent connection over 5,000 synthetic registry records: one registry request, one matching device, a 350-byte tool response in about 0.5 seconds. Malformed predicates and changed status were also verified.

The full local integration attempt was interrupted after six Zenoh peer-discovery failures on macOS (those tests passed in the first Linux CI run); NATS broadcast cases are validated separately against Docker. The 5,000-record discovery check used a synthetic stored snapshot rather than etcd. State discovery requires an updated registry and edge SDK; D2D and old-server client fallback are not included. Registry scan cost and heartbeat/snapshot freshness remain unchanged.

Closes #63.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Discovery: state predicate (CEL where) on discover/listDevices for state questions over function-less devices

1 participant