hank-model-authority 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. hank_model_authority-1.0.0/PKG-INFO +63 -0
  2. hank_model_authority-1.0.0/README.md +54 -0
  3. hank_model_authority-1.0.0/hank_model_authority.egg-info/PKG-INFO +63 -0
  4. hank_model_authority-1.0.0/hank_model_authority.egg-info/SOURCES.txt +33 -0
  5. hank_model_authority-1.0.0/hank_model_authority.egg-info/dependency_links.txt +1 -0
  6. hank_model_authority-1.0.0/hank_model_authority.egg-info/requires.txt +2 -0
  7. hank_model_authority-1.0.0/hank_model_authority.egg-info/top_level.txt +1 -0
  8. hank_model_authority-1.0.0/model_authority/__init__.py +46 -0
  9. hank_model_authority-1.0.0/model_authority/__main__.py +34 -0
  10. hank_model_authority-1.0.0/model_authority/authority/model-authority.yaml +973 -0
  11. hank_model_authority-1.0.0/model_authority/authority/rates/anthropic.json +108 -0
  12. hank_model_authority-1.0.0/model_authority/authority/rates/codex.json +117 -0
  13. hank_model_authority-1.0.0/model_authority/authority/rates/ollama.json +17 -0
  14. hank_model_authority-1.0.0/model_authority/authority/rates/openai.json +75 -0
  15. hank_model_authority-1.0.0/model_authority/authority/rates/xai.json +43 -0
  16. hank_model_authority-1.0.0/model_authority/bind.py +80 -0
  17. hank_model_authority-1.0.0/model_authority/binding.py +1256 -0
  18. hank_model_authority-1.0.0/model_authority/capabilities.py +101 -0
  19. hank_model_authority-1.0.0/model_authority/current.py +39 -0
  20. hank_model_authority-1.0.0/model_authority/loader.py +423 -0
  21. hank_model_authority-1.0.0/model_authority/rates.py +245 -0
  22. hank_model_authority-1.0.0/model_authority/registry.py +286 -0
  23. hank_model_authority-1.0.0/model_authority/schema.py +251 -0
  24. hank_model_authority-1.0.0/model_authority/selection.py +138 -0
  25. hank_model_authority-1.0.0/model_authority/thinking.py +129 -0
  26. hank_model_authority-1.0.0/pyproject.toml +21 -0
  27. hank_model_authority-1.0.0/setup.cfg +4 -0
  28. hank_model_authority-1.0.0/tests/test_binding.py +1003 -0
  29. hank_model_authority-1.0.0/tests/test_build_install_smoke.py +152 -0
  30. hank_model_authority-1.0.0/tests/test_check_cli.py +51 -0
  31. hank_model_authority-1.0.0/tests/test_loader.py +215 -0
  32. hank_model_authority-1.0.0/tests/test_rates.py +306 -0
  33. hank_model_authority-1.0.0/tests/test_registry_authority.py +623 -0
  34. hank_model_authority-1.0.0/tests/test_schema_compat.py +203 -0
  35. hank_model_authority-1.0.0/tests/test_thinking.py +30 -0
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: hank-model-authority
3
+ Version: 1.0.0
4
+ Summary: Hank model authority: the model-authority/2.x artifact, its loader and capability resolver
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: PyYAML<7,>=6.0
8
+ Requires-Dist: pydantic<3,>=2.10
9
+
10
+ # hank-model-authority
11
+
12
+ The model authority every product repository reads: which models exist (registry
13
+ entries with their execution identity and per-family request facts), which model
14
+ each capability uses (selection policy), and what each model costs (rate tables).
15
+ The distribution depends on PyYAML and pydantic only, so Risk, Investment and Edgar
16
+ take it without the gateway.
17
+
18
+ Design and rollout: `docs/design/model-authority-registry-as-data-artifact-design-2026-09-29.md`
19
+ and its implementation plan.
20
+
21
+ ## Layout
22
+
23
+ | Module | Owns |
24
+ |---|---|
25
+ | `authority/model-authority.yaml`, `authority/rates/*.json` | the packaged artifact: one `model-authority/2.x` document (registry `models`, `selection.capabilities`, one `revision`) and per-provider prices |
26
+ | `schema.py` | the version rule (`SCHEMA_MAJOR`/`SCHEMA_MINOR`), `ModelAuthorityError` and its message, protocol families and each family's `compat:` key set |
27
+ | `loader.py` | `HANK_MODEL_AUTHORITY_DIR` resolution, the strict load, the directory digest |
28
+ | `current.py` | the process's one import-time load: `INITIAL_MODEL_REGISTRY`, `INITIAL_MODEL_SELECTION_POLICY`, `RATE_TABLES`, `HEALTH_FACT`, `health_fact()` |
29
+ | `registry.py`, `selection.py` | registry entries and selection policy |
30
+ | `capabilities.py` | capability IDs and the process that executes each (a release, not data) |
31
+ | `binding.py`, `bind.py` | the single resolver and `CapabilityBind` |
32
+ | `rates.py`, `thinking.py` | rate tables; effort vocabulary |
33
+
34
+ The package root imports types and the loader, never `current`, so
35
+ `python -m model_authority check <dir>` can check a candidate directory while the
36
+ host directory is broken.
37
+
38
+ ## Which directory a process loads
39
+
40
+ `HANK_MODEL_AUTHORITY_DIR` set: that directory, resolved once at start; missing or
41
+ unreadable fails the start. Unset: the packaged `authority/` directory. Every
42
+ process reports what it admitted through `health_fact()`:
43
+ `{"revision", "schema", "sha256", "source", "loader", "admits"}`.
44
+
45
+ ## Changing it
46
+
47
+ - **A data change** (a model, a default, a price, a compat value) edits
48
+ `authority/` and ships by the host deploy of that directory, not by a release.
49
+ Declare the lowest schema minor that covers the fields the artifact uses.
50
+ - **A schema change** is a release: a new optional field or literal is a minor
51
+ (`SCHEMA_MINOR`), a removal or redefinition a major. Deploy loaders before data
52
+ that uses a new minor: a loader refuses an artifact whose minor is newer than its
53
+ own, naming both.
54
+ - **A capability or its executing process** is a release (`capabilities.py`).
55
+
56
+ Check a candidate directory with the ordinary load:
57
+
58
+ ```bash
59
+ python -m model_authority check <dir> # prints the health fact, or exits 1 with the refusal
60
+ ```
61
+
62
+ Tests: `.venv/bin/python3 -m pytest packages/model-authority/tests -q`
63
+ (`make test-area AREA=model_authority`).
@@ -0,0 +1,54 @@
1
+ # hank-model-authority
2
+
3
+ The model authority every product repository reads: which models exist (registry
4
+ entries with their execution identity and per-family request facts), which model
5
+ each capability uses (selection policy), and what each model costs (rate tables).
6
+ The distribution depends on PyYAML and pydantic only, so Risk, Investment and Edgar
7
+ take it without the gateway.
8
+
9
+ Design and rollout: `docs/design/model-authority-registry-as-data-artifact-design-2026-09-29.md`
10
+ and its implementation plan.
11
+
12
+ ## Layout
13
+
14
+ | Module | Owns |
15
+ |---|---|
16
+ | `authority/model-authority.yaml`, `authority/rates/*.json` | the packaged artifact: one `model-authority/2.x` document (registry `models`, `selection.capabilities`, one `revision`) and per-provider prices |
17
+ | `schema.py` | the version rule (`SCHEMA_MAJOR`/`SCHEMA_MINOR`), `ModelAuthorityError` and its message, protocol families and each family's `compat:` key set |
18
+ | `loader.py` | `HANK_MODEL_AUTHORITY_DIR` resolution, the strict load, the directory digest |
19
+ | `current.py` | the process's one import-time load: `INITIAL_MODEL_REGISTRY`, `INITIAL_MODEL_SELECTION_POLICY`, `RATE_TABLES`, `HEALTH_FACT`, `health_fact()` |
20
+ | `registry.py`, `selection.py` | registry entries and selection policy |
21
+ | `capabilities.py` | capability IDs and the process that executes each (a release, not data) |
22
+ | `binding.py`, `bind.py` | the single resolver and `CapabilityBind` |
23
+ | `rates.py`, `thinking.py` | rate tables; effort vocabulary |
24
+
25
+ The package root imports types and the loader, never `current`, so
26
+ `python -m model_authority check <dir>` can check a candidate directory while the
27
+ host directory is broken.
28
+
29
+ ## Which directory a process loads
30
+
31
+ `HANK_MODEL_AUTHORITY_DIR` set: that directory, resolved once at start; missing or
32
+ unreadable fails the start. Unset: the packaged `authority/` directory. Every
33
+ process reports what it admitted through `health_fact()`:
34
+ `{"revision", "schema", "sha256", "source", "loader", "admits"}`.
35
+
36
+ ## Changing it
37
+
38
+ - **A data change** (a model, a default, a price, a compat value) edits
39
+ `authority/` and ships by the host deploy of that directory, not by a release.
40
+ Declare the lowest schema minor that covers the fields the artifact uses.
41
+ - **A schema change** is a release: a new optional field or literal is a minor
42
+ (`SCHEMA_MINOR`), a removal or redefinition a major. Deploy loaders before data
43
+ that uses a new minor: a loader refuses an artifact whose minor is newer than its
44
+ own, naming both.
45
+ - **A capability or its executing process** is a release (`capabilities.py`).
46
+
47
+ Check a candidate directory with the ordinary load:
48
+
49
+ ```bash
50
+ python -m model_authority check <dir> # prints the health fact, or exits 1 with the refusal
51
+ ```
52
+
53
+ Tests: `.venv/bin/python3 -m pytest packages/model-authority/tests -q`
54
+ (`make test-area AREA=model_authority`).
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: hank-model-authority
3
+ Version: 1.0.0
4
+ Summary: Hank model authority: the model-authority/2.x artifact, its loader and capability resolver
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: PyYAML<7,>=6.0
8
+ Requires-Dist: pydantic<3,>=2.10
9
+
10
+ # hank-model-authority
11
+
12
+ The model authority every product repository reads: which models exist (registry
13
+ entries with their execution identity and per-family request facts), which model
14
+ each capability uses (selection policy), and what each model costs (rate tables).
15
+ The distribution depends on PyYAML and pydantic only, so Risk, Investment and Edgar
16
+ take it without the gateway.
17
+
18
+ Design and rollout: `docs/design/model-authority-registry-as-data-artifact-design-2026-09-29.md`
19
+ and its implementation plan.
20
+
21
+ ## Layout
22
+
23
+ | Module | Owns |
24
+ |---|---|
25
+ | `authority/model-authority.yaml`, `authority/rates/*.json` | the packaged artifact: one `model-authority/2.x` document (registry `models`, `selection.capabilities`, one `revision`) and per-provider prices |
26
+ | `schema.py` | the version rule (`SCHEMA_MAJOR`/`SCHEMA_MINOR`), `ModelAuthorityError` and its message, protocol families and each family's `compat:` key set |
27
+ | `loader.py` | `HANK_MODEL_AUTHORITY_DIR` resolution, the strict load, the directory digest |
28
+ | `current.py` | the process's one import-time load: `INITIAL_MODEL_REGISTRY`, `INITIAL_MODEL_SELECTION_POLICY`, `RATE_TABLES`, `HEALTH_FACT`, `health_fact()` |
29
+ | `registry.py`, `selection.py` | registry entries and selection policy |
30
+ | `capabilities.py` | capability IDs and the process that executes each (a release, not data) |
31
+ | `binding.py`, `bind.py` | the single resolver and `CapabilityBind` |
32
+ | `rates.py`, `thinking.py` | rate tables; effort vocabulary |
33
+
34
+ The package root imports types and the loader, never `current`, so
35
+ `python -m model_authority check <dir>` can check a candidate directory while the
36
+ host directory is broken.
37
+
38
+ ## Which directory a process loads
39
+
40
+ `HANK_MODEL_AUTHORITY_DIR` set: that directory, resolved once at start; missing or
41
+ unreadable fails the start. Unset: the packaged `authority/` directory. Every
42
+ process reports what it admitted through `health_fact()`:
43
+ `{"revision", "schema", "sha256", "source", "loader", "admits"}`.
44
+
45
+ ## Changing it
46
+
47
+ - **A data change** (a model, a default, a price, a compat value) edits
48
+ `authority/` and ships by the host deploy of that directory, not by a release.
49
+ Declare the lowest schema minor that covers the fields the artifact uses.
50
+ - **A schema change** is a release: a new optional field or literal is a minor
51
+ (`SCHEMA_MINOR`), a removal or redefinition a major. Deploy loaders before data
52
+ that uses a new minor: a loader refuses an artifact whose minor is newer than its
53
+ own, naming both.
54
+ - **A capability or its executing process** is a release (`capabilities.py`).
55
+
56
+ Check a candidate directory with the ordinary load:
57
+
58
+ ```bash
59
+ python -m model_authority check <dir> # prints the health fact, or exits 1 with the refusal
60
+ ```
61
+
62
+ Tests: `.venv/bin/python3 -m pytest packages/model-authority/tests -q`
63
+ (`make test-area AREA=model_authority`).
@@ -0,0 +1,33 @@
1
+ README.md
2
+ pyproject.toml
3
+ hank_model_authority.egg-info/PKG-INFO
4
+ hank_model_authority.egg-info/SOURCES.txt
5
+ hank_model_authority.egg-info/dependency_links.txt
6
+ hank_model_authority.egg-info/requires.txt
7
+ hank_model_authority.egg-info/top_level.txt
8
+ model_authority/__init__.py
9
+ model_authority/__main__.py
10
+ model_authority/bind.py
11
+ model_authority/binding.py
12
+ model_authority/capabilities.py
13
+ model_authority/current.py
14
+ model_authority/loader.py
15
+ model_authority/rates.py
16
+ model_authority/registry.py
17
+ model_authority/schema.py
18
+ model_authority/selection.py
19
+ model_authority/thinking.py
20
+ model_authority/authority/model-authority.yaml
21
+ model_authority/authority/rates/anthropic.json
22
+ model_authority/authority/rates/codex.json
23
+ model_authority/authority/rates/ollama.json
24
+ model_authority/authority/rates/openai.json
25
+ model_authority/authority/rates/xai.json
26
+ tests/test_binding.py
27
+ tests/test_build_install_smoke.py
28
+ tests/test_check_cli.py
29
+ tests/test_loader.py
30
+ tests/test_rates.py
31
+ tests/test_registry_authority.py
32
+ tests/test_schema_compat.py
33
+ tests/test_thinking.py
@@ -0,0 +1,2 @@
1
+ PyYAML<7,>=6.0
2
+ pydantic<3,>=2.10
@@ -0,0 +1,46 @@
1
+ """hank-model-authority: the model authority artifact, its loader and resolver.
2
+
3
+ The package root exports types and the loader only. The process's one
4
+ import-time load lives in ``model_authority.current``; the resolver in
5
+ ``model_authority.binding``.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from .bind import CapabilityBind
11
+ from .loader import (
12
+ AUTHORITY_DIR_ENV_VAR,
13
+ PACKAGED_AUTHORITY_DIR,
14
+ ModelAuthority,
15
+ load_configured_model_authority,
16
+ load_model_authority,
17
+ resolve_authority_dir,
18
+ )
19
+ from .registry import AdapterRouteSupport, ModelRegistryEntry, ProductModelRegistry
20
+ from .schema import DISTRIBUTION_VERSION, SCHEMA, ModelAuthorityError
21
+ from .selection import (
22
+ CapabilityDefault,
23
+ CapabilitySelectionPolicy,
24
+ ProductModelSelectionPolicy,
25
+ )
26
+
27
+ __version__ = DISTRIBUTION_VERSION
28
+
29
+ __all__ = [
30
+ "AUTHORITY_DIR_ENV_VAR",
31
+ "AdapterRouteSupport",
32
+ "CapabilityBind",
33
+ "CapabilityDefault",
34
+ "CapabilitySelectionPolicy",
35
+ "ModelAuthority",
36
+ "ModelAuthorityError",
37
+ "ModelRegistryEntry",
38
+ "PACKAGED_AUTHORITY_DIR",
39
+ "ProductModelRegistry",
40
+ "ProductModelSelectionPolicy",
41
+ "SCHEMA",
42
+ "__version__",
43
+ "load_configured_model_authority",
44
+ "load_model_authority",
45
+ "resolve_authority_dir",
46
+ ]
@@ -0,0 +1,34 @@
1
+ """``python -m model_authority check <dir>``: admit a candidate directory.
2
+
3
+ Prints the directory's health fact as JSON and exits 0, or prints the one
4
+ refusal message to stderr and exits 1. It is the ordinary load, nothing more.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import argparse
10
+ import json
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ from .loader import load_model_authority
15
+ from .schema import ModelAuthorityError
16
+
17
+
18
+ def main(argv: list[str] | None = None) -> int:
19
+ parser = argparse.ArgumentParser(prog="python -m model_authority")
20
+ commands = parser.add_subparsers(dest="command", required=True)
21
+ check = commands.add_parser("check", help="admit one model authority directory")
22
+ check.add_argument("directory", type=Path)
23
+ args = parser.parse_args(argv)
24
+ try:
25
+ authority = load_model_authority(args.directory)
26
+ except ModelAuthorityError as exc:
27
+ print(exc, file=sys.stderr)
28
+ return 1
29
+ print(json.dumps(dict(authority.health_fact)))
30
+ return 0
31
+
32
+
33
+ if __name__ == "__main__":
34
+ raise SystemExit(main())