ouroboros/pyproject.toml
Ouroboros cf9da98c3e Paint the interface from the translation memory, not from a shipped dictionary
The browser now reads the install's language and its translation memory from
GET /api/ui/i18n and paints from that; web/i18n/ru.js, the hand-written
Russian dictionary PR #940 shipped, is removed together with its package-data
entry, so the repository enumerates no language and a merge of the managed
branch never carries a translation diff.

web/modules/i18n.js keeps the PR's DOM overlay (TreeWalker, title/placeholder/
aria-label, MutationObserver, an idempotent stash so a switch back restores the
exact English) and adds the two seams a dictionary keyed by rendered text
cannot cover: tr(code, english) for the host sentences minted from closed
code->sentence tables, read at the place the table is read (task headline words,
cause sentences, question status, notification titles, routing labels, time
words), so the chat transcript is never walked and an upstream reword never
orphans a translation; and fmt(template, params) for composed strings, with
Intl.PluralRules choosing the plural form. Inline composites (a sentence with a
<code> in it) translate as one sentence with numbered slots; <code>/<kbd> stay
verbatim. Strings the memory lacks stay English and are reported, batched and
shape-filtered, to POST /api/ui/i18n/missing for the generator. The overlay
never enters a chat transcript (Main or any Project), live cards, logs, file
views or owner-supplied names.

Settings -> Appearance -> Language is one control for the install-wide setting
(web/modules/settings_language.js): a select with English (source), this
device's language, every memory on disk with its readiness, and Other..., a free
field for a code such as pt-BR, a name, or a language to invent; a tag saves at
once through POST /api/ui/i18n/language with the browser's plural map, anything
else is explained inline until the generator can resolve it. Import/Export/
Regenerate act on the memory file. The choice never touches the Settings draft,
so it marks nothing dirty. The onboarding wizard boots from the same memory;
app.js re-reads the dictionary on ui_language_changed / ui_i18n_updated frames,
the only cross-client signals.

