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,711 @@
|
|
|
1
|
+
"""Explicitly transductive, source-pinned ACE online execution.
|
|
2
|
+
|
|
3
|
+
The unchanged native online loop evaluates a window before updating on its
|
|
4
|
+
feedback. Initial evaluation, adaptation and post-update generations all count.
|
|
5
|
+
This is not an offline or held-out evaluation protocol.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import contextlib
|
|
11
|
+
import functools
|
|
12
|
+
import hashlib
|
|
13
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
import random
|
|
16
|
+
import sys
|
|
17
|
+
import threading
|
|
18
|
+
import time
|
|
19
|
+
from collections.abc import Mapping, Sequence
|
|
20
|
+
from dataclasses import asdict, dataclass
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from types import SimpleNamespace
|
|
23
|
+
|
|
24
|
+
from agentinputlab.contracts import ValidationError
|
|
25
|
+
from agentinputlab.contracts.serialization import content_hash, to_jsonable
|
|
26
|
+
|
|
27
|
+
from .ace import ACEExample
|
|
28
|
+
|
|
29
|
+
RELEASE = "recipe.ace.online_transductive"
|
|
30
|
+
PROTOCOL = "agentinputlab.ace.native-online.v1"
|
|
31
|
+
_LOCK = threading.RLock()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _save(path, value):
|
|
35
|
+
with path.open("x", encoding="utf-8") as stream:
|
|
36
|
+
json.dump(value, stream, indent=2, sort_keys=True, allow_nan=False)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _sha(path):
|
|
40
|
+
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass(frozen=True, slots=True)
|
|
44
|
+
class ACEOnlineControls:
|
|
45
|
+
max_rounds: int = 1
|
|
46
|
+
per_case_model_calls: int = 8
|
|
47
|
+
per_case_output_tokens: int = 4096
|
|
48
|
+
per_call_output_tokens: int = 512
|
|
49
|
+
window_size: int = 1
|
|
50
|
+
max_stream_examples: int = 128
|
|
51
|
+
playbook_token_budget: int = 4096
|
|
52
|
+
timeout_seconds: int = 3600
|
|
53
|
+
seed: int = 17
|
|
54
|
+
|
|
55
|
+
def __post_init__(self):
|
|
56
|
+
for name, value in asdict(self).items():
|
|
57
|
+
if type(value) is not int or value < (0 if name == "seed" else 1):
|
|
58
|
+
raise ValidationError(f"ACE online {name} must be an integer in range")
|
|
59
|
+
if self.per_call_output_tokens > self.per_case_output_tokens:
|
|
60
|
+
raise ValidationError("ACE online per-call cap must fit its shared case budget")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def audit_online_stream(examples, controls):
|
|
64
|
+
if not isinstance(examples, Sequence) or isinstance(examples, (str, bytes)):
|
|
65
|
+
raise ValidationError("ACE online needs an ordered example sequence")
|
|
66
|
+
rows = tuple(ACEExample.from_value(row, split="test") for row in examples)
|
|
67
|
+
if not rows or len(rows) > controls.max_stream_examples or controls.window_size > len(rows):
|
|
68
|
+
raise ValidationError("ACE online stream size or window exceeds its explicit bound")
|
|
69
|
+
if any(row.expected_output is None for row in rows):
|
|
70
|
+
raise ValidationError("ACE online requires explicitly acknowledged feedback labels")
|
|
71
|
+
if len({row.example_id for row in rows}) != len(rows):
|
|
72
|
+
raise ValidationError("ACE online stream IDs must be unique")
|
|
73
|
+
from workers.ace.driver import adapt_example
|
|
74
|
+
|
|
75
|
+
adapted = tuple(adapt_example(row.as_dict()) for row in rows)
|
|
76
|
+
# Summarization/code tasks can repeat a question for different documents.
|
|
77
|
+
# Native sample callbacks expose both original fields; neither field needs
|
|
78
|
+
# rewriting just to attribute usage to its stable source example.
|
|
79
|
+
if len({(row["question"], row["context"]) for row in adapted}) != len(rows):
|
|
80
|
+
raise ValidationError(
|
|
81
|
+
"ACE online callback attribution requires unique question/context inputs"
|
|
82
|
+
)
|
|
83
|
+
return rows, adapted
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class _Journal:
|
|
87
|
+
def __init__(self, root):
|
|
88
|
+
self.stream = (root / "events.jsonl").open("x", encoding="utf-8")
|
|
89
|
+
self.previous = "0" * 64
|
|
90
|
+
self.count = 0
|
|
91
|
+
self.lock = threading.RLock()
|
|
92
|
+
|
|
93
|
+
def event(self, kind, **data):
|
|
94
|
+
with self.lock:
|
|
95
|
+
row = dict(index=self.count, previous_sha256=self.previous, kind=kind, **data)
|
|
96
|
+
digest = content_hash(row)
|
|
97
|
+
self.stream.write(
|
|
98
|
+
json.dumps({**row, "sha256": digest}, sort_keys=True, allow_nan=False) + "\n"
|
|
99
|
+
)
|
|
100
|
+
self.stream.flush()
|
|
101
|
+
self.previous, self.count = digest, self.count + 1
|
|
102
|
+
|
|
103
|
+
def close(self):
|
|
104
|
+
self.stream.close()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _tracker_type():
|
|
108
|
+
from workers.ace.driver import UsageTracker, WorkerFailure
|
|
109
|
+
|
|
110
|
+
class OnlineTracker(UsageTracker):
|
|
111
|
+
def __init__(self, controls, config, online, ids, journal):
|
|
112
|
+
super().__init__(controls, config)
|
|
113
|
+
self.online, self.journal = online, journal
|
|
114
|
+
self._lock, self.local = threading.RLock(), threading.local()
|
|
115
|
+
self.started = time.monotonic()
|
|
116
|
+
self.phase = "initial_evaluation"
|
|
117
|
+
self.input_to_id = {
|
|
118
|
+
(key if isinstance(key, tuple) else (key, "")): value for key, value in ids.items()
|
|
119
|
+
}
|
|
120
|
+
self.question_to_ids = {}
|
|
121
|
+
for (question, _), case in self.input_to_id.items():
|
|
122
|
+
self.question_to_ids.setdefault(question, set()).add(case)
|
|
123
|
+
# Budget keys remain stable source IDs, including repeated queries.
|
|
124
|
+
self.by_case = {
|
|
125
|
+
key: dict(
|
|
126
|
+
model_calls=0, input_tokens=0, output_tokens=0, provider_usage_responses=0
|
|
127
|
+
)
|
|
128
|
+
for key in ids.values()
|
|
129
|
+
}
|
|
130
|
+
self.budget_rejections = []
|
|
131
|
+
|
|
132
|
+
def select(self, question, context=None):
|
|
133
|
+
candidates = self.question_to_ids.get(question, set())
|
|
134
|
+
if context is not None:
|
|
135
|
+
case = self.input_to_id.get((question, context))
|
|
136
|
+
elif len(candidates) == 1:
|
|
137
|
+
case = next(iter(candidates))
|
|
138
|
+
else:
|
|
139
|
+
# Component callbacks inside an already selected native sample
|
|
140
|
+
# may expose only question; never guess between distinct inputs.
|
|
141
|
+
case = getattr(self.local, "case_id", None)
|
|
142
|
+
if case not in candidates:
|
|
143
|
+
case = None
|
|
144
|
+
if case is None:
|
|
145
|
+
raise WorkerFailure(
|
|
146
|
+
"EXAMPLE_ATTRIBUTION_FAILED",
|
|
147
|
+
"native ACE question/context differs from the frozen stream or is ambiguous",
|
|
148
|
+
)
|
|
149
|
+
self.local.case_id = case
|
|
150
|
+
|
|
151
|
+
def case_for(self, item):
|
|
152
|
+
key = (item["question"], item.get("context", ""))
|
|
153
|
+
if key not in self.input_to_id:
|
|
154
|
+
raise WorkerFailure(
|
|
155
|
+
"EXAMPLE_ATTRIBUTION_FAILED", "native sample differs from frozen stream"
|
|
156
|
+
)
|
|
157
|
+
return self.input_to_id[key]
|
|
158
|
+
|
|
159
|
+
def _wrap(self, component, method_name, role):
|
|
160
|
+
original = getattr(component, method_name)
|
|
161
|
+
|
|
162
|
+
@functools.wraps(original)
|
|
163
|
+
def observed(*args, **kwargs):
|
|
164
|
+
if "question" in kwargs:
|
|
165
|
+
self.select(kwargs["question"])
|
|
166
|
+
return base(*args, **kwargs)
|
|
167
|
+
|
|
168
|
+
super()._wrap(component, method_name, role)
|
|
169
|
+
base = getattr(component, method_name)
|
|
170
|
+
setattr(component, method_name, observed)
|
|
171
|
+
|
|
172
|
+
def before_provider_attempt(self, role):
|
|
173
|
+
with self._lock:
|
|
174
|
+
case = getattr(self.local, "case_id", None)
|
|
175
|
+
if case not in self.by_case:
|
|
176
|
+
raise WorkerFailure(
|
|
177
|
+
"EXAMPLE_ATTRIBUTION_FAILED", "provider attempt has no source example"
|
|
178
|
+
)
|
|
179
|
+
usage = self.by_case[case]
|
|
180
|
+
if (
|
|
181
|
+
usage["model_calls"] >= self.online.per_case_model_calls
|
|
182
|
+
or usage["output_tokens"] + self.online.per_call_output_tokens
|
|
183
|
+
> self.online.per_case_output_tokens
|
|
184
|
+
or time.monotonic() - self.started >= self.online.timeout_seconds
|
|
185
|
+
):
|
|
186
|
+
self.budget_rejections.append(dict(case_id=case, role=role, phase=self.phase))
|
|
187
|
+
raise WorkerFailure(
|
|
188
|
+
"ONLINE_BUDGET_EXHAUSTED",
|
|
189
|
+
"ACE online shared case budget exhausted before dispatch",
|
|
190
|
+
)
|
|
191
|
+
super().before_provider_attempt(role)
|
|
192
|
+
usage["model_calls"] += 1
|
|
193
|
+
self.journal.event(
|
|
194
|
+
"provider_attempt",
|
|
195
|
+
case_id=case,
|
|
196
|
+
role=role,
|
|
197
|
+
phase=self.phase,
|
|
198
|
+
per_case_attempt=usage["model_calls"],
|
|
199
|
+
seed=self.online.seed,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
def after_provider_response(self, role, response):
|
|
203
|
+
usage = (
|
|
204
|
+
response.get("usage")
|
|
205
|
+
if isinstance(response, Mapping)
|
|
206
|
+
else getattr(response, "usage", None)
|
|
207
|
+
)
|
|
208
|
+
if usage is None:
|
|
209
|
+
raise WorkerFailure(
|
|
210
|
+
"UPSTREAM_USAGE_UNAVAILABLE", "online provider omitted actual usage"
|
|
211
|
+
)
|
|
212
|
+
getter = (
|
|
213
|
+
usage.get if isinstance(usage, Mapping) else lambda key: getattr(usage, key, None)
|
|
214
|
+
)
|
|
215
|
+
incoming, outgoing = getter("prompt_tokens"), getter("completion_tokens")
|
|
216
|
+
if (
|
|
217
|
+
type(incoming) is not int
|
|
218
|
+
or incoming < 0
|
|
219
|
+
or type(outgoing) is not int
|
|
220
|
+
or outgoing < 0
|
|
221
|
+
):
|
|
222
|
+
raise WorkerFailure(
|
|
223
|
+
"UPSTREAM_USAGE_UNAVAILABLE", "online provider usage is invalid"
|
|
224
|
+
)
|
|
225
|
+
with self._lock:
|
|
226
|
+
row = self.by_case[self.local.case_id]
|
|
227
|
+
row["input_tokens"] += incoming
|
|
228
|
+
row["output_tokens"] += outgoing
|
|
229
|
+
row["provider_usage_responses"] += 1
|
|
230
|
+
super().after_provider_response(role, response)
|
|
231
|
+
if (
|
|
232
|
+
outgoing > self.online.per_call_output_tokens
|
|
233
|
+
or row["output_tokens"] > self.online.per_case_output_tokens
|
|
234
|
+
):
|
|
235
|
+
raise WorkerFailure(
|
|
236
|
+
"PROVIDER_BUDGET_BREACH", "online provider exceeded the declared output cap"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
return OnlineTracker
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class _RecordingCompletions:
|
|
243
|
+
def __init__(self, delegate, tracker, role, calls):
|
|
244
|
+
self.delegate, self.tracker, self.role, self.calls = delegate, tracker, role, calls
|
|
245
|
+
|
|
246
|
+
def create(self, *args, **kwargs):
|
|
247
|
+
if args:
|
|
248
|
+
raise ValidationError("native ACE completion must use named arguments")
|
|
249
|
+
if "seed" in kwargs and kwargs["seed"] != self.tracker.online.seed:
|
|
250
|
+
raise ValidationError("native ACE supplied a different provider seed")
|
|
251
|
+
kwargs = dict(kwargs, seed=self.tracker.online.seed)
|
|
252
|
+
row = dict(
|
|
253
|
+
case_id=self.tracker.local.case_id,
|
|
254
|
+
role=self.role,
|
|
255
|
+
phase=self.tracker.phase,
|
|
256
|
+
request=to_jsonable(kwargs),
|
|
257
|
+
started=time.time(),
|
|
258
|
+
)
|
|
259
|
+
self.calls.append(row)
|
|
260
|
+
try:
|
|
261
|
+
response = self.delegate.create(**kwargs)
|
|
262
|
+
row["response"] = (
|
|
263
|
+
response.model_dump(mode="json")
|
|
264
|
+
if callable(getattr(response, "model_dump", None))
|
|
265
|
+
else to_jsonable(response)
|
|
266
|
+
)
|
|
267
|
+
return response
|
|
268
|
+
except Exception as exc:
|
|
269
|
+
row["error_type"] = type(exc).__name__
|
|
270
|
+
raise
|
|
271
|
+
finally:
|
|
272
|
+
row["wall_seconds"] = time.time() - row["started"]
|
|
273
|
+
self.tracker.journal.event("provider_return", call=row)
|
|
274
|
+
|
|
275
|
+
def __getattr__(self, name):
|
|
276
|
+
return getattr(self.delegate, name)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
class _RecordingClient:
|
|
280
|
+
def __init__(self, delegate, tracker, role, calls):
|
|
281
|
+
self.delegate = delegate
|
|
282
|
+
self.chat = SimpleNamespace(
|
|
283
|
+
completions=_RecordingCompletions(delegate.chat.completions, tracker, role, calls)
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
def __getattr__(self, name):
|
|
287
|
+
return getattr(self.delegate, name)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
@dataclass(frozen=True, slots=True)
|
|
291
|
+
class ACEOnlineResult:
|
|
292
|
+
root: Path
|
|
293
|
+
artifact_id: str
|
|
294
|
+
terminal: Mapping
|
|
295
|
+
|
|
296
|
+
@classmethod
|
|
297
|
+
def load(cls, root):
|
|
298
|
+
folder = Path(root).expanduser()
|
|
299
|
+
if folder.is_symlink() or not folder.is_dir():
|
|
300
|
+
raise ValidationError("ACE online result requires a regular run directory")
|
|
301
|
+
names = (
|
|
302
|
+
"plan.json",
|
|
303
|
+
"terminal.json",
|
|
304
|
+
"provider-calls.json",
|
|
305
|
+
"events.jsonl",
|
|
306
|
+
"final-playbook.txt",
|
|
307
|
+
"native-files.json",
|
|
308
|
+
"manifest.json",
|
|
309
|
+
)
|
|
310
|
+
if any((folder / name).is_symlink() or not (folder / name).is_file() for name in names):
|
|
311
|
+
raise ValidationError("ACE online result closure is incomplete")
|
|
312
|
+
metadata = json.loads((folder / "manifest.json").read_text())
|
|
313
|
+
identity = metadata.pop("artifact_id", None)
|
|
314
|
+
if identity != content_hash(metadata) or metadata.get("protocol") != PROTOCOL:
|
|
315
|
+
raise ValidationError("ACE online result identity differs")
|
|
316
|
+
if set(metadata.get("files", {})) != set(names) - {"manifest.json"} or any(
|
|
317
|
+
_sha(folder / name) != sha for name, sha in metadata["files"].items()
|
|
318
|
+
):
|
|
319
|
+
raise ValidationError("ACE online result file hashes differ")
|
|
320
|
+
previous = "0" * 64
|
|
321
|
+
for index, line in enumerate((folder / "events.jsonl").read_text().splitlines()):
|
|
322
|
+
row = json.loads(line)
|
|
323
|
+
digest = row.pop("sha256")
|
|
324
|
+
if (
|
|
325
|
+
row["index"] != index
|
|
326
|
+
or row["previous_sha256"] != previous
|
|
327
|
+
or content_hash(row) != digest
|
|
328
|
+
):
|
|
329
|
+
raise ValidationError("ACE online event chain is invalid")
|
|
330
|
+
previous = digest
|
|
331
|
+
terminal = json.loads((folder / "terminal.json").read_text())
|
|
332
|
+
if (
|
|
333
|
+
terminal.get("protocol") != PROTOCOL
|
|
334
|
+
or terminal.get("event_chain_final_sha256") != previous
|
|
335
|
+
):
|
|
336
|
+
raise ValidationError("ACE online terminal event binding differs")
|
|
337
|
+
native_files = json.loads((folder / "native-files.json").read_text())
|
|
338
|
+
from pathlib import PurePosixPath
|
|
339
|
+
|
|
340
|
+
for name, digest in native_files.items():
|
|
341
|
+
path = PurePosixPath(name)
|
|
342
|
+
target = folder / name
|
|
343
|
+
if (
|
|
344
|
+
path.is_absolute()
|
|
345
|
+
or ".." in path.parts
|
|
346
|
+
or str(path) != name
|
|
347
|
+
or target.is_symlink()
|
|
348
|
+
or not target.is_file()
|
|
349
|
+
or not target.resolve().is_relative_to(folder.resolve())
|
|
350
|
+
or _sha(target) != digest
|
|
351
|
+
):
|
|
352
|
+
raise ValidationError("ACE native output closure differs")
|
|
353
|
+
return cls(folder.resolve(), identity, terminal)
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
class ACEOnlineRecipe:
|
|
357
|
+
release_id = RELEASE
|
|
358
|
+
|
|
359
|
+
def __init__(self, controls=None):
|
|
360
|
+
self.controls = (
|
|
361
|
+
ACEOnlineControls(**controls)
|
|
362
|
+
if isinstance(controls, Mapping)
|
|
363
|
+
else controls or ACEOnlineControls()
|
|
364
|
+
)
|
|
365
|
+
if not isinstance(self.controls, ACEOnlineControls):
|
|
366
|
+
raise ValidationError("ACE online requires typed controls")
|
|
367
|
+
|
|
368
|
+
def run_stream(
|
|
369
|
+
self,
|
|
370
|
+
examples,
|
|
371
|
+
*,
|
|
372
|
+
checkout,
|
|
373
|
+
llm_config,
|
|
374
|
+
output_root,
|
|
375
|
+
allow_test_feedback=False,
|
|
376
|
+
source_and_asset_acknowledged=False,
|
|
377
|
+
data_processor=None,
|
|
378
|
+
):
|
|
379
|
+
if allow_test_feedback is not True or source_and_asset_acknowledged is not True:
|
|
380
|
+
raise ValidationError(
|
|
381
|
+
"ACE online requires explicit transductive feedback and source acknowledgement"
|
|
382
|
+
)
|
|
383
|
+
from workers.ace.driver import (
|
|
384
|
+
ACEWorkerRuntime,
|
|
385
|
+
BoundedHashSink,
|
|
386
|
+
Controls,
|
|
387
|
+
GenericTextProcessor,
|
|
388
|
+
LLMConfig,
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
c = self.controls
|
|
392
|
+
rows, adapted = audit_online_stream(examples, c)
|
|
393
|
+
task_fingerprint = None
|
|
394
|
+
if data_processor is not None:
|
|
395
|
+
for name in (
|
|
396
|
+
"answer_is_correct",
|
|
397
|
+
"evaluate_accuracy",
|
|
398
|
+
"fingerprint",
|
|
399
|
+
"validate_online_examples",
|
|
400
|
+
):
|
|
401
|
+
if not callable(getattr(data_processor, name, None)):
|
|
402
|
+
raise ValidationError(f"ACE online task processor lacks {name}()")
|
|
403
|
+
value = data_processor.fingerprint()
|
|
404
|
+
if not isinstance(value, Mapping) or not value:
|
|
405
|
+
raise ValidationError(
|
|
406
|
+
"ACE online task processor fingerprint must be a nonempty object"
|
|
407
|
+
)
|
|
408
|
+
task_fingerprint = to_jsonable(value)
|
|
409
|
+
data_processor.validate_online_examples(tuple(row.as_dict() for row in rows))
|
|
410
|
+
if not isinstance(llm_config, Mapping):
|
|
411
|
+
raise ValidationError("ACE online needs an explicit data-only LLM deployment mapping")
|
|
412
|
+
config = LLMConfig.from_json(json.dumps(to_jsonable(llm_config), allow_nan=False))
|
|
413
|
+
if config.max_tokens_per_call != c.per_call_output_tokens or config.base_url is None:
|
|
414
|
+
raise ValidationError(
|
|
415
|
+
"ACE online requires an explicit no-retry OpenAI-compatible deployment and matching cap"
|
|
416
|
+
)
|
|
417
|
+
root = Path(output_root).expanduser()
|
|
418
|
+
if root.exists() or root.is_symlink():
|
|
419
|
+
raise ValidationError(
|
|
420
|
+
"ACE online output must be create-only; consumed streams are not retried"
|
|
421
|
+
)
|
|
422
|
+
root = root.absolute()
|
|
423
|
+
root.mkdir(parents=True)
|
|
424
|
+
controls = Controls(
|
|
425
|
+
max_rounds=c.max_rounds,
|
|
426
|
+
max_model_calls=c.per_case_model_calls * len(rows),
|
|
427
|
+
max_tokens=2_000_000_000,
|
|
428
|
+
max_cost_usd=1e12,
|
|
429
|
+
seed=c.seed,
|
|
430
|
+
)
|
|
431
|
+
plan = dict(
|
|
432
|
+
protocol=PROTOCOL,
|
|
433
|
+
release_id=RELEASE,
|
|
434
|
+
controls=asdict(c),
|
|
435
|
+
stream=[row.as_dict() for row in rows],
|
|
436
|
+
deployment=to_jsonable(llm_config),
|
|
437
|
+
transductive_not_offline_or_heldout=True,
|
|
438
|
+
order_preserved=True,
|
|
439
|
+
initial_evaluation_and_all_adaptation_costs_in_shared_case_budget=True,
|
|
440
|
+
generated_artifact_must_not_be_reused_as_offline_heldout_evidence=True,
|
|
441
|
+
automatic_retry=False,
|
|
442
|
+
)
|
|
443
|
+
if task_fingerprint is not None:
|
|
444
|
+
plan["native_task_processor"] = task_fingerprint
|
|
445
|
+
_save(root / "plan.json", plan)
|
|
446
|
+
journal = _Journal(root)
|
|
447
|
+
calls, predictions, windows, updates = [], [], [], []
|
|
448
|
+
tracker = runtime = ace_system = None
|
|
449
|
+
started, cpu = time.monotonic(), time.process_time()
|
|
450
|
+
error = None
|
|
451
|
+
diagnostics = BoundedHashSink()
|
|
452
|
+
try:
|
|
453
|
+
with _LOCK:
|
|
454
|
+
runtime = (
|
|
455
|
+
ACEWorkerRuntime(Path(checkout), config, data_processor=data_processor)
|
|
456
|
+
if data_processor is not None
|
|
457
|
+
else ACEWorkerRuntime(Path(checkout), config)
|
|
458
|
+
)
|
|
459
|
+
roles = config.roles
|
|
460
|
+
if not os.environ.get(config.api_key_env, ""):
|
|
461
|
+
raise ValidationError(
|
|
462
|
+
"ACE online configured API-key environment variable is unset"
|
|
463
|
+
)
|
|
464
|
+
bootstrap = "OPENAI_API_KEY" not in os.environ
|
|
465
|
+
if bootstrap:
|
|
466
|
+
# Native construction creates clients but performs no API
|
|
467
|
+
# call; immediately bind the caller's actual deployment.
|
|
468
|
+
os.environ["OPENAI_API_KEY"] = "native-constructor-bootstrap-not-a-secret"
|
|
469
|
+
with contextlib.redirect_stdout(diagnostics):
|
|
470
|
+
try:
|
|
471
|
+
ace_system = runtime.ace_class(
|
|
472
|
+
api_provider=config.api_provider,
|
|
473
|
+
generator_model=roles["target"].model,
|
|
474
|
+
reflector_model=roles["reflector"].model,
|
|
475
|
+
curator_model=roles["curator"].model,
|
|
476
|
+
max_tokens=c.per_call_output_tokens,
|
|
477
|
+
use_bulletpoint_analyzer=False,
|
|
478
|
+
)
|
|
479
|
+
runtime._bind_openai_compatible_clients(ace_system, seed=c.seed)
|
|
480
|
+
finally:
|
|
481
|
+
if bootstrap:
|
|
482
|
+
os.environ.pop("OPENAI_API_KEY", None)
|
|
483
|
+
tracker = _tracker_type()(
|
|
484
|
+
controls,
|
|
485
|
+
config,
|
|
486
|
+
c,
|
|
487
|
+
{
|
|
488
|
+
(row["question"], row["context"]): item.example_id
|
|
489
|
+
for item, row in zip(rows, adapted, strict=True)
|
|
490
|
+
},
|
|
491
|
+
journal,
|
|
492
|
+
)
|
|
493
|
+
for role, component in (
|
|
494
|
+
("target", ace_system.generator),
|
|
495
|
+
("reflector", ace_system.reflector),
|
|
496
|
+
("curator", ace_system.curator),
|
|
497
|
+
):
|
|
498
|
+
component.api_client = _RecordingClient(
|
|
499
|
+
component.api_client, tracker, role, calls
|
|
500
|
+
)
|
|
501
|
+
tracker.install(ace_system)
|
|
502
|
+
ace_module = sys.modules[runtime.ace_class.__module__]
|
|
503
|
+
utils = sys.modules["utils"]
|
|
504
|
+
native_eval, native_sample = (
|
|
505
|
+
ace_module.evaluate_test_set,
|
|
506
|
+
utils.evaluate_single_test_sample,
|
|
507
|
+
)
|
|
508
|
+
native_train = ace_system._train_single_sample
|
|
509
|
+
native_initial = ace_system._run_test
|
|
510
|
+
evaluations = 0
|
|
511
|
+
|
|
512
|
+
def observed_sample(args_tuple, data_processor):
|
|
513
|
+
if (
|
|
514
|
+
task_fingerprint is not None
|
|
515
|
+
and to_jsonable(data_processor.fingerprint()) != task_fingerprint
|
|
516
|
+
):
|
|
517
|
+
raise ValidationError("ACE online task processor fingerprint changed")
|
|
518
|
+
item = args_tuple[1]
|
|
519
|
+
tracker.select(item["question"], item.get("context", ""))
|
|
520
|
+
result, sample_error = native_sample(args_tuple, data_processor)
|
|
521
|
+
record = dict(
|
|
522
|
+
case_id=tracker.case_for(item),
|
|
523
|
+
phase=tracker.phase,
|
|
524
|
+
native_result=to_jsonable(result),
|
|
525
|
+
native_error=sample_error,
|
|
526
|
+
)
|
|
527
|
+
predictions.append(record)
|
|
528
|
+
journal.event("native_sample_evaluated", **record)
|
|
529
|
+
return result, sample_error
|
|
530
|
+
|
|
531
|
+
def evaluate(*args, **kwargs):
|
|
532
|
+
nonlocal evaluations
|
|
533
|
+
phase = "initial_evaluation" if evaluations == 0 else "pre_window_evaluation"
|
|
534
|
+
tracker.phase = phase
|
|
535
|
+
evaluations += 1
|
|
536
|
+
playbook = args[2]
|
|
537
|
+
window = dict(
|
|
538
|
+
phase=phase,
|
|
539
|
+
case_ids=[tracker.case_for(x) for x in args[3]],
|
|
540
|
+
before_playbook_sha256=content_hash(playbook),
|
|
541
|
+
)
|
|
542
|
+
journal.event("evaluation_window_started", **window)
|
|
543
|
+
result = native_eval(*args, **kwargs)
|
|
544
|
+
window["native_statistics"] = to_jsonable(result)
|
|
545
|
+
windows.append(window)
|
|
546
|
+
journal.event("evaluation_window_finished", **window)
|
|
547
|
+
return result
|
|
548
|
+
|
|
549
|
+
def train(*args, **kwargs):
|
|
550
|
+
item = kwargs["task_dict"]
|
|
551
|
+
tracker.select(item["question"], item.get("context", ""))
|
|
552
|
+
tracker.phase = "feedback_adaptation"
|
|
553
|
+
record = dict(
|
|
554
|
+
case_id=tracker.local.case_id,
|
|
555
|
+
before_playbook_sha256=content_hash(ace_system.playbook),
|
|
556
|
+
)
|
|
557
|
+
journal.event("feedback_update_started", **record)
|
|
558
|
+
result = native_train(*args, **kwargs)
|
|
559
|
+
record.update(
|
|
560
|
+
after_playbook_sha256=content_hash(ace_system.playbook),
|
|
561
|
+
native_tracking=to_jsonable(result),
|
|
562
|
+
)
|
|
563
|
+
updates.append(record)
|
|
564
|
+
journal.event("feedback_update_finished", **record)
|
|
565
|
+
return result
|
|
566
|
+
|
|
567
|
+
# Observation only: every native call receives its original
|
|
568
|
+
# arguments and every native return value is passed unchanged.
|
|
569
|
+
ace_module.evaluate_test_set = evaluate
|
|
570
|
+
utils.evaluate_single_test_sample = observed_sample
|
|
571
|
+
ace_system._train_single_sample = train
|
|
572
|
+
state = random.getstate()
|
|
573
|
+
try:
|
|
574
|
+
random.seed(c.seed)
|
|
575
|
+
with contextlib.redirect_stdout(diagnostics):
|
|
576
|
+
native_result = ace_system.run(
|
|
577
|
+
mode="online",
|
|
578
|
+
train_samples=None,
|
|
579
|
+
val_samples=None,
|
|
580
|
+
test_samples=list(adapted),
|
|
581
|
+
data_processor=(
|
|
582
|
+
data_processor
|
|
583
|
+
if data_processor is not None
|
|
584
|
+
else GenericTextProcessor()
|
|
585
|
+
),
|
|
586
|
+
config=dict(
|
|
587
|
+
num_epochs=1,
|
|
588
|
+
max_num_rounds=c.max_rounds,
|
|
589
|
+
curator_frequency=1,
|
|
590
|
+
online_eval_frequency=c.window_size,
|
|
591
|
+
eval_steps=len(rows),
|
|
592
|
+
save_steps=len(rows) + 1,
|
|
593
|
+
playbook_token_budget=c.playbook_token_budget,
|
|
594
|
+
task_name="toolkit_explicit_online",
|
|
595
|
+
json_mode=config.json_mode,
|
|
596
|
+
no_ground_truth=False,
|
|
597
|
+
save_dir=str(root / "native"),
|
|
598
|
+
test_workers=1,
|
|
599
|
+
use_bulletpoint_analyzer=False,
|
|
600
|
+
),
|
|
601
|
+
)
|
|
602
|
+
finally:
|
|
603
|
+
random.setstate(state)
|
|
604
|
+
ace_module.evaluate_test_set = native_eval
|
|
605
|
+
utils.evaluate_single_test_sample = native_sample
|
|
606
|
+
ace_system._train_single_sample = native_train
|
|
607
|
+
ace_system._run_test = native_initial
|
|
608
|
+
_save(root / "native-result.json", to_jsonable(native_result))
|
|
609
|
+
except Exception as exc:
|
|
610
|
+
error = dict(error_type=type(exc).__name__, message=str(exc))
|
|
611
|
+
primary = []
|
|
612
|
+
for row in rows:
|
|
613
|
+
records = [
|
|
614
|
+
p
|
|
615
|
+
for p in predictions
|
|
616
|
+
if p["case_id"] == row.example_id and p["phase"] == "pre_window_evaluation"
|
|
617
|
+
]
|
|
618
|
+
if len(records) > 1:
|
|
619
|
+
raise ValidationError("ACE online primary prediction was evaluated twice")
|
|
620
|
+
record = records[0] if records else None
|
|
621
|
+
result = record["native_result"] if record else None
|
|
622
|
+
valid = (
|
|
623
|
+
isinstance(result, dict)
|
|
624
|
+
and result.get("success") is True
|
|
625
|
+
and isinstance(result.get("final_answer"), str)
|
|
626
|
+
and bool(result["final_answer"].strip())
|
|
627
|
+
and result["final_answer"] != "No final answer found"
|
|
628
|
+
)
|
|
629
|
+
primary.append(
|
|
630
|
+
dict(
|
|
631
|
+
case_id=row.example_id,
|
|
632
|
+
status=(
|
|
633
|
+
"native_prediction_returned"
|
|
634
|
+
if valid
|
|
635
|
+
else "failed_primary_prediction"
|
|
636
|
+
if record
|
|
637
|
+
else "not_reached_after_native_failure"
|
|
638
|
+
if tracker and tracker.by_case[row.example_id]["model_calls"]
|
|
639
|
+
else "never_started"
|
|
640
|
+
),
|
|
641
|
+
native_prediction=result,
|
|
642
|
+
raw_primary_observation=record,
|
|
643
|
+
feedback_completed=any(u["case_id"] == row.example_id for u in updates),
|
|
644
|
+
)
|
|
645
|
+
)
|
|
646
|
+
journal.event("stream_terminal", native_returned=error is None, error=error)
|
|
647
|
+
journal.close()
|
|
648
|
+
_save(root / "provider-calls.json", calls)
|
|
649
|
+
with (root / "final-playbook.txt").open("x", encoding="utf-8") as stream:
|
|
650
|
+
stream.write(ace_system.playbook if ace_system is not None else "")
|
|
651
|
+
terminal = dict(
|
|
652
|
+
protocol=PROTOCOL,
|
|
653
|
+
release_id=RELEASE,
|
|
654
|
+
status=(
|
|
655
|
+
"native_online_returned"
|
|
656
|
+
if error is None
|
|
657
|
+
else "native_failed_terminal"
|
|
658
|
+
if tracker and tracker.model_calls
|
|
659
|
+
else "execution_failed_before_model"
|
|
660
|
+
),
|
|
661
|
+
error=error,
|
|
662
|
+
expected_positions=len(rows),
|
|
663
|
+
primary_outcomes=primary,
|
|
664
|
+
predictions_before_current_window_feedback=True,
|
|
665
|
+
post_update_predictions_are_not_primary=True,
|
|
666
|
+
upstream_results_may_exclude_failures_denominator_preserved=len(rows),
|
|
667
|
+
windows=windows,
|
|
668
|
+
updates=updates,
|
|
669
|
+
usage=tracker.as_dict() if tracker else {},
|
|
670
|
+
per_case_usage=tracker.by_case if tracker else {},
|
|
671
|
+
budget_rejections=tracker.budget_rejections if tracker else [],
|
|
672
|
+
event_chain_final_sha256=journal.previous,
|
|
673
|
+
event_count=journal.count,
|
|
674
|
+
wall_seconds=time.monotonic() - started,
|
|
675
|
+
cpu_seconds=time.process_time() - cpu,
|
|
676
|
+
monetary_prices_unconfigured=all(
|
|
677
|
+
not r.input_cost_per_million and not r.output_cost_per_million
|
|
678
|
+
for r in config.roles.values()
|
|
679
|
+
),
|
|
680
|
+
automatic_retry=False,
|
|
681
|
+
transductive_not_offline_or_heldout=True,
|
|
682
|
+
paper_results_changed=False,
|
|
683
|
+
native_source_commit=runtime.policy.commit if runtime else None,
|
|
684
|
+
verified_native_source_files=dict(runtime.policy.source_hashes) if runtime else {},
|
|
685
|
+
)
|
|
686
|
+
_save(root / "terminal.json", terminal)
|
|
687
|
+
native_files = {
|
|
688
|
+
str(p.relative_to(root)): _sha(p) for p in (root / "native").rglob("*") if p.is_file()
|
|
689
|
+
}
|
|
690
|
+
if (root / "native-result.json").exists():
|
|
691
|
+
native_files["native-result.json"] = _sha(root / "native-result.json")
|
|
692
|
+
_save(root / "native-files.json", native_files)
|
|
693
|
+
files = {
|
|
694
|
+
name: _sha(root / name)
|
|
695
|
+
for name in (
|
|
696
|
+
"plan.json",
|
|
697
|
+
"terminal.json",
|
|
698
|
+
"provider-calls.json",
|
|
699
|
+
"events.jsonl",
|
|
700
|
+
"final-playbook.txt",
|
|
701
|
+
"native-files.json",
|
|
702
|
+
)
|
|
703
|
+
}
|
|
704
|
+
manifest = dict(
|
|
705
|
+
protocol=PROTOCOL, release_id=RELEASE, files=files, offline_reuse_allowed=False
|
|
706
|
+
)
|
|
707
|
+
_save(root / "manifest.json", {**manifest, "artifact_id": content_hash(manifest)})
|
|
708
|
+
return ACEOnlineResult.load(root)
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
__all__ = ["ACEOnlineControls", "ACEOnlineRecipe", "ACEOnlineResult", "audit_online_stream"]
|