agentinputlab 0.1.0a1__py3-none-any.whl
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.
- agentinputlab/__init__.py +28 -0
- agentinputlab/algorithms/__init__.py +6 -0
- agentinputlab/algorithms/acquire/__init__.py +145 -0
- agentinputlab/algorithms/acquire/adaptive_rag/__init__.py +43 -0
- agentinputlab/algorithms/acquire/adaptive_rag/replay.py +367 -0
- agentinputlab/algorithms/acquire/adaptive_rag/runtime.py +1202 -0
- agentinputlab/algorithms/acquire/adaptive_rag_common_support.py +542 -0
- agentinputlab/algorithms/acquire/hyde.py +296 -0
- agentinputlab/algorithms/acquire/hyde_controlled.py +200 -0
- agentinputlab/algorithms/acquire/hyde_external.py +148 -0
- agentinputlab/algorithms/acquire/ircot.py +28 -0
- agentinputlab/algorithms/acquire/ircot_common_support.py +478 -0
- agentinputlab/algorithms/acquire/ircot_native.py +355 -0
- agentinputlab/algorithms/acquire/ircot_replay.py +327 -0
- agentinputlab/algorithms/acquire/qrag/__init__.py +79 -0
- agentinputlab/algorithms/acquire/qrag/bridge.py +828 -0
- agentinputlab/algorithms/acquire/qrag/common_support.py +891 -0
- agentinputlab/algorithms/acquire/qrag/native_axis.py +71 -0
- agentinputlab/algorithms/acquire/qrag/reader_adapter.py +139 -0
- agentinputlab/algorithms/acquire/r2ag/__init__.py +57 -0
- agentinputlab/algorithms/acquire/r2ag/bridge.py +1312 -0
- agentinputlab/algorithms/acquire/r2ag/common_support.py +1029 -0
- agentinputlab/algorithms/acquire/r2ag/socket_runtime.py +255 -0
- agentinputlab/algorithms/clarify/__init__.py +61 -0
- agentinputlab/algorithms/clarify/_structured.py +64 -0
- agentinputlab/algorithms/clarify/active_task_disambiguation.py +371 -0
- agentinputlab/algorithms/clarify/ask_or_assume/__init__.py +17 -0
- agentinputlab/algorithms/clarify/ask_or_assume/monitor.py +410 -0
- agentinputlab/algorithms/clarify/future_turns.py +379 -0
- agentinputlab/algorithms/clarify/udcs.py +255 -0
- agentinputlab/algorithms/clarify/udcs_deterministic.py +196 -0
- agentinputlab/algorithms/curate/__init__.py +65 -0
- agentinputlab/algorithms/curate/acon/__init__.py +27 -0
- agentinputlab/algorithms/curate/acon/common.py +284 -0
- agentinputlab/algorithms/curate/acon/common_support.py +136 -0
- agentinputlab/algorithms/curate/acon/history_bridge.py +309 -0
- agentinputlab/algorithms/curate/acon/observation_bridge.py +290 -0
- agentinputlab/algorithms/curate/llmlingua/__init__.py +30 -0
- agentinputlab/algorithms/curate/llmlingua/adapters.py +537 -0
- agentinputlab/algorithms/curate/llmlingua/budget.py +48 -0
- agentinputlab/algorithms/curate/llmlingua/controlled.py +175 -0
- agentinputlab/algorithms/curate/llmlingua/multilingual.py +105 -0
- agentinputlab/algorithms/curate/llmlingua/span_map.py +167 -0
- agentinputlab/algorithms/curate/recomp/__init__.py +47 -0
- agentinputlab/algorithms/curate/recomp/external.py +1129 -0
- agentinputlab/algorithms/curate/recomp/selective.py +304 -0
- agentinputlab/algorithms/decompose/__init__.py +107 -0
- agentinputlab/algorithms/decompose/decomp/__init__.py +53 -0
- agentinputlab/algorithms/decompose/decomp/common_support.py +478 -0
- agentinputlab/algorithms/decompose/decomp/planner_component.py +199 -0
- agentinputlab/algorithms/decompose/decomp/worker_bridge.py +416 -0
- agentinputlab/algorithms/decompose/llm_compiler/__init__.py +35 -0
- agentinputlab/algorithms/decompose/llm_compiler/bridge.py +520 -0
- agentinputlab/algorithms/decompose/llm_compiler/common_support.py +504 -0
- agentinputlab/algorithms/decompose/plan_and_budget/__init__.py +43 -0
- agentinputlab/algorithms/decompose/plan_and_budget/cached_soft_budget.py +362 -0
- agentinputlab/algorithms/decompose/plan_and_budget/decomposer_component.py +107 -0
- agentinputlab/algorithms/decompose/plan_and_budget/full.py +205 -0
- agentinputlab/algorithms/decompose/plan_and_budget/hard_cap.py +246 -0
- agentinputlab/algorithms/decompose/plan_and_budget/regenerated_soft_budget.py +448 -0
- agentinputlab/algorithms/decompose/plan_and_solve/__init__.py +33 -0
- agentinputlab/algorithms/decompose/plan_and_solve/plan_component.py +192 -0
- agentinputlab/algorithms/decompose/plan_and_solve/ps_prompt.py +127 -0
- agentinputlab/algorithms/decompose/self_ask/__init__.py +27 -0
- agentinputlab/algorithms/decompose/self_ask/loop.py +362 -0
- agentinputlab/algorithms/decompose/self_ask/planner_component.py +117 -0
- agentinputlab/algorithms/reformulate/__init__.py +85 -0
- agentinputlab/algorithms/reformulate/infocqr/__init__.py +40 -0
- agentinputlab/algorithms/reformulate/infocqr/cache_replay.py +362 -0
- agentinputlab/algorithms/reformulate/infocqr/external.py +675 -0
- agentinputlab/algorithms/reformulate/infocqr/student.py +189 -0
- agentinputlab/algorithms/reformulate/query2doc/__init__.py +42 -0
- agentinputlab/algorithms/reformulate/query2doc/controlled_live.py +190 -0
- agentinputlab/algorithms/reformulate/query2doc/models.py +95 -0
- agentinputlab/algorithms/reformulate/query2doc/official_cached.py +335 -0
- agentinputlab/algorithms/reformulate/query2doc/querygym_bridge.py +223 -0
- agentinputlab/algorithms/reformulate/query2doc/querygym_runtime.py +326 -0
- agentinputlab/algorithms/reformulate/reformer/__init__.py +23 -0
- agentinputlab/algorithms/reformulate/reformer/external.py +417 -0
- agentinputlab/algorithms/reformulate/rrr.py +696 -0
- agentinputlab/annotation/__init__.py +5 -0
- agentinputlab/annotation/independent.py +428 -0
- agentinputlab/annotation/server.py +233 -0
- agentinputlab/annotation/static/app.js +121 -0
- agentinputlab/annotation/static/index.html +60 -0
- agentinputlab/annotation/static/review.css +2 -0
- agentinputlab/annotation/static/review.html +10 -0
- agentinputlab/annotation/static/review.js +11 -0
- agentinputlab/annotation/static/styles.css +55 -0
- agentinputlab/annotation/store.py +444 -0
- agentinputlab/api.py +368 -0
- agentinputlab/artifacts/__init__.py +15 -0
- agentinputlab/artifacts/json_file.py +104 -0
- agentinputlab/artifacts/manifest.py +98 -0
- agentinputlab/artifacts/store.py +157 -0
- agentinputlab/backends/__init__.py +98 -0
- agentinputlab/backends/embedding/__init__.py +25 -0
- agentinputlab/backends/embedding/base.py +145 -0
- agentinputlab/backends/embedding/callable.py +75 -0
- agentinputlab/backends/embedding/replay.py +129 -0
- agentinputlab/backends/llm/__init__.py +31 -0
- agentinputlab/backends/llm/base.py +149 -0
- agentinputlab/backends/llm/callable.py +108 -0
- agentinputlab/backends/llm/decomp_completion.py +88 -0
- agentinputlab/backends/llm/final_content_stop.py +72 -0
- agentinputlab/backends/llm/gpt_oss_final_channel.py +84 -0
- agentinputlab/backends/llm/openai_compatible.py +332 -0
- agentinputlab/backends/llm/transformers.py +171 -0
- agentinputlab/backends/retrieval/__init__.py +35 -0
- agentinputlab/backends/retrieval/base.py +50 -0
- agentinputlab/backends/retrieval/dense.py +777 -0
- agentinputlab/backends/retrieval/memory.py +119 -0
- agentinputlab/backends/retrieval/sqlite_fts.py +155 -0
- agentinputlab/backends/user/__init__.py +15 -0
- agentinputlab/backends/user/base.py +66 -0
- agentinputlab/backends/user/callable.py +54 -0
- agentinputlab/backends/user/replay.py +89 -0
- agentinputlab/backends/vector.py +38 -0
- agentinputlab/benchmarks/__init__.py +246 -0
- agentinputlab/benchmarks/acquisition.py +106 -0
- agentinputlab/benchmarks/ale.py +540 -0
- agentinputlab/benchmarks/appworld_ul.py +669 -0
- agentinputlab/benchmarks/assets.py +226 -0
- agentinputlab/benchmarks/base.py +68 -0
- agentinputlab/benchmarks/beir_archive.py +235 -0
- agentinputlab/benchmarks/beir_sample.py +269 -0
- agentinputlab/benchmarks/bfcl_native.py +245 -0
- agentinputlab/benchmarks/bfcl_v3.py +607 -0
- agentinputlab/benchmarks/cache.py +218 -0
- agentinputlab/benchmarks/clariq.py +203 -0
- agentinputlab/benchmarks/data/registry.json +321 -0
- agentinputlab/benchmarks/data/smoke_assets.json +511 -0
- agentinputlab/benchmarks/data/statebench_v0_8_1_task_ids.json +475 -0
- agentinputlab/benchmarks/data/toolsandbox_165848b_scenario_names.json +1 -0
- agentinputlab/benchmarks/execution.py +1111 -0
- agentinputlab/benchmarks/interactive.py +257 -0
- agentinputlab/benchmarks/ir_query.py +204 -0
- agentinputlab/benchmarks/longbench.py +203 -0
- agentinputlab/benchmarks/paired_replay.py +479 -0
- agentinputlab/benchmarks/preprocess.py +2313 -0
- agentinputlab/benchmarks/production.py +236 -0
- agentinputlab/benchmarks/qa.py +963 -0
- agentinputlab/benchmarks/registry.py +110 -0
- agentinputlab/benchmarks/retrieval.py +459 -0
- agentinputlab/benchmarks/runtime.py +509 -0
- agentinputlab/benchmarks/statebench.py +938 -0
- agentinputlab/benchmarks/tau3.py +725 -0
- agentinputlab/benchmarks/toolsandbox.py +626 -0
- agentinputlab/benchmarks/trec_dl_sample.py +263 -0
- agentinputlab/campaign.py +654 -0
- agentinputlab/campaign_runner.py +953 -0
- agentinputlab/cli/__init__.py +6 -0
- agentinputlab/cli/main.py +933 -0
- agentinputlab/connectors/__init__.py +46 -0
- agentinputlab/connectors/knowledge/__init__.py +4 -0
- agentinputlab/connectors/tools/__init__.py +30 -0
- agentinputlab/connectors/tools/base.py +57 -0
- agentinputlab/connectors/tools/mcp.py +222 -0
- agentinputlab/connectors/tools/memory.py +41 -0
- agentinputlab/connectors/tools/openapi.py +695 -0
- agentinputlab/connectors/tools/schema.py +102 -0
- agentinputlab/contracts/__init__.py +91 -0
- agentinputlab/contracts/availability.py +24 -0
- agentinputlab/contracts/dependency.py +58 -0
- agentinputlab/contracts/enums.py +82 -0
- agentinputlab/contracts/errors.py +63 -0
- agentinputlab/contracts/evidence.py +43 -0
- agentinputlab/contracts/intent.py +110 -0
- agentinputlab/contracts/lifecycle.py +164 -0
- agentinputlab/contracts/patch.py +167 -0
- agentinputlab/contracts/serialization.py +93 -0
- agentinputlab/contracts/state.py +127 -0
- agentinputlab/contracts/trace.py +59 -0
- agentinputlab/contracts/worker.py +42 -0
- agentinputlab/core/__init__.py +7 -0
- agentinputlab/data/__init__.py +32 -0
- agentinputlab/data/checksums.py +9 -0
- agentinputlab/data/downloader.py +235 -0
- agentinputlab/data/http.py +171 -0
- agentinputlab/data/index.py +21 -0
- agentinputlab/data/overlap.py +28 -0
- agentinputlab/data/preprocess.py +32 -0
- agentinputlab/data/storage.py +57 -0
- agentinputlab/data/trec_sample.py +427 -0
- agentinputlab/evaluation/__init__.py +5 -0
- agentinputlab/evaluation/outcomes.py +32 -0
- agentinputlab/experiments/__init__.py +278 -0
- agentinputlab/experiments/analysis.py +981 -0
- agentinputlab/experiments/artifacts.py +687 -0
- agentinputlab/experiments/automatic_measurement.py +678 -0
- agentinputlab/experiments/auxiliary_matrix.py +203 -0
- agentinputlab/experiments/bindings.py +430 -0
- agentinputlab/experiments/blueprints.py +147 -0
- agentinputlab/experiments/builders/__init__.py +45 -0
- agentinputlab/experiments/builders/executable_external_payload.py +423 -0
- agentinputlab/experiments/builders/external_process_arena.py +1018 -0
- agentinputlab/experiments/builders/registry_intervention.py +463 -0
- agentinputlab/experiments/cli.py +158 -0
- agentinputlab/experiments/controls.py +340 -0
- agentinputlab/experiments/driver_guard.py +205 -0
- agentinputlab/experiments/drivers/__init__.py +89 -0
- agentinputlab/experiments/drivers/external_arena.py +2908 -0
- agentinputlab/experiments/drivers/method_process.py +662 -0
- agentinputlab/experiments/drivers/parity_process.py +1484 -0
- agentinputlab/experiments/drivers/static_production.py +1574 -0
- agentinputlab/experiments/executor.py +448 -0
- agentinputlab/experiments/loader.py +605 -0
- agentinputlab/experiments/measurement.py +675 -0
- agentinputlab/experiments/paper_analysis.py +1818 -0
- agentinputlab/experiments/parity_identity.py +605 -0
- agentinputlab/experiments/plan.py +277 -0
- agentinputlab/experiments/production_builders.py +3739 -0
- agentinputlab/experiments/readiness.py +432 -0
- agentinputlab/experiments/schema.py +514 -0
- agentinputlab/experiments/secrets.py +177 -0
- agentinputlab/experiments/stateful_analysis.py +1738 -0
- agentinputlab/experiments/transfer_analysis.py +1316 -0
- agentinputlab/experiments/unseen_analysis.py +1025 -0
- agentinputlab/integrations/__init__.py +1 -0
- agentinputlab/integrations/action_space/__init__.py +1 -0
- agentinputlab/integrations/external_workers/__init__.py +76 -0
- agentinputlab/integrations/external_workers/ace.py +431 -0
- agentinputlab/integrations/external_workers/base.py +181 -0
- agentinputlab/integrations/external_workers/decomp_live.py +249 -0
- agentinputlab/integrations/external_workers/decomp_planner.py +30 -0
- agentinputlab/integrations/external_workers/infocqr_student.py +280 -0
- agentinputlab/integrations/external_workers/ircot.py +576 -0
- agentinputlab/integrations/external_workers/llmcompiler_live.py +360 -0
- agentinputlab/integrations/external_workers/longllmlingua.py +162 -0
- agentinputlab/integrations/external_workers/method.py +314 -0
- agentinputlab/integrations/external_workers/process.py +678 -0
- agentinputlab/integrations/external_workers/supervisor.py +1071 -0
- agentinputlab/integrations/full_architecture/__init__.py +1 -0
- agentinputlab/integrations/full_architecture/hyde.py +212 -0
- agentinputlab/integrations/full_architecture/plan_and_budget.py +188 -0
- agentinputlab/integrations/live_history.py +222 -0
- agentinputlab/integrations/prompt_optimization/__init__.py +1 -0
- agentinputlab/integrations/training/__init__.py +1 -0
- agentinputlab/metrics/__init__.py +50 -0
- agentinputlab/metrics/catalog.py +313 -0
- agentinputlab/metrics/harm.py +95 -0
- agentinputlab/metrics/paired.py +40 -0
- agentinputlab/metrics/qa.py +76 -0
- agentinputlab/metrics/text.py +33 -0
- agentinputlab/metrics/third_party.py +161 -0
- agentinputlab/models/__init__.py +4 -0
- agentinputlab/observability/__init__.py +56 -0
- agentinputlab/observability/budget.py +316 -0
- agentinputlab/observability/instrumentation.py +754 -0
- agentinputlab/observability/models.py +403 -0
- agentinputlab/observability/monitor.py +380 -0
- agentinputlab/optimizers/__init__.py +1 -0
- agentinputlab/optimizers/clarify/__init__.py +12 -0
- agentinputlab/optimizers/context/__init__.py +22 -0
- agentinputlab/optimizers/decompose/__init__.py +64 -0
- agentinputlab/optimizers/evidence/__init__.py +22 -0
- agentinputlab/optimizers/rewrite/__init__.py +30 -0
- agentinputlab/parity/__init__.py +5 -0
- agentinputlab/parity/base.py +206 -0
- agentinputlab/production_campaign.py +763 -0
- agentinputlab/py.typed +1 -0
- agentinputlab/recipes/__init__.py +333 -0
- agentinputlab/recipes/ace.py +418 -0
- agentinputlab/recipes/ace_bfcl.py +273 -0
- agentinputlab/recipes/ace_common_support.py +169 -0
- agentinputlab/recipes/ace_native_plan.py +322 -0
- agentinputlab/recipes/ace_online.py +711 -0
- agentinputlab/recipes/ace_retrieval.py +330 -0
- agentinputlab/recipes/ace_statebench.py +382 -0
- agentinputlab/recipes/ace_tau.py +463 -0
- agentinputlab/recipes/ace_toolsandbox.py +432 -0
- agentinputlab/recipes/acon_guideline.py +22 -0
- agentinputlab/recipes/adaptive_rag.py +822 -0
- agentinputlab/recipes/llmlingua2_inference.py +146 -0
- agentinputlab/recipes/llmlingua2_training.py +796 -0
- agentinputlab/recipes/mce.py +1486 -0
- agentinputlab/recipes/mce_final.py +335 -0
- agentinputlab/recipes/mce_text_fit.py +499 -0
- agentinputlab/recipes/mce_text_only.py +298 -0
- agentinputlab/recipes/qrag.py +729 -0
- agentinputlab/recipes/qrag_inference.py +364 -0
- agentinputlab/recipes/r2ag_features.py +236 -0
- agentinputlab/recipes/r2ag_inference.py +503 -0
- agentinputlab/recipes/r2ag_training.py +948 -0
- agentinputlab/recipes/recomp_abstractive.py +592 -0
- agentinputlab/recipes/recomp_extractive.py +525 -0
- agentinputlab/recipes/reformer.py +17 -0
- agentinputlab/recipes/rqrag.py +1516 -0
- agentinputlab/recipes/rqrag_common_support.py +193 -0
- agentinputlab/recipes/rqrag_completion.py +147 -0
- agentinputlab/recipes/skillopt.py +462 -0
- agentinputlab/recipes/skillopt_common_support.py +154 -0
- agentinputlab/recipes/skillopt_environment.py +165 -0
- agentinputlab/recipes/skillopt_environment_cli.py +5 -0
- agentinputlab/recipes/skillopt_retrieval.py +188 -0
- agentinputlab/recipes/smartsearch.py +897 -0
- agentinputlab/recipes/smartsearch_curriculum.py +283 -0
- agentinputlab/recipes/smartsearch_grpo_contracts.py +58 -0
- agentinputlab/recipes/smartsearch_grpo_data.py +314 -0
- agentinputlab/recipes/smartsearch_grpo_meter.py +324 -0
- agentinputlab/recipes/smartsearch_grpo_prefix.py +144 -0
- agentinputlab/recipes/smartsearch_grpo_rollout.py +119 -0
- agentinputlab/recipes/smartsearch_grpo_tools.py +364 -0
- agentinputlab/recipes/smartsearch_grpo_training.py +305 -0
- agentinputlab/recipes/smartsearch_grpo_transport.py +248 -0
- agentinputlab/recipes/smartsearch_grpo_worker.py +364 -0
- agentinputlab/recipes/smartsearch_inference.py +524 -0
- agentinputlab/recipes/smartsearch_native_data.py +172 -0
- agentinputlab/recipes/smartsearch_policy.py +616 -0
- agentinputlab/recipes/smartsearch_policy_worker.py +9 -0
- agentinputlab/recipes/smartsearch_sampling.py +232 -0
- agentinputlab/recipes/smartsearch_teacher.py +203 -0
- agentinputlab/recipes/smartsearch_training.py +265 -0
- agentinputlab/registry/__init__.py +46 -0
- agentinputlab/registry/beta.py +727 -0
- agentinputlab/registry/data/algorithms.json +1959 -0
- agentinputlab/registry/data/auxiliary_method_profiles.json +34 -0
- agentinputlab/registry/loader.py +100 -0
- agentinputlab/registry/result_manifest.py +184 -0
- agentinputlab/registry/runtime.py +195 -0
- agentinputlab/registry/schema.py +449 -0
- agentinputlab/runner/__init__.py +30 -0
- agentinputlab/runner/balance.py +248 -0
- agentinputlab/runner/cache.py +135 -0
- agentinputlab/runner/composite.py +130 -0
- agentinputlab/runner/engine.py +285 -0
- agentinputlab/runner/runtime_guard.py +268 -0
- agentinputlab/runner/worker.py +80 -0
- agentinputlab/runtime_bootstrap.py +288 -0
- agentinputlab/selectors/__init__.py +196 -0
- agentinputlab/selectors/advanced.py +1514 -0
- agentinputlab/selectors/artifacts.py +1087 -0
- agentinputlab/selectors/base.py +112 -0
- agentinputlab/selectors/campaigns.py +1893 -0
- agentinputlab/selectors/catalog.py +86 -0
- agentinputlab/selectors/discovery.py +1860 -0
- agentinputlab/selectors/evaluation.py +1348 -0
- agentinputlab/selectors/features.py +383 -0
- agentinputlab/selectors/learned.py +502 -0
- agentinputlab/selectors/no_op.py +28 -0
- agentinputlab/selectors/outcome_table.py +475 -0
- agentinputlab/selectors/producer.py +853 -0
- agentinputlab/selectors/rules.py +109 -0
- agentinputlab/selectors/runtime.py +420 -0
- agentinputlab/studies/__init__.py +16 -0
- agentinputlab/studies/design.py +165 -0
- agentinputlab/studies/paired.py +322 -0
- agentinputlab/studio/__init__.py +6 -0
- agentinputlab/studio/campaigns.py +819 -0
- agentinputlab/studio/engine.py +1408 -0
- agentinputlab/studio/model_backends.py +425 -0
- agentinputlab/studio/prepared.py +410 -0
- agentinputlab/studio/server.py +613 -0
- agentinputlab/studio/static/app.js +397 -0
- agentinputlab/studio/static/campaigns.html +175 -0
- agentinputlab/studio/static/campaigns.js +426 -0
- agentinputlab/studio/static/index.html +192 -0
- agentinputlab/studio/static/result.html +103 -0
- agentinputlab/studio/static/result.js +273 -0
- agentinputlab/studio/static/styles.css +467 -0
- agentinputlab-0.1.0a1.data/data/share/agentinputlab/CITATION.cff +22 -0
- agentinputlab-0.1.0a1.dist-info/METADATA +392 -0
- agentinputlab-0.1.0a1.dist-info/RECORD +469 -0
- agentinputlab-0.1.0a1.dist-info/WHEEL +5 -0
- agentinputlab-0.1.0a1.dist-info/entry_points.txt +6 -0
- agentinputlab-0.1.0a1.dist-info/licenses/LICENSE +21 -0
- agentinputlab-0.1.0a1.dist-info/licenses/NOTICE +31 -0
- agentinputlab-0.1.0a1.dist-info/licenses/THIRD_PARTY_NOTICES.md +94 -0
- agentinputlab-0.1.0a1.dist-info/top_level.txt +2 -0
- workers/README.md +94 -0
- workers/ace/README.md +261 -0
- workers/ace/__init__.py +1 -0
- workers/ace/compatibility_manifest.json +39 -0
- workers/ace/driver.py +1682 -0
- workers/acon/README.md +215 -0
- workers/acon/__init__.py +5 -0
- workers/acon/compatibility_manifest.json +93 -0
- workers/acon/driver.py +1859 -0
- workers/acon/fitted.py +395 -0
- workers/acon/guideline.py +470 -0
- workers/acon/guideline_source_manifest.json +20 -0
- workers/adaptive_rag/README.md +96 -0
- workers/adaptive_rag/__init__.py +15 -0
- workers/adaptive_rag/compatibility_manifest.json +61 -0
- workers/adaptive_rag/driver.py +1470 -0
- workers/adaptive_rag/fixture_runtime.py +163 -0
- workers/adaptive_rag/runtime.py +252 -0
- workers/ask_or_assume/README.md +124 -0
- workers/ask_or_assume/__init__.py +1 -0
- workers/ask_or_assume/compatibility_manifest.json +36 -0
- workers/ask_or_assume/driver.py +1227 -0
- workers/decomp/README.md +133 -0
- workers/decomp/UPSTREAM_LICENSE.Apache-2.0.txt +201 -0
- workers/decomp/__init__.py +5 -0
- workers/decomp/compatibility_manifest.json +205 -0
- workers/decomp/driver.py +1015 -0
- workers/decomp/live.py +137 -0
- workers/decomp/runtime.py +231 -0
- workers/infocqr/README.md +106 -0
- workers/infocqr/__init__.py +1 -0
- workers/infocqr/compatibility_manifest.json +84 -0
- workers/infocqr/driver.py +1766 -0
- workers/ircot/README.md +167 -0
- workers/ircot/__init__.py +7 -0
- workers/ircot/compatibility_manifest.json +121 -0
- workers/ircot/controlled.py +457 -0
- workers/ircot/driver.py +1373 -0
- workers/ircot/fixture_bindings.json +39 -0
- workers/ircot/fixture_config.json +48 -0
- workers/ircot/fixture_prompt.txt +2 -0
- workers/ircot/native_qa.py +398 -0
- workers/ircot/qa_compatibility_manifest.json +57 -0
- workers/ircot/runtime.py +97 -0
- workers/llmcompiler/README.md +160 -0
- workers/llmcompiler/__init__.py +1 -0
- workers/llmcompiler/compatibility_manifest.json +45 -0
- workers/llmcompiler/driver.py +1514 -0
- workers/llmcompiler/export_prompts.py +74 -0
- workers/llmcompiler/live.py +174 -0
- workers/llmcompiler/patch_manifest.json +147 -0
- workers/mce/README.md +198 -0
- workers/mce/__init__.py +29 -0
- workers/mce/compatibility_manifest.json +115 -0
- workers/mce/driver.py +2585 -0
- workers/mce/final_eval.py +173 -0
- workers/official_arenas/README.md +25 -0
- workers/official_arenas/__init__.py +1 -0
- workers/official_arenas/capture_records.py +110 -0
- workers/official_arenas/driver.py +619 -0
- workers/official_arenas/protocol.py +334 -0
- workers/official_arenas/providers/__init__.py +1 -0
- workers/official_arenas/providers/_live_history.py +228 -0
- workers/official_arenas/providers/_message_compat.py +77 -0
- workers/official_arenas/providers/appworld_ul.py +196 -0
- workers/official_arenas/providers/fixture.py +112 -0
- workers/official_arenas/providers/statebench.py +960 -0
- workers/official_arenas/providers/tau3.py +1672 -0
- workers/official_arenas/providers/tau_retail.py +586 -0
- workers/official_arenas/providers/toolsandbox.py +1321 -0
- workers/official_arenas/providers/tooltalk.py +699 -0
- workers/official_arenas/retail_capture.py +188 -0
- workers/official_arenas/retail_driver.py +275 -0
- workers/qrag/README.md +172 -0
- workers/qrag/__init__.py +1 -0
- workers/qrag/compatibility_manifest.json +64 -0
- workers/qrag/driver.py +673 -0
- workers/r2ag/README.md +154 -0
- workers/r2ag/__init__.py +5 -0
- workers/r2ag/compatibility_manifest.json +55 -0
- workers/r2ag/driver.py +1287 -0
- workers/r2ag/feature_schema.json +8 -0
- workers/r2ag/runtime.py +589 -0
- workers/recomp/README.md +120 -0
- workers/recomp/__init__.py +1 -0
- workers/recomp/compatibility_manifest.json +43 -0
- workers/recomp/driver.py +1653 -0
- workers/reformer/README.md +125 -0
- workers/reformer/__init__.py +1 -0
- workers/reformer/compatibility_manifest.json +68 -0
- workers/reformer/driver.py +1459 -0
- workers/reformer/induction.py +457 -0
- workers/rrr/README.md +126 -0
- workers/rrr/__init__.py +1 -0
- workers/rrr/compatibility_manifest.json +57 -0
- workers/rrr/driver.py +1133 -0
- workers/smartsearch/README.md +331 -0
- workers/smartsearch/__init__.py +1 -0
- workers/smartsearch/compatibility_manifest.json +41 -0
- workers/smartsearch/driver.py +1643 -0
workers/rrr/driver.py
ADDED
|
@@ -0,0 +1,1133 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Quarantined pinned-source inference worker for Rewrite-Retrieve-Read.
|
|
3
|
+
|
|
4
|
+
The unlicensed upstream tarball is verified and security-scanned but never
|
|
5
|
+
extracted or imported. Inference follows the audited rewrite -> retrieve ->
|
|
6
|
+
snippet -> frozen-reader trajectory using user-mounted prompts, search artifacts,
|
|
7
|
+
and checkpoints. PPO checkpoints are inference-only; this worker cannot train.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import ast
|
|
14
|
+
import hashlib
|
|
15
|
+
import importlib
|
|
16
|
+
import json
|
|
17
|
+
import math
|
|
18
|
+
import re
|
|
19
|
+
import subprocess
|
|
20
|
+
import sys
|
|
21
|
+
import tarfile
|
|
22
|
+
from collections.abc import Mapping, Sequence
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from pathlib import Path, PurePosixPath
|
|
25
|
+
from typing import Any, Protocol
|
|
26
|
+
|
|
27
|
+
UPSTREAM_COMMIT = "6bab6243e60c7f3e526b6ee44f95381b1024d471"
|
|
28
|
+
METHOD_ID = "rrr"
|
|
29
|
+
RELEASE_IDS = {
|
|
30
|
+
"prompt": "rewrite.rrr.prompt_external",
|
|
31
|
+
"warmup_checkpoint": "rewrite.rrr.warmup_external",
|
|
32
|
+
"ppo_checkpoint": "rewrite.rrr.ppo_external",
|
|
33
|
+
}
|
|
34
|
+
PROTOCOL_VERSION = "agentinputlab.rrr.inference.v2"
|
|
35
|
+
MANIFEST_SCHEMA = "agentinputlab.rrr.compatibility.v1"
|
|
36
|
+
CHECKPOINT_SCHEMA = "agentinputlab.rrr.checkpoint.v1"
|
|
37
|
+
SEARCH_SCHEMA = "agentinputlab.rrr.search-cache.v1"
|
|
38
|
+
DEFAULT_MANIFEST = Path(__file__).with_name("compatibility_manifest.json")
|
|
39
|
+
DEFAULT_MANIFEST_SHA256 = "83cb80359eadbed1b8d115e60f22a7dd26f16424aa71ff1f37350ba40ef953ff"
|
|
40
|
+
DRIVER_ID = "agentinputlab.rrr.quarantined.v1"
|
|
41
|
+
MAX_REQUEST_BYTES = 8 * 1024 * 1024
|
|
42
|
+
MAX_SOURCE_BYTES = 128 * 1024 * 1024
|
|
43
|
+
MAX_MEMBER_BYTES = 8 * 1024 * 1024
|
|
44
|
+
MAX_TEXT_CHARS = 2_000_000
|
|
45
|
+
_HEX64 = re.compile(r"^[0-9a-f]{64}$")
|
|
46
|
+
_DATE = re.compile(r"^(?:|[0-9]{4}-[0-9]{2}-[0-9]{2})$")
|
|
47
|
+
_CREDENTIAL_ASSIGNMENT = re.compile(
|
|
48
|
+
rb"(?i)(?:api[_-]?key|subscription[_-]?key|authorization|bearer|azure|"
|
|
49
|
+
rb"client[_-]?secret|password)\s*[:=]"
|
|
50
|
+
)
|
|
51
|
+
_ROOT_FIELDS = frozenset(
|
|
52
|
+
{
|
|
53
|
+
"method_id",
|
|
54
|
+
"release_id",
|
|
55
|
+
"upstream_commit",
|
|
56
|
+
"state_hash",
|
|
57
|
+
"payload",
|
|
58
|
+
"dependency_fingerprints",
|
|
59
|
+
"minimum_reservation",
|
|
60
|
+
"protocol_version",
|
|
61
|
+
"request_id",
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
_PAYLOAD_FIELDS = frozenset(
|
|
65
|
+
{
|
|
66
|
+
"task_id",
|
|
67
|
+
"query",
|
|
68
|
+
"instruction",
|
|
69
|
+
"messages",
|
|
70
|
+
"controls",
|
|
71
|
+
"prompt_hash",
|
|
72
|
+
"reader_prompt_hash",
|
|
73
|
+
"search_artifact_hash",
|
|
74
|
+
"corpus_revision",
|
|
75
|
+
"index_revision",
|
|
76
|
+
"rewriter_checkpoint_revision",
|
|
77
|
+
"reader_checkpoint_revision",
|
|
78
|
+
"source_license_acknowledged",
|
|
79
|
+
"checkpoint_license_acknowledged",
|
|
80
|
+
"backend_artifact_hash",
|
|
81
|
+
"retriever_artifact_hash",
|
|
82
|
+
"input_artifact_hash",
|
|
83
|
+
"seed",
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
_CONTROL_FIELDS = frozenset(
|
|
87
|
+
{
|
|
88
|
+
"max_queries",
|
|
89
|
+
"top_k",
|
|
90
|
+
"query_parser",
|
|
91
|
+
"search_mode",
|
|
92
|
+
"rewriter_profile",
|
|
93
|
+
"search_window_start",
|
|
94
|
+
"search_window_end",
|
|
95
|
+
"max_rewriter_tokens",
|
|
96
|
+
"max_reader_tokens",
|
|
97
|
+
"max_input_chars",
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
_WEIGHT_SUFFIXES = (".bin", ".pt", ".pth", ".safetensors")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class DriverError(RuntimeError):
|
|
104
|
+
"""Stable error that never includes source or credential contents."""
|
|
105
|
+
|
|
106
|
+
def __init__(
|
|
107
|
+
self,
|
|
108
|
+
code: str,
|
|
109
|
+
message: str,
|
|
110
|
+
*,
|
|
111
|
+
consumed: bool = False,
|
|
112
|
+
usage: Mapping[str, int] | None = None,
|
|
113
|
+
) -> None:
|
|
114
|
+
super().__init__(message)
|
|
115
|
+
self.code = code
|
|
116
|
+
self.public_message = message
|
|
117
|
+
self.consumed = consumed
|
|
118
|
+
self.usage = dict(usage) if usage is not None else None
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass(frozen=True, slots=True)
|
|
122
|
+
class SourceEvidence:
|
|
123
|
+
manifest_sha256: str
|
|
124
|
+
evidence_level: str
|
|
125
|
+
credential_risk_count: int
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@dataclass(frozen=True, slots=True)
|
|
129
|
+
class Generation:
|
|
130
|
+
text: str
|
|
131
|
+
input_tokens: int
|
|
132
|
+
output_tokens: int
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@dataclass(frozen=True, slots=True)
|
|
136
|
+
class SearchDocument:
|
|
137
|
+
document_id: str
|
|
138
|
+
title: str
|
|
139
|
+
text: str
|
|
140
|
+
score: float
|
|
141
|
+
metadata: Mapping[str, Any]
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class Generator(Protocol):
|
|
145
|
+
def generate(self, prompt: str, *, seed: int, max_tokens: int) -> Generation: ...
|
|
146
|
+
|
|
147
|
+
def fingerprint(self) -> Mapping[str, Any]: ...
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class Searcher(Protocol):
|
|
151
|
+
def search(
|
|
152
|
+
self,
|
|
153
|
+
query: str,
|
|
154
|
+
*,
|
|
155
|
+
top_k: int,
|
|
156
|
+
window_start: str,
|
|
157
|
+
window_end: str,
|
|
158
|
+
) -> tuple[SearchDocument, ...]: ...
|
|
159
|
+
|
|
160
|
+
def fingerprint(self) -> Mapping[str, Any]: ...
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _canonical_json(value: Any) -> str:
|
|
164
|
+
return json.dumps(
|
|
165
|
+
value,
|
|
166
|
+
ensure_ascii=False,
|
|
167
|
+
sort_keys=True,
|
|
168
|
+
separators=(",", ":"),
|
|
169
|
+
allow_nan=False,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _sha_bytes(value: bytes) -> str:
|
|
174
|
+
return hashlib.sha256(value).hexdigest()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _content_hash(value: Any) -> str:
|
|
178
|
+
return _sha_bytes(_canonical_json(value).encode("utf-8"))
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _sha_file(path: Path, *, limit: int) -> str:
|
|
182
|
+
if path.is_symlink() or not path.is_file():
|
|
183
|
+
raise DriverError("ARTIFACT_INVALID", "artifact must be a regular non-symlink file")
|
|
184
|
+
if path.stat().st_size > limit:
|
|
185
|
+
raise DriverError("ARTIFACT_TOO_LARGE", "artifact exceeds its byte limit")
|
|
186
|
+
digest = hashlib.sha256()
|
|
187
|
+
with path.open("rb") as handle:
|
|
188
|
+
while chunk := handle.read(1024 * 1024):
|
|
189
|
+
digest.update(chunk)
|
|
190
|
+
return digest.hexdigest()
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _read_bytes(path: Path, *, label: str, limit: int = MAX_MEMBER_BYTES) -> bytes:
|
|
194
|
+
if path.is_symlink() or not path.is_file():
|
|
195
|
+
raise DriverError("ARTIFACT_INVALID", f"{label} must be a regular non-symlink file")
|
|
196
|
+
if path.stat().st_size > limit:
|
|
197
|
+
raise DriverError("ARTIFACT_TOO_LARGE", f"{label} exceeds its byte limit")
|
|
198
|
+
try:
|
|
199
|
+
return path.read_bytes()
|
|
200
|
+
except OSError as exc:
|
|
201
|
+
raise DriverError("ARTIFACT_INVALID", f"{label} is unreadable") from exc
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _load_json(path: Path, *, label: str) -> tuple[Mapping[str, Any], str]:
|
|
205
|
+
raw = _read_bytes(path, label=label)
|
|
206
|
+
try:
|
|
207
|
+
value = json.loads(raw)
|
|
208
|
+
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
|
|
209
|
+
raise DriverError("ARTIFACT_INVALID", f"{label} is not valid UTF-8 JSON") from exc
|
|
210
|
+
if not isinstance(value, Mapping):
|
|
211
|
+
raise DriverError("ARTIFACT_INVALID", f"{label} must contain an object")
|
|
212
|
+
return value, _sha_bytes(raw)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _sha(value: Any, *, label: str) -> str:
|
|
216
|
+
if not isinstance(value, str) or not _HEX64.fullmatch(value):
|
|
217
|
+
raise DriverError("INVALID_REQUEST", f"{label} must be a SHA-256 digest")
|
|
218
|
+
return value
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def _text(value: Any, *, label: str, allow_empty: bool = False) -> str:
|
|
222
|
+
if not isinstance(value, str) or (not allow_empty and not value.strip()):
|
|
223
|
+
raise DriverError("INVALID_REQUEST", f"{label} must be text")
|
|
224
|
+
if len(value) > MAX_TEXT_CHARS:
|
|
225
|
+
raise DriverError("INVALID_REQUEST", f"{label} exceeds its character limit")
|
|
226
|
+
return value
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def _positive_int(value: Any, *, label: str) -> int:
|
|
230
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 1:
|
|
231
|
+
raise DriverError("INVALID_REQUEST", f"{label} must be positive")
|
|
232
|
+
return value
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _nonnegative_int(value: Any, *, label: str) -> int:
|
|
236
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 0:
|
|
237
|
+
raise DriverError("INVALID_REQUEST", f"{label} must be non-negative")
|
|
238
|
+
return value
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _safe_member(name: str, root: str) -> str:
|
|
242
|
+
path = PurePosixPath(name)
|
|
243
|
+
if path.is_absolute() or ".." in path.parts or not path.parts or path.parts[0] != root:
|
|
244
|
+
raise DriverError("SOURCE_ARCHIVE_UNSAFE", "source archive contains an unsafe path")
|
|
245
|
+
relative = PurePosixPath(*path.parts[1:])
|
|
246
|
+
if not relative.parts:
|
|
247
|
+
return ""
|
|
248
|
+
return str(relative)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _validate_manifest(value: Mapping[str, Any]) -> None:
|
|
252
|
+
expected = {
|
|
253
|
+
"schema_version",
|
|
254
|
+
"evidence_level",
|
|
255
|
+
"upstream",
|
|
256
|
+
"source_files",
|
|
257
|
+
"required_symbols",
|
|
258
|
+
"credential_risk_paths",
|
|
259
|
+
"runtime_contract",
|
|
260
|
+
"artifact_policy",
|
|
261
|
+
}
|
|
262
|
+
if set(value) != expected or value.get("schema_version") != MANIFEST_SCHEMA:
|
|
263
|
+
raise DriverError("MANIFEST_INVALID", "RRR compatibility manifest schema mismatch")
|
|
264
|
+
if value.get("evidence_level") not in {
|
|
265
|
+
"pinned_tarball_compatible_chain",
|
|
266
|
+
"fake_checkout_plumbing",
|
|
267
|
+
}:
|
|
268
|
+
raise DriverError("MANIFEST_INVALID", "RRR evidence level is invalid")
|
|
269
|
+
upstream = value.get("upstream")
|
|
270
|
+
if not isinstance(upstream, Mapping) or upstream.get("commit") != UPSTREAM_COMMIT:
|
|
271
|
+
raise DriverError("MANIFEST_INVALID", "RRR upstream revision mismatch")
|
|
272
|
+
if (
|
|
273
|
+
upstream.get("license_spdx") != "NOASSERTION"
|
|
274
|
+
or upstream.get("license_file_present") is not False
|
|
275
|
+
):
|
|
276
|
+
raise DriverError("MANIFEST_INVALID", "RRR license must remain absent/NOASSERTION")
|
|
277
|
+
_sha(upstream.get("tarball_sha256"), label="upstream tarball hash")
|
|
278
|
+
root = _text(upstream.get("archive_root"), label="archive_root")
|
|
279
|
+
if "/" in root or root in {".", ".."}:
|
|
280
|
+
raise DriverError("MANIFEST_INVALID", "RRR archive root is invalid")
|
|
281
|
+
files = value.get("source_files")
|
|
282
|
+
symbols = value.get("required_symbols")
|
|
283
|
+
risks = value.get("credential_risk_paths")
|
|
284
|
+
if not isinstance(files, Mapping) or not isinstance(symbols, Mapping):
|
|
285
|
+
raise DriverError("MANIFEST_INVALID", "RRR source evidence is invalid")
|
|
286
|
+
for relative, digest in files.items():
|
|
287
|
+
if not isinstance(relative, str) or not relative or ".." in PurePosixPath(relative).parts:
|
|
288
|
+
raise DriverError("MANIFEST_INVALID", "RRR source path is invalid")
|
|
289
|
+
_sha(digest, label="source hash")
|
|
290
|
+
if not set(symbols) <= set(files):
|
|
291
|
+
raise DriverError("MANIFEST_INVALID", "RRR symbol source is not hash-bound")
|
|
292
|
+
if not isinstance(risks, Sequence) or isinstance(risks, (str, bytes)):
|
|
293
|
+
raise DriverError("MANIFEST_INVALID", "RRR credential-risk paths are invalid")
|
|
294
|
+
if not all(isinstance(path, str) and path.endswith(".py") for path in risks):
|
|
295
|
+
raise DriverError("MANIFEST_INVALID", "RRR credential-risk path is invalid")
|
|
296
|
+
contract = value.get("runtime_contract")
|
|
297
|
+
if not isinstance(contract, Mapping) or contract != {
|
|
298
|
+
"stage_order": ["rewrite", "retrieve", "snippet", "reader"],
|
|
299
|
+
"query_separator": ";",
|
|
300
|
+
"generation_terminator": "**",
|
|
301
|
+
"search_wrapper": "search[{query}]",
|
|
302
|
+
"snippet_joiner": " ",
|
|
303
|
+
"supported_rewriter_profiles": [
|
|
304
|
+
"prompt",
|
|
305
|
+
"warmup_checkpoint",
|
|
306
|
+
"ppo_checkpoint",
|
|
307
|
+
],
|
|
308
|
+
"supported_search_modes": ["bing_cache", "controlled_static"],
|
|
309
|
+
"imports_upstream_runtime": False,
|
|
310
|
+
"trains_ppo": False,
|
|
311
|
+
}:
|
|
312
|
+
raise DriverError("MANIFEST_INVALID", "RRR runtime contract drifted")
|
|
313
|
+
if value.get("artifact_policy") != {
|
|
314
|
+
"checkpoint_license": "NOASSERTION",
|
|
315
|
+
"bundle_source": False,
|
|
316
|
+
"bundle_checkpoints": False,
|
|
317
|
+
"bundle_search_cache": False,
|
|
318
|
+
"local_files_only": True,
|
|
319
|
+
"trust_remote_code": False,
|
|
320
|
+
}:
|
|
321
|
+
raise DriverError("MANIFEST_INVALID", "RRR artifact policy drifted")
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def verify_source_tarball(
|
|
325
|
+
path: Path,
|
|
326
|
+
*,
|
|
327
|
+
manifest_path: Path = DEFAULT_MANIFEST,
|
|
328
|
+
allow_fixture_manifest: bool = False,
|
|
329
|
+
) -> SourceEvidence:
|
|
330
|
+
manifest, manifest_hash = _load_json(manifest_path, label="RRR compatibility manifest")
|
|
331
|
+
if not allow_fixture_manifest and manifest_hash != DEFAULT_MANIFEST_SHA256:
|
|
332
|
+
raise DriverError("WORKER_INTEGRITY_FAILURE", "RRR compatibility manifest hash mismatch")
|
|
333
|
+
_validate_manifest(manifest)
|
|
334
|
+
upstream = manifest["upstream"]
|
|
335
|
+
assert isinstance(upstream, Mapping)
|
|
336
|
+
if _sha_file(path, limit=MAX_SOURCE_BYTES) != upstream["tarball_sha256"]:
|
|
337
|
+
raise DriverError("SOURCE_ARCHIVE_MISMATCH", "RRR source tarball hash mismatch")
|
|
338
|
+
archive_root = str(upstream["archive_root"])
|
|
339
|
+
files = manifest["source_files"]
|
|
340
|
+
symbols = manifest["required_symbols"]
|
|
341
|
+
expected_risks = set(manifest["credential_risk_paths"])
|
|
342
|
+
assert isinstance(files, Mapping) and isinstance(symbols, Mapping)
|
|
343
|
+
seen: set[str] = set()
|
|
344
|
+
risks: set[str] = set()
|
|
345
|
+
license_files: set[str] = set()
|
|
346
|
+
try:
|
|
347
|
+
with tarfile.open(path, mode="r:gz") as archive:
|
|
348
|
+
members = archive.getmembers()
|
|
349
|
+
for member in members:
|
|
350
|
+
relative = _safe_member(member.name, archive_root)
|
|
351
|
+
if member.issym() or member.islnk() or member.isdev():
|
|
352
|
+
raise DriverError(
|
|
353
|
+
"SOURCE_ARCHIVE_UNSAFE", "RRR source archive contains a link/device"
|
|
354
|
+
)
|
|
355
|
+
if relative and PurePosixPath(relative).name.lower() in {
|
|
356
|
+
"license",
|
|
357
|
+
"license.md",
|
|
358
|
+
"license.txt",
|
|
359
|
+
"copying",
|
|
360
|
+
"notice",
|
|
361
|
+
}:
|
|
362
|
+
license_files.add(relative)
|
|
363
|
+
if not member.isfile():
|
|
364
|
+
continue
|
|
365
|
+
if relative in seen:
|
|
366
|
+
raise DriverError("SOURCE_ARCHIVE_UNSAFE", "RRR archive has duplicate paths")
|
|
367
|
+
seen.add(relative)
|
|
368
|
+
if member.size > MAX_MEMBER_BYTES and (
|
|
369
|
+
relative in files or relative.endswith(".py")
|
|
370
|
+
):
|
|
371
|
+
raise DriverError("SOURCE_ARCHIVE_UNSAFE", "RRR source member is too large")
|
|
372
|
+
if relative in files or relative.endswith(".py"):
|
|
373
|
+
handle = archive.extractfile(member)
|
|
374
|
+
if handle is None:
|
|
375
|
+
raise DriverError(
|
|
376
|
+
"SOURCE_ARCHIVE_INVALID", "RRR source member is unreadable"
|
|
377
|
+
)
|
|
378
|
+
raw = handle.read(MAX_MEMBER_BYTES + 1)
|
|
379
|
+
if len(raw) > MAX_MEMBER_BYTES:
|
|
380
|
+
raise DriverError("SOURCE_ARCHIVE_UNSAFE", "RRR source member is too large")
|
|
381
|
+
if relative in files and _sha_bytes(raw) != files[relative]:
|
|
382
|
+
raise DriverError(
|
|
383
|
+
"SOURCE_FILE_MISMATCH", f"RRR source hash mismatch: {relative}"
|
|
384
|
+
)
|
|
385
|
+
if relative.endswith(".py") and _CREDENTIAL_ASSIGNMENT.search(raw):
|
|
386
|
+
risks.add(relative)
|
|
387
|
+
if relative in symbols:
|
|
388
|
+
try:
|
|
389
|
+
tree = ast.parse(raw.decode("utf-8"), filename=relative)
|
|
390
|
+
except (UnicodeDecodeError, SyntaxError) as exc:
|
|
391
|
+
raise DriverError(
|
|
392
|
+
"SOURCE_SYMBOL_MISMATCH", "RRR source AST is invalid"
|
|
393
|
+
) from exc
|
|
394
|
+
names = {
|
|
395
|
+
node.name
|
|
396
|
+
for node in tree.body
|
|
397
|
+
if isinstance(
|
|
398
|
+
node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)
|
|
399
|
+
)
|
|
400
|
+
}
|
|
401
|
+
required = symbols[relative]
|
|
402
|
+
if not isinstance(required, Sequence) or not set(required) <= names:
|
|
403
|
+
raise DriverError(
|
|
404
|
+
"SOURCE_SYMBOL_MISMATCH", "RRR required source symbol is absent"
|
|
405
|
+
)
|
|
406
|
+
except DriverError:
|
|
407
|
+
raise
|
|
408
|
+
except (OSError, tarfile.TarError) as exc:
|
|
409
|
+
raise DriverError("SOURCE_ARCHIVE_INVALID", "RRR source tarball is invalid") from exc
|
|
410
|
+
if license_files:
|
|
411
|
+
raise DriverError("LICENSE_STATUS_DRIFT", "RRR source unexpectedly contains a license file")
|
|
412
|
+
if not set(files) <= seen:
|
|
413
|
+
raise DriverError("SOURCE_FILE_MISSING", "RRR source tarball omits audited files")
|
|
414
|
+
if risks != expected_risks:
|
|
415
|
+
raise DriverError(
|
|
416
|
+
"CREDENTIAL_SCAN_DRIFT",
|
|
417
|
+
"RRR credential-risk scan changed; values are intentionally redacted",
|
|
418
|
+
)
|
|
419
|
+
return SourceEvidence(
|
|
420
|
+
manifest_sha256=manifest_hash,
|
|
421
|
+
evidence_level=str(manifest["evidence_level"]),
|
|
422
|
+
credential_risk_count=len(risks),
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def _git_read(root: Path, *arguments: str) -> str:
|
|
427
|
+
try:
|
|
428
|
+
result = subprocess.run(
|
|
429
|
+
["git", "--no-pager", "--no-optional-locks", "--no-replace-objects", "-C", str(root), *arguments],
|
|
430
|
+
capture_output=True, text=True, timeout=20, check=False,
|
|
431
|
+
)
|
|
432
|
+
except (OSError, subprocess.SubprocessError) as exc:
|
|
433
|
+
raise DriverError("SOURCE_CHECKOUT_INVALID", "RRR pinned checkout metadata is unavailable") from exc
|
|
434
|
+
if result.returncode or len(result.stdout.encode()) > 4 * 1024 * 1024:
|
|
435
|
+
raise DriverError("SOURCE_CHECKOUT_INVALID", "RRR pinned checkout metadata is invalid")
|
|
436
|
+
return result.stdout
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
def verify_source_checkout(
|
|
440
|
+
root: Path, *, manifest_path: Path = DEFAULT_MANIFEST, allow_fixture_manifest: bool = False,
|
|
441
|
+
) -> SourceEvidence:
|
|
442
|
+
"""Verify pinned executable source without importing it or reading datasets.
|
|
443
|
+
|
|
444
|
+
Required files retain the shipped SHA-256 locks; every tracked Python file
|
|
445
|
+
matches its blob at the pinned commit and the credential-risk inventory.
|
|
446
|
+
This explicit source mode does not claim the complete archive checksum.
|
|
447
|
+
"""
|
|
448
|
+
if root.is_symlink() or not root.is_dir():
|
|
449
|
+
raise DriverError("SOURCE_CHECKOUT_INVALID", "RRR source checkout must be a regular directory")
|
|
450
|
+
root = root.resolve()
|
|
451
|
+
manifest, manifest_hash = _load_json(manifest_path, label="RRR compatibility manifest")
|
|
452
|
+
if not allow_fixture_manifest and manifest_hash != DEFAULT_MANIFEST_SHA256:
|
|
453
|
+
raise DriverError("WORKER_INTEGRITY_FAILURE", "RRR compatibility manifest hash mismatch")
|
|
454
|
+
_validate_manifest(manifest)
|
|
455
|
+
if _git_read(root, "rev-parse", "HEAD").strip() != UPSTREAM_COMMIT or (
|
|
456
|
+
Path(_git_read(root, "rev-parse", "--show-toplevel").strip()).resolve() != root
|
|
457
|
+
):
|
|
458
|
+
raise DriverError("SOURCE_CHECKOUT_MISMATCH", "RRR checkout commit/root differs")
|
|
459
|
+
entries = _git_read(root, "ls-tree", "-r", "--full-tree", "-z", "HEAD").split("\0")
|
|
460
|
+
if len(entries) > 10000:
|
|
461
|
+
raise DriverError("SOURCE_CHECKOUT_INVALID", "RRR source tree exceeds its bounded file inventory")
|
|
462
|
+
seen, risks, total_bytes = set(), set(), 0
|
|
463
|
+
required = manifest["source_files"]
|
|
464
|
+
for entry in filter(None, entries):
|
|
465
|
+
try:
|
|
466
|
+
metadata, name = entry.split("\t", 1)
|
|
467
|
+
mode, kind, blob = metadata.split()
|
|
468
|
+
except ValueError as exc:
|
|
469
|
+
raise DriverError("SOURCE_CHECKOUT_INVALID", "RRR Git source inventory is malformed") from exc
|
|
470
|
+
relative = _safe_member("tree/" + name, "tree")
|
|
471
|
+
if relative in seen or mode not in {"100644", "100755"} or kind != "blob":
|
|
472
|
+
raise DriverError("SOURCE_CHECKOUT_INVALID", "RRR Git source inventory contains a link or duplicate")
|
|
473
|
+
seen.add(relative)
|
|
474
|
+
if PurePosixPath(relative).name.lower() in {"license", "license.md", "license.txt", "copying", "notice"}:
|
|
475
|
+
raise DriverError("LICENSE_STATUS_DRIFT", "RRR source unexpectedly contains a license file")
|
|
476
|
+
if relative not in required and not relative.endswith(".py"):
|
|
477
|
+
continue
|
|
478
|
+
path = root / relative
|
|
479
|
+
if path.is_symlink() or not path.is_file() or path.stat().st_size > MAX_MEMBER_BYTES:
|
|
480
|
+
raise DriverError("SOURCE_FILE_MISMATCH", "RRR tracked source file is missing, linked or too large")
|
|
481
|
+
if not path.resolve().is_relative_to(root):
|
|
482
|
+
raise DriverError("SOURCE_FILE_MISMATCH", "RRR tracked source escaped its checkout")
|
|
483
|
+
raw = path.read_bytes()
|
|
484
|
+
total_bytes += len(raw)
|
|
485
|
+
if total_bytes > 64 * 1024 * 1024:
|
|
486
|
+
raise DriverError("SOURCE_ARCHIVE_UNSAFE", "RRR executable-source review exceeds its byte cap")
|
|
487
|
+
if hashlib.sha1(f"blob {len(raw)}\0".encode() + raw).hexdigest() != blob:
|
|
488
|
+
raise DriverError("SOURCE_FILE_MISMATCH", "RRR tracked source differs from its pinned Git blob")
|
|
489
|
+
if relative in required and _sha_bytes(raw) != required[relative]:
|
|
490
|
+
raise DriverError("SOURCE_FILE_MISMATCH", f"RRR source hash mismatch: {relative}")
|
|
491
|
+
if relative.endswith(".py") and _CREDENTIAL_ASSIGNMENT.search(raw):
|
|
492
|
+
risks.add(relative)
|
|
493
|
+
if relative in manifest["required_symbols"]:
|
|
494
|
+
try:
|
|
495
|
+
tree = ast.parse(raw.decode("utf-8"), filename=relative)
|
|
496
|
+
except (UnicodeDecodeError, SyntaxError) as exc:
|
|
497
|
+
raise DriverError("SOURCE_SYMBOL_MISMATCH", "RRR source AST is invalid") from exc
|
|
498
|
+
names = {n.name for n in tree.body if isinstance(n, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef))}
|
|
499
|
+
if not set(manifest["required_symbols"][relative]) <= names:
|
|
500
|
+
raise DriverError("SOURCE_SYMBOL_MISMATCH", "RRR required source symbol is absent")
|
|
501
|
+
if not set(required) <= seen or risks != set(manifest["credential_risk_paths"]):
|
|
502
|
+
raise DriverError("CREDENTIAL_SCAN_DRIFT", "RRR source/risk inventory changed; values are redacted")
|
|
503
|
+
return SourceEvidence(manifest_hash,
|
|
504
|
+
"fake_checkout_plumbing" if allow_fixture_manifest else "pinned_checkout_compatible_chain", len(risks))
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
def verify_checkpoint(root: Path, manifest_path: Path) -> Mapping[str, Any]:
|
|
508
|
+
manifest, digest = _load_json(manifest_path, label="RRR checkpoint manifest")
|
|
509
|
+
expected = {
|
|
510
|
+
"schema_version",
|
|
511
|
+
"role",
|
|
512
|
+
"profile",
|
|
513
|
+
"revision",
|
|
514
|
+
"model_type",
|
|
515
|
+
"license",
|
|
516
|
+
"files",
|
|
517
|
+
}
|
|
518
|
+
if set(manifest) != expected or manifest.get("schema_version") != CHECKPOINT_SCHEMA:
|
|
519
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint manifest schema mismatch")
|
|
520
|
+
if manifest.get("role") not in {"rewriter", "reader"}:
|
|
521
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint role is invalid")
|
|
522
|
+
if manifest.get("profile") not in {
|
|
523
|
+
"prompt",
|
|
524
|
+
"warmup_checkpoint",
|
|
525
|
+
"ppo_checkpoint",
|
|
526
|
+
"frozen_reader",
|
|
527
|
+
}:
|
|
528
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint profile is invalid")
|
|
529
|
+
if manifest.get("model_type") not in {"seq2seq", "causal"}:
|
|
530
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint model_type is invalid")
|
|
531
|
+
if manifest.get("license") != "NOASSERTION":
|
|
532
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint license must remain NOASSERTION")
|
|
533
|
+
_text(manifest.get("revision"), label="checkpoint revision")
|
|
534
|
+
files = manifest.get("files")
|
|
535
|
+
if not isinstance(files, Mapping) or not files:
|
|
536
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint files are empty")
|
|
537
|
+
if not any(str(name).lower().endswith(_WEIGHT_SUFFIXES) for name in files):
|
|
538
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint omits model weights")
|
|
539
|
+
root = root.resolve()
|
|
540
|
+
if not root.is_dir():
|
|
541
|
+
raise DriverError("CHECKPOINT_MISSING", "RRR checkpoint root is missing")
|
|
542
|
+
for relative, expected_hash in files.items():
|
|
543
|
+
if not isinstance(relative, str):
|
|
544
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint path is invalid")
|
|
545
|
+
_sha(expected_hash, label="checkpoint file hash")
|
|
546
|
+
candidate = root / relative
|
|
547
|
+
try:
|
|
548
|
+
candidate.resolve().relative_to(root)
|
|
549
|
+
except ValueError as exc:
|
|
550
|
+
raise DriverError("CHECKPOINT_INVALID", "RRR checkpoint path escapes root") from exc
|
|
551
|
+
if _sha_file(candidate, limit=2**40) != expected_hash:
|
|
552
|
+
raise DriverError("CHECKPOINT_MISMATCH", "RRR checkpoint file hash mismatch")
|
|
553
|
+
return {**dict(manifest), "manifest_sha256": digest, "root": root}
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
class LocalHFGenerator:
|
|
557
|
+
"""Local-only inference for prompt, warm-up, PPO, or frozen-reader checkpoints."""
|
|
558
|
+
|
|
559
|
+
def __init__(self, checkpoint: Mapping[str, Any]) -> None:
|
|
560
|
+
self.checkpoint = checkpoint
|
|
561
|
+
try:
|
|
562
|
+
transformers = importlib.import_module("transformers")
|
|
563
|
+
except ModuleNotFoundError as exc:
|
|
564
|
+
raise DriverError("DEPENDENCY_MISSING", "transformers is unavailable") from exc
|
|
565
|
+
root = str(checkpoint["root"])
|
|
566
|
+
try:
|
|
567
|
+
self.tokenizer = transformers.AutoTokenizer.from_pretrained(
|
|
568
|
+
root, local_files_only=True, trust_remote_code=False
|
|
569
|
+
)
|
|
570
|
+
model_cls = (
|
|
571
|
+
transformers.AutoModelForSeq2SeqLM
|
|
572
|
+
if checkpoint["model_type"] == "seq2seq"
|
|
573
|
+
else transformers.AutoModelForCausalLM
|
|
574
|
+
)
|
|
575
|
+
self.model = model_cls.from_pretrained(
|
|
576
|
+
root, local_files_only=True, trust_remote_code=False
|
|
577
|
+
)
|
|
578
|
+
self.model.eval()
|
|
579
|
+
except Exception as exc:
|
|
580
|
+
raise DriverError(
|
|
581
|
+
"CHECKPOINT_LOAD_FAILURE", "RRR local checkpoint failed to load"
|
|
582
|
+
) from exc
|
|
583
|
+
|
|
584
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
585
|
+
return {
|
|
586
|
+
"role": self.checkpoint["role"],
|
|
587
|
+
"profile": self.checkpoint["profile"],
|
|
588
|
+
"revision": self.checkpoint["revision"],
|
|
589
|
+
"manifest_sha256": self.checkpoint["manifest_sha256"],
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
def generate(self, prompt: str, *, seed: int, max_tokens: int) -> Generation:
|
|
593
|
+
del seed
|
|
594
|
+
try:
|
|
595
|
+
encoded = self.tokenizer(prompt, return_tensors="pt", truncation=True)
|
|
596
|
+
outputs = self.model.generate(**encoded, max_new_tokens=max_tokens, do_sample=False)
|
|
597
|
+
input_ids = encoded["input_ids"]
|
|
598
|
+
input_tokens = int(input_ids.shape[-1])
|
|
599
|
+
row = outputs[0]
|
|
600
|
+
if self.checkpoint["model_type"] == "causal":
|
|
601
|
+
row = row[input_tokens:]
|
|
602
|
+
text = self.tokenizer.decode(row, skip_special_tokens=True)
|
|
603
|
+
output_tokens = int(row.shape[-1]) if hasattr(row, "shape") else len(row)
|
|
604
|
+
if self.checkpoint["model_type"] == "seq2seq":
|
|
605
|
+
# Encoder-decoder sequences contain a supplied decoder prefix;
|
|
606
|
+
# max_new_tokens and metered output exclude that prefix.
|
|
607
|
+
decoder_input = encoded.get("decoder_input_ids")
|
|
608
|
+
decoder_prefix = int(decoder_input.shape[-1]) if decoder_input is not None else 1
|
|
609
|
+
output_tokens -= decoder_prefix
|
|
610
|
+
if output_tokens < 0:
|
|
611
|
+
raise ValueError("RRR sequence omits its decoder prefix")
|
|
612
|
+
except Exception as exc:
|
|
613
|
+
raise DriverError(
|
|
614
|
+
"MODEL_RUNTIME_FAILURE",
|
|
615
|
+
"RRR local generation failed",
|
|
616
|
+
consumed=True,
|
|
617
|
+
) from exc
|
|
618
|
+
return Generation(text=text, input_tokens=input_tokens, output_tokens=output_tokens)
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
class SearchCache:
|
|
622
|
+
def __init__(self, path: Path) -> None:
|
|
623
|
+
manifest, digest = _load_json(path, label="RRR search cache")
|
|
624
|
+
expected = {
|
|
625
|
+
"schema_version",
|
|
626
|
+
"mode",
|
|
627
|
+
"corpus_revision",
|
|
628
|
+
"index_revision",
|
|
629
|
+
"window_start",
|
|
630
|
+
"window_end",
|
|
631
|
+
"entries",
|
|
632
|
+
}
|
|
633
|
+
if set(manifest) != expected or manifest.get("schema_version") != SEARCH_SCHEMA:
|
|
634
|
+
raise DriverError("SEARCH_CACHE_INVALID", "RRR search cache schema mismatch")
|
|
635
|
+
if manifest.get("mode") not in {"bing_cache", "controlled_static"}:
|
|
636
|
+
raise DriverError("SEARCH_CACHE_INVALID", "RRR search cache mode is invalid")
|
|
637
|
+
if not _DATE.fullmatch(str(manifest.get("window_start", ""))) or not _DATE.fullmatch(
|
|
638
|
+
str(manifest.get("window_end", ""))
|
|
639
|
+
):
|
|
640
|
+
raise DriverError("SEARCH_CACHE_INVALID", "RRR search cache window is invalid")
|
|
641
|
+
entries = manifest.get("entries")
|
|
642
|
+
if not isinstance(entries, Mapping):
|
|
643
|
+
raise DriverError("SEARCH_CACHE_INVALID", "RRR search cache entries are invalid")
|
|
644
|
+
self.manifest = manifest
|
|
645
|
+
self.digest = digest
|
|
646
|
+
|
|
647
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
648
|
+
return {
|
|
649
|
+
"mode": self.manifest["mode"],
|
|
650
|
+
"artifact_sha256": self.digest,
|
|
651
|
+
"corpus_revision": self.manifest["corpus_revision"],
|
|
652
|
+
"index_revision": self.manifest["index_revision"],
|
|
653
|
+
"window_start": self.manifest["window_start"],
|
|
654
|
+
"window_end": self.manifest["window_end"],
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
def search(
|
|
658
|
+
self,
|
|
659
|
+
query: str,
|
|
660
|
+
*,
|
|
661
|
+
top_k: int,
|
|
662
|
+
window_start: str,
|
|
663
|
+
window_end: str,
|
|
664
|
+
) -> tuple[SearchDocument, ...]:
|
|
665
|
+
if (
|
|
666
|
+
window_start != self.manifest["window_start"]
|
|
667
|
+
or window_end != self.manifest["window_end"]
|
|
668
|
+
):
|
|
669
|
+
raise DriverError("SEARCH_IDENTITY_MISMATCH", "RRR search time window mismatch")
|
|
670
|
+
rows = self.manifest["entries"].get(query)
|
|
671
|
+
if not isinstance(rows, Sequence) or isinstance(rows, (str, bytes)):
|
|
672
|
+
raise DriverError("SEARCH_CACHE_MISS", "RRR search cache has no bound query")
|
|
673
|
+
if len(rows) > top_k:
|
|
674
|
+
rows = rows[:top_k]
|
|
675
|
+
result: list[SearchDocument] = []
|
|
676
|
+
seen: set[str] = set()
|
|
677
|
+
for row in rows:
|
|
678
|
+
if not isinstance(row, Mapping) or set(row) != {
|
|
679
|
+
"document_id",
|
|
680
|
+
"title",
|
|
681
|
+
"text",
|
|
682
|
+
"score",
|
|
683
|
+
"metadata",
|
|
684
|
+
}:
|
|
685
|
+
raise DriverError("SEARCH_CACHE_INVALID", "RRR search row schema is invalid")
|
|
686
|
+
document_id = _text(row["document_id"], label="search document ID")
|
|
687
|
+
text = _text(row["text"], label="search document text")
|
|
688
|
+
score = row["score"]
|
|
689
|
+
if (
|
|
690
|
+
document_id in seen
|
|
691
|
+
or isinstance(score, bool)
|
|
692
|
+
or not isinstance(score, (int, float))
|
|
693
|
+
or not math.isfinite(float(score))
|
|
694
|
+
):
|
|
695
|
+
raise DriverError("SEARCH_CACHE_INVALID", "RRR search row identity is invalid")
|
|
696
|
+
seen.add(document_id)
|
|
697
|
+
metadata = row["metadata"]
|
|
698
|
+
if not isinstance(metadata, Mapping):
|
|
699
|
+
raise DriverError("SEARCH_CACHE_INVALID", "RRR search metadata is invalid")
|
|
700
|
+
result.append(
|
|
701
|
+
SearchDocument(
|
|
702
|
+
document_id=document_id,
|
|
703
|
+
title=_text(row["title"], label="search title", allow_empty=True),
|
|
704
|
+
text=text,
|
|
705
|
+
score=float(score),
|
|
706
|
+
metadata=dict(metadata),
|
|
707
|
+
)
|
|
708
|
+
)
|
|
709
|
+
return tuple(result)
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
def _validate_request(value: Any) -> Mapping[str, Any]:
|
|
713
|
+
if not isinstance(value, Mapping) or set(value) != _ROOT_FIELDS:
|
|
714
|
+
raise DriverError("INVALID_REQUEST", "RRR request fields do not match schema")
|
|
715
|
+
if (
|
|
716
|
+
value.get("method_id") != METHOD_ID
|
|
717
|
+
or value.get("release_id") not in set(RELEASE_IDS.values())
|
|
718
|
+
or value.get("upstream_commit") != UPSTREAM_COMMIT
|
|
719
|
+
or value.get("protocol_version") != PROTOCOL_VERSION
|
|
720
|
+
):
|
|
721
|
+
raise DriverError("IDENTITY_MISMATCH", "RRR request identity mismatch")
|
|
722
|
+
request_id = _sha(value.get("request_id"), label="request_id")
|
|
723
|
+
_sha(value.get("state_hash"), label="state_hash")
|
|
724
|
+
try:
|
|
725
|
+
expected_id = _content_hash({key: value[key] for key in value if key != "request_id"})
|
|
726
|
+
except (TypeError, ValueError) as exc:
|
|
727
|
+
raise DriverError("INVALID_REQUEST", "RRR request is not canonical JSON") from exc
|
|
728
|
+
if request_id != expected_id:
|
|
729
|
+
raise DriverError("REQUEST_ID_MISMATCH", "RRR request_id mismatch")
|
|
730
|
+
payload = value.get("payload")
|
|
731
|
+
dependencies = value.get("dependency_fingerprints")
|
|
732
|
+
if not isinstance(payload, Mapping) or set(payload) != _PAYLOAD_FIELDS:
|
|
733
|
+
raise DriverError("INVALID_REQUEST", "RRR payload fields do not match schema")
|
|
734
|
+
if not isinstance(dependencies, Mapping) or set(dependencies) != {"backend", "retriever"}:
|
|
735
|
+
raise DriverError("INVALID_REQUEST", "RRR dependency fields do not match schema")
|
|
736
|
+
if not isinstance(dependencies["backend"], Mapping) or not dependencies["backend"]:
|
|
737
|
+
raise DriverError("INVALID_REQUEST", "RRR backend fingerprint is required")
|
|
738
|
+
if not isinstance(dependencies["retriever"], Mapping):
|
|
739
|
+
raise DriverError("INVALID_REQUEST", "RRR retriever fingerprint must be an object")
|
|
740
|
+
if value.get("minimum_reservation") != {"model_calls": 2, "retrieval_calls": 1}:
|
|
741
|
+
raise DriverError("INVALID_REQUEST", "RRR reservation is invalid")
|
|
742
|
+
normalized = json.loads(_canonical_json(payload))
|
|
743
|
+
controls = normalized.get("controls")
|
|
744
|
+
if not isinstance(controls, Mapping) or set(controls) != _CONTROL_FIELDS:
|
|
745
|
+
raise DriverError("INVALID_REQUEST", "RRR controls do not match schema")
|
|
746
|
+
if controls.get("max_queries") != 1:
|
|
747
|
+
raise DriverError("INVALID_REQUEST", "RRR worker supports one query")
|
|
748
|
+
top_k = _positive_int(controls.get("top_k"), label="top_k")
|
|
749
|
+
if top_k > 100:
|
|
750
|
+
raise DriverError("INVALID_REQUEST", "RRR top_k exceeds 100")
|
|
751
|
+
if controls.get("query_parser") != "upstream_semicolon_terminator_single":
|
|
752
|
+
raise DriverError("INVALID_REQUEST", "RRR parser identity drifted")
|
|
753
|
+
if controls.get("search_mode") not in {"bing_cache", "controlled_static"}:
|
|
754
|
+
raise DriverError("INVALID_REQUEST", "RRR search mode is invalid")
|
|
755
|
+
if controls.get("rewriter_profile") not in {
|
|
756
|
+
"prompt",
|
|
757
|
+
"warmup_checkpoint",
|
|
758
|
+
"ppo_checkpoint",
|
|
759
|
+
}:
|
|
760
|
+
raise DriverError("INVALID_REQUEST", "RRR rewriter profile is invalid")
|
|
761
|
+
if value.get("release_id") != RELEASE_IDS[controls["rewriter_profile"]]:
|
|
762
|
+
raise DriverError("IDENTITY_MISMATCH", "RRR release/profile identity mismatch")
|
|
763
|
+
for key in ("max_rewriter_tokens", "max_reader_tokens", "max_input_chars"):
|
|
764
|
+
_positive_int(controls.get(key), label=key)
|
|
765
|
+
for key in ("search_window_start", "search_window_end"):
|
|
766
|
+
if not isinstance(controls.get(key), str) or not _DATE.fullmatch(controls[key]):
|
|
767
|
+
raise DriverError("INVALID_REQUEST", "RRR search time window is invalid")
|
|
768
|
+
if controls["search_window_start"] > controls["search_window_end"]:
|
|
769
|
+
raise DriverError("INVALID_REQUEST", "RRR search time window is reversed")
|
|
770
|
+
_text(normalized.get("query"), label="query")
|
|
771
|
+
_text(normalized.get("task_id"), label="task_id", allow_empty=True)
|
|
772
|
+
_text(normalized.get("instruction"), label="instruction", allow_empty=True)
|
|
773
|
+
if not isinstance(normalized.get("messages"), Sequence):
|
|
774
|
+
raise DriverError("INVALID_REQUEST", "RRR messages must be a sequence")
|
|
775
|
+
for key in (
|
|
776
|
+
"prompt_hash",
|
|
777
|
+
"reader_prompt_hash",
|
|
778
|
+
"search_artifact_hash",
|
|
779
|
+
"backend_artifact_hash",
|
|
780
|
+
"retriever_artifact_hash",
|
|
781
|
+
"input_artifact_hash",
|
|
782
|
+
):
|
|
783
|
+
_sha(normalized.get(key), label=key)
|
|
784
|
+
for key in (
|
|
785
|
+
"corpus_revision",
|
|
786
|
+
"index_revision",
|
|
787
|
+
"rewriter_checkpoint_revision",
|
|
788
|
+
"reader_checkpoint_revision",
|
|
789
|
+
):
|
|
790
|
+
_text(
|
|
791
|
+
normalized.get(key), label=key, allow_empty=key in {"corpus_revision", "index_revision"}
|
|
792
|
+
)
|
|
793
|
+
if (
|
|
794
|
+
normalized.get("source_license_acknowledged") is not True
|
|
795
|
+
or normalized.get("checkpoint_license_acknowledged") is not True
|
|
796
|
+
):
|
|
797
|
+
raise DriverError("LICENSE_ACKNOWLEDGEMENT_REQUIRED", "RRR license acknowledgement missing")
|
|
798
|
+
_nonnegative_int(normalized.get("seed"), label="seed")
|
|
799
|
+
backend_hash = _content_hash(dependencies["backend"])
|
|
800
|
+
retriever_hash = _content_hash(dependencies["retriever"])
|
|
801
|
+
if (
|
|
802
|
+
normalized["backend_artifact_hash"] != backend_hash
|
|
803
|
+
or normalized["retriever_artifact_hash"] != retriever_hash
|
|
804
|
+
):
|
|
805
|
+
raise DriverError("DEPENDENCY_MISMATCH", "RRR dependency fingerprint hash mismatch")
|
|
806
|
+
expected_input = _content_hash(
|
|
807
|
+
{
|
|
808
|
+
"query": normalized["query"],
|
|
809
|
+
"instruction": normalized["instruction"],
|
|
810
|
+
"messages": normalized["messages"],
|
|
811
|
+
"controls": controls,
|
|
812
|
+
}
|
|
813
|
+
)
|
|
814
|
+
if normalized["input_artifact_hash"] != expected_input:
|
|
815
|
+
raise DriverError("INPUT_IDENTITY_MISMATCH", "RRR input artifact hash mismatch")
|
|
816
|
+
return {
|
|
817
|
+
"request_id": request_id,
|
|
818
|
+
"payload": normalized,
|
|
819
|
+
"dependencies": json.loads(_canonical_json(dependencies)),
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
def _parse_query(raw: str) -> str:
|
|
824
|
+
value = raw.split("**", 1)[0].strip()
|
|
825
|
+
if "Query:" in value:
|
|
826
|
+
value = value.split("Query:", 1)[1].strip()
|
|
827
|
+
queries = tuple(item.strip() for item in value.split(";") if item.strip())
|
|
828
|
+
if len(queries) != 1:
|
|
829
|
+
raise DriverError("QUERY_PARSE_FAILURE", "RRR single-query parser produced != 1 query")
|
|
830
|
+
return queries[0]
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
def _usage(rewriter: Generation, reader: Generation) -> dict[str, int]:
|
|
834
|
+
return {
|
|
835
|
+
"model_calls": 2,
|
|
836
|
+
"retrieval_calls": 1,
|
|
837
|
+
"input_tokens": rewriter.input_tokens + reader.input_tokens,
|
|
838
|
+
"output_tokens": rewriter.output_tokens + reader.output_tokens,
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
@dataclass(slots=True)
|
|
843
|
+
class RRRRuntime:
|
|
844
|
+
source: SourceEvidence
|
|
845
|
+
prompt_path: Path
|
|
846
|
+
reader_prompt_path: Path
|
|
847
|
+
rewriter: Generator
|
|
848
|
+
searcher: Searcher
|
|
849
|
+
reader: Generator
|
|
850
|
+
acknowledge_noassertion_source: bool = False
|
|
851
|
+
acknowledge_noassertion_checkpoints: bool = False
|
|
852
|
+
acknowledge_credential_quarantine: bool = False
|
|
853
|
+
prompt: str = field(init=False, repr=False)
|
|
854
|
+
reader_prompt: str = field(init=False, repr=False)
|
|
855
|
+
|
|
856
|
+
def __post_init__(self) -> None:
|
|
857
|
+
if not self.acknowledge_noassertion_source:
|
|
858
|
+
raise DriverError(
|
|
859
|
+
"LICENSE_ACKNOWLEDGEMENT_REQUIRED",
|
|
860
|
+
"RRR source NOASSERTION acknowledgement required",
|
|
861
|
+
)
|
|
862
|
+
if not self.acknowledge_noassertion_checkpoints:
|
|
863
|
+
raise DriverError(
|
|
864
|
+
"LICENSE_ACKNOWLEDGEMENT_REQUIRED",
|
|
865
|
+
"RRR checkpoint NOASSERTION acknowledgement required",
|
|
866
|
+
)
|
|
867
|
+
if self.source.credential_risk_count and not self.acknowledge_credential_quarantine:
|
|
868
|
+
raise DriverError(
|
|
869
|
+
"CREDENTIAL_QUARANTINE_REQUIRED",
|
|
870
|
+
"RRR source contains redacted credential-risk findings and must remain quarantined",
|
|
871
|
+
)
|
|
872
|
+
self.prompt = _read_bytes(self.prompt_path, label="RRR rewrite prompt").decode("utf-8")
|
|
873
|
+
self.reader_prompt = _read_bytes(self.reader_prompt_path, label="RRR reader prompt").decode(
|
|
874
|
+
"utf-8"
|
|
875
|
+
)
|
|
876
|
+
if "{query}" not in self.prompt or not {"{query}", "{background}"} <= {
|
|
877
|
+
token for token in ("{query}", "{background}") if token in self.reader_prompt
|
|
878
|
+
}:
|
|
879
|
+
raise DriverError("PROMPT_INVALID", "RRR mounted prompt placeholders are invalid")
|
|
880
|
+
|
|
881
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
882
|
+
return {
|
|
883
|
+
"worker_id": DRIVER_ID,
|
|
884
|
+
"upstream_commit": UPSTREAM_COMMIT,
|
|
885
|
+
"source_manifest_sha256": self.source.manifest_sha256,
|
|
886
|
+
"execution_evidence": self.source.evidence_level,
|
|
887
|
+
"credential_risk_count": self.source.credential_risk_count,
|
|
888
|
+
"upstream_imported": False,
|
|
889
|
+
"ppo_training": False,
|
|
890
|
+
"rewriter": dict(self.rewriter.fingerprint()),
|
|
891
|
+
"searcher": dict(self.searcher.fingerprint()),
|
|
892
|
+
"reader": dict(self.reader.fingerprint()),
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
def call(self, raw: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
896
|
+
request = _validate_request(raw)
|
|
897
|
+
payload = request["payload"]
|
|
898
|
+
controls = payload["controls"]
|
|
899
|
+
if (
|
|
900
|
+
_sha_bytes(self.prompt.encode()) != payload["prompt_hash"]
|
|
901
|
+
or _sha_bytes(self.reader_prompt.encode()) != payload["reader_prompt_hash"]
|
|
902
|
+
):
|
|
903
|
+
raise DriverError("PROMPT_IDENTITY_MISMATCH", "RRR prompt hash mismatch")
|
|
904
|
+
search_fp = self.searcher.fingerprint()
|
|
905
|
+
if (
|
|
906
|
+
search_fp.get("artifact_sha256") != payload["search_artifact_hash"]
|
|
907
|
+
or search_fp.get("mode") != controls["search_mode"]
|
|
908
|
+
or search_fp.get("corpus_revision") != payload["corpus_revision"]
|
|
909
|
+
or search_fp.get("index_revision") != payload["index_revision"]
|
|
910
|
+
):
|
|
911
|
+
raise DriverError("SEARCH_IDENTITY_MISMATCH", "RRR search artifact identity mismatch")
|
|
912
|
+
rewriter_fp = self.rewriter.fingerprint()
|
|
913
|
+
reader_fp = self.reader.fingerprint()
|
|
914
|
+
expected_backend_hash = _content_hash({"rewriter": rewriter_fp, "reader": reader_fp})
|
|
915
|
+
if payload["backend_artifact_hash"] != expected_backend_hash:
|
|
916
|
+
raise DriverError(
|
|
917
|
+
"DEPENDENCY_MISMATCH", "RRR rewriter/reader deployment identity mismatch"
|
|
918
|
+
)
|
|
919
|
+
expected_retriever_hash = (
|
|
920
|
+
_content_hash(search_fp)
|
|
921
|
+
if controls["search_mode"] == "controlled_static"
|
|
922
|
+
else _content_hash({})
|
|
923
|
+
)
|
|
924
|
+
if payload["retriever_artifact_hash"] != expected_retriever_hash:
|
|
925
|
+
raise DriverError("DEPENDENCY_MISMATCH", "RRR controlled retriever identity mismatch")
|
|
926
|
+
if (
|
|
927
|
+
rewriter_fp.get("profile") != controls["rewriter_profile"]
|
|
928
|
+
or rewriter_fp.get("revision") != payload["rewriter_checkpoint_revision"]
|
|
929
|
+
or reader_fp.get("revision") != payload["reader_checkpoint_revision"]
|
|
930
|
+
):
|
|
931
|
+
raise DriverError("CHECKPOINT_IDENTITY_MISMATCH", "RRR model identity mismatch")
|
|
932
|
+
rewrite_prompt = self.prompt.replace("{query}", payload["query"])
|
|
933
|
+
if len(rewrite_prompt) > controls["max_input_chars"]:
|
|
934
|
+
raise DriverError("BUDGET_EXCEEDED", "RRR rewrite prompt exceeds character budget")
|
|
935
|
+
rewrite = self.rewriter.generate(
|
|
936
|
+
rewrite_prompt,
|
|
937
|
+
seed=payload["seed"],
|
|
938
|
+
max_tokens=controls["max_rewriter_tokens"],
|
|
939
|
+
)
|
|
940
|
+
try:
|
|
941
|
+
query = _parse_query(rewrite.text)
|
|
942
|
+
except DriverError as exc:
|
|
943
|
+
# Parsing happens after the paid rewrite. Keep the known first
|
|
944
|
+
# call's cost instead of reporting an unconsumed input failure.
|
|
945
|
+
exc.consumed = True
|
|
946
|
+
exc.usage = dict(model_calls=1, retrieval_calls=0,
|
|
947
|
+
input_tokens=rewrite.input_tokens, output_tokens=rewrite.output_tokens)
|
|
948
|
+
raise
|
|
949
|
+
documents = self.searcher.search(
|
|
950
|
+
query,
|
|
951
|
+
top_k=controls["top_k"],
|
|
952
|
+
window_start=controls["search_window_start"],
|
|
953
|
+
window_end=controls["search_window_end"],
|
|
954
|
+
)
|
|
955
|
+
snippet = " ".join(item.text for item in documents)
|
|
956
|
+
reader_prompt = self.reader_prompt.replace("{background}", snippet).replace(
|
|
957
|
+
"{query}", payload["query"]
|
|
958
|
+
)
|
|
959
|
+
if len(reader_prompt) > controls["max_input_chars"]:
|
|
960
|
+
raise DriverError(
|
|
961
|
+
"BUDGET_EXCEEDED",
|
|
962
|
+
"RRR reader prompt exceeds character budget",
|
|
963
|
+
consumed=True,
|
|
964
|
+
usage={
|
|
965
|
+
"model_calls": 1,
|
|
966
|
+
"retrieval_calls": 1,
|
|
967
|
+
"input_tokens": rewrite.input_tokens,
|
|
968
|
+
"output_tokens": rewrite.output_tokens,
|
|
969
|
+
},
|
|
970
|
+
)
|
|
971
|
+
reader = self.reader.generate(
|
|
972
|
+
reader_prompt,
|
|
973
|
+
seed=payload["seed"],
|
|
974
|
+
max_tokens=controls["max_reader_tokens"],
|
|
975
|
+
)
|
|
976
|
+
rows = [
|
|
977
|
+
{
|
|
978
|
+
"document_id": item.document_id,
|
|
979
|
+
"title": item.title,
|
|
980
|
+
"text": item.text,
|
|
981
|
+
"corpus_revision": payload["corpus_revision"],
|
|
982
|
+
"query_index": 0,
|
|
983
|
+
"rank": index + 1,
|
|
984
|
+
"score": item.score,
|
|
985
|
+
"metadata": {
|
|
986
|
+
**dict(item.metadata),
|
|
987
|
+
"search_artifact_hash": payload["search_artifact_hash"],
|
|
988
|
+
},
|
|
989
|
+
}
|
|
990
|
+
for index, item in enumerate(documents)
|
|
991
|
+
]
|
|
992
|
+
trajectory = {
|
|
993
|
+
"stage_order": ["rewrite", "retrieve", "snippet", "reader"],
|
|
994
|
+
"rewrite_prompt_hash": _sha_bytes(rewrite_prompt.encode()),
|
|
995
|
+
"raw_rewrite_hash": _sha_bytes(rewrite.text.encode()),
|
|
996
|
+
"query": query,
|
|
997
|
+
"search_artifact_hash": payload["search_artifact_hash"],
|
|
998
|
+
"document_ids": [item.document_id for item in documents],
|
|
999
|
+
"snippet_hash": _sha_bytes(snippet.encode()),
|
|
1000
|
+
"reader_prompt_hash": _sha_bytes(reader_prompt.encode()),
|
|
1001
|
+
"answer_hash": _sha_bytes(reader.text.encode()),
|
|
1002
|
+
}
|
|
1003
|
+
return {
|
|
1004
|
+
"status": "ok",
|
|
1005
|
+
"request_id": request["request_id"],
|
|
1006
|
+
"upstream_commit": UPSTREAM_COMMIT,
|
|
1007
|
+
"protocol_version": PROTOCOL_VERSION,
|
|
1008
|
+
"payload": {
|
|
1009
|
+
"queries": [query],
|
|
1010
|
+
"reader_query": payload["query"],
|
|
1011
|
+
"documents": rows,
|
|
1012
|
+
"answer": reader.text.strip().removesuffix("**").strip(),
|
|
1013
|
+
"parser_mode": controls["query_parser"],
|
|
1014
|
+
"stage_order": ["rewrite", "retrieve", "snippet", "reader"],
|
|
1015
|
+
"trajectory_hash": _content_hash(trajectory),
|
|
1016
|
+
"prompt_hash": payload["prompt_hash"],
|
|
1017
|
+
"reader_prompt_hash": payload["reader_prompt_hash"],
|
|
1018
|
+
"search_artifact_hash": payload["search_artifact_hash"],
|
|
1019
|
+
"rewriter_checkpoint_revision": payload["rewriter_checkpoint_revision"],
|
|
1020
|
+
"reader_checkpoint_revision": payload["reader_checkpoint_revision"],
|
|
1021
|
+
"backend_artifact_hash": payload["backend_artifact_hash"],
|
|
1022
|
+
"retriever_artifact_hash": payload["retriever_artifact_hash"],
|
|
1023
|
+
"input_artifact_hash": payload["input_artifact_hash"],
|
|
1024
|
+
"source_manifest_sha256": self.source.manifest_sha256,
|
|
1025
|
+
"execution_evidence": self.source.evidence_level,
|
|
1026
|
+
},
|
|
1027
|
+
"usage": _usage(rewrite, reader),
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
def _failure(exc: DriverError, request_id: str = "") -> Mapping[str, Any]:
|
|
1032
|
+
result: dict[str, Any] = {
|
|
1033
|
+
"status": "error",
|
|
1034
|
+
"failure_code": exc.code,
|
|
1035
|
+
"message": exc.public_message,
|
|
1036
|
+
"consumed": exc.consumed,
|
|
1037
|
+
}
|
|
1038
|
+
if request_id:
|
|
1039
|
+
result["request_id"] = request_id
|
|
1040
|
+
if exc.usage is not None:
|
|
1041
|
+
result["usage"] = exc.usage
|
|
1042
|
+
return result
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
def _read_request() -> Any:
|
|
1046
|
+
raw = sys.stdin.buffer.readline(MAX_REQUEST_BYTES + 1)
|
|
1047
|
+
if not raw or len(raw) > MAX_REQUEST_BYTES or sys.stdin.buffer.read(1):
|
|
1048
|
+
raise DriverError("INVALID_REQUEST", "RRR worker accepts one bounded JSON line")
|
|
1049
|
+
try:
|
|
1050
|
+
return json.loads(raw)
|
|
1051
|
+
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
|
|
1052
|
+
raise DriverError("INVALID_REQUEST", "RRR request is invalid JSON") from exc
|
|
1053
|
+
|
|
1054
|
+
|
|
1055
|
+
def _parser() -> argparse.ArgumentParser:
|
|
1056
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
1057
|
+
source = parser.add_mutually_exclusive_group(required=True)
|
|
1058
|
+
source.add_argument("--source-tarball", type=Path)
|
|
1059
|
+
source.add_argument("--source-checkout", type=Path)
|
|
1060
|
+
parser.add_argument("--smoke-source", action="store_true")
|
|
1061
|
+
parser.add_argument("--prompt", type=Path)
|
|
1062
|
+
parser.add_argument("--reader-prompt", type=Path)
|
|
1063
|
+
parser.add_argument("--search-cache", type=Path)
|
|
1064
|
+
parser.add_argument("--rewriter-checkpoint", type=Path)
|
|
1065
|
+
parser.add_argument("--rewriter-manifest", type=Path)
|
|
1066
|
+
parser.add_argument("--reader-checkpoint", type=Path)
|
|
1067
|
+
parser.add_argument("--reader-manifest", type=Path)
|
|
1068
|
+
parser.add_argument("--acknowledge-noassertion-source", action="store_true")
|
|
1069
|
+
parser.add_argument("--acknowledge-noassertion-checkpoints", action="store_true")
|
|
1070
|
+
parser.add_argument("--acknowledge-credential-quarantine", action="store_true")
|
|
1071
|
+
return parser
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
def main(argv: Sequence[str] | None = None) -> int:
|
|
1075
|
+
args = _parser().parse_args(argv)
|
|
1076
|
+
request_id = ""
|
|
1077
|
+
try:
|
|
1078
|
+
source = (verify_source_checkout(args.source_checkout) if args.source_checkout is not None
|
|
1079
|
+
else verify_source_tarball(args.source_tarball))
|
|
1080
|
+
if args.smoke_source:
|
|
1081
|
+
response: Mapping[str, Any] = {
|
|
1082
|
+
"status": "ok",
|
|
1083
|
+
"upstream_commit": UPSTREAM_COMMIT,
|
|
1084
|
+
"source_manifest_sha256": source.manifest_sha256,
|
|
1085
|
+
"execution_evidence": source.evidence_level,
|
|
1086
|
+
"credential_risk_count": source.credential_risk_count,
|
|
1087
|
+
"credential_values_redacted": True,
|
|
1088
|
+
"upstream_imported": False,
|
|
1089
|
+
}
|
|
1090
|
+
else:
|
|
1091
|
+
required = (
|
|
1092
|
+
args.prompt,
|
|
1093
|
+
args.reader_prompt,
|
|
1094
|
+
args.search_cache,
|
|
1095
|
+
args.rewriter_checkpoint,
|
|
1096
|
+
args.rewriter_manifest,
|
|
1097
|
+
args.reader_checkpoint,
|
|
1098
|
+
args.reader_manifest,
|
|
1099
|
+
)
|
|
1100
|
+
if any(value is None for value in required):
|
|
1101
|
+
raise DriverError("CONFIGURATION_MISSING", "RRR inference mounts are incomplete")
|
|
1102
|
+
rewriter_checkpoint = verify_checkpoint(
|
|
1103
|
+
args.rewriter_checkpoint, args.rewriter_manifest
|
|
1104
|
+
)
|
|
1105
|
+
reader_checkpoint = verify_checkpoint(args.reader_checkpoint, args.reader_manifest)
|
|
1106
|
+
runtime = RRRRuntime(
|
|
1107
|
+
source=source,
|
|
1108
|
+
prompt_path=args.prompt,
|
|
1109
|
+
reader_prompt_path=args.reader_prompt,
|
|
1110
|
+
rewriter=LocalHFGenerator(rewriter_checkpoint),
|
|
1111
|
+
searcher=SearchCache(args.search_cache),
|
|
1112
|
+
reader=LocalHFGenerator(reader_checkpoint),
|
|
1113
|
+
acknowledge_noassertion_source=args.acknowledge_noassertion_source,
|
|
1114
|
+
acknowledge_noassertion_checkpoints=args.acknowledge_noassertion_checkpoints,
|
|
1115
|
+
acknowledge_credential_quarantine=args.acknowledge_credential_quarantine,
|
|
1116
|
+
)
|
|
1117
|
+
raw = _read_request()
|
|
1118
|
+
if isinstance(raw, Mapping) and isinstance(raw.get("request_id"), str):
|
|
1119
|
+
request_id = raw["request_id"]
|
|
1120
|
+
response = runtime.call(raw)
|
|
1121
|
+
except DriverError as exc:
|
|
1122
|
+
response = _failure(exc, request_id)
|
|
1123
|
+
except Exception as exc: # pragma: no cover - final secret-free containment
|
|
1124
|
+
response = _failure(
|
|
1125
|
+
DriverError("WORKER_INTERNAL_FAILURE", f"RRR failed closed: {type(exc).__name__}"),
|
|
1126
|
+
request_id,
|
|
1127
|
+
)
|
|
1128
|
+
sys.stdout.write(_canonical_json(response) + "\n")
|
|
1129
|
+
return 0
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
if __name__ == "__main__":
|
|
1133
|
+
raise SystemExit(main())
|