feat(diagnostics): listen for agent_hello + warn on bad client config#16
Conversation
|
Casing nit, but load-bearing: the wire string The Flutter One-line diff in - AGENT_HELLO: "agent_hello",
+ AGENT_HELLO: "agent-hello",The TS constant name Coordinated comment going onto |
Tech World clients now publish a one-shot `agent_hello` data message on the LiveKit data channel immediately after connect (Flutter PR coming), carrying the ConnectOptions actually in use plus SDK / build / version metadata. This change makes both Clawd and Dreamfinder log every hello they receive and emit a structured warning when a client is connected with `adaptiveStream: true` — the configuration known to silently break Tech World video forwarding (and pause audio via SFU demand-signaling) because the Flutter client renders through the Flame canvas instead of `VideoTrackRenderer`. Complements the publisher-side heuristic detector in PR #15: that one infers the misconfiguration from a downstream symptom (track-subscribed but no first frame); this one reads the cause directly off the wire. - New src/livekit-topics.ts mirroring Tech World's LiveKitTopic (today: just AGENT_HELLO; format ready for the rest as needed). - New src/agent-hello.ts with a pure parseAgentHello() validator (rejects unknown schemaVersion, missing required fields, wrong types) and a handleAgentHello() that logs structured JSON via console.log/warn. - Wired into both src/index.ts and src/dreamfinder-entry.ts data-received handlers ahead of any other topic switch. - No persistence — the log line is the artifact. No retries, no buffering. Safe to deploy independently of the Flutter PR: until clients ship the publisher side, nothing arrives on `agent_hello` and the new code paths are unreachable. After the Flutter PR ships, old bots silently drop the data message (no consumer). Tests: npm run typecheck / lint / build all green. No test harness in this repo today; parseAgentHello documents the expected shape in JSDoc and ships as a pure function so it's trivially unit-testable when one gets added. Wire contract: topic string `agent_hello` (snake_case, deliberate — treated as the inbound agent-fleet channel name). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wire-string casing audit on the Flutter side flagged 'agent_hello'
as the lone snake_case outlier — every other LiveKitTopic in the
Flutter enum is kebab-case ('map-info', 'door-unlock', 'chat-response',
…). Mirror the Flutter-side fix here so the wire contract stays
byte-for-byte identical.
Companion fix lands in `enspyrco/tech_world` PR #478.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9ffa2a8 to
c4ed225
Compare
Summary
Tech World clients now publish a one-shot
agent_hellodata message immediately afterroom.connect()succeeds (Flutter PR enspyrco/tech_world#478), carrying the ConnectOptions actually in use plus SDK / build / version metadata.This change makes both Clawd and Dreamfinder log every hello they receive and emit a structured warning when a client is connected with
adaptiveStream: true— the configuration known to silently break Tech World video forwarding (and pause audio via SFU demand-signaling) because the Flutter client renders through the Flame canvas instead ofVideoTrackRenderer.Complements PR #15's publisher-side heuristic: that infers misconfiguration from a downstream symptom (track-subscribed but no first frame); this reads the cause directly off the wire.
Coupled PR
Flutter publisher: enspyrco/tech_world#478 (
feat/agent-hello-diagnostic). The two PRs are independently deployable:Wire contract
Topic:
agent_hello(snake_case — deliberate, agent-inbound channel naming).Payload v1:
{ "schemaVersion": 1, "clientSdk": "flutter", "clientSdkVersion": "2.7.0", "buildSha": "string", "appVersion": "0.0.0+1", "adaptiveStream": false, "dynacast": false, "platform": "macos|ios|android|web|...", "userAgent": "string | null" }Log shape
Successful parse:
{ "event": "agent_hello_received", "participant": "<identity>", "payload": { ... } }Bad-config warning (only when
adaptiveStream === true):{ "event": "client_misconfig_detected", "warning": "adaptiveStream=true breaks Tech World video/audio forwarding", "participant": "<identity>", "clientSdkVersion": "...", "buildSha": "...", "appVersion": "..." }Notable design choices
src/livekit-topics.tsto start mirroring Tech World'sLiveKitTopicenum (onlyAGENT_HELLOtoday — extend opportunistically).parseAgentHellois a pure validator: rejects unknownschemaVersion, missing or wrong-typed fields. No throw on bad payloads; warn + drop.console.log/console.warnmatches the rest of this codebase. Project memory mentions pino but the codebase doesn't actually have it — followed what's here.src/index.ts(Clawd) andsrc/dreamfinder-entry.ts(DF) so every bot variant observes hellos.Test plan
npm run typecheckclean.npm run lintclean.npm run buildclean.tw-clawd/tw-dreamfinderlogs foragent_hello_receivedlines on next player join.🤖 Generated with Claude Code