schemarouter 0.3.0__tar.gz → 0.4.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.
- {schemarouter-0.3.0 → schemarouter-0.4.0}/.github/workflows/ci.yml +5 -4
- {schemarouter-0.3.0 → schemarouter-0.4.0}/CHANGELOG.md +55 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/PKG-INFO +120 -7
- {schemarouter-0.3.0 → schemarouter-0.4.0}/README.ko.md +116 -7
- {schemarouter-0.3.0 → schemarouter-0.4.0}/README.md +117 -6
- {schemarouter-0.3.0 → schemarouter-0.4.0}/SECURITY.md +3 -2
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/architecture.md +83 -38
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/changelog.md +44 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/compatibility.md +14 -6
- schemarouter-0.4.0/docs/concepts/decision-backends.md +219 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/concepts/registry.md +35 -2
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/framework-maturity.md +24 -14
- schemarouter-0.4.0/docs/guides/candidate-indexing.md +63 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/decision-benchmark.md +42 -0
- schemarouter-0.4.0/docs/guides/execution-hooks.md +120 -0
- schemarouter-0.4.0/docs/guides/field-projection.md +92 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/openapi-compatibility.md +8 -2
- schemarouter-0.4.0/docs/guides/openapi.md +149 -0
- schemarouter-0.4.0/docs/guides/run-traces.md +119 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/runtime.md +21 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/integrations/langchain.md +2 -0
- schemarouter-0.4.0/docs/integrations/langgraph.md +139 -0
- schemarouter-0.4.0/docs/integrations/ollama.md +94 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/reference/planning.md +4 -0
- schemarouter-0.4.0/docs/reference/runtime.md +58 -0
- schemarouter-0.4.0/docs/releases/0.4.0.md +121 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/security/threat-model.md +27 -1
- schemarouter-0.4.0/examples/langgraph_quickstart.py +45 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/mkdocs.yml +9 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/pyproject.toml +4 -1
- schemarouter-0.4.0/scripts/benchmark_candidate_index.py +119 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/scripts/benchmark_decision_routing.py +84 -5
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/__init__.py +28 -1
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/adapters/base.py +4 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/adapters/openapi.py +146 -23
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/decision_policy.py +10 -1
- schemarouter-0.4.0/src/schemarouter/decisions.py +371 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/errors.py +8 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/executor.py +137 -23
- schemarouter-0.4.0/src/schemarouter/hooks.py +42 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/ingestion.py +275 -6
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/integrations/__init__.py +6 -0
- schemarouter-0.4.0/src/schemarouter/integrations/langgraph.py +144 -0
- schemarouter-0.4.0/src/schemarouter/integrations/ollama.py +251 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/models.py +27 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/openapi_compatibility.py +45 -35
- schemarouter-0.4.0/src/schemarouter/planner.py +950 -0
- schemarouter-0.4.0/src/schemarouter/registry.py +370 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/runtime.py +55 -18
- schemarouter-0.4.0/src/schemarouter/traces.py +359 -0
- schemarouter-0.4.0/tests/test_candidate_index.py +222 -0
- schemarouter-0.4.0/tests/test_decision_policy.py +47 -0
- schemarouter-0.4.0/tests/test_embedding_decision_backend.py +222 -0
- schemarouter-0.4.0/tests/test_evidence_sufficiency.py +334 -0
- schemarouter-0.4.0/tests/test_execution_hooks.py +493 -0
- schemarouter-0.4.0/tests/test_langgraph_integration.py +136 -0
- schemarouter-0.4.0/tests/test_nested_projection.py +284 -0
- schemarouter-0.4.0/tests/test_ollama_integration.py +316 -0
- schemarouter-0.4.0/tests/test_openapi_external_refs.py +540 -0
- schemarouter-0.4.0/tests/test_openapi_ref_composition.py +275 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_planner.py +167 -8
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_public_api.py +14 -0
- schemarouter-0.4.0/tests/test_run_traces.py +336 -0
- schemarouter-0.4.0/tests/test_sqlite_registry.py +217 -0
- schemarouter-0.3.0/docs/concepts/decision-backends.md +0 -100
- schemarouter-0.3.0/docs/guides/openapi.md +0 -92
- schemarouter-0.3.0/docs/reference/runtime.md +0 -21
- schemarouter-0.3.0/src/schemarouter/decisions.py +0 -178
- schemarouter-0.3.0/src/schemarouter/planner.py +0 -404
- schemarouter-0.3.0/src/schemarouter/registry.py +0 -84
- schemarouter-0.3.0/tests/test_decision_policy.py +0 -21
- {schemarouter-0.3.0 → schemarouter-0.4.0}/.github/dependabot.yml +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/.github/workflows/compatibility.yml +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/.github/workflows/docs.yml +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/.github/workflows/python-preview.yml +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/.github/workflows/release.yml +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/.gitignore +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/CONTRIBUTING.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/LICENSE +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/benchmarks/decision-routing-v1.json +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/adapter-authoring.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/assets/brand/README.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/assets/brand/schemarouter-lockup-dark.svg +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/assets/brand/schemarouter-lockup-light.svg +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/assets/brand/schemarouter-mark-dark.svg +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/assets/brand/schemarouter-mark-light.svg +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/assets/brand/schemarouter-social-preview.svg +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/concepts/adapters.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/concepts/execution.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/concepts/planning.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/concepts/schema-router.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/concepts/tool-endpoint.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/contributing.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/getting-started/ingestion-paths.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/getting-started/installation.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/getting-started/quickstart.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/adapter-plugins.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/execution-policy.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/html-documentation.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/mcp.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/model-analyzer.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/optimade.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/python-tools.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/guides/retry.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/index.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/integrations/jev.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/integrations/llamaindex.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/integrations/opentelemetry.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/license.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/project/brand.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/recipes/many-tools.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/recipes/mcp-agent.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/recipes/openapi-agent.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/reference/api.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/reference/models.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/release-checklist.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/releases/0.2.0a1.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/releases/0.3.0.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/releases/0.3.0a1.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/stylesheets/brand.css +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/docs/versioning.md +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/examples/langchain_quickstart.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/examples/llamaindex_quickstart.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/examples/quickstart.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/scripts/live_openapi_smoke.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/scripts/live_optimade_smoke.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/_version.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/adapters/__init__.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/adapters/mcp.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/adapters/optimade.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/adapters/plugins.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/adapters/python.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/analyzers/__init__.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/analyzers/model.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/integrations/jev.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/integrations/langchain.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/integrations/llamaindex.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/integrations/opentelemetry.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/policy.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/proposals.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/py.typed +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/runs.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/src/schemarouter/validation.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/fixtures/mcp_http_server.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_adapter_plugins.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_adapter_registry.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_adapters.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_benchmark_corpus.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_brand_assets.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_decisions.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_execution_controls.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_executor.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_ingestion.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_jev_integration.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_langchain_integration.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_llamaindex_integration.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_mcp_integration.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_mcp_transport.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_model_analyzer.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_openapi_compatibility.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_opentelemetry_integration.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_optimade_adapter.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_optimade_security.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_package_metadata.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_policy.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_proposals.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_python_adapter.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_registry.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_release_metadata.py +0 -0
- {schemarouter-0.3.0 → schemarouter-0.4.0}/tests/test_runtime_interface.py +0 -0
|
@@ -52,7 +52,7 @@ jobs:
|
|
|
52
52
|
with:
|
|
53
53
|
python-version: "3.12"
|
|
54
54
|
- run: python -m pip install --upgrade pip
|
|
55
|
-
- run: pip install -e ".[dev,mcp,langchain,llamaindex,jev,otel]"
|
|
55
|
+
- run: pip install -e ".[dev,mcp,langchain,langgraph,llamaindex,jev,otel]"
|
|
56
56
|
- run: pyright
|
|
57
57
|
|
|
58
58
|
coverage:
|
|
@@ -63,7 +63,7 @@ jobs:
|
|
|
63
63
|
with:
|
|
64
64
|
python-version: "3.12"
|
|
65
65
|
- run: python -m pip install --upgrade pip
|
|
66
|
-
- run: pip install -e ".[dev,mcp,langchain,llamaindex,jev,otel]"
|
|
66
|
+
- run: pip install -e ".[dev,mcp,langchain,langgraph,llamaindex,jev,otel]"
|
|
67
67
|
- run: pytest -q --cov=schemarouter --cov-branch --cov-report=term-missing --cov-report=xml:coverage.xml
|
|
68
68
|
- uses: actions/upload-artifact@v7
|
|
69
69
|
with:
|
|
@@ -127,9 +127,10 @@ jobs:
|
|
|
127
127
|
with:
|
|
128
128
|
python-version: "3.12"
|
|
129
129
|
- run: python -m pip install --upgrade pip
|
|
130
|
-
- run: pip install -e ".[dev,langchain]"
|
|
131
|
-
- run: pytest -q tests/test_langchain_integration.py
|
|
130
|
+
- run: pip install -e ".[dev,langchain,langgraph]"
|
|
131
|
+
- run: pytest -q tests/test_langchain_integration.py tests/test_langgraph_integration.py
|
|
132
132
|
- run: python examples/langchain_quickstart.py
|
|
133
|
+
- run: python examples/langgraph_quickstart.py
|
|
133
134
|
|
|
134
135
|
llamaindex-integration:
|
|
135
136
|
runs-on: ubuntu-latest
|
|
@@ -7,6 +7,61 @@ The project is pre-1.0 and follows the compatibility rules in
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
## 0.4.0 - 2026-09-22
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- trusted ordered sync/async before/after execution hooks with detached schema/call/result
|
|
15
|
+
snapshots, non-transforming None-only return contracts, post-await schema/binding refresh, and
|
|
16
|
+
fail-closed non-retryable hook errors.
|
|
17
|
+
- explicit opt-in bounded same-origin OpenAPI cross-document `$ref` bundling with schema-header
|
|
18
|
+
credential confinement, redirect/origin enforcement, depth/document/aggregate-byte budgets,
|
|
19
|
+
complete-document JSON/YAML parsing, cycle caching, runtime schema preservation, and fail-closed
|
|
20
|
+
handling for `$id` rebasing and non-JSON-Pointer anchors.
|
|
21
|
+
- exact-recall candidate indexing cached by registry version, with exhaustive-mode parity tests,
|
|
22
|
+
stable-snapshot rebuilds, synthetic scorer-call benchmarking, and no approximate pruning.
|
|
23
|
+
- conservative bounded `evidence_sufficiency` decision surface with deterministic local
|
|
24
|
+
provenance/license/unit/source-type prechecks, provider veto-only semantics, sync/async support,
|
|
25
|
+
abstention/error fallback policy, and no ability to upgrade missing evidence.
|
|
26
|
+
- explicit `FieldSpec.path` nested-object projection with logical field IDs, full raw-output
|
|
27
|
+
validation before extraction, overlap/collision fail-closed validation, planner path-token
|
|
28
|
+
matching, local projection enforcement for nested paths, and detached projected values.
|
|
29
|
+
- bounded `field_selection` decision surface that exposes only declared non-identifier output
|
|
30
|
+
fields, always preserves identifier fields locally, caps selections by the deterministic
|
|
31
|
+
projection width, recomputes evidence from the final field set, and supports sync/async
|
|
32
|
+
deterministic fallback.
|
|
33
|
+
- append-only `SQLiteRunTraceStore` with strict sequence/run/timestamp invariants, corruption
|
|
34
|
+
fail-closed validation, direct `astream_events(..., trace_store=...)` persistence, redaction-
|
|
35
|
+
preserving storage, and non-executing historical replay.
|
|
36
|
+
- transactional `SQLiteRegistry` persistence with monotonic version retention, deterministic tool
|
|
37
|
+
ordering, atomic batch writes, JSON-only storage, corruption/key-mismatch fail-closed validation,
|
|
38
|
+
and no persistence of trusted invokers or credentials.
|
|
39
|
+
- local Ollama bounded-decision backend using structured JSON Schema output, local option-ID
|
|
40
|
+
revalidation, sync/async HTTP paths, redirect rejection, token metadata capture, adversarial
|
|
41
|
+
mock-transport tests, and shared benchmark-harness support.
|
|
42
|
+
- provider-neutral `EmbeddingDecisionBackend` with sync/async embedding callables, cosine ranking,
|
|
43
|
+
bounded top-k selection, similarity/margin abstention, malformed-vector fail-closed validation,
|
|
44
|
+
and common benchmark-harness support.
|
|
45
|
+
- OpenAPI planner fidelity for chained local references, local Path Item references, safe
|
|
46
|
+
same-document URI-reference normalization during URL ingestion, and object property/required
|
|
47
|
+
discovery through `allOf` while preserving runtime schema validation.
|
|
48
|
+
- native LangGraph `StateGraph` integration through `schemarouter[langgraph]`, with sync/async
|
|
49
|
+
execution, checkpoint-friendly result serialization, custom state-to-request adaptation, contract
|
|
50
|
+
tests, and a runnable example.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- promoted the 0.4 development line to the non-prerelease `0.4.0` release after the persistence,
|
|
55
|
+
bounded-decision, OpenAPI, LangGraph, and execution-hook surfaces passed the required release gates.
|
|
56
|
+
|
|
57
|
+
### Compatibility
|
|
58
|
+
|
|
59
|
+
- no intentional public API removals are introduced relative to `0.3.0`;
|
|
60
|
+
- new operational surfaces remain opt-in where they can affect persistence, model-assisted decisions,
|
|
61
|
+
cross-document network access, or execution interception;
|
|
62
|
+
- the project remains pre-1.0, so later 0.x minor releases may still include deliberate documented
|
|
63
|
+
compatibility changes.
|
|
64
|
+
|
|
10
65
|
## 0.3.0 - 2026-09-22
|
|
11
66
|
|
|
12
67
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: schemarouter
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Schema-aware planning and execution layer for LLM tool ecosystems
|
|
5
5
|
Project-URL: Homepage, https://github.com/JDeun/SchemaRouter
|
|
6
6
|
Project-URL: Repository, https://github.com/JDeun/SchemaRouter
|
|
@@ -44,6 +44,8 @@ Provides-Extra: jev
|
|
|
44
44
|
Requires-Dist: typesafe-sdk<1,>=0.7; extra == 'jev'
|
|
45
45
|
Provides-Extra: langchain
|
|
46
46
|
Requires-Dist: langchain-core<2,>=1.6; extra == 'langchain'
|
|
47
|
+
Provides-Extra: langgraph
|
|
48
|
+
Requires-Dist: langgraph<2,>=1.2; extra == 'langgraph'
|
|
47
49
|
Provides-Extra: llamaindex
|
|
48
50
|
Requires-Dist: llama-index-core<1,>=0.14; extra == 'llamaindex'
|
|
49
51
|
Provides-Extra: mcp
|
|
@@ -90,7 +92,7 @@ SchemaRouter is intentionally narrower than LangChain or LangGraph. It is design
|
|
|
90
92
|
**tool-schema boundary** between an agent and structured capability sources such as OpenAPI, MCP,
|
|
91
93
|
OPTIMADE, Python callables, and third-party adapter protocols.
|
|
92
94
|
|
|
93
|
-
> Status: **0.
|
|
95
|
+
> Status: **0.4.0 is the current public non-prerelease release**. Install it from PyPI with
|
|
94
96
|
> `pip install schemarouter`. SchemaRouter remains pre-1.0, so deliberate compatibility changes
|
|
95
97
|
> may still occur in later 0.x minor releases under the documented versioning policy.
|
|
96
98
|
|
|
@@ -164,6 +166,17 @@ router = await SchemaRouter.from_url(
|
|
|
164
166
|
)
|
|
165
167
|
```
|
|
166
168
|
|
|
169
|
+
Cross-document OpenAPI `$ref` fetching stays off by default. Trusted callers can opt into bounded
|
|
170
|
+
same-origin resolution:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
router = await SchemaRouter.from_url(
|
|
174
|
+
"https://api.example.com/openapi.json",
|
|
175
|
+
kind="openapi",
|
|
176
|
+
openapi_external_refs=True,
|
|
177
|
+
)
|
|
178
|
+
```
|
|
179
|
+
|
|
167
180
|
### OPTIMADE
|
|
168
181
|
|
|
169
182
|
```python
|
|
@@ -218,18 +231,28 @@ evidence-grounded proposal and then requires explicit approval.
|
|
|
218
231
|
executable calls.
|
|
219
232
|
- **Runtime JSON Schema validation** — validate arguments before invocation and raw output before
|
|
220
233
|
projection.
|
|
234
|
+
- **Bounded nested projection** — declared logical fields may map to explicit nested object paths
|
|
235
|
+
without allowing model-produced JSONPath or undeclared field traversal.
|
|
221
236
|
- **Schema and binding drift detection** — stale plans and stale transports fail closed.
|
|
222
237
|
- **Local execution authority** — remote metadata and model output cannot grant mutation or
|
|
223
238
|
destructive permissions.
|
|
224
239
|
- **Credential separation** — schema-fetch credentials and runtime credentials stay in different
|
|
225
240
|
channels; authenticated MCP keeps secrets in the trusted transport boundary.
|
|
241
|
+
- **Bounded OpenAPI external refs** — cross-document `$ref` loading is explicit opt-in, confined to
|
|
242
|
+
the entry-document origin, and bounded by redirect/depth/document/byte limits.
|
|
226
243
|
- **Read-only retries by default** — contract violations are never retried.
|
|
227
244
|
- **Per-call approval and execution budgets** — trusted local callbacks and deterministic call,
|
|
228
245
|
attempt, remote, time, quota, and cost-unit limits fail closed.
|
|
246
|
+
- **Trusted execution hooks** — ordered sync/async before/after hooks receive detached snapshots,
|
|
247
|
+
cannot transform calls/results, and fail closed without turning hook failures into tool retries.
|
|
229
248
|
- **OpenAPI compatibility reporting** — partial/unsupported constructs are machine-readable instead
|
|
230
249
|
of silently reinterpreted.
|
|
231
250
|
- **Redacted runtime events by default** — payload tracing is opt-in.
|
|
232
|
-
- **
|
|
251
|
+
- **Replayable persistent traces** — `SQLiteRunTraceStore` can persist validated event streams and
|
|
252
|
+
replay them later without re-running planners, network calls, or tools.
|
|
253
|
+
- **Persistent/pluggable registry** — use the built-in transactional `SQLiteRegistry` or inject a
|
|
254
|
+
custom implementation of the public `ToolRegistry` protocol. Persistent catalog state never
|
|
255
|
+
serializes trusted invokers or credentials.
|
|
233
256
|
- **Pluggable source adapters** — `AdapterRegistry` lets structured protocols compile into the same
|
|
234
257
|
`ToolSpec` / `EndpointSpec` execution model; installed entry-point plugins require an explicit
|
|
235
258
|
allowlist before import.
|
|
@@ -250,6 +273,21 @@ tools = to_langchain_tools(router)
|
|
|
250
273
|
|
|
251
274
|
Execution still flows through SchemaRouter's policy, fingerprint, input, and output validation.
|
|
252
275
|
|
|
276
|
+
## With LangGraph
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
pip install "schemarouter[langgraph]"
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
```python
|
|
283
|
+
from schemarouter.integrations import to_langgraph_node
|
|
284
|
+
|
|
285
|
+
builder.add_node("schema_router", to_langgraph_node(router))
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
The node supports sync/async `StateGraph` execution and returns checkpoint-friendly partial state
|
|
289
|
+
updates while SchemaRouter retains planning, policy, and validated execution authority.
|
|
290
|
+
|
|
253
291
|
## With LlamaIndex
|
|
254
292
|
|
|
255
293
|
Install the packaged LlamaIndex bridge:
|
|
@@ -269,8 +307,8 @@ endpoint execution.
|
|
|
269
307
|
|
|
270
308
|
## Experimental bounded decisions
|
|
271
309
|
|
|
272
|
-
SchemaRouter includes an optional bounded `DecisionBackend` for tool/endpoint
|
|
273
|
-
**off by default** and cannot invent executable schema members.
|
|
310
|
+
SchemaRouter includes an optional bounded `DecisionBackend` for tool/endpoint and output-field
|
|
311
|
+
selection. It is **off by default** and cannot invent executable schema members.
|
|
274
312
|
|
|
275
313
|
```python
|
|
276
314
|
from schemarouter import DecisionPolicy, SchemaPlanner
|
|
@@ -287,6 +325,23 @@ planner = SchemaPlanner(
|
|
|
287
325
|
)
|
|
288
326
|
```
|
|
289
327
|
|
|
328
|
+
A provider-neutral local embedding backend is also available without adding an embedding library to
|
|
329
|
+
SchemaRouter's dependencies:
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
from schemarouter import EmbeddingDecisionBackend
|
|
333
|
+
|
|
334
|
+
backend = EmbeddingDecisionBackend(
|
|
335
|
+
embed_batch,
|
|
336
|
+
min_similarity=0.35,
|
|
337
|
+
min_margin=0.05,
|
|
338
|
+
)
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The callable can wrap a local SentenceTransformers/FastEmbed-style encoder or an application-owned
|
|
342
|
+
embedding service. SchemaRouter computes cosine ranking locally and can abstain on weak or ambiguous
|
|
343
|
+
matches.
|
|
344
|
+
|
|
290
345
|
Jev / TypeSafe System One is optional:
|
|
291
346
|
|
|
292
347
|
```bash
|
|
@@ -298,6 +353,44 @@ The provider receives only bounded decision inputs. Unknown option IDs fail clos
|
|
|
298
353
|
valid choices can abstain, and deterministic fallback remains available. Jev is never enabled just
|
|
299
354
|
because the package or an API key exists.
|
|
300
355
|
|
|
356
|
+
A local Ollama model can also serve as a bounded decision backend without an additional Python SDK:
|
|
357
|
+
|
|
358
|
+
```python
|
|
359
|
+
from schemarouter.integrations import OllamaDecisionBackend
|
|
360
|
+
|
|
361
|
+
backend = OllamaDecisionBackend("your-installed-model")
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Ollama structured output constrains the finite option IDs, and SchemaRouter revalidates the result
|
|
365
|
+
locally. No local model is enabled automatically.
|
|
366
|
+
|
|
367
|
+
Bounded field selection is independently opt-in:
|
|
368
|
+
|
|
369
|
+
```python
|
|
370
|
+
policy = DecisionPolicy(
|
|
371
|
+
enabled=True,
|
|
372
|
+
field_selection=True,
|
|
373
|
+
fallback="deterministic",
|
|
374
|
+
)
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Only declared non-identifier fields are offered to the backend. Identifier fields are always
|
|
378
|
+
preserved locally, and invalid/abstaining provider output falls back to deterministic projection.
|
|
379
|
+
|
|
380
|
+
Evidence sufficiency is independently opt-in as a conservative gate:
|
|
381
|
+
|
|
382
|
+
```python
|
|
383
|
+
policy = DecisionPolicy(
|
|
384
|
+
enabled=True,
|
|
385
|
+
evidence_sufficiency=True,
|
|
386
|
+
fallback="deterministic",
|
|
387
|
+
)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Requested provenance/license/unit/source-type requirements must first be satisfied by local schema
|
|
391
|
+
metadata. The backend then receives only `evidence:sufficient` / `evidence:insufficient` and can
|
|
392
|
+
veto a locally sufficient call, but it cannot upgrade missing evidence or grant execution authority.
|
|
393
|
+
|
|
301
394
|
## Decision benchmark
|
|
302
395
|
|
|
303
396
|
Run the deterministic baseline:
|
|
@@ -306,16 +399,31 @@ Run the deterministic baseline:
|
|
|
306
399
|
python scripts/benchmark_decision_routing.py
|
|
307
400
|
```
|
|
308
401
|
|
|
402
|
+
Compare an embedding backend through a local callable:
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
python scripts/benchmark_decision_routing.py \
|
|
406
|
+
--corpus benchmarks/decision-routing-v1.json \
|
|
407
|
+
--embedding-callable my_embeddings:embed_batch
|
|
408
|
+
```
|
|
409
|
+
|
|
309
410
|
Compare Jev when credentials are available:
|
|
310
411
|
|
|
311
412
|
```bash
|
|
312
413
|
TYPESAFE_API_KEY="..." python scripts/benchmark_decision_routing.py --jev
|
|
313
414
|
```
|
|
314
415
|
|
|
416
|
+
Compare an installed local Ollama model:
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
python scripts/benchmark_decision_routing.py --ollama-model your-installed-model
|
|
420
|
+
```
|
|
421
|
+
|
|
315
422
|
The harness includes a checked-in 144-case multilingual/adversarial corpus and reports routing
|
|
316
423
|
accuracy, invalid-plan rate, abstentions/fallbacks, category accuracy, p50/p95 latency, token usage,
|
|
317
424
|
errors, and optional cost estimates. A provider-neutral `ModelQueryAnalyzer` callable can also be
|
|
318
|
-
supplied with `--model-callable module:function
|
|
425
|
+
supplied with `--model-callable module:function`; embedding encoders use
|
|
426
|
+
`--embedding-callable module:function`.
|
|
319
427
|
|
|
320
428
|
```bash
|
|
321
429
|
python scripts/benchmark_decision_routing.py \
|
|
@@ -337,10 +445,15 @@ Full documentation is organized as a framework manual rather than embedded in th
|
|
|
337
445
|
- [LangChain integration](https://jdeun.github.io/SchemaRouter/integrations/langchain/)
|
|
338
446
|
- [LlamaIndex integration](https://jdeun.github.io/SchemaRouter/integrations/llamaindex/)
|
|
339
447
|
- [Jev / TypeSafe integration](https://jdeun.github.io/SchemaRouter/integrations/jev/)
|
|
448
|
+
- [Ollama decision backend](https://jdeun.github.io/SchemaRouter/integrations/ollama/)
|
|
340
449
|
- [OpenTelemetry integration](https://jdeun.github.io/SchemaRouter/integrations/opentelemetry/)
|
|
341
450
|
- [Third-party adapter plugins](https://jdeun.github.io/SchemaRouter/guides/adapter-plugins/)
|
|
342
451
|
- [Decision backends](https://jdeun.github.io/SchemaRouter/concepts/decision-backends/)
|
|
343
452
|
- [Decision benchmark](https://jdeun.github.io/SchemaRouter/guides/decision-benchmark/)
|
|
453
|
+
- [Persistent run traces](https://jdeun.github.io/SchemaRouter/guides/run-traces/)
|
|
454
|
+
- [Trusted execution hooks](https://jdeun.github.io/SchemaRouter/guides/execution-hooks/)
|
|
455
|
+
- [Field projection](https://jdeun.github.io/SchemaRouter/guides/field-projection/)
|
|
456
|
+
- [Candidate indexing](https://jdeun.github.io/SchemaRouter/guides/candidate-indexing/)
|
|
344
457
|
- [API reference](https://jdeun.github.io/SchemaRouter/reference/api/)
|
|
345
458
|
- [Architecture](https://jdeun.github.io/SchemaRouter/architecture/)
|
|
346
459
|
- [Security](https://github.com/JDeun/SchemaRouter/blob/main/SECURITY.md)
|
|
@@ -365,7 +478,7 @@ python examples/quickstart.py
|
|
|
365
478
|
python scripts/benchmark_decision_routing.py
|
|
366
479
|
|
|
367
480
|
# Type-check the complete packaged surface, including optional integrations.
|
|
368
|
-
pip install -e ".[dev,mcp,langchain,llamaindex,jev,otel]"
|
|
481
|
+
pip install -e ".[dev,mcp,langchain,langgraph,llamaindex,jev,otel]"
|
|
369
482
|
pyright
|
|
370
483
|
pytest -q --cov=schemarouter --cov-branch --cov-report=term-missing
|
|
371
484
|
```
|
|
@@ -35,7 +35,7 @@ SchemaRouter는 LangChain이나 LangGraph를 대체하는 범용 에이전트
|
|
|
35
35
|
OpenAPI, MCP, OPTIMADE, Python callable 및 제3자 어댑터와 에이전트 사이의
|
|
36
36
|
**tool-schema boundary**를 담당하도록 설계되었습니다.
|
|
37
37
|
|
|
38
|
-
> 현재 공개 non-prerelease 릴리스는 **0.
|
|
38
|
+
> 현재 공개 non-prerelease 릴리스는 **0.4.0**입니다. PyPI에서
|
|
39
39
|
> `pip install schemarouter`로 설치할 수 있습니다. SchemaRouter는 아직 pre-1.0이므로
|
|
40
40
|
> 이후 0.x minor 릴리스에서는 문서화된 버전 정책에 따라 의도적인 호환성 변경이 있을 수 있습니다.
|
|
41
41
|
|
|
@@ -109,6 +109,17 @@ router = await SchemaRouter.from_url(
|
|
|
109
109
|
)
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
OpenAPI cross-document `$ref` fetch는 기본적으로 꺼져 있습니다. 신뢰된 호출자가 명시적으로
|
|
113
|
+
same-origin bounded resolution을 켤 수 있습니다.
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
router = await SchemaRouter.from_url(
|
|
117
|
+
"https://api.example.com/openapi.json",
|
|
118
|
+
kind="openapi",
|
|
119
|
+
openapi_external_refs=True,
|
|
120
|
+
)
|
|
121
|
+
```
|
|
122
|
+
|
|
112
123
|
### OPTIMADE
|
|
113
124
|
|
|
114
125
|
```python
|
|
@@ -163,20 +174,27 @@ proposal로 변환한 뒤 명시적인 승인을 받아야 합니다.
|
|
|
163
174
|
가능한 호출이 될 수 없습니다.
|
|
164
175
|
- **Runtime JSON Schema validation** — 호출 전 argument와 projection 전 raw output을
|
|
165
176
|
검증합니다.
|
|
177
|
+
- **Bounded nested projection** — 선언된 logical field만 명시적 nested object path에
|
|
178
|
+
매핑할 수 있으며 모델이 임의 JSONPath나 미선언 경로를 만들 수 없습니다.
|
|
166
179
|
- **Schema / binding drift detection** — 오래된 plan이나 transport binding은 fail closed로
|
|
167
180
|
차단합니다.
|
|
168
181
|
- **Local execution authority** — 원격 metadata나 모델 출력이 mutation/destructive 권한을
|
|
169
182
|
부여할 수 없습니다.
|
|
170
183
|
- **Credential separation** — schema fetch credential과 runtime credential을 분리하며,
|
|
171
184
|
인증 MCP secret은 trusted transport 경계 안에만 둡니다.
|
|
185
|
+
- **Bounded OpenAPI external ref** — cross-document `$ref`는 명시적 opt-in일 때만 entry
|
|
186
|
+
document와 같은 origin에서 fetch되며 redirect/depth/document/byte limit을 적용합니다.
|
|
172
187
|
- **Read-only retry by default** — 계약 위반이나 위험한 호출을 자동 재시도하지 않습니다.
|
|
173
188
|
- **호출별 승인 및 실행 budget** — trusted local callback과 call/attempt/remote/time/quota/
|
|
174
189
|
cost-unit 제한을 fail-closed로 적용합니다.
|
|
190
|
+
- **Trusted execution hook** — 순서가 보장되는 sync/async before/after hook은 detached snapshot만
|
|
191
|
+
받고 call/result를 변환하지 못하며, hook 실패를 tool retry로 오인하지 않고 fail closed 처리합니다.
|
|
175
192
|
- **OpenAPI compatibility report** — partial/unsupported construct를 숨기지 않고
|
|
176
193
|
machine-readable report로 노출합니다.
|
|
177
194
|
- **Redacted runtime event by default** — payload trace는 명시적으로 opt-in해야 합니다.
|
|
178
|
-
- **
|
|
179
|
-
있습니다.
|
|
195
|
+
- **Persistent/pluggable registry** — built-in transactional `SQLiteRegistry`를 사용하거나
|
|
196
|
+
공개 `ToolRegistry` protocol 기반 커스텀 구현을 주입할 수 있습니다. persistent catalog에는
|
|
197
|
+
trusted invoker나 credential을 직렬화하지 않습니다.
|
|
180
198
|
- **Pluggable adapter** — `AdapterRegistry`를 통해 다양한 structured protocol을 동일한
|
|
181
199
|
`ToolSpec` / `EndpointSpec` 실행 모델로 변환할 수 있으며, 설치된 entry-point plugin은
|
|
182
200
|
명시적 allowlist가 있어야 import됩니다.
|
|
@@ -198,6 +216,21 @@ tools = to_langchain_tools(router)
|
|
|
198
216
|
LangChain 도구로 노출해도 실행은 SchemaRouter의 policy, fingerprint, input/output validation
|
|
199
217
|
경계를 그대로 통과합니다.
|
|
200
218
|
|
|
219
|
+
## LangGraph와 사용
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
pip install "schemarouter[langgraph]"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
from schemarouter.integrations import to_langgraph_node
|
|
227
|
+
|
|
228
|
+
builder.add_node("schema_router", to_langgraph_node(router))
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
이 노드는 sync/async `StateGraph` 실행을 지원하고 checkpoint에 적합한 partial state update를
|
|
232
|
+
반환합니다. planning, policy, 검증된 execution authority는 SchemaRouter가 계속 유지합니다.
|
|
233
|
+
|
|
201
234
|
## LlamaIndex와 사용
|
|
202
235
|
|
|
203
236
|
LlamaIndex bridge는 패키지 extra로 설치할 수 있습니다.
|
|
@@ -217,8 +250,8 @@ validation 및 endpoint execution 경계를 유지합니다.
|
|
|
217
250
|
|
|
218
251
|
## 실험적 bounded decision
|
|
219
252
|
|
|
220
|
-
SchemaRouter는 tool/endpoint 선택을 보조하는 opt-in `DecisionBackend`를
|
|
221
|
-
기본값은 **OFF**이며 모델이 임의의 실행 가능한 스키마 멤버를 만들 수 없습니다.
|
|
253
|
+
SchemaRouter는 tool/endpoint와 output field 선택을 보조하는 opt-in `DecisionBackend`를
|
|
254
|
+
제공합니다. 기본값은 **OFF**이며 모델이 임의의 실행 가능한 스키마 멤버를 만들 수 없습니다.
|
|
222
255
|
|
|
223
256
|
```python
|
|
224
257
|
from schemarouter import DecisionPolicy, SchemaPlanner
|
|
@@ -235,6 +268,23 @@ planner = SchemaPlanner(
|
|
|
235
268
|
)
|
|
236
269
|
```
|
|
237
270
|
|
|
271
|
+
특정 provider에 종속되지 않는 local embedding backend도 core dependency 추가 없이 사용할 수
|
|
272
|
+
있습니다.
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
from schemarouter import EmbeddingDecisionBackend
|
|
276
|
+
|
|
277
|
+
backend = EmbeddingDecisionBackend(
|
|
278
|
+
embed_batch,
|
|
279
|
+
min_similarity=0.35,
|
|
280
|
+
min_margin=0.05,
|
|
281
|
+
)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
callable에는 local SentenceTransformers/FastEmbed 계열 encoder나 애플리케이션 소유 embedding
|
|
285
|
+
service를 연결할 수 있습니다. cosine ranking은 SchemaRouter가 로컬에서 수행하며 약하거나
|
|
286
|
+
모호한 선택은 abstain할 수 있습니다.
|
|
287
|
+
|
|
238
288
|
Jev / TypeSafe System One은 선택형 기능입니다.
|
|
239
289
|
|
|
240
290
|
```bash
|
|
@@ -248,6 +298,45 @@ abstain한 뒤 deterministic fallback으로 돌아갈 수 있습니다.
|
|
|
248
298
|
|
|
249
299
|
패키지를 설치했거나 API key가 존재한다는 이유만으로 Jev가 자동 활성화되지는 않습니다.
|
|
250
300
|
|
|
301
|
+
로컬 Ollama 모델도 별도 Python SDK 없이 bounded decision backend로 사용할 수 있습니다.
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
from schemarouter.integrations import OllamaDecisionBackend
|
|
305
|
+
|
|
306
|
+
backend = OllamaDecisionBackend("your-installed-model")
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Ollama structured output으로 유한한 option ID를 제한하고, SchemaRouter가 결과를 다시 로컬
|
|
310
|
+
검증합니다. 로컬 모델이 존재한다는 이유만으로 자동 활성화되지는 않습니다.
|
|
311
|
+
|
|
312
|
+
bounded field selection도 별도로 opt-in할 수 있습니다.
|
|
313
|
+
|
|
314
|
+
```python
|
|
315
|
+
policy = DecisionPolicy(
|
|
316
|
+
enabled=True,
|
|
317
|
+
field_selection=True,
|
|
318
|
+
fallback="deterministic",
|
|
319
|
+
)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
backend에는 선언된 non-identifier field만 제공되고 identifier field는 항상 로컬에서
|
|
323
|
+
보존됩니다. invalid output이나 abstain은 deterministic projection으로 fallback됩니다.
|
|
324
|
+
|
|
325
|
+
Evidence sufficiency도 별도로 opt-in할 수 있는 보수적 gate입니다.
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
policy = DecisionPolicy(
|
|
329
|
+
enabled=True,
|
|
330
|
+
evidence_sufficiency=True,
|
|
331
|
+
fallback="deterministic",
|
|
332
|
+
)
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
요청된 provenance/license/unit/source-type은 먼저 로컬 schema metadata로 충족되어야 합니다.
|
|
336
|
+
그 뒤 backend는 `evidence:sufficient` / `evidence:insufficient` 두 선택지만 받으며,
|
|
337
|
+
로컬에서 충분한 call을 veto할 수 있을 뿐 없는 evidence를 만들어내거나 실행 권한을 높일 수
|
|
338
|
+
없습니다.
|
|
339
|
+
|
|
251
340
|
## Decision benchmark
|
|
252
341
|
|
|
253
342
|
기본 deterministic routing을 측정합니다.
|
|
@@ -256,16 +345,31 @@ abstain한 뒤 deterministic fallback으로 돌아갈 수 있습니다.
|
|
|
256
345
|
python scripts/benchmark_decision_routing.py
|
|
257
346
|
```
|
|
258
347
|
|
|
348
|
+
local embedding callable도 같은 corpus에서 비교할 수 있습니다.
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
python scripts/benchmark_decision_routing.py \
|
|
352
|
+
--corpus benchmarks/decision-routing-v1.json \
|
|
353
|
+
--embedding-callable my_embeddings:embed_batch
|
|
354
|
+
```
|
|
355
|
+
|
|
259
356
|
API key가 있다면 같은 케이스로 Jev도 비교할 수 있습니다.
|
|
260
357
|
|
|
261
358
|
```bash
|
|
262
359
|
TYPESAFE_API_KEY="..." python scripts/benchmark_decision_routing.py --jev
|
|
263
360
|
```
|
|
264
361
|
|
|
362
|
+
설치된 로컬 Ollama 모델도 같은 corpus로 비교할 수 있습니다.
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
python scripts/benchmark_decision_routing.py --ollama-model your-installed-model
|
|
366
|
+
```
|
|
367
|
+
|
|
265
368
|
benchmark에는 144개 multilingual/adversarial 고정 corpus가 포함되며 routing accuracy,
|
|
266
369
|
invalid-plan rate, abstention/fallback, category accuracy, p50/p95 latency, token usage, error와
|
|
267
370
|
선택적인 비용 추정치를 기록합니다. `--model-callable module:function`을 이용하면
|
|
268
|
-
provider-neutral `ModelQueryAnalyzer`도 같은 harness에서 비교할 수
|
|
371
|
+
provider-neutral `ModelQueryAnalyzer`도 같은 harness에서 비교할 수 있고, embedding
|
|
372
|
+
encoder는 `--embedding-callable module:function`으로 연결할 수 있습니다.
|
|
269
373
|
|
|
270
374
|
```bash
|
|
271
375
|
python scripts/benchmark_decision_routing.py \
|
|
@@ -287,10 +391,15 @@ python scripts/benchmark_decision_routing.py \
|
|
|
287
391
|
- [LangChain integration](https://jdeun.github.io/SchemaRouter/integrations/langchain/)
|
|
288
392
|
- [LlamaIndex integration](https://jdeun.github.io/SchemaRouter/integrations/llamaindex/)
|
|
289
393
|
- [Jev / TypeSafe integration](https://jdeun.github.io/SchemaRouter/integrations/jev/)
|
|
394
|
+
- [Ollama decision backend](https://jdeun.github.io/SchemaRouter/integrations/ollama/)
|
|
290
395
|
- [OpenTelemetry integration](https://jdeun.github.io/SchemaRouter/integrations/opentelemetry/)
|
|
291
396
|
- [Third-party adapter plugins](https://jdeun.github.io/SchemaRouter/guides/adapter-plugins/)
|
|
292
397
|
- [Decision backends](https://jdeun.github.io/SchemaRouter/concepts/decision-backends/)
|
|
293
398
|
- [Decision benchmark](https://jdeun.github.io/SchemaRouter/guides/decision-benchmark/)
|
|
399
|
+
- [Persistent run traces](https://jdeun.github.io/SchemaRouter/guides/run-traces/)
|
|
400
|
+
- [Trusted execution hooks](https://jdeun.github.io/SchemaRouter/guides/execution-hooks/)
|
|
401
|
+
- [Field projection](https://jdeun.github.io/SchemaRouter/guides/field-projection/)
|
|
402
|
+
- [Candidate indexing](https://jdeun.github.io/SchemaRouter/guides/candidate-indexing/)
|
|
294
403
|
- [API reference](https://jdeun.github.io/SchemaRouter/reference/api/)
|
|
295
404
|
- [Architecture](https://jdeun.github.io/SchemaRouter/architecture/)
|
|
296
405
|
- [Security](https://github.com/JDeun/SchemaRouter/blob/main/SECURITY.md)
|
|
@@ -315,7 +424,7 @@ python examples/quickstart.py
|
|
|
315
424
|
python scripts/benchmark_decision_routing.py
|
|
316
425
|
|
|
317
426
|
# 선택형 통합을 포함한 전체 패키지 surface 타입 검사
|
|
318
|
-
pip install -e ".[dev,mcp,langchain,llamaindex,jev,otel]"
|
|
427
|
+
pip install -e ".[dev,mcp,langchain,langgraph,llamaindex,jev,otel]"
|
|
319
428
|
pyright
|
|
320
429
|
pytest -q --cov=schemarouter --cov-branch --cov-report=term-missing
|
|
321
430
|
```
|