Skip to main content

kokoro-chat

PyPI version CI Python License: MIT

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_checkable Protocol 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_complete events
  • 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)

Source distribution for kokoro-chat 0.1.2
File Size Uploaded Provenance
kokoro_chat-0.1.2.tar.gz 93.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for kokoro-chat 0.1.2
File Interpreter ABI Platform
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page