Skip to main content

Character chat engine core — Protocol-based storage, dependency-injectable ChatEngine

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kokoro_chat-0.1.1.tar.gz (93.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kokoro_chat-0.1.1-py3-none-any.whl (53.4 kB view details)

Uploaded Python 3

File details

Details for the file kokoro_chat-0.1.1.tar.gz.

File metadata

  • Download URL: kokoro_chat-0.1.1.tar.gz
  • Upload date:
  • Size: 93.0 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for kokoro_chat-0.1.1.tar.gz
Algorithm Hash digest
SHA256 464adf4e2a45b99ea18a92f056025d4d169fb52f788d523ddd4e3b589a1a1643
MD5 3c9a8ea3193e2c37fdec7f8e7ee977fa
BLAKE2b-256 24656060e3151c6f1d16bac18fd14541590115230acec3941be399077bb10d2d

See more details on using hashes here.

File details

Details for the file kokoro_chat-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: kokoro_chat-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 53.4 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for kokoro_chat-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 106e23fdd0098b1119bc33f93c33656e5ce19819fb3ca9e0cc6cadeae6a36029
MD5 6c9af45a747221644ab00f1cf9b3e052
BLAKE2b-256 afd628fcb6fde91f4522522b8f0f2c15f6a707c85211104750a90051db1288f7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page