Size debts this change would have created are paid instead of registered: the
interface-language envelopes move to gateway/ui_i18n_contracts.py (re-exported
by contracts.py, as history_contracts.py is) with their browser twin in
web/modules/ui_i18n_types.js; the /api/ui/* routes leave collect_routes for a
helper; the log_events seam is trimmed to the base's line count. The four new
modules are registered in domains.toml (D11/D12), named in the component map,
and the chapter growth is granted per chapter.

Tests: web/tests/i18n.test.js (overlay, plural forms, misses, inline
composites, restore, serialized switch), i18n_catalog.test.js (an install
language changes a rendered catalog line while the English readings and
web/tests/fixtures/outcome_phase_parity.json stay byte-identical),
settings_language.test.js (option rows, status line, the choose/other/import/
export/regenerate flows).

Co-authored-by: Nikita Kolesnikov <Fgeeha@users.noreply.github.com>
2026-10-03 18:26:07 +03:00

156 lines
6.4 KiB
TOML

[build-system]
requires = ["setuptools>=69", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "ouroboros"
version = "7.5.1"
description = "Self-creating AI agent with constitution, background consciousness, and persistent identity"
readme = "README.md"
license = {text = "MIT"}
requires-python = ">=3.10"
authors = [
{name = "Anton Razzhigaev"},
]
keywords = ["ai-agent", "self-modifying", "autonomous", "llm", "openrouter"]
classifiers = [
"Development Status :: 4 - Beta",
"License :: OSI Approved :: MIT License",
"Operating System :: MacOS",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
dependencies = [
"openai>=1.66.0",
"gigachat>=0.2.1,<0.3",
"requests",
# Runtime self-update and install paths execute ``sys.executable -m pip``.
# uv-created source/tool environments do not seed pip unless it is declared.
"pip",
"httpx[socks]>=0.28", # SOCKS transport plus socks5h URL support (HTTPX 0.28+).
# Native process command/tree observations for shared-daemon custody on Windows.
"psutil>=7.2; sys_platform == 'win32'",
# Runtime custom-tool calls are validated against the exact projected schema.
"jsonschema>=4.0",
"ddgs",
"dulwich",
"huggingface_hub",
"starlette",
"python-multipart",
"Pillow>=10.0",
"pypdf>=4.0",
"uvicorn[standard]",
"websockets",
"pytest>=7.0",
# Runtime, not test-only: the hermetic commit gate's parallel pass hard-blocks
# with PREFLIGHT_PLUGIN_MISSING rather than degrading to serial, so a wheel /
# `pip install .` that carries pytest without these cannot commit at all.
# Floors kept in step with _REQUIRED_PREFLIGHT_PLUGINS. These remain runtime
# dependencies because the packaged hermetic commit gate invokes them.
"pytest-xdist>=3.5",
"pytest-timeout>=2.1",
"mcp>=1.6,<2.0",
"PyYAML>=6.0",
"croniter",
# Upper-bounded: tree-sitter 0.25.x + language-pack 1.x changed the grammar/
# node-type behavior so the WS3 polyglot symbol extraction returned nothing
# (green locally on 0.23.2/0.9.1, red in CI which pulled the latest). Pin to
# the verified-working line until code_intelligence is updated for the new API.
"tree-sitter>=0.23.2,<0.25",
"tree-sitter-language-pack>=0.9.1,<1.0",
"tzdata",
# Python 3.10 needs typing_extensions.NotRequired for gateway contracts.
"typing_extensions>=4.5.0",
]
[project.scripts]
ouroboros = "ouroboros.cli:main"
ouroboros-web = "server:main"
[project.urls]
Homepage = "https://github.com/razzant/ouroboros"
Repository = "https://github.com/razzant/ouroboros"
Issues = "https://github.com/razzant/ouroboros/issues"
"Previous Version (Colab)" = "https://github.com/razzant/ouroboros/tree/legacy-google-colab"
[project.optional-dependencies]
browser = ["playwright", "playwright-stealth"]
desktop = [
"pywebview==5.4",
"pythonnet==3.0.5; platform_system == 'Windows'",
"clr_loader==0.2.7.post0; platform_system == 'Windows'",
]
local-model = ["llama-cpp-python"]
build = ["pyinstaller>=6.0"]
all = [
"playwright",
"playwright-stealth",
"pywebview==5.4",
"pythonnet==3.0.5; platform_system == 'Windows'",
"clr_loader==0.2.7.post0; platform_system == 'Windows'",
"llama-cpp-python",
"huggingface_hub",
]
[dependency-groups]
dev = ["ruff>=0.12"]
[tool.uv]
required-version = "==0.12.1"
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
# Default local pytest excludes token-burning integration/browser suites.
addopts = "-q --tb=short -m 'not integration and not browser and not ui_browser and not ui_browser_docker and not portable_detail and not skill_smoke and not size_ratchet' --durations=25 --durations-min=1.0"
markers = [
"integration: real external-surface suites excluded from default local runs — the CI provider-contract lane (requires real provider API keys: OPENROUTER_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY / MINIMAX_API_KEY / DEEPSEEK_API_KEY / CLOUDRU_FOUNDATION_MODELS_API_KEY / GIGACHAT_CREDENTIALS; opt in via `pytest -m integration`) AND the KEYLESS tests/system_e2e/ scenario lane (real isolated servers, no provider keys; additionally env-gated on OUROBOROS_E2E_DEEP)",
"browser: launches real Playwright Chromium; excluded from default local runs, opt in via `pytest -m browser`",
"ui_browser: launches the real Ouroboros web UI in host/direct mode; excluded from default local runs",
"ui_browser_docker: launches UI smoke checks against Docker runtime; excluded from default local runs",
"portable_detail: portable/build artifact detail checks; excluded from default local runs",
"serial: real subprocess / real port / mutable module-global test — run in a serial pass, excluded from the `-n auto` parallel pass via `-m 'not serial'` (see .github/workflows/ci.yml AND the hermetic commit gate ouroboros/preflight_runner.py, which runs the same two-pass split)",
"skill_smoke: real-network OuroborosHub official-skill install + review-flow smoke; excluded from default local runs, opt in via `pytest -m skill_smoke` (canonical lane description: docs/DEVELOPMENT.md 'Pytest marker lanes')",
"size_ratchet: per-module line/UTF-8 byte and per-function length gates against the live repo (manifest exactness, shrink-only pairwise transition) — a BLOCKING lane only in official-repository CI; excluded from default local runs, which surface the same validator findings as warnings (canonical lane description: docs/DEVELOPMENT.md 'Pytest marker lanes')",
]
[tool.setuptools]
py-modules = ["server"]
[tool.setuptools.packages.find]
include = ["ouroboros*", "supervisor*", "web*"]
[tool.setuptools.package-data]
ouroboros = [
"domains.toml",
]
web = [
"*.html",
"*.js",
"*.css",
"*.png",
"*.jpg",
"modules/*.js",
"providers/*.svg",
"providers/*.png",
"providers/*.ico",
"vendor/VENDOR-MANIFEST.md",
"vendor/katex/*.css",
"vendor/katex/*.js",
"vendor/katex/contrib/*.js",
"vendor/katex/fonts/*.woff2",
"vendor/licenses/*",
]
[tool.ruff]
line-length = 120
target-version = "py310"
[tool.ruff.lint]
select = ["E", "F", "W", "I"]
ignore = ["E501"]