Conversation Pipeline
The ConversationPipeline orchestrates the complete user text to response flow with a 30-second timeout and non-blocking listener pattern.
flowchart LR
Transcript["Transcript"] --> Listener["Listener"]
Listener --> CanThink{"Can think?"}
CanThink -->|no| Skip["Skip"]
CanThink -->|yes| Task["Background Task"]
Task --> Pipeline["Conversation Pipeline"]
Pipeline --> Generator["Response Generator"] ConversationManager maintains a deque(maxlen=10) of recent user and assistant messages. It is used as LLM context after the system prompt and before the current user message.
Response Generation
ResponseGenerator routes text to local commands, personality adjustments, or LLM calls.
flowchart LR
Input["User Text"] --> Router["Router"]
Router --> Local["Local Command"]
Router --> Personality["Personality"]
Router --> LLM["LLM"]
Local --> Output["Response"]
Personality --> Output
LLM --> Output
Output --> Memory["Memory"]
Memory --> SQLite["SQLite"]
Output --> TTS["TTS"] - Empty check: skip if
not user_text.strip(). - Local command check:
LocalCommandParser.parse(text). - Personality command check:
PersonalityCommandParser.parse(text). - LLM check: for normal text, call provider.
Memories are not extracted for local commands or incomplete personality commands. Memories are extracted for complete personality commands and normal LLM responses.
Prompt Construction
- System prompt with persona identity, profile text, personality parameters, derived style rules, example dialogue, Portuguese directive, and no Markdown directive.
- Memory context as separate system message, max 5 memories.
- Conversation history from
ConversationManager. - Current user message.
LLM Providers
| Provider | Path | Notes |
|---|---|---|
| OpenRouter | cosmo/ai/llm/providers/openrouter_provider.py | Requires OPENROUTER_API_KEY; supports streaming and non-streaming. |
| Ollama | cosmo/ai/llm/providers/ollama_provider.py | Local inference server, default http://localhost:11434; synchronous blocking. |
Local Commands
Local commands bypass the LLM and return hardcoded or database-backed responses.
| Intent | Phrase examples | Handler | Returns |
|---|---|---|---|
system_status | "como você está", "qual seu status" | _system_status() | Compact diagnostics from DiagnosticsManager. |
memory_list | "quais minhas memórias", "liste memórias" | _memory_list() | Recent 10 memories from database. |
memory_clear | "limpe memórias", "apague histórico" | _memory_clear() | Deletes all memories for default user. |
CREATE TABLE local_commands (
id INTEGER PRIMARY KEY,
intent TEXT,
phrase TEXT,
language TEXT,
active INTEGER,
created_at TIMESTAMP
); Personality System
The personality system allows runtime tuning of Cosmo's behavior through adjustable parameters on a 0-100 scale.
parameters:
verbosity: 10
humor: 40
sarcasm: 50
honesty: 95
empathy: 20
curiosity: 30
confidence: 100
formality: 10
adaptability: 70
discipline: 100
imagination: 10
emotional_stability: 100
pragmatism: 100
optimism: 50
resourcefulness: 95
cheerfulness: 30
engagement: 40
respectfulness: 20 Runtime parameters are stored in PersonalityState. On update, they are saved to cosmo/data/state/personality_state.json; on startup, JSON is loaded if active_profile matches.
Persistent Memory
The memory system extracts, filters, stores, and retrieves conversation facts from SQLite. Ex:
| Category | Trigger phrases | Content prefix | Importance |
|---|---|---|---|
preference | "eu prefiro", "prefiro", "gosto que você", "responda sempre" | "Preferência do usuário:" | 3 |
instruction | "de agora em diante", "sempre que", "quando eu pedir", "nas próximas" | "Instrução persistente:" | 4 |
project_fact | "no projeto cosmo", "o cosmo deve", "arquitetura cosmo" | "Fato sobre Cosmo:" | 3 |
explicit | "lembre que", "guarde que", "salve que", "registre que" | Clean text | 5 |
MemoryFilter.is_valid() rejects short content, blocked terms such as passwords or personal documents, and exact noise markers. add_memory_if_new() prevents duplicates by checking for the same lowercase content for the user.
CREATE TABLE memories (
id INTEGER PRIMARY KEY,
user_id INTEGER,
category TEXT,
content TEXT,
importance INTEGER,
created_at TIMESTAMP,
FOREIGN KEY(user_id) REFERENCES users(id)
); build_memory_context(user_text, limit=5) returns up to 5 memories ordered by importance and recency. It currently ignores user_text for semantic ranking.

