A production-ready Python library for emotional AI agents
Project description
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.
Table of Contents
- Features
- Installation
- Quick Start
- Core Concepts
- API Reference
- Configuration
- Advanced Usage
- Examples
- Troubleshooting
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 that influence behavior
- 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
pip install cogni
Prerequisites:
- Python 3.8 or higher
- Google Cloud Project with Vertex AI API enabled
- Google Cloud credentials configured (via
gcloud auth application-default loginor service account)
Quick Start
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",
storage_path="./agent_data",
synthetic_data_dir="./synthetic_past_data",
verbose=True
)
# Chat with the agent (with user_id for relationship tracking)
response = agent.chat("Hello, how are you?", user_id="user123")
print(response["response"]) # The spoken response
print(response["thought"]) # Internal monologue/thought
print(response["emotions"]) # Current emotional state dict
print(response["model_used"]) # Which model was used ("S1" or "S2")
print(response["relationship"]) # Relationship summary (affinity, familiarity, trust_tier)
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)
- Uses:
-
System 2 (S2): Deep, analytical reasoning for complex tasks, coding, and detailed explanations
- Uses:
gemini-2.5-flash(default) - Temperature: 0.9 (more focused)
- Uses:
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 fromPERSONALITY_LIBRARY(e.g.,"THE_CHILL_GEN_Z")persona(dict, optional): Custom persona configuration dict (see Custom Personalities)project_id(str, required): Google Cloud project IDlocation(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, usesstorage_pathverbose(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-flash")
Raises:
ValueError: Ifproject_idis not providedValueError: If neitherpersona_keynorpersonais providedValueError: If bothpersona_keyandpersonaare providedValueError: Ifpersona_keydoesn't exist in libraryValueError: Ifpersonadict is missing required keys
Example:
# Using a pre-built personality
agent = Agent(
persona_key="THE_PRAGMATIST",
project_id="my-project",
verbose=True
)
# 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
}
},
project_id="my-project"
)
Agent.chat(user_input, user_id="default_user")
Process a user input and generate a response.
Parameters:
user_input(str): User's input textuser_id(str): User identifier for relationship tracking (default:"default_user")
Returns:
dict: Response dictionary with keys:response(str): The spoken responsethought(str): Internal monologue/thoughtemotions(dict): Current emotional state dictionarymodel_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 coefficienttotal_interactions(int): Total number of interactions with this user
Example:
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
Example:
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.
Example:
# 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.
Example:
# 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 asresponse['relationship'])
Example:
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 identifieradjustment(float): Adjustment to bonding coefficient (can be positive or negative). Final value is clamped between 0.1 and 2.0.
Example:
# 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:
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 swingsdecay(float): Rate at which emotions decay per turn. Higher = emotions fade fasterforgiveness(float): Reduction factor for negative emotions when positive emotions are highmax_delta(float): Maximum change per emotion per update. Prevents single inputs from maxing out emotionssocial_openness(float, optional): How open the persona is to bonding (0.0-1.0). Default: 0.5trust_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,approvalcaring,confusion,curiosity,desire,disappointmentdisapproval,disgust,embarrassment,excitement,feargratitude,grief,joy,love,nervousnessoptimism,pride,realization,relief,remorsesadness,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:
# Get last 6 turns of conversation
recent_history = agent.stm.get_recent_turns(turns=6)
Long-Term Memory
Long-term memory stores permanent facts. Facts are automatically extracted during consolidate_session(), but you can also add facts manually:
# Add a fact directly
agent.ltm.add_fact("User prefers Python over JavaScript")
Synthetic Memory
Synthetic memory is loaded from JSON files. The file should be named {PERSONA_KEY}.json and located in the synthetic_data_dir.
JSON Format:
[
{
"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:
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:
agent = Agent(
persona_key="THE_CHILL_GEN_Z",
project_id="my-project",
verbose=True # Shows emotion detection, memory retrieval, model routing, etc.
)
Multi-Tenancy
Each Agent instance maintains its own state, making it perfect for multi-tenant applications:
# 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
- Amygdala Reflex: User input is analyzed for emotions using RoBERTa
- Emotional Processing: Detected emotions are processed through the emotional engine
- Social Update: Relationship metrics (affinity, familiarity) are calculated and updated based on emotions and persona alignment
- Memory Retrieval: Relevant memories are retrieved from STM, LTM, and Synthetic memory
- Social Dynamics Check: Recent conversation is analyzed for loops or stagnation
- Routing Decision: Input is classified as SIMPLE or COMPLEX
- Emotional & Relationship Injection: Current emotional state and relationship context are injected into system instructions
- Generation: Response is generated using the appropriate model (S1 or S2)
- Parsing: Response is parsed to extract thought and speech
- State Updates: Emotional decay is applied, memories are updated
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
- Detection: RoBERTa model detects emotions in user input
- Scaling: Emotions are scaled by personality volatility
- Forgiveness: Positive emotions reduce negative emotions
- Capping: Deltas are capped to prevent extreme swings
- State Update: Emotional state is updated
- Decay: Emotions decay over time based on personality decay rate
- Injection: Active emotions (>0.2) are injected into system instructions
Relationship Processing
The relationship system creates dynamic, evolving relationships with users:
-
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
-
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
-
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
-
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
- Base value: Set by persona's
-
Trust Tiers & Behavior: The agent's behavior adapts based on trust tier:
- 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
-
Significant Moments: Major relationship changes (>0.3 affinity delta or >0.2 familiarity delta) are logged as significant moments
Examples
Basic Chat Loop
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
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
}
}
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
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
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
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
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:
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-litegemini-2.5-flashgemini-1.5-flashgemini-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_PRAGMATISTTHE_HYPE_MANTHE_REALISTTHE_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:
agent = Agent(
persona_key="THE_CHILL_GEN_Z",
project_id="your-project-id",
verbose=True # Shows all internal operations
)
This will show:
- Emotion detection results
- Memory retrieval results
- Model routing decisions
- Social dynamics analysis
- Emotional state updates
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cogni_59-1.0.0.tar.gz.
File metadata
- Download URL: cogni_59-1.0.0.tar.gz
- Upload date:
- Size: 39.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4dd10145dd3fede01dad9b3d6a77d8f6a01c5713195d6445a2a61f948793d9ea
|
|
| MD5 |
873b2b3c8b051d505feb208cded61e25
|
|
| BLAKE2b-256 |
6d170a3cacda8758c50457e0d0c85eb1a8facf99950457f299c11d65b6cd4d43
|
File details
Details for the file cogni_59-1.0.0-py3-none-any.whl.
File metadata
- Download URL: cogni_59-1.0.0-py3-none-any.whl
- Upload date:
- Size: 35.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c9321ebdce469baba71e281454ec215c4f9f550f776cb6c32774812c49072b3
|
|
| MD5 |
80dc91c4557a63cf7a525d91be59d7f5
|
|
| BLAKE2b-256 |
e187e169b06a964d08c92609201f7b3b73e1bd59eb5c84660de2bdbf13dc34dd
|