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
|
@@ -0,0 +1,828 @@
|
|
|
1
|
+
"""Fail-closed bridge for Q-RAG's released frozen E5/HotpotQA policy.
|
|
2
|
+
|
|
3
|
+
Q-RAG's source checkout has no repository-level license declaration. The
|
|
4
|
+
source and the separately licensed checkpoint therefore stay in a dedicated,
|
|
5
|
+
user-mounted worker. This module sends only the ordered candidate texts,
|
|
6
|
+
binds every treatment-defining artifact, and validates the official
|
|
7
|
+
candidate-index/Q-value trajectory. It never exposes training, rewards,
|
|
8
|
+
supporting-fact labels, or a synthetic ``stop`` action.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import math
|
|
14
|
+
import re
|
|
15
|
+
from collections.abc import Mapping, Sequence
|
|
16
|
+
from dataclasses import asdict, dataclass
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
from agentinputlab.contracts import (
|
|
20
|
+
AlgorithmOutputError,
|
|
21
|
+
BudgetExceededError,
|
|
22
|
+
CompositeResult,
|
|
23
|
+
ExecutionTrace,
|
|
24
|
+
ExternalDependencyError,
|
|
25
|
+
FrozenAgentState,
|
|
26
|
+
InterventionContext,
|
|
27
|
+
SemanticFamily,
|
|
28
|
+
TraceEvent,
|
|
29
|
+
TracePhase,
|
|
30
|
+
ValidationError,
|
|
31
|
+
)
|
|
32
|
+
from agentinputlab.contracts.serialization import content_hash, freeze_mapping
|
|
33
|
+
from agentinputlab.integrations.external_workers import WorkerClient
|
|
34
|
+
from agentinputlab.integrations.external_workers.method import (
|
|
35
|
+
MethodWorkerRequest,
|
|
36
|
+
call_worker,
|
|
37
|
+
finite_number,
|
|
38
|
+
mapping_sequence,
|
|
39
|
+
nonnegative_integer,
|
|
40
|
+
required_text,
|
|
41
|
+
resolve_worker,
|
|
42
|
+
worker_fingerprint,
|
|
43
|
+
)
|
|
44
|
+
from agentinputlab.observability import external_usage_counters
|
|
45
|
+
|
|
46
|
+
from .reader_adapter import (
|
|
47
|
+
QRAG_INSTRUCTION_PROMPT_SHA256,
|
|
48
|
+
QRAG_INSTRUCTION_PROTOCOL,
|
|
49
|
+
QRAG_INSTRUCTION_READER_PROFILE,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
QRAG_UPSTREAM_COMMIT = "e7598130b63eaab868469877e88bcacc59a44efb"
|
|
53
|
+
QRAG_PROTOCOL = "agentinputlab.qrag.frozen.v3"
|
|
54
|
+
QRAG_PROFILE_ID = "qrag.e5_hotpotqa.frozen.v1"
|
|
55
|
+
|
|
56
|
+
QRAG_CHECKPOINT_REPOSITORY = "Q-RAG/qrag-ft-e5-on-hotpotqa"
|
|
57
|
+
QRAG_CHECKPOINT_REVISION = "e0e48389f551075ace2ce61207522b6bad55593a"
|
|
58
|
+
QRAG_CHECKPOINT_FILE_SHA256 = "ccd4068d3917bed2e44afcd7ee7a9d66c8487b44dd2206252e6d2985352f92b7"
|
|
59
|
+
QRAG_CHECKPOINT_CONFIG_SHA256 = "edbba621832e545a63723eda2b6652eccfd51b29eda7d04145ba22a7ea48c241"
|
|
60
|
+
QRAG_EMBEDDER_REPOSITORY = "intfloat/multilingual-e5-large"
|
|
61
|
+
QRAG_EMBEDDER_REVISION = "3d7cfbdacd47fdda877c5cd8a79fbcc4f2a574f3"
|
|
62
|
+
QRAG_EMBEDDER_MODEL_SHA256 = "020afdebf2762b29fcaf286629a96c3b3b65af241f6a08226b1cfee60a21def6"
|
|
63
|
+
QRAG_SOURCE_MANIFEST_SHA256 = "86c49eee9c64329bd77f3b5a4286e937aadb7c5fcd67d1238f214421cc27ae1a"
|
|
64
|
+
|
|
65
|
+
QRAG_QA_ENV_SOURCE_SHA256 = "267c27c248f332478bf810a50f097a898a818cf6f8f4bd7b70a2893312c0eae1"
|
|
66
|
+
QRAG_TEXT_ENV_SOURCE_SHA256 = "2bfee69d8bea9e9fc2822dce8aa42c563344da1454a111f807fe2ac7a00fc39c"
|
|
67
|
+
QRAG_PQN_SOURCE_SHA256 = "5e69ee5e20f098c101ceebb0c3713a3e63ffcd0a1b614d7180c1b474465cce39"
|
|
68
|
+
|
|
69
|
+
QRAG_ENVIRONMENT_CONTRACT = freeze_mapping(
|
|
70
|
+
{
|
|
71
|
+
"dataset_profile": "hotpotqa",
|
|
72
|
+
"max_steps": 2,
|
|
73
|
+
"sort_by_index": False,
|
|
74
|
+
"separator": " [SEP] ",
|
|
75
|
+
"position_processor": "absolute_none",
|
|
76
|
+
"feedback_model": "DummyFeedbackModel",
|
|
77
|
+
"feedback_never_terminate": True,
|
|
78
|
+
"gold_answer_available": False,
|
|
79
|
+
"supporting_fact_labels_available": False,
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
QRAG_ENVIRONMENT_CONFIG_SHA256 = content_hash(QRAG_ENVIRONMENT_CONTRACT)
|
|
83
|
+
QRAG_ACTION_SCHEMA = freeze_mapping(
|
|
84
|
+
{
|
|
85
|
+
"action": "candidate_index",
|
|
86
|
+
"stop_action": False,
|
|
87
|
+
"policy": "argmax_available_q_value",
|
|
88
|
+
"termination": ("fixed_step_budget", "candidate_exhausted", "empty_candidates"),
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
QRAG_ACTION_SCHEMA_SHA256 = content_hash(QRAG_ACTION_SCHEMA)
|
|
92
|
+
QRAG_CANDIDATE_BUILDER_CONTRACT = freeze_mapping(
|
|
93
|
+
{
|
|
94
|
+
"input_fields": ("id", "question", "chunks"),
|
|
95
|
+
"candidate_fields": ("document_id", "text"),
|
|
96
|
+
"preserve_input_order": True,
|
|
97
|
+
"dummy_answer": "",
|
|
98
|
+
"dummy_supporting_fact_indices": (),
|
|
99
|
+
}
|
|
100
|
+
)
|
|
101
|
+
QRAG_CANDIDATE_BUILDER_SHA256 = content_hash(QRAG_CANDIDATE_BUILDER_CONTRACT)
|
|
102
|
+
|
|
103
|
+
QRAG_READER_SYSTEM_PROMPT = (
|
|
104
|
+
"Answer the question based on the given passages.\n"
|
|
105
|
+
"Only give me the short and precise answer, do not output any other words.\n"
|
|
106
|
+
"Keep your reasoning very brief and concise.\n"
|
|
107
|
+
'Always end your response with "Final answer: [your final answer]".\n'
|
|
108
|
+
)
|
|
109
|
+
QRAG_READER_USER_TEMPLATE = (
|
|
110
|
+
"\nGIVEN PASSAGES:\n{context}\n\nQUESTION:\n{question}\n\nFinal answer: "
|
|
111
|
+
)
|
|
112
|
+
QRAG_READER_PROMPT_SHA256 = content_hash(
|
|
113
|
+
{"system": QRAG_READER_SYSTEM_PROMPT, "user": QRAG_READER_USER_TEMPLATE}
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
_HEX64 = re.compile(r"^[0-9a-f]{64}$")
|
|
117
|
+
_NATIVE_READER_PROFILE = "upstream_qwq32b_family_controlled"
|
|
118
|
+
_TRANSFER_READER_PROFILE = "factorial_reader_transfer"
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass(frozen=True, slots=True)
|
|
122
|
+
class QRAGLicenseAcknowledgement:
|
|
123
|
+
"""Explicitly acknowledge the two independently governed user mounts."""
|
|
124
|
+
|
|
125
|
+
source_noassertion_acknowledged: bool = False
|
|
126
|
+
checkpoint_cc_by_4_0_acknowledged: bool = False
|
|
127
|
+
user_mounted_source: bool = False
|
|
128
|
+
user_mounted_checkpoint: bool = False
|
|
129
|
+
|
|
130
|
+
def __post_init__(self) -> None:
|
|
131
|
+
if any(
|
|
132
|
+
not isinstance(value, bool)
|
|
133
|
+
for value in (
|
|
134
|
+
self.source_noassertion_acknowledged,
|
|
135
|
+
self.checkpoint_cc_by_4_0_acknowledged,
|
|
136
|
+
self.user_mounted_source,
|
|
137
|
+
self.user_mounted_checkpoint,
|
|
138
|
+
)
|
|
139
|
+
):
|
|
140
|
+
raise ValidationError("Q-RAG license acknowledgements must be boolean")
|
|
141
|
+
|
|
142
|
+
def require_complete(self) -> None:
|
|
143
|
+
if not self.source_noassertion_acknowledged or not self.user_mounted_source:
|
|
144
|
+
raise ExternalDependencyError(
|
|
145
|
+
"Q-RAG source is NOASSERTION; explicitly acknowledge and user-mount "
|
|
146
|
+
"the pinned source checkout before execution"
|
|
147
|
+
)
|
|
148
|
+
if not self.checkpoint_cc_by_4_0_acknowledged or not self.user_mounted_checkpoint:
|
|
149
|
+
raise ExternalDependencyError(
|
|
150
|
+
"Q-RAG checkpoint is a separate CC-BY-4.0 asset; explicitly acknowledge "
|
|
151
|
+
"and user-mount the pinned checkpoint before execution"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
def as_mapping(self) -> Mapping[str, bool]:
|
|
155
|
+
return freeze_mapping(asdict(self))
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass(frozen=True, slots=True)
|
|
159
|
+
class QRAGArtifactIdentity:
|
|
160
|
+
"""Treatment-defining identity for one frozen Q-RAG evaluation cell."""
|
|
161
|
+
|
|
162
|
+
checkpoint_manifest_sha256: str
|
|
163
|
+
checkpoint_file_sha256: str
|
|
164
|
+
embedder_manifest_sha256: str
|
|
165
|
+
source_manifest_sha256: str
|
|
166
|
+
compatibility_manifest_sha256: str
|
|
167
|
+
retriever_revision: str
|
|
168
|
+
retriever_deployment_fingerprint_sha256: str
|
|
169
|
+
corpus_sha256: str
|
|
170
|
+
index_sha256: str
|
|
171
|
+
reader_repository: str
|
|
172
|
+
reader_revision: str
|
|
173
|
+
reader_deployment_fingerprint_sha256: str
|
|
174
|
+
reader_profile: str = _NATIVE_READER_PROFILE
|
|
175
|
+
checkpoint_repository: str = QRAG_CHECKPOINT_REPOSITORY
|
|
176
|
+
checkpoint_revision: str = QRAG_CHECKPOINT_REVISION
|
|
177
|
+
embedder_repository: str = QRAG_EMBEDDER_REPOSITORY
|
|
178
|
+
embedder_revision: str = QRAG_EMBEDDER_REVISION
|
|
179
|
+
environment_config_sha256: str = QRAG_ENVIRONMENT_CONFIG_SHA256
|
|
180
|
+
action_schema_sha256: str = QRAG_ACTION_SCHEMA_SHA256
|
|
181
|
+
candidate_builder_sha256: str = QRAG_CANDIDATE_BUILDER_SHA256
|
|
182
|
+
reader_prompt_sha256: str = QRAG_READER_PROMPT_SHA256
|
|
183
|
+
checkpoint_config_sha256: str = QRAG_CHECKPOINT_CONFIG_SHA256
|
|
184
|
+
profile_id: str = QRAG_PROFILE_ID
|
|
185
|
+
|
|
186
|
+
def __post_init__(self) -> None:
|
|
187
|
+
fixed = {
|
|
188
|
+
"checkpoint_repository": QRAG_CHECKPOINT_REPOSITORY,
|
|
189
|
+
"checkpoint_revision": QRAG_CHECKPOINT_REVISION,
|
|
190
|
+
"checkpoint_file_sha256": QRAG_CHECKPOINT_FILE_SHA256,
|
|
191
|
+
"checkpoint_config_sha256": QRAG_CHECKPOINT_CONFIG_SHA256,
|
|
192
|
+
"embedder_repository": QRAG_EMBEDDER_REPOSITORY,
|
|
193
|
+
"embedder_revision": QRAG_EMBEDDER_REVISION,
|
|
194
|
+
"source_manifest_sha256": QRAG_SOURCE_MANIFEST_SHA256,
|
|
195
|
+
"environment_config_sha256": QRAG_ENVIRONMENT_CONFIG_SHA256,
|
|
196
|
+
"action_schema_sha256": QRAG_ACTION_SCHEMA_SHA256,
|
|
197
|
+
"candidate_builder_sha256": QRAG_CANDIDATE_BUILDER_SHA256,
|
|
198
|
+
"profile_id": QRAG_PROFILE_ID,
|
|
199
|
+
}
|
|
200
|
+
for name, expected in fixed.items():
|
|
201
|
+
if getattr(self, name) != expected:
|
|
202
|
+
raise ValidationError(f"Q-RAG {name} is fixed to {expected}")
|
|
203
|
+
for name in (
|
|
204
|
+
"checkpoint_manifest_sha256",
|
|
205
|
+
"embedder_manifest_sha256",
|
|
206
|
+
"compatibility_manifest_sha256",
|
|
207
|
+
"retriever_deployment_fingerprint_sha256",
|
|
208
|
+
"corpus_sha256",
|
|
209
|
+
"index_sha256",
|
|
210
|
+
"reader_deployment_fingerprint_sha256",
|
|
211
|
+
):
|
|
212
|
+
value = getattr(self, name)
|
|
213
|
+
if not isinstance(value, str) or not _HEX64.fullmatch(value):
|
|
214
|
+
raise ValidationError(f"Q-RAG {name} must be a lowercase SHA-256 digest")
|
|
215
|
+
for name in (
|
|
216
|
+
"retriever_revision",
|
|
217
|
+
"reader_repository",
|
|
218
|
+
"reader_revision",
|
|
219
|
+
"reader_profile",
|
|
220
|
+
):
|
|
221
|
+
value = getattr(self, name)
|
|
222
|
+
if not isinstance(value, str) or not value.strip():
|
|
223
|
+
raise ValidationError(f"Q-RAG {name} must not be empty")
|
|
224
|
+
if self.reader_profile not in {
|
|
225
|
+
_NATIVE_READER_PROFILE, _TRANSFER_READER_PROFILE, QRAG_INSTRUCTION_READER_PROFILE,
|
|
226
|
+
}:
|
|
227
|
+
raise ValidationError("Q-RAG reader_profile is unsupported")
|
|
228
|
+
expected_prompt = (
|
|
229
|
+
QRAG_INSTRUCTION_PROMPT_SHA256
|
|
230
|
+
if self.reader_profile == QRAG_INSTRUCTION_READER_PROFILE
|
|
231
|
+
else QRAG_READER_PROMPT_SHA256
|
|
232
|
+
)
|
|
233
|
+
if self.reader_prompt_sha256 != expected_prompt:
|
|
234
|
+
raise ValidationError("Q-RAG reader prompt does not match the explicit reader profile")
|
|
235
|
+
|
|
236
|
+
def as_mapping(self) -> Mapping[str, Any]:
|
|
237
|
+
return freeze_mapping(asdict(self))
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def identity_sha256(self) -> str:
|
|
241
|
+
return content_hash(self.as_mapping())
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
@dataclass(frozen=True, slots=True)
|
|
245
|
+
class QRAGControls:
|
|
246
|
+
"""Fixed two-action selector; configurable reader output ceiling.
|
|
247
|
+
|
|
248
|
+
4000 preserves the upstream reader default. The effective request ceiling
|
|
249
|
+
is also bounded by the run's remaining output tokens, not a requirement
|
|
250
|
+
to generate or reserve all 4000 tokens.
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
max_select_actions: int = 2
|
|
254
|
+
max_output_tokens: int = 4000
|
|
255
|
+
max_candidates: int = 128
|
|
256
|
+
max_candidate_chars: int = 2_000_000
|
|
257
|
+
|
|
258
|
+
def __post_init__(self) -> None:
|
|
259
|
+
if self.max_select_actions != 2:
|
|
260
|
+
raise ValidationError("Q-RAG HotpotQA frozen profile requires max_select_actions=2")
|
|
261
|
+
if any(
|
|
262
|
+
isinstance(value, bool) or not isinstance(value, int) or value < 1
|
|
263
|
+
for value in (self.max_output_tokens, self.max_candidates, self.max_candidate_chars)
|
|
264
|
+
):
|
|
265
|
+
raise ValidationError("Q-RAG output and candidate limits must be positive integers")
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@dataclass(frozen=True, slots=True)
|
|
269
|
+
class QRAGStep:
|
|
270
|
+
index: int
|
|
271
|
+
available_indices: tuple[int, ...]
|
|
272
|
+
q_values: tuple[float, ...]
|
|
273
|
+
action_index: int
|
|
274
|
+
selected_q_value: float
|
|
275
|
+
selected_indices: tuple[int, ...]
|
|
276
|
+
selected_document_ids: tuple[str, ...]
|
|
277
|
+
|
|
278
|
+
@classmethod
|
|
279
|
+
def from_mapping(cls, value: Mapping[str, object]) -> QRAGStep:
|
|
280
|
+
available = _integer_tuple(
|
|
281
|
+
value.get("available_indices"), label="Q-RAG available_indices", unique=True
|
|
282
|
+
)
|
|
283
|
+
q_raw = value.get("q_values")
|
|
284
|
+
if isinstance(q_raw, (str, bytes)) or not isinstance(q_raw, Sequence):
|
|
285
|
+
raise AlgorithmOutputError("Q-RAG q_values must be a sequence")
|
|
286
|
+
q_values = tuple(finite_number(item, label="Q-RAG q_value") for item in q_raw)
|
|
287
|
+
if len(q_values) != len(available):
|
|
288
|
+
raise AlgorithmOutputError("Q-RAG q_values must align with available_indices")
|
|
289
|
+
selected_ids_raw = value.get("selected_document_ids")
|
|
290
|
+
if isinstance(selected_ids_raw, (str, bytes)) or not isinstance(selected_ids_raw, Sequence):
|
|
291
|
+
raise AlgorithmOutputError("Q-RAG selected_document_ids must be a sequence")
|
|
292
|
+
selected_ids = tuple(selected_ids_raw)
|
|
293
|
+
if not all(isinstance(item, str) and item for item in selected_ids):
|
|
294
|
+
raise AlgorithmOutputError("Q-RAG selected_document_ids must contain non-empty strings")
|
|
295
|
+
return cls(
|
|
296
|
+
index=nonnegative_integer(value.get("index"), label="Q-RAG step index"),
|
|
297
|
+
available_indices=available,
|
|
298
|
+
q_values=q_values,
|
|
299
|
+
action_index=nonnegative_integer(value.get("action_index"), label="Q-RAG action_index"),
|
|
300
|
+
selected_q_value=finite_number(
|
|
301
|
+
value.get("selected_q_value"), label="Q-RAG selected_q_value"
|
|
302
|
+
),
|
|
303
|
+
selected_indices=_integer_tuple(
|
|
304
|
+
value.get("selected_indices"),
|
|
305
|
+
label="Q-RAG selected_indices",
|
|
306
|
+
unique=True,
|
|
307
|
+
),
|
|
308
|
+
selected_document_ids=selected_ids,
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
@dataclass(slots=True)
|
|
313
|
+
class _QRAGWorker:
|
|
314
|
+
artifacts: QRAGArtifactIdentity
|
|
315
|
+
acknowledgements: QRAGLicenseAcknowledgement = QRAGLicenseAcknowledgement()
|
|
316
|
+
client: WorkerClient | None = None
|
|
317
|
+
controls: QRAGControls = QRAGControls()
|
|
318
|
+
release_id: str = "acquire.qrag.released_checkpoint_native"
|
|
319
|
+
profile_kind: str = "controlled_adapter"
|
|
320
|
+
method_id: str = "qrag"
|
|
321
|
+
family: SemanticFamily = SemanticFamily.ACQUIRE
|
|
322
|
+
|
|
323
|
+
def __post_init__(self) -> None:
|
|
324
|
+
if not isinstance(self.artifacts, QRAGArtifactIdentity):
|
|
325
|
+
raise ValidationError("Q-RAG requires QRAGArtifactIdentity")
|
|
326
|
+
if not isinstance(self.acknowledgements, QRAGLicenseAcknowledgement):
|
|
327
|
+
raise ValidationError("Q-RAG requires QRAGLicenseAcknowledgement")
|
|
328
|
+
if not isinstance(self.controls, QRAGControls):
|
|
329
|
+
raise ValidationError("Q-RAG controls must be QRAGControls")
|
|
330
|
+
|
|
331
|
+
def run(self, state: FrozenAgentState, context: InterventionContext) -> CompositeResult:
|
|
332
|
+
self.acknowledgements.require_complete()
|
|
333
|
+
self._validate_reader_profile()
|
|
334
|
+
if not state.query.strip():
|
|
335
|
+
raise ValidationError("Q-RAG requires a non-empty question")
|
|
336
|
+
instruction_adapter = self.artifacts.reader_profile == QRAG_INSTRUCTION_READER_PROFILE
|
|
337
|
+
if state.messages or (state.instruction.strip() and not instruction_adapter):
|
|
338
|
+
raise ValidationError(
|
|
339
|
+
"the frozen Q-RAG profile accepts one question; instruction/messages "
|
|
340
|
+
"require a separate factorial profile"
|
|
341
|
+
)
|
|
342
|
+
if instruction_adapter and state.tool_names:
|
|
343
|
+
raise ValidationError("Q-RAG instruction reader does not execute tools")
|
|
344
|
+
if len(state.context) > self.controls.max_candidates:
|
|
345
|
+
raise ValidationError("Q-RAG candidate count exceeds max_candidates")
|
|
346
|
+
if sum(len(block.text) for block in state.context) > self.controls.max_candidate_chars:
|
|
347
|
+
raise ValidationError("Q-RAG candidate text exceeds max_candidate_chars")
|
|
348
|
+
candidate_ids = tuple(block.block_id for block in state.context)
|
|
349
|
+
if any(not value for value in candidate_ids) or len(candidate_ids) != len(
|
|
350
|
+
set(candidate_ids)
|
|
351
|
+
):
|
|
352
|
+
raise ValidationError("Q-RAG candidates require unique non-empty IDs")
|
|
353
|
+
|
|
354
|
+
candidates = tuple(
|
|
355
|
+
{"document_id": block.block_id, "text": block.text} for block in state.context
|
|
356
|
+
)
|
|
357
|
+
candidate_pool_sha256 = content_hash(candidates)
|
|
358
|
+
candidate_order_sha256 = content_hash(candidate_ids)
|
|
359
|
+
remaining_budget = _remaining_budget(state, context)
|
|
360
|
+
if remaining_budget["model_calls"] < 1:
|
|
361
|
+
raise BudgetExceededError("Q-RAG reader requires one remaining model call")
|
|
362
|
+
if remaining_budget["output_tokens"] < 1:
|
|
363
|
+
raise BudgetExceededError("Q-RAG reader has no remaining output tokens")
|
|
364
|
+
reader_budget = {
|
|
365
|
+
"configured_max_output_tokens": self.controls.max_output_tokens,
|
|
366
|
+
"effective_max_output_tokens": min(
|
|
367
|
+
self.controls.max_output_tokens, remaining_budget["output_tokens"]
|
|
368
|
+
),
|
|
369
|
+
"remaining_output_tokens": remaining_budget["output_tokens"],
|
|
370
|
+
"preset": (
|
|
371
|
+
"upstream_default" if self.controls.max_output_tokens == 4000 else "custom"
|
|
372
|
+
),
|
|
373
|
+
}
|
|
374
|
+
if state.budget.max_cost_usd is not None:
|
|
375
|
+
raise BudgetExceededError(
|
|
376
|
+
"Q-RAG external reader is unpriced; a cost budget cannot be guaranteed"
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
worker = resolve_worker(self.client, context, label="Q-RAG")
|
|
380
|
+
worker_identity = worker_fingerprint(worker, label="Q-RAG")
|
|
381
|
+
artifact_mapping = self.artifacts.as_mapping()
|
|
382
|
+
reader_task = {
|
|
383
|
+
"instruction": state.instruction,
|
|
384
|
+
"candidate_annotations": tuple(
|
|
385
|
+
{"document_id": block.block_id, "source": block.source, "metadata": block.metadata}
|
|
386
|
+
for block in state.context
|
|
387
|
+
),
|
|
388
|
+
} if instruction_adapter else None
|
|
389
|
+
reader_task_fields = (
|
|
390
|
+
{"reader_task": reader_task, "reader_task_sha256": content_hash(reader_task)}
|
|
391
|
+
if instruction_adapter else {}
|
|
392
|
+
)
|
|
393
|
+
request = MethodWorkerRequest(
|
|
394
|
+
method_id=self.method_id,
|
|
395
|
+
release_id=self.release_id,
|
|
396
|
+
upstream_commit=QRAG_UPSTREAM_COMMIT,
|
|
397
|
+
state_hash=state.state_hash,
|
|
398
|
+
payload={
|
|
399
|
+
**reader_task_fields,
|
|
400
|
+
"profile_id": self.artifacts.profile_id,
|
|
401
|
+
"task_id": state.task_id,
|
|
402
|
+
"question": state.query,
|
|
403
|
+
"candidates": candidates,
|
|
404
|
+
"candidate_pool_sha256": candidate_pool_sha256,
|
|
405
|
+
"candidate_order_sha256": candidate_order_sha256,
|
|
406
|
+
"artifacts": artifact_mapping,
|
|
407
|
+
"artifact_identity_sha256": self.artifacts.identity_sha256,
|
|
408
|
+
"acknowledgements": self.acknowledgements.as_mapping(),
|
|
409
|
+
"controls": asdict(self.controls),
|
|
410
|
+
"remaining_budget": remaining_budget,
|
|
411
|
+
"reader_budget": reader_budget,
|
|
412
|
+
"seed": context.seed,
|
|
413
|
+
"inference_contract": {
|
|
414
|
+
"mode": "frozen_checkpoint_inference",
|
|
415
|
+
"allow_training": False,
|
|
416
|
+
"allow_gold_answer": False,
|
|
417
|
+
"allow_supporting_fact_labels": False,
|
|
418
|
+
"allow_reward": False,
|
|
419
|
+
"allow_ground_truth_feedback": False,
|
|
420
|
+
"allow_stop_action": False,
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
dependency_fingerprints={
|
|
424
|
+
"worker": worker_identity,
|
|
425
|
+
"artifact_identity_sha256": self.artifacts.identity_sha256,
|
|
426
|
+
"candidate_pool_sha256": candidate_pool_sha256,
|
|
427
|
+
"candidate_order_sha256": candidate_order_sha256,
|
|
428
|
+
},
|
|
429
|
+
minimum_reservation={"model_calls": 1},
|
|
430
|
+
protocol_version=QRAG_INSTRUCTION_PROTOCOL if instruction_adapter else QRAG_PROTOCOL,
|
|
431
|
+
)
|
|
432
|
+
response = call_worker(worker, request)
|
|
433
|
+
payload = response.payload
|
|
434
|
+
if instruction_adapter and payload.get("reader_task_sha256") != content_hash(reader_task):
|
|
435
|
+
raise AlgorithmOutputError("Q-RAG worker task instruction binding mismatch")
|
|
436
|
+
|
|
437
|
+
echoed_artifacts = payload.get("artifacts")
|
|
438
|
+
if not isinstance(echoed_artifacts, Mapping) or content_hash(
|
|
439
|
+
echoed_artifacts
|
|
440
|
+
) != content_hash(artifact_mapping):
|
|
441
|
+
raise AlgorithmOutputError("Q-RAG artifact identity mismatch")
|
|
442
|
+
for key, expected in (
|
|
443
|
+
("profile_id", self.artifacts.profile_id),
|
|
444
|
+
("artifact_identity_sha256", self.artifacts.identity_sha256),
|
|
445
|
+
("candidate_pool_sha256", candidate_pool_sha256),
|
|
446
|
+
("candidate_order_sha256", candidate_order_sha256),
|
|
447
|
+
):
|
|
448
|
+
if required_text(payload, key, label="Q-RAG response") != expected:
|
|
449
|
+
raise AlgorithmOutputError(f"Q-RAG {key} mismatch")
|
|
450
|
+
|
|
451
|
+
attestation = _validate_runtime_attestation(payload, artifacts=self.artifacts)
|
|
452
|
+
if payload.get("reader_budget") != reader_budget:
|
|
453
|
+
raise AlgorithmOutputError("Q-RAG worker reader budget mismatch")
|
|
454
|
+
steps = tuple(
|
|
455
|
+
QRAGStep.from_mapping(row)
|
|
456
|
+
for row in mapping_sequence(payload.get("trajectory"), label="Q-RAG trajectory")
|
|
457
|
+
)
|
|
458
|
+
selected_indices = _validate_trajectory(
|
|
459
|
+
steps,
|
|
460
|
+
candidate_ids=candidate_ids,
|
|
461
|
+
max_select_actions=self.controls.max_select_actions,
|
|
462
|
+
)
|
|
463
|
+
final_selected = _integer_tuple(
|
|
464
|
+
payload.get("selected_indices"),
|
|
465
|
+
label="Q-RAG final selected_indices",
|
|
466
|
+
unique=True,
|
|
467
|
+
)
|
|
468
|
+
if final_selected != selected_indices:
|
|
469
|
+
raise AlgorithmOutputError("Q-RAG final selected indices disagree with trajectory")
|
|
470
|
+
final_document_ids = _string_tuple(
|
|
471
|
+
payload.get("selected_document_ids"),
|
|
472
|
+
label="Q-RAG final selected_document_ids",
|
|
473
|
+
)
|
|
474
|
+
expected_document_ids = tuple(candidate_ids[index] for index in selected_indices)
|
|
475
|
+
if final_document_ids != expected_document_ids:
|
|
476
|
+
raise AlgorithmOutputError("Q-RAG final selected document IDs disagree with trajectory")
|
|
477
|
+
|
|
478
|
+
termination = required_text(payload, "termination", label="Q-RAG response")
|
|
479
|
+
expected_termination = _expected_termination(
|
|
480
|
+
candidate_count=len(candidate_ids),
|
|
481
|
+
selected_count=len(selected_indices),
|
|
482
|
+
max_select_actions=self.controls.max_select_actions,
|
|
483
|
+
)
|
|
484
|
+
if termination != expected_termination:
|
|
485
|
+
raise AlgorithmOutputError("Q-RAG termination disagrees with fixed environment horizon")
|
|
486
|
+
answer = required_text(payload, "final_answer", label="Q-RAG response")
|
|
487
|
+
trajectory_sha256 = required_text(payload, "trajectory_sha256", label="Q-RAG response")
|
|
488
|
+
if not _HEX64.fullmatch(trajectory_sha256) or trajectory_sha256 != content_hash(
|
|
489
|
+
payload.get("trajectory")
|
|
490
|
+
):
|
|
491
|
+
raise AlgorithmOutputError("Q-RAG trajectory_sha256 mismatch")
|
|
492
|
+
if response.usage.model_calls != 1:
|
|
493
|
+
raise AlgorithmOutputError("Q-RAG frozen reader must report exactly one model call")
|
|
494
|
+
if response.usage.retrieval_calls != 0 or response.usage.tool_calls != 0:
|
|
495
|
+
raise AlgorithmOutputError(
|
|
496
|
+
"Q-RAG receives a frozen candidate pool and cannot report retrieval/tool calls"
|
|
497
|
+
)
|
|
498
|
+
_validate_usage_against_sent_budget(response.usage, remaining_budget)
|
|
499
|
+
if response.usage.output_tokens > reader_budget["effective_max_output_tokens"]:
|
|
500
|
+
raise AlgorithmOutputError("Q-RAG worker exceeded effective reader output limit")
|
|
501
|
+
|
|
502
|
+
selected_blocks = tuple(state.context[index] for index in selected_indices)
|
|
503
|
+
trace_events: list[TraceEvent] = [
|
|
504
|
+
TraceEvent(
|
|
505
|
+
TracePhase.PREPARE,
|
|
506
|
+
"frozen_candidate_pool",
|
|
507
|
+
{
|
|
508
|
+
"profile_id": self.artifacts.profile_id,
|
|
509
|
+
"artifact_identity_sha256": self.artifacts.identity_sha256,
|
|
510
|
+
"candidate_pool_sha256": candidate_pool_sha256,
|
|
511
|
+
"candidate_order_sha256": candidate_order_sha256,
|
|
512
|
+
"checkpoint_revision": self.artifacts.checkpoint_revision,
|
|
513
|
+
"embedder_revision": self.artifacts.embedder_revision,
|
|
514
|
+
"retriever_revision": self.artifacts.retriever_revision,
|
|
515
|
+
"reader_revision": self.artifacts.reader_revision,
|
|
516
|
+
"selection_budget": self.controls.max_select_actions,
|
|
517
|
+
"reader_budget": reader_budget,
|
|
518
|
+
"paper_native_parity_claimed": False,
|
|
519
|
+
},
|
|
520
|
+
)
|
|
521
|
+
]
|
|
522
|
+
trace_events.extend(
|
|
523
|
+
TraceEvent(
|
|
524
|
+
TracePhase.OBSERVE,
|
|
525
|
+
"candidate_index_policy_step",
|
|
526
|
+
{
|
|
527
|
+
"index": step.index,
|
|
528
|
+
"available_indices": step.available_indices,
|
|
529
|
+
"q_values": step.q_values,
|
|
530
|
+
"action_index": step.action_index,
|
|
531
|
+
"selected_q_value": step.selected_q_value,
|
|
532
|
+
"selected_indices": step.selected_indices,
|
|
533
|
+
"selected_document_ids": step.selected_document_ids,
|
|
534
|
+
},
|
|
535
|
+
)
|
|
536
|
+
for step in steps
|
|
537
|
+
)
|
|
538
|
+
trace_events.append(
|
|
539
|
+
TraceEvent(
|
|
540
|
+
TracePhase.FINALIZE,
|
|
541
|
+
"selected_context_and_reader_answer",
|
|
542
|
+
{
|
|
543
|
+
"selected_indices": selected_indices,
|
|
544
|
+
"selected_document_ids": expected_document_ids,
|
|
545
|
+
"termination": termination,
|
|
546
|
+
"trajectory_sha256": trajectory_sha256,
|
|
547
|
+
"answer_is_intervention_input": False,
|
|
548
|
+
},
|
|
549
|
+
)
|
|
550
|
+
)
|
|
551
|
+
trace = ExecutionTrace(
|
|
552
|
+
method_id=self.method_id,
|
|
553
|
+
release_id=self.release_id,
|
|
554
|
+
events=tuple(trace_events),
|
|
555
|
+
counters={
|
|
556
|
+
**external_usage_counters(response.usage),
|
|
557
|
+
"worker_calls": 1,
|
|
558
|
+
"policy_steps": len(steps),
|
|
559
|
+
"selected_documents": len(selected_blocks),
|
|
560
|
+
},
|
|
561
|
+
)
|
|
562
|
+
return CompositeResult(
|
|
563
|
+
method_id=self.method_id,
|
|
564
|
+
release_id=self.release_id,
|
|
565
|
+
source_state_hash=state.state_hash,
|
|
566
|
+
final_answer=answer,
|
|
567
|
+
evidence=selected_blocks,
|
|
568
|
+
trace=trace,
|
|
569
|
+
implementation_identity=(f"thin_external_wrapper:griver/Q-RAG@{QRAG_UPSTREAM_COMMIT}"),
|
|
570
|
+
profile_kind=self.profile_kind,
|
|
571
|
+
metadata={
|
|
572
|
+
"implementation_origin": "thin_external_wrapper",
|
|
573
|
+
"profile_id": self.artifacts.profile_id,
|
|
574
|
+
"artifact_identity_sha256": self.artifacts.identity_sha256,
|
|
575
|
+
"source_license_id": "NOASSERTION",
|
|
576
|
+
"checkpoint_license_id": "CC-BY-4.0",
|
|
577
|
+
"source_license_acknowledged": True,
|
|
578
|
+
"checkpoint_license_acknowledged": True,
|
|
579
|
+
"checkpoint_repository": self.artifacts.checkpoint_repository,
|
|
580
|
+
"checkpoint_revision": self.artifacts.checkpoint_revision,
|
|
581
|
+
"embedder_repository": self.artifacts.embedder_repository,
|
|
582
|
+
"embedder_revision": self.artifacts.embedder_revision,
|
|
583
|
+
"retriever_revision": self.artifacts.retriever_revision,
|
|
584
|
+
"reader_repository": self.artifacts.reader_repository,
|
|
585
|
+
"reader_revision": self.artifacts.reader_revision,
|
|
586
|
+
"reader_profile": self.artifacts.reader_profile,
|
|
587
|
+
"input_adapter": "instruction_preserving_v1" if instruction_adapter else "question_only",
|
|
588
|
+
"reader_prompt_sha256": self.artifacts.reader_prompt_sha256,
|
|
589
|
+
"reader_task_sha256": content_hash(reader_task) if instruction_adapter else None,
|
|
590
|
+
"task_instruction_preserved": instruction_adapter,
|
|
591
|
+
"reader_budget": reader_budget,
|
|
592
|
+
"candidate_pool_sha256": candidate_pool_sha256,
|
|
593
|
+
"candidate_order_sha256": candidate_order_sha256,
|
|
594
|
+
"selected_indices": selected_indices,
|
|
595
|
+
"selected_document_ids": expected_document_ids,
|
|
596
|
+
"termination": termination,
|
|
597
|
+
"trajectory_sha256": trajectory_sha256,
|
|
598
|
+
"runtime_attestation": attestation,
|
|
599
|
+
"worker_fingerprint": worker_identity,
|
|
600
|
+
"treatment_scope": "native_checkpoint_embedder_and_value_policy",
|
|
601
|
+
"reader_is_controlled_factor": True,
|
|
602
|
+
"paper_native_parity_claimed": False,
|
|
603
|
+
"gold_answer_used": False,
|
|
604
|
+
"supporting_fact_labels_used": False,
|
|
605
|
+
"reward_used": False,
|
|
606
|
+
"training_called": False,
|
|
607
|
+
},
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
def _validate_reader_profile(self) -> None:
|
|
611
|
+
expected = (
|
|
612
|
+
_TRANSFER_READER_PROFILE
|
|
613
|
+
if self.profile_kind == "factorial_adapter"
|
|
614
|
+
else _NATIVE_READER_PROFILE
|
|
615
|
+
)
|
|
616
|
+
allowed = {expected}
|
|
617
|
+
if self.profile_kind == "factorial_adapter":
|
|
618
|
+
allowed.add(QRAG_INSTRUCTION_READER_PROFILE)
|
|
619
|
+
if self.artifacts.reader_profile not in allowed:
|
|
620
|
+
raise ValidationError(f"Q-RAG {self.release_id} requires reader_profile={expected}")
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
class QRAGNativeWorker(_QRAGWorker):
|
|
624
|
+
"""Native released checkpoint/retriever treatment with a controlled reader.
|
|
625
|
+
|
|
626
|
+
The historical class name is retained for registry compatibility. The
|
|
627
|
+
result is deliberately labelled ``controlled_adapter`` and never claims
|
|
628
|
+
end-to-end paper parity because upstream does not pin the reader artifact
|
|
629
|
+
and the benchmark-safe environment removes ground-truth feedback.
|
|
630
|
+
"""
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
class QRAGReaderTransferWorker(_QRAGWorker):
|
|
634
|
+
def __init__(
|
|
635
|
+
self,
|
|
636
|
+
artifacts: QRAGArtifactIdentity,
|
|
637
|
+
acknowledgements: QRAGLicenseAcknowledgement | None = None,
|
|
638
|
+
client: WorkerClient | None = None,
|
|
639
|
+
*,
|
|
640
|
+
controls: QRAGControls | None = None,
|
|
641
|
+
) -> None:
|
|
642
|
+
super().__init__(
|
|
643
|
+
artifacts=artifacts,
|
|
644
|
+
acknowledgements=(
|
|
645
|
+
acknowledgements if acknowledgements is not None else QRAGLicenseAcknowledgement()
|
|
646
|
+
),
|
|
647
|
+
client=client,
|
|
648
|
+
controls=controls if controls is not None else QRAGControls(),
|
|
649
|
+
release_id="acquire.qrag.reader_transfer_factorial",
|
|
650
|
+
profile_kind="factorial_adapter",
|
|
651
|
+
)
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
def _validate_runtime_attestation(
|
|
655
|
+
payload: Mapping[str, Any], *, artifacts: QRAGArtifactIdentity
|
|
656
|
+
) -> Mapping[str, Any]:
|
|
657
|
+
value = payload.get("runtime_attestation")
|
|
658
|
+
if not isinstance(value, Mapping):
|
|
659
|
+
raise AlgorithmOutputError("Q-RAG requires runtime_attestation")
|
|
660
|
+
expected: Mapping[str, Any] = {
|
|
661
|
+
"source_commit": QRAG_UPSTREAM_COMMIT,
|
|
662
|
+
"source_manifest_sha256": artifacts.source_manifest_sha256,
|
|
663
|
+
"compatibility_manifest_sha256": artifacts.compatibility_manifest_sha256,
|
|
664
|
+
"checkpoint_repository": artifacts.checkpoint_repository,
|
|
665
|
+
"checkpoint_revision": artifacts.checkpoint_revision,
|
|
666
|
+
"checkpoint_manifest_sha256": artifacts.checkpoint_manifest_sha256,
|
|
667
|
+
"checkpoint_file_sha256": artifacts.checkpoint_file_sha256,
|
|
668
|
+
"embedder_repository": artifacts.embedder_repository,
|
|
669
|
+
"embedder_revision": artifacts.embedder_revision,
|
|
670
|
+
"official_candidate_builder_called": True,
|
|
671
|
+
"official_pqn_select_action_called": True,
|
|
672
|
+
"official_qa_env_step_called": True,
|
|
673
|
+
"dummy_feedback_used": True,
|
|
674
|
+
"ground_truth_feedback_used": False,
|
|
675
|
+
"gold_answer_used": False,
|
|
676
|
+
"supporting_fact_labels_used": False,
|
|
677
|
+
"reward_used": False,
|
|
678
|
+
"training_called": False,
|
|
679
|
+
"stop_action_used": False,
|
|
680
|
+
"strict_state_dict_load": True,
|
|
681
|
+
"safe_weights_only_load": True,
|
|
682
|
+
"checkpoint_eval_mode": True,
|
|
683
|
+
"source_user_mounted": True,
|
|
684
|
+
"checkpoint_user_mounted": True,
|
|
685
|
+
"checkpoint_deserialization_isolated": True,
|
|
686
|
+
"host_secret_mounts": False,
|
|
687
|
+
"reader_profile": artifacts.reader_profile,
|
|
688
|
+
}
|
|
689
|
+
for key, expected_value in expected.items():
|
|
690
|
+
if value.get(key) != expected_value:
|
|
691
|
+
raise AlgorithmOutputError(f"Q-RAG runtime attestation {key} mismatch")
|
|
692
|
+
if value.get("source_attestation") not in {"git_checkout", "verified_archive_snapshot"}:
|
|
693
|
+
raise AlgorithmOutputError("Q-RAG source attestation is unsupported")
|
|
694
|
+
return freeze_mapping(value)
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
def _validate_trajectory(
|
|
698
|
+
steps: tuple[QRAGStep, ...],
|
|
699
|
+
*,
|
|
700
|
+
candidate_ids: tuple[str, ...],
|
|
701
|
+
max_select_actions: int,
|
|
702
|
+
) -> tuple[int, ...]:
|
|
703
|
+
if tuple(step.index for step in steps) != tuple(range(len(steps))):
|
|
704
|
+
raise AlgorithmOutputError("Q-RAG step indices must be contiguous")
|
|
705
|
+
expected_steps = min(len(candidate_ids), max_select_actions)
|
|
706
|
+
if len(steps) != expected_steps:
|
|
707
|
+
raise AlgorithmOutputError("Q-RAG trajectory length disagrees with fixed horizon")
|
|
708
|
+
selected: list[int] = []
|
|
709
|
+
for step in steps:
|
|
710
|
+
expected_available = tuple(
|
|
711
|
+
index for index in range(len(candidate_ids)) if index not in selected
|
|
712
|
+
)
|
|
713
|
+
if step.available_indices != expected_available:
|
|
714
|
+
raise AlgorithmOutputError("Q-RAG available-index trajectory is inconsistent")
|
|
715
|
+
if step.action_index not in expected_available:
|
|
716
|
+
raise AlgorithmOutputError("Q-RAG action is unavailable or out of range")
|
|
717
|
+
q_position = expected_available.index(step.action_index)
|
|
718
|
+
if not math.isclose(
|
|
719
|
+
step.selected_q_value,
|
|
720
|
+
step.q_values[q_position],
|
|
721
|
+
rel_tol=1e-12,
|
|
722
|
+
abs_tol=1e-12,
|
|
723
|
+
):
|
|
724
|
+
raise AlgorithmOutputError("Q-RAG selected_q_value disagrees with q_values")
|
|
725
|
+
if step.q_values and step.selected_q_value < max(step.q_values):
|
|
726
|
+
raise AlgorithmOutputError("Q-RAG action is not an argmax available Q-value")
|
|
727
|
+
selected.append(step.action_index)
|
|
728
|
+
if step.selected_indices != tuple(selected):
|
|
729
|
+
raise AlgorithmOutputError("Q-RAG selected-index history is inconsistent")
|
|
730
|
+
expected_ids = tuple(candidate_ids[index] for index in selected)
|
|
731
|
+
if step.selected_document_ids != expected_ids:
|
|
732
|
+
raise AlgorithmOutputError("Q-RAG selected-document history is inconsistent")
|
|
733
|
+
return tuple(selected)
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
def _expected_termination(
|
|
737
|
+
*, candidate_count: int, selected_count: int, max_select_actions: int
|
|
738
|
+
) -> str:
|
|
739
|
+
if candidate_count == 0:
|
|
740
|
+
return "empty_candidates"
|
|
741
|
+
if selected_count == candidate_count:
|
|
742
|
+
return "candidate_exhausted"
|
|
743
|
+
if selected_count == max_select_actions:
|
|
744
|
+
return "fixed_step_budget"
|
|
745
|
+
raise AlgorithmOutputError("Q-RAG trajectory has no valid fixed-horizon termination")
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
def _integer_tuple(value: Any, *, label: str, unique: bool) -> tuple[int, ...]:
|
|
749
|
+
if isinstance(value, (str, bytes)) or not isinstance(value, Sequence):
|
|
750
|
+
raise AlgorithmOutputError(f"{label} must be a sequence")
|
|
751
|
+
result = tuple(nonnegative_integer(item, label=label) for item in value)
|
|
752
|
+
if unique and len(result) != len(set(result)):
|
|
753
|
+
raise AlgorithmOutputError(f"{label} contains duplicates")
|
|
754
|
+
return result
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
def _string_tuple(value: Any, *, label: str) -> tuple[str, ...]:
|
|
758
|
+
if isinstance(value, (str, bytes)) or not isinstance(value, Sequence):
|
|
759
|
+
raise AlgorithmOutputError(f"{label} must be a sequence")
|
|
760
|
+
result = tuple(value)
|
|
761
|
+
if not all(isinstance(item, str) and item for item in result):
|
|
762
|
+
raise AlgorithmOutputError(f"{label} must contain non-empty strings")
|
|
763
|
+
if len(result) != len(set(result)):
|
|
764
|
+
raise AlgorithmOutputError(f"{label} contains duplicates")
|
|
765
|
+
return result
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
def _remaining_budget(
|
|
769
|
+
state: FrozenAgentState, context: InterventionContext
|
|
770
|
+
) -> Mapping[str, int | None]:
|
|
771
|
+
usage = None
|
|
772
|
+
ledger = context.budget_ledger
|
|
773
|
+
if ledger is not None:
|
|
774
|
+
ledger_budget = getattr(ledger, "budget", None)
|
|
775
|
+
usage = getattr(ledger, "usage", None)
|
|
776
|
+
if ledger_budget != state.budget or usage is None:
|
|
777
|
+
raise ValidationError("Q-RAG received an incompatible budget ledger")
|
|
778
|
+
|
|
779
|
+
def consumed(name: str) -> int:
|
|
780
|
+
value = 0 if usage is None else getattr(usage, name, None)
|
|
781
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 0:
|
|
782
|
+
raise ValidationError(f"Q-RAG budget usage {name} is invalid")
|
|
783
|
+
return value
|
|
784
|
+
|
|
785
|
+
remaining_context = None
|
|
786
|
+
if state.budget.max_context_tokens is not None:
|
|
787
|
+
remaining_context = max(0, state.budget.max_context_tokens - consumed("input_tokens"))
|
|
788
|
+
return freeze_mapping(
|
|
789
|
+
{
|
|
790
|
+
"model_calls": max(0, state.budget.max_model_calls - consumed("model_calls")),
|
|
791
|
+
"output_tokens": max(0, state.budget.max_output_tokens - consumed("output_tokens")),
|
|
792
|
+
"context_tokens": remaining_context,
|
|
793
|
+
}
|
|
794
|
+
)
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
def _validate_usage_against_sent_budget(usage: Any, budget: Mapping[str, int | None]) -> None:
|
|
798
|
+
if usage.model_calls > budget["model_calls"]:
|
|
799
|
+
raise AlgorithmOutputError("Q-RAG worker exceeded sent model_calls budget")
|
|
800
|
+
if usage.output_tokens > budget["output_tokens"]:
|
|
801
|
+
raise AlgorithmOutputError("Q-RAG worker exceeded sent output_tokens budget")
|
|
802
|
+
context_cap = budget["context_tokens"]
|
|
803
|
+
if context_cap is not None and usage.input_tokens > context_cap:
|
|
804
|
+
raise AlgorithmOutputError("Q-RAG worker exceeded sent context_tokens budget")
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
__all__ = [
|
|
808
|
+
"QRAG_ACTION_SCHEMA_SHA256",
|
|
809
|
+
"QRAG_CANDIDATE_BUILDER_SHA256",
|
|
810
|
+
"QRAG_CHECKPOINT_CONFIG_SHA256",
|
|
811
|
+
"QRAG_CHECKPOINT_FILE_SHA256",
|
|
812
|
+
"QRAG_CHECKPOINT_REPOSITORY",
|
|
813
|
+
"QRAG_CHECKPOINT_REVISION",
|
|
814
|
+
"QRAG_EMBEDDER_MODEL_SHA256",
|
|
815
|
+
"QRAG_EMBEDDER_REPOSITORY",
|
|
816
|
+
"QRAG_EMBEDDER_REVISION",
|
|
817
|
+
"QRAG_ENVIRONMENT_CONFIG_SHA256",
|
|
818
|
+
"QRAG_PROFILE_ID",
|
|
819
|
+
"QRAG_PROTOCOL",
|
|
820
|
+
"QRAG_SOURCE_MANIFEST_SHA256",
|
|
821
|
+
"QRAG_UPSTREAM_COMMIT",
|
|
822
|
+
"QRAGArtifactIdentity",
|
|
823
|
+
"QRAGControls",
|
|
824
|
+
"QRAGLicenseAcknowledgement",
|
|
825
|
+
"QRAGNativeWorker",
|
|
826
|
+
"QRAGReaderTransferWorker",
|
|
827
|
+
"QRAGStep",
|
|
828
|
+
]
|