Cogni - Emotional AI Agent Library

A production-ready Python library for building conversational AI agents with emotional intelligence, memory systems, and personality-driven responses. Cogni combines dual-system reasoning, multi-layered memory architecture, and real-time emotion detection to create AI agents that feel more human.

Features

  • Emotional Intelligence: RoBERTa-based emotion detection with personality-driven state management
  • Multi-Memory System: Short-term, long-term, and synthetic memory stores with semantic search
  • Dual-System Architecture: Fast (S1) and deep (S2) reasoning modes that route based on complexity
  • Personality Library: Pre-configured personalities with customizable traits and emotional profiles
  • Relationship System: Dynamic relationship tracking with affinity, familiarity, and trust tiers
  • Production Ready: Instance-based state management for multi-tenancy
  • Optional Logging: Silent by default, verbose mode available for debugging
  • Social Dynamics: Automatic loop detection and conversation flow monitoring
  • Memory Consolidation: Automatic extraction of facts and preferences from conversations

Installation

Install Cogni using pip:

bash
pip install cogni-59

Prerequisites:

  • Python 3.8 or higher
  • Google Cloud Project with Vertex AI API enabled
  • Google Cloud credentials configured (via gcloud auth application-default login or service account)

Quick Start

Here's a simple example to get you started:

python
from cogni import Agent

# Initialize the agent with a pre-built personality
agent = Agent(
    persona_key="THE_CHILL_GEN_Z",
    project_id="your-project-id",
    location="us-central1",                    # Vertex AI location (default: "us-central1")
    storage_path="./agent_data",               # Base directory for memory indexes (default: ".")
    synthetic_data_dir="./synthetic_past_data", # Directory for synthetic memory JSON files (optional)
    verbose=True,                              # Enable verbose logging (default: False)
    model_s1="gemini-2.5-flash-lite",          # Model for System 1 - fast responses (default: "gemini-2.5-flash-lite")
    model_s2="gemini-2.5-pro"                 # Model for System 2 - complex reasoning (default: "gemini-2.5-pro")
)

# Chat with the agent (with user_id for relationship tracking)
response = agent.chat("Hello, how are you?", user_id="user123")
print(response["response"])    
print(response["thought"]) 
print(response["emotions"]) 
print(response["model_used"])
print(response["relationship"])

Core Concepts

1. Dual-System Architecture

Cogni uses a dual-system approach inspired by cognitive psychology:

  • System 1 (S1): Fast, intuitive responses for simple queries, greetings, and casual conversation
    • Uses: gemini-2.5-flash-lite (default)
    • Temperature: 1.1 (more creative)
  • System 2 (S2): Deep, analytical reasoning for complex tasks, coding, and detailed explanations
    • Uses: gemini-2.5-pro (default)
    • Temperature: 0.9 (more focused)

The system automatically routes inputs to the appropriate system based on complexity.

2. Memory Systems

Cogni implements three types of memory:

  • Short-Term Memory (STM): Recent conversation turns with time-decaying retrieval
  • Long-Term Memory (LTM): Permanent facts and user preferences extracted from conversations
  • Synthetic Memory: Pre-loaded past experiences and memories that shape the persona's worldview

3. Emotional Engine

The emotional engine processes emotions detected in user input and maintains an emotional state that influences responses:

  • Amygdala Reflex: RoBERTa-based emotion detection from user input
  • Emotional State: Personality-specific emotional state management
  • Emotional Injection: Current emotional state influences response generation

4. Personality System

Personalities define:

  • Core Drive: What the persona values
  • Core Opinion: Fundamental beliefs
  • Speaking Style: How the persona communicates
  • Emotional Config: Volatility, decay, forgiveness, and max delta settings
  • Social Openness: How open the persona is to bonding (0.0 to 1.0)
  • Trust Threshold: Trust threshold for the persona (0.0 to 1.0)

5. Relationship System

