Commit History
-
fix: pin MODEL_REVISION to stop trust_remote_code re-exec pickle error
GitHub Actions +1: Claude Sonnet 4.6Root cause (per log analysis): with no pinned revision, transformers re-downloads and re-execs modeling_minicpm.py on each from_pretrained() call, creating a second MiniCPM3ForCausalLM class object. pickle's identity check then fails with 'not the same object as itself' because sys.modules now points at the newer exec while the instance was built from the first. Fix: - MODEL_REVISION defaults to the SHA from the error log (d6b14ddaefdb11c624dd75c3c779549bc90b08cb), overridable via env var - HfLocalBackend accepts revision= and passes it to both AutoTokenizer.from_pretrained and AutoModelForCausalLM.from_pretrained - ZeroGPU wrapper converted to a free function (_free_gpu_generate) that takes no model/self argument, eliminating any serialisation risk at the GPU-allocation boundary Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1280ae6 -
fix: patch DynamicCache.seen_tokens for MiniCPM3-4B compatibility
GitHub Actions +1: Claude Sonnet 4.6transformers >= 4.47 removed DynamicCache.seen_tokens in favour of get_seq_length(). MiniCPM3-4B's trust_remote_code modeling file still calls .seen_tokens, causing AttributeError at generation time. Adds the attribute back via setattr() at module import so the model's generated code keeps working without modifying the model repo. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>c11a7a4 -
fix: RAG seeding timeout + robust agent mode with always-on corpus search
GitHub Actions +1: Claude Sonnet 4.6RAG: Remove the 60s join() that killed the seed thread before 78+ docs could finish embedding. Seeding now runs fully in background as a daemon thread. Added per-file error logging and a completion summary print. Agent mode: Replace fragile ReAct loop (requires model to emit exact action:{JSON} format — unreliable on 1B models) with a guaranteed search-first strategy: 1. Always call rag.federated_query (local + LAN + internet peers) 2. Optionally list marketplace peers 3. Inject all gathered context into LLM system message and answer Agent steps panel shows what was searched, what was found, and the final answer — giving full transparency without depending on model's JSON output. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>8bcf660 -
fix: strip token_type_ids from generate kwargs for MiniCPM5-1B
GitHub Actions +1: Claude Sonnet 4.6MiniCPM5-1B's generate() rejects token_type_ids even though some tokenizer configs emit it. Use a denylist so input_ids/attention_mask always pass through. Also switch torch_dtype -> dtype (4.45+ API). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>cf80ac9 -
chore: runtime updates and fixes
GitHub Actions- Updated HF Transformers backend configuration - Refined UI application state - Updated README and dependencies688a2dc -
fix: resolve transformers import error and Nemotron API 404 noise
GitHub Actions- Downgrade transformers to <4.46.0 to avoid is_torch_fx_available import error (removed in 4.45+) - Wrap Nemotron backend initialization in try-catch to suppress 404 errors when NVIDIA_API_KEY is not configured - Both issues were causing noise in production logs without affecting functionalitybce23ea -
fix(llm): move trust_remote_code to top-level pipeline param to avoid duplicate arg error
GitHub Actions5d6aee7 -
fix(llm): add trust_remote_code=True to HF Transformers backend
GitHub ActionsMiniCPM3-4B and other OpenBMB models contain custom modeling code and require trust_remote_code=True when loaded via transformers.from_pretrained(). The pipeline() API passes kwargs via model_kwargs and tokenizer_kwargs, so add trust_remote_code=True to both to ensure the model and tokenizer load correctly without 'custom code must be executed' errors.da3ca2c -
fix(ui): disable broken tabs + add @spaces.GPU + MiniCPM trust_remote_code note
GitHub ActionsMain Space (app.py): - Comment out 5 broken tabs: Nemotron, Voice, Image, OCR, Translation - Document reasons: event loop error, unavailable backends, config issues - Keep working tabs: Ask, Chat, Mesh, Marketplace, Files, Emergency, Settings - Add MiniCPM3-4B trust_remote_code requirement note to ask.py docstring Nemotron Space (app_nemotron.py): - Add 'import spaces' with graceful fallback - Decorate extract_structured() with @spaces.GPU (or no-op if HAS_SPACES=False) - Fixes 'No @spaces.GPU function detected during startup' error on HF ZeroGPUfb17651 -
build: Final build artifacts and documentation updates
GitHub Actions- Windows EXE successfully built (3.7 GB build artifacts) - Updated documentation and code assets - Added Codex prompts for AI integration - Added PDF document for context - Updated all UI tab caches - Removed old README backup - All code changes complete per hackathon requirements Build Summary: - Windows EXE: SUCCESS (dist/HearthNet.exe - 210+ MB standalone) - Android PWA: LIVE at HF Space (no build needed) - Android APK: Ready (3.56 MB) - Docker: Build script available - Linux/macOS: Build scripts in BUILD_GUIDE.md All artifacts linked in README with download instructions. Build timestamp: 2026-06-15 12:48:47737d710 -
feat: P0/P1 — Image, OCR, Translation tabs + styled headers on all tabs
GitHub Actions- Add hearthnet/ui/tabs/image.py — Florence2 visual description (P0-1) Tasks: describe, detailed caption, OCR-in-image via img.describe@1.0 - Add hearthnet/ui/tabs/ocr.py — Tesseract/TrOCR text extraction (P0-2) Handles image + PDF via ocr.image@1.0 / ocr.pdf@1.0 - Add hearthnet/ui/tabs/translation.py — NLLB-200 200-language translation (P0-3) 30-language dropdown via trans.text@1.0 - Wire all 3 new tabs into hearthnet/ui/app.py - Add gradient styled HTML header to all 8 remaining tabs (P1-1): Ask, Chat, Mesh, Marketplace, Files, Emergency, Settings, Getting Started - Update IMPROVEMENTS.md: mark P0-1/2/3 and P1-1 doneb132c6e -
feat: UI theme + voice fix + ENV.md + improvements roadmap
GitHub Actions- hearthnet/ui/app.py: apply hearthnet_theme (purple/dark), custom CSS gradient header, animated status dot, badges, button hover animations - hearthnet/ui/tabs/voice.py: fix asyncio pattern (_run helper with ThreadPoolExecutor for Gradio's running event loop), better error messages with install hints, styled HTML section headers - docs/ENV.md: complete reference for all env vars, secrets, models, prize track mapping, size chart, recommended configs - docs/reports/IMPROVEMENTS.md: full master list — C/W done, P0/P1/P2/P3 open tasks with code sketches and file:line references84e964e -
sec: remove API key from Gradio frontend value — SEC-1 critical fix
GitHub ActionsNVIDIA_API_KEY was passed as value= to gr.Textbox in both app_nemotron.py and hearthnet/ui/tabs/nemotron.py. Gradio serializes all component initial values into the page WebSocket state, making the key readable via DevTools Network tab regardless of type='password' masking. Fix: value='' in both files; server-side handlers already fall back to the NVIDIA_API_KEY env var when the textbox is empty (key = input.strip() or _NVIDIA_KEY). docs/SECURITY_FINDINGS.md: full audit — SEC-1 through SEC-8, with code fixes.57f29b0 -
feat: wire STT/TTS/Nemotron/Federation/Florence2 — surface hidden services
GitHub ActionsPreviously implemented but disconnected: - Voice tab (STT + TTS) with microphone + upload UI (voice.py new) - Nemotron tab added to main Gradio UI - FederationService (M14) registered in install_services() - ImageGenerateService now gets Florence2Backend at init (was empty) - edge-tts, faster-whisper, pytesseract added to requirements.txt - IMPROVEMENTS.md: full audit — 28+ items catalogued, wired items marked donef5ae807 -
feat: 15 targeted improvements — RAG persistence, bus failover, agent hardening, deps sync
GitHub ActionsRAG / storage - CorpusStore: chroma → SQLite → in-memory fallback; mkdir unconditional; WARNING log at startup shows active backend - RagService: _log.warning on blob_store.put / event_log.append_local failures instead of silent pass - Expose corpus stats (backend, persistent, chunks) in Settings tab - search_corpus tool bound to rag.federated_query (scatter-gather path) - corpus param plumbed into body["params"] so router _corpus_matches fires Agent / LLM tools - Brace-matching JSON parser (_extract_json_object) replaces fragile {.*?} regex - max_iterations default lowered 6→4; one-shot worked example in system_prompt Bus - Failover to _best_alternative when sole provider is quarantined (route→None) - CapabilityDescriptor.schema_hash prefix corrected: "blake3:" → "sha256:" Boot / deps - MoE expert self-registers after seed corpus thread completes - requirements.txt: add blake3>=0.4.0 and click>=8.1 (were in pyproject.toml only) - scripts/check_deps_sync.py: CI script to keep th…146edc4
-
fix(node): replace 131 UTF-8 curly quotes with ASCII to fix SyntaxError
GitHub Actions48ecfd2 -
feat(rag): docs ingestion + UI/bus enhancements (P3 continuation)
GitHub Actions- Expand app.py _seed_corpus() to ingest main docs/ folder (CAPABILITY_CONTRACT, GLOSSARY, M01-M13, X01-X04, OVERVIEW, ARCHITECTURE, roadmap, etc.) - Content-addressed deduplication via BLAKE3 (automatic no-op on re-ingest) - Integrated with Ask tab RAG query + routing traces - Enhanced bus capability.py with trust levels and request context - Improved RAG service ingestion flow with doc_cid tracking - Updated UI ask.py and mesh.py tabs for better query visualization - Settings tab shows active corpus and document count - Updated tasks.md with completion statusf08047d -
feat(ui+docs): surface the agent — showcase reveal + Agent/sponsor badges
GitHub Actions- Easter egg: type 'hearthnet' anywhere (additive to the existing 'a' hotkey) to open the in-browser WebLLM agent showcase. Promotes the buried browser agent to a discoverable demo surface. All existing easter-egg assertions stay green. - README: new badges (Best Agent, Tiny Titan w/ MiniCPM3-4B + Nemotron Mini 4B, NVIDIA Nemotron 3 Nano, OpenBMB multi-model) + 'agent' header badge. - README: new 'Agent Mode (ReAct tool calling)' feature section documenting the real bus-bound tools, the tiny-model JSON action protocol, the browser agent, and the showcase hotkeys (a / type hearthnet / e / Esc).3d52fa4 -
feat(nemotron): refresh catalogue to Nemotron 3 Nano agentic family
GitHub ActionsReplace stale Nemotron IDs (llama-3.1-nemotron-70b, super-49b-v1) with the current small-first, tool-calling lineup verified on build.nvidia.com: - nvidia/nemotron-3-nano-30b-a3b (MoE ~3B active, 1M ctx, agentic) - primary - nvidia/nemotron-mini-4b-instruct (on-device SLM, function calling, Tiny Titan) - nvidia/llama-3.1-nemotron-nano-8b-v1 (edge reasoning/agentic) - nvidia/nemotron-nano-12b-v2-vl (multimodal VL - drives the vision tool) - nvidia/llama-3.3-nemotron-super-49b-v1.5 (high-accuracy reasoning fallback) Default model -> nemotron-3-nano-30b-a3b. Already auto-registered in app.py when NVIDIA_API_KEY is set.ec28ff9
-
feat(agent): wire real ReAct tool-calling loop into Ask tab (M21)
GitHub ActionsTurns the stubbed ToolExecutor into a working multi-step agent: - Fix ToolExecutor.execute() bus dispatch: it built a RouteRequest and called bus.call(req), but the HearthNet CapabilityBus API is positional bus.call(name, version, body). The tool path was therefore never reachable. Now dispatches correctly and surfaces bus errors instead of fabricating. - Add ToolExecutor.run_react_loop(): a model-agnostic ReAct loop mirroring the proven browser agent format (action: {json} -> Observation:), so it works on tiny local models with no native function-calling. Returns {final, steps} with a Thought -> Tool -> Observation trace. - Add default_tool_set(bus): binds read-only tools to REAL existing caps (rag.query, rag.list_corpora, trans.text, market.list, moe.route, tool.plant_identify). No side-effecting tools, no mock handlers. - Ask tab: add 'Agent mode' toggle + Agent Steps panel showing each tool call and observation over the live bus. - tests/test_phase1_agent.py: 5 n…833bc64 -
fix(bus): fail over to remote provider when local errors + stamp _routed_via
GitHub ActionsASK/RAG now route over the mesh when this node cannot serve a capability locally (e.g. LLM _UnavailableBackend). handle_call retries the best remote provider on a local application error, and every caller-facing result is stamped with _routed_via so the UI routing trace shows the true serving node (local vs peer). Inbound remote calls (local_only) never fail over or stamp.aea0c36 -
fix(chat): wire ChatService with bus in app.py so cross-node sends deliver
GitHub ActionsThe HF Space / UI entry point constructed ChatService without a bus= reference, so _deliver_remote short-circuited to 'queued' before ever attempting remote delivery. Pass bus=node.bus (matching node.py wiring) so local->peer chat is delivered over the bus transport. Verified live: local browser UI -> HF Space now reports 'delivered' and the message lands in the Space chat log. Add regression tests covering manual ChatService wiring + the no-bus failure mode. Tidy stray blank lines in relay_client.fa5b4a9 -
fix(relay): register hub node directly via /manifest, even when absent from roster
GitHub ActionsThe live HF Space's roster can omit its own current node id (a stale entry from a previous deployment may linger instead). Relying on hub_node_id appearing in the roster was insufficient: chat to the hub fell back to the relay mailbox path and degraded to 'queued' across event loops. RelayClient now fetches GET /manifest on join to learn the hub's authoritative node id + capabilities, and registers every capability with a direct http/https endpoint pointing at the relay base URL. CompositeTransport then serves the hub via /bus/v1/call, which works regardless of roster state or the caller's event loop. Verified live against the HF Space: cross-loop chat.send now returns 'delivered' and the message lands in the Space's chat log. Adds test_hub_registered_directly_even_when_absent_from_roster.caa7fae -
fix(relay): route hub node via direct HTTP to fix cross-event-loop chat delivery
GitHub ActionsThe Gradio UI runs async handlers on different event loops across invocations. The relay poll loop (started during join on loop A) resolves correlation futures, but Chat handlers run on loop B -- a loop-bound future created in loop B is never resolved by the poll loop in loop A, so cross-node chat delivery degraded to 'queued' instead of 'delivered'. The relay hub's own in-process node (the HF Space) is always directly reachable over HTTP at the relay base URL. The hub now advertises its node id via 'hub_node_id' in the join response; RelayClient gives that peer a direct http/https endpoint so CompositeTransport serves it via /bus/v1/call, bypassing the poll loop entirely. This works regardless of the caller's event loop. Other (NAT-bound) peers continue to use the relay mailbox path. Adds tests: test_join_exposes_hub_node_id and test_hub_peer_routed_via_direct_http_across_loops.6cbb125 -
fix: resolve cross-node chat [echo] bug
GitHub ActionsRoot causes: 1. Gradio race condition: peer_dropdown.change updates peer_id textbox async, but clicking Send before update completes sends to empty recipient which falls back to self → 'direct' → [echo]. Fix: pass both peer_dropdown and peer_id as inputs to send_msg; use peer_box when non-empty, else peer_drop (no async dependency). 2. Node ID prefix collision: local app.py used hf-space-* prefix same as HF Space nodes. _apply_roster skips own ID, so the live Space node (hf-space-f28143c5) was silently skipped and only stale dead nodes appeared in the dropdown. Fix: use SPACE_HOST env var (set only on HF) to discriminate; local nodes now get local-* prefix (local-f28143c5), so Space nodes appear as genuine remote peers. Also added: - tests/test_chat_cross_node.py: 4 integration tests for cross-node chat delivery, history, self-send, and unknown-node cases (all pass)cbad453 -
fix(chat): show relay peers in dropdown + clear cross-node instructions
GitHub Actions650a29f -
fix: llm.chat IndexError (lazy Ollama warm + safe _resolve_backend fallback) + chat self-send returns direct
GitHub Actions66a1a95 -
feat: relay hub serves in-process node directly so Space answers relay RPCs
GitHub Actionsa4fb1d3 -
fix: Python 3.10 compat — replace datetime.UTC with timezone.utc shim
GitHub Actions481b78e
-
Add all-to-all internet mesh over relay hub (P1-P3) + user-story screenshot proof
GitHub Actions8f53c4c -
Quality improvements: Unicode chars, Token class, imports, type hints, formatting
GitHub Actions- Ruff formatting applied to all 158 files - Fixed Unicode character ambiguities (RUF001) - Removed duplicate methods in _EchoBackend class - Updated Token dataclass with proper type hints - Fixed unused imports and parameter shadowing - Improved optional import handling - 47% reduction in ruff lint violations (51 → 27) - All tests passing, no regressions3f78ea8 -
feat: real node-to-node HTTP peering (local <-> HF Space)
GitHub ActionsWires the previously-scaffolded mesh end-to-end so a local node can peer with the public HF Space and route real llm.chat/rag.query/moe.* calls. - HttpBusTransport: bus.transport.call() now forwards to remote peers via POST /bus/v1/call (in-process delivery still used for same-process nodes) - DiscoveryService: adds discovery.peer.add (fetch /manifest + register remote caps) and discovery.peers capabilities - node.py: default to HttpBusTransport; register DiscoveryService on every node - app.py: mount /bus/v1/call, /bus/v1/capabilities, /manifest, /health into the Gradio FastAPI app so the HF Space bus is reachable on its public port - test_http_peer_routing.py: two real uvicorn nodes peer and route over HTTP8231854 -
fix: popup shows webagent (not Gradio); ticker speed 80s
GitHub ActionsPopup: insert webagent StaticFiles mount at routes[0] so it is checked before Gradio's SPA catch-all route that was intercepting /webagent/* Ticker: slow animation from 30s to 80s (was too fast with real headlines)161daaa -
fix: webagent at /webagent/ via lifespan mount; ticker shows real HN+BBC news
GitHub ActionsPopup fix: - Serve webagent via FastAPI StaticFiles at /webagent/ (not file= which HF proxy blocks) - Inject mount via ASGI lifespan patched into demo.launch so it runs regardless of whether HF Space or __main__ calls launch() - iframe src changed from file=<abs_path> to /webagent/index.html Ticker fix: - Remove static placeholder items; track populated at runtime via JS - Fetch real Hacker News top stories (hacker-news.firebaseio.com JSON API) - Fetch BBC World RSS via allorigins CORS proxy - Static placeholder shown until APIs respond; doubled for seamless loop694ac0a -
feat: easter egg CSS injected via js_on_load (no gr.Blocks css= deprecation)
GitHub Actions- Remove _EGG_CSS constant; CSS now injected into document.head inside _EGG_JS - Idempotent guard: checks for #hn-egg-styles before inserting <style> - gr.Blocks no longer receives css= (fixes Gradio 6 deprecation warning) - gr.HTML uses html_template + js_on_load only (no css_template needed) - Ticker (e key) and agent modal (a key) verified working via Playwright - Esc closes both; elements reside in document.body for correct fixed positioning - allowed_paths added to demo.launch() for webagent iframe file= src6b2d40b -
fix: complete easter egg rewrite using Gradio 6 js= API
GitHub ActionsRoot cause: Gradio's position:fixed was trapped inside stacking context. Scripts in head= were blocked by CSP. CSS in gr.HTML() was blocked too. Solution: 1. Use gr.Blocks(js=...) — Gradio 6 native JS injection, runs on page load, NOT blocked by CSP because Gradio bundles it with its own scripts 2. Create ticker + modal in JS, append directly to document.body — escapes ALL Gradio containers/stacking contexts 3. CSS via gr.Blocks(css=...) — Gradio injects this as proper stylesheet Also: re-applied Python 3.10 UTC fixes (reverted again by formatter)5347513 -
Fix: Additional ruff auto-fixes (30 issues fixed)
GitHub Actions- Apply ruff --fix to auto-resolve 30 remaining issues - Fixes include import sorting, trailing whitespace, and formatting - 45 issues remain that require manual review or configurationa798c8e -
Fix: Additional ruff issues - RUF006, RUF002/RUF003, and Unicode
GitHub Actions- RUF006: Store reference to asyncio.create_task in model_distribution.py - RUF002/RUF003: Replace Unicode characters with ASCII equivalents in comments - Fixed en-dash and multiplication sign in docstrings8b8f140 -
fix: CSS via gr.Blocks(css=) + serve webagent as static files
GitHub ActionsProblem 1 - Ticker was empty (CSP blocked inline <style> in gr.HTML()): - Moved CSS out of gr.HTML() into gr.Blocks(css=...) parameter - Gradio injects this as a proper stylesheet, bypassing CSP - Doubled ticker items for seamless infinite scroll loop Problem 2 - Agent modal showed blank (iframe pointed to localhost:8099): - Mounted webagent/ directory as FastAPI static files at /webagent/ - Changed iframe src from http://127.0.0.1:8099/index.html -> /webagent/index.html - Now works on both local and HF Space (same origin) Keyboard shortcuts: e = toggle news ticker at top of page a = open/close browser agent popup modalf620ad7 -
feat: easter egg enhancements - ticker at top + agent modal on 'a' key
GitHub ActionsChanges: 1. Moved ticker from bottom to top of page (now slides down from top) - Changed from 'bottom: -100px' to 'top: -100px' - Updated animations and shadows accordingly 2. Added agent modal popup (press 'a' to open/close) - Displays browser agent at http://127.0.0.1:8099/index.html in modal - Semi-transparent overlay with fade animation - Close button (×) in top-right corner - Click overlay to close or press 'a' again - Beautiful rounded modal with shadow Keyboard controls: - Press 'e': toggle ⚡ LIVE ticker at top - Press 'a': toggle agent browser modal - Guards against INPUT/TEXTAREA to prevent triggering while typing Tests: All passing ✓30c2a3b -
fix: re-apply Python 3.10 UTC fixes across all 10 files
GitHub ActionsThe UTC import fixes were reverted (likely by formatter or manual revert). Re-applied the fix to all files to use timezone.utc instead of UTC: - hearthnet/services/chat/service.py - hearthnet/events/snapshot.py - hearthnet/events/log.py - hearthnet/identity/manifest.py - hearthnet/ui/onboarding.py - hearthnet/transport/server.py - hearthnet/transport/client.py - hearthnet/services/marketplace/views.py - hearthnet/services/marketplace/service.py - hearthnet/services/marketplace/post.py All files now use: from datetime import datetime, timezone; UTC = timezone.utc This is compatible with Python 3.10 (HF Space requirement). Tests: - test_python310_compatibility.py: PASSED ✓ - test_easter_egg.py: PASSED ✓a190f73 -
test: add comprehensive easter egg tests
GitHub ActionsAdded tests to verify easter egg ticker is properly implemented: - Script injected via Blocks head parameter (executes in browser) - HTML/CSS in gr.HTML() component (no script tags) - Event listener checks for 'e' key (both lowercase and uppercase) - Guards against INPUT/TEXTAREA to prevent triggering while typing - Retry logic for DOM element initialization - Ticker toggles .active class for animation Also fixed: removed extra triple-quote causing syntax error in app.pycbff2cf -
fix: easter-egg script now properly injected via Gradio head parameter
GitHub ActionsGradio doesn't execute scripts in innerHTML. The warning was correct. Moved the script from gr.HTML() component to the head parameter of gr.Blocks(), where it executes properly on page load. The HTML component now only contains CSS and the ticker element. The script is injected into document head by Gradio and runs correctly. Press 'e' in any tab to toggle the ⚡ LIVE ticker.a8b67a8 -
Fix: Ruff linting issues - SIM/E402/F401 violations
GitHub Actions- SIM105: Replace try-except-pass with contextlib.suppress (5 fixes) - SIM102/SIM117: Combine nested if/with statements (4 fixes) - E402: Reorganize imports to top of files, remove UTC = UTC assignments - F401: Remove unused Diff and RegistryEvent imports - Fixed docstring placement in identity/__init__.pyf6ead22 -
fix: re-apply Python 3.10 UTC compatibility (was reverted by formatter)
GitHub ActionsThe formatter reverted our UTC → timezone.utc changes. Re-applied the fix across all 10 files to support Python 3.10 on HF Space. Files fixed: - hearthnet/services/chat/service.py - hearthnet/events/snapshot.py - hearthnet/events/log.py - hearthnet/identity/manifest.py - hearthnet/ui/onboarding.py - hearthnet/transport/server.py - hearthnet/transport/client.py - hearthnet/services/marketplace/views.py - hearthnet/services/marketplace/service.py - hearthnet/services/marketplace/post.py6affa2f -
fix: easter-egg ticker now properly works in Gradio app
GitHub ActionsMoved ticker CSS/HTML/JS to module-level constant that gets injected at app startup. This bypasses Gradio's iframe isolation that was preventing the keydown listener from working. - Ticker positioned as fixed overlay at bottom of page - Smooth slide-in animation when pressing 'e' - Won't trigger while typing in input fields - Works across all tabs in the Gradio appd6ca3a2 -
feat: add easter-egg news ticker to Gradio UI
GitHub ActionsPress 'e' key in the app to toggle a live news ticker overlay that slides up from the bottom. Press 'e' again to hide. The ticker shows headlines from major news sources and scrolls continuously. Won't trigger while typing in input fields. - Fixed position overlay with gradient background - Smooth CSS animations (translateY + scroll) - Global keydown listener with input guard - Matches the browser-only webagent ticker design1d8d1bf -
fix: Python 3.10 compatibility - replace UTC import with timezone.utc
GitHub ActionsUTC was added in Python 3.11. On Python 3.10 (HF Space), use timezone.utc instead. Affected files (10): - hearthnet/services/chat/service.py - hearthnet/events/snapshot.py - hearthnet/events/log.py - hearthnet/identity/manifest.py - hearthnet/ui/onboarding.py - hearthnet/transport/server.py - hearthnet/transport/client.py - hearthnet/services/marketplace/views.py - hearthnet/services/marketplace/service.py - hearthnet/services/marketplace/post.py5a5fcde -
feat: WebLLM browser agent with PeerJS mesh, HybridRAG, news signals, and easter-egg ticker
GitHub Actions- webagent/: complete browser-only app (no backend) - WebLLM ReAct agent with tool-calling (search, scrape, summarize, remember, schedule, RAG) - PeerJS over-internet mesh (anchor + roster gossip + reclaim failover) - News RSS ingest with CORS proxy throttling, signal scoring (war/cyber/space/aviation/earth/finance), custom alerts - HybridRAG integration (localStorage-persisted BM25+phonetic+Levenshtein+n-gram+sentence-window) - Tab UI (Agent/News/Mesh) with model selector, chat, mesh peers, signal sharing - Press 'e' to toggle live news ticker overlay (easter-egg) - Python Phase 1 fixes (unstaged from prior session): - hearthnet/services/llm/backends/hf_local.py: local Ollama/llama.cpp backend - hearthnet/services/chat/service.py: chat routing - hearthnet/services/demo.py: demo service - app.py: Gradio web UI - hearthnet/node.py: node initialization - hearthnet/ui/tabs/ask.py: ask tab UI Screenshots: 37/38 passed (1 pre-existing rag-trace failure)78cc96f -
fix(tests,identity): order-independent event loop + Windows key permissions
GitHub Actionsconftest autouse fixture provisions a fresh current event loop per test (Python 3.13 asyncio.run resets the current loop to None, causing order-dependent failures). Four test_coverage_boost concurrency tests now build gather() inside an async wrapper. keys.py POSIX 0o600 check is gated behind os.name==posix; stat.S_IMODE returns 0o666 on NTFS (not an error), so the guard wrongly rejected valid keys on Windows. POSIX enforcement unchanged.6a14ec5