Files
ratatoskr/pyproject.toml
T
vh e5ec63967e feat(web): memory viewer + design iteration-3 + markdown pass-2 (v0.20.7)
Web-UI iteration-3 — three queued items landed together.

(A) Design iteration-3 into static/index.html:
- sparkline grid background (<pattern id=sparkGrid> + bg rect behind each
  relation-row spark polyline);
- PAD strips → per-turn Δ bars: replace the vertical polyline strip
  (stripPoints/proj3 removed) with padDeltas→deltaStrip, a 12-cell HTML
  column of diverging bars (newest at bottom, magnitude→width, age→opacity);
- mood orbit → dimetric open box (viewBox 124×140, az35/el25,
  D-right/A-left-back/P-up): ghost A×P wall + D×A floor +
  orbitProj/orbitShadowY/orbitWallPt/orbitAxisPt, JS-driven animated replay
  (orbitFrame per rAF via a singleton startOrbitAnim reading live ORBIT_HIST;
  reduced-motion → static final-state).

(B) Memory viewer — a non-bifrost debug read on OUR own store, mirroring the
    #18-D2 affect read:
- provider: RatatoskrMemoryStore.list_chunks + count_chunks + shared
  add_memory_read_route (GET /memory/chunks?agent_id=&end_user_id=), wired
  into build_memory_provider_app + the combined :8392 provider. end_user
  strict, agent_id lenient (an {end_user}-only chunk stays visible);
  {chunks,count,total}, empty match = 200 (not 404);
- web: _memory_chunks_endpoint (GET /api/memory/chunks) supplies end_user_id
  server-side, forwards the browser agent_id, proxies to memory_read_url;
  create_app gains memory_read_url, entrypoint reads RATATOSKR_MEMORY_READ_URL;
- pane: loadMemory/renderMemory/setMemHead — a live-polling MEMORY console
  pane (content·scope·origin·revision per chunk; count/total distinguish
  empty-store from scope-mismatch), polled on open + post-turn.

(C) Markdown pass-2 in markdownSafe: GFM pipe tables (mdTable, alignment
    colons), indentation-nested lists (child list inside the open <li>),
    ordered-list start=N numbering, streaming robustness (partial fence →
    code block; header-without-delimiter → paragraph until it streams in).
    esc-first → INV-004 held.

Contract web_debug_surface.contract.md amended in-commit (create_app
memory_read_url; dimetric-orbit + Δ-bar renderConsole POST-002; memory-viewer
+ markdown-pass-2 function contracts). 631 tests green; Playwright-verified
all render paths (dark+light).
2026-07-07 02:11:29 -07:00

98 lines
3.4 KiB
TOML

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "ratatoskr"
version = "0.20.7"
description = "Worldtree Conversation API debug TUI — multi-pane observability dashboard"
readme = "README.md"
requires-python = ">=3.12"
license = { file = "LICENSE" }
authors = [{ name = "Vuong Hoang" }]
keywords = ["worldtree", "tui", "debug", "sse", "textual"]
# Network + SSE consumer + TUI framework.
# See docs/design-brief.md §1 (Textual), §3 (httpx-sse).
dependencies = [
"httpx>=0.27",
"httpx-sse>=0.4",
"textual>=0.85",
]
[project.optional-dependencies]
web = [
"starlette>=0.40",
"uvicorn[standard]>=0.30",
]
# Tier-3 Bifrost consumer: the durable memory.* + affect.* persistence
# provider Worldtree writes into. Opt-in extra — distinct deployment surface
# from the debug TUI. Recipe: bifrost/docs/implementing-a-consumer.md.
provider = [
"ratatoskr[web]", # reuse the starlette + uvicorn ASGI stack
"bifrost==1.0.0", # consumer engines + library. 1.0.0 = first STABLE release, wire v0.6 FROZEN (non-breaking repin from >=0.10.0; build_combined_app #18 + mandatory affect.fetch; 0.8.0/v0.6 scope_all/scope_any #11; 0.7.0/v0.5 agent_self)
"jsonschema>=4", # bifrost runtime dep — envelope validation
"sqlite-vec>=0.1.6", # vector index for the memory plane (vec0 virtual table)
]
dev = [
"pytest>=8",
"pytest-asyncio>=0.24",
"respx>=0.21", # httpx mocking for SSE-recorded snapshot tests
"ruff>=0.6",
"mypy>=1.11",
"textual-dev>=1.5", # textual console + live reload during dev
"pyyaml>=6", # used by docs/contracts/contract_parser.py and scripts/contract_drift_check.py
"ratatoskr[web]", # web extras included in dev so test_web_* can import starlette
]
[project.scripts]
ratatoskr = "ratatoskr.cli:main"
ratatoskr-web = "ratatoskr.web.entrypoint:main"
ratatoskr-provider = "ratatoskr.provider.serve:main"
ratatoskr-memory-provider = "ratatoskr.provider.serve_memory:main"
ratatoskr-combined-provider = "ratatoskr.provider.serve_combined:main"
[project.urls]
Repository = "https://gitea.phasefinal.com/vh/ratatoskr"
"Design Brief" = "https://gitea.phasefinal.com/vh/brokkr-smithy/src/branch/main/docs/ratatoskr-design-brief.md"
# Worldtree spec pin — see docs/SPEC-PIN.md for the full bump procedure.
# Ratatoskr is built against Worldtree at this commit; the vendored
# spec snapshot in docs/ reflects that SHA.
[tool.ratatoskr.spec-pin]
worldtree-spec-rev = "c9e59ec"
worldtree-version = "v1.0.0b22"
pinned-on = "2026-07-06"
# Bifrost lives on the auth-gated gitea PyPI index (not public PyPI).
# uv reads the credential from UV_INDEX_GITEA_USERNAME / _PASSWORD or ~/.netrc.
[[tool.uv.index]]
name = "gitea"
url = "https://gitea.phasefinal.com/api/packages/vh/pypi/simple/"
[tool.uv.sources]
bifrost = { index = "gitea" }
[tool.hatch.build.targets.wheel]
packages = ["src/ratatoskr"]
# Issue #16: ship the web companion's static HTML in the wheel so
# importlib.resources can locate it post-install.
[tool.hatch.build.targets.wheel.force-include]
"src/ratatoskr/web/static" = "ratatoskr/web/static"
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "RUF"]
[tool.mypy]
python_version = "3.12"
strict = true