forked from Rockachopa/Timmy-time-dashboard
fix: Docker-first test suite, UX improvements, and bug fixes (#100)
Dashboard UX: - Restructure nav from 22 flat links to 6 core + MORE dropdown - Add mobile nav section labels (Core, Intelligence, Agents, System, Commerce) - Defer marked.js and dompurify.js loading, consolidate CDN to jsdelivr - Optimize font weights (drop unused 300/500), bump style.css cache buster - Remove duplicate HTMX load triggers from sidebar and health panels Bug fixes: - Fix Timmy showing OFFLINE by registering after swarm recovery sweep - Fix ThinkingEngine await bug with asyncio.run_coroutine_threadsafe - Fix chat auto-scroll by calling scrollChat() after history partial loads - Add missing /voice/button page and /voice/command endpoint - Fix Grok api_key="" treated as falsy falling through to env key - Fix self_modify PROJECT_ROOT using settings.repo_root instead of __file__ Docker test infrastructure: - Bind-mount hands/, docker/, Dockerfiles, and compose files into test container - Add fontconfig + fonts-dejavu-core for creative/assembler TextClip tests - Initialize minimal git repo in Dockerfile.test for GitSafety compatibility - Fix introspection and path resolution tests for Docker /app context All 1863 tests pass in Docker (0 failures, 77 skipped). Co-authored-by: Alexander Payne <apayne@MM.local> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
6e67c3b421
commit
89cfe1be0d
@@ -275,7 +275,11 @@ async def _task_processor_loop() -> None:
|
||||
def handle_thought(task):
|
||||
from timmy.thinking import thinking_engine
|
||||
try:
|
||||
result = thinking_engine.think_once()
|
||||
loop = asyncio.get_event_loop()
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
thinking_engine.think_once(), loop
|
||||
)
|
||||
result = future.result(timeout=120)
|
||||
return str(result) if result else "Thought completed"
|
||||
except Exception as e:
|
||||
logger.error("Thought processing failed: %s", e)
|
||||
@@ -457,15 +461,7 @@ async def lifespan(app: FastAPI):
|
||||
# Create all background tasks without waiting for them
|
||||
briefing_task = asyncio.create_task(_briefing_scheduler())
|
||||
|
||||
# Register Timmy in swarm registry
|
||||
from swarm import registry as swarm_registry
|
||||
swarm_registry.register(
|
||||
name="Timmy",
|
||||
capabilities="chat,reasoning,research,planning",
|
||||
agent_id="timmy",
|
||||
)
|
||||
|
||||
# Run swarm recovery and log summary
|
||||
# Run swarm recovery first (offlines all stale agents)
|
||||
from swarm.coordinator import coordinator as swarm_coordinator
|
||||
swarm_coordinator.initialize()
|
||||
rec = swarm_coordinator._recovery_summary
|
||||
@@ -476,6 +472,14 @@ async def lifespan(app: FastAPI):
|
||||
rec["agents_offlined"],
|
||||
)
|
||||
|
||||
# Register Timmy AFTER recovery sweep so status sticks as "idle"
|
||||
from swarm import registry as swarm_registry
|
||||
swarm_registry.register(
|
||||
name="Timmy",
|
||||
capabilities="chat,reasoning,research,planning",
|
||||
agent_id="timmy",
|
||||
)
|
||||
|
||||
# Spawn persona agents in background
|
||||
persona_task = asyncio.create_task(_spawn_persona_agents_background())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user