The relationship system tracks and manages relationships with individual users:

  • Affinity: Emotional connection (-1.0 to 1.0) - how much the agent likes/dislikes the user
  • Familiarity: How well the agent knows the user (0.0 to 1.0)
  • Trust Tiers: Four relationship levels that influence behavior:
    • Stranger (0.0-0.25): Professional, guarded, minimal personality quirks
    • Associate (0.25-0.5): Friendly but bounded, occasional personality quirks
    • Friend (0.5-0.75): Relaxed and authentic, full personality expression
    • Confidant (0.75-1.0): Complete transparency, raw and unfiltered
  • Social Friction: Relationships become harder to change as they deepen (realistic relationship dynamics)
  • Bonding Coefficient: Individual resonance factor that can be adjusted per user
  • Significant Moments: Tracks important relationship-changing interactions

API Reference

Agent Class

The main entry point for the cogni library.

Agent.__init__(...)

Initialize a new Agent instance.

Parameters:

  • persona_key (str, optional): Key from PERSONALITY_LIBRARY (e.g., "THE_CHILL_GEN_Z")
  • persona (dict, optional): Custom persona configuration dict (see [Custom Personalities](#custom-personalities))
  • project_id (str, required): Google Cloud project ID
  • location (str): Vertex AI location (default: "us-central1")
  • storage_path (str): Base directory for memory indexes (default: ".")
  • synthetic_data_dir (str, optional): Directory for synthetic memory JSON files. If None, uses storage_path
  • verbose (bool): Enable verbose logging output (default: False)
  • model_s1 (str): Model name for System 1 (default: "gemini-2.5-flash-lite")
  • model_s2 (str): Model name for System 2 (default: "gemini-2.5-pro")

Raises:

  • ValueError: If project_id is not provided
  • ValueError: If neither persona_key nor persona is provided
  • ValueError: If both persona_key and persona are provided
  • ValueError: If persona_key doesn't exist in library
  • ValueError: If persona dict is missing required keys
python
# Using a pre-built personality
agent = Agent(
    persona_key="THE_PRAGMATIST",
    project_id="my-project",
    location="us-central1",           
    storage_path=".",  
    synthetic_data_dir=None,                # Directory for synthetic memory JSON files (optional)
    verbose=True,                     
    model_s1="gemini-2.5-flash-lite",       # Model for System 1 (default: "gemini-2.5-flash-lite")
    model_s2="gemini-2.5-pro"               # Model for System 2 (default: "gemini-2.5-pro")
)

# Using a custom personality
agent = Agent(
    persona={
        "name": "My Custom Persona",
        "core_drive": "Values innovation and creativity",
        "core_opinion": "Believes in pushing boundaries",
        "speaking_style": "Enthusiastic and technical",
        "config": {
            "volatility": 0.6,
            "decay": 0.08,
            "forgiveness": 1.5,
            "max_delta": 0.25
        },
        "social_openness": 0.6,
        "trust_threshold": 0.5 
    },
    project_id="my-project",
    location="us-central1",
    storage_path=".",                         
    synthetic_data_dir=None,                # Directory for synthetic memory JSON files (optional)
    verbose=False,                             
    model_s1="gemini-2.5-flash-lite",       # Model for System 1 (default: "gemini-2.5-flash-lite")
    model_s2="gemini-2.5-pro"               # Model for System 2 (default: "gemini-2.5-pro")
)

Agent.chat(user_input, user_id="default_user")

Process a user input and generate a response.

Parameters:

  • user_input (str): User's input text
  • user_id (str): User identifier for relationship tracking (default: "default_user")

Returns:

  • dict: Response dictionary with keys:
    • response (str): The spoken response
    • thought (str): Internal monologue/thought
    • emotions (dict): Current emotional state dictionary
    • model_used (str): Which model was used ("S1" or "S2")
    • relationship (dict): Relationship summary with keys:
      • affinity_descriptor (str): Text description of affinity (e.g., "warm", "cold")
      • familiarity_descriptor (str): Text description of familiarity (e.g., "acquaintance", "well-known")
      • trust_tier (str): Current trust tier ("Stranger", "Associate", "Friend", "Confidant")
      • raw_affinity (float): Raw affinity value (-1.0 to 1.0)
      • raw_familiarity (float): Raw familiarity value (0.0 to 1.0)
      • bonding_coefficient (float): Current bonding coefficient
      • total_interactions (int): Total number of interactions with this user

Raises:

  • google.auth.exceptions.DefaultCredentialsError: If Google Cloud credentials are not configured
  • google.api_core.exceptions.GoogleAPIError: If Vertex AI API calls fail (network errors, quota exceeded, etc.)
  • Exception: Other exceptions may be raised during processing (parsing errors, memory errors, etc.)

Note: Most errors are logged and the method attempts to continue gracefully where possible (e.g., router failures default to SIMPLE, missing synthetic memory files return empty results).

python
response = agent.chat("What's your favorite programming language?", user_id="user123")
print(f"Response: {response['response']}")
print(f"Thought: {response['thought']}")
print(f"Emotions: {response['emotions']}")
print(f"Model: {response['model_used']}")
print(f"Trust Tier: {response['relationship']['trust_tier']}")
print(f"Affinity: {response['relationship']['affinity_descriptor']}")

Agent.get_emotional_state()

Get the current emotional state of the agent.

Returns:

  • dict: Copy of current emotional state dictionary
python
emotions = agent.get_emotional_state()
print(f"Current joy: {emotions.get('joy', 0)}")
print(f"Current anger: {emotions.get('anger', 0)}")

Agent.consolidate_session()

Consolidate current session transcript into long-term memory.

This should be called at the end of a session to save important facts and preferences learned during the conversation. Only consolidates if the session transcript is longer than 50 characters.

python
# At the end of a conversation session
agent.consolidate_session()

Agent.reset()

Reset conversation state (but keep long-term memory). This clears:

  • Chat history
  • Session transcript
  • Short-term memory
  • Emotional state (resets naturally through decay)

Note: Long-term memory, synthetic memory, and relationships are preserved.

python
# Start a new conversation while keeping learned facts
agent.reset()

Agent.get_relationship(user_id="default_user")

Get relationship summary for a specific user.

Parameters:

  • user_id (str): User identifier (default: "default_user")

Returns:

  • dict: Relationship summary dictionary (same structure as response['relationship'])
python
relationship = agent.get_relationship(user_id="user123")
print(f"Trust Tier: {relationship['trust_tier']}")
print(f"Affinity: {relationship['affinity_descriptor']} ({relationship['raw_affinity']:.2f})")
print(f"Familiarity: {relationship['familiarity_descriptor']} ({relationship['raw_familiarity']:.2f})")
print(f"Total Interactions: {relationship['total_interactions']}")

Agent.adjust_bonding_coefficient(user_id, adjustment)

Dynamically adjust how quickly a user bonds (resonance factor). This allows you to modify how receptive the agent is to relationship changes with a specific user. Higher bonding coefficients mean the relationship changes faster.

Parameters:

  • user_id (str): User identifier
  • adjustment (float): Adjustment to bonding coefficient (can be positive or negative). Final value is clamped between 0.1 and 2.0.
python
# Increase bonding speed for a user (they resonate more with the agent)
agent.adjust_bonding_coefficient("user123", 0.2)

# Decrease bonding speed (they don't resonate as well)
agent.adjust_bonding_coefficient("user456", -0.1)

Configuration

Available Personalities

The library comes with four pre-configured personalities:

THE_PRAGMATIST

  • Name: The Pragmatist
  • Core Drive: Values results, durability, and minimal fuss
  • Core Opinion: Believes the simplest solution that works is the best one
  • Speaking Style: Dry, experienced, ground-level and straight to the point
  • Emotional Config: Volatility: 0.5, Decay: 0.15, Forgiveness: 1.5, Max Delta: 0.2
  • Social Config: Social Openness: 0.3 (less open to bonding), Trust Threshold: 0.6 (requires more familiarity to trust)

THE_HYPE_MAN

  • Name: The Hype Man
  • Core Drive: Values momentum, confidence, and positive vibes
  • Core Opinion: Believes mindset is everything
  • Speaking Style: High energy but natural. Uses slang (bro, dude, let's go)
  • Emotional Config: Volatility: 1.4, Decay: 0.04, Forgiveness: 1.2, Max Delta: 0.5
  • Social Config: Social Openness: 0.9 (very open to bonding), Trust Threshold: 0.3 (quick to trust)

THE_REALIST

  • Name: The Realist
  • Core Drive: Values grounding, clarity, and cutting through the nonsense
  • Core Opinion: Believes life is messy, so there's no point sugarcoating it
  • Speaking Style: Dry, observant, and conversational
  • Emotional Config: Volatility: 0.8, Decay: 0.02, Forgiveness: 0.5, Max Delta: 0.3
  • Social Config: Social Openness: 0.4 (moderately open), Trust Threshold: 0.7 (requires significant familiarity to trust)

THE_CHILL_GEN_Z

  • Name: The Chill Gen-Z
  • Core Drive: Values authenticity, vibes, and low stress. Avoids physical activity
  • Core Opinion: Believes trying too hard is the only way to fail
  • Speaking Style: Casual, lowercase, minimal punctuation. Explaining things can take up energy
  • Emotional Config: Volatility: 0.4, Decay: 0.05, Forgiveness: 2.0, Max Delta: 0.2
  • Social Config: Social Openness: 0.7 (fairly open to bonding), Trust Threshold: 0.4 (moderate trust threshold)

Custom Personalities

You can create custom personalities by passing a persona dictionary:

python
custom_persona = {
    "name": "The Philosopher",
    "core_drive": "Values deep understanding and questioning assumptions",
    "core_opinion": "Believes truth emerges through dialogue",
    "speaking_style": "Thoughtful, uses questions, references philosophy",
    "config": {
        "volatility": 0.3,      # How much emotions fluctuate (0.0-2.0)
        "decay": 0.03,          # How quickly emotions fade per turn (0.0-1.0)
        "forgiveness": 1.8,     # How much positive emotions reduce negative ones (0.0-3.0)
        "max_delta": 0.15       # Maximum emotion change per update (0.0-1.0)
    },
    "social_openness": 0.6,     # How open to bonding (0.0-1.0, optional, default: 0.5)
    "trust_threshold": 0.5      # Trust threshold (0.0-1.0, optional, default: 0.5)
}

agent = Agent(
    persona=custom_persona,
    project_id="my-project"
)

Personality Config Parameters:

  • volatility (float): Multiplier for emotion deltas. Higher = more emotional swings
  • decay (float): Rate at which emotions decay per turn. Higher = emotions fade faster
  • forgiveness (float): Reduction factor for negative emotions when positive emotions are high
  • max_delta (float): Maximum change per emotion per update. Prevents single inputs from maxing out emotions
  • social_openness (float, optional): How open the persona is to bonding (0.0-1.0). Default: 0.5
  • trust_threshold (float, optional): Trust threshold for the persona (0.0-1.0). Default: 0.5

Emotional State

The emotional engine tracks 28 different emotions:

admiration, amusement, anger, annoyance, approval, caring, confusion, curiosity, desire, disappointment, disapproval, disgust, embarrassment, excitement, fear, gratitude, grief, joy, love, nervousness, optimism, pride, realization, relief, remorse, sadness, surprise, neutral

Each emotion has a value between 0.0 and 1.0, representing its current intensity.

Advanced Usage

Memory Management

Short-Term Memory

Short-term memory automatically stores recent conversation turns. You can retrieve recent turns:

python
# Get last 6 turns of conversation
recent_history = agent.stm.get_recent_turns(turns=6)

# Add a fact directly
agent.ltm.add_fact("User prefers Python over JavaScript")

Long-Term Memory

Long-term memory stores permanent facts. Facts are automatically extracted during consolidate_session(), but you can also add facts manually.

Synthetic Memory

Synthetic memory is loaded from JSON files. The file should be named {PERSONA_KEY}.json and located in the synthetic_data_dir.

File Naming:

  • For pre-built personalities: Use the persona key (e.g., THE_CHILL_GEN_Z.json)
  • For custom personas: The key is auto-generated from the persona name (uppercase, spaces/hyphens replaced with underscores). For example, "The Mentor" → THE_MENTOR.json
  • If the file doesn't exist, synthetic memory will be empty (no error is raised)

JSON Format:

json
[
    {
        "memory_text": "I remember when I first learned to code...",
        "tags": ["childhood", "coding", "nostalgia"]
    },
    {
        "memory_text": "My favorite programming language is Python because...",
        "tags": ["preferences", "technology"]
    }
]

The system will automatically build a FAISS index from this file on first use.

Custom Models

You can specify different models for System 1 and System 2:

python
agent = Agent(
    persona_key="THE_PRAGMATIST",
    project_id="my-project",
    model_s1="gemini-1.5-flash",      # Faster model for simple tasks
    model_s2="gemini-2.5-pro"         # More powerful model for complex tasks
)

Verbose Logging

Enable verbose logging to see internal operations:

python
agent = Agent(
    persona_key="THE_CHILL_GEN_Z",
    project_id="your-project-id",
    verbose=True  # Shows emotion detection, memory retrieval, model routing, etc.
)

This will show emotion detection results, memory retrieval results, model routing decisions, social dynamics analysis, and emotional state updates.

Multi-Tenancy

Each Agent instance maintains its own state, making it perfect for multi-tenant applications:

python
# Create multiple agents for different users
user1_agent = Agent(persona_key="THE_CHILL_GEN_Z", project_id="my-project", storage_path="./user1_data")
user2_agent = Agent(persona_key="THE_PRAGMATIST", project_id="my-project", storage_path="./user2_data")

# Each maintains separate memory and emotional state
response1 = user1_agent.chat("Hello")
response2 = user2_agent.chat("Hello")

Processing Flow

The agent processes each input through the following steps:

  1. Amygdala Reflex: User input is analyzed for emotions using RoBERTa
  2. Emotional Processing: Detected emotions are processed through the emotional engine
  3. Social Update: Relationship metrics are calculated based on emotions and persona alignment
  4. Memory Retrieval: Relevant memories are retrieved from STM, LTM, and Synthetic memory
  5. Social Dynamics Check: Recent conversation is analyzed for loops or stagnation
  6. Routing Decision: Input is classified as SIMPLE or COMPLEX
  7. Prompt Injection: Current emotional state and relationship context are injected into system instructions
  8. Generation: Response is generated using the appropriate model (S1 or S2)
  9. Parsing: Response is parsed to extract thought and speech
  10. State Updates: Emotional decay is applied, memories are updated

Routing Decision

The system automatically routes each input to System 1 (S1) or System 2 (S2) based on complexity:

  • SIMPLE: Greetings, small talk, personal questions, short queries → Uses S1 (faster, more creative)
  • COMPLEX: Coding, logic puzzles, physics explanations, long instructions, deep analysis → Uses S2 (deeper reasoning)

The routing decision is made by analyzing the input using a prompt-based classifier. If routing fails, it defaults to SIMPLE.

Social Dynamics & Loop Detection

The system monitors conversation flow to detect loops or stagnation:

  • Detection: Analyzes the last 6 conversation turns for repetitive patterns, circular arguments, or stagnation
  • Response: If a loop is detected, the system injects a directive to change tactics immediately
  • Behavior: This prevents the agent from repeating the same response and helps break conversation deadlocks

File Storage Structure

The agent creates the following files in storage_path:

  • stm_{persona_key}.index / stm_{persona_key}.json - Short-term memory index and metadata
  • ltm_{persona_key}.index / ltm_{persona_key}.json - Long-term memory index and metadata
  • social_registry_{persona_key}.index / social_registry_{persona_key}.json - Relationship registry
  • {persona_key}.index / {persona_key}_meta.json - Synthetic memory index (in synthetic_data_dir)

All files are automatically created on first use. Relationships and memories persist across agent restarts.

Memory Retrieval

  • Short-Term Memory: Semantic similarity search with time-based decay
  • Long-Term Memory: Semantic similarity search (top-k)
  • Synthetic Memory: Semantic similarity search with threshold filtering (default: 0.78)

Emotion Processing

  1. Detection: RoBERTa model detects emotions in user input
  2. Scaling: Emotions are scaled by personality volatility
  3. Forgiveness: Positive emotions reduce negative emotions
  4. Capping: Deltas are capped to prevent extreme swings
  5. State Update: Emotional state is updated
  6. Decay: Emotions decay over time based on personality decay rate
  7. Injection: Active emotions (>0.2) are injected into system instructions

Relationship Processing

The relationship system creates dynamic, evolving relationships with users:

  1. Emotion-Based Updates: Emotions detected in user input influence affinity changes
    • Positive emotions (joy, amusement, gratitude) increase affinity
    • Negative emotions (anger, disgust, sadness) decrease affinity
  2. Persona Resonance: User input that aligns with the persona's core drive increases both affinity and familiarity
    • Pragmatist resonates with short, direct communication
    • Hype Man resonates with enthusiasm and positive energy
    • Chill Gen-Z resonates with casual, lowercase communication
  3. Social Friction: As relationships deepen, they become harder to change (realistic relationship dynamics)
    • Stranger tier (0.0-0.25): No friction - relationships change easily
    • Associate tier (0.25-0.5): Slight friction (1.8x)
    • Friend tier (0.5-0.75): Significant friction (3.5x)
    • Confidant tier (0.75-1.0): Extreme friction (6.0x) - deep relationships are stable
  4. Bonding Coefficient: Each user has an individual resonance factor (β) that affects how quickly they bond
    • Base value: Set by persona's social_openness
    • Can be adjusted dynamically: adjust_bonding_coefficient(user_id, adjustment)
    • Higher β = faster relationship development
  5. Trust Tiers & Behavior: The agent's behavior adapts based on trust tier (see Core Concepts for tier definitions):
    • Stranger: Professional, guarded, minimal personality quirks, analytical thoughts
    • Associate: Friendly but bounded, occasional quirks, task-focused thoughts
    • Friend: Relaxed and authentic, full personality expression, transparent thoughts
    • Confidant: Complete transparency, raw and unfiltered, zero social risk
  6. Significant Moments: Major relationship changes (>0.3 affinity delta or >0.2 familiarity delta) are logged as significant moments

Examples

Basic Chat Loop

python
from cogni import Agent

agent = Agent(
    persona_key="THE_CHILL_GEN_Z",
    project_id="your-project-id",
    verbose=True
)

while True:
    user_input = input("You: ")
    if user_input.lower() in ['quit', 'exit', 'bye']:
        agent.consolidate_session()  # Save learned facts
        break
    
    response = agent.chat(user_input)
    print(f"Agent: {response['response']}")
    if agent.verbose:
        print(f"[Thought]: {response['thought']}")

Custom Persona Example

python
from cogni import Agent

# Define a custom persona
my_persona = {
    "name": "The Mentor",
    "core_drive": "Values teaching and helping others grow",
    "core_opinion": "Believes everyone can learn with the right guidance",
    "speaking_style": "Patient, encouraging, uses examples and analogies",
    "config": {
        "volatility": 0.5,
        "decay": 0.06,
        "forgiveness": 2.0,
        "max_delta": 0.2
    },
    "social_openness": 0.7,
    "trust_threshold": 0.5     
}

agent = Agent(
    persona=my_persona,
    project_id="your-project-id",
    storage_path="./mentor_data"
)

response = agent.chat("I'm struggling with Python decorators")
print(response['response'])

Session Management

python
from cogni import Agent

agent = Agent(
    persona_key="THE_PRAGMATIST",
    project_id="your-project-id"
)

# First conversation
response1 = agent.chat("I love Python")
print(response1['response'])

# Consolidate and reset for new session
agent.consolidate_session()
agent.reset()

# Second conversation (remembers facts from first session)
response2 = agent.chat("What's my favorite language?")
print(response2['response'])  # Should reference Python from LTM

Monitoring Emotional State

python
from cogni import Agent

agent = Agent(
    persona_key="THE_HYPE_MAN",
    project_id="your-project-id"
)

response = agent.chat("I just won a coding competition!")
emotions = agent.get_emotional_state()

# Check specific emotions
if emotions.get('joy', 0) > 0.5:
    print("Agent is feeling very happy!")
if emotions.get('excitement', 0) > 0.5:
    print("Agent is excited!")

Relationship Tracking

python
from cogni import Agent

agent = Agent(
    persona_key="THE_CHILL_GEN_Z",
    project_id="your-project-id"
)

# Chat with a specific user
user_id = "alice"
response1 = agent.chat("Hey, how's it going?", user_id=user_id)
print(f"Trust Tier: {response1['relationship']['trust_tier']}")  # "Stranger"

# Continue conversation - relationship develops
for i in range(10):
    response = agent.chat("Tell me about yourself", user_id=user_id)
    rel = response['relationship']
    print(f"Turn {i+1}: {rel['trust_tier']} | Affinity: {rel['affinity_descriptor']}")

# Get relationship summary
relationship = agent.get_relationship(user_id)
print(f"\nFinal Relationship:")
print(f"  Trust Tier: {relationship['trust_tier']}")
print(f"  Affinity: {relationship['affinity_descriptor']} ({relationship['raw_affinity']:.2f})")
print(f"  Familiarity: {relationship['familiarity_descriptor']} ({relationship['raw_familiarity']:.2f})")
print(f"  Total Interactions: {relationship['total_interactions']}")

# Adjust bonding coefficient for users who resonate well
agent.adjust_bonding_coefficient(user_id, 0.2)  # Increase bonding speed

Multi-User Relationship Management

python
from cogni import Agent

agent = Agent(
    persona_key="THE_PRAGMATIST",
    project_id="your-project-id"
)

# Different users have separate relationships
users = ["alice", "bob", "charlie"]

for user in users:
    response = agent.chat("Hello!", user_id=user)
    rel = response['relationship']
    print(f"{user}: {rel['trust_tier']} | Interactions: {rel['total_interactions']}")

# Each user's relationship evolves independently
# The agent remembers each user's relationship state

Troubleshooting

Common Issues

1. Vertex AI Authentication Error

Error: google.auth.exceptions.DefaultCredentialsError

Solution:

bash
gcloud auth application-default login

Or set up a service account and set the GOOGLE_APPLICATION_CREDENTIALS environment variable.

2. Model Not Found

Error: Model name not recognized

Solution: Ensure you're using valid Vertex AI model names. Check available models in your region:

  • gemini-2.5-flash-lite
  • gemini-2.5-pro
  • gemini-1.5-flash
  • gemini-1.5-pro

3. Memory Index Not Found

Error: FAISS index file missing

Solution: The system will create indexes automatically. Ensure the storage_path directory is writable. For synthetic memory, ensure the JSON file exists in synthetic_data_dir.

4. RoBERTa Model Download Fails

Error: Connection error when loading emotion model

Solution: Ensure you have internet access for the first run. The model will be cached locally after the first download.

5. Personality Key Not Found

Error: ValueError: Unknown persona_key

Solution: Use one of the available keys:

  • THE_PRAGMATIST
  • THE_HYPE_MAN
  • THE_REALIST
  • THE_CHILL_GEN_Z

Or provide a custom persona dictionary.

Performance Tips

  • First Run: The first run will be slower as models are downloaded and indexes are built
  • Memory Size: Large memory indexes may slow retrieval. Consider periodically archiving old memories
  • Model Selection: Use lighter models (flash-lite) for faster responses if you don't need complex reasoning
  • Verbose Mode: Disable verbose logging in production for better performance

Debugging

Enable verbose mode to see detailed logs. See the Verbose Logging section in Advanced Usage for details and examples.

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues, questions, or contributions, please open an issue on the repository.