9.7 KiB
9.7 KiB
GIA — Agent Knowledge Base
Overview
GIA is a multi-transport communication platform bridging Signal, WhatsApp, XMPP, and Instagram through a Django web interface. It provides message relay, AI-powered workspace analysis, compose UX, and OSINT search. Stack: Python 3.11, Django 4.x, HTMX, Bulma CSS, SQLite, Redis, Docker Compose. Async runtime uses asyncio + uvloop.
Structure
GIA/
├── app/ # Django project config (settings, urls, asgi, wsgi)
│ ├── settings.py # Main settings (imports local_settings.py at bottom)
│ ├── local_settings.py # Env-driven overrides (secrets, feature flags)
│ ├── urls.py # All URL routing (single flat file, no includes)
│ └── asgi.py # ASGI entrypoint with WebSocket routing
├── core/ # ALL application logic lives here
│ ├── models.py # All models (~1600 lines) — User, Person, AI, Message, etc.
│ ├── forms.py # Django ModelForms using RestrictedFormMixin from mixins
│ ├── admin.py # Admin registrations
│ ├── clients/ # Transport service adapters
│ │ ├── __init__.py # ClientBase ABC (start, message_received, etc.)
│ │ ├── transport.py # Shared transport layer — attachment prep, send, runtime state
│ │ ├── whatsapp.py # WhatsApp client via Neonize (~3100 lines)
│ │ ├── signal.py # Signal client via signal-cli REST API
│ │ ├── xmpp.py # XMPP client via slixmpp
│ │ ├── instagram.py # Instagram client via aiograpi
│ │ └── gateway.py # Gateway HTTP helpers
│ ├── messaging/ # Message processing pipeline
│ │ ├── ai.py # OpenAI integration (AsyncOpenAI)
│ │ ├── history.py # Prompt window builder with adaptive limits
│ │ ├── media_bridge.py # Media attachment resolution
│ │ ├── analysis.py # Conversation analysis
│ │ ├── natural.py # Natural language processing
│ │ ├── replies.py # Reply generation
│ │ └── utils.py # Message formatting helpers
│ ├── modules/
│ │ └── router.py # UnifiedRouter — orchestrates all transport clients
│ ├── views/ # Django views (class-based)
│ │ ├── compose.py # Compose UX (~3400 lines) — send, drafts, thread, media
│ │ ├── workspace.py # AI workspace (~5200 lines) — insights, mitigation, patterns
│ │ ├── osint.py # OSINT/search interface
│ │ └── ... # CRUD views for people, groups, sessions, etc.
│ ├── lib/prompts/ # AI persona prompt templates
│ ├── realtime/ # WebSocket handlers (compose thread)
│ ├── templates/ # Django templates (75 files, partials/ heavy)
│ ├── management/commands/ # ur (unified router), scheduling
│ └── util/logs.py # Custom colored logger — use logs.get_logger("name")
├── Makefile # Docker Compose orchestration commands
├── docker-compose.yml # Services: app, asgi, ur, scheduling, redis, signal-cli
├── Dockerfile # Python 3.11, venv at /venv
├── requirements.txt # Pinned deps (django, openai, neonize, slixmpp, etc.)
├── stack.env # Runtime env vars (from stack.env.example)
└── LLM_CODING_STANDARDS.md # Project-specific coding rules (READ THIS)
Commands
# All commands run via Docker Compose with stack.env
make build # Build Docker images
make run # Start all services (quadlet manager)
make stop # Stop all services
make log # Tail logs
make compose-run # Start via docker-compose directly
make compose-stop # Stop via docker-compose
make compose-log # Tail via docker-compose
# Database
make migrate # Run Django migrations
make makemigrations # Generate new migrations
make auth # Create superuser
# Testing
make test # Run all tests
make test MODULES=core.tests # Run specific test module
# Inside container (or with venv activated):
python manage.py test core.tests -v 2 # All tests
python manage.py test core.tests.test_foo -v 2 # Single test module
python manage.py test core.tests.test_foo.TestBar -v 2 # Single class
python manage.py test core.tests.test_foo.TestBar.test_method -v 2 # Single test
# Service restarts after code changes
docker-compose restart ur # Restart unified router
docker-compose restart scheduling # Restart scheduler
# uWSGI auto-reloads for app/core code changes
Code Style
Formatting & Linting (pre-commit enforced)
- Black: Line length 88, excludes
core/migrations/ - isort: Profile
black(compatible grouping) - flake8: Max line 88, ignores E203, E231, E501, E702, W291
- djhtml: Template indent 2 spaces (
-t 2) - ripsecrets: Scans for leaked credentials
Imports
- Standard library first, then third-party, then Django, then project
- Project imports use absolute paths:
from core.models import Person - Within same package, relative OK:
from .models import User(seen in admin/forms) - Views import models explicitly:
from core.models import AI, Person, Message
Naming
snake_casefor functions, variables, modulesPascalCasefor classes (Django views, models)UPPER_CASEfor module-level constants and Django settings- Private helpers prefixed with
_:_safe_limit(),_service_key() - Service names always lowercase strings:
"signal","whatsapp","xmpp","instagram"
Logging
- Use
from core.util import logsthenlog = logs.get_logger("name")for transport/messaging code - Use
import logging; logger = logging.getLogger(__name__)for views/models - Info for lifecycle events, warning/error for failures, debug for high-volume traces
- Debug logs gated behind
GIA_DEBUG_LOGSenv var
Views
- Class-based views inheriting
VieworLoginRequiredMixin - CRUD views use
mixins.views.ObjectCreate/ObjectUpdate/ObjectDeletefromdjango-crud-mixins - Forms use
RestrictedFormMixinfor user-scoped queryset filtering - HTMX-driven partials in
core/templates/partials/
Models
- All models in single
core/models.py(~1600 lines) - UUIDs as primary keys for
Personand related models SERVICE_CHOICEStuple for transport type fields- Custom
Usermodel extendingAbstractUserwith billing fields - Multi-tenant: most models have
user = ForeignKey(User)
Async Patterns
- Transport clients are async (
async def send_message_raw(...)) - Views bridge sync Django to async transport via
async_to_sync() orjsonfor fast JSON serialization in transport layer- Redis cache for runtime state, bridge maps, command queues
Error Handling
- Standard
try/exceptwith specific exception types - Django
ValidationErrorfor model validation get_object_or_404()in views for missing resourcesHttpResponseBadRequest/HttpResponseNotFoundfor view error responses- No custom exception hierarchy — use built-in Django/Python exceptions
LLM Coding Standards (from LLM_CODING_STANDARDS.md)
MUST READ: LLM_CODING_STANDARDS.md contains binding project rules. Key points:
- Fix root causes; don't paper over with UI-only patches
- Keep behavior symmetric across all transports where protocol permits
- Centralize shared logic — no copy/paste service forks
- Shared attachment prep goes through
core/clients/transport.py - Never inject internal blob links as relay body text for attachment-only messages
- After changing
core/clients/*or router/relay/transport: restart runtime (make stop && make run) - Logging: lifecycle at info, failures at warning/error, high-volume at debug
- Debug diagnostics must be gated (e.g.
WHATSAPP_DEBUG) and removable in one patch - When touching large files (2000+ lines): extract minimal reusable helpers, add docstrings
- Update
INSTALL.mdandREADME.mdwhen operational commands/env requirements change
Anti-Patterns
- DO NOT create separate transport-specific media pipelines — use
transport.prepare_outbound_attachments() - DO NOT add
TODO/FIXMEcomments — codebase is currently clean of them - DO NOT use
print()— use the logging system vialogs.get_logger() - DO NOT modify
core/migrations/files — Black/linting excludes them for a reason - DO NOT commit
stack.env,db.sqlite3, or any secrets —ripsecretspre-commit hook will block - DO NOT add new models outside
core/models.py— all models live in one file - DO NOT use type suppression or ignore runtime errors silently
Key Architecture Notes
- Unified Router (
core/modules/router.py): Management commandpython manage.py urruns the event loop with all transport clients. Each client inheritsClientBaseABC. - Transport Layer (
core/clients/transport.py): Shared cache-backed runtime state, command queuing, and attachment prep. All outbound media goes throughprepare_outbound_attachments(). - Settings Chain:
app/settings.py→ importsapp/local_settings.py(wildcard*) → env vars fromstack.env. Feature flags:WHATSAPP_ENABLED,INSTAGRAM_ENABLED,COMPOSE_WS_ENABLED. - Services in docker-compose:
app(uWSGI),asgi(uvicorn for WebSockets),ur(unified router),scheduling(APScheduler),redis,signal-cli-rest-api. - No test suite currently:
core/tests.pyis empty scaffold;core/tests/has only__init__.py. Tests run viamake test MODULES=...but need to be written.