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,1029 @@
|
|
|
1
|
+
"""R²AG hidden-state conditioning adapted to the shared agent arenas.
|
|
2
|
+
|
|
3
|
+
The upstream-compatible worker remains the strict paper-shaped composite path.
|
|
4
|
+
This module defines a separate common-support intervention. It preserves the
|
|
5
|
+
three retrieval features, R²-Former, learned projection, and marker-only input
|
|
6
|
+
embedding replacement. The custom reader's answer is exposed to the
|
|
7
|
+
downstream agent only as a non-authoritative generated anchor beside the real
|
|
8
|
+
retrieved documents. That final placement is an explicit agent-arena
|
|
9
|
+
adaptation and is never reported as upstream checkpoint or paper-result parity.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import hashlib
|
|
15
|
+
import importlib.util
|
|
16
|
+
import json
|
|
17
|
+
import math
|
|
18
|
+
import re
|
|
19
|
+
from collections.abc import Mapping, Sequence
|
|
20
|
+
from dataclasses import dataclass, field
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from types import ModuleType
|
|
23
|
+
from typing import Any, Protocol, runtime_checkable
|
|
24
|
+
|
|
25
|
+
from agentinputlab.backends.retrieval import RetrievalResult, Retriever
|
|
26
|
+
from agentinputlab.contracts import (
|
|
27
|
+
AlgorithmOutputError,
|
|
28
|
+
BudgetExceededError,
|
|
29
|
+
CapabilityError,
|
|
30
|
+
ContextBlock,
|
|
31
|
+
ExecutionTrace,
|
|
32
|
+
ExternalDependencyError,
|
|
33
|
+
FrozenAgentState,
|
|
34
|
+
InputPatch,
|
|
35
|
+
InterventionContext,
|
|
36
|
+
PatchOp,
|
|
37
|
+
PatchOperation,
|
|
38
|
+
SemanticFamily,
|
|
39
|
+
TraceEvent,
|
|
40
|
+
TracePhase,
|
|
41
|
+
ValidationError,
|
|
42
|
+
)
|
|
43
|
+
from agentinputlab.contracts.serialization import content_hash, freeze_mapping
|
|
44
|
+
|
|
45
|
+
from .bridge import R2AG_UPSTREAM_COMMIT, compute_r2ag_retrieval_features
|
|
46
|
+
|
|
47
|
+
_SHA256 = re.compile(r"^[0-9a-f]{64}$")
|
|
48
|
+
_MANIFEST_NAME = "artifact-manifest.json"
|
|
49
|
+
_MANIFEST_SCHEMA = "agentinputlab.r2ag-common-support-artifact.v1"
|
|
50
|
+
_MARKER = "<R>"
|
|
51
|
+
_QWEN38_FP8_BACKBONE = "Qwen3.8-27B-FP8"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _qwen38_fp8_min_new_tokens(*, backbone: str, max_new_tokens: int) -> int | None:
|
|
55
|
+
"""Prevent an EOS-only anchor for the exact Qwen3.8 FP8 reader.
|
|
56
|
+
|
|
57
|
+
``generate(inputs_embeds=...)`` can otherwise terminate immediately with
|
|
58
|
+
EOS for a subset of prompts. R2AG requires a non-empty, explicitly
|
|
59
|
+
non-authoritative anchor, so require one generated token for this exact
|
|
60
|
+
backbone while leaving every other reader unchanged.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
if backbone != _QWEN38_FP8_BACKBONE:
|
|
64
|
+
return None
|
|
65
|
+
return min(1, max_new_tokens)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _sha256_file(path: Path) -> str:
|
|
69
|
+
digest = hashlib.sha256()
|
|
70
|
+
with path.open("rb") as handle:
|
|
71
|
+
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
|
72
|
+
digest.update(chunk)
|
|
73
|
+
return digest.hexdigest()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def r2ag_reader_backbone_identity(model_root: Path) -> str:
|
|
77
|
+
"""Return the portable local-snapshot identity recorded in the artifact."""
|
|
78
|
+
|
|
79
|
+
identity = model_root.expanduser().resolve().name
|
|
80
|
+
if not identity:
|
|
81
|
+
raise ValidationError("R²AG base-model snapshot identity is empty")
|
|
82
|
+
return identity
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _repair_qwen38_fp8_model_config(model_config: Any, *, backbone: str) -> int:
|
|
86
|
+
"""Remove stale dense-layer exclusions from the official Qwen3.8 FP8 config.
|
|
87
|
+
|
|
88
|
+
The checkpoint contains FP8 weights and inverse scales for every language
|
|
89
|
+
MLP gate projection, but its generated ``modules_to_not_convert`` list also
|
|
90
|
+
names those gates. Transformers would therefore build a dense Linear for
|
|
91
|
+
an FP8 tensor and fail at the first forward pass. Keep this repair scoped
|
|
92
|
+
to the exact local backbone used by the campaign.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
if backbone != _QWEN38_FP8_BACKBONE:
|
|
96
|
+
return 0
|
|
97
|
+
quantization_config = getattr(model_config, "quantization_config", None)
|
|
98
|
+
if not isinstance(quantization_config, Mapping):
|
|
99
|
+
return 0
|
|
100
|
+
normalized = dict(quantization_config)
|
|
101
|
+
if normalized.get("quant_method") != "fp8":
|
|
102
|
+
return 0
|
|
103
|
+
exclusions = list(normalized.get("modules_to_not_convert", ()))
|
|
104
|
+
retained = [name for name in exclusions if not str(name).endswith(".mlp.gate")]
|
|
105
|
+
repaired = len(exclusions) - len(retained)
|
|
106
|
+
if repaired:
|
|
107
|
+
normalized["modules_to_not_convert"] = retained
|
|
108
|
+
model_config.quantization_config = normalized
|
|
109
|
+
return repaired
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@dataclass(frozen=True, slots=True)
|
|
113
|
+
class R2AGReaderResult:
|
|
114
|
+
anchor: str
|
|
115
|
+
input_tokens: int
|
|
116
|
+
output_tokens: int
|
|
117
|
+
marker_positions: tuple[int, ...]
|
|
118
|
+
rformer_output_sha256: str
|
|
119
|
+
projection_output_sha256: str
|
|
120
|
+
|
|
121
|
+
def __post_init__(self) -> None:
|
|
122
|
+
if not self.anchor.strip():
|
|
123
|
+
raise ValidationError("R²AG common-support reader returned an empty anchor")
|
|
124
|
+
for name, value in (
|
|
125
|
+
("input_tokens", self.input_tokens),
|
|
126
|
+
("output_tokens", self.output_tokens),
|
|
127
|
+
):
|
|
128
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 1:
|
|
129
|
+
raise ValidationError(f"R²AG reader {name} must be positive")
|
|
130
|
+
positions = tuple(self.marker_positions)
|
|
131
|
+
if not positions or positions != tuple(sorted(set(positions))):
|
|
132
|
+
raise ValidationError("R²AG marker positions must be ordered and unique")
|
|
133
|
+
if any(
|
|
134
|
+
_SHA256.fullmatch(value) is None
|
|
135
|
+
for value in (
|
|
136
|
+
self.rformer_output_sha256,
|
|
137
|
+
self.projection_output_sha256,
|
|
138
|
+
)
|
|
139
|
+
):
|
|
140
|
+
raise ValidationError("R²AG tensor identities must be lowercase SHA-256")
|
|
141
|
+
object.__setattr__(self, "marker_positions", positions)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@runtime_checkable
|
|
145
|
+
class R2AGCommonSupportReader(Protocol):
|
|
146
|
+
def run(
|
|
147
|
+
self,
|
|
148
|
+
*,
|
|
149
|
+
query: str,
|
|
150
|
+
documents: Sequence[RetrievalResult],
|
|
151
|
+
features: Sequence[Mapping[str, float]],
|
|
152
|
+
max_new_tokens: int,
|
|
153
|
+
seed: int,
|
|
154
|
+
) -> R2AGReaderResult:
|
|
155
|
+
"""Run R²-Former, projection, marker replacement, and generation."""
|
|
156
|
+
|
|
157
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
158
|
+
"""Return the closed source/model/training identity."""
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@runtime_checkable
|
|
162
|
+
class R2AGFeatureEncoder(Protocol):
|
|
163
|
+
def encode(
|
|
164
|
+
self,
|
|
165
|
+
*,
|
|
166
|
+
query: str,
|
|
167
|
+
documents: Sequence[RetrievalResult],
|
|
168
|
+
) -> tuple[Sequence[float], tuple[Sequence[float], ...]]:
|
|
169
|
+
"""Encode one query and ordered documents with role-correct prefixes."""
|
|
170
|
+
|
|
171
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
172
|
+
"""Return the checksum-closed encoder identity."""
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@dataclass(frozen=True, slots=True)
|
|
176
|
+
class R2AGRuntimeRequest:
|
|
177
|
+
query: str
|
|
178
|
+
documents: tuple[RetrievalResult, ...]
|
|
179
|
+
max_new_tokens: int
|
|
180
|
+
seed: int
|
|
181
|
+
|
|
182
|
+
def __post_init__(self) -> None:
|
|
183
|
+
if not self.query.strip() or not self.documents:
|
|
184
|
+
raise ValidationError("R²AG runtime request requires query and documents")
|
|
185
|
+
if self.max_new_tokens < 1 or self.seed < 0:
|
|
186
|
+
raise ValidationError("R²AG runtime request controls are invalid")
|
|
187
|
+
object.__setattr__(self, "documents", tuple(self.documents))
|
|
188
|
+
|
|
189
|
+
def external_reservation(self) -> Mapping[str, int]:
|
|
190
|
+
return {"model_calls": 1, "embedding_calls": 1}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@runtime_checkable
|
|
194
|
+
class R2AGCommonSupportRuntime(Protocol):
|
|
195
|
+
def run(self, request: R2AGRuntimeRequest) -> Mapping[str, Any]:
|
|
196
|
+
"""Encode features and execute the local hidden-state-conditioned reader."""
|
|
197
|
+
|
|
198
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
199
|
+
"""Return both reader and feature-encoder identities."""
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@dataclass(slots=True)
|
|
203
|
+
class LocalSentenceTransformerR2AGFeatureEncoder: # pragma: no cover - L20 GPU acceptance
|
|
204
|
+
"""Role-correct local E5 encoder used only for R²AG retrieval features."""
|
|
205
|
+
|
|
206
|
+
model_root: Path
|
|
207
|
+
model_load_set_sha256: str
|
|
208
|
+
device: str = "cuda"
|
|
209
|
+
batch_size: int = 16
|
|
210
|
+
query_prefix: str = "query: "
|
|
211
|
+
document_prefix: str = "passage: "
|
|
212
|
+
_model: Any | None = field(init=False, default=None, repr=False)
|
|
213
|
+
|
|
214
|
+
def __post_init__(self) -> None:
|
|
215
|
+
root = self.model_root.expanduser().resolve()
|
|
216
|
+
if not root.is_dir() or root.is_symlink():
|
|
217
|
+
raise ValidationError("R²AG feature model_root must be a real directory")
|
|
218
|
+
if _SHA256.fullmatch(self.model_load_set_sha256) is None:
|
|
219
|
+
raise ValidationError("R²AG feature model load-set identity is invalid")
|
|
220
|
+
if r2ag_model_tree_sha256(root) != self.model_load_set_sha256:
|
|
221
|
+
raise ValidationError("R²AG feature model load-set checksum mismatch")
|
|
222
|
+
if isinstance(self.batch_size, bool) or not isinstance(self.batch_size, int):
|
|
223
|
+
raise ValidationError("R²AG feature batch_size must be an integer")
|
|
224
|
+
if self.batch_size < 1:
|
|
225
|
+
raise ValidationError("R²AG feature batch_size must be positive")
|
|
226
|
+
if not self.query_prefix or not self.document_prefix:
|
|
227
|
+
raise ValidationError("R²AG feature prefixes must be non-empty")
|
|
228
|
+
object.__setattr__(self, "model_root", root)
|
|
229
|
+
|
|
230
|
+
def _load(self) -> Any:
|
|
231
|
+
if self._model is not None:
|
|
232
|
+
return self._model
|
|
233
|
+
try:
|
|
234
|
+
from sentence_transformers import SentenceTransformer
|
|
235
|
+
except ImportError as exc:
|
|
236
|
+
raise ExternalDependencyError(
|
|
237
|
+
"R²AG feature encoding requires sentence-transformers"
|
|
238
|
+
) from exc
|
|
239
|
+
try:
|
|
240
|
+
model = SentenceTransformer(
|
|
241
|
+
str(self.model_root),
|
|
242
|
+
device=self.device,
|
|
243
|
+
local_files_only=True,
|
|
244
|
+
)
|
|
245
|
+
except TypeError:
|
|
246
|
+
model = SentenceTransformer(str(self.model_root), device=self.device)
|
|
247
|
+
self._model = model
|
|
248
|
+
return model
|
|
249
|
+
|
|
250
|
+
def encode(
|
|
251
|
+
self,
|
|
252
|
+
*,
|
|
253
|
+
query: str,
|
|
254
|
+
documents: Sequence[RetrievalResult],
|
|
255
|
+
) -> tuple[Sequence[float], tuple[Sequence[float], ...]]:
|
|
256
|
+
if not query.strip() or not documents:
|
|
257
|
+
raise ValidationError("R²AG feature encoding requires query and documents")
|
|
258
|
+
texts = [
|
|
259
|
+
f"{self.query_prefix}{query.strip()}",
|
|
260
|
+
*(
|
|
261
|
+
f"{self.document_prefix}Title: {item.document.title}\n{item.document.text}"
|
|
262
|
+
for item in documents
|
|
263
|
+
),
|
|
264
|
+
]
|
|
265
|
+
vectors = self._load().encode(
|
|
266
|
+
texts,
|
|
267
|
+
batch_size=self.batch_size,
|
|
268
|
+
convert_to_numpy=True,
|
|
269
|
+
normalize_embeddings=True,
|
|
270
|
+
show_progress_bar=False,
|
|
271
|
+
)
|
|
272
|
+
rows = tuple(tuple(float(value) for value in row) for row in vectors)
|
|
273
|
+
if len(rows) != len(texts):
|
|
274
|
+
raise AlgorithmOutputError("R²AG feature encoder returned an invalid vector count")
|
|
275
|
+
if not rows[0] or any(len(row) != len(rows[0]) for row in rows):
|
|
276
|
+
raise AlgorithmOutputError("R²AG feature encoder returned ragged vectors")
|
|
277
|
+
return rows[0], rows[1:]
|
|
278
|
+
|
|
279
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
280
|
+
return freeze_mapping(
|
|
281
|
+
{
|
|
282
|
+
"runtime": "sentence_transformers_role_correct.v1",
|
|
283
|
+
"model_root": str(self.model_root),
|
|
284
|
+
"model_load_set_sha256": self.model_load_set_sha256,
|
|
285
|
+
"query_prefix": self.query_prefix,
|
|
286
|
+
"document_prefix": self.document_prefix,
|
|
287
|
+
"normalize_embeddings": True,
|
|
288
|
+
}
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
@dataclass(slots=True)
|
|
293
|
+
class LocalR2AGCommonSupportRuntime:
|
|
294
|
+
"""Monitored context runtime bundling the reader and role-correct encoder."""
|
|
295
|
+
|
|
296
|
+
reader: R2AGCommonSupportReader
|
|
297
|
+
feature_encoder: R2AGFeatureEncoder
|
|
298
|
+
worker_id: str = "r2ag-common-support-local"
|
|
299
|
+
|
|
300
|
+
def __post_init__(self) -> None:
|
|
301
|
+
if not isinstance(self.reader, R2AGCommonSupportReader):
|
|
302
|
+
raise CapabilityError("R²AG runtime reader does not implement its protocol")
|
|
303
|
+
if not isinstance(self.feature_encoder, R2AGFeatureEncoder):
|
|
304
|
+
raise CapabilityError("R²AG runtime feature encoder does not implement its protocol")
|
|
305
|
+
|
|
306
|
+
def run(self, request: R2AGRuntimeRequest) -> Mapping[str, Any]:
|
|
307
|
+
if not isinstance(request, R2AGRuntimeRequest):
|
|
308
|
+
raise TypeError("R²AG runtime requires R2AGRuntimeRequest")
|
|
309
|
+
query_vector, document_vectors = self.feature_encoder.encode(
|
|
310
|
+
query=request.query,
|
|
311
|
+
documents=request.documents,
|
|
312
|
+
)
|
|
313
|
+
features = compute_r2ag_retrieval_features(query_vector, document_vectors)
|
|
314
|
+
reader = self.reader.run(
|
|
315
|
+
query=request.query,
|
|
316
|
+
documents=request.documents,
|
|
317
|
+
features=features,
|
|
318
|
+
max_new_tokens=request.max_new_tokens,
|
|
319
|
+
seed=request.seed,
|
|
320
|
+
)
|
|
321
|
+
return {
|
|
322
|
+
"status": "ok",
|
|
323
|
+
"features": [dict(row) for row in features],
|
|
324
|
+
"reader": {
|
|
325
|
+
"anchor": reader.anchor,
|
|
326
|
+
"input_tokens": reader.input_tokens,
|
|
327
|
+
"output_tokens": reader.output_tokens,
|
|
328
|
+
"marker_positions": list(reader.marker_positions),
|
|
329
|
+
"rformer_output_sha256": reader.rformer_output_sha256,
|
|
330
|
+
"projection_output_sha256": reader.projection_output_sha256,
|
|
331
|
+
},
|
|
332
|
+
"usage": {
|
|
333
|
+
"model_calls": 1,
|
|
334
|
+
"retrieval_calls": 0,
|
|
335
|
+
"tool_calls": 0,
|
|
336
|
+
"embedding_calls": 1,
|
|
337
|
+
"input_tokens": reader.input_tokens,
|
|
338
|
+
"output_tokens": reader.output_tokens,
|
|
339
|
+
},
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
343
|
+
return freeze_mapping(
|
|
344
|
+
{
|
|
345
|
+
"runtime": "r2ag_common_support_context_runtime.v1",
|
|
346
|
+
"reader": dict(self.reader.fingerprint()),
|
|
347
|
+
"feature_encoder": dict(self.feature_encoder.fingerprint()),
|
|
348
|
+
}
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
@dataclass(slots=True)
|
|
353
|
+
class LocalR2AGCommonSupportReader: # pragma: no cover - L20 GPU acceptance
|
|
354
|
+
"""Lazy local Qwen reader backed by a checksum-closed retrained artifact."""
|
|
355
|
+
|
|
356
|
+
artifact_root: Path
|
|
357
|
+
manifest_sha256: str
|
|
358
|
+
source_root: Path
|
|
359
|
+
base_model_root: Path
|
|
360
|
+
base_model_load_set_sha256: str
|
|
361
|
+
device: str = "cuda"
|
|
362
|
+
_manifest: Mapping[str, Any] = field(init=False, repr=False)
|
|
363
|
+
_runtime: tuple[Any, Any, Any, Any, Any] | None = field(
|
|
364
|
+
init=False,
|
|
365
|
+
default=None,
|
|
366
|
+
repr=False,
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
def __post_init__(self) -> None:
|
|
370
|
+
artifact = self.artifact_root.expanduser().resolve()
|
|
371
|
+
source = self.source_root.expanduser().resolve()
|
|
372
|
+
base_model = self.base_model_root.expanduser().resolve()
|
|
373
|
+
for label, path in (
|
|
374
|
+
("artifact_root", artifact),
|
|
375
|
+
("source_root", source),
|
|
376
|
+
("base_model_root", base_model),
|
|
377
|
+
):
|
|
378
|
+
if not path.is_dir() or path.is_symlink():
|
|
379
|
+
raise ValidationError(f"R²AG {label} must be a real directory")
|
|
380
|
+
if _SHA256.fullmatch(self.manifest_sha256) is None:
|
|
381
|
+
raise ValidationError("R²AG manifest_sha256 must be lowercase SHA-256")
|
|
382
|
+
if _SHA256.fullmatch(self.base_model_load_set_sha256) is None:
|
|
383
|
+
raise ValidationError("R²AG base model load-set identity is invalid")
|
|
384
|
+
manifest_path = artifact / _MANIFEST_NAME
|
|
385
|
+
if (
|
|
386
|
+
not manifest_path.is_file()
|
|
387
|
+
or manifest_path.is_symlink()
|
|
388
|
+
or _sha256_file(manifest_path) != self.manifest_sha256
|
|
389
|
+
):
|
|
390
|
+
raise ValidationError("R²AG artifact manifest checksum mismatch")
|
|
391
|
+
try:
|
|
392
|
+
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
|
393
|
+
except (OSError, json.JSONDecodeError) as exc:
|
|
394
|
+
raise ValidationError("R²AG artifact manifest is invalid") from exc
|
|
395
|
+
if not isinstance(manifest, Mapping) or manifest.get("schema_version") != _MANIFEST_SCHEMA:
|
|
396
|
+
raise ValidationError("R²AG artifact manifest schema mismatch")
|
|
397
|
+
expected = {
|
|
398
|
+
"upstream_commit": R2AG_UPSTREAM_COMMIT,
|
|
399
|
+
"marker_token": _MARKER,
|
|
400
|
+
"feature_names": ["rerank", "neighbor", "precedent"],
|
|
401
|
+
"reader_backbone": r2ag_reader_backbone_identity(base_model),
|
|
402
|
+
"base_model_load_set_sha256": self.base_model_load_set_sha256,
|
|
403
|
+
"upstream_checkpoint_parity_claimed": False,
|
|
404
|
+
"paper_result_parity_claimed": False,
|
|
405
|
+
"generated_anchor_is_evidence": False,
|
|
406
|
+
}
|
|
407
|
+
for name, value in expected.items():
|
|
408
|
+
if manifest.get(name) != value:
|
|
409
|
+
raise ValidationError(f"R²AG artifact manifest drifted at {name}")
|
|
410
|
+
for name in (
|
|
411
|
+
"num_documents",
|
|
412
|
+
"marker_token_id",
|
|
413
|
+
"rformer_hidden_size",
|
|
414
|
+
"rformer_heads",
|
|
415
|
+
"rformer_layers",
|
|
416
|
+
"reader_hidden_size",
|
|
417
|
+
"max_sequence_length",
|
|
418
|
+
"max_document_chars",
|
|
419
|
+
):
|
|
420
|
+
value = manifest.get(name)
|
|
421
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 1:
|
|
422
|
+
raise ValidationError(f"R²AG artifact manifest has invalid {name}")
|
|
423
|
+
model_source = source / "RRAG/models/modeling_rrag.py"
|
|
424
|
+
if (
|
|
425
|
+
not model_source.is_file()
|
|
426
|
+
or model_source.is_symlink()
|
|
427
|
+
or _sha256_file(model_source) != manifest.get("modeling_source_sha256")
|
|
428
|
+
):
|
|
429
|
+
raise ValidationError("R²AG pinned modeling source checksum mismatch")
|
|
430
|
+
files = manifest.get("artifact_files")
|
|
431
|
+
if not isinstance(files, Mapping) or not files:
|
|
432
|
+
raise ValidationError("R²AG artifact closure is empty")
|
|
433
|
+
observed: set[str] = set()
|
|
434
|
+
for raw_name, raw_digest in files.items():
|
|
435
|
+
if (
|
|
436
|
+
not isinstance(raw_name, str)
|
|
437
|
+
or not raw_name
|
|
438
|
+
or Path(raw_name).is_absolute()
|
|
439
|
+
or ".." in Path(raw_name).parts
|
|
440
|
+
or not isinstance(raw_digest, str)
|
|
441
|
+
or _SHA256.fullmatch(raw_digest) is None
|
|
442
|
+
):
|
|
443
|
+
raise ValidationError("R²AG artifact closure entry is invalid")
|
|
444
|
+
target = artifact / raw_name
|
|
445
|
+
if not target.is_file() or target.is_symlink() or _sha256_file(target) != raw_digest:
|
|
446
|
+
raise ValidationError(f"R²AG artifact closure mismatch: {raw_name}")
|
|
447
|
+
observed.add(raw_name)
|
|
448
|
+
actual = {
|
|
449
|
+
str(path.relative_to(artifact))
|
|
450
|
+
for path in artifact.rglob("*")
|
|
451
|
+
if path.is_file() and path.name != _MANIFEST_NAME
|
|
452
|
+
}
|
|
453
|
+
if observed != actual or "checkpoint.pt" not in observed:
|
|
454
|
+
raise ValidationError("R²AG artifact closure has missing or extra files")
|
|
455
|
+
tokenizer_files = {name for name in observed if name.startswith("tokenizer/")}
|
|
456
|
+
if not tokenizer_files:
|
|
457
|
+
raise ValidationError("R²AG artifact has no closed tokenizer snapshot")
|
|
458
|
+
object.__setattr__(self, "artifact_root", artifact)
|
|
459
|
+
object.__setattr__(self, "source_root", source)
|
|
460
|
+
object.__setattr__(self, "base_model_root", base_model)
|
|
461
|
+
object.__setattr__(self, "_manifest", freeze_mapping(dict(manifest)))
|
|
462
|
+
|
|
463
|
+
def _load(self) -> tuple[Any, Any, Any, Any, Any]:
|
|
464
|
+
if self._runtime is not None:
|
|
465
|
+
return self._runtime
|
|
466
|
+
try:
|
|
467
|
+
import torch
|
|
468
|
+
from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer
|
|
469
|
+
except ImportError as exc:
|
|
470
|
+
raise ExternalDependencyError(
|
|
471
|
+
"R²AG common-support runtime requires torch and transformers"
|
|
472
|
+
) from exc
|
|
473
|
+
if self.device.startswith("cuda") and not torch.cuda.is_available():
|
|
474
|
+
raise ExternalDependencyError("R²AG requested unavailable CUDA")
|
|
475
|
+
module = _load_source_module(
|
|
476
|
+
self.source_root / "RRAG/models/modeling_rrag.py",
|
|
477
|
+
"agentinputlab_common_support_rrag_modeling",
|
|
478
|
+
)
|
|
479
|
+
rformer_type = getattr(module, "RFormer", None)
|
|
480
|
+
if not isinstance(rformer_type, type):
|
|
481
|
+
raise ExternalDependencyError("R²AG pinned source does not expose RFormer")
|
|
482
|
+
tokenizer = AutoTokenizer.from_pretrained(
|
|
483
|
+
self.artifact_root / "tokenizer",
|
|
484
|
+
local_files_only=True,
|
|
485
|
+
trust_remote_code=False,
|
|
486
|
+
)
|
|
487
|
+
marker_id = tokenizer.convert_tokens_to_ids(_MARKER)
|
|
488
|
+
if marker_id != self._manifest.get("marker_token_id"):
|
|
489
|
+
raise ValidationError("R²AG marker token ID differs from the training artifact")
|
|
490
|
+
dtype = torch.bfloat16 if self.device.startswith("cuda") else torch.float32
|
|
491
|
+
model_config = AutoConfig.from_pretrained(
|
|
492
|
+
self.base_model_root,
|
|
493
|
+
local_files_only=True,
|
|
494
|
+
trust_remote_code=False,
|
|
495
|
+
)
|
|
496
|
+
_repair_qwen38_fp8_model_config(
|
|
497
|
+
model_config,
|
|
498
|
+
backbone=str(self._manifest["reader_backbone"]),
|
|
499
|
+
)
|
|
500
|
+
model = AutoModelForCausalLM.from_pretrained(
|
|
501
|
+
self.base_model_root,
|
|
502
|
+
config=model_config,
|
|
503
|
+
local_files_only=True,
|
|
504
|
+
trust_remote_code=False,
|
|
505
|
+
dtype=dtype,
|
|
506
|
+
).to(self.device)
|
|
507
|
+
model.resize_token_embeddings(len(tokenizer))
|
|
508
|
+
model.eval()
|
|
509
|
+
for parameter in model.parameters():
|
|
510
|
+
parameter.requires_grad_(False)
|
|
511
|
+
num_k = int(self._manifest["num_documents"])
|
|
512
|
+
d_model = int(self._manifest["rformer_hidden_size"])
|
|
513
|
+
rformer = rformer_type(
|
|
514
|
+
input_dim=3,
|
|
515
|
+
num_k=num_k,
|
|
516
|
+
d_model=d_model,
|
|
517
|
+
n_head=int(self._manifest["rformer_heads"]),
|
|
518
|
+
num_layers=int(self._manifest["rformer_layers"]),
|
|
519
|
+
dropout=float(self._manifest["rformer_dropout"]),
|
|
520
|
+
).to(self.device)
|
|
521
|
+
projection = torch.nn.Linear(
|
|
522
|
+
d_model,
|
|
523
|
+
int(self._manifest["reader_hidden_size"]),
|
|
524
|
+
device=self.device,
|
|
525
|
+
)
|
|
526
|
+
try:
|
|
527
|
+
checkpoint = torch.load(
|
|
528
|
+
self.artifact_root / "checkpoint.pt",
|
|
529
|
+
map_location="cpu",
|
|
530
|
+
weights_only=True,
|
|
531
|
+
)
|
|
532
|
+
except TypeError as exc:
|
|
533
|
+
raise ExternalDependencyError("R²AG requires safe weights-only loading") from exc
|
|
534
|
+
if not isinstance(checkpoint, Mapping) or set(checkpoint) != {"r_former", "llama_proj"}:
|
|
535
|
+
raise ValidationError("R²AG checkpoint component schema mismatch")
|
|
536
|
+
rformer.load_state_dict(checkpoint["r_former"], strict=True)
|
|
537
|
+
projection.load_state_dict(checkpoint["llama_proj"], strict=True)
|
|
538
|
+
rformer.eval()
|
|
539
|
+
projection.eval()
|
|
540
|
+
for component in (rformer, projection):
|
|
541
|
+
for parameter in component.parameters():
|
|
542
|
+
parameter.requires_grad_(False)
|
|
543
|
+
self._runtime = (torch, tokenizer, model, rformer, projection)
|
|
544
|
+
return self._runtime
|
|
545
|
+
|
|
546
|
+
def run(
|
|
547
|
+
self,
|
|
548
|
+
*,
|
|
549
|
+
query: str,
|
|
550
|
+
documents: Sequence[RetrievalResult],
|
|
551
|
+
features: Sequence[Mapping[str, float]],
|
|
552
|
+
max_new_tokens: int,
|
|
553
|
+
seed: int,
|
|
554
|
+
) -> R2AGReaderResult:
|
|
555
|
+
if not query.strip():
|
|
556
|
+
raise ValidationError("R²AG reader requires a non-empty query")
|
|
557
|
+
if len(documents) != int(self._manifest["num_documents"]):
|
|
558
|
+
raise ValidationError("R²AG document count differs from its trained checkpoint")
|
|
559
|
+
if len(features) != len(documents):
|
|
560
|
+
raise ValidationError("R²AG feature count differs from its documents")
|
|
561
|
+
if (
|
|
562
|
+
isinstance(max_new_tokens, bool)
|
|
563
|
+
or not isinstance(max_new_tokens, int)
|
|
564
|
+
or max_new_tokens < 1
|
|
565
|
+
):
|
|
566
|
+
raise ValidationError("R²AG max_new_tokens must be positive")
|
|
567
|
+
torch, tokenizer, model, rformer, projection = self._load()
|
|
568
|
+
prompt = r2ag_reader_prompt(
|
|
569
|
+
query,
|
|
570
|
+
documents,
|
|
571
|
+
max_document_chars=int(self._manifest["max_document_chars"]),
|
|
572
|
+
)
|
|
573
|
+
encoded = tokenizer(
|
|
574
|
+
prompt,
|
|
575
|
+
return_tensors="pt",
|
|
576
|
+
add_special_tokens=False,
|
|
577
|
+
truncation=False,
|
|
578
|
+
).to(self.device)
|
|
579
|
+
input_tokens = int(encoded.attention_mask.sum().detach().cpu())
|
|
580
|
+
if input_tokens > int(self._manifest["max_sequence_length"]):
|
|
581
|
+
raise BudgetExceededError("R²AG reader input exceeds its trained sequence length")
|
|
582
|
+
marker_id = int(self._manifest["marker_token_id"])
|
|
583
|
+
marker_rows = torch.nonzero(encoded.input_ids == marker_id, as_tuple=False)
|
|
584
|
+
marker_positions = tuple(int(row[1].item()) for row in marker_rows)
|
|
585
|
+
if len(marker_positions) != len(documents):
|
|
586
|
+
raise AlgorithmOutputError("R²AG tokenizer did not preserve one marker per document")
|
|
587
|
+
values = [
|
|
588
|
+
[float(row[name]) for name in ("rerank", "neighbor", "precedent")] for row in features
|
|
589
|
+
]
|
|
590
|
+
feature_tensor = torch.tensor(values, dtype=torch.float32, device=self.device)
|
|
591
|
+
with torch.inference_mode():
|
|
592
|
+
rformer_output, loss = rformer(feature_tensor)
|
|
593
|
+
if loss is not None:
|
|
594
|
+
raise AlgorithmOutputError("R²AG inference RFormer returned training loss")
|
|
595
|
+
projected = projection(rformer_output)
|
|
596
|
+
input_embeddings = model.get_input_embeddings()(encoded.input_ids)
|
|
597
|
+
updated = input_embeddings.clone()
|
|
598
|
+
flattened = projected.reshape(-1, projected.shape[-1])
|
|
599
|
+
for index, position in enumerate(marker_positions):
|
|
600
|
+
updated[0, position] = flattened[index].to(updated.dtype)
|
|
601
|
+
before = input_embeddings.clone()
|
|
602
|
+
untouched = [
|
|
603
|
+
index for index in range(updated.shape[1]) if index not in marker_positions
|
|
604
|
+
]
|
|
605
|
+
if untouched:
|
|
606
|
+
selector = torch.tensor(untouched, dtype=torch.long, device=self.device)
|
|
607
|
+
if not torch.equal(updated[:, selector], before[:, selector]):
|
|
608
|
+
raise AlgorithmOutputError("R²AG modified a non-marker embedding")
|
|
609
|
+
torch.manual_seed(seed)
|
|
610
|
+
if torch.cuda.is_available():
|
|
611
|
+
torch.cuda.manual_seed_all(seed)
|
|
612
|
+
generation_compatibility: dict[str, int] = {}
|
|
613
|
+
min_new_tokens = _qwen38_fp8_min_new_tokens(
|
|
614
|
+
backbone=str(self._manifest["reader_backbone"]),
|
|
615
|
+
max_new_tokens=max_new_tokens,
|
|
616
|
+
)
|
|
617
|
+
if min_new_tokens is not None:
|
|
618
|
+
generation_compatibility["min_new_tokens"] = min_new_tokens
|
|
619
|
+
output = model.generate(
|
|
620
|
+
inputs_embeds=updated.contiguous(),
|
|
621
|
+
attention_mask=encoded.attention_mask,
|
|
622
|
+
max_new_tokens=max_new_tokens,
|
|
623
|
+
do_sample=False,
|
|
624
|
+
num_beams=1,
|
|
625
|
+
repetition_penalty=1.0,
|
|
626
|
+
length_penalty=1.0,
|
|
627
|
+
**generation_compatibility,
|
|
628
|
+
)
|
|
629
|
+
if output.ndim != 2 or output.shape[0] != 1:
|
|
630
|
+
raise AlgorithmOutputError("R²AG reader output must be one token sequence")
|
|
631
|
+
output_tokens = int(output.shape[1])
|
|
632
|
+
if not 1 <= output_tokens <= max_new_tokens:
|
|
633
|
+
raise AlgorithmOutputError("R²AG reader output exceeds its generation budget")
|
|
634
|
+
anchor = tokenizer.decode(output[0], skip_special_tokens=True).strip()
|
|
635
|
+
if not anchor:
|
|
636
|
+
raise AlgorithmOutputError("R²AG reader returned an empty generated anchor")
|
|
637
|
+
return R2AGReaderResult(
|
|
638
|
+
anchor=anchor,
|
|
639
|
+
input_tokens=input_tokens,
|
|
640
|
+
output_tokens=output_tokens,
|
|
641
|
+
marker_positions=marker_positions,
|
|
642
|
+
rformer_output_sha256=_tensor_sha256(rformer_output, torch),
|
|
643
|
+
projection_output_sha256=_tensor_sha256(projected, torch),
|
|
644
|
+
)
|
|
645
|
+
|
|
646
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
647
|
+
return freeze_mapping(
|
|
648
|
+
{
|
|
649
|
+
"runtime": "r2ag_marker_only_hidden_state_conditioning.v1",
|
|
650
|
+
"upstream_commit": R2AG_UPSTREAM_COMMIT,
|
|
651
|
+
"manifest_sha256": self.manifest_sha256,
|
|
652
|
+
"artifact_closure_sha256": self._manifest.get("artifact_closure_sha256"),
|
|
653
|
+
"base_model_load_set_sha256": self.base_model_load_set_sha256,
|
|
654
|
+
"training_data_sha256": self._manifest.get("training_data_sha256"),
|
|
655
|
+
"reader_backbone": self._manifest.get("reader_backbone"),
|
|
656
|
+
"fp8_model_config_compatibility": (
|
|
657
|
+
"qwen3.8_fp8_mlp_gate_exclusion.v1"
|
|
658
|
+
if self._manifest.get("reader_backbone") == _QWEN38_FP8_BACKBONE
|
|
659
|
+
else None
|
|
660
|
+
),
|
|
661
|
+
"fp8_generation_compatibility": (
|
|
662
|
+
"qwen3.8_fp8_min_new_tokens_1.v1"
|
|
663
|
+
if self._manifest.get("reader_backbone") == _QWEN38_FP8_BACKBONE
|
|
664
|
+
else None
|
|
665
|
+
),
|
|
666
|
+
"num_documents": self._manifest.get("num_documents"),
|
|
667
|
+
"marker_token_id": self._manifest.get("marker_token_id"),
|
|
668
|
+
"upstream_checkpoint_parity_claimed": False,
|
|
669
|
+
"paper_result_parity_claimed": False,
|
|
670
|
+
}
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
@dataclass(frozen=True, slots=True)
|
|
675
|
+
class R2AGCommonSupportConfig:
|
|
676
|
+
retrieval_top_k: int = 6
|
|
677
|
+
max_new_tokens: int = 96
|
|
678
|
+
|
|
679
|
+
def __post_init__(self) -> None:
|
|
680
|
+
for name, value in (
|
|
681
|
+
("retrieval_top_k", self.retrieval_top_k),
|
|
682
|
+
("max_new_tokens", self.max_new_tokens),
|
|
683
|
+
):
|
|
684
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 1:
|
|
685
|
+
raise ValidationError(f"R²AG {name} must be positive")
|
|
686
|
+
if self.retrieval_top_k < 2:
|
|
687
|
+
raise ValidationError("R²AG requires at least two documents")
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
@dataclass(slots=True)
|
|
691
|
+
class R2AGCommonSupport:
|
|
692
|
+
"""Expose a retrieval-conditioned anchor and its real documents to an agent."""
|
|
693
|
+
|
|
694
|
+
config: R2AGCommonSupportConfig = R2AGCommonSupportConfig()
|
|
695
|
+
method_id: str = "r2ag"
|
|
696
|
+
release_id: str = "acquire.r2ag.common_support"
|
|
697
|
+
family: SemanticFamily = SemanticFamily.ACQUIRE
|
|
698
|
+
|
|
699
|
+
def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
|
|
700
|
+
if not state.query.strip():
|
|
701
|
+
raise ValidationError("R²AG requires a non-empty query")
|
|
702
|
+
runtime = _runtime(context.external_runtime)
|
|
703
|
+
retriever = _retriever(context.retriever)
|
|
704
|
+
if state.budget.max_model_calls < 1:
|
|
705
|
+
raise BudgetExceededError("R²AG has no reader model-call budget")
|
|
706
|
+
if state.budget.max_retrieval_calls < 1:
|
|
707
|
+
raise BudgetExceededError("R²AG has no retrieval budget")
|
|
708
|
+
if state.budget.max_output_tokens < 1:
|
|
709
|
+
raise BudgetExceededError("R²AG has no output-token budget")
|
|
710
|
+
results = _validated_results(
|
|
711
|
+
retriever.retrieve(state.query, top_k=self.config.retrieval_top_k),
|
|
712
|
+
top_k=self.config.retrieval_top_k,
|
|
713
|
+
)
|
|
714
|
+
if len(results) != self.config.retrieval_top_k:
|
|
715
|
+
raise AlgorithmOutputError("R²AG requires its exact checkpoint document count")
|
|
716
|
+
runtime_response = runtime.run(
|
|
717
|
+
R2AGRuntimeRequest(
|
|
718
|
+
query=state.query,
|
|
719
|
+
documents=results,
|
|
720
|
+
max_new_tokens=min(self.config.max_new_tokens, state.budget.max_output_tokens),
|
|
721
|
+
seed=context.seed,
|
|
722
|
+
)
|
|
723
|
+
)
|
|
724
|
+
features, reader_result = _validated_runtime_response(runtime_response, len(results))
|
|
725
|
+
if (
|
|
726
|
+
state.budget.max_context_tokens is not None
|
|
727
|
+
and reader_result.input_tokens > state.budget.max_context_tokens
|
|
728
|
+
):
|
|
729
|
+
raise BudgetExceededError("R²AG reader exceeded max_context_tokens")
|
|
730
|
+
real_blocks = tuple(
|
|
731
|
+
_real_context(result, feature)
|
|
732
|
+
for result, feature in zip(results, features, strict=True)
|
|
733
|
+
)
|
|
734
|
+
anchor_hash = content_hash(
|
|
735
|
+
{
|
|
736
|
+
"anchor": reader_result.anchor,
|
|
737
|
+
"rformer": reader_result.rformer_output_sha256,
|
|
738
|
+
"projection": reader_result.projection_output_sha256,
|
|
739
|
+
}
|
|
740
|
+
)
|
|
741
|
+
anchor_block = ContextBlock(
|
|
742
|
+
block_id=f"r2ag-generated-anchor:{anchor_hash[:16]}",
|
|
743
|
+
text=(
|
|
744
|
+
"R²AG retrieval-conditioned hypothesis (non-authoritative; verify against the "
|
|
745
|
+
f"retrieved documents): {reader_result.anchor}"
|
|
746
|
+
),
|
|
747
|
+
source="r2ag_common_support_generated_anchor",
|
|
748
|
+
metadata={
|
|
749
|
+
"evidence_kind": "model_generated_non_authoritative_anchor",
|
|
750
|
+
"generated_anchor_is_evidence": False,
|
|
751
|
+
"anchor_sha256": anchor_hash,
|
|
752
|
+
"rformer_output_sha256": reader_result.rformer_output_sha256,
|
|
753
|
+
"projection_output_sha256": reader_result.projection_output_sha256,
|
|
754
|
+
},
|
|
755
|
+
)
|
|
756
|
+
runtime_identity = dict(runtime.fingerprint())
|
|
757
|
+
reader_identity = runtime_identity.get("reader", {})
|
|
758
|
+
feature_encoder_identity = runtime_identity.get("feature_encoder", {})
|
|
759
|
+
if not isinstance(reader_identity, Mapping) or not isinstance(
|
|
760
|
+
feature_encoder_identity, Mapping
|
|
761
|
+
):
|
|
762
|
+
raise AlgorithmOutputError("R²AG runtime fingerprint lacks component identities")
|
|
763
|
+
trace = ExecutionTrace(
|
|
764
|
+
method_id=self.method_id,
|
|
765
|
+
release_id=self.release_id,
|
|
766
|
+
events=(
|
|
767
|
+
TraceEvent(
|
|
768
|
+
TracePhase.PREPARE,
|
|
769
|
+
"r2ag_common_support_configuration",
|
|
770
|
+
{
|
|
771
|
+
"upstream_commit": R2AG_UPSTREAM_COMMIT,
|
|
772
|
+
"reader": reader_identity,
|
|
773
|
+
"retriever": dict(retriever.fingerprint()),
|
|
774
|
+
"feature_encoder": feature_encoder_identity,
|
|
775
|
+
"external_runtime": runtime_identity,
|
|
776
|
+
"candidate_document_ids": tuple(item.document.doc_id for item in results),
|
|
777
|
+
"upstream_checkpoint_parity_claimed": False,
|
|
778
|
+
"paper_result_parity_claimed": False,
|
|
779
|
+
},
|
|
780
|
+
),
|
|
781
|
+
TraceEvent(
|
|
782
|
+
TracePhase.OBSERVE,
|
|
783
|
+
"r2ag_retrieval_feature_tensor",
|
|
784
|
+
{
|
|
785
|
+
"feature_names": ("rerank", "neighbor", "precedent"),
|
|
786
|
+
"features": tuple(dict(row) for row in features),
|
|
787
|
+
"feature_tensor_sha256": content_hash(features),
|
|
788
|
+
},
|
|
789
|
+
),
|
|
790
|
+
TraceEvent(
|
|
791
|
+
TracePhase.FINALIZE,
|
|
792
|
+
"r2ag_marker_conditioned_anchor",
|
|
793
|
+
{
|
|
794
|
+
"marker_positions": reader_result.marker_positions,
|
|
795
|
+
"rformer_output_sha256": reader_result.rformer_output_sha256,
|
|
796
|
+
"projection_output_sha256": reader_result.projection_output_sha256,
|
|
797
|
+
"anchor_sha256": anchor_hash,
|
|
798
|
+
"generated_anchor_visible_to_downstream": True,
|
|
799
|
+
"generated_anchor_is_evidence": False,
|
|
800
|
+
},
|
|
801
|
+
),
|
|
802
|
+
),
|
|
803
|
+
counters={
|
|
804
|
+
"model_calls": 1,
|
|
805
|
+
"retrieval_calls": 1,
|
|
806
|
+
"embedding_calls": 1,
|
|
807
|
+
"input_tokens": reader_result.input_tokens,
|
|
808
|
+
"output_tokens": reader_result.output_tokens,
|
|
809
|
+
"conditioned_documents": len(results),
|
|
810
|
+
"retrieval_feature_values": len(results) * 3,
|
|
811
|
+
},
|
|
812
|
+
)
|
|
813
|
+
return InputPatch(
|
|
814
|
+
method_id=self.method_id,
|
|
815
|
+
release_id=self.release_id,
|
|
816
|
+
source_state_hash=state.state_hash,
|
|
817
|
+
operations=(
|
|
818
|
+
PatchOperation(
|
|
819
|
+
PatchOp.ADD_CONTEXT,
|
|
820
|
+
(*real_blocks, anchor_block),
|
|
821
|
+
target="retrieved_evidence_and_generated_anchor",
|
|
822
|
+
rationale=(
|
|
823
|
+
"preserve R²AG hidden-state conditioning as a non-authoritative "
|
|
824
|
+
"agent input anchor beside real retrieved documents"
|
|
825
|
+
),
|
|
826
|
+
),
|
|
827
|
+
),
|
|
828
|
+
trace=trace,
|
|
829
|
+
implementation_identity=(
|
|
830
|
+
f"controlled_marker_conditioned_reader:yefd/RRAG@{R2AG_UPSTREAM_COMMIT}"
|
|
831
|
+
),
|
|
832
|
+
profile_kind="controlled_adapter",
|
|
833
|
+
metadata={
|
|
834
|
+
"common_support_adaptation": (
|
|
835
|
+
"custom_reader_answer_as_non_authoritative_downstream_context"
|
|
836
|
+
),
|
|
837
|
+
"generated_anchor_visible_to_downstream": True,
|
|
838
|
+
"generated_anchor_is_evidence": False,
|
|
839
|
+
"real_documents_are_evidence": True,
|
|
840
|
+
"marker_only_embedding_replacement": True,
|
|
841
|
+
"upstream_checkpoint_parity_claimed": False,
|
|
842
|
+
"paper_result_parity_claimed": False,
|
|
843
|
+
"reader_manifest_sha256": reader_identity.get("manifest_sha256"),
|
|
844
|
+
"reader_backbone": reader_identity.get("reader_backbone"),
|
|
845
|
+
"feature_encoder_load_set_sha256": feature_encoder_identity.get(
|
|
846
|
+
"model_load_set_sha256"
|
|
847
|
+
),
|
|
848
|
+
},
|
|
849
|
+
)
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
def _retriever(value: object) -> Retriever:
|
|
853
|
+
if value is None or not hasattr(value, "retrieve") or not hasattr(value, "fingerprint"):
|
|
854
|
+
raise ExternalDependencyError("R²AG common-support requires a Retriever")
|
|
855
|
+
return value # type: ignore[return-value]
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
def _runtime(value: object) -> R2AGCommonSupportRuntime:
|
|
859
|
+
if not isinstance(value, R2AGCommonSupportRuntime):
|
|
860
|
+
raise ExternalDependencyError(
|
|
861
|
+
"R²AG common-support requires InterventionContext.external_runtime"
|
|
862
|
+
)
|
|
863
|
+
return value
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
def _validated_runtime_response(
|
|
867
|
+
value: Mapping[str, Any],
|
|
868
|
+
expected_documents: int,
|
|
869
|
+
) -> tuple[tuple[Mapping[str, float], ...], R2AGReaderResult]:
|
|
870
|
+
if not isinstance(value, Mapping) or value.get("status") != "ok":
|
|
871
|
+
raise AlgorithmOutputError("R²AG external runtime returned a failed response")
|
|
872
|
+
raw_features = value.get("features")
|
|
873
|
+
raw_reader = value.get("reader")
|
|
874
|
+
if (
|
|
875
|
+
isinstance(raw_features, (str, bytes))
|
|
876
|
+
or not isinstance(raw_features, Sequence)
|
|
877
|
+
or len(raw_features) != expected_documents
|
|
878
|
+
or not isinstance(raw_reader, Mapping)
|
|
879
|
+
):
|
|
880
|
+
raise AlgorithmOutputError("R²AG external runtime response schema is invalid")
|
|
881
|
+
features: list[Mapping[str, float]] = []
|
|
882
|
+
for row in raw_features:
|
|
883
|
+
if not isinstance(row, Mapping) or set(row) != {"rerank", "neighbor", "precedent"}:
|
|
884
|
+
raise AlgorithmOutputError("R²AG external runtime feature schema is invalid")
|
|
885
|
+
try:
|
|
886
|
+
parsed = {name: float(row[name]) for name in ("rerank", "neighbor", "precedent")}
|
|
887
|
+
except (TypeError, ValueError, OverflowError) as exc:
|
|
888
|
+
raise AlgorithmOutputError("R²AG external runtime features are non-numeric") from exc
|
|
889
|
+
if not all(math.isfinite(item) for item in parsed.values()):
|
|
890
|
+
raise AlgorithmOutputError("R²AG external runtime features are non-finite")
|
|
891
|
+
features.append(freeze_mapping(parsed))
|
|
892
|
+
try:
|
|
893
|
+
result = R2AGReaderResult(
|
|
894
|
+
anchor=raw_reader["anchor"],
|
|
895
|
+
input_tokens=raw_reader["input_tokens"],
|
|
896
|
+
output_tokens=raw_reader["output_tokens"],
|
|
897
|
+
marker_positions=tuple(raw_reader["marker_positions"]),
|
|
898
|
+
rformer_output_sha256=raw_reader["rformer_output_sha256"],
|
|
899
|
+
projection_output_sha256=raw_reader["projection_output_sha256"],
|
|
900
|
+
)
|
|
901
|
+
except (KeyError, TypeError, ValidationError) as exc:
|
|
902
|
+
raise AlgorithmOutputError("R²AG external runtime reader receipt is invalid") from exc
|
|
903
|
+
usage = value.get("usage")
|
|
904
|
+
if (
|
|
905
|
+
not isinstance(usage, Mapping)
|
|
906
|
+
or usage.get("model_calls") != 1
|
|
907
|
+
or usage.get("embedding_calls") != 1
|
|
908
|
+
or usage.get("input_tokens") != result.input_tokens
|
|
909
|
+
or usage.get("output_tokens") != result.output_tokens
|
|
910
|
+
):
|
|
911
|
+
raise AlgorithmOutputError("R²AG external runtime usage receipt is invalid")
|
|
912
|
+
return tuple(features), result
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
def _validated_results(
|
|
916
|
+
values: Sequence[RetrievalResult], *, top_k: int
|
|
917
|
+
) -> tuple[RetrievalResult, ...]:
|
|
918
|
+
try:
|
|
919
|
+
results = tuple(values)
|
|
920
|
+
except TypeError as exc:
|
|
921
|
+
raise AlgorithmOutputError("R²AG retriever returned a non-sequence") from exc
|
|
922
|
+
if not all(isinstance(item, RetrievalResult) for item in results) or len(results) > top_k:
|
|
923
|
+
raise AlgorithmOutputError("R²AG retriever returned invalid results")
|
|
924
|
+
ids = tuple(item.document.doc_id for item in results)
|
|
925
|
+
if any(not value for value in ids) or len(ids) != len(set(ids)):
|
|
926
|
+
raise AlgorithmOutputError("R²AG retrieval IDs must be non-empty and unique")
|
|
927
|
+
if tuple(item.rank for item in results) != tuple(range(1, len(results) + 1)):
|
|
928
|
+
raise AlgorithmOutputError("R²AG retrieval ranks must be contiguous and one-based")
|
|
929
|
+
return results
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
def _real_context(
|
|
933
|
+
result: RetrievalResult,
|
|
934
|
+
feature: Mapping[str, float],
|
|
935
|
+
) -> ContextBlock:
|
|
936
|
+
document = result.document
|
|
937
|
+
if not document.corpus_revision:
|
|
938
|
+
raise AlgorithmOutputError("R²AG evidence requires a corpus revision")
|
|
939
|
+
reserved = {
|
|
940
|
+
"corpus_revision",
|
|
941
|
+
"document_id",
|
|
942
|
+
"evidence_kind",
|
|
943
|
+
"rank",
|
|
944
|
+
"r2ag_features",
|
|
945
|
+
"title",
|
|
946
|
+
}
|
|
947
|
+
if reserved & set(document.metadata):
|
|
948
|
+
raise AlgorithmOutputError("R²AG document metadata uses reserved provenance keys")
|
|
949
|
+
return ContextBlock(
|
|
950
|
+
block_id=document.doc_id,
|
|
951
|
+
text=document.text,
|
|
952
|
+
source=document.corpus_revision,
|
|
953
|
+
score=result.score,
|
|
954
|
+
metadata={
|
|
955
|
+
**dict(document.metadata),
|
|
956
|
+
"document_id": document.doc_id,
|
|
957
|
+
"title": document.title,
|
|
958
|
+
"corpus_revision": document.corpus_revision,
|
|
959
|
+
"rank": result.rank,
|
|
960
|
+
"r2ag_features": dict(feature),
|
|
961
|
+
"evidence_kind": "real_corpus_document",
|
|
962
|
+
},
|
|
963
|
+
)
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
def r2ag_reader_prompt(
|
|
967
|
+
query: str,
|
|
968
|
+
documents: Sequence[RetrievalResult],
|
|
969
|
+
*,
|
|
970
|
+
max_document_chars: int,
|
|
971
|
+
) -> str:
|
|
972
|
+
rows = [
|
|
973
|
+
"Use the retrieval signals and documents to propose a concise answer. The answer is a "
|
|
974
|
+
"hypothesis and must not invent facts absent from the documents.",
|
|
975
|
+
f"Question: {query.strip()}",
|
|
976
|
+
"Documents:",
|
|
977
|
+
]
|
|
978
|
+
for index, item in enumerate(documents, start=1):
|
|
979
|
+
title = item.document.title.strip() or item.document.doc_id
|
|
980
|
+
text = item.document.text.strip()[:max_document_chars]
|
|
981
|
+
rows.append(f"[{index}] relevance: {_MARKER} Title: {title}\n{text}")
|
|
982
|
+
rows.append("Answer:")
|
|
983
|
+
return "\n".join(rows)
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
def _tensor_sha256(value: Any, torch: Any) -> str:
|
|
987
|
+
tensor = value.detach().cpu().contiguous()
|
|
988
|
+
digest = hashlib.sha256()
|
|
989
|
+
digest.update(str(tensor.dtype).encode("ascii"))
|
|
990
|
+
digest.update(json.dumps(tuple(tensor.shape)).encode("ascii"))
|
|
991
|
+
digest.update(tensor.view(torch.uint8).numpy().tobytes())
|
|
992
|
+
return digest.hexdigest()
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
def r2ag_model_tree_sha256(root: Path) -> str:
|
|
996
|
+
records: list[tuple[str, str]] = []
|
|
997
|
+
for path in sorted(root.rglob("*")):
|
|
998
|
+
if path.is_symlink():
|
|
999
|
+
raise ValidationError("R²AG feature model load set may not contain symlinks")
|
|
1000
|
+
if path.is_file():
|
|
1001
|
+
records.append((str(path.relative_to(root)), _sha256_file(path)))
|
|
1002
|
+
if not records:
|
|
1003
|
+
raise ValidationError("R²AG feature model load set is empty")
|
|
1004
|
+
return content_hash(records)
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
def _load_source_module(path: Path, name: str) -> ModuleType:
|
|
1008
|
+
spec = importlib.util.spec_from_file_location(name, path)
|
|
1009
|
+
if spec is None or spec.loader is None:
|
|
1010
|
+
raise ExternalDependencyError("unable to import pinned R²AG source")
|
|
1011
|
+
module = importlib.util.module_from_spec(spec)
|
|
1012
|
+
spec.loader.exec_module(module)
|
|
1013
|
+
return module
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
__all__ = [
|
|
1017
|
+
"LocalR2AGCommonSupportReader",
|
|
1018
|
+
"LocalR2AGCommonSupportRuntime",
|
|
1019
|
+
"LocalSentenceTransformerR2AGFeatureEncoder",
|
|
1020
|
+
"R2AGCommonSupport",
|
|
1021
|
+
"R2AGCommonSupportConfig",
|
|
1022
|
+
"R2AGCommonSupportReader",
|
|
1023
|
+
"R2AGCommonSupportRuntime",
|
|
1024
|
+
"R2AGFeatureEncoder",
|
|
1025
|
+
"R2AGReaderResult",
|
|
1026
|
+
"R2AGRuntimeRequest",
|
|
1027
|
+
"r2ag_model_tree_sha256",
|
|
1028
|
+
"r2ag_reader_prompt",
|
|
1029
|
+
]
|