Add generic MQTT 3.1.1/5.0 support for IoT and messaging integration:
- MqttConfig with broker_url, TLS, QoS, auth via env vars
- MqttAdapter implementing ChannelAdapter trait
- Support for text and JSON {"text": "..."} payloads
- Command messages via /command args syntax
- Auto-reconnect with exponential backoff
- Message chunking for long responses
Configuration example:
[channels.mqtt]
broker_url = "tcp://broker.hivemq.com:1883"
subscribe_topic = "openfang/inbox"
publish_topic = "openfang/outbox"
- #825: Doctor now surfaces blocked workspace skills count in injection scan
- #828: Skill install detects Git URLs (https://, git@) and clones before install
- #856: Custom model names preserved — user-defined models take priority over builtins
- #770: Dashboard WS streaming now triggers Alpine.js reactivity via splice()
- #774: tool_use.input always normalized to JSON object (fixes Anthropic API errors)
- #851/#808: Global skills loaded for all agents; workspace skills properly override globals
- #785: Gemini streaming SSE parser handles \r\n line endings (fixes empty response loop)
All 2,186 tests passing. Live tested with daemon.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- #845: Model fallback chain now retries with fallback_models on ModelNotFound
- #844: Heartbeat skips idle agents that never received a message (no more crash loops)
- #823: Doctor --json outputs clean JSON to stdout, tracing to stderr, BrokenPipe handled
- #767: Workflows page scrollable with flex layout fix
- #802: Model dropdown handles object options (no more [object Object] for Ollama)
- #816: Spawn wizard provider dropdown loads dynamically from /api/providers (43 providers)
All 829+ tests passing. Live tested with daemon.
- #834: Remove 3 decommissioned Groq models (gemma2-9b-it, llama-3.2-1b/3b-preview)
- #805: Ollama streaming parser now checks both reasoning_content and reasoning fields
- #820: Browser Hand checks python3 before python, fix optional dep logic
- #848: Hand continuous interval changed from 60s to 3600s to prevent credit waste
- #826: Doctor command no longer reports all_ok when provider key is rejected
- #836: WebSocket tool events now include tool call ID for concurrent call correlation
All 825+ tests passing. Verified live with daemon.
- Implement create-with-PATCH-on-conflict push pattern (POST 409 → PATCH)
- Migrate push and delete endpoints from deprecated v3 to v4 API
- Replace workspaceId with projectId in push/delete API calls
Claude CLI ≥2.x emits type=assistant events where the response text is
inside message.content[{"type":"text","text":"..."}] rather than a flat
content string. The old handler only checked event.content, so every
token was silently dropped and streaming always returned an empty response.
The handler now checks the flat content field first (backward-compatible),
then falls back to joining all text blocks from message.content[].
Refs: RightNow-AI/openfang#295
Mirror the same environment fixes applied to complete(): inject HOME so
the CLI locates ~/.claude/credentials when running as a service, and set
stdin to null so the process does not block on interactive input.
Refs: RightNow-AI/openfang#295