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,699 @@
|
|
|
1
|
+
"""Official ToolTalk full-set provider at the pinned Microsoft revision."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import copy
|
|
6
|
+
import hashlib
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
import types
|
|
12
|
+
from collections.abc import Mapping, Sequence
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from ..protocol import (
|
|
17
|
+
OfficialArenaError,
|
|
18
|
+
ProviderArmResult,
|
|
19
|
+
content_hash,
|
|
20
|
+
intervention_usage,
|
|
21
|
+
materialized_state,
|
|
22
|
+
require_materialized_budget,
|
|
23
|
+
resolve_shared_budget_config,
|
|
24
|
+
validate_dependency_hashes,
|
|
25
|
+
visible_shared_budget,
|
|
26
|
+
)
|
|
27
|
+
from ._message_compat import coalesce_chat_system_messages
|
|
28
|
+
|
|
29
|
+
_BUDGET_STOP = "I could not complete the task within the shared run budget."
|
|
30
|
+
_SENT2VEC_REVISION = "c2830440298372a76a5deccdac1b25da71530009"
|
|
31
|
+
_DISTILBERT_REVISION = "12040accade4e8a0f71eabdb258fecc2e7e948be"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _install_sent2vec_compatibility() -> None:
|
|
35
|
+
"""Install pdrm83/sent2vec's exact BERT-CLS path without unused extras.
|
|
36
|
+
|
|
37
|
+
ToolTalk imports ``sent2vec.vectorizer.Vectorizer`` globally, while the
|
|
38
|
+
official package imports gensim and spaCy even though its default runtime
|
|
39
|
+
uses only DistilBERT. This source-locked shim preserves the 0.3.0 default
|
|
40
|
+
algorithm (tokenizer.encode, zero padding, first hidden-state CLS vector)
|
|
41
|
+
and pins the otherwise floating Hugging Face model revision.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
if "sent2vec.vectorizer" in sys.modules:
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
class Vectorizer:
|
|
48
|
+
def __init__(self, pretrained_weights: str = "distilbert-base-uncased", **_: Any):
|
|
49
|
+
if pretrained_weights != "distilbert-base-uncased":
|
|
50
|
+
raise OfficialArenaError("ToolTalk sent2vec model differs")
|
|
51
|
+
import torch
|
|
52
|
+
from transformers import DistilBertModel, DistilBertTokenizer
|
|
53
|
+
|
|
54
|
+
self._torch = torch
|
|
55
|
+
self._device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
56
|
+
self._tokenizer = DistilBertTokenizer.from_pretrained(
|
|
57
|
+
pretrained_weights,
|
|
58
|
+
revision=_DISTILBERT_REVISION,
|
|
59
|
+
)
|
|
60
|
+
self._model = DistilBertModel.from_pretrained(
|
|
61
|
+
pretrained_weights,
|
|
62
|
+
revision=_DISTILBERT_REVISION,
|
|
63
|
+
)
|
|
64
|
+
self.vectors: list[Any] = []
|
|
65
|
+
|
|
66
|
+
def run(self, sentences: list[str], **_: Any) -> None:
|
|
67
|
+
import numpy as np
|
|
68
|
+
|
|
69
|
+
if not isinstance(sentences, list) or any(
|
|
70
|
+
not isinstance(item, str) for item in sentences
|
|
71
|
+
):
|
|
72
|
+
raise TypeError("sent2vec requires a list of strings")
|
|
73
|
+
tokenized = [
|
|
74
|
+
self._tokenizer.encode(item, add_special_tokens=True) for item in sentences
|
|
75
|
+
]
|
|
76
|
+
maximum = max(len(item) for item in tokenized)
|
|
77
|
+
padded = np.array([item + [0] * (maximum - len(item)) for item in tokenized])
|
|
78
|
+
input_ids = self._torch.tensor(padded).type(self._torch.LongTensor).to(self._device)
|
|
79
|
+
model = self._model.to(self._device)
|
|
80
|
+
model.eval()
|
|
81
|
+
with self._torch.no_grad():
|
|
82
|
+
vectors = model(input_ids)[0][:, 0, :].cpu().numpy()
|
|
83
|
+
self.vectors.extend(vectors[index] for index in range(vectors.shape[0]))
|
|
84
|
+
|
|
85
|
+
package = types.ModuleType("sent2vec")
|
|
86
|
+
package.__path__ = [] # type: ignore[attr-defined]
|
|
87
|
+
vectorizer = types.ModuleType("sent2vec.vectorizer")
|
|
88
|
+
vectorizer.Vectorizer = Vectorizer
|
|
89
|
+
package.vectorizer = vectorizer # type: ignore[attr-defined]
|
|
90
|
+
sys.modules["sent2vec"] = package
|
|
91
|
+
sys.modules["sent2vec.vectorizer"] = vectorizer
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _sha256(path: Path) -> str:
|
|
95
|
+
digest = hashlib.sha256()
|
|
96
|
+
with path.open("rb") as handle:
|
|
97
|
+
for block in iter(lambda: handle.read(1024 * 1024), b""):
|
|
98
|
+
digest.update(block)
|
|
99
|
+
return digest.hexdigest()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _system_prompt(metadata: Mapping[str, Any]) -> str:
|
|
103
|
+
return (
|
|
104
|
+
"You are a helpful assistant. Here is some user data:"
|
|
105
|
+
f"\nlocation: {metadata['location']}"
|
|
106
|
+
f"\ntimestamp: {metadata['timestamp']}"
|
|
107
|
+
f"\nusername (if logged in): {metadata.get('username')}"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _tool_schemas() -> list[dict[str, Any]]:
|
|
112
|
+
from tooltalk.apis import ALL_APIS
|
|
113
|
+
|
|
114
|
+
schemas: list[dict[str, Any]] = []
|
|
115
|
+
for api in ALL_APIS:
|
|
116
|
+
legacy = dict(api.to_openai_doc(False))
|
|
117
|
+
required = legacy.pop("required", [])
|
|
118
|
+
parameters = dict(legacy["parameters"])
|
|
119
|
+
parameters["required"] = list(required)
|
|
120
|
+
schemas.append(
|
|
121
|
+
{
|
|
122
|
+
"type": "function",
|
|
123
|
+
"function": {
|
|
124
|
+
"name": legacy["name"],
|
|
125
|
+
"description": legacy["description"],
|
|
126
|
+
"parameters": parameters,
|
|
127
|
+
},
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
return schemas
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class _Predictor:
|
|
134
|
+
"""OpenAI-compatible predictor preserving ToolTalk's official turn loop."""
|
|
135
|
+
|
|
136
|
+
def __init__(
|
|
137
|
+
self,
|
|
138
|
+
*,
|
|
139
|
+
model: str,
|
|
140
|
+
base_url: str,
|
|
141
|
+
api_key: str,
|
|
142
|
+
materialized: Mapping[str, Any],
|
|
143
|
+
budget: Mapping[str, Any],
|
|
144
|
+
optimizer_usage: Mapping[str, int | float],
|
|
145
|
+
seed: int,
|
|
146
|
+
max_output_tokens_per_call: int,
|
|
147
|
+
history_transform: Any = None,
|
|
148
|
+
) -> None:
|
|
149
|
+
from openai import OpenAI
|
|
150
|
+
|
|
151
|
+
self.client = OpenAI(api_key=api_key, base_url=base_url, timeout=600.0, max_retries=0)
|
|
152
|
+
self.model = model
|
|
153
|
+
self.materialized = materialized
|
|
154
|
+
self.seed = seed
|
|
155
|
+
self.tools = _tool_schemas()
|
|
156
|
+
self.first_prediction = True
|
|
157
|
+
self.model_calls = 0
|
|
158
|
+
self.tool_calls = 0
|
|
159
|
+
self.input_tokens = 0
|
|
160
|
+
self.output_tokens = 0
|
|
161
|
+
self.max_model_calls = max(
|
|
162
|
+
0, int(budget["max_model_calls"]) - int(optimizer_usage.get("model_calls", 0))
|
|
163
|
+
)
|
|
164
|
+
self.max_tool_calls = max(
|
|
165
|
+
0, int(budget["max_tool_calls"]) - int(optimizer_usage.get("tool_calls", 0))
|
|
166
|
+
)
|
|
167
|
+
self.max_output_tokens = max(
|
|
168
|
+
0, int(budget["max_output_tokens"]) - int(optimizer_usage.get("output_tokens", 0))
|
|
169
|
+
)
|
|
170
|
+
context_cap = budget.get("max_context_tokens")
|
|
171
|
+
self.max_input_tokens = (
|
|
172
|
+
2**63 - 1
|
|
173
|
+
if context_cap is None
|
|
174
|
+
else max(0, int(context_cap) - int(optimizer_usage.get("input_tokens", 0)))
|
|
175
|
+
)
|
|
176
|
+
self.max_output_tokens_per_call = max_output_tokens_per_call
|
|
177
|
+
self.hard_stops = 0
|
|
178
|
+
self.history_transform = history_transform
|
|
179
|
+
self.history_usage: dict[str, int | float] = {}
|
|
180
|
+
self._history_raw_boundary: list[dict[str, Any]] | None = None
|
|
181
|
+
self._history_logical_boundary: list[dict[str, Any]] | None = None
|
|
182
|
+
|
|
183
|
+
def _history_messages(self, messages: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
184
|
+
if self.history_transform is None:
|
|
185
|
+
return messages
|
|
186
|
+
# ToolTalk's official executor starts every user turn from committed
|
|
187
|
+
# ground-truth history. Predicted tool actions are a temporary rollout,
|
|
188
|
+
# not an append-only extension of that history across user turns. The
|
|
189
|
+
# transformer therefore observes only committed user boundaries; reuse
|
|
190
|
+
# its view plus the exact temporary tool suffix within the same turn.
|
|
191
|
+
if not messages or messages[-1].get("role") != "user":
|
|
192
|
+
raw = self._history_raw_boundary
|
|
193
|
+
logical = self._history_logical_boundary
|
|
194
|
+
if raw is None or logical is None:
|
|
195
|
+
raise OfficialArenaError("ToolTalk live history requires an initial user boundary")
|
|
196
|
+
if len(messages) < len(raw) or messages[:len(raw)] != raw:
|
|
197
|
+
raise OfficialArenaError("ToolTalk temporary tool rollout changed its user boundary")
|
|
198
|
+
result = copy.deepcopy(logical) + copy.deepcopy(messages[len(raw):])
|
|
199
|
+
from agentinputlab.integrations.live_history import _balanced_tool_frames
|
|
200
|
+
if not _balanced_tool_frames(result):
|
|
201
|
+
raise OfficialArenaError("ToolTalk temporary rollout orphaned native tool frames")
|
|
202
|
+
return result
|
|
203
|
+
from agentinputlab.observability import external_usage_counters, normalize_external_usage
|
|
204
|
+
|
|
205
|
+
remaining = {
|
|
206
|
+
"max_model_calls": self.max_model_calls - self.model_calls
|
|
207
|
+
- int(self.history_usage.get("model_calls", 0)),
|
|
208
|
+
"max_output_tokens": self.max_output_tokens - self.output_tokens
|
|
209
|
+
- int(self.history_usage.get("output_tokens", 0)),
|
|
210
|
+
}
|
|
211
|
+
transformed = self.history_transform.transform(
|
|
212
|
+
copy.deepcopy(messages), state=copy.deepcopy(self.materialized),
|
|
213
|
+
remaining_budget=dict(remaining),
|
|
214
|
+
)
|
|
215
|
+
if not isinstance(transformed, Mapping) or set(transformed) != {"messages", "usage"}:
|
|
216
|
+
raise OfficialArenaError("ToolTalk history transform response fields differ")
|
|
217
|
+
raw_usage = transformed["usage"]
|
|
218
|
+
if not isinstance(raw_usage, Mapping) or not {"model_calls", "output_tokens"} <= raw_usage.keys():
|
|
219
|
+
raise OfficialArenaError("ToolTalk history transform requires actual call/output usage")
|
|
220
|
+
if raw_usage["model_calls"] and not {"input_tokens", "retrieval_calls"} <= raw_usage.keys():
|
|
221
|
+
raise OfficialArenaError("ToolTalk history model calls require complete actual usage")
|
|
222
|
+
usage = external_usage_counters(normalize_external_usage({
|
|
223
|
+
"model_calls": 0, "retrieval_calls": 0, "input_tokens": 0, "output_tokens": 0,
|
|
224
|
+
**raw_usage,
|
|
225
|
+
}))
|
|
226
|
+
if not usage["model_calls"] and (usage["input_tokens"] or usage["output_tokens"]):
|
|
227
|
+
raise OfficialArenaError("ToolTalk skipped history transform cannot report model tokens")
|
|
228
|
+
for key, value in usage.items():
|
|
229
|
+
self.history_usage[key] = self.history_usage.get(key, 0) + value
|
|
230
|
+
if usage["tool_calls"] or usage["retrieval_calls"] or usage["embedding_calls"]:
|
|
231
|
+
raise OfficialArenaError("ToolTalk history transform cannot execute tools or retrieval")
|
|
232
|
+
if usage["model_calls"] >= remaining["max_model_calls"] or usage["output_tokens"] >= remaining["max_output_tokens"]:
|
|
233
|
+
raise OfficialArenaError("ToolTalk history transform failed to reserve downstream budget")
|
|
234
|
+
result = transformed["messages"]
|
|
235
|
+
if not isinstance(result, (list, tuple)) or len(result) < 2 or any(
|
|
236
|
+
not isinstance(row, Mapping) or not isinstance(row.get("role"), str)
|
|
237
|
+
for row in result
|
|
238
|
+
):
|
|
239
|
+
raise OfficialArenaError("ToolTalk history transform messages are invalid")
|
|
240
|
+
if result[0]["role"] != "system" or result[1]["role"] != "user":
|
|
241
|
+
raise OfficialArenaError("ToolTalk history transform must preserve system/user session framing")
|
|
242
|
+
from agentinputlab.integrations.live_history import _balanced_tool_frames
|
|
243
|
+
if not _balanced_tool_frames(result):
|
|
244
|
+
raise OfficialArenaError("ToolTalk history transform orphaned native tool frames")
|
|
245
|
+
self._history_raw_boundary = copy.deepcopy(messages)
|
|
246
|
+
self._history_logical_boundary = copy.deepcopy([dict(row) for row in result])
|
|
247
|
+
return copy.deepcopy(self._history_logical_boundary)
|
|
248
|
+
|
|
249
|
+
def _messages(
|
|
250
|
+
self,
|
|
251
|
+
metadata: Mapping[str, Any],
|
|
252
|
+
history: Sequence[Mapping[str, Any]],
|
|
253
|
+
) -> list[dict[str, Any]]:
|
|
254
|
+
additions = [str(self.materialized.get("instruction", ""))]
|
|
255
|
+
additions.extend(
|
|
256
|
+
str(item.get("text", ""))
|
|
257
|
+
for item in self.materialized.get("context", [])
|
|
258
|
+
if isinstance(item, Mapping)
|
|
259
|
+
)
|
|
260
|
+
official = _system_prompt(metadata)
|
|
261
|
+
injected = "\n\n".join(item for item in additions if item and item != official)
|
|
262
|
+
system = official if not injected else official + "\n\n" + injected
|
|
263
|
+
messages: list[dict[str, Any]] = [{"role": "system", "content": system}]
|
|
264
|
+
first_user = True
|
|
265
|
+
tool_index = 0
|
|
266
|
+
for turn in history:
|
|
267
|
+
role = turn.get("role")
|
|
268
|
+
if role in {"user", "assistant"}:
|
|
269
|
+
text = turn.get("text", "")
|
|
270
|
+
if role == "user" and first_user:
|
|
271
|
+
text = self.materialized["query"]
|
|
272
|
+
first_user = False
|
|
273
|
+
messages.append({"role": role, "content": str(text)})
|
|
274
|
+
elif role == "api":
|
|
275
|
+
tool_index += 1
|
|
276
|
+
call_id = f"tooltalk_{tool_index:03d}"
|
|
277
|
+
request = turn["request"]
|
|
278
|
+
messages.append(
|
|
279
|
+
{
|
|
280
|
+
"role": "assistant",
|
|
281
|
+
"content": None,
|
|
282
|
+
"tool_calls": [
|
|
283
|
+
{
|
|
284
|
+
"id": call_id,
|
|
285
|
+
"type": "function",
|
|
286
|
+
"function": {
|
|
287
|
+
"name": request["api_name"],
|
|
288
|
+
"arguments": json.dumps(
|
|
289
|
+
request["parameters"],
|
|
290
|
+
ensure_ascii=False,
|
|
291
|
+
sort_keys=True,
|
|
292
|
+
),
|
|
293
|
+
},
|
|
294
|
+
}
|
|
295
|
+
],
|
|
296
|
+
}
|
|
297
|
+
)
|
|
298
|
+
messages.append(
|
|
299
|
+
{
|
|
300
|
+
"role": "tool",
|
|
301
|
+
"tool_call_id": call_id,
|
|
302
|
+
"content": json.dumps(
|
|
303
|
+
{
|
|
304
|
+
"response": turn.get("response"),
|
|
305
|
+
"exception": turn.get("exception"),
|
|
306
|
+
},
|
|
307
|
+
ensure_ascii=False,
|
|
308
|
+
sort_keys=True,
|
|
309
|
+
),
|
|
310
|
+
}
|
|
311
|
+
)
|
|
312
|
+
return coalesce_chat_system_messages(messages)
|
|
313
|
+
|
|
314
|
+
def __call__(
|
|
315
|
+
self,
|
|
316
|
+
metadata: Mapping[str, Any],
|
|
317
|
+
history: Sequence[Mapping[str, Any]],
|
|
318
|
+
) -> Mapping[str, Any]:
|
|
319
|
+
visible_metadata = self.materialized.get("metadata", {})
|
|
320
|
+
clarification = (
|
|
321
|
+
visible_metadata.get("clarification_request")
|
|
322
|
+
if isinstance(visible_metadata, Mapping)
|
|
323
|
+
else None
|
|
324
|
+
)
|
|
325
|
+
if self.first_prediction and isinstance(clarification, str) and clarification.strip():
|
|
326
|
+
self.first_prediction = False
|
|
327
|
+
return {"role": "assistant", "text": clarification}
|
|
328
|
+
self.first_prediction = False
|
|
329
|
+
|
|
330
|
+
remaining_output = self.max_output_tokens - self.output_tokens - int(self.history_usage.get("output_tokens", 0))
|
|
331
|
+
if self.model_calls + self.history_usage.get("model_calls", 0) >= self.max_model_calls or remaining_output < 1:
|
|
332
|
+
self.hard_stops += 1
|
|
333
|
+
return {"role": "assistant", "text": _BUDGET_STOP}
|
|
334
|
+
messages = self._messages(metadata, history)
|
|
335
|
+
messages = self._history_messages(messages)
|
|
336
|
+
remaining_output = self.max_output_tokens - self.output_tokens - int(self.history_usage.get("output_tokens", 0))
|
|
337
|
+
if self.input_tokens + self.history_usage.get("input_tokens", 0) > self.max_input_tokens:
|
|
338
|
+
self.hard_stops += 1
|
|
339
|
+
return {"role": "assistant", "text": _BUDGET_STOP}
|
|
340
|
+
response = self.client.chat.completions.create(
|
|
341
|
+
model=self.model,
|
|
342
|
+
messages=messages,
|
|
343
|
+
tools=self.tools,
|
|
344
|
+
tool_choice="auto",
|
|
345
|
+
parallel_tool_calls=False,
|
|
346
|
+
temperature=0,
|
|
347
|
+
seed=self.seed + self.model_calls,
|
|
348
|
+
max_tokens=min(
|
|
349
|
+
self.max_output_tokens_per_call,
|
|
350
|
+
remaining_output,
|
|
351
|
+
),
|
|
352
|
+
extra_body={"chat_template_kwargs": {"enable_thinking": False}},
|
|
353
|
+
)
|
|
354
|
+
self.model_calls += 1
|
|
355
|
+
usage = getattr(response, "usage", None)
|
|
356
|
+
self.input_tokens += int(getattr(usage, "prompt_tokens", 0) or 0)
|
|
357
|
+
self.output_tokens += int(getattr(usage, "completion_tokens", 0) or 0)
|
|
358
|
+
if (self.input_tokens + self.history_usage.get("input_tokens", 0) > self.max_input_tokens
|
|
359
|
+
or self.output_tokens + self.history_usage.get("output_tokens", 0) > self.max_output_tokens):
|
|
360
|
+
self.hard_stops += 1
|
|
361
|
+
return {"role": "assistant", "text": _BUDGET_STOP}
|
|
362
|
+
message = response.choices[0].message
|
|
363
|
+
calls = list(message.tool_calls or ())
|
|
364
|
+
if calls:
|
|
365
|
+
if self.tool_calls >= self.max_tool_calls:
|
|
366
|
+
self.hard_stops += 1
|
|
367
|
+
return {"role": "assistant", "text": _BUDGET_STOP}
|
|
368
|
+
call = calls[0]
|
|
369
|
+
self.tool_calls += 1
|
|
370
|
+
try:
|
|
371
|
+
parameters = json.loads(call.function.arguments)
|
|
372
|
+
if not isinstance(parameters, dict):
|
|
373
|
+
parameters = None
|
|
374
|
+
except (TypeError, json.JSONDecodeError):
|
|
375
|
+
parameters = None
|
|
376
|
+
return {
|
|
377
|
+
"role": "api",
|
|
378
|
+
"request": {
|
|
379
|
+
"api_name": call.function.name,
|
|
380
|
+
"parameters": parameters,
|
|
381
|
+
},
|
|
382
|
+
"metadata": {
|
|
383
|
+
"model": self.model,
|
|
384
|
+
"finish_reason": response.choices[0].finish_reason,
|
|
385
|
+
},
|
|
386
|
+
}
|
|
387
|
+
return {"role": "assistant", "text": message.content or ""}
|
|
388
|
+
|
|
389
|
+
def usage(self) -> dict[str, int | float]:
|
|
390
|
+
usage = {
|
|
391
|
+
"model_calls": self.model_calls,
|
|
392
|
+
"tool_calls": self.tool_calls,
|
|
393
|
+
"input_tokens": self.input_tokens,
|
|
394
|
+
"output_tokens": self.output_tokens,
|
|
395
|
+
"cost_usd": 0.0,
|
|
396
|
+
"unpriced_model_calls": self.model_calls,
|
|
397
|
+
}
|
|
398
|
+
for key, value in self.history_usage.items():
|
|
399
|
+
usage[key] = usage.get(key, 0) + value
|
|
400
|
+
return usage
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
class ToolTalkProvider:
|
|
404
|
+
benchmark_id = "tooltalk.full"
|
|
405
|
+
source_revision = "e05f4ce6132c80ed33392b81535b077d56ab28fd"
|
|
406
|
+
scorer_id = "tooltalk.official_conversation_success.v1"
|
|
407
|
+
scorer_revision = "122fb0872f116c9a3b531ea24ba3d1b19bd8c75e4785863dfb4add9617fa157e"
|
|
408
|
+
conversation_set_sha256 = (
|
|
409
|
+
"ce9a691f52830a3aef7e5c0665bf30676c536bfdd0ffb0e534770d10d793227d"
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
_REQUIRED = frozenset(
|
|
413
|
+
{
|
|
414
|
+
"dataset_parts",
|
|
415
|
+
"limit",
|
|
416
|
+
"api_mode",
|
|
417
|
+
"agent_model",
|
|
418
|
+
"agent_base_url",
|
|
419
|
+
"agent_key_env",
|
|
420
|
+
"locked_dependency_hashes",
|
|
421
|
+
}
|
|
422
|
+
)
|
|
423
|
+
_OPTIONAL = frozenset({"budget_override"})
|
|
424
|
+
|
|
425
|
+
def __init__(self, *, history_transform: Any = None) -> None:
|
|
426
|
+
if history_transform is not None and not all(
|
|
427
|
+
callable(getattr(history_transform, name, None)) for name in ("transform", "fingerprint")
|
|
428
|
+
):
|
|
429
|
+
raise OfficialArenaError("ToolTalk history transform requires transform and fingerprint")
|
|
430
|
+
self.history_transform = history_transform
|
|
431
|
+
|
|
432
|
+
def doctor(self, config: Mapping[str, Any]) -> tuple[str, ...]:
|
|
433
|
+
try:
|
|
434
|
+
self._validate_config(config)
|
|
435
|
+
head = subprocess.check_output(
|
|
436
|
+
["git", "rev-parse", "HEAD"],
|
|
437
|
+
text=True,
|
|
438
|
+
stderr=subprocess.DEVNULL,
|
|
439
|
+
).strip()
|
|
440
|
+
if head != self.source_revision:
|
|
441
|
+
raise OfficialArenaError("ToolTalk checkout revision differs")
|
|
442
|
+
_install_sent2vec_compatibility()
|
|
443
|
+
from tooltalk.apis import ALL_APIS
|
|
444
|
+
from tooltalk.evaluation.tool_executor import ToolExecutor
|
|
445
|
+
|
|
446
|
+
if len(ALL_APIS) != 28:
|
|
447
|
+
raise OfficialArenaError("ToolTalk official tool catalog differs")
|
|
448
|
+
counts = {part: len(list((Path("data") / part).glob("*.json"))) for part in ("easy", "tooltalk")}
|
|
449
|
+
if counts != {"easy": 28, "tooltalk": 50}:
|
|
450
|
+
raise OfficialArenaError("ToolTalk full-set inventory differs")
|
|
451
|
+
ToolExecutor(init_database_dir="data/databases")
|
|
452
|
+
except Exception as exc:
|
|
453
|
+
return (f"{type(exc).__name__}: {exc}",)
|
|
454
|
+
return ()
|
|
455
|
+
|
|
456
|
+
def capture(
|
|
457
|
+
self,
|
|
458
|
+
config: Mapping[str, Any],
|
|
459
|
+
*,
|
|
460
|
+
output_root: Path,
|
|
461
|
+
) -> tuple[Mapping[str, Any], ...]:
|
|
462
|
+
del output_root
|
|
463
|
+
parsed = self._validate_config(config)
|
|
464
|
+
_install_sent2vec_compatibility()
|
|
465
|
+
schemas = _tool_schemas()
|
|
466
|
+
tool_names = [item["function"]["name"] for item in schemas]
|
|
467
|
+
rows: list[Mapping[str, Any]] = []
|
|
468
|
+
for part in parsed["dataset_parts"]:
|
|
469
|
+
for path in sorted((Path("data") / part).glob("*.json")):
|
|
470
|
+
raw = path.read_bytes()
|
|
471
|
+
conversation = json.loads(raw)
|
|
472
|
+
opening = conversation["conversation"][0]
|
|
473
|
+
if opening.get("role") != "user":
|
|
474
|
+
raise OfficialArenaError("ToolTalk conversation has no opening user turn")
|
|
475
|
+
checkpoint_id = f"{part}:{conversation['conversation_id']}"
|
|
476
|
+
instruction = _system_prompt(conversation["metadata"])
|
|
477
|
+
visible_state = {
|
|
478
|
+
"query": opening["text"],
|
|
479
|
+
"task_id": checkpoint_id,
|
|
480
|
+
"instruction": instruction,
|
|
481
|
+
"context": [
|
|
482
|
+
{
|
|
483
|
+
"text": json.dumps(schemas, ensure_ascii=False, sort_keys=True),
|
|
484
|
+
"block_id": "official_tool_catalog",
|
|
485
|
+
"source": "tooltalk.apis.ALL_APIS",
|
|
486
|
+
"score": None,
|
|
487
|
+
"metadata": {"api_mode": "all"},
|
|
488
|
+
}
|
|
489
|
+
],
|
|
490
|
+
"messages": [
|
|
491
|
+
{"role": "user", "content": opening["text"], "name": None}
|
|
492
|
+
],
|
|
493
|
+
"tool_names": tool_names,
|
|
494
|
+
"metadata": {
|
|
495
|
+
"benchmark_id": self.benchmark_id,
|
|
496
|
+
"difficulty": part,
|
|
497
|
+
"conversation_id": conversation["conversation_id"],
|
|
498
|
+
"checkpoint_phase": "turn_zero",
|
|
499
|
+
"clarification_roundtrip_available": True,
|
|
500
|
+
"state_restore_available": True,
|
|
501
|
+
},
|
|
502
|
+
"budget": visible_shared_budget(
|
|
503
|
+
parsed,
|
|
504
|
+
{
|
|
505
|
+
"max_model_calls": 16,
|
|
506
|
+
"max_retrieval_calls": 8,
|
|
507
|
+
"max_tool_calls": 9,
|
|
508
|
+
"max_output_tokens": 8192,
|
|
509
|
+
"max_context_tokens": None,
|
|
510
|
+
"max_cost_usd": None,
|
|
511
|
+
},
|
|
512
|
+
),
|
|
513
|
+
}
|
|
514
|
+
rows.append(
|
|
515
|
+
{
|
|
516
|
+
"checkpoint_id": checkpoint_id,
|
|
517
|
+
"group_key": checkpoint_id,
|
|
518
|
+
"visible_state": visible_state,
|
|
519
|
+
"eligible_families": [
|
|
520
|
+
"reformulate",
|
|
521
|
+
"decompose",
|
|
522
|
+
"acquire",
|
|
523
|
+
"clarify",
|
|
524
|
+
"curate",
|
|
525
|
+
],
|
|
526
|
+
"protected": {
|
|
527
|
+
"dataset_part": part,
|
|
528
|
+
"relative_path": path.as_posix(),
|
|
529
|
+
"conversation_sha256": hashlib.sha256(raw).hexdigest(),
|
|
530
|
+
"conversation_id": conversation["conversation_id"],
|
|
531
|
+
"locked_dependency_hashes": parsed["locked_dependency_hashes"],
|
|
532
|
+
},
|
|
533
|
+
}
|
|
534
|
+
)
|
|
535
|
+
if len(rows) >= parsed["limit"]:
|
|
536
|
+
return tuple(rows)
|
|
537
|
+
if not rows:
|
|
538
|
+
raise OfficialArenaError("ToolTalk capture found no conversations")
|
|
539
|
+
return tuple(rows)
|
|
540
|
+
|
|
541
|
+
def run_arm(
|
|
542
|
+
self,
|
|
543
|
+
config: Mapping[str, Any],
|
|
544
|
+
*,
|
|
545
|
+
replay_record: Mapping[str, Any],
|
|
546
|
+
arm_payload: Mapping[str, Any],
|
|
547
|
+
seed: int,
|
|
548
|
+
role: str,
|
|
549
|
+
work_dir: Path,
|
|
550
|
+
) -> ProviderArmResult:
|
|
551
|
+
parsed = self._validate_config(config)
|
|
552
|
+
prediction_path = work_dir / "predicted-conversation.json"
|
|
553
|
+
evaluation_path = work_dir / "native-evaluation.json"
|
|
554
|
+
trajectory_path = work_dir / "trajectory.json"
|
|
555
|
+
history_path = work_dir / "live-history.json"
|
|
556
|
+
artifacts = (prediction_path, evaluation_path, trajectory_path)
|
|
557
|
+
if self.history_transform is not None:
|
|
558
|
+
artifacts += (history_path,)
|
|
559
|
+
if any(path.exists() for path in artifacts):
|
|
560
|
+
raise OfficialArenaError("ToolTalk requires a fresh work directory")
|
|
561
|
+
state = materialized_state(arm_payload)
|
|
562
|
+
budget = require_materialized_budget(state, parsed)
|
|
563
|
+
optimizer_usage = intervention_usage(arm_payload)
|
|
564
|
+
protected = replay_record["protected"]
|
|
565
|
+
path = Path(protected["relative_path"])
|
|
566
|
+
raw = path.read_bytes()
|
|
567
|
+
if _sha256(path) != protected["conversation_sha256"]:
|
|
568
|
+
raise OfficialArenaError("ToolTalk protected conversation differs")
|
|
569
|
+
conversation = json.loads(raw)
|
|
570
|
+
if conversation.get("conversation_id") != protected["conversation_id"]:
|
|
571
|
+
raise OfficialArenaError("ToolTalk protected conversation identity differs")
|
|
572
|
+
api_key = os.environ.get(parsed["agent_key_env"])
|
|
573
|
+
if not api_key:
|
|
574
|
+
raise OfficialArenaError(
|
|
575
|
+
f"ToolTalk environment {parsed['agent_key_env']} is missing"
|
|
576
|
+
)
|
|
577
|
+
override = parsed.get("budget_override")
|
|
578
|
+
per_call_cap = (
|
|
579
|
+
int(override["max_output_tokens_per_call"])
|
|
580
|
+
if isinstance(override, Mapping)
|
|
581
|
+
else 512
|
|
582
|
+
)
|
|
583
|
+
# Fresh execution processes need the pinned import shim before the
|
|
584
|
+
# predictor imports tooltalk.apis; capture()/doctor() need not precede
|
|
585
|
+
# every restored native episode in the same Python process.
|
|
586
|
+
_install_sent2vec_compatibility()
|
|
587
|
+
predictor = _Predictor(
|
|
588
|
+
model=parsed["agent_model"],
|
|
589
|
+
base_url=parsed["agent_base_url"],
|
|
590
|
+
api_key=api_key,
|
|
591
|
+
materialized=state,
|
|
592
|
+
budget=budget,
|
|
593
|
+
optimizer_usage=optimizer_usage,
|
|
594
|
+
seed=seed,
|
|
595
|
+
max_output_tokens_per_call=per_call_cap,
|
|
596
|
+
history_transform=self.history_transform,
|
|
597
|
+
)
|
|
598
|
+
from tooltalk.evaluation.tool_executor import ToolExecutor
|
|
599
|
+
|
|
600
|
+
executor = ToolExecutor(init_database_dir="data/databases")
|
|
601
|
+
try:
|
|
602
|
+
evaluated = executor.run_conversation(copy.deepcopy(conversation), predictor)
|
|
603
|
+
finally:
|
|
604
|
+
if self.history_transform is not None:
|
|
605
|
+
with history_path.open("x", encoding="utf-8") as handle:
|
|
606
|
+
json.dump({
|
|
607
|
+
"fingerprint": self.history_transform.fingerprint(),
|
|
608
|
+
"records": list(getattr(self.history_transform, "records", ())),
|
|
609
|
+
"history_usage": predictor.history_usage,
|
|
610
|
+
"agent_and_history_usage": predictor.usage(),
|
|
611
|
+
"original_shared_budget": dict(budget),
|
|
612
|
+
"native_boundary_protocol": "tooltalk.committed_user_turns.v1",
|
|
613
|
+
}, handle, ensure_ascii=False, sort_keys=True, indent=2, allow_nan=False)
|
|
614
|
+
handle.write("\n")
|
|
615
|
+
# Preserve the actual episode before scoring, including scorer failures.
|
|
616
|
+
# Exclusive creation keeps an earlier attempt's evidence immutable.
|
|
617
|
+
with prediction_path.open("x", encoding="utf-8") as handle:
|
|
618
|
+
json.dump(evaluated, handle, ensure_ascii=False, indent=2, sort_keys=True,
|
|
619
|
+
allow_nan=False)
|
|
620
|
+
handle.write("\n")
|
|
621
|
+
evaluated = executor.evaluate_predictions(evaluated)
|
|
622
|
+
with evaluation_path.open("x", encoding="utf-8") as handle:
|
|
623
|
+
json.dump(evaluated, handle, ensure_ascii=False, indent=2, sort_keys=True,
|
|
624
|
+
allow_nan=False)
|
|
625
|
+
handle.write("\n")
|
|
626
|
+
metrics = evaluated["metrics"]
|
|
627
|
+
trace = {
|
|
628
|
+
"provider": "tooltalk",
|
|
629
|
+
"source_revision": self.source_revision,
|
|
630
|
+
"conversation_id": protected["conversation_id"],
|
|
631
|
+
"dataset_part": protected["dataset_part"],
|
|
632
|
+
"role": role,
|
|
633
|
+
"seed": seed,
|
|
634
|
+
"metrics": metrics,
|
|
635
|
+
"generation_controls": {
|
|
636
|
+
"hard_stops": predictor.hard_stops,
|
|
637
|
+
"shared_budget": dict(budget),
|
|
638
|
+
"optimizer_usage": dict(optimizer_usage),
|
|
639
|
+
},
|
|
640
|
+
"prediction_trace_sha256": content_hash(evaluated["conversation"]),
|
|
641
|
+
"native_artifacts": {
|
|
642
|
+
"prediction": {"path": prediction_path.name, "sha256": _sha256(prediction_path)},
|
|
643
|
+
"evaluation": {"path": evaluation_path.name, "sha256": _sha256(evaluation_path)},
|
|
644
|
+
},
|
|
645
|
+
}
|
|
646
|
+
if self.history_transform is not None:
|
|
647
|
+
trace["live_history_transform"] = self.history_transform.fingerprint()
|
|
648
|
+
trace["live_history_artifact"] = {"path": history_path.name, "sha256": _sha256(history_path)}
|
|
649
|
+
trace["live_history_boundary_protocol"] = "tooltalk.committed_user_turns.v1"
|
|
650
|
+
with trajectory_path.open("x", encoding="utf-8") as handle:
|
|
651
|
+
json.dump(trace, handle, ensure_ascii=False, indent=2, sort_keys=True,
|
|
652
|
+
allow_nan=False)
|
|
653
|
+
handle.write("\n")
|
|
654
|
+
return ProviderArmResult(
|
|
655
|
+
metrics={
|
|
656
|
+
"official_success": float(metrics["success"]),
|
|
657
|
+
"precision": float(metrics["precision"]),
|
|
658
|
+
"recall": float(metrics["recall"]),
|
|
659
|
+
"action_precision": float(metrics["action_precision"]),
|
|
660
|
+
"bad_action_rate": float(metrics["bad_action_rate"]),
|
|
661
|
+
"soft_success": float(metrics["soft_success"]),
|
|
662
|
+
"adapter_hard_stops": float(predictor.hard_stops),
|
|
663
|
+
},
|
|
664
|
+
trace=trace,
|
|
665
|
+
usage=predictor.usage(),
|
|
666
|
+
runtime_instance_id=content_hash(
|
|
667
|
+
{
|
|
668
|
+
"provider": "tooltalk",
|
|
669
|
+
"checkpoint_id": replay_record["checkpoint_id"],
|
|
670
|
+
"role": role,
|
|
671
|
+
"seed": seed,
|
|
672
|
+
"work_dir": str(work_dir),
|
|
673
|
+
}
|
|
674
|
+
),
|
|
675
|
+
)
|
|
676
|
+
|
|
677
|
+
def _validate_config(self, config: Mapping[str, Any]) -> Mapping[str, Any]:
|
|
678
|
+
config = resolve_shared_budget_config(config)
|
|
679
|
+
if not isinstance(config, Mapping) or set(config) not in {
|
|
680
|
+
self._REQUIRED,
|
|
681
|
+
self._REQUIRED | self._OPTIONAL,
|
|
682
|
+
}:
|
|
683
|
+
raise OfficialArenaError("ToolTalk provider config fields are invalid")
|
|
684
|
+
if list(config["dataset_parts"]) != ["easy", "tooltalk"]:
|
|
685
|
+
raise OfficialArenaError("ToolTalk full set must use easy then tooltalk")
|
|
686
|
+
limit = config["limit"]
|
|
687
|
+
if isinstance(limit, bool) or not isinstance(limit, int) or not 1 <= limit <= 78:
|
|
688
|
+
raise OfficialArenaError("ToolTalk limit must be between 1 and 78")
|
|
689
|
+
if config["api_mode"] != "all":
|
|
690
|
+
raise OfficialArenaError("ToolTalk paper protocol requires api_mode=all")
|
|
691
|
+
for name in ("agent_model", "agent_base_url", "agent_key_env"):
|
|
692
|
+
if not isinstance(config[name], str) or not config[name].strip():
|
|
693
|
+
raise OfficialArenaError(f"ToolTalk {name} is invalid")
|
|
694
|
+
validate_dependency_hashes(config["locked_dependency_hashes"], label="ToolTalk")
|
|
695
|
+
return config
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
def factory() -> ToolTalkProvider:
|
|
699
|
+
return ToolTalkProvider()
|