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,1129 @@
|
|
|
1
|
+
"""License-gated external bridges for the two released RECOMP compressors.
|
|
2
|
+
|
|
3
|
+
The pinned repository exposes an extractive sentence scorer and a Hugging Face
|
|
4
|
+
seq2seq prediction script, rather than one online RECOMP runtime. These
|
|
5
|
+
adapters therefore keep model execution in a user-mounted worker and make the
|
|
6
|
+
small amount of AgentInputLab assembly explicit and auditable.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import hashlib
|
|
12
|
+
import re
|
|
13
|
+
from collections.abc import Mapping
|
|
14
|
+
from dataclasses import asdict, dataclass, replace
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from agentinputlab.contracts import (
|
|
18
|
+
AlgorithmOutputError,
|
|
19
|
+
BudgetExceededError,
|
|
20
|
+
ContextBlock,
|
|
21
|
+
ExecutionTrace,
|
|
22
|
+
ExternalDependencyError,
|
|
23
|
+
FrozenAgentState,
|
|
24
|
+
InputPatch,
|
|
25
|
+
InterventionContext,
|
|
26
|
+
PatchOp,
|
|
27
|
+
PatchOperation,
|
|
28
|
+
SemanticFamily,
|
|
29
|
+
TraceEvent,
|
|
30
|
+
TracePhase,
|
|
31
|
+
ValidationError,
|
|
32
|
+
)
|
|
33
|
+
from agentinputlab.contracts.serialization import content_hash
|
|
34
|
+
from agentinputlab.integrations.external_workers import WorkerClient
|
|
35
|
+
from agentinputlab.integrations.external_workers.method import (
|
|
36
|
+
MethodWorkerRequest,
|
|
37
|
+
call_worker,
|
|
38
|
+
dependency_fingerprint,
|
|
39
|
+
finite_number,
|
|
40
|
+
mapping_sequence,
|
|
41
|
+
nonnegative_integer,
|
|
42
|
+
optional_text,
|
|
43
|
+
required_text,
|
|
44
|
+
resolve_worker,
|
|
45
|
+
string_tuple,
|
|
46
|
+
worker_fingerprint,
|
|
47
|
+
)
|
|
48
|
+
from agentinputlab.observability import external_usage_counters
|
|
49
|
+
|
|
50
|
+
RECOMP_UPSTREAM_COMMIT = "51d4432151efb3275257a9407dc71d1e5ec6634d"
|
|
51
|
+
RECOMP_EXTRACTIVE_PROTOCOL = "agentinputlab.recomp.extractive.v3"
|
|
52
|
+
RECOMP_ABSTRACTIVE_PROTOCOL = "agentinputlab.recomp.abstractive.v3"
|
|
53
|
+
RECOMP_CANDIDATE_UNIT_KIND = "presegmented_sentence"
|
|
54
|
+
RECOMP_COMMON_SUPPORT_RELEASE = "curate.recomp.common_support_extractive"
|
|
55
|
+
RECOMP_COMMON_SUPPORT_SPLITTER = "agentinputlab.visible_context_sentence_split.v1"
|
|
56
|
+
RECOMP_ABSTRACTIVE_INPUT_TEMPLATE = "Question: {question}\n Document: {passages}\n Summary: "
|
|
57
|
+
RECOMP_ABSTRACTIVE_INPUT_TEMPLATE_SHA256 = hashlib.sha256(
|
|
58
|
+
RECOMP_ABSTRACTIVE_INPUT_TEMPLATE.encode("utf-8")
|
|
59
|
+
).hexdigest()
|
|
60
|
+
_HEX64 = re.compile(r"^[0-9a-f]{64}$")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(frozen=True, slots=True)
|
|
64
|
+
class RECOMPExtractiveControls:
|
|
65
|
+
"""AgentInputLab's explicit assembly policy for upstream sentence scores."""
|
|
66
|
+
|
|
67
|
+
max_sentences: int = 5
|
|
68
|
+
minimum_score: float | None = None
|
|
69
|
+
output_order: str = "source_order"
|
|
70
|
+
assembly_profile: str = "controlled"
|
|
71
|
+
dataset: str = ""
|
|
72
|
+
|
|
73
|
+
def __post_init__(self) -> None:
|
|
74
|
+
if (
|
|
75
|
+
isinstance(self.max_sentences, bool)
|
|
76
|
+
or not isinstance(self.max_sentences, int)
|
|
77
|
+
or (self.max_sentences != -1 and self.max_sentences < 1)
|
|
78
|
+
):
|
|
79
|
+
raise ValidationError("RECOMP max_sentences must be -1 or positive")
|
|
80
|
+
if self.minimum_score is not None:
|
|
81
|
+
finite_number(self.minimum_score, label="RECOMP minimum_score")
|
|
82
|
+
if self.output_order not in {"source_order", "score_descending"}:
|
|
83
|
+
raise ValidationError("RECOMP output_order must be source_order or score_descending")
|
|
84
|
+
if self.assembly_profile not in {"controlled", "native_paper_qa"}:
|
|
85
|
+
raise ValidationError("RECOMP assembly_profile is unsupported")
|
|
86
|
+
if self.assembly_profile == "controlled":
|
|
87
|
+
if self.dataset:
|
|
88
|
+
raise ValidationError("controlled RECOMP assembly must not claim a paper dataset")
|
|
89
|
+
return
|
|
90
|
+
expected = {"nq": 1, "tqa": 1, "hotpotqa": 2}.get(self.dataset)
|
|
91
|
+
if expected is None:
|
|
92
|
+
raise ValidationError("paper-native RECOMP dataset must be nq, tqa, or hotpotqa")
|
|
93
|
+
if (
|
|
94
|
+
self.max_sentences != expected
|
|
95
|
+
or self.minimum_score is not None
|
|
96
|
+
or self.output_order != "score_descending"
|
|
97
|
+
):
|
|
98
|
+
raise ValidationError(
|
|
99
|
+
"paper-native RECOMP requires top-1 NQ/TQA or top-2 HotpotQA by score"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
@classmethod
|
|
103
|
+
def paper_native(cls, dataset: str) -> RECOMPExtractiveControls:
|
|
104
|
+
normalized = dataset.lower()
|
|
105
|
+
expected = {"nq": 1, "tqa": 1, "hotpotqa": 2}.get(normalized)
|
|
106
|
+
if expected is None:
|
|
107
|
+
raise ValidationError("paper-native RECOMP dataset must be nq, tqa, or hotpotqa")
|
|
108
|
+
return cls(
|
|
109
|
+
max_sentences=expected,
|
|
110
|
+
output_order="score_descending",
|
|
111
|
+
assembly_profile="native_paper_qa",
|
|
112
|
+
dataset=normalized,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@dataclass(frozen=True, slots=True)
|
|
117
|
+
class RECOMPAbstractiveControls:
|
|
118
|
+
max_source_tokens: int = 1024
|
|
119
|
+
max_target_tokens: int = 512
|
|
120
|
+
num_beams: int = 1
|
|
121
|
+
empty_output_policy: str = "clear_context"
|
|
122
|
+
input_assembly: str = "controlled_concatenate_no_separator"
|
|
123
|
+
|
|
124
|
+
def __post_init__(self) -> None:
|
|
125
|
+
if any(
|
|
126
|
+
isinstance(value, bool) or not isinstance(value, int) or value < 1
|
|
127
|
+
for value in (self.max_source_tokens, self.max_target_tokens, self.num_beams)
|
|
128
|
+
):
|
|
129
|
+
raise ValidationError("RECOMP generation limits must be positive")
|
|
130
|
+
if self.empty_output_policy != "clear_context":
|
|
131
|
+
raise ValidationError(
|
|
132
|
+
"RECOMP empty output is selective augmentation and must clear context"
|
|
133
|
+
)
|
|
134
|
+
if self.input_assembly not in {
|
|
135
|
+
"controlled_concatenate_no_separator",
|
|
136
|
+
"prejoined_official_artifact",
|
|
137
|
+
}:
|
|
138
|
+
raise ValidationError("RECOMP abstractive input assembly is unsupported")
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@dataclass(frozen=True, slots=True)
|
|
142
|
+
class RECOMPSentenceScore:
|
|
143
|
+
sentence_id: str
|
|
144
|
+
document_id: str
|
|
145
|
+
document_index: int
|
|
146
|
+
sentence_index: int
|
|
147
|
+
char_start: int
|
|
148
|
+
char_end: int
|
|
149
|
+
text: str
|
|
150
|
+
score: float
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def source_order(self) -> tuple[int, int, int]:
|
|
154
|
+
return (self.document_index, self.char_start, self.sentence_index)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@dataclass(frozen=True, slots=True)
|
|
158
|
+
class _SourceSentence:
|
|
159
|
+
block: ContextBlock
|
|
160
|
+
source_block_id: str
|
|
161
|
+
source_block_index: int
|
|
162
|
+
char_start: int
|
|
163
|
+
char_end: int
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _common_support_sentences(
|
|
167
|
+
context: tuple[ContextBlock, ...],
|
|
168
|
+
*,
|
|
169
|
+
max_candidates: int | None = None,
|
|
170
|
+
) -> tuple[_SourceSentence, ...]:
|
|
171
|
+
"""Split visible blocks into immutable RECOMP candidate units.
|
|
172
|
+
|
|
173
|
+
The upstream inference function consumes already segmented sentences. Its
|
|
174
|
+
repository does not publish the dataset-specific splitter, so the common-
|
|
175
|
+
support profile freezes a minimal punctuation/newline splitter and records
|
|
176
|
+
exact offsets back to the captured arena block. No hidden benchmark state
|
|
177
|
+
or answer label participates in this preprocessing step.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
candidates: list[_SourceSentence] = []
|
|
181
|
+
boundary = re.compile(r"(?<=[.!?])\s+|\n+")
|
|
182
|
+
for block_index, source in enumerate(context):
|
|
183
|
+
source_id = source.block_id or f"context-{block_index}"
|
|
184
|
+
cursor = 0
|
|
185
|
+
sentence_index = 0
|
|
186
|
+
for match in (*boundary.finditer(source.text), None):
|
|
187
|
+
stop = len(source.text) if match is None else match.start()
|
|
188
|
+
raw = source.text[cursor:stop]
|
|
189
|
+
leading = len(raw) - len(raw.lstrip())
|
|
190
|
+
trailing = len(raw.rstrip())
|
|
191
|
+
start = cursor + leading
|
|
192
|
+
end = cursor + trailing
|
|
193
|
+
if end > start:
|
|
194
|
+
sentence_id = f"{source_id}:sentence:{sentence_index}"
|
|
195
|
+
candidates.append(
|
|
196
|
+
_SourceSentence(
|
|
197
|
+
block=ContextBlock(
|
|
198
|
+
block_id=sentence_id,
|
|
199
|
+
text=source.text[start:end],
|
|
200
|
+
source="recomp_common_support_preprocessor",
|
|
201
|
+
metadata={
|
|
202
|
+
"source_context_block_id": source_id,
|
|
203
|
+
"source_context_block_index": block_index,
|
|
204
|
+
"source_char_start": start,
|
|
205
|
+
"source_char_end": end,
|
|
206
|
+
"splitter_revision": RECOMP_COMMON_SUPPORT_SPLITTER,
|
|
207
|
+
},
|
|
208
|
+
),
|
|
209
|
+
source_block_id=source_id,
|
|
210
|
+
source_block_index=block_index,
|
|
211
|
+
char_start=start,
|
|
212
|
+
char_end=end,
|
|
213
|
+
)
|
|
214
|
+
)
|
|
215
|
+
if max_candidates is not None and len(candidates) > max_candidates:
|
|
216
|
+
raise ValidationError("RECOMP sentence candidate limit exceeded; no truncation applied")
|
|
217
|
+
sentence_index += 1
|
|
218
|
+
if match is None:
|
|
219
|
+
break
|
|
220
|
+
cursor = match.end()
|
|
221
|
+
if not candidates:
|
|
222
|
+
raise ValidationError("RECOMP common-support requires non-empty visible context")
|
|
223
|
+
return tuple(candidates)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def prepare_recomp_sentence_state(
|
|
227
|
+
state: FrozenAgentState, *, max_candidates: int = 4096,
|
|
228
|
+
) -> FrozenAgentState:
|
|
229
|
+
"""Prepare bounded, source-offset-bound inputs for the extractive interface.
|
|
230
|
+
|
|
231
|
+
This is the same disclosed punctuation/newline splitter as the controlled
|
|
232
|
+
common-support adapter, not a claimed upstream dataset-specific splitter.
|
|
233
|
+
No model, retrieval, reference labels or network are used. Apply it to the
|
|
234
|
+
common input of both NO_OP and compressor arms, not just to the treatment.
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
if not isinstance(state, FrozenAgentState):
|
|
238
|
+
raise ValidationError("RECOMP sentence preparation requires a FrozenAgentState")
|
|
239
|
+
if type(max_candidates) is not int or max_candidates < 1:
|
|
240
|
+
raise ValidationError("RECOMP max_candidates must be a positive integer")
|
|
241
|
+
if "recomp_sentence_preparation" in state.metadata:
|
|
242
|
+
raise ValidationError("state already has RECOMP sentence preparation; use it directly")
|
|
243
|
+
sentences = _common_support_sentences(state.context, max_candidates=max_candidates)
|
|
244
|
+
ids = [item.block.block_id for item in sentences]
|
|
245
|
+
if len(ids) != len(set(ids)):
|
|
246
|
+
raise ValidationError("RECOMP sentence preparation has ambiguous source block IDs")
|
|
247
|
+
blocks = tuple(replace(item.block, metadata={
|
|
248
|
+
**dict(item.block.metadata), "source_captured_state_hash": state.state_hash,
|
|
249
|
+
}) for item in sentences)
|
|
250
|
+
return replace(state, context=blocks, metadata={
|
|
251
|
+
**dict(state.metadata),
|
|
252
|
+
"recomp_sentence_preparation": {
|
|
253
|
+
"splitter_revision": RECOMP_COMMON_SUPPORT_SPLITTER,
|
|
254
|
+
"source_state_hash": state.state_hash,
|
|
255
|
+
"source_context_blocks": len(state.context),
|
|
256
|
+
"candidate_sentences": len(blocks),
|
|
257
|
+
"max_candidates": max_candidates,
|
|
258
|
+
"reference_or_network_access": False,
|
|
259
|
+
"paper_native_preprocessing_claimed": False,
|
|
260
|
+
},
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@dataclass(slots=True)
|
|
265
|
+
class RECOMPExtractiveCommonSupport:
|
|
266
|
+
"""Source-faithful scorer plus a frozen visible-context sentence adapter."""
|
|
267
|
+
|
|
268
|
+
checkpoint_revision: str = ""
|
|
269
|
+
tokenizer_revision: str = ""
|
|
270
|
+
asset_manifest_hash: str = ""
|
|
271
|
+
asset_license_acknowledged: bool = False
|
|
272
|
+
controls: RECOMPExtractiveControls = RECOMPExtractiveControls()
|
|
273
|
+
method_id: str = "recomp"
|
|
274
|
+
release_id: str = RECOMP_COMMON_SUPPORT_RELEASE
|
|
275
|
+
family: SemanticFamily = SemanticFamily.CURATE
|
|
276
|
+
|
|
277
|
+
def __post_init__(self) -> None:
|
|
278
|
+
_validate_asset_identity(
|
|
279
|
+
checkpoint_revision=self.checkpoint_revision,
|
|
280
|
+
tokenizer_revision=self.tokenizer_revision,
|
|
281
|
+
asset_manifest_hash=self.asset_manifest_hash,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
|
|
285
|
+
sentences = _common_support_sentences(state.context)
|
|
286
|
+
derived = replace(state, context=tuple(item.block for item in sentences))
|
|
287
|
+
component = RECOMPExtractiveExternal(
|
|
288
|
+
checkpoint_revision=self.checkpoint_revision,
|
|
289
|
+
tokenizer_revision=self.tokenizer_revision,
|
|
290
|
+
sentence_splitter_revision=RECOMP_COMMON_SUPPORT_SPLITTER,
|
|
291
|
+
asset_manifest_hash=self.asset_manifest_hash,
|
|
292
|
+
asset_license_acknowledged=self.asset_license_acknowledged,
|
|
293
|
+
controls=self.controls,
|
|
294
|
+
).propose(derived, context)
|
|
295
|
+
source_by_sentence = {item.block.block_id: item for item in sentences}
|
|
296
|
+
operations: list[PatchOperation] = []
|
|
297
|
+
for operation in component.operations:
|
|
298
|
+
if operation.op is not PatchOp.REPLACE_CONTEXT:
|
|
299
|
+
raise AlgorithmOutputError(
|
|
300
|
+
"RECOMP common-support component emitted an unexpected patch operation"
|
|
301
|
+
)
|
|
302
|
+
selected: list[ContextBlock] = []
|
|
303
|
+
for block in operation.value:
|
|
304
|
+
sentence_id = str(block.metadata.get("source_document_id", ""))
|
|
305
|
+
source = source_by_sentence.get(sentence_id)
|
|
306
|
+
if source is None or block.text != source.block.text:
|
|
307
|
+
raise AlgorithmOutputError(
|
|
308
|
+
"RECOMP common-support output lost its source sentence binding"
|
|
309
|
+
)
|
|
310
|
+
selected.append(
|
|
311
|
+
ContextBlock(
|
|
312
|
+
block_id=block.block_id,
|
|
313
|
+
text=block.text,
|
|
314
|
+
source=block.source,
|
|
315
|
+
score=block.score,
|
|
316
|
+
metadata={
|
|
317
|
+
**dict(block.metadata),
|
|
318
|
+
"source_context_block_id": source.source_block_id,
|
|
319
|
+
"source_context_block_index": source.source_block_index,
|
|
320
|
+
"source_char_start": source.char_start,
|
|
321
|
+
"source_char_end": source.char_end,
|
|
322
|
+
"source_captured_state_hash": state.state_hash,
|
|
323
|
+
"splitter_revision": RECOMP_COMMON_SUPPORT_SPLITTER,
|
|
324
|
+
},
|
|
325
|
+
)
|
|
326
|
+
)
|
|
327
|
+
operations.append(
|
|
328
|
+
PatchOperation(
|
|
329
|
+
PatchOp.REPLACE_CONTEXT,
|
|
330
|
+
tuple(selected),
|
|
331
|
+
target=operation.target,
|
|
332
|
+
rationale=(
|
|
333
|
+
"official RECOMP sentence scores after frozen visible-context "
|
|
334
|
+
"presegmentation"
|
|
335
|
+
),
|
|
336
|
+
)
|
|
337
|
+
)
|
|
338
|
+
trace = ExecutionTrace(
|
|
339
|
+
method_id=self.method_id,
|
|
340
|
+
release_id=self.release_id,
|
|
341
|
+
events=(
|
|
342
|
+
TraceEvent(
|
|
343
|
+
TracePhase.PREPARE,
|
|
344
|
+
"recomp_common_support_presegmentation",
|
|
345
|
+
{
|
|
346
|
+
"splitter_revision": RECOMP_COMMON_SUPPORT_SPLITTER,
|
|
347
|
+
"source_state_hash": state.state_hash,
|
|
348
|
+
"derived_state_hash": derived.state_hash,
|
|
349
|
+
"source_block_count": len(state.context),
|
|
350
|
+
"candidate_sentence_count": len(sentences),
|
|
351
|
+
"candidate_manifest_hash": content_hash(
|
|
352
|
+
tuple(
|
|
353
|
+
{
|
|
354
|
+
"sentence_id": item.block.block_id,
|
|
355
|
+
"text": item.block.text,
|
|
356
|
+
"source_block_id": item.source_block_id,
|
|
357
|
+
"source_block_index": item.source_block_index,
|
|
358
|
+
"char_start": item.char_start,
|
|
359
|
+
"char_end": item.char_end,
|
|
360
|
+
}
|
|
361
|
+
for item in sentences
|
|
362
|
+
)
|
|
363
|
+
),
|
|
364
|
+
},
|
|
365
|
+
),
|
|
366
|
+
*component.trace.events,
|
|
367
|
+
),
|
|
368
|
+
counters={
|
|
369
|
+
**dict(component.trace.counters),
|
|
370
|
+
"source_context_blocks": len(state.context),
|
|
371
|
+
"candidate_sentences": len(sentences),
|
|
372
|
+
},
|
|
373
|
+
warnings=(
|
|
374
|
+
*component.trace.warnings,
|
|
375
|
+
"controlled_common_support_sentence_splitter_not_paper_result_parity",
|
|
376
|
+
),
|
|
377
|
+
)
|
|
378
|
+
return InputPatch(
|
|
379
|
+
method_id=self.method_id,
|
|
380
|
+
release_id=self.release_id,
|
|
381
|
+
source_state_hash=state.state_hash,
|
|
382
|
+
operations=tuple(operations),
|
|
383
|
+
trace=trace,
|
|
384
|
+
implementation_identity=(
|
|
385
|
+
"common_support_preprocessor+"
|
|
386
|
+
f"thin_external_wrapper:carriex/recomp@{RECOMP_UPSTREAM_COMMIT}"
|
|
387
|
+
),
|
|
388
|
+
profile_kind="controlled_adapter",
|
|
389
|
+
metadata={
|
|
390
|
+
**dict(component.metadata),
|
|
391
|
+
"component_release_id": component.release_id,
|
|
392
|
+
"common_support_splitter_revision": RECOMP_COMMON_SUPPORT_SPLITTER,
|
|
393
|
+
"source_state_hash": state.state_hash,
|
|
394
|
+
"derived_candidate_state_hash": derived.state_hash,
|
|
395
|
+
"paper_result_parity_claimed": False,
|
|
396
|
+
},
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
@dataclass(slots=True)
|
|
401
|
+
class RECOMPExtractiveExternal:
|
|
402
|
+
"""Run the official scorer externally, then apply a frozen assembly rule."""
|
|
403
|
+
|
|
404
|
+
client: WorkerClient | None = None
|
|
405
|
+
checkpoint_revision: str = ""
|
|
406
|
+
tokenizer_revision: str = ""
|
|
407
|
+
sentence_splitter_revision: str = ""
|
|
408
|
+
asset_manifest_hash: str = ""
|
|
409
|
+
asset_license_acknowledged: bool = False
|
|
410
|
+
controls: RECOMPExtractiveControls = RECOMPExtractiveControls()
|
|
411
|
+
method_id: str = "recomp"
|
|
412
|
+
release_id: str = "curate.recomp.extractive"
|
|
413
|
+
family: SemanticFamily = SemanticFamily.CURATE
|
|
414
|
+
|
|
415
|
+
def __post_init__(self) -> None:
|
|
416
|
+
_validate_asset_identity(
|
|
417
|
+
checkpoint_revision=self.checkpoint_revision,
|
|
418
|
+
tokenizer_revision=self.tokenizer_revision,
|
|
419
|
+
asset_manifest_hash=self.asset_manifest_hash,
|
|
420
|
+
)
|
|
421
|
+
if not self.sentence_splitter_revision.strip():
|
|
422
|
+
raise ValidationError("RECOMP sentence_splitter_revision must not be empty")
|
|
423
|
+
|
|
424
|
+
def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
|
|
425
|
+
document_ids = _document_ids(state)
|
|
426
|
+
_require_asset_acknowledgement(self.asset_license_acknowledged)
|
|
427
|
+
worker = resolve_worker(self.client, context, label="RECOMP extractive")
|
|
428
|
+
worker_identity = worker_fingerprint(worker, label="RECOMP extractive")
|
|
429
|
+
retriever_fp = dependency_fingerprint(
|
|
430
|
+
context.retriever, label="RECOMP upstream retriever", required=True
|
|
431
|
+
)
|
|
432
|
+
retriever_hash = content_hash(retriever_fp)
|
|
433
|
+
input_hash = content_hash(
|
|
434
|
+
{
|
|
435
|
+
"query": state.query,
|
|
436
|
+
"documents": state.context,
|
|
437
|
+
"document_ids": document_ids,
|
|
438
|
+
"candidate_unit_kind": RECOMP_CANDIDATE_UNIT_KIND,
|
|
439
|
+
}
|
|
440
|
+
)
|
|
441
|
+
remaining_budget = _remaining_execution_budget(state, context)
|
|
442
|
+
_require_local_compute_budget(
|
|
443
|
+
remaining_budget,
|
|
444
|
+
output_tokens_required=0,
|
|
445
|
+
)
|
|
446
|
+
base_payload = {
|
|
447
|
+
"task_id": state.task_id,
|
|
448
|
+
"query": state.query,
|
|
449
|
+
"documents": state.context,
|
|
450
|
+
"document_ids": document_ids,
|
|
451
|
+
"checkpoint_revision": self.checkpoint_revision,
|
|
452
|
+
"tokenizer_revision": self.tokenizer_revision,
|
|
453
|
+
"sentence_splitter_revision": self.sentence_splitter_revision,
|
|
454
|
+
"asset_manifest_hash": self.asset_manifest_hash,
|
|
455
|
+
"retriever_artifact_hash": retriever_hash,
|
|
456
|
+
"input_artifact_hash": input_hash,
|
|
457
|
+
"candidate_unit_kind": RECOMP_CANDIDATE_UNIT_KIND,
|
|
458
|
+
"controls": asdict(self.controls),
|
|
459
|
+
"seed": context.seed,
|
|
460
|
+
}
|
|
461
|
+
preflight_payload, response = _preflight_then_execute(
|
|
462
|
+
worker=worker,
|
|
463
|
+
worker_identity=worker_identity,
|
|
464
|
+
method_id=self.method_id,
|
|
465
|
+
release_id=self.release_id,
|
|
466
|
+
protocol=RECOMP_EXTRACTIVE_PROTOCOL,
|
|
467
|
+
state_hash=state.state_hash,
|
|
468
|
+
base_payload=base_payload,
|
|
469
|
+
dependencies={"retriever": retriever_fp},
|
|
470
|
+
remaining_budget=remaining_budget,
|
|
471
|
+
)
|
|
472
|
+
_validate_response_identity(
|
|
473
|
+
response.payload,
|
|
474
|
+
checkpoint_revision=self.checkpoint_revision,
|
|
475
|
+
tokenizer_revision=self.tokenizer_revision,
|
|
476
|
+
asset_manifest_hash=self.asset_manifest_hash,
|
|
477
|
+
document_ids=document_ids,
|
|
478
|
+
retriever_artifact_hash=retriever_hash,
|
|
479
|
+
input_artifact_hash=input_hash,
|
|
480
|
+
)
|
|
481
|
+
_validate_worker_attestation(response.payload, worker_identity)
|
|
482
|
+
if response.payload.get("candidate_unit_kind") != RECOMP_CANDIDATE_UNIT_KIND:
|
|
483
|
+
raise AlgorithmOutputError("RECOMP worker changed fixed candidate units")
|
|
484
|
+
if response.payload.get("scoring_api") != (
|
|
485
|
+
"run_extractive_compressor.get_contriever_scores(top_k=-1)"
|
|
486
|
+
):
|
|
487
|
+
raise AlgorithmOutputError("RECOMP worker did not use the pinned scoring API")
|
|
488
|
+
if response.usage.model_calls != 1 or response.usage.retrieval_calls != 0:
|
|
489
|
+
raise AlgorithmOutputError("RECOMP scorer usage is inconsistent")
|
|
490
|
+
returned_splitter = required_text(
|
|
491
|
+
response.payload,
|
|
492
|
+
"sentence_splitter_revision",
|
|
493
|
+
label="RECOMP extractive response",
|
|
494
|
+
)
|
|
495
|
+
if returned_splitter != self.sentence_splitter_revision:
|
|
496
|
+
raise AlgorithmOutputError("RECOMP sentence splitter revision mismatch")
|
|
497
|
+
scores = _parse_sentence_scores(response.payload.get("sentence_scores"), state)
|
|
498
|
+
selected = _select_sentences(scores, self.controls)
|
|
499
|
+
blocks = tuple(
|
|
500
|
+
ContextBlock(
|
|
501
|
+
block_id=f"recomp:{record.sentence_id}",
|
|
502
|
+
text=record.text,
|
|
503
|
+
source="recomp_extractive",
|
|
504
|
+
score=record.score,
|
|
505
|
+
metadata={
|
|
506
|
+
"source_document_id": record.document_id,
|
|
507
|
+
"source_document_index": record.document_index,
|
|
508
|
+
"source_sentence_index": record.sentence_index,
|
|
509
|
+
"source_char_start": record.char_start,
|
|
510
|
+
"source_char_end": record.char_end,
|
|
511
|
+
"source_state_hash": state.state_hash,
|
|
512
|
+
},
|
|
513
|
+
)
|
|
514
|
+
for record in selected
|
|
515
|
+
)
|
|
516
|
+
trace = ExecutionTrace(
|
|
517
|
+
method_id=self.method_id,
|
|
518
|
+
release_id=self.release_id,
|
|
519
|
+
events=(
|
|
520
|
+
TraceEvent(
|
|
521
|
+
TracePhase.PREPARE,
|
|
522
|
+
"recomp_extractive_assets",
|
|
523
|
+
{
|
|
524
|
+
"checkpoint_revision": self.checkpoint_revision,
|
|
525
|
+
"tokenizer_revision": self.tokenizer_revision,
|
|
526
|
+
"sentence_splitter_revision": self.sentence_splitter_revision,
|
|
527
|
+
"document_ids": document_ids,
|
|
528
|
+
},
|
|
529
|
+
),
|
|
530
|
+
TraceEvent(
|
|
531
|
+
TracePhase.OBSERVE,
|
|
532
|
+
"official_sentence_scores",
|
|
533
|
+
{
|
|
534
|
+
"sentence_ids": tuple(item.sentence_id for item in scores),
|
|
535
|
+
"scores": tuple(item.score for item in scores),
|
|
536
|
+
},
|
|
537
|
+
),
|
|
538
|
+
TraceEvent(
|
|
539
|
+
TracePhase.FINALIZE,
|
|
540
|
+
"agentinputlab_assembly",
|
|
541
|
+
{
|
|
542
|
+
"controls": asdict(self.controls),
|
|
543
|
+
"selected_sentence_ids": tuple(item.sentence_id for item in selected),
|
|
544
|
+
},
|
|
545
|
+
),
|
|
546
|
+
),
|
|
547
|
+
counters={
|
|
548
|
+
**external_usage_counters(response.usage),
|
|
549
|
+
"worker_calls": 2,
|
|
550
|
+
"scored_sentences": len(scores),
|
|
551
|
+
"selected_sentences": len(selected),
|
|
552
|
+
},
|
|
553
|
+
)
|
|
554
|
+
return InputPatch(
|
|
555
|
+
method_id=self.method_id,
|
|
556
|
+
release_id=self.release_id,
|
|
557
|
+
source_state_hash=state.state_hash,
|
|
558
|
+
operations=(
|
|
559
|
+
PatchOperation(
|
|
560
|
+
PatchOp.REPLACE_CONTEXT,
|
|
561
|
+
blocks,
|
|
562
|
+
target="compressed_retrieved_context",
|
|
563
|
+
rationale="official RECOMP scores with a frozen AgentInputLab assembly policy",
|
|
564
|
+
),
|
|
565
|
+
),
|
|
566
|
+
trace=trace,
|
|
567
|
+
implementation_identity=(
|
|
568
|
+
f"thin_external_wrapper:carriex/recomp@{RECOMP_UPSTREAM_COMMIT}"
|
|
569
|
+
),
|
|
570
|
+
profile_kind=(
|
|
571
|
+
"paper_native_adapter"
|
|
572
|
+
if self.controls.assembly_profile == "native_paper_qa"
|
|
573
|
+
else "controlled_adapter"
|
|
574
|
+
),
|
|
575
|
+
metadata={
|
|
576
|
+
"implementation_origin": "official_scorer_plus_controlled_assembly",
|
|
577
|
+
"known_deviation": "upstream repository does not provide online assembly",
|
|
578
|
+
"asset_license": "NOASSERTION_acknowledged_by_user",
|
|
579
|
+
"asset_manifest_hash": self.asset_manifest_hash,
|
|
580
|
+
"assembly_policy_hash": content_hash(asdict(self.controls)),
|
|
581
|
+
"assembly_profile": self.controls.assembly_profile,
|
|
582
|
+
"retriever_artifact_hash": retriever_hash,
|
|
583
|
+
"input_artifact_hash": input_hash,
|
|
584
|
+
"compatibility_manifest_sha256": response.payload["compatibility_manifest_sha256"],
|
|
585
|
+
"execution_evidence": response.payload["execution_evidence"],
|
|
586
|
+
"worker_fingerprint": worker_identity,
|
|
587
|
+
"runtime_fingerprint": response.payload["runtime_fingerprint"],
|
|
588
|
+
"runtime_fingerprint_hash": response.payload["runtime_fingerprint_hash"],
|
|
589
|
+
"checkpoint_tree_sha256": response.payload["checkpoint_tree_sha256"],
|
|
590
|
+
"preflight_token": preflight_payload["preflight_token"],
|
|
591
|
+
},
|
|
592
|
+
)
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
@dataclass(slots=True)
|
|
596
|
+
class RECOMPAbstractiveExternal:
|
|
597
|
+
"""Bridge the official seq2seq prediction path, preserving empty summaries."""
|
|
598
|
+
|
|
599
|
+
client: WorkerClient | None = None
|
|
600
|
+
checkpoint_revision: str = ""
|
|
601
|
+
tokenizer_revision: str = ""
|
|
602
|
+
input_template_hash: str = ""
|
|
603
|
+
asset_manifest_hash: str = ""
|
|
604
|
+
asset_license_acknowledged: bool = False
|
|
605
|
+
controls: RECOMPAbstractiveControls = RECOMPAbstractiveControls()
|
|
606
|
+
method_id: str = "recomp"
|
|
607
|
+
release_id: str = "curate.recomp.abstractive"
|
|
608
|
+
family: SemanticFamily = SemanticFamily.CURATE
|
|
609
|
+
|
|
610
|
+
def __post_init__(self) -> None:
|
|
611
|
+
_validate_asset_identity(
|
|
612
|
+
checkpoint_revision=self.checkpoint_revision,
|
|
613
|
+
tokenizer_revision=self.tokenizer_revision,
|
|
614
|
+
asset_manifest_hash=self.asset_manifest_hash,
|
|
615
|
+
)
|
|
616
|
+
if self.input_template_hash != RECOMP_ABSTRACTIVE_INPUT_TEMPLATE_SHA256:
|
|
617
|
+
raise ValidationError(
|
|
618
|
+
"RECOMP input_template_hash must match the pinned official prompt"
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
def propose(self, state: FrozenAgentState, context: InterventionContext) -> InputPatch:
|
|
622
|
+
document_ids = _document_ids(state)
|
|
623
|
+
_require_asset_acknowledgement(self.asset_license_acknowledged)
|
|
624
|
+
worker = resolve_worker(self.client, context, label="RECOMP abstractive")
|
|
625
|
+
worker_identity = worker_fingerprint(worker, label="RECOMP abstractive")
|
|
626
|
+
retriever_fp = dependency_fingerprint(
|
|
627
|
+
context.retriever, label="RECOMP upstream retriever", required=True
|
|
628
|
+
)
|
|
629
|
+
retriever_hash = content_hash(retriever_fp)
|
|
630
|
+
if self.controls.input_assembly == "prejoined_official_artifact":
|
|
631
|
+
if len(state.context) != 1:
|
|
632
|
+
raise ValidationError("prejoined RECOMP input requires exactly one context block")
|
|
633
|
+
passages = state.context[0].text
|
|
634
|
+
else:
|
|
635
|
+
passages = "".join(block.text for block in state.context)
|
|
636
|
+
passages_hash = content_hash(passages)
|
|
637
|
+
input_hash = content_hash(
|
|
638
|
+
{
|
|
639
|
+
"query": state.query,
|
|
640
|
+
"documents": state.context,
|
|
641
|
+
"document_ids": document_ids,
|
|
642
|
+
"passages": passages,
|
|
643
|
+
"input_template_hash": self.input_template_hash,
|
|
644
|
+
}
|
|
645
|
+
)
|
|
646
|
+
remaining_budget = _remaining_execution_budget(state, context)
|
|
647
|
+
_require_local_compute_budget(
|
|
648
|
+
remaining_budget,
|
|
649
|
+
output_tokens_required=self.controls.max_target_tokens,
|
|
650
|
+
)
|
|
651
|
+
base_payload = {
|
|
652
|
+
"task_id": state.task_id,
|
|
653
|
+
"query": state.query,
|
|
654
|
+
"documents": state.context,
|
|
655
|
+
"document_ids": document_ids,
|
|
656
|
+
"passages": passages,
|
|
657
|
+
"passages_hash": passages_hash,
|
|
658
|
+
"checkpoint_revision": self.checkpoint_revision,
|
|
659
|
+
"tokenizer_revision": self.tokenizer_revision,
|
|
660
|
+
"input_template_hash": self.input_template_hash,
|
|
661
|
+
"asset_manifest_hash": self.asset_manifest_hash,
|
|
662
|
+
"retriever_artifact_hash": retriever_hash,
|
|
663
|
+
"input_artifact_hash": input_hash,
|
|
664
|
+
"controls": asdict(self.controls),
|
|
665
|
+
"seed": context.seed,
|
|
666
|
+
}
|
|
667
|
+
preflight_payload, response = _preflight_then_execute(
|
|
668
|
+
worker=worker,
|
|
669
|
+
worker_identity=worker_identity,
|
|
670
|
+
method_id=self.method_id,
|
|
671
|
+
release_id=self.release_id,
|
|
672
|
+
protocol=RECOMP_ABSTRACTIVE_PROTOCOL,
|
|
673
|
+
state_hash=state.state_hash,
|
|
674
|
+
base_payload=base_payload,
|
|
675
|
+
dependencies={"retriever": retriever_fp},
|
|
676
|
+
remaining_budget=remaining_budget,
|
|
677
|
+
)
|
|
678
|
+
payload = response.payload
|
|
679
|
+
_validate_response_identity(
|
|
680
|
+
payload,
|
|
681
|
+
checkpoint_revision=self.checkpoint_revision,
|
|
682
|
+
tokenizer_revision=self.tokenizer_revision,
|
|
683
|
+
asset_manifest_hash=self.asset_manifest_hash,
|
|
684
|
+
document_ids=document_ids,
|
|
685
|
+
retriever_artifact_hash=retriever_hash,
|
|
686
|
+
input_artifact_hash=input_hash,
|
|
687
|
+
)
|
|
688
|
+
_validate_worker_attestation(payload, worker_identity)
|
|
689
|
+
if (
|
|
690
|
+
required_text(payload, "input_template_hash", label="RECOMP abstractive response")
|
|
691
|
+
!= self.input_template_hash
|
|
692
|
+
):
|
|
693
|
+
raise AlgorithmOutputError("RECOMP input template hash mismatch")
|
|
694
|
+
if payload.get("passages_hash") != passages_hash:
|
|
695
|
+
raise AlgorithmOutputError("RECOMP passages hash mismatch")
|
|
696
|
+
expected_prompt = RECOMP_ABSTRACTIVE_INPUT_TEMPLATE.format(
|
|
697
|
+
question=state.query, passages=passages
|
|
698
|
+
)
|
|
699
|
+
if payload.get("prompt_hash") != hashlib.sha256(expected_prompt.encode()).hexdigest():
|
|
700
|
+
raise AlgorithmOutputError("RECOMP official prompt hash mismatch")
|
|
701
|
+
if payload.get("generation_api") != ("AutoModelForSeq2SeqLM.generate+batch_decode(strip)"):
|
|
702
|
+
raise AlgorithmOutputError("RECOMP worker did not use the pinned generation path")
|
|
703
|
+
if payload.get("applied") is not True:
|
|
704
|
+
raise AlgorithmOutputError(
|
|
705
|
+
"successful RECOMP generation must report applied=true, including empty output"
|
|
706
|
+
)
|
|
707
|
+
summary = optional_text(payload, "summary", label="RECOMP abstractive response")
|
|
708
|
+
raw_generation = optional_text(
|
|
709
|
+
payload, "raw_generation", label="RECOMP abstractive response"
|
|
710
|
+
)
|
|
711
|
+
if summary != summary.strip():
|
|
712
|
+
raise AlgorithmOutputError("RECOMP summary must be normalized without edge whitespace")
|
|
713
|
+
selective_empty = not summary
|
|
714
|
+
if payload.get("selective_augmentation") is not selective_empty:
|
|
715
|
+
raise AlgorithmOutputError("RECOMP selective-augmentation flag disagrees with output")
|
|
716
|
+
parse_status = required_text(payload, "parse_status", label="RECOMP abstractive response")
|
|
717
|
+
expected_status = "generated_empty" if selective_empty else "generated_text"
|
|
718
|
+
if parse_status != expected_status:
|
|
719
|
+
raise AlgorithmOutputError("RECOMP generation parse status is inconsistent")
|
|
720
|
+
if response.usage.model_calls < 1:
|
|
721
|
+
raise AlgorithmOutputError("RECOMP abstractive generation must report a model call")
|
|
722
|
+
|
|
723
|
+
blocks: tuple[ContextBlock, ...]
|
|
724
|
+
if selective_empty:
|
|
725
|
+
blocks = ()
|
|
726
|
+
else:
|
|
727
|
+
blocks = (
|
|
728
|
+
ContextBlock(
|
|
729
|
+
block_id=f"{self.release_id}:summary",
|
|
730
|
+
text=summary,
|
|
731
|
+
source="recomp_abstractive",
|
|
732
|
+
metadata={
|
|
733
|
+
"source_document_ids": document_ids,
|
|
734
|
+
"source_state_hash": state.state_hash,
|
|
735
|
+
"raw_generation_hash": content_hash(raw_generation),
|
|
736
|
+
},
|
|
737
|
+
),
|
|
738
|
+
)
|
|
739
|
+
trace = ExecutionTrace(
|
|
740
|
+
method_id=self.method_id,
|
|
741
|
+
release_id=self.release_id,
|
|
742
|
+
events=(
|
|
743
|
+
TraceEvent(
|
|
744
|
+
TracePhase.PREPARE,
|
|
745
|
+
"recomp_abstractive_assets",
|
|
746
|
+
{
|
|
747
|
+
"checkpoint_revision": self.checkpoint_revision,
|
|
748
|
+
"tokenizer_revision": self.tokenizer_revision,
|
|
749
|
+
"input_template_hash": self.input_template_hash,
|
|
750
|
+
"document_ids": document_ids,
|
|
751
|
+
},
|
|
752
|
+
),
|
|
753
|
+
TraceEvent(
|
|
754
|
+
TracePhase.FINALIZE,
|
|
755
|
+
"selective_generation",
|
|
756
|
+
{
|
|
757
|
+
"parse_status": parse_status,
|
|
758
|
+
"selective_augmentation": selective_empty,
|
|
759
|
+
"raw_generation": raw_generation,
|
|
760
|
+
"selected_context_count": len(blocks),
|
|
761
|
+
},
|
|
762
|
+
),
|
|
763
|
+
),
|
|
764
|
+
counters={
|
|
765
|
+
**external_usage_counters(response.usage),
|
|
766
|
+
"worker_calls": 2,
|
|
767
|
+
"selected_context_blocks": len(blocks),
|
|
768
|
+
},
|
|
769
|
+
warnings=("selective_augmentation_cleared_context",) if selective_empty else (),
|
|
770
|
+
)
|
|
771
|
+
return InputPatch(
|
|
772
|
+
method_id=self.method_id,
|
|
773
|
+
release_id=self.release_id,
|
|
774
|
+
source_state_hash=state.state_hash,
|
|
775
|
+
operations=(
|
|
776
|
+
PatchOperation(
|
|
777
|
+
PatchOp.REPLACE_CONTEXT,
|
|
778
|
+
blocks,
|
|
779
|
+
target="compressed_retrieved_context",
|
|
780
|
+
rationale=(
|
|
781
|
+
"successful empty RECOMP output disables augmentation"
|
|
782
|
+
if selective_empty
|
|
783
|
+
else "official RECOMP abstractive compressor output"
|
|
784
|
+
),
|
|
785
|
+
),
|
|
786
|
+
),
|
|
787
|
+
trace=trace,
|
|
788
|
+
implementation_identity=(
|
|
789
|
+
f"thin_external_wrapper:carriex/recomp@{RECOMP_UPSTREAM_COMMIT}"
|
|
790
|
+
),
|
|
791
|
+
profile_kind=(
|
|
792
|
+
"official_prompt_adapter"
|
|
793
|
+
if self.controls.input_assembly == "prejoined_official_artifact"
|
|
794
|
+
else "controlled_adapter"
|
|
795
|
+
),
|
|
796
|
+
metadata={
|
|
797
|
+
"implementation_origin": "thin_external_wrapper",
|
|
798
|
+
"asset_license": "NOASSERTION_acknowledged_by_user",
|
|
799
|
+
"asset_manifest_hash": self.asset_manifest_hash,
|
|
800
|
+
"selective_augmentation": selective_empty,
|
|
801
|
+
"applied": True,
|
|
802
|
+
"raw_generation": raw_generation,
|
|
803
|
+
"input_assembly": self.controls.input_assembly,
|
|
804
|
+
"retriever_artifact_hash": retriever_hash,
|
|
805
|
+
"input_artifact_hash": input_hash,
|
|
806
|
+
"compatibility_manifest_sha256": payload["compatibility_manifest_sha256"],
|
|
807
|
+
"execution_evidence": payload["execution_evidence"],
|
|
808
|
+
"worker_fingerprint": worker_identity,
|
|
809
|
+
"runtime_fingerprint": payload["runtime_fingerprint"],
|
|
810
|
+
"runtime_fingerprint_hash": payload["runtime_fingerprint_hash"],
|
|
811
|
+
"checkpoint_tree_sha256": payload["checkpoint_tree_sha256"],
|
|
812
|
+
"preflight_token": preflight_payload["preflight_token"],
|
|
813
|
+
},
|
|
814
|
+
)
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
def _remaining_execution_budget(
|
|
818
|
+
state: FrozenAgentState, context: InterventionContext
|
|
819
|
+
) -> Mapping[str, int | float | None]:
|
|
820
|
+
usage = None
|
|
821
|
+
ledger = context.budget_ledger
|
|
822
|
+
if ledger is not None:
|
|
823
|
+
ledger_budget = getattr(ledger, "budget", None)
|
|
824
|
+
usage = getattr(ledger, "usage", None)
|
|
825
|
+
if ledger_budget != state.budget or usage is None:
|
|
826
|
+
raise ValidationError("RECOMP received an incompatible budget ledger")
|
|
827
|
+
|
|
828
|
+
def consumed_integer(name: str) -> int:
|
|
829
|
+
value = 0 if usage is None else getattr(usage, name, None)
|
|
830
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 0:
|
|
831
|
+
raise ValidationError(f"RECOMP budget usage {name} is invalid")
|
|
832
|
+
return value
|
|
833
|
+
|
|
834
|
+
remaining_context = None
|
|
835
|
+
if state.budget.max_context_tokens is not None:
|
|
836
|
+
remaining_context = max(
|
|
837
|
+
0,
|
|
838
|
+
state.budget.max_context_tokens - consumed_integer("input_tokens"),
|
|
839
|
+
)
|
|
840
|
+
remaining_cost: float | None = None
|
|
841
|
+
if state.budget.max_cost_usd is not None:
|
|
842
|
+
consumed_cost = 0.0 if usage is None else getattr(usage, "total_cost_usd", None)
|
|
843
|
+
if (
|
|
844
|
+
isinstance(consumed_cost, bool)
|
|
845
|
+
or not isinstance(consumed_cost, (int, float))
|
|
846
|
+
or consumed_cost < 0
|
|
847
|
+
):
|
|
848
|
+
raise ValidationError("RECOMP budget usage total_cost_usd is invalid")
|
|
849
|
+
remaining_cost = max(0.0, float(state.budget.max_cost_usd) - float(consumed_cost))
|
|
850
|
+
return {
|
|
851
|
+
"model_calls": max(0, state.budget.max_model_calls - consumed_integer("model_calls")),
|
|
852
|
+
"context_tokens": remaining_context,
|
|
853
|
+
"output_tokens": max(0, state.budget.max_output_tokens - consumed_integer("output_tokens")),
|
|
854
|
+
"cost_usd": remaining_cost,
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
def _require_local_compute_budget(
|
|
859
|
+
budget: Mapping[str, int | float | None], *, output_tokens_required: int
|
|
860
|
+
) -> None:
|
|
861
|
+
if budget["model_calls"] < 1: # type: ignore[operator]
|
|
862
|
+
raise BudgetExceededError("RECOMP requires one remaining model call")
|
|
863
|
+
if budget["output_tokens"] < output_tokens_required: # type: ignore[operator]
|
|
864
|
+
raise BudgetExceededError(
|
|
865
|
+
"RECOMP remaining output-token budget is below the generation maximum"
|
|
866
|
+
)
|
|
867
|
+
if budget["cost_usd"] is not None:
|
|
868
|
+
raise BudgetExceededError(
|
|
869
|
+
"RECOMP local inference is unpriced; a configured cost cap cannot be guaranteed"
|
|
870
|
+
)
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
def _preflight_then_execute(
|
|
874
|
+
*,
|
|
875
|
+
worker: WorkerClient,
|
|
876
|
+
worker_identity: Mapping[str, Any],
|
|
877
|
+
method_id: str,
|
|
878
|
+
release_id: str,
|
|
879
|
+
protocol: str,
|
|
880
|
+
state_hash: str,
|
|
881
|
+
base_payload: Mapping[str, Any],
|
|
882
|
+
dependencies: Mapping[str, Any],
|
|
883
|
+
remaining_budget: Mapping[str, int | float | None],
|
|
884
|
+
) -> tuple[Mapping[str, Any], Any]:
|
|
885
|
+
def request(*, phase: str, token: str) -> MethodWorkerRequest:
|
|
886
|
+
return MethodWorkerRequest(
|
|
887
|
+
method_id=method_id,
|
|
888
|
+
release_id=release_id,
|
|
889
|
+
upstream_commit=RECOMP_UPSTREAM_COMMIT,
|
|
890
|
+
state_hash=state_hash,
|
|
891
|
+
payload={
|
|
892
|
+
**base_payload,
|
|
893
|
+
"phase": phase,
|
|
894
|
+
"preflight_token": token,
|
|
895
|
+
"checkpoint_license_acknowledged": True,
|
|
896
|
+
"remaining_budget": remaining_budget,
|
|
897
|
+
},
|
|
898
|
+
dependency_fingerprints=dependencies,
|
|
899
|
+
minimum_reservation={} if phase == "preflight" else {"model_calls": 1},
|
|
900
|
+
protocol_version=protocol,
|
|
901
|
+
)
|
|
902
|
+
|
|
903
|
+
preflight = call_worker(worker, request(phase="preflight", token=""))
|
|
904
|
+
if (
|
|
905
|
+
preflight.usage.model_calls
|
|
906
|
+
or preflight.usage.retrieval_calls
|
|
907
|
+
or preflight.usage.input_tokens
|
|
908
|
+
or preflight.usage.output_tokens
|
|
909
|
+
or preflight.usage.unpriced_model_calls
|
|
910
|
+
):
|
|
911
|
+
raise AlgorithmOutputError("RECOMP preflight must report zero inference usage")
|
|
912
|
+
payload = preflight.payload
|
|
913
|
+
_validate_worker_attestation(payload, worker_identity)
|
|
914
|
+
_validate_preflight_payload(payload, remaining_budget=remaining_budget)
|
|
915
|
+
token = required_text(payload, "preflight_token", label="RECOMP preflight")
|
|
916
|
+
execute = call_worker(worker, request(phase="execute", token=token))
|
|
917
|
+
_validate_worker_attestation(execute.payload, worker_identity)
|
|
918
|
+
_validate_preflight_payload(execute.payload, remaining_budget=remaining_budget)
|
|
919
|
+
for key in (
|
|
920
|
+
"preflight_token",
|
|
921
|
+
"runtime_fingerprint_hash",
|
|
922
|
+
"checkpoint_tree_sha256",
|
|
923
|
+
"remaining_budget_hash",
|
|
924
|
+
"input_tokens_required",
|
|
925
|
+
"output_tokens_required",
|
|
926
|
+
):
|
|
927
|
+
if execute.payload.get(key) != payload.get(key):
|
|
928
|
+
raise AlgorithmOutputError(f"RECOMP {key} changed after preflight")
|
|
929
|
+
return payload, execute
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
def _validate_preflight_payload(
|
|
933
|
+
payload: Mapping[str, Any],
|
|
934
|
+
*,
|
|
935
|
+
remaining_budget: Mapping[str, int | float | None],
|
|
936
|
+
) -> None:
|
|
937
|
+
if (
|
|
938
|
+
payload.get("checkpoint_license") != "NOASSERTION"
|
|
939
|
+
or payload.get("checkpoint_license_acknowledged") is not True
|
|
940
|
+
):
|
|
941
|
+
raise AlgorithmOutputError("RECOMP checkpoint license acknowledgement was not attested")
|
|
942
|
+
if payload.get("remaining_budget_hash") != content_hash(remaining_budget):
|
|
943
|
+
raise AlgorithmOutputError("RECOMP worker budget binding mismatch")
|
|
944
|
+
input_required = nonnegative_integer(
|
|
945
|
+
payload.get("input_tokens_required"), label="RECOMP input_tokens_required"
|
|
946
|
+
)
|
|
947
|
+
output_required = nonnegative_integer(
|
|
948
|
+
payload.get("output_tokens_required"), label="RECOMP output_tokens_required"
|
|
949
|
+
)
|
|
950
|
+
context_cap = remaining_budget["context_tokens"]
|
|
951
|
+
if context_cap is not None and input_required > context_cap:
|
|
952
|
+
raise AlgorithmOutputError("RECOMP preflight exceeded the sent context-token budget")
|
|
953
|
+
if output_required > remaining_budget["output_tokens"]: # type: ignore[operator]
|
|
954
|
+
raise AlgorithmOutputError("RECOMP preflight exceeded the sent output-token budget")
|
|
955
|
+
runtime = payload.get("runtime_fingerprint")
|
|
956
|
+
if not isinstance(runtime, Mapping) or not runtime:
|
|
957
|
+
raise AlgorithmOutputError("RECOMP response omits runtime fingerprint")
|
|
958
|
+
runtime_hash = required_text(payload, "runtime_fingerprint_hash", label="RECOMP response")
|
|
959
|
+
if runtime_hash != content_hash(runtime):
|
|
960
|
+
raise AlgorithmOutputError("RECOMP runtime fingerprint hash mismatch")
|
|
961
|
+
required_keys = {
|
|
962
|
+
"device",
|
|
963
|
+
"python_version",
|
|
964
|
+
"python_implementation",
|
|
965
|
+
"dependency_versions",
|
|
966
|
+
"container_digest",
|
|
967
|
+
"custom_model_loader",
|
|
968
|
+
}
|
|
969
|
+
if set(runtime) != required_keys or not isinstance(runtime.get("dependency_versions"), Mapping):
|
|
970
|
+
raise AlgorithmOutputError("RECOMP runtime fingerprint schema mismatch")
|
|
971
|
+
for key in ("checkpoint_tree_sha256", "preflight_token"):
|
|
972
|
+
if not _HEX64.fullmatch(required_text(payload, key, label="RECOMP response")):
|
|
973
|
+
raise AlgorithmOutputError(f"RECOMP {key} must be a SHA-256 digest")
|
|
974
|
+
nonnegative_integer(payload.get("checkpoint_file_count"), label="RECOMP checkpoint_file_count")
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
def _validate_asset_identity(
|
|
978
|
+
*, checkpoint_revision: str, tokenizer_revision: str, asset_manifest_hash: str
|
|
979
|
+
) -> None:
|
|
980
|
+
for label, value in (
|
|
981
|
+
("checkpoint_revision", checkpoint_revision),
|
|
982
|
+
("tokenizer_revision", tokenizer_revision),
|
|
983
|
+
("asset_manifest_hash", asset_manifest_hash),
|
|
984
|
+
):
|
|
985
|
+
if not isinstance(value, str) or not value.strip():
|
|
986
|
+
raise ValidationError(f"RECOMP {label} must not be empty")
|
|
987
|
+
if not _HEX64.fullmatch(asset_manifest_hash):
|
|
988
|
+
raise ValidationError("RECOMP asset_manifest_hash must be a SHA-256 digest")
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
def _require_asset_acknowledgement(acknowledged: bool) -> None:
|
|
992
|
+
if not acknowledged:
|
|
993
|
+
raise ExternalDependencyError(
|
|
994
|
+
"RECOMP model artifacts are NOASSERTION; explicitly acknowledge the "
|
|
995
|
+
"user-mounted asset license before execution"
|
|
996
|
+
)
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
def _validate_worker_attestation(
|
|
1000
|
+
payload: Mapping[str, Any], worker_identity: Mapping[str, Any]
|
|
1001
|
+
) -> None:
|
|
1002
|
+
for key in ("compatibility_manifest_sha256", "execution_evidence"):
|
|
1003
|
+
expected = worker_identity.get(key)
|
|
1004
|
+
if not isinstance(expected, str) or not expected:
|
|
1005
|
+
raise ValidationError(f"RECOMP worker fingerprint omits {key}")
|
|
1006
|
+
if payload.get(key) != expected:
|
|
1007
|
+
raise AlgorithmOutputError(f"RECOMP worker {key} attestation mismatch")
|
|
1008
|
+
expected_runtime = worker_identity.get("runtime_fingerprint_hash")
|
|
1009
|
+
if expected_runtime is not None:
|
|
1010
|
+
if not isinstance(expected_runtime, str) or not _HEX64.fullmatch(expected_runtime):
|
|
1011
|
+
raise ValidationError("RECOMP worker fingerprint runtime hash is invalid")
|
|
1012
|
+
if payload.get("runtime_fingerprint_hash") != expected_runtime:
|
|
1013
|
+
raise AlgorithmOutputError("RECOMP worker runtime fingerprint attestation mismatch")
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
def _document_ids(state: FrozenAgentState) -> tuple[str, ...]:
|
|
1017
|
+
if not state.context:
|
|
1018
|
+
raise ValidationError("RECOMP requires already-retrieved context")
|
|
1019
|
+
values = tuple(block.block_id for block in state.context)
|
|
1020
|
+
if any(not value for value in values) or len(values) != len(set(values)):
|
|
1021
|
+
raise ValidationError("RECOMP documents require unique non-empty block IDs")
|
|
1022
|
+
return values
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
def _validate_response_identity(
|
|
1026
|
+
payload: Mapping[str, Any],
|
|
1027
|
+
*,
|
|
1028
|
+
checkpoint_revision: str,
|
|
1029
|
+
tokenizer_revision: str,
|
|
1030
|
+
asset_manifest_hash: str,
|
|
1031
|
+
document_ids: tuple[str, ...],
|
|
1032
|
+
retriever_artifact_hash: str,
|
|
1033
|
+
input_artifact_hash: str,
|
|
1034
|
+
) -> None:
|
|
1035
|
+
for key, expected in (
|
|
1036
|
+
("checkpoint_revision", checkpoint_revision),
|
|
1037
|
+
("tokenizer_revision", tokenizer_revision),
|
|
1038
|
+
("asset_manifest_hash", asset_manifest_hash),
|
|
1039
|
+
):
|
|
1040
|
+
if required_text(payload, key, label="RECOMP response") != expected:
|
|
1041
|
+
raise AlgorithmOutputError(f"RECOMP {key} mismatch")
|
|
1042
|
+
returned_ids = string_tuple(
|
|
1043
|
+
payload.get("source_document_ids"),
|
|
1044
|
+
label="RECOMP source_document_ids",
|
|
1045
|
+
allow_empty=False,
|
|
1046
|
+
unique=True,
|
|
1047
|
+
)
|
|
1048
|
+
if returned_ids != document_ids:
|
|
1049
|
+
raise AlgorithmOutputError("RECOMP worker changed source document order")
|
|
1050
|
+
for key, expected in (
|
|
1051
|
+
("retriever_artifact_hash", retriever_artifact_hash),
|
|
1052
|
+
("input_artifact_hash", input_artifact_hash),
|
|
1053
|
+
):
|
|
1054
|
+
if required_text(payload, key, label="RECOMP response") != expected:
|
|
1055
|
+
raise AlgorithmOutputError(f"RECOMP {key} mismatch")
|
|
1056
|
+
for key in ("compatibility_manifest_sha256",):
|
|
1057
|
+
if not _HEX64.fullmatch(required_text(payload, key, label="RECOMP response")):
|
|
1058
|
+
raise AlgorithmOutputError(f"RECOMP {key} must be a SHA-256 digest")
|
|
1059
|
+
if required_text(payload, "execution_evidence", label="RECOMP response") not in {
|
|
1060
|
+
"pinned_upstream_source",
|
|
1061
|
+
"fake_checkout_plumbing",
|
|
1062
|
+
}:
|
|
1063
|
+
raise AlgorithmOutputError("RECOMP execution evidence is invalid")
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
def _parse_sentence_scores(raw: Any, state: FrozenAgentState) -> tuple[RECOMPSentenceScore, ...]:
|
|
1067
|
+
rows = mapping_sequence(raw, label="RECOMP sentence_scores")
|
|
1068
|
+
if len(rows) != len(state.context):
|
|
1069
|
+
raise AlgorithmOutputError("RECOMP score count must match fixed candidate sentences")
|
|
1070
|
+
result: list[RECOMPSentenceScore] = []
|
|
1071
|
+
for row_index, (row, source) in enumerate(zip(rows, state.context, strict=True)):
|
|
1072
|
+
label = f"RECOMP sentence score {row_index}"
|
|
1073
|
+
sentence_id = required_text(row, "sentence_id", label=label)
|
|
1074
|
+
document_id = required_text(row, "document_id", label=label)
|
|
1075
|
+
index = nonnegative_integer(row.get("document_index"), label=f"{label} document_index")
|
|
1076
|
+
if sentence_id != source.block_id or document_id != source.block_id or index != row_index:
|
|
1077
|
+
raise AlgorithmOutputError("RECOMP fixed candidate ID/order mismatch")
|
|
1078
|
+
sentence_index = nonnegative_integer(
|
|
1079
|
+
row.get("sentence_index"), label=f"{label} sentence_index"
|
|
1080
|
+
)
|
|
1081
|
+
char_start = nonnegative_integer(row.get("char_start"), label=f"{label} char_start")
|
|
1082
|
+
char_end = nonnegative_integer(row.get("char_end"), label=f"{label} char_end")
|
|
1083
|
+
text = required_text(row, "text", label=label)
|
|
1084
|
+
if sentence_index != 0 or char_start != 0 or char_end != len(source.text):
|
|
1085
|
+
raise AlgorithmOutputError("RECOMP fixed candidate offsets changed")
|
|
1086
|
+
if text != source.text:
|
|
1087
|
+
raise AlgorithmOutputError("RECOMP fixed candidate text changed")
|
|
1088
|
+
result.append(
|
|
1089
|
+
RECOMPSentenceScore(
|
|
1090
|
+
sentence_id=sentence_id,
|
|
1091
|
+
document_id=document_id,
|
|
1092
|
+
document_index=index,
|
|
1093
|
+
sentence_index=sentence_index,
|
|
1094
|
+
char_start=char_start,
|
|
1095
|
+
char_end=char_end,
|
|
1096
|
+
text=text,
|
|
1097
|
+
score=finite_number(row.get("score"), label=f"{label} score"),
|
|
1098
|
+
)
|
|
1099
|
+
)
|
|
1100
|
+
return tuple(result)
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
def _select_sentences(
|
|
1104
|
+
scores: tuple[RECOMPSentenceScore, ...], controls: RECOMPExtractiveControls
|
|
1105
|
+
) -> tuple[RECOMPSentenceScore, ...]:
|
|
1106
|
+
eligible = tuple(
|
|
1107
|
+
item
|
|
1108
|
+
for item in scores
|
|
1109
|
+
if controls.minimum_score is None or item.score >= controls.minimum_score
|
|
1110
|
+
)
|
|
1111
|
+
ranked = sorted(eligible, key=lambda item: (-item.score, item.source_order))
|
|
1112
|
+
if controls.max_sentences != -1:
|
|
1113
|
+
ranked = ranked[: controls.max_sentences]
|
|
1114
|
+
if controls.output_order == "source_order":
|
|
1115
|
+
ranked.sort(key=lambda item: item.source_order)
|
|
1116
|
+
return tuple(ranked)
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
__all__ = [
|
|
1120
|
+
"RECOMP_ABSTRACTIVE_INPUT_TEMPLATE",
|
|
1121
|
+
"RECOMP_ABSTRACTIVE_INPUT_TEMPLATE_SHA256",
|
|
1122
|
+
"RECOMP_CANDIDATE_UNIT_KIND",
|
|
1123
|
+
"RECOMP_UPSTREAM_COMMIT",
|
|
1124
|
+
"RECOMPAbstractiveControls",
|
|
1125
|
+
"RECOMPAbstractiveExternal",
|
|
1126
|
+
"RECOMPExtractiveControls",
|
|
1127
|
+
"RECOMPExtractiveExternal",
|
|
1128
|
+
"RECOMPSentenceScore",
|
|
1129
|
+
]
|