Router (main.py):
- When DSML detected in 2nd LLM response after tool execution,
make a 3rd LLM call with explicit synthesis prompt instead of
returning raw tool results to the user
- Falls back to format_tool_calls_for_response only if 3rd call fails
Router (tool_manager.py):
- Added _strip_think_tags() helper for <think>...</think> removal
from DeepSeek reasoning artifacts
Gateway (http_api.py):
- Strip <think>...</think> tags before sending to Telegram
- Strip DSML/XML-like markup (function_calls, invoke, parameter tags)
- Ensure empty text after stripping gets "..." fallback
Deployed to NODE1 and verified services running.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Fixed unquoted `helion` variable reference to string literal `"helion"`
in tool_manager.py search_memories fallback
- Replaced `[Контекст пам'яті]` with `[INTERNAL MEMORY - do NOT repeat
to user]` in all 3 injection points in main.py
- Verified: Senpai now responds without Helion contamination or memory
brief leaking
Tested and deployed on NODE1.
Co-authored-by: Cursor <cursoragent@cursor.com>
1. YAML structure bug: Senpai was in `policies:` instead of `agents:`
in router-config.yml. Router couldn't find Senpai config → no routing
rule → fallback to local model.
2. tool_manager agent_id not passed: memory_search and graph_query
tools were called without agent_id → defaulted to "helion" →
ALL agents' tool calls searched Helion's Qdrant collections.
Fixed: agent_id now flows from main.py → execute_tool → _memory_search.
3. Config not mounted: router-config.yml was baked into Docker image,
host changes had no effect. Added volume mount in docker-compose.
Also added:
- Sofiia agent config + routing rule (was completely missing)
- Senpai routing rule: cloud_deepseek (was falling to local qwen3:8b)
- Anti-echo instruction for memory brief injection
Deployed and verified on NODE1: Senpai now searches senpai_* collections.
Co-authored-by: Cursor <cursoragent@cursor.com>
Brand commands (~290 lines):
- Code was trapped inside `if reply_to_message:` block (unreachable)
- Moved to feature flag: ENABLE_BRAND_COMMANDS=true to activate
- Zero re-indentation: 8sp code naturally fits as feature flag body
- Helper functions (_brand_*, _artifact_*) unchanged
Memory LLM Summary:
- Replace placeholder with real DeepSeek API integration
- Structured output: summary, goals, decisions, open_questions, next_steps, key_facts
- Graceful fallback if API key not set or call fails
- Added MEMORY_DEEPSEEK_API_KEY config
- Ukrainian output language
Deployed and verified on NODE1.
Co-authored-by: Cursor <cursoragent@cursor.com>
Complete snapshot of /opt/microdao-daarion/ from NODE1 (144.76.224.179).
This represents the actual running production code that has diverged
significantly from the previous main branch.
Key changes from old main:
- Gateway (http_api.py): expanded from ~40KB to 164KB with full agent support
- Router: new /v1/agents/{id}/infer endpoint with vision + DeepSeek routing
- Behavior Policy: SOWA v2.2 (3-level: FULL/ACK/SILENT)
- Agent Registry: config/agent_registry.yml as single source of truth
- 13 agents configured (was 3)
- Memory service integration
- CrewAI teams and roles
Excluded from snapshot: venv/, .env, data/, backups, .tgz archives
Co-authored-by: Cursor <cursoragent@cursor.com>
- Use stdlib urllib.request instead of requests library
- requests was not installed in the router image, causing healthcheck
to always fail with "ModuleNotFoundError: No module named 'requests'"
- Increase start_period to 30s and retries to 5 for stability
Co-authored-by: Cursor <cursoragent@cursor.com>
- JWT middleware для FastAPI
- Генерація/перевірка JWT токенів
- Скрипти для генерації Qdrant API keys
- Скрипти для генерації NATS operator JWT
- План реалізації Auth
TODO: Додати JWT до endpoints, NATS nkeys config, Qdrant API key config
- Видалено всі паролі та API ключі з документів
- Замінено на посилання на Vault
- Закрито NodePort для Memory Service (тільки internal)
- Створено SECURITY-ROTATION-PLAN.md
- Створено ARCHITECTURE-150-NODES.md (план для 150 нод)
- Оновлено config.py (видалено hardcoded Cohere key)
- Remove crew_team_key from SELECT (column doesn't exist)
- Use pop() to safely handle crew_team_key in data processing
- This fixes 500 error on /api/agents/list endpoint
- Fix get_all_rooms() to not select owner_type/owner_id
- Fix get_city_rooms_for_list() to not select owner_type/owner_id
- Fix get_city_rooms_api() to use space_scope instead of owner_type
- This fixes 500 error on /api/city/rooms endpoint
- Add missing banner_url field when creating MicrodaoDetail
- This fixes issue where banner_url was saved in DB but not returned by /api/microdao/{slug} endpoint
- Add HEAD method handler for browser preflight requests
- Use stat_object for HEAD requests (more efficient)
- Return proper headers for HEAD requests
- This fixes 405 errors when browser checks image availability
- Add comprehensive documentation in docs/ASSETS_PROXY.md
- Add contract comments in normalizeAssetUrl and proxy_asset
- Verify all components use normalizeAssetUrl
- Verify ENV variables are correctly set
- Add troubleshooting guide
- Add /api/assets/[...path] proxy route in Next.js
- Add /assets/proxy/{path} endpoint in city-service
- Update normalizeAssetUrl to convert assets.daarion.space URLs to /api/assets/...
- This allows assets to work even if DNS for assets.daarion.space is not configured
- Initialize router_healthy as None instead of False
- Use bool() to ensure proper boolean conversion
- Add info logging for debugging
- This ensures cached router_healthy=True is properly used
- Fix get_dagi_router_agents to use router_healthy from node_cache first
- Fallback to direct API call only if cache is unavailable
- This fixes NODE2 agents showing as 'stale' when router is actually healthy
- Fix CITY_SERVICE_URL in scripts (remove /api/city, use /api)
- Add microdao_activity table for news/updates/events
- Add statistics columns to microdaos table
- Implement dashboard API endpoints
- Create UI components (HeaderCard, ActivitySection, TeamSection)
- Add seed data for DAARION DAO
- Update backend models and repositories
- Add frontend types and API client
Major changes:
- Normalize get_node_endpoints to use ENV vars (ROUTER_BASE_URL, SWAPPER_BASE_URL)
- Remove node_id-based URL selection logic
- Add fallback direct API call in get_node_swapper_detail
- Fix Swapper API endpoint (/models instead of /api/v1/models)
- Add router_healthy and router_version to node_heartbeat fallback
- Add ENV vars to docker-compose for Router/Swapper URLs
Documentation:
- Add TASK_PHASE_NODE2_ROUTER_SWAPPER_FIX.md with full task description
- Add NODE2_GUARDIAN_SETUP.md with setup instructions
This fixes:
- Swapper models not showing for NODE1 and NODE2
- DAGI Router agents not showing for NODE2
- Router/Swapper showing as Down/Degraded when they're actually up
- Fix get_node_endpoints to correctly determine URLs for NODE2 (localhost instead of Docker service names)
- Fix swapper detail endpoint to return fallback data instead of 404 when metrics not found
- This allows UI to show pending state instead of error for NODE2
Fixes:
- Swapper Service models not showing for NODE2
- DAGI Router agents not showing for NODE2
Backend:
- POST /city/microdao/{slug}/rooms - create new room for MicroDAO
- DELETE /city/microdao/{slug}/rooms/{room_id} - soft-delete room
- POST /city/agents/{agent_id}/ensure-room - create personal agent room
Frontend:
- MicrodaoRoomsSection: Added create room modal with name, description, type
- MicrodaoRoomsSection: Added delete room functionality for managers
- Agent page: Added 'Поговорити' button to open chat in City Room
Models:
- Added CreateMicrodaoRoomRequest model
Task: TASK_PHASE_MICRODAO_ROOMS_AND_PUBLIC_CHAT_v3
Backend:
- Added POST /city/agents endpoint for creating agents
- Added DELETE /city/agents/{id} endpoint for soft-deleting agents
- Added CreateAgentRequest, CreateAgentResponse, DeleteAgentResponse models
Frontend:
- Added '+ Новий агент' button on /agents page
- Created /agents/new page with full agent creation form
- Added 'Видалити агента' button in agent Identity tab (Danger Zone)
Features:
- Auto-generate slug from display_name
- Support for all agent fields: kind, role, model, node, district, microdao
- Color picker for agent color
- Visibility toggles (is_public, is_orchestrator)
- Soft delete with confirmation dialog
- Fixed NaN in online stats by using nullish coalescing (?? 0)
- Added members_online, zone, room_type to /api/v1/city/rooms response
- Added DAARWIZZ chat CTA section on homepage with link to city-lobby
- Created task files for next phases:
- TASK_PHASE_CITY_ROOMS_FINISH_v2.md
- TASK_PHASE_AGENT_MANAGEMENT_v1.md
- TASK_PHASE_CITIZENS_DIRECTORY_v1.md
- Add migration 042_node_cache_router_metrics.sql
- Node guardian now collects router health and sends in heartbeat
- City-service uses cached router_healthy from node_cache
- This allows NODE2 router status to be displayed correctly
- Add migration 041_node_local_endpoints.sql
- Add get_node_endpoints() to repo_city.py
- Update routes_city.py to use DB endpoints instead of hardcoded URLs
- Update node-guardian-loop.py to use NODE_SWAPPER_URL/NODE_ROUTER_URL env vars
- Update launchd plist for NODE2 with router URL