Contracts (the shared language): - percept / state / context / utterance / render / audio / capabilities - Capability model instead of vendor schemas (see below) Providers (capability-based abstraction): - LLM + Embedding: OpenAI-compatible shape IS the standard, adopted directly - ASR: internal contract is an event stream (partial -> final), because /v1/audio/transcriptions has no partial and dialogue needs it for endpointing. OpenAI adapter degrades to supports_partial=False. - TTS: internal contract carries tags/emotion/style, because /v1/audio/speech has no paralinguistics and [laughter]/[breath] are the core of feeling alive. Unsupported providers are stripped AND reported via Degradation -- silent degradation is forbidden. - Avatar: no de-facto standard, custom RenderCmd protocol driven by State. Core: - mood: dynamical system, slow variables, negativity bias (grudge), numbing after prolonged negativity - bazi: four pillars -> numeric vector; 'ming' is data, not prose - projection: phi, system event -> in-world statement; uncovered events are counted as projection gaps Storage: - SQLite schema, three memory layers, dyad ledger - accessibility floor 0.03 (not 0): forgettable but still there Config split: - models.yaml is the ONLY place model versions live - character.yaml holds world rules / emotion params, no version numbers 58 tests pass; ruff clean.
32 lines
652 B
Python
32 lines
652 B
Python
"""共享 fixture。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from cybergril.config import CharacterConfig, ModelsConfig, Settings
|
|
from cybergril.memory import Store
|
|
|
|
|
|
@pytest.fixture
|
|
def repo_root() -> Path:
|
|
return Path(__file__).resolve().parents[1]
|
|
|
|
|
|
@pytest.fixture
|
|
def settings(repo_root: Path) -> Settings:
|
|
return Settings(
|
|
models=ModelsConfig(),
|
|
character=CharacterConfig(identity={"y": 2000, "m": 1, "d": 1, "h": 12}),
|
|
db_path=repo_root / "test.db",
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def store(tmp_path: Path) -> Store:
|
|
s = Store(tmp_path / "test.db")
|
|
yield s
|
|
s.close()
|