kokoro-chat
Character chat engine core — extracted from roleplay-chat.
Protocol-based storage interfaces + dependency-injectable ChatEngine. No database or web framework dependencies.
Features
- ChatEngine — full LLM conversation loop with tool calling (attitude, memory, memo, search)
- Protocol-based storage — 9
@runtime_checkableProtocol interfaces; inject any DB backend - Character system — YAML V2 character cards with lorebook, attitude levels, few-shot examples
- Attitude system — affection/trust tracking (0-100) with time decay, event-triggered modifiers, 5 relationship levels
- Memory — semantic search + rolling summary + structured memo with room/private visibility
- Lorebook — keyword-triggered context injection with token budget and priority sorting
- Prompt assembly — static (slim) and full paths with progressive degradation on budget overflow
- Streaming — async generator yielding
text_delta/message_completeevents - Multi-provider LLM — Anthropic, OpenAI, MiniMax via motosan-ai
Architecture
kokoro_chat/
├── character/ ← Character model + YAML V2 loader
├── lorebook/ ← Lorebook engine (keyword trigger → context injection)
├── attitude/ ← AttitudeState + 5 behavior levels (stranger → married)
├── memory/ ← Memo stale-filtering logic
├── prompt/
│ ├── assembler.py ← System prompt assembly (static + full paths)
│ ├── sections.py ← Shared section builders (character, traits, speech...)
│ ├── budget.py ← Token budget constants + estimator
│ └── formatter.py ← Conversation history formatting
├── providers/ ← Context providers (attitude, persona, recent_chat)
├── tools/ ← LLM tools (update_attitude, save_memory, upsert_memo, search_memories)
├── storage/ ← 9 Protocol interfaces (DB-agnostic)
├── engine/
│ ├── chat.py ← ChatEngine (orchestration)
│ ├── llm.py ← LLM client factory + bridges
│ ├── attitude_manager.py ← AttitudeManager
│ ├── message_manager.py ← MessageManager
│ ├── summarizer.py ← Summarizer
│ └── background.py ← Background task prompts + parsers
└── config.py ← ChatConfig dataclass
Installation
pip install kokoro-chat
Or from source:
pip install -e ".[dev]"
Quick Start
from kokoro_chat import Character, ChatConfig, ChatEngine
# 1. Build a Character (from DB model or manually)
character = Character(
id="xing_lang",
name="星浪",
description="一個活潑開朗的女孩,喜歡音樂和冒險。",
personality_summary="外向、好奇心強、有點衝動",
likes=["音樂", "冒險", "甜食"],
default_mood="happy",
)
# 2. Configure
config = ChatConfig(
chat_provider="anthropic",
chat_model="claude-sonnet-4-5-20250929",
anthropic_api_key="sk-ant-...",
)
# 3. Inject your storage implementations (must implement the Protocols)
engine = ChatEngine(
config=config,
attitude_store=your_attitude_store, # AttitudeStore
cache=your_cache_store, # CacheStore
chat_history=your_history_store, # ChatHistoryStore
chat_writer=your_message_writer, # ChatMessageWriter
memory_store=your_memory_store, # MemoryVectorStore
memo_store=your_memo_store, # MemoStore
rolling_summary_store=your_summary_store, # RollingSummaryStore
event_store=your_event_store, # EventStore
)
# 4. Stream a conversation
async for chunk in engine.chat_stream(
user_message="你好啊",
character=character,
user_id="user-123",
chat_mode="short",
):
if chunk["type"] == "text_delta":
print(chunk["text"], end="", flush=True)
elif chunk["type"] == "message_complete":
print() # done
Storage Protocols
All storage interfaces are typing.Protocol with @runtime_checkable.
Implement any concrete backend (PostgreSQL, SQLite, in-memory dict) — as long as it matches the protocol signature.
from kokoro_chat.storage.protocol import (
AttitudeStore, # get / get_or_create / save — affection, trust, mood
ChatHistoryStore, # get_recent — recent messages
MemoryVectorStore, # search / add — semantic memory with visibility
MemoStore, # get / upsert — key-value user info
RollingSummaryStore, # get_or_create / update — compressed history
EventStore, # get_by_character — character/user events
UsageLogStore, # log — token count + cost tracking
ChatMessageWriter, # add_message — persist new messages
CacheStore, # get/set attitude, messages, rolling summary
)
See kokoro_chat/storage/protocol.py for full protocol definitions and value objects (ChatMessage, AttitudeRecord, MemorySearchResult, RollingSummaryRecord, EventRecord).
Attitude System
Characters have dynamic attitude toward each user:
affection: 0-100 (好感度)
trust: 0-100 (信任度)
mood: string (當前心情)
5 relationship levels based on affection score:
| Level | Range | Behavior |
|---|---|---|
| stranger | 0-20 | Polite, distant, formal |
| friend | 21-40 | Casual, joking, caring |
| crush | 41-60 | Shy, blushing, finding excuses to get closer |
| lover | 61-80 | Intimate, clingy, using pet names |
| married | 81-100 | Maximum intimacy, deep trust |
- Time decay — affection/trust decrease after 3+ days of inactivity (floor: affection 30, trust 20)
- Event-triggered modifiers — temporary attitude shifts with turn-based countdown
- Custom overrides — characters can define their own behavior text per level
Room Memory
Characters in the same room share non-private memories:
# save_memory tool — LLM decides visibility
save_memory(text="User is learning guitar", visibility="room") # shared in room
save_memory(text="User has a crush on NPC", visibility="private") # only this character
# search_memories — returns own + same-room memories
results = await memory_store.search(
query="music",
character_id="xing_lang",
user_id="user-123",
room_id="cafe", # includes other characters' room-visible memories
)
Character Card V2
Supports standard Character Card V2 format with Kokoro extensions:
| Extension | Purpose |
|---|---|
speech_patterns_v2 |
Mood-based speech patterns ({mood: pattern}) |
affection_overrides |
Custom behavior text per relationship level |
post_history_by_level |
Level-specific post-history instructions |
anti_patterns |
Prevent character drift ({bad, correct, why}) |
Load from YAML V2:
from kokoro_chat.character.loader import map_v2_yaml_to_db
db_kwargs = map_v2_yaml_to_db(yaml_data) # → dict for DB model creation
Load from DB model:
character = Character.from_db_model(db_char) # duck-typed, reads attributes
Dependencies
| Package | Purpose |
|---|---|
motosan-ai |
LLM client (Anthropic, OpenAI, MiniMax) |
motosan-chat |
AgentLoop, ContextProvider, Tool framework |
pyyaml |
YAML V2 character card parsing |
License
MIT
Metadata
Release files for kokoro-chat 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| kokoro_chat-0.1.2.tar.gz | 93.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kokoro_chat-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 146.7 kB
Release files / kokoro_chat-0.1.2.tar.gz
| Download URL | kokoro_chat-0.1.2.tar.gz |
|---|---|
| Size | 93.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ece638813d2c3900fa2f52c062875314c0c0dccaec590a2da245acf37cb341d7
|
|
BLAKE2b-256 checksum How to use checksums |
dbfd17e601e28c3509aa17e4faa09d5875da53ecdd80f3f18ccbefb0255aef60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / kokoro_chat-0.1.2-py3-none-any.whl
| Download URL | kokoro_chat-0.1.2-py3-none-any.whl |
|---|---|
| Size | 53.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b8338872fc3dfa0125e368b6881bf184edf8ebd190f480c2b011569fe7dfed29
|
|
BLAKE2b-256 checksum How to use checksums |
ceffea00a9ada109470a49b9533e335f70b26c4e1344d822e2d36e4dca678859
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for kokoro-chat 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.