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,360 @@
|
|
|
1
|
+
"""Live, context-bound callbacks for the isolated pinned LLMCompiler worker.
|
|
2
|
+
|
|
3
|
+
The worker process has no provider credential or request-selected network tool.
|
|
4
|
+
A per-call authenticated loopback endpoint exposes only the already bound model
|
|
5
|
+
and read-only ToolConnector. The ordinary supervisor still bounds its process
|
|
6
|
+
and pipes. Caller backends/tools remain responsible for their own I/O timeouts.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import hmac
|
|
11
|
+
import json
|
|
12
|
+
import math
|
|
13
|
+
import os
|
|
14
|
+
import secrets
|
|
15
|
+
import threading
|
|
16
|
+
from collections.abc import Mapping
|
|
17
|
+
from contextlib import suppress
|
|
18
|
+
from dataclasses import dataclass, field
|
|
19
|
+
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
from agentinputlab.backends import GenerationRequest, LLMBackend
|
|
24
|
+
from agentinputlab.connectors.tools import ToolCall, ToolConnector
|
|
25
|
+
from agentinputlab.connectors.tools.openapi import validate_json_value
|
|
26
|
+
from agentinputlab.contracts import ExecutionBudget, ValidationError
|
|
27
|
+
from agentinputlab.contracts.serialization import content_hash, to_jsonable
|
|
28
|
+
|
|
29
|
+
from .base import JsonLineSubprocessWorker
|
|
30
|
+
from .supervisor import SupervisedWorkerError
|
|
31
|
+
|
|
32
|
+
_KEY_ENV = "AGENTINPUTLAB_LLMC_CALLBACK_KEY"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _strict_json(raw):
|
|
36
|
+
def unique(pairs):
|
|
37
|
+
result = {}
|
|
38
|
+
for key, value in pairs:
|
|
39
|
+
if key in result:
|
|
40
|
+
raise ValueError("duplicate JSON key")
|
|
41
|
+
result[key] = value
|
|
42
|
+
return result
|
|
43
|
+
return json.loads(raw, object_pairs_hook=unique,
|
|
44
|
+
parse_constant=lambda value: (_ for _ in ()).throw(ValueError("nonfinite JSON")))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class _Callbacks:
|
|
48
|
+
def __init__(self, owner, request):
|
|
49
|
+
self.owner, self.request = owner, request
|
|
50
|
+
budget = request["payload"].get("execution_budget")
|
|
51
|
+
if not isinstance(budget, Mapping):
|
|
52
|
+
raise ValidationError("live LLMCompiler requires the state execution_budget")
|
|
53
|
+
self.budget = ExecutionBudget(**budget)
|
|
54
|
+
if self.budget.max_context_tokens is not None or self.budget.max_cost_usd is not None:
|
|
55
|
+
raise ValidationError("live callbacks do not yet attest pre-call input-token or priced-cost ceilings")
|
|
56
|
+
self.specs = {s.name: s for s in owner.tools.list_tools()}
|
|
57
|
+
self.argument_order = {name: tuple(keys) for name, keys in owner.argument_order.items()}
|
|
58
|
+
if to_jsonable(owner.argument_order) != request["payload"].get("tool_argument_order", {}):
|
|
59
|
+
raise ValidationError("tool positional argument order differs from the request")
|
|
60
|
+
if not self.specs or any(not s.read_only or s.network for s in self.specs.values()):
|
|
61
|
+
raise ValidationError("live LLMCompiler tools must be read-only and no-network")
|
|
62
|
+
if to_jsonable(tuple(self.specs.values())) != request["payload"]["tool_specs"]:
|
|
63
|
+
raise ValidationError("live tool schemas differ from the request")
|
|
64
|
+
deps = request["dependency_fingerprints"]
|
|
65
|
+
if (content_hash(deps["backend"]) != content_hash(owner.backend.fingerprint())
|
|
66
|
+
or content_hash(deps["tools"]) != content_hash(owner.tools.fingerprint())):
|
|
67
|
+
raise ValidationError("live dependencies differ from the request")
|
|
68
|
+
self.lock = threading.RLock()
|
|
69
|
+
self.model_calls = self.tool_calls = self.input_tokens = self.output_tokens = 0
|
|
70
|
+
self.reserved_output = self.inflight = self.unknown_usage_calls = 0
|
|
71
|
+
self.cost = 0.0
|
|
72
|
+
self.unpriced = 0
|
|
73
|
+
self.closed = self.fatal = False
|
|
74
|
+
self.attested = False
|
|
75
|
+
self.expected_attestation = owner.fingerprint()["worker_attestation"]
|
|
76
|
+
self.seen = set()
|
|
77
|
+
self.events = []
|
|
78
|
+
|
|
79
|
+
def usage(self):
|
|
80
|
+
with self.lock:
|
|
81
|
+
result = {"model_calls": self.model_calls, "tool_calls": self.tool_calls,
|
|
82
|
+
"retrieval_calls": 0, "input_tokens": self.input_tokens,
|
|
83
|
+
"output_tokens": self.output_tokens,
|
|
84
|
+
"unpriced_model_calls": self.model_calls if self.unpriced else 0}
|
|
85
|
+
if self.unpriced == 0:
|
|
86
|
+
result["cost_usd"] = self.cost
|
|
87
|
+
return result
|
|
88
|
+
|
|
89
|
+
def dispatch(self, value):
|
|
90
|
+
if (not isinstance(value, dict) or set(value) != {"request_id", "call_id", "kind", "payload"}
|
|
91
|
+
or value["request_id"] != self.request["request_id"]
|
|
92
|
+
or not isinstance(value["call_id"], str) or not value["call_id"]):
|
|
93
|
+
raise ValueError("invalid callback envelope")
|
|
94
|
+
with self.lock:
|
|
95
|
+
if self.closed or self.fatal or value["call_id"] in self.seen:
|
|
96
|
+
raise ValueError("closed, failed, or duplicate callback")
|
|
97
|
+
self.seen.add(value["call_id"])
|
|
98
|
+
if value["kind"] == "attest":
|
|
99
|
+
if self.attested or value["payload"] != self.expected_attestation:
|
|
100
|
+
raise ValueError("worker source/version attestation differs")
|
|
101
|
+
self.attested = True
|
|
102
|
+
self.events.append({"kind": "attestation", "matched": True})
|
|
103
|
+
return {"attested": True}
|
|
104
|
+
if not self.attested:
|
|
105
|
+
raise ValueError("native worker must attest before model/tool dispatch")
|
|
106
|
+
if value["kind"] == "model":
|
|
107
|
+
return self.model(value["payload"])
|
|
108
|
+
if value["kind"] == "tool":
|
|
109
|
+
return self.tool(value["payload"])
|
|
110
|
+
raise ValueError("unknown callback kind")
|
|
111
|
+
|
|
112
|
+
def model(self, value):
|
|
113
|
+
if (not isinstance(value, dict) or set(value) != {"prompt", "channel", "stop", "seed"}
|
|
114
|
+
or value["channel"] not in {"planner", "join"}
|
|
115
|
+
or value["seed"] != self.request["payload"]["seed"]
|
|
116
|
+
or not isinstance(value["prompt"], str) or not value["prompt"]
|
|
117
|
+
or not isinstance(value["stop"], list)
|
|
118
|
+
or not all(isinstance(s, str) and s for s in value["stop"])):
|
|
119
|
+
raise ValueError("invalid live model request")
|
|
120
|
+
cap = self.owner.per_call_output_cap
|
|
121
|
+
request = GenerationRequest(prompt=value["prompt"], seed=value["seed"],
|
|
122
|
+
stop=tuple(value["stop"]), max_tokens=cap, temperature=0.0,
|
|
123
|
+
metadata={"method_id": "llm_compiler", "stage": value["channel"],
|
|
124
|
+
"transport_profile": "controlled_host_callback_v1"})
|
|
125
|
+
with self.lock:
|
|
126
|
+
if (self.fatal or self.closed or self.model_calls >= self.budget.max_model_calls
|
|
127
|
+
or self.output_tokens + self.reserved_output + cap > self.budget.max_output_tokens):
|
|
128
|
+
raise ValueError("live model budget exhausted before dispatch")
|
|
129
|
+
self.model_calls += 1
|
|
130
|
+
self.unpriced += 1
|
|
131
|
+
self.reserved_output += cap
|
|
132
|
+
self.inflight += 1
|
|
133
|
+
event = {"kind": "model", "request": to_jsonable(request)}
|
|
134
|
+
self.events.append(event)
|
|
135
|
+
try:
|
|
136
|
+
response = self.owner.backend.generate(request)
|
|
137
|
+
usage = response.usage
|
|
138
|
+
with self.lock:
|
|
139
|
+
self.input_tokens += usage.input_tokens
|
|
140
|
+
self.output_tokens += usage.output_tokens
|
|
141
|
+
self.reserved_output -= cap
|
|
142
|
+
if usage.cost_usd is not None:
|
|
143
|
+
self.unpriced -= 1
|
|
144
|
+
self.cost += usage.cost_usd
|
|
145
|
+
if usage.output_tokens > cap:
|
|
146
|
+
self.fatal = True
|
|
147
|
+
event["response"] = to_jsonable(response)
|
|
148
|
+
if usage.output_tokens > cap:
|
|
149
|
+
raise RuntimeError("provider exceeded the requested output cap")
|
|
150
|
+
return {"text": response.text, "input_tokens": usage.input_tokens,
|
|
151
|
+
"output_tokens": usage.output_tokens, "finish_reason": response.finish_reason}
|
|
152
|
+
except Exception as exc:
|
|
153
|
+
with self.lock:
|
|
154
|
+
self.fatal = True
|
|
155
|
+
if "response" not in event:
|
|
156
|
+
self.unknown_usage_calls += 1
|
|
157
|
+
# Keep the full output reservation when actual usage is unknown.
|
|
158
|
+
event["error_type"] = type(exc).__name__
|
|
159
|
+
raise RuntimeError("bound model callback failed; no retry") from None
|
|
160
|
+
finally:
|
|
161
|
+
with self.lock:
|
|
162
|
+
self.inflight -= 1
|
|
163
|
+
|
|
164
|
+
def tool(self, value):
|
|
165
|
+
if (not isinstance(value, dict) or set(value) != {"name", "arguments"}
|
|
166
|
+
or value["name"] not in self.specs):
|
|
167
|
+
raise ValueError("invalid bound tool request")
|
|
168
|
+
spec = self.specs[value["name"]]
|
|
169
|
+
properties = spec.input_schema.get("properties", {})
|
|
170
|
+
arguments = value["arguments"]
|
|
171
|
+
if isinstance(arguments, list):
|
|
172
|
+
if len(arguments) == 1 and isinstance(arguments[0], dict):
|
|
173
|
+
arguments = arguments[0]
|
|
174
|
+
else:
|
|
175
|
+
order = self.argument_order.get(spec.name)
|
|
176
|
+
if order is None:
|
|
177
|
+
if len(properties) > 1:
|
|
178
|
+
raise ValueError("multi-argument tools require explicit positional argument_order")
|
|
179
|
+
order = tuple(properties)
|
|
180
|
+
if len(arguments) > len(order):
|
|
181
|
+
raise ValueError("positional argument count differs from its explicit binding")
|
|
182
|
+
arguments = dict(zip(order[:len(arguments)], arguments, strict=True))
|
|
183
|
+
if not isinstance(arguments, dict):
|
|
184
|
+
raise ValueError("tool arguments must be a JSON object or positional list")
|
|
185
|
+
validate_json_value(arguments, spec.input_schema)
|
|
186
|
+
with self.lock:
|
|
187
|
+
if self.fatal or self.closed or self.tool_calls >= self.budget.max_tool_calls:
|
|
188
|
+
raise ValueError("live tool budget exhausted before dispatch")
|
|
189
|
+
self.tool_calls += 1
|
|
190
|
+
self.inflight += 1
|
|
191
|
+
call = ToolCall(value["name"], arguments, call_id=secrets.token_hex(16))
|
|
192
|
+
event = {"kind": "tool", "request": to_jsonable(call)}
|
|
193
|
+
self.events.append(event)
|
|
194
|
+
try:
|
|
195
|
+
result = self.owner.tools.call(call)
|
|
196
|
+
event["response"] = to_jsonable(result)
|
|
197
|
+
if result.error:
|
|
198
|
+
raise RuntimeError("bound tool returned an error")
|
|
199
|
+
return {"output": to_jsonable(result.output)}
|
|
200
|
+
except Exception as exc:
|
|
201
|
+
self.fatal = True
|
|
202
|
+
event["error_type"] = type(exc).__name__
|
|
203
|
+
raise RuntimeError("bound read-only tool failed; no synthetic observation") from None
|
|
204
|
+
finally:
|
|
205
|
+
with self.lock:
|
|
206
|
+
self.inflight -= 1
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _server(callbacks, key, limit):
|
|
210
|
+
class Handler(BaseHTTPRequestHandler):
|
|
211
|
+
def log_message(self, *args):
|
|
212
|
+
pass
|
|
213
|
+
|
|
214
|
+
def do_POST(self):
|
|
215
|
+
try:
|
|
216
|
+
self.connection.settimeout(10)
|
|
217
|
+
if (self.path != "/callback" or not hmac.compare_digest(
|
|
218
|
+
self.headers.get("Authorization", ""), "Bearer " + key)):
|
|
219
|
+
self.send_error(403)
|
|
220
|
+
return
|
|
221
|
+
size = int(self.headers.get("Content-Length", "0"))
|
|
222
|
+
if size < 1 or size > limit:
|
|
223
|
+
raise ValueError("callback byte limit exceeded")
|
|
224
|
+
raw = self.rfile.read(size)
|
|
225
|
+
if len(raw) != size:
|
|
226
|
+
raise ValueError("truncated callback")
|
|
227
|
+
result = {"ok": True, "payload": callbacks.dispatch(_strict_json(raw))}
|
|
228
|
+
except Exception as exc:
|
|
229
|
+
result = {"ok": False, "failure_code": "HOST_CALLBACK_FAILED",
|
|
230
|
+
"error_type": type(exc).__name__}
|
|
231
|
+
body = json.dumps(result, allow_nan=False).encode()
|
|
232
|
+
if len(body) > limit:
|
|
233
|
+
body = b'{"ok":false,"failure_code":"CALLBACK_RESPONSE_TOO_LARGE"}'
|
|
234
|
+
self.send_response(200)
|
|
235
|
+
self.send_header("Content-Type", "application/json")
|
|
236
|
+
self.send_header("Content-Length", str(len(body)))
|
|
237
|
+
self.end_headers()
|
|
238
|
+
with suppress(BrokenPipeError, ConnectionResetError):
|
|
239
|
+
self.wfile.write(body)
|
|
240
|
+
|
|
241
|
+
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
|
|
242
|
+
server.daemon_threads = True
|
|
243
|
+
server.block_on_close = False
|
|
244
|
+
return server
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@dataclass
|
|
248
|
+
class LLMCompilerLiveWorker:
|
|
249
|
+
"""Execute pinned Planner/TFU/join with caller-owned live dependencies.
|
|
250
|
+
|
|
251
|
+
Keep the legacy worker environment separate from the host package. Tools
|
|
252
|
+
must be read-only/no-network, and backends/tools must set their own bounded
|
|
253
|
+
I/O timeouts. Streaming controls use buffered callback delivery, not provider
|
|
254
|
+
streaming latency/parity. Priced/input-token ceilings fail before dispatch.
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
python_executable: str
|
|
258
|
+
checkout: Path
|
|
259
|
+
prompt_bundle: Path
|
|
260
|
+
backend: LLMBackend
|
|
261
|
+
tools: ToolConnector
|
|
262
|
+
per_call_output_cap: int = 512
|
|
263
|
+
timeout_seconds: float = 400
|
|
264
|
+
argument_order: Mapping[str, tuple[str, ...]] = field(default_factory=dict)
|
|
265
|
+
worker_id: str = "agentinputlab.llmcompiler.controlled-live.v1"
|
|
266
|
+
_last_resource_receipt: Any = field(default=None, init=False, repr=False)
|
|
267
|
+
callback_events: list = field(default_factory=list, init=False, repr=False)
|
|
268
|
+
|
|
269
|
+
def __post_init__(self):
|
|
270
|
+
if (isinstance(self.per_call_output_cap, bool) or not isinstance(self.per_call_output_cap, int)
|
|
271
|
+
or self.per_call_output_cap < 1):
|
|
272
|
+
raise ValidationError("per_call_output_cap must be positive")
|
|
273
|
+
if (not isinstance(self.python_executable, str) or not self.python_executable
|
|
274
|
+
or isinstance(self.timeout_seconds, bool)
|
|
275
|
+
or not isinstance(self.timeout_seconds, (int, float))
|
|
276
|
+
or not math.isfinite(self.timeout_seconds) or self.timeout_seconds <= 0):
|
|
277
|
+
raise ValidationError("worker interpreter and finite positive timeout required")
|
|
278
|
+
if any(not isinstance(name, str) or not isinstance(order, (list, tuple))
|
|
279
|
+
or not all(isinstance(key, str) and key for key in order)
|
|
280
|
+
or len(set(order)) != len(order) for name, order in self.argument_order.items()):
|
|
281
|
+
raise ValidationError("argument_order must map tool names to unique parameter names")
|
|
282
|
+
self.checkout, self.prompt_bundle = Path(self.checkout), Path(self.prompt_bundle)
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def last_resource_receipt(self):
|
|
286
|
+
return self._last_resource_receipt
|
|
287
|
+
|
|
288
|
+
def fingerprint(self):
|
|
289
|
+
import hashlib
|
|
290
|
+
from importlib import resources
|
|
291
|
+
|
|
292
|
+
package = resources.files("workers").joinpath("llmcompiler")
|
|
293
|
+
driver_sha = hashlib.sha256(package.joinpath("driver.py").read_bytes()).hexdigest()
|
|
294
|
+
live_sha = hashlib.sha256(package.joinpath("live.py").read_bytes()).hexdigest()
|
|
295
|
+
manifest = package.joinpath("compatibility_manifest.json").read_bytes()
|
|
296
|
+
manifest_sha = hashlib.sha256(manifest).hexdigest()
|
|
297
|
+
attestation = {"schema": "agentinputlab.llmcompiler.live-attestation.v1",
|
|
298
|
+
"driver_sha256": driver_sha, "live_driver_sha256": live_sha,
|
|
299
|
+
"compatibility_manifest_sha256": manifest_sha,
|
|
300
|
+
"required_versions": json.loads(manifest)["legacy_dependencies"]["required_versions"],
|
|
301
|
+
"source_files_verified": True, "required_versions_verified": True, "import_origins_verified": True}
|
|
302
|
+
return {"worker_id": self.worker_id,
|
|
303
|
+
"upstream_commit": "a00c9d35507507da70e8c637eee64efc8c1857ae",
|
|
304
|
+
"driver_sha256": driver_sha, "live_driver_sha256": live_sha,
|
|
305
|
+
"compatibility_manifest_sha256": manifest_sha, "worker_attestation": attestation,
|
|
306
|
+
"prompt_bundle_sha256": hashlib.sha256(self.prompt_bundle.read_bytes()).hexdigest(),
|
|
307
|
+
"model": dict(self.backend.fingerprint()), "tools": dict(self.tools.fingerprint()),
|
|
308
|
+
"model_transport": "context_bound_host_callback", "tool_transport": "context_bound_readonly_callback",
|
|
309
|
+
"streaming_delivery": "buffered_completion_callbacks_not_native_streaming",
|
|
310
|
+
"positional_argument_order": to_jsonable(self.argument_order),
|
|
311
|
+
"per_call_output_cap": self.per_call_output_cap, "timeout_seconds": self.timeout_seconds}
|
|
312
|
+
|
|
313
|
+
def call(self, payload):
|
|
314
|
+
if not isinstance(payload, Mapping):
|
|
315
|
+
raise ValidationError("live LLMCompiler requires a typed request mapping")
|
|
316
|
+
callbacks = _Callbacks(self, payload)
|
|
317
|
+
identity = self.fingerprint()
|
|
318
|
+
self.callback_events = callbacks.events
|
|
319
|
+
self._last_resource_receipt = None
|
|
320
|
+
key = secrets.token_urlsafe(32)
|
|
321
|
+
server = _server(callbacks, key, 4 * 1024 * 1024)
|
|
322
|
+
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
|
323
|
+
thread.start()
|
|
324
|
+
worker = JsonLineSubprocessWorker(
|
|
325
|
+
command=(self.python_executable, "-m", "workers.llmcompiler.live",
|
|
326
|
+
"--checkout", str(self.checkout), "--prompt-bundle", str(self.prompt_bundle),
|
|
327
|
+
"--callback-url", f"http://127.0.0.1:{server.server_port}/callback",
|
|
328
|
+
"--callback-key-env", _KEY_ENV), worker_id=self.worker_id,
|
|
329
|
+
identity=identity, timeout_seconds=self.timeout_seconds,
|
|
330
|
+
environment={"PATH": os.environ.get("PATH", ""), "PYTHONDONTWRITEBYTECODE": "1",
|
|
331
|
+
"CUDA_VISIBLE_DEVICES": "", _KEY_ENV: key})
|
|
332
|
+
try:
|
|
333
|
+
try:
|
|
334
|
+
response = dict(worker.call(payload))
|
|
335
|
+
except SupervisedWorkerError:
|
|
336
|
+
response = {"status": "error", "request_id": payload["request_id"],
|
|
337
|
+
"failure_code": "LIVE_WORKER_EXECUTION_FAILED", "message": "supervised native worker failed"}
|
|
338
|
+
with callbacks.lock:
|
|
339
|
+
callbacks.closed = True
|
|
340
|
+
usage = callbacks.usage()
|
|
341
|
+
incomplete = callbacks.inflight > 0
|
|
342
|
+
if incomplete:
|
|
343
|
+
response = {"status": "error", "request_id": payload["request_id"],
|
|
344
|
+
"failure_code": "CALLBACK_USAGE_INCOMPLETE", "message": "bound callback still in flight at worker exit"}
|
|
345
|
+
elif response.get("status") == "ok" and any(
|
|
346
|
+
response.get("usage", {}).get(k) != usage[k]
|
|
347
|
+
for k in ("model_calls", "tool_calls", "input_tokens", "output_tokens")):
|
|
348
|
+
response = {"status": "error", "request_id": payload["request_id"],
|
|
349
|
+
"failure_code": "CALLBACK_USAGE_MISMATCH", "message": "worker and host usage differ"}
|
|
350
|
+
response["usage"] = usage
|
|
351
|
+
response["consumed"] = bool(usage["model_calls"] or usage["tool_calls"])
|
|
352
|
+
response["callback_diagnostics"] = {"unknown_usage_calls": callbacks.unknown_usage_calls,
|
|
353
|
+
"usage_incomplete": incomplete, "automatic_retry": False}
|
|
354
|
+
return response
|
|
355
|
+
finally:
|
|
356
|
+
self._last_resource_receipt = worker.last_resource_receipt
|
|
357
|
+
callbacks.closed = True
|
|
358
|
+
server.shutdown()
|
|
359
|
+
server.server_close()
|
|
360
|
+
thread.join(timeout=2)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Pinned local LLMLingua runtime; executable objects stay in the context."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib.metadata
|
|
6
|
+
import json
|
|
7
|
+
import re
|
|
8
|
+
import threading
|
|
9
|
+
import time
|
|
10
|
+
from collections.abc import Mapping
|
|
11
|
+
from dataclasses import replace
|
|
12
|
+
from functools import lru_cache
|
|
13
|
+
from pathlib import Path, PurePosixPath
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from agentinputlab.algorithms.curate.llmlingua import (
|
|
17
|
+
LongLLMLinguaOfficialAdapter,
|
|
18
|
+
)
|
|
19
|
+
from agentinputlab.algorithms.curate.llmlingua.controlled import LongLLMLinguaCompressionRequest
|
|
20
|
+
from agentinputlab.artifacts import sha256_file
|
|
21
|
+
from agentinputlab.contracts import (
|
|
22
|
+
ExternalDependencyError,
|
|
23
|
+
InterventionContext,
|
|
24
|
+
TraceEvent,
|
|
25
|
+
TracePhase,
|
|
26
|
+
ValidationError,
|
|
27
|
+
)
|
|
28
|
+
from agentinputlab.contracts.serialization import freeze_mapping
|
|
29
|
+
|
|
30
|
+
_SOURCE_FILES = {
|
|
31
|
+
"prompt_compressor.py": "472fde8f6f55f273fe94eee40c25c73508f1ed3a7f5d61788636c20fc4be5068",
|
|
32
|
+
"utils.py": "1ed3eb0734354ea0136a0d98a9366233a872d22ff350fab107e53de45c954e33",
|
|
33
|
+
}
|
|
34
|
+
_SHA = re.compile(r"[0-9a-f]{64}")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@lru_cache(maxsize=4)
|
|
38
|
+
def _verify_files(snapshot: str, pins: tuple[tuple[str, str], ...],
|
|
39
|
+
identities: tuple[tuple[str, int, int], ...]) -> None:
|
|
40
|
+
del identities
|
|
41
|
+
for name, expected in pins:
|
|
42
|
+
if sha256_file(Path(snapshot) / name) != expected:
|
|
43
|
+
raise ExternalDependencyError(f"LongLLMLingua snapshot checksum differs: {name}")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class LongLLMLinguaNativeRuntime:
|
|
47
|
+
"""Use a caller-mounted safetensors snapshot, never an implicit alternative.
|
|
48
|
+
|
|
49
|
+
The supplied checksums are operator trust. Live calls verify every file
|
|
50
|
+
before loading. Injected factories are explicit caller code; their identity
|
|
51
|
+
is recorded and they do not certify model execution or verify model weights.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(self, snapshot: str | Path, *, model_id: str, revision: str,
|
|
55
|
+
file_sha256: Mapping[str, str], device_map: str = "cpu",
|
|
56
|
+
torch_dtype: str = "float16", compressor_factory: Any = None):
|
|
57
|
+
self.snapshot = Path(snapshot).resolve()
|
|
58
|
+
if not self.snapshot.is_dir() or not model_id or re.fullmatch(r"[0-9a-f]{40}", revision) is None:
|
|
59
|
+
raise ValidationError("LongLLMLingua needs a local snapshot and pinned model identity")
|
|
60
|
+
if device_map not in {"cpu", "cuda:0", "mps"} or torch_dtype not in {"float16", "bfloat16", "float32"}:
|
|
61
|
+
raise ValidationError("LongLLMLingua requires an explicit device and floating dtype")
|
|
62
|
+
pins = dict(file_sha256)
|
|
63
|
+
for name, value in pins.items():
|
|
64
|
+
path = PurePosixPath(name)
|
|
65
|
+
if (not name or path.is_absolute() or ".." in path.parts or "\\" in name
|
|
66
|
+
or not isinstance(value, str) or _SHA.fullmatch(value) is None):
|
|
67
|
+
raise ValidationError("LongLLMLingua snapshot pins must be safe paths and SHA-256")
|
|
68
|
+
if (not {"config.json", "tokenizer_config.json", "special_tokens_map.json"}.issubset(pins)
|
|
69
|
+
or not any(n.endswith(".safetensors") for n in pins)
|
|
70
|
+
or not any(n in pins for n in ("tokenizer.json", "tokenizer.model"))):
|
|
71
|
+
raise ValidationError("LongLLMLingua snapshot closure lacks model/tokenizer files")
|
|
72
|
+
self._pins = tuple(sorted(pins.items()))
|
|
73
|
+
self._model_id, self._revision = model_id, revision
|
|
74
|
+
self._device, self._dtype = device_map, torch_dtype
|
|
75
|
+
self._factory = compressor_factory
|
|
76
|
+
self._lock = threading.RLock()
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def _source() -> Mapping[str, Any]:
|
|
80
|
+
try:
|
|
81
|
+
distribution = importlib.metadata.distribution("llmlingua")
|
|
82
|
+
if distribution.version != "0.2.2":
|
|
83
|
+
raise ExternalDependencyError("LongLLMLingua requires llmlingua==0.2.2")
|
|
84
|
+
for name, expected in _SOURCE_FILES.items():
|
|
85
|
+
if sha256_file(distribution.locate_file("llmlingua/" + name)) != expected:
|
|
86
|
+
raise ExternalDependencyError("LongLLMLingua upstream source differs from its lock")
|
|
87
|
+
except (importlib.metadata.PackageNotFoundError, OSError) as exc:
|
|
88
|
+
raise ExternalDependencyError("install agentinputlab[compression] and mount the pinned assets") from exc
|
|
89
|
+
return {"package": "llmlingua", "version": "0.2.2", "file_sha256": _SOURCE_FILES}
|
|
90
|
+
|
|
91
|
+
def fingerprint(self) -> Mapping[str, Any]:
|
|
92
|
+
return freeze_mapping({
|
|
93
|
+
"runtime_id": "agentinputlab.longllmlingua.native.v1", "source": self._source(),
|
|
94
|
+
"model": {"id": self._model_id, "locator": str(self.snapshot),
|
|
95
|
+
"revision": self._revision, "file_sha256": dict(self._pins)},
|
|
96
|
+
"tokenizer": {"revision": self._revision, "file_sha256": {
|
|
97
|
+
name: sha for name, sha in self._pins if "tokenizer" in name or "special_tokens" in name}},
|
|
98
|
+
"load": {"device_map": self._device, "torch_dtype": self._dtype,
|
|
99
|
+
"local_files_only": True, "trust_remote_code": False},
|
|
100
|
+
"injected_factory": self._factory is not None,
|
|
101
|
+
"file_verification": "caller_runtime" if self._factory is not None else "full_sha256_before_live_load",
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
def _require_loader_closure(self) -> None:
|
|
105
|
+
"""Reject undeclared sidecars/shards that native auto-loading could use."""
|
|
106
|
+
pins = dict(self._pins)
|
|
107
|
+
for name in ("generation_config.json", "model.safetensors.index.json", "tokenizer.json",
|
|
108
|
+
"tokenizer.model", "added_tokens.json", "chat_template.jinja"):
|
|
109
|
+
if (self.snapshot/name).exists() and name not in pins:
|
|
110
|
+
raise ExternalDependencyError(f"LongLLMLingua loader file is not pinned: {name}")
|
|
111
|
+
if (self.snapshot/'adapter_config.json').exists():
|
|
112
|
+
raise ExternalDependencyError("LongLLMLingua does not implicitly load PEFT adapters")
|
|
113
|
+
try:
|
|
114
|
+
config = json.loads((self.snapshot/'config.json').read_text())
|
|
115
|
+
if not any(str(name).endswith('ForCausalLM') for name in config.get('architectures', [])):
|
|
116
|
+
raise ExternalDependencyError("LongLLMLingua perplexity scoring requires a causal LM")
|
|
117
|
+
index = self.snapshot/'model.safetensors.index.json'
|
|
118
|
+
if index.exists():
|
|
119
|
+
if (self.snapshot/'model.safetensors').exists():
|
|
120
|
+
raise ExternalDependencyError("LongLLMLingua snapshot has ambiguous weight layouts")
|
|
121
|
+
shards = set(json.loads(index.read_text())['weight_map'].values())
|
|
122
|
+
if not shards or any(not isinstance(n, str) or n not in pins for n in shards):
|
|
123
|
+
raise ExternalDependencyError("LongLLMLingua weight index references unpinned shards")
|
|
124
|
+
elif 'model.safetensors' not in pins:
|
|
125
|
+
raise ExternalDependencyError("LongLLMLingua needs pinned single or indexed safetensors")
|
|
126
|
+
except (ValueError, KeyError, AttributeError, TypeError) as exc:
|
|
127
|
+
raise ExternalDependencyError("LongLLMLingua loader config/index is malformed") from exc
|
|
128
|
+
|
|
129
|
+
def run(self, request: LongLLMLinguaCompressionRequest) -> Mapping[str, Any]:
|
|
130
|
+
if not isinstance(request, LongLLMLinguaCompressionRequest):
|
|
131
|
+
raise ValidationError("LongLLMLingua runtime requires a typed compression request")
|
|
132
|
+
state, config, seed = request.state, request.config, request.seed
|
|
133
|
+
with self._lock:
|
|
134
|
+
self._source()
|
|
135
|
+
started = time.monotonic()
|
|
136
|
+
cpu_started = time.process_time()
|
|
137
|
+
if self._factory is None:
|
|
138
|
+
try:
|
|
139
|
+
self._require_loader_closure()
|
|
140
|
+
identities = tuple((name, (self.snapshot/name).stat().st_size,
|
|
141
|
+
(self.snapshot/name).stat().st_mtime_ns) for name, _ in self._pins)
|
|
142
|
+
_verify_files(str(self.snapshot), self._pins, identities)
|
|
143
|
+
except OSError as exc:
|
|
144
|
+
raise ExternalDependencyError("LongLLMLingua snapshot closure is incomplete") from exc
|
|
145
|
+
adapter = LongLLMLinguaOfficialAdapter(model_name=str(self.snapshot), model_revision=self._revision,
|
|
146
|
+
device_map=self._device, model_config={"local_files_only": True, "torch_dtype": self._dtype},
|
|
147
|
+
config=config, compressor_factory=self._factory)
|
|
148
|
+
native = adapter.propose(state, InterventionContext(seed=seed))
|
|
149
|
+
native = replace(native, trace=replace(native.trace, events=(*native.trace.events,
|
|
150
|
+
TraceEvent(TracePhase.FINALIZE, "native_helper_execution", {
|
|
151
|
+
"wall_seconds": time.monotonic()-started,
|
|
152
|
+
"injected_factory": self._factory is not None,
|
|
153
|
+
"compression_invocations": 1,
|
|
154
|
+
"internal_forward_count": "not_metered_native_perplexity_passes",
|
|
155
|
+
"helper_sampled_output_tokens": 0,
|
|
156
|
+
"helper_compute_free": False}))))
|
|
157
|
+
return {"patch": native, "usage": {"model_calls": 0, "retrieval_calls": 0,
|
|
158
|
+
"input_tokens": 0, "output_tokens": 0, "cpu_seconds": time.process_time()-cpu_started},
|
|
159
|
+
"usage_scope": "zero sampled generation; helper forward passes and wall time are separate"}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
__all__ = ["LongLLMLinguaNativeRuntime"]
|