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,305 @@
|
|
|
1
|
+
"""Public native SmartSearch GRPO execution, with explicit aggregate admission."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import importlib
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import secrets
|
|
8
|
+
import shutil
|
|
9
|
+
import sys
|
|
10
|
+
import tempfile
|
|
11
|
+
import threading
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from agentinputlab.contracts import ExternalDependencyError, ValidationError
|
|
16
|
+
from agentinputlab.contracts.serialization import content_hash, to_jsonable
|
|
17
|
+
|
|
18
|
+
from .qrag import _file, _sha
|
|
19
|
+
from .smartsearch_grpo_data import (
|
|
20
|
+
SmartSearchGRPOControls,
|
|
21
|
+
SmartSearchGRPODataArtifact,
|
|
22
|
+
_native_grpo_config,
|
|
23
|
+
verify_smartsearch_grpo_source,
|
|
24
|
+
)
|
|
25
|
+
from .smartsearch_grpo_meter import SmartSearchGRPOCostLedger, SmartSearchGRPOCostLimits
|
|
26
|
+
from .smartsearch_grpo_tools import (
|
|
27
|
+
SmartSearchGRPORetrievalService,
|
|
28
|
+
_new_output,
|
|
29
|
+
_save,
|
|
30
|
+
make_smartsearch_grpo_retrieval_server,
|
|
31
|
+
)
|
|
32
|
+
from .smartsearch_grpo_transport import (
|
|
33
|
+
SmartSearchGRPOCoordinator,
|
|
34
|
+
make_smartsearch_grpo_coordinator_server,
|
|
35
|
+
)
|
|
36
|
+
from .smartsearch_policy import MODEL_SCHEMA, _model
|
|
37
|
+
|
|
38
|
+
GRPO_TRAINING_PROTOCOL = "agentinputlab.smartsearch.native_grpo_fit.v1"
|
|
39
|
+
_RUNTIME_FILES = (
|
|
40
|
+
"smartsearch_grpo_training.py", "smartsearch_grpo_worker.py", "smartsearch_grpo_transport.py",
|
|
41
|
+
"smartsearch_grpo_meter.py", "smartsearch_grpo_prefix.py", "smartsearch_grpo_rollout.py",
|
|
42
|
+
"smartsearch_grpo_tools.py", "smartsearch_grpo_data.py", "smartsearch_teacher.py",
|
|
43
|
+
"smartsearch_sampling.py", "smartsearch_curriculum.py",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _prepare_native_output_directories(root):
|
|
48
|
+
"""Create native checkpoint/rollout parents before any paid generation.
|
|
49
|
+
|
|
50
|
+
The pinned reward manager opens its validation journal in append mode and
|
|
51
|
+
does not create the journal's parent. The enclosing fit root is new and
|
|
52
|
+
exclusively owned; existing native output (including symlinks) is refused.
|
|
53
|
+
"""
|
|
54
|
+
root = Path(root)
|
|
55
|
+
if root.is_symlink() or not root.is_dir():
|
|
56
|
+
raise ValidationError("SmartSearch native output requires its own regular fit root")
|
|
57
|
+
native = root / "native"
|
|
58
|
+
native.mkdir()
|
|
59
|
+
(native / "rollouts").mkdir()
|
|
60
|
+
return native
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(frozen=True, slots=True)
|
|
64
|
+
class SmartSearchGRPOArtifact:
|
|
65
|
+
root: Path
|
|
66
|
+
artifact_id: str
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def checkpoint(self):
|
|
70
|
+
return self.root / "exported-policy"
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def load(cls, root):
|
|
74
|
+
folder = Path(root)
|
|
75
|
+
if folder.is_symlink() or not folder.is_dir():
|
|
76
|
+
raise ValidationError("SmartSearch GRPO artifact must be a regular completed run directory")
|
|
77
|
+
folder = folder.resolve()
|
|
78
|
+
record = json.loads(_file(folder / "artifact.json", "native GRPO artifact").read_text())
|
|
79
|
+
identity = record.pop("artifact_id", None)
|
|
80
|
+
if record.get("protocol") != GRPO_TRAINING_PROTOCOL or identity != content_hash(record):
|
|
81
|
+
raise ValidationError("SmartSearch native GRPO artifact identity differs")
|
|
82
|
+
for name, key in (("fit-plan.json", "fit_plan_sha256"), ("fit-terminal.json", "fit_terminal_sha256"),
|
|
83
|
+
("model-manifest.json", "model_manifest_sha256")):
|
|
84
|
+
if _sha(_file(folder / name, "native GRPO closure")) != record.get(key):
|
|
85
|
+
raise ValidationError("SmartSearch native GRPO artifact closure changed")
|
|
86
|
+
_model(folder / "exported-policy", folder / "model-manifest.json", record["model_manifest_sha256"])
|
|
87
|
+
terminal = json.loads((folder / "fit-terminal.json").read_text())
|
|
88
|
+
if terminal.get("status") != "trained_native_grpo_candidate" or terminal.get("usage", {}).get("failed") is not False:
|
|
89
|
+
raise ValidationError("SmartSearch native GRPO artifact is not a healthy completed fit")
|
|
90
|
+
return cls(folder, identity)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _references(data):
|
|
94
|
+
try:
|
|
95
|
+
import pyarrow.parquet as pq
|
|
96
|
+
except ImportError as exc:
|
|
97
|
+
raise ExternalDependencyError("Install the benchmark parquet extra for native GRPO inputs") from exc
|
|
98
|
+
result = {}
|
|
99
|
+
manifest = json.loads((data.root / "manifest.json").read_text())
|
|
100
|
+
for role, filename in (("train", "train.parquet"), ("validation", "validation.parquet")):
|
|
101
|
+
if _sha(data.root / filename) != manifest["outputs"][filename]:
|
|
102
|
+
raise ValidationError("SmartSearch GRPO reference parquet changed before native loading")
|
|
103
|
+
rows = pq.read_table(data.root / filename).to_pylist()
|
|
104
|
+
if _sha(data.root / filename) != manifest["outputs"][filename]:
|
|
105
|
+
raise ValidationError("SmartSearch GRPO reference parquet changed during native loading")
|
|
106
|
+
values = {}
|
|
107
|
+
for row in rows:
|
|
108
|
+
key = row["question"].strip()
|
|
109
|
+
if key in values:
|
|
110
|
+
raise ValidationError("SmartSearch native GRPO reference questions collide after native extraction")
|
|
111
|
+
values[key] = row["reward_model"]["ground_truth"]
|
|
112
|
+
result[role + "_references"] = values
|
|
113
|
+
if set(result["train_references"]) & set(result["validation_references"]):
|
|
114
|
+
raise ValidationError("SmartSearch GRPO training/development references overlap")
|
|
115
|
+
return result
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _visible_actor_devices(controls):
|
|
119
|
+
visible = os.environ.get("CUDA_VISIBLE_DEVICES", "")
|
|
120
|
+
devices = visible.split(",") if visible else []
|
|
121
|
+
if len(devices) != controls.gpu_processes or any(not value.strip() or value != value.strip() for value in devices) or (
|
|
122
|
+
len(set(devices)) != len(devices)
|
|
123
|
+
):
|
|
124
|
+
raise ValidationError("Select exactly the admitted actor GPUs with CUDA_VISIBLE_DEVICES in a fresh process")
|
|
125
|
+
return visible
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class SmartSearchNativeGRPOTraining:
|
|
129
|
+
"""Run upstream native FSDP/vLLM/GRPO, not a replacement training loop.
|
|
130
|
+
|
|
131
|
+
The operator supplies a frozen retriever and a separately metered raw-text
|
|
132
|
+
helper provider. The helper model must run outside the selected actor GPU
|
|
133
|
+
mesh. A fresh, dedicated native runtime is required; this owns a new local
|
|
134
|
+
Ray cluster and never attaches to an existing user's cluster.
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
def __init__(self, *, controls: SmartSearchGRPOControls, cost_limits: SmartSearchGRPOCostLimits,
|
|
138
|
+
max_helper_rows=10000, max_retrieval_calls=10000, min_free_output_bytes=64 * 1024**3):
|
|
139
|
+
if not isinstance(controls, SmartSearchGRPOControls) or not isinstance(cost_limits, SmartSearchGRPOCostLimits):
|
|
140
|
+
raise ValidationError("SmartSearch native GRPO requires typed training and aggregate cost controls")
|
|
141
|
+
if cost_limits.actor_ranks != controls.gpu_processes or any(type(v) is not int or v < 1
|
|
142
|
+
for v in (max_helper_rows, max_retrieval_calls, min_free_output_bytes)):
|
|
143
|
+
raise ValidationError("SmartSearch GRPO actor mesh and explicit runtime caps differ")
|
|
144
|
+
self.controls, self.cost_limits = controls, cost_limits
|
|
145
|
+
self.max_helper_rows, self.max_retrieval_calls = max_helper_rows, max_retrieval_calls
|
|
146
|
+
self.min_free_output_bytes = min_free_output_bytes
|
|
147
|
+
|
|
148
|
+
def fit(self, *, checkout, model_root, model_manifest, model_manifest_sha256, data_root,
|
|
149
|
+
output_root, retriever, generate_helper, count_helper_input_tokens, helper_fingerprint_sha256,
|
|
150
|
+
model_provenance, source_and_data_acknowledged=False):
|
|
151
|
+
if source_and_data_acknowledged is not True or not isinstance(model_provenance, dict) or not model_provenance:
|
|
152
|
+
raise ValidationError("SmartSearch native GRPO needs explicit model provenance and source/data acknowledgement")
|
|
153
|
+
try:
|
|
154
|
+
model_provenance = to_jsonable(model_provenance)
|
|
155
|
+
json.dumps(model_provenance, allow_nan=False)
|
|
156
|
+
except (TypeError, ValueError) as exc:
|
|
157
|
+
raise ValidationError("SmartSearch native GRPO model provenance must be canonical JSON") from exc
|
|
158
|
+
if any(name == "verl" or name.startswith("verl.") for name in sys.modules):
|
|
159
|
+
raise ExternalDependencyError("Run native SmartSearch GRPO once in a fresh dedicated process")
|
|
160
|
+
visible = _visible_actor_devices(self.controls)
|
|
161
|
+
source, binding = verify_smartsearch_grpo_source(checkout)
|
|
162
|
+
model, model_closure = _model(model_root, model_manifest, model_manifest_sha256)
|
|
163
|
+
data = SmartSearchGRPODataArtifact.load(data_root)
|
|
164
|
+
data_record = json.loads((data.root / "manifest.json").read_text())
|
|
165
|
+
if data_record["source"] != binding:
|
|
166
|
+
raise ValidationError("SmartSearch GRPO data was not prepared with the same native source binding")
|
|
167
|
+
global_steps = self.controls.planned_steps(data.train_rows)
|
|
168
|
+
# Native YAML is loaded below as well; this value is rechecked against
|
|
169
|
+
# its actual ppo_epochs before any model initialization.
|
|
170
|
+
planned_actor_steps = self.controls.planned_actor_optimizer_steps(data.train_rows, ppo_epochs=1)
|
|
171
|
+
if planned_actor_steps > self.cost_limits.optimizer_steps_per_rank:
|
|
172
|
+
raise ValidationError("SmartSearch GRPO aggregate optimizer admission is smaller than the native plan")
|
|
173
|
+
references = _references(data)
|
|
174
|
+
supplied = Path(output_root)
|
|
175
|
+
output = supplied.resolve(strict=False)
|
|
176
|
+
if any(output.is_relative_to(p) or p.is_relative_to(output) for p in (source, model, data.root)):
|
|
177
|
+
raise ValidationError("SmartSearch GRPO output overlaps a protected source/model/data input")
|
|
178
|
+
parent = output.parent
|
|
179
|
+
while not parent.exists():
|
|
180
|
+
parent = parent.parent
|
|
181
|
+
if shutil.disk_usage(parent).free < self.min_free_output_bytes:
|
|
182
|
+
raise ExternalDependencyError("SmartSearch native GRPO checkpoint capacity is insufficient")
|
|
183
|
+
root = _new_output(supplied)
|
|
184
|
+
plan = dict(protocol=GRPO_TRAINING_PROTOCOL, source=binding, controls=self.controls, cost_limits=self.cost_limits,
|
|
185
|
+
model_manifest_sha256=model_manifest_sha256, model_revision=model_closure["revision"],
|
|
186
|
+
model_provenance=model_provenance, data_artifact_id=data.artifact_id,
|
|
187
|
+
planned_global_steps=global_steps, planned_actor_optimizer_steps=planned_actor_steps,
|
|
188
|
+
actor_visible_devices=visible, helper_fingerprint_sha256=helper_fingerprint_sha256,
|
|
189
|
+
max_helper_rows=self.max_helper_rows, max_retrieval_calls=self.max_retrieval_calls,
|
|
190
|
+
no_automatic_neural_retry=True, native_loss_optimizer_rollout_reward_math_unchanged=True,
|
|
191
|
+
physical_engine_initialization_and_checkpoint_recomputation_forwards_unmeasured=True,
|
|
192
|
+
seed_scope="data/helper/PyTorch seed; native vLLM rank-derived seed retained",
|
|
193
|
+
toolkit_modules={name: _sha(Path(__file__).with_name(name)) for name in _RUNTIME_FILES},
|
|
194
|
+
toolkit_executor_sha256=_sha(Path(__file__)))
|
|
195
|
+
_save(root, "fit-plan.json", plan)
|
|
196
|
+
servers, threads, ray_module, ledger = [], [], None, None
|
|
197
|
+
prior_path = list(sys.path)
|
|
198
|
+
old_ensure = os.environ.get("ENSURE_CUDA_VISIBLE_DEVICES")
|
|
199
|
+
try:
|
|
200
|
+
native_output = _prepare_native_output_directories(root)
|
|
201
|
+
ledger = SmartSearchGRPOCostLedger(output_root=root / "costs", limits=self.cost_limits)
|
|
202
|
+
coordinator = SmartSearchGRPOCoordinator(ledger=ledger, generate=generate_helper,
|
|
203
|
+
count_input_tokens=count_helper_input_tokens, model_fingerprint_sha256=helper_fingerprint_sha256)
|
|
204
|
+
rpc_capability, tool_capability = secrets.token_urlsafe(32), secrets.token_urlsafe(32)
|
|
205
|
+
def start_server(server):
|
|
206
|
+
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
|
207
|
+
try:
|
|
208
|
+
thread.start()
|
|
209
|
+
except BaseException:
|
|
210
|
+
server.server_close()
|
|
211
|
+
raise
|
|
212
|
+
servers.append(server)
|
|
213
|
+
threads.append(thread)
|
|
214
|
+
|
|
215
|
+
rpc = make_smartsearch_grpo_coordinator_server(coordinator, capability=rpc_capability)
|
|
216
|
+
start_server(rpc)
|
|
217
|
+
tools = SmartSearchGRPORetrievalService(retriever, output_root=root / "retrieval",
|
|
218
|
+
max_retrieval_calls=self.max_retrieval_calls)
|
|
219
|
+
tool_server = make_smartsearch_grpo_retrieval_server(tools, capability=tool_capability)
|
|
220
|
+
start_server(tool_server)
|
|
221
|
+
descriptor = dict(checkout=str(source), output_root=str(root), seed=self.controls.seed,
|
|
222
|
+
coordinator_endpoint=f"http://127.0.0.1:{rpc.server_port}/{rpc_capability}/rpc",
|
|
223
|
+
helper_fingerprint_sha256=helper_fingerprint_sha256, max_helper_rows=self.max_helper_rows,
|
|
224
|
+
cost_limits=to_jsonable(self.cost_limits), toolkit_modules=plan["toolkit_modules"], **references)
|
|
225
|
+
config = _native_grpo_config(source, model=model, data=data, output_root=native_output,
|
|
226
|
+
controls=self.controls,
|
|
227
|
+
sandbox_url=f"http://127.0.0.1:{tool_server.server_port}/{tool_capability}",
|
|
228
|
+
reward_module=source / "src/verl/utils/reward_score/re_call.py")
|
|
229
|
+
actual_steps = self.controls.planned_actor_optimizer_steps(data.train_rows,
|
|
230
|
+
ppo_epochs=config["actor_rollout_ref"]["actor"]["ppo_epochs"])
|
|
231
|
+
if actual_steps != planned_actor_steps or config["actor_rollout_ref"]["actor"]["strategy"] != "fsdp":
|
|
232
|
+
raise ExternalDependencyError("SmartSearch native actor plan/strategy differs from admitted FSDP execution")
|
|
233
|
+
_save(root, "private-runtime.json", dict(descriptor=descriptor, native_config=config,
|
|
234
|
+
contains_run_local_capabilities_not_for_publication=True))
|
|
235
|
+
try:
|
|
236
|
+
import ray
|
|
237
|
+
import torch
|
|
238
|
+
from omegaconf import OmegaConf
|
|
239
|
+
except ImportError as exc:
|
|
240
|
+
raise ExternalDependencyError("Install the pinned native SmartSearch Ray/vLLM training runtime") from exc
|
|
241
|
+
if ray.is_initialized():
|
|
242
|
+
raise ExternalDependencyError("SmartSearch GRPO cannot reuse an existing Ray cluster")
|
|
243
|
+
if not torch.cuda.is_available() or torch.cuda.device_count() != self.controls.gpu_processes:
|
|
244
|
+
raise ExternalDependencyError("SmartSearch native GRPO requires exactly its selected CUDA actor mesh")
|
|
245
|
+
sys.path.insert(0, str(source / "src"))
|
|
246
|
+
native_driver = importlib.import_module("verl.trainer.main_ppo")
|
|
247
|
+
from .smartsearch_grpo_worker import native_grpo_task_runner
|
|
248
|
+
task_type = native_grpo_task_runner(native_driver, descriptor)
|
|
249
|
+
package_root = Path(__file__).resolve().parents[2]
|
|
250
|
+
temporary = tempfile.mkdtemp(prefix="ail-smartsearch-ray-")
|
|
251
|
+
_save(root, "ray-runtime.json", dict(temp_root=temporary, own_local_cluster=True, actor_gpu_count=self.controls.gpu_processes))
|
|
252
|
+
os.environ["ENSURE_CUDA_VISIBLE_DEVICES"] = visible
|
|
253
|
+
ray_module = ray
|
|
254
|
+
ray.init(address="local", num_gpus=self.controls.gpu_processes, num_cpus=max(8, self.controls.gpu_processes * 4),
|
|
255
|
+
include_dashboard=False, _temp_dir=temporary,
|
|
256
|
+
runtime_env={"env_vars": dict(PYTHONPATH=str(source / "src") + os.pathsep + str(package_root),
|
|
257
|
+
PYTHONDONTWRITEBYTECODE="1", PYTHONNOUSERSITE="1", TOKENIZERS_PARALLELISM="false",
|
|
258
|
+
HF_HUB_OFFLINE="1", TRANSFORMERS_OFFLINE="1", ENSURE_CUDA_VISIBLE_DEVICES=visible,
|
|
259
|
+
NCCL_DEBUG="WARN", VLLM_LOGGING_LEVEL="WARN")})
|
|
260
|
+
actor_type = ray.remote(num_cpus=1, max_restarts=0, max_task_retries=0)(task_type)
|
|
261
|
+
runner = actor_type.remote()
|
|
262
|
+
result = ray.get(runner.run.remote(OmegaConf.create(config)))
|
|
263
|
+
if result["global_steps"] != global_steps:
|
|
264
|
+
raise ExternalDependencyError("SmartSearch native GRPO did not finish its admitted global-step plan")
|
|
265
|
+
usage = coordinator.assert_healthy(expected_optimizer_steps=actual_steps,
|
|
266
|
+
required_roles=("actor_rollout", "ref"))
|
|
267
|
+
retrieval_usage = tools.assert_healthy()
|
|
268
|
+
export = json.loads(_file(root / "safe-export.json", "trained actor export").read_text())
|
|
269
|
+
if export.get("same_live_trained_actor") is not True or export.get("new_optimizer_steps") != 0:
|
|
270
|
+
raise ExternalDependencyError("SmartSearch GRPO checkpoint is not its actual trained actor")
|
|
271
|
+
manifest = dict(schema=MODEL_SCHEMA, revision=content_hash(dict(plan=plan, export=export)),
|
|
272
|
+
files=export["files"], native_grpo=True, trained_actor_not_original_input=True)
|
|
273
|
+
_save(root, "model-manifest.json", manifest)
|
|
274
|
+
_model(root / "exported-policy", root / "model-manifest.json", _sha(root / "model-manifest.json"))
|
|
275
|
+
# Confirm the mounted input snapshot was not used as an output path.
|
|
276
|
+
_model(model, model_manifest, model_manifest_sha256)
|
|
277
|
+
_save(root, "fit-terminal.json", dict(status="trained_native_grpo_candidate", usage=usage,
|
|
278
|
+
retrieval_usage=retrieval_usage, native_driver_result=result, safe_export=export,
|
|
279
|
+
full_sft_dpo_grpo_recipe_certification=False, heldout_acceptance_completed=False))
|
|
280
|
+
artifact = dict(protocol=GRPO_TRAINING_PROTOCOL, fit_plan_sha256=_sha(root / "fit-plan.json"),
|
|
281
|
+
fit_terminal_sha256=_sha(root / "fit-terminal.json"),
|
|
282
|
+
model_manifest_sha256=_sha(root / "model-manifest.json"),
|
|
283
|
+
source_commit=binding["source_commit"], data_artifact_id=data.artifact_id)
|
|
284
|
+
_save(root, "artifact.json", {**artifact, "artifact_id": content_hash(artifact)})
|
|
285
|
+
return SmartSearchGRPOArtifact.load(root)
|
|
286
|
+
except BaseException as exc:
|
|
287
|
+
if ledger is not None:
|
|
288
|
+
ledger.fail("native-driver", error_type=type(exc).__name__)
|
|
289
|
+
_save(root, "failed.json", dict(error_type=type(exc).__name__, error=str(exc),
|
|
290
|
+
usage=ledger.snapshot() if ledger is not None else None,
|
|
291
|
+
no_automatic_retry=True, accept_checkpoint=False))
|
|
292
|
+
raise
|
|
293
|
+
finally:
|
|
294
|
+
if ray_module is not None:
|
|
295
|
+
ray_module.shutdown() # This newly owned cluster only.
|
|
296
|
+
for server in servers:
|
|
297
|
+
server.shutdown()
|
|
298
|
+
server.server_close()
|
|
299
|
+
for thread in threads:
|
|
300
|
+
thread.join(timeout=10)
|
|
301
|
+
sys.path[:] = prior_path
|
|
302
|
+
if old_ensure is None:
|
|
303
|
+
os.environ.pop("ENSURE_CUDA_VISIBLE_DEVICES", None)
|
|
304
|
+
else:
|
|
305
|
+
os.environ["ENSURE_CUDA_VISIBLE_DEVICES"] = old_ensure
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Loopback-only coordinator RPC for one native GRPO run, with no retries.
|
|
2
|
+
|
|
3
|
+
This carries measured costs and native helper completions, never Python code,
|
|
4
|
+
shell commands, pickle or import paths. Retrieval has its separate fixed-tool
|
|
5
|
+
service. The coordinator owns ONE ledger and ONE helper callback for all ranks.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import hmac
|
|
10
|
+
import json
|
|
11
|
+
import re
|
|
12
|
+
import threading
|
|
13
|
+
import urllib.error
|
|
14
|
+
import urllib.request
|
|
15
|
+
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
16
|
+
from urllib.parse import urlsplit
|
|
17
|
+
|
|
18
|
+
from agentinputlab.contracts import BudgetExceededError, ExternalDependencyError, ValidationError
|
|
19
|
+
from agentinputlab.contracts.serialization import to_jsonable
|
|
20
|
+
|
|
21
|
+
from .smartsearch_grpo_meter import SmartSearchGRPOCostLedger, meter_smartsearch_grpo_helper
|
|
22
|
+
from .smartsearch_grpo_tools import _save
|
|
23
|
+
from .smartsearch_teacher import SmartSearchTeacherCompletion
|
|
24
|
+
|
|
25
|
+
_LIMIT = 16 * 1024 * 1024
|
|
26
|
+
_METHODS = {
|
|
27
|
+
"reserve": {"kind", "worker", "input_token_counts", "samples", "max_new_tokens"},
|
|
28
|
+
"settle": {"ticket", "output_token_counts"},
|
|
29
|
+
"fail": {"ticket", "error_type"},
|
|
30
|
+
"optimizer_begin": {"rank"},
|
|
31
|
+
"optimizer_end": {"rank"},
|
|
32
|
+
"snapshot": set(),
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class SmartSearchGRPOCoordinator:
|
|
37
|
+
"""Own aggregate accounting and a serialized, measured native helper."""
|
|
38
|
+
|
|
39
|
+
def __init__(self, *, ledger, generate, count_input_tokens, model_fingerprint_sha256):
|
|
40
|
+
if not isinstance(ledger, SmartSearchGRPOCostLedger):
|
|
41
|
+
raise ValidationError("SmartSearch GRPO coordinator requires one shared cost ledger")
|
|
42
|
+
self.ledger = ledger
|
|
43
|
+
self.helper = meter_smartsearch_grpo_helper(generate, ledger=ledger, worker="shared-native-teacher",
|
|
44
|
+
fingerprint=model_fingerprint_sha256, count_input_tokens=count_input_tokens)
|
|
45
|
+
self.fingerprint = model_fingerprint_sha256
|
|
46
|
+
self._lock = threading.Lock()
|
|
47
|
+
self._helper_number = 0
|
|
48
|
+
self.workers = {}
|
|
49
|
+
|
|
50
|
+
def dispatch(self, operation, arguments):
|
|
51
|
+
if operation in _METHODS and set(arguments) == _METHODS[operation]:
|
|
52
|
+
return getattr(self.ledger, operation)(**arguments)
|
|
53
|
+
if operation == "helper" and set(arguments) == {"prompt", "temperature", "max_new_tokens", "stop", "seed"}:
|
|
54
|
+
with self._lock:
|
|
55
|
+
self._helper_number += 1
|
|
56
|
+
number = self._helper_number
|
|
57
|
+
# A missing transport response is not free work: the ledger and
|
|
58
|
+
# these coordinator-side records survive a disconnected worker.
|
|
59
|
+
_save(self.ledger.root, f"native-helper-{number:06d}-request.json", arguments)
|
|
60
|
+
result = self.helper(**arguments)
|
|
61
|
+
_save(self.ledger.root, f"native-helper-{number:06d}-response.json", result)
|
|
62
|
+
return to_jsonable(result)
|
|
63
|
+
if operation == "worker_completed" and set(arguments) == {"rank", "role", "usage"}:
|
|
64
|
+
rank, role, usage = arguments["rank"], arguments["role"], arguments["usage"]
|
|
65
|
+
fields = {"forward_attempts", "forward_responses", "input_token_positions", "nonfinite_native_metrics"}
|
|
66
|
+
if type(rank) is not int or not 0 <= rank < self.ledger.limits.actor_ranks or (
|
|
67
|
+
role not in {"actor_rollout", "actor_rollout_ref", "actor", "rollout", "ref"}
|
|
68
|
+
or not isinstance(usage, dict) or set(usage) != fields
|
|
69
|
+
or any(type(n) is not int or n < 0 for n in usage.values())
|
|
70
|
+
or usage["forward_attempts"] != usage["forward_responses"]
|
|
71
|
+
or usage["nonfinite_native_metrics"]
|
|
72
|
+
):
|
|
73
|
+
raise ExternalDependencyError("SmartSearch GRPO worker has incomplete/nonfinite native observations")
|
|
74
|
+
key = f"{role}-rank-{rank}"
|
|
75
|
+
with self._lock:
|
|
76
|
+
if key in self.workers:
|
|
77
|
+
raise ExternalDependencyError("SmartSearch GRPO worker completion cannot be repeated")
|
|
78
|
+
_save(self.ledger.root, key + "-terminal.json", arguments)
|
|
79
|
+
self.workers[key] = to_jsonable(arguments)
|
|
80
|
+
return None
|
|
81
|
+
raise ValidationError("SmartSearch GRPO coordinator operation/argument schema differs")
|
|
82
|
+
|
|
83
|
+
def assert_healthy(self, *, expected_optimizer_steps, required_roles):
|
|
84
|
+
result = self.ledger.assert_healthy(expected_optimizer_steps=expected_optimizer_steps)
|
|
85
|
+
expected = {f"{role}-rank-{rank}" for role in required_roles
|
|
86
|
+
for rank in range(self.ledger.limits.actor_ranks)}
|
|
87
|
+
if set(self.workers) != expected or any(
|
|
88
|
+
not row["usage"]["forward_responses"] for row in self.workers.values()
|
|
89
|
+
):
|
|
90
|
+
raise ExternalDependencyError("SmartSearch GRPO actor/reference rank receipts are incomplete")
|
|
91
|
+
return {**result, "workers": to_jsonable(self.workers)}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def make_smartsearch_grpo_coordinator_server(coordinator, *, capability, port=0):
|
|
95
|
+
"""Start separately with serve_forever; bound to 127.0.0.1 only."""
|
|
96
|
+
if not isinstance(coordinator, SmartSearchGRPOCoordinator) or not isinstance(capability, str) or (
|
|
97
|
+
not re.fullmatch(r"[A-Za-z0-9_-]{32,128}", capability)
|
|
98
|
+
or type(port) is not int or not 0 <= port <= 65535
|
|
99
|
+
):
|
|
100
|
+
raise ValidationError("SmartSearch GRPO coordinator needs an explicit random capability")
|
|
101
|
+
slots = threading.BoundedSemaphore(16)
|
|
102
|
+
|
|
103
|
+
class Handler(BaseHTTPRequestHandler):
|
|
104
|
+
def setup(self):
|
|
105
|
+
super().setup()
|
|
106
|
+
self.connection.settimeout(600)
|
|
107
|
+
|
|
108
|
+
def log_message(self, *_args):
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
def send_json(self, status, value):
|
|
112
|
+
raw = json.dumps(to_jsonable(value), ensure_ascii=False, allow_nan=False).encode()
|
|
113
|
+
self.send_response(status)
|
|
114
|
+
self.send_header("Content-Type", "application/json")
|
|
115
|
+
self.send_header("Content-Length", str(len(raw)))
|
|
116
|
+
self.send_header("Cache-Control", "no-store")
|
|
117
|
+
self.end_headers()
|
|
118
|
+
self.wfile.write(raw)
|
|
119
|
+
|
|
120
|
+
def do_POST(self):
|
|
121
|
+
parts = self.path.split("/")
|
|
122
|
+
if len(parts) != 3 or not hmac.compare_digest(parts[1].encode(), capability.encode()):
|
|
123
|
+
self.send_json(401, {"error_type": "Unauthorized"})
|
|
124
|
+
return
|
|
125
|
+
if parts[2] != "rpc":
|
|
126
|
+
self.send_json(404, {"error_type": "NotFound"})
|
|
127
|
+
return
|
|
128
|
+
entered = False
|
|
129
|
+
try:
|
|
130
|
+
lengths = self.headers.get_all("Content-Length", [])
|
|
131
|
+
if self.headers.get("Transfer-Encoding") or len(lengths) != 1 or not lengths[0].isdigit() or (
|
|
132
|
+
not 0 < int(lengths[0]) <= _LIMIT or self.headers.get_content_type() != "application/json"
|
|
133
|
+
):
|
|
134
|
+
raise ValidationError("SmartSearch GRPO RPC body contract differs")
|
|
135
|
+
entered = slots.acquire(blocking=False)
|
|
136
|
+
if not entered:
|
|
137
|
+
raise ExternalDependencyError("SmartSearch GRPO coordinator is at its explicit concurrency limit")
|
|
138
|
+
|
|
139
|
+
def unique(pairs):
|
|
140
|
+
result = {}
|
|
141
|
+
for key, value in pairs:
|
|
142
|
+
if key in result:
|
|
143
|
+
raise ValidationError("SmartSearch GRPO RPC duplicate key")
|
|
144
|
+
result[key] = value
|
|
145
|
+
return result
|
|
146
|
+
|
|
147
|
+
raw = self.rfile.read(int(lengths[0]))
|
|
148
|
+
if len(raw) != int(lengths[0]):
|
|
149
|
+
raise ValidationError("SmartSearch GRPO RPC body is incomplete")
|
|
150
|
+
body = json.loads(raw, object_pairs_hook=unique,
|
|
151
|
+
parse_constant=lambda _: (_ for _ in ()).throw(ValueError("nonfinite JSON")))
|
|
152
|
+
if not isinstance(body, dict) or set(body) != {"operation", "arguments"} or (
|
|
153
|
+
not isinstance(body["operation"], str) or not isinstance(body["arguments"], dict)
|
|
154
|
+
):
|
|
155
|
+
raise ValidationError("SmartSearch GRPO RPC envelope differs")
|
|
156
|
+
result = coordinator.dispatch(body["operation"], body["arguments"])
|
|
157
|
+
except BaseException as exc:
|
|
158
|
+
coordinator.ledger.fail("authenticated-rpc", error_type=type(exc).__name__)
|
|
159
|
+
self.send_json(409, {"error_type": type(exc).__name__, "error": str(exc)})
|
|
160
|
+
return
|
|
161
|
+
finally:
|
|
162
|
+
if entered:
|
|
163
|
+
slots.release()
|
|
164
|
+
self.send_json(200, {"result": result})
|
|
165
|
+
|
|
166
|
+
server = ThreadingHTTPServer(("127.0.0.1", port), Handler)
|
|
167
|
+
# Do not discard a paid in-flight helper when the driver fails. Closing
|
|
168
|
+
# this server joins its own authenticated requests before the run exits.
|
|
169
|
+
server.daemon_threads = False
|
|
170
|
+
return server
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class SmartSearchGRPOCoordinatorClient:
|
|
174
|
+
"""Synchronous, JSON-only worker client; failed neural requests never retry."""
|
|
175
|
+
|
|
176
|
+
def __init__(self, endpoint, *, timeout=600):
|
|
177
|
+
try:
|
|
178
|
+
url = urlsplit(endpoint)
|
|
179
|
+
port = url.port
|
|
180
|
+
except (TypeError, ValueError) as exc:
|
|
181
|
+
raise ValidationError("SmartSearch GRPO coordinator URL is invalid") from exc
|
|
182
|
+
if url.scheme != "http" or url.hostname != "127.0.0.1" or not port or (
|
|
183
|
+
url.username or url.password or url.query or url.fragment
|
|
184
|
+
or not re.fullmatch(r"/[A-Za-z0-9_-]{32,128}/rpc", url.path)
|
|
185
|
+
or type(timeout) is not int or not 1 <= timeout <= 3600
|
|
186
|
+
):
|
|
187
|
+
raise ValidationError("SmartSearch GRPO coordinator must be an operator-owned loopback endpoint")
|
|
188
|
+
self.endpoint, self.timeout, self.failed = endpoint, timeout, False
|
|
189
|
+
# Neither proxy settings nor HTTP redirects may move native prompts
|
|
190
|
+
# or the run capability to a remote service.
|
|
191
|
+
class NoRedirect(urllib.request.HTTPRedirectHandler):
|
|
192
|
+
def redirect_request(self, *_args, **_kwargs):
|
|
193
|
+
return None
|
|
194
|
+
self.opener = urllib.request.build_opener(urllib.request.ProxyHandler({}), NoRedirect())
|
|
195
|
+
|
|
196
|
+
def _rpc(self, operation, arguments):
|
|
197
|
+
if self.failed and operation not in {"fail", "settle", "optimizer_end", "worker_completed", "snapshot"}:
|
|
198
|
+
raise ExternalDependencyError("SmartSearch GRPO coordinator request failed; no automatic neural retry")
|
|
199
|
+
raw = json.dumps(to_jsonable(dict(operation=operation, arguments=arguments)), allow_nan=False).encode()
|
|
200
|
+
if len(raw) > _LIMIT:
|
|
201
|
+
raise ValidationError("SmartSearch GRPO RPC input exceeds its byte bound")
|
|
202
|
+
request = urllib.request.Request(self.endpoint, data=raw, headers={"Content-Type": "application/json"}, method="POST")
|
|
203
|
+
try:
|
|
204
|
+
with self.opener.open(request, timeout=self.timeout) as response:
|
|
205
|
+
value = json.loads(response.read(_LIMIT + 1))
|
|
206
|
+
if not isinstance(value, dict) or set(value) != {"result"}:
|
|
207
|
+
raise ExternalDependencyError("SmartSearch GRPO coordinator response schema differs")
|
|
208
|
+
return value["result"]
|
|
209
|
+
except BaseException as exc:
|
|
210
|
+
self.failed = True
|
|
211
|
+
if isinstance(exc, urllib.error.HTTPError):
|
|
212
|
+
try:
|
|
213
|
+
error = json.loads(exc.read(16384))
|
|
214
|
+
except (ValueError, UnicodeError):
|
|
215
|
+
error = {}
|
|
216
|
+
if error.get("error_type") == "BudgetExceededError":
|
|
217
|
+
raise BudgetExceededError("SmartSearch GRPO aggregate coordinator allowance exhausted") from exc
|
|
218
|
+
raise ExternalDependencyError("SmartSearch GRPO coordinator transport failed; no automatic retry") from exc
|
|
219
|
+
|
|
220
|
+
def reserve(self, **arguments):
|
|
221
|
+
return self._rpc("reserve", arguments)
|
|
222
|
+
|
|
223
|
+
def settle(self, ticket, **arguments):
|
|
224
|
+
return self._rpc("settle", {"ticket": ticket, **arguments})
|
|
225
|
+
|
|
226
|
+
def fail(self, ticket, **arguments):
|
|
227
|
+
return self._rpc("fail", {"ticket": ticket, **arguments})
|
|
228
|
+
|
|
229
|
+
def optimizer_begin(self, rank):
|
|
230
|
+
return self._rpc("optimizer_begin", {"rank": rank})
|
|
231
|
+
|
|
232
|
+
def optimizer_end(self, rank):
|
|
233
|
+
return self._rpc("optimizer_end", {"rank": rank})
|
|
234
|
+
|
|
235
|
+
def snapshot(self):
|
|
236
|
+
return self._rpc("snapshot", {})
|
|
237
|
+
|
|
238
|
+
def worker_completed(self, *, rank, role, usage):
|
|
239
|
+
return self._rpc("worker_completed", dict(rank=rank, role=role, usage=usage))
|
|
240
|
+
|
|
241
|
+
def generate(self, prompt, *, temperature, max_new_tokens, stop, seed):
|
|
242
|
+
value = self._rpc("helper", dict(prompt=prompt, temperature=temperature,
|
|
243
|
+
max_new_tokens=max_new_tokens, stop=list(stop), seed=seed))
|
|
244
|
+
try:
|
|
245
|
+
return SmartSearchTeacherCompletion(**value)
|
|
246
|
+
except (TypeError, ValidationError) as exc:
|
|
247
|
+
self.failed = True
|
|
248
|
+
raise ExternalDependencyError("SmartSearch GRPO coordinator omitted typed measured helper usage") from exc
|