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.0.tar.gz (92.7 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.0-py3-none-any.whl (53.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: kokoro_chat-0.1.0.tar.gz
  • Upload date:
  • Size: 92.7 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.0.tar.gz
Algorithm Hash digest
SHA256 6b6faabbe843b740b79ab664f2e126bb9f4f3f6b1983d8f684f9b7ccf141f1f0
MD5 df13f50dca4e76d1761edc4182d7ab0f
BLAKE2b-256 f26a237ff050958fcdb71a16e12c475e33e3aadd22823300375453e42bb95924

See more details on using hashes here.

File details

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

File metadata

  • Download URL: kokoro_chat-0.1.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c931a0ab5ca695abbe32db7f22829a19641f94a49c41968919a18426c801a60a
MD5 db294af8472fab8001c69831dfe21379
BLAKE2b-256 ea16c2882beff18c52a300e9ce7d3f60d4d36d6a19436bbbb40cbcc65cac90b1

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