@r1z4x/tezgah 1.0.0
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.
- package/CHANGELOG.md +738 -0
- package/LICENSE +21 -0
- package/MANIFEST +753 -0
- package/README.de.md +169 -0
- package/README.es.md +168 -0
- package/README.fr.md +166 -0
- package/README.md +161 -0
- package/README.tr.md +163 -0
- package/agents/tezgah-reviewer.md +70 -0
- package/bin/codegen +337 -0
- package/bin/consult +797 -0
- package/bin/tezgah-adhd +50 -0
- package/bin/tezgah-agents +45 -0
- package/bin/tezgah-capture +66 -0
- package/bin/tezgah-context +96 -0
- package/bin/tezgah-decisions +213 -0
- package/bin/tezgah-design +953 -0
- package/bin/tezgah-docs +1199 -0
- package/bin/tezgah-doctor +497 -0
- package/bin/tezgah-dsh +37 -0
- package/bin/tezgah-dsh.cmd +70 -0
- package/bin/tezgah-gate +75 -0
- package/bin/tezgah-import-ai-research +439 -0
- package/bin/tezgah-index +32 -0
- package/bin/tezgah-lessons +148 -0
- package/bin/tezgah-mcp +322 -0
- package/bin/tezgah-migrate +324 -0
- package/bin/tezgah-pony +50 -0
- package/bin/tezgah-research +772 -0
- package/bin/tezgah-rollback +93 -0
- package/bin/tezgah-route +124 -0
- package/bin/tezgah-setup +5798 -0
- package/bin/tezgah-status +383 -0
- package/bin/tezgah-task +607 -0
- package/bin/tezgah-taste +423 -0
- package/bin/tezgah-triage +485 -0
- package/bin/tezgah.js +36 -0
- package/commands/adhd.md +21 -0
- package/commands/ponytail.md +21 -0
- package/docs/README.md +112 -0
- package/docs/architecture.md +226 -0
- package/docs/citations-baseline.json +59 -0
- package/docs/clarity-baseline.json +116 -0
- package/docs/contract.md +416 -0
- package/docs/environment.md +141 -0
- package/docs/evidence.md +831 -0
- package/docs/feature-audit.md +139 -0
- package/docs/gate.md +407 -0
- package/docs/glossary.md +201 -0
- package/docs/hosts.md +400 -0
- package/docs/index.json +471 -0
- package/docs/judge.md +193 -0
- package/docs/layers.md +189 -0
- package/docs/models.md +160 -0
- package/docs/operations.md +666 -0
- package/docs/research.md +809 -0
- package/docs/results/paired-outcome-2026-10.jsonl +254 -0
- package/docs/results/paired-outcome-2026-10.md +204 -0
- package/docs/skills.md +236 -0
- package/docs/status-line.md +315 -0
- package/docs/testing.md +287 -0
- package/docs/vision.md +117 -0
- package/hooks/hooks.json +33 -0
- package/hooks/projects-auto-init.py +98 -0
- package/hooks/projects-posttooluse.py +149 -0
- package/hooks/projects-pretooluse.py +40 -0
- package/hooks/projects-stop.py +60 -0
- package/hooks/tezgah_agents.py +817 -0
- package/hooks/tezgah_apps.py +266 -0
- package/hooks/tezgah_attest.py +255 -0
- package/hooks/tezgah_clarity.py +171 -0
- package/hooks/tezgah_components.py +140 -0
- package/hooks/tezgah_context.py +2953 -0
- package/hooks/tezgah_embed.py +765 -0
- package/hooks/tezgah_gate.py +2736 -0
- package/hooks/tezgah_guard.py +177 -0
- package/hooks/tezgah_index.py +124 -0
- package/hooks/tezgah_integrity.py +5141 -0
- package/hooks/tezgah_judge.py +487 -0
- package/hooks/tezgah_lang.py +230 -0
- package/hooks/tezgah_lessons.py +210 -0
- package/hooks/tezgah_models.py +855 -0
- package/hooks/tezgah_paths.py +1132 -0
- package/hooks/tezgah_policy.py +1039 -0
- package/hooks/tezgah_rank.py +77 -0
- package/hooks/tezgah_replay.py +1109 -0
- package/hooks/tezgah_research.py +5176 -0
- package/hooks/tezgah_shapes.py +305 -0
- package/hooks/tezgah_skill_pick.py +227 -0
- package/hooks/tezgah_snapshot.py +490 -0
- package/hooks/tezgah_stopspec.py +320 -0
- package/hooks/tezgah_task.py +458 -0
- package/hooks/tezgah_taste.py +201 -0
- package/hooks/tezgah_untrusted.py +112 -0
- package/hooks/tezgah_update.py +430 -0
- package/hosts/codex/hook.py +268 -0
- package/hosts/codex/hooks.json +26 -0
- package/hosts/cursor/hook.py +461 -0
- package/hosts/cursor/hooks.json +44 -0
- package/hosts/dsh/hooks.json +21 -0
- package/hosts/dsh/statusline/lib/client.js +138 -0
- package/hosts/dsh/statusline/lib/index.js +104 -0
- package/hosts/dsh/statusline/package.json +28 -0
- package/hosts/omp/hook.py +277 -0
- package/hosts/omp/tezgah-hook.ts.in +701 -0
- package/hosts/opencode/plugins/tezgah.js +2742 -0
- package/hosts/opencode/tui/tezgah-tui.tsx +151 -0
- package/output-styles/tezgah.md +142 -0
- package/package.json +32 -0
- package/packaging/build.sh +342 -0
- package/packaging/install.ps1 +166 -0
- package/packaging/install.sh +56 -0
- package/packaging/upgrade.sh +142 -0
- package/skills/ai-research/0-autoresearch-skill/SKILL.md +411 -0
- package/skills/ai-research/0-autoresearch-skill/references/agent-continuity.md +95 -0
- package/skills/ai-research/0-autoresearch-skill/references/progress-reporting.md +166 -0
- package/skills/ai-research/0-autoresearch-skill/references/skill-routing.md +219 -0
- package/skills/ai-research/0-autoresearch-skill/templates/findings.md +44 -0
- package/skills/ai-research/0-autoresearch-skill/templates/research-log.md +41 -0
- package/skills/ai-research/01-model-architecture/litgpt/SKILL.md +469 -0
- package/skills/ai-research/01-model-architecture/litgpt/references/custom-models.md +569 -0
- package/skills/ai-research/01-model-architecture/litgpt/references/distributed-training.md +452 -0
- package/skills/ai-research/01-model-architecture/litgpt/references/supported-models.md +337 -0
- package/skills/ai-research/01-model-architecture/litgpt/references/training-recipes.md +620 -0
- package/skills/ai-research/01-model-architecture/mamba/SKILL.md +260 -0
- package/skills/ai-research/01-model-architecture/mamba/references/architecture-details.md +207 -0
- package/skills/ai-research/01-model-architecture/mamba/references/benchmarks.md +256 -0
- package/skills/ai-research/01-model-architecture/mamba/references/training-guide.md +389 -0
- package/skills/ai-research/01-model-architecture/nanogpt/SKILL.md +290 -0
- package/skills/ai-research/01-model-architecture/nanogpt/references/architecture.md +383 -0
- package/skills/ai-research/01-model-architecture/nanogpt/references/data.md +477 -0
- package/skills/ai-research/01-model-architecture/nanogpt/references/training.md +565 -0
- package/skills/ai-research/01-model-architecture/rwkv/SKILL.md +260 -0
- package/skills/ai-research/01-model-architecture/rwkv/references/architecture-details.md +345 -0
- package/skills/ai-research/01-model-architecture/rwkv/references/rwkv7.md +387 -0
- package/skills/ai-research/01-model-architecture/rwkv/references/state-management.md +370 -0
- package/skills/ai-research/01-model-architecture/torchtitan/SKILL.md +358 -0
- package/skills/ai-research/01-model-architecture/torchtitan/references/checkpoint.md +182 -0
- package/skills/ai-research/01-model-architecture/torchtitan/references/custom-models.md +259 -0
- package/skills/ai-research/01-model-architecture/torchtitan/references/float8.md +134 -0
- package/skills/ai-research/01-model-architecture/torchtitan/references/fsdp.md +127 -0
- package/skills/ai-research/02-tokenization/huggingface-tokenizers/SKILL.md +516 -0
- package/skills/ai-research/02-tokenization/huggingface-tokenizers/references/algorithms.md +654 -0
- package/skills/ai-research/02-tokenization/huggingface-tokenizers/references/integration.md +638 -0
- package/skills/ai-research/02-tokenization/huggingface-tokenizers/references/pipeline.md +724 -0
- package/skills/ai-research/02-tokenization/huggingface-tokenizers/references/training.md +566 -0
- package/skills/ai-research/02-tokenization/sentencepiece/SKILL.md +235 -0
- package/skills/ai-research/02-tokenization/sentencepiece/references/algorithms.md +201 -0
- package/skills/ai-research/02-tokenization/sentencepiece/references/training.md +305 -0
- package/skills/ai-research/03-fine-tuning/axolotl/SKILL.md +158 -0
- package/skills/ai-research/03-fine-tuning/axolotl/references/api.md +5549 -0
- package/skills/ai-research/03-fine-tuning/axolotl/references/dataset-formats.md +1030 -0
- package/skills/ai-research/03-fine-tuning/axolotl/references/index.md +16 -0
- package/skills/ai-research/03-fine-tuning/axolotl/references/other.md +3564 -0
- package/skills/ai-research/03-fine-tuning/llama-factory/SKILL.md +80 -0
- package/skills/ai-research/03-fine-tuning/llama-factory/references/_images.md +24 -0
- package/skills/ai-research/03-fine-tuning/llama-factory/references/advanced.md +1056 -0
- package/skills/ai-research/03-fine-tuning/llama-factory/references/getting_started.md +350 -0
- package/skills/ai-research/03-fine-tuning/llama-factory/references/index.md +20 -0
- package/skills/ai-research/03-fine-tuning/llama-factory/references/other.md +32 -0
- package/skills/ai-research/03-fine-tuning/peft/SKILL.md +431 -0
- package/skills/ai-research/03-fine-tuning/peft/references/advanced-usage.md +515 -0
- package/skills/ai-research/03-fine-tuning/peft/references/troubleshooting.md +481 -0
- package/skills/ai-research/03-fine-tuning/unsloth/SKILL.md +80 -0
- package/skills/ai-research/03-fine-tuning/unsloth/references/index.md +8 -0
- package/skills/ai-research/03-fine-tuning/unsloth/references/llms.md +83 -0
- package/skills/ai-research/04-mechanistic-interpretability/nnsight/SKILL.md +436 -0
- package/skills/ai-research/04-mechanistic-interpretability/nnsight/references/README.md +79 -0
- package/skills/ai-research/04-mechanistic-interpretability/nnsight/references/api.md +345 -0
- package/skills/ai-research/04-mechanistic-interpretability/nnsight/references/tutorials.md +301 -0
- package/skills/ai-research/04-mechanistic-interpretability/pyvene/SKILL.md +473 -0
- package/skills/ai-research/04-mechanistic-interpretability/pyvene/references/README.md +74 -0
- package/skills/ai-research/04-mechanistic-interpretability/pyvene/references/api.md +384 -0
- package/skills/ai-research/04-mechanistic-interpretability/pyvene/references/tutorials.md +377 -0
- package/skills/ai-research/04-mechanistic-interpretability/saelens/SKILL.md +386 -0
- package/skills/ai-research/04-mechanistic-interpretability/saelens/references/README.md +71 -0
- package/skills/ai-research/04-mechanistic-interpretability/saelens/references/api.md +334 -0
- package/skills/ai-research/04-mechanistic-interpretability/saelens/references/tutorials.md +319 -0
- package/skills/ai-research/04-mechanistic-interpretability/transformer-lens/SKILL.md +346 -0
- package/skills/ai-research/04-mechanistic-interpretability/transformer-lens/references/README.md +55 -0
- package/skills/ai-research/04-mechanistic-interpretability/transformer-lens/references/api.md +363 -0
- package/skills/ai-research/04-mechanistic-interpretability/transformer-lens/references/tutorials.md +340 -0
- package/skills/ai-research/05-data-processing/nemo-curator/SKILL.md +383 -0
- package/skills/ai-research/05-data-processing/nemo-curator/references/deduplication.md +88 -0
- package/skills/ai-research/05-data-processing/nemo-curator/references/filtering.md +103 -0
- package/skills/ai-research/05-data-processing/ray-data/SKILL.md +326 -0
- package/skills/ai-research/05-data-processing/ray-data/references/integration.md +83 -0
- package/skills/ai-research/05-data-processing/ray-data/references/transformations.md +84 -0
- package/skills/ai-research/06-post-training/grpo-rl-training/README.md +98 -0
- package/skills/ai-research/06-post-training/grpo-rl-training/SKILL.md +572 -0
- package/skills/ai-research/06-post-training/miles/SKILL.md +315 -0
- package/skills/ai-research/06-post-training/miles/references/api-reference.md +142 -0
- package/skills/ai-research/06-post-training/miles/references/troubleshooting.md +353 -0
- package/skills/ai-research/06-post-training/openrlhf/SKILL.md +249 -0
- package/skills/ai-research/06-post-training/openrlhf/references/algorithm-comparison.md +405 -0
- package/skills/ai-research/06-post-training/openrlhf/references/custom-rewards.md +531 -0
- package/skills/ai-research/06-post-training/openrlhf/references/hybrid-engine.md +288 -0
- package/skills/ai-research/06-post-training/openrlhf/references/multi-node-training.md +455 -0
- package/skills/ai-research/06-post-training/simpo/SKILL.md +219 -0
- package/skills/ai-research/06-post-training/simpo/references/datasets.md +479 -0
- package/skills/ai-research/06-post-training/simpo/references/hyperparameters.md +453 -0
- package/skills/ai-research/06-post-training/simpo/references/loss-functions.md +351 -0
- package/skills/ai-research/06-post-training/slime/SKILL.md +464 -0
- package/skills/ai-research/06-post-training/slime/references/api-reference.md +393 -0
- package/skills/ai-research/06-post-training/slime/references/troubleshooting.md +387 -0
- package/skills/ai-research/06-post-training/torchforge/SKILL.md +433 -0
- package/skills/ai-research/06-post-training/torchforge/references/api-reference.md +328 -0
- package/skills/ai-research/06-post-training/torchforge/references/troubleshooting.md +410 -0
- package/skills/ai-research/06-post-training/trl-fine-tuning/SKILL.md +455 -0
- package/skills/ai-research/06-post-training/trl-fine-tuning/references/dpo-variants.md +228 -0
- package/skills/ai-research/06-post-training/trl-fine-tuning/references/online-rl.md +83 -0
- package/skills/ai-research/06-post-training/trl-fine-tuning/references/reward-modeling.md +123 -0
- package/skills/ai-research/06-post-training/trl-fine-tuning/references/sft-training.md +169 -0
- package/skills/ai-research/06-post-training/verl/SKILL.md +391 -0
- package/skills/ai-research/06-post-training/verl/references/api-reference.md +302 -0
- package/skills/ai-research/06-post-training/verl/references/troubleshooting.md +392 -0
- package/skills/ai-research/07-safety-alignment/constitutional-ai/SKILL.md +290 -0
- package/skills/ai-research/07-safety-alignment/llamaguard/SKILL.md +337 -0
- package/skills/ai-research/07-safety-alignment/nemo-guardrails/SKILL.md +297 -0
- package/skills/ai-research/07-safety-alignment/prompt-guard/SKILL.md +312 -0
- package/skills/ai-research/08-distributed-training/accelerate/SKILL.md +332 -0
- package/skills/ai-research/08-distributed-training/accelerate/references/custom-plugins.md +454 -0
- package/skills/ai-research/08-distributed-training/accelerate/references/megatron-integration.md +490 -0
- package/skills/ai-research/08-distributed-training/accelerate/references/performance.md +526 -0
- package/skills/ai-research/08-distributed-training/deepspeed/SKILL.md +141 -0
- package/skills/ai-research/08-distributed-training/deepspeed/references/08.md +18 -0
- package/skills/ai-research/08-distributed-training/deepspeed/references/09.md +174 -0
- package/skills/ai-research/08-distributed-training/deepspeed/references/2020.md +379 -0
- package/skills/ai-research/08-distributed-training/deepspeed/references/2023.md +280 -0
- package/skills/ai-research/08-distributed-training/deepspeed/references/assets.md +180 -0
- package/skills/ai-research/08-distributed-training/deepspeed/references/index.md +36 -0
- package/skills/ai-research/08-distributed-training/deepspeed/references/mii.md +119 -0
- package/skills/ai-research/08-distributed-training/deepspeed/references/other.md +1192 -0
- package/skills/ai-research/08-distributed-training/megatron-core/SKILL.md +366 -0
- package/skills/ai-research/08-distributed-training/megatron-core/references/benchmarks.md +250 -0
- package/skills/ai-research/08-distributed-training/megatron-core/references/parallelism-guide.md +405 -0
- package/skills/ai-research/08-distributed-training/megatron-core/references/production-examples.md +474 -0
- package/skills/ai-research/08-distributed-training/megatron-core/references/training-recipes.md +548 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/SKILL.md +231 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_dcp_async_recipe.md +14 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_dcp_overview.md +19 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_dcp_recipe.md +18 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_ddp_notes.md +10 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_device_mesh_tutorial.md +22 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_examples_fsdp2.md +15 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_fsdp1_api.md +9 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_fsdp2_tutorial.md +45 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_fully_shard_api.md +49 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/pytorch_tp_tutorial.md +22 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/ray_train_fsdp2_example.md +13 -0
- package/skills/ai-research/08-distributed-training/pytorch-fsdp2/references/torchtitan_fsdp_notes.md +14 -0
- package/skills/ai-research/08-distributed-training/pytorch-lightning/SKILL.md +346 -0
- package/skills/ai-research/08-distributed-training/pytorch-lightning/references/callbacks.md +437 -0
- package/skills/ai-research/08-distributed-training/pytorch-lightning/references/distributed.md +491 -0
- package/skills/ai-research/08-distributed-training/pytorch-lightning/references/hyperparameter-tuning.md +557 -0
- package/skills/ai-research/08-distributed-training/ray-train/SKILL.md +406 -0
- package/skills/ai-research/08-distributed-training/ray-train/references/multi-node.md +629 -0
- package/skills/ai-research/09-infrastructure/lambda-labs/SKILL.md +545 -0
- package/skills/ai-research/09-infrastructure/lambda-labs/references/advanced-usage.md +612 -0
- package/skills/ai-research/09-infrastructure/lambda-labs/references/troubleshooting.md +531 -0
- package/skills/ai-research/09-infrastructure/modal/SKILL.md +341 -0
- package/skills/ai-research/09-infrastructure/modal/references/advanced-usage.md +504 -0
- package/skills/ai-research/09-infrastructure/modal/references/troubleshooting.md +495 -0
- package/skills/ai-research/09-infrastructure/skypilot/SKILL.md +509 -0
- package/skills/ai-research/09-infrastructure/skypilot/references/advanced-usage.md +492 -0
- package/skills/ai-research/09-infrastructure/skypilot/references/troubleshooting.md +571 -0
- package/skills/ai-research/10-optimization/awq/SKILL.md +310 -0
- package/skills/ai-research/10-optimization/awq/references/advanced-usage.md +325 -0
- package/skills/ai-research/10-optimization/awq/references/troubleshooting.md +345 -0
- package/skills/ai-research/10-optimization/bitsandbytes/SKILL.md +411 -0
- package/skills/ai-research/10-optimization/bitsandbytes/references/memory-optimization.md +522 -0
- package/skills/ai-research/10-optimization/bitsandbytes/references/qlora-training.md +522 -0
- package/skills/ai-research/10-optimization/bitsandbytes/references/quantization-formats.md +448 -0
- package/skills/ai-research/10-optimization/flash-attention/SKILL.md +367 -0
- package/skills/ai-research/10-optimization/flash-attention/references/benchmarks.md +216 -0
- package/skills/ai-research/10-optimization/flash-attention/references/transformers-integration.md +294 -0
- package/skills/ai-research/10-optimization/gguf/SKILL.md +427 -0
- package/skills/ai-research/10-optimization/gguf/references/advanced-usage.md +505 -0
- package/skills/ai-research/10-optimization/gguf/references/troubleshooting.md +443 -0
- package/skills/ai-research/10-optimization/gptq/SKILL.md +450 -0
- package/skills/ai-research/10-optimization/gptq/references/calibration.md +338 -0
- package/skills/ai-research/10-optimization/gptq/references/integration.md +130 -0
- package/skills/ai-research/10-optimization/gptq/references/troubleshooting.md +96 -0
- package/skills/ai-research/10-optimization/hqq/SKILL.md +445 -0
- package/skills/ai-research/10-optimization/hqq/references/advanced-usage.md +529 -0
- package/skills/ai-research/10-optimization/hqq/references/troubleshooting.md +504 -0
- package/skills/ai-research/10-optimization/ml-training-recipes/SKILL.md +319 -0
- package/skills/ai-research/10-optimization/ml-training-recipes/references/architecture.md +320 -0
- package/skills/ai-research/10-optimization/ml-training-recipes/references/biomedical.md +498 -0
- package/skills/ai-research/10-optimization/ml-training-recipes/references/domain-specific.md +626 -0
- package/skills/ai-research/10-optimization/ml-training-recipes/references/experiment-loop.md +129 -0
- package/skills/ai-research/10-optimization/ml-training-recipes/references/optimizers.md +330 -0
- package/skills/ai-research/10-optimization/ml-training-recipes/references/scaling-and-selection.md +428 -0
- package/skills/ai-research/11-evaluation/bigcode-evaluation-harness/SKILL.md +405 -0
- package/skills/ai-research/11-evaluation/bigcode-evaluation-harness/references/benchmarks.md +394 -0
- package/skills/ai-research/11-evaluation/bigcode-evaluation-harness/references/custom-tasks.md +425 -0
- package/skills/ai-research/11-evaluation/bigcode-evaluation-harness/references/issues.md +395 -0
- package/skills/ai-research/11-evaluation/lm-evaluation-harness/SKILL.md +490 -0
- package/skills/ai-research/11-evaluation/lm-evaluation-harness/references/api-evaluation.md +491 -0
- package/skills/ai-research/11-evaluation/lm-evaluation-harness/references/benchmark-guide.md +489 -0
- package/skills/ai-research/11-evaluation/lm-evaluation-harness/references/custom-tasks.md +603 -0
- package/skills/ai-research/11-evaluation/lm-evaluation-harness/references/distributed-eval.md +520 -0
- package/skills/ai-research/11-evaluation/nemo-evaluator/SKILL.md +494 -0
- package/skills/ai-research/11-evaluation/nemo-evaluator/references/adapter-system.md +341 -0
- package/skills/ai-research/11-evaluation/nemo-evaluator/references/configuration.md +448 -0
- package/skills/ai-research/11-evaluation/nemo-evaluator/references/custom-benchmarks.md +316 -0
- package/skills/ai-research/11-evaluation/nemo-evaluator/references/execution-backends.md +362 -0
- package/skills/ai-research/12-inference-serving/llama-cpp/SKILL.md +258 -0
- package/skills/ai-research/12-inference-serving/llama-cpp/references/optimization.md +90 -0
- package/skills/ai-research/12-inference-serving/llama-cpp/references/quantization.md +214 -0
- package/skills/ai-research/12-inference-serving/llama-cpp/references/server.md +126 -0
- package/skills/ai-research/12-inference-serving/sglang/SKILL.md +442 -0
- package/skills/ai-research/12-inference-serving/sglang/references/deployment.md +491 -0
- package/skills/ai-research/12-inference-serving/sglang/references/radix-attention.md +414 -0
- package/skills/ai-research/12-inference-serving/sglang/references/structured-generation.md +542 -0
- package/skills/ai-research/12-inference-serving/tensorrt-llm/SKILL.md +187 -0
- package/skills/ai-research/12-inference-serving/tensorrt-llm/references/multi-gpu.md +299 -0
- package/skills/ai-research/12-inference-serving/tensorrt-llm/references/optimization.md +243 -0
- package/skills/ai-research/12-inference-serving/tensorrt-llm/references/serving.md +471 -0
- package/skills/ai-research/12-inference-serving/vllm/SKILL.md +364 -0
- package/skills/ai-research/12-inference-serving/vllm/references/optimization.md +227 -0
- package/skills/ai-research/12-inference-serving/vllm/references/quantization.md +285 -0
- package/skills/ai-research/12-inference-serving/vllm/references/server-deployment.md +256 -0
- package/skills/ai-research/12-inference-serving/vllm/references/troubleshooting.md +448 -0
- package/skills/ai-research/13-mlops/mlflow/SKILL.md +704 -0
- package/skills/ai-research/13-mlops/mlflow/references/deployment.md +745 -0
- package/skills/ai-research/13-mlops/mlflow/references/model-registry.md +771 -0
- package/skills/ai-research/13-mlops/mlflow/references/tracking.md +681 -0
- package/skills/ai-research/13-mlops/swanlab/SKILL.md +406 -0
- package/skills/ai-research/13-mlops/swanlab/references/integrations.md +305 -0
- package/skills/ai-research/13-mlops/swanlab/references/visualization.md +234 -0
- package/skills/ai-research/13-mlops/tensorboard/SKILL.md +629 -0
- package/skills/ai-research/13-mlops/tensorboard/references/integrations.md +639 -0
- package/skills/ai-research/13-mlops/tensorboard/references/profiling.md +546 -0
- package/skills/ai-research/13-mlops/tensorboard/references/visualization.md +621 -0
- package/skills/ai-research/13-mlops/weights-and-biases/SKILL.md +590 -0
- package/skills/ai-research/13-mlops/weights-and-biases/references/artifacts.md +585 -0
- package/skills/ai-research/13-mlops/weights-and-biases/references/integrations.md +701 -0
- package/skills/ai-research/13-mlops/weights-and-biases/references/sweeps.md +848 -0
- package/skills/ai-research/14-agents/a-evolve/SKILL.md +383 -0
- package/skills/ai-research/14-agents/a-evolve/references/README.md +831 -0
- package/skills/ai-research/14-agents/a-evolve/references/api.md +594 -0
- package/skills/ai-research/14-agents/a-evolve/references/architecture.md +417 -0
- package/skills/ai-research/14-agents/a-evolve/references/design-patterns.md +462 -0
- package/skills/ai-research/14-agents/a-evolve/references/examples.md +352 -0
- package/skills/ai-research/14-agents/a-evolve/references/issues.md +591 -0
- package/skills/ai-research/14-agents/a-evolve/references/releases.md +112 -0
- package/skills/ai-research/14-agents/a-evolve/references/tutorials.md +819 -0
- package/skills/ai-research/14-agents/autogpt/SKILL.md +403 -0
- package/skills/ai-research/14-agents/autogpt/references/advanced-usage.md +536 -0
- package/skills/ai-research/14-agents/autogpt/references/troubleshooting.md +421 -0
- package/skills/ai-research/14-agents/crewai/SKILL.md +498 -0
- package/skills/ai-research/14-agents/crewai/references/flows.md +439 -0
- package/skills/ai-research/14-agents/crewai/references/tools.md +430 -0
- package/skills/ai-research/14-agents/crewai/references/troubleshooting.md +481 -0
- package/skills/ai-research/14-agents/langchain/SKILL.md +480 -0
- package/skills/ai-research/14-agents/langchain/references/agents.md +500 -0
- package/skills/ai-research/14-agents/langchain/references/integration.md +563 -0
- package/skills/ai-research/14-agents/langchain/references/rag.md +601 -0
- package/skills/ai-research/14-agents/llamaindex/SKILL.md +569 -0
- package/skills/ai-research/14-agents/llamaindex/references/agents.md +84 -0
- package/skills/ai-research/14-agents/llamaindex/references/data_connectors.md +109 -0
- package/skills/ai-research/14-agents/llamaindex/references/query_engines.md +407 -0
- package/skills/ai-research/15-rag/chroma/SKILL.md +406 -0
- package/skills/ai-research/15-rag/chroma/references/integration.md +39 -0
- package/skills/ai-research/15-rag/faiss/SKILL.md +221 -0
- package/skills/ai-research/15-rag/faiss/references/index_types.md +281 -0
- package/skills/ai-research/15-rag/pinecone/SKILL.md +358 -0
- package/skills/ai-research/15-rag/pinecone/references/deployment.md +182 -0
- package/skills/ai-research/15-rag/qdrant/SKILL.md +493 -0
- package/skills/ai-research/15-rag/qdrant/references/advanced-usage.md +649 -0
- package/skills/ai-research/15-rag/qdrant/references/troubleshooting.md +632 -0
- package/skills/ai-research/15-rag/sentence-transformers/SKILL.md +255 -0
- package/skills/ai-research/15-rag/sentence-transformers/references/models.md +124 -0
- package/skills/ai-research/16-prompt-engineering/dspy/SKILL.md +590 -0
- package/skills/ai-research/16-prompt-engineering/dspy/references/examples.md +664 -0
- package/skills/ai-research/16-prompt-engineering/dspy/references/modules.md +476 -0
- package/skills/ai-research/16-prompt-engineering/dspy/references/optimizers.md +567 -0
- package/skills/ai-research/16-prompt-engineering/guidance/SKILL.md +572 -0
- package/skills/ai-research/16-prompt-engineering/guidance/references/backends.md +555 -0
- package/skills/ai-research/16-prompt-engineering/guidance/references/constraints.md +675 -0
- package/skills/ai-research/16-prompt-engineering/guidance/references/examples.md +768 -0
- package/skills/ai-research/16-prompt-engineering/instructor/SKILL.md +740 -0
- package/skills/ai-research/16-prompt-engineering/instructor/references/examples.md +108 -0
- package/skills/ai-research/16-prompt-engineering/instructor/references/providers.md +71 -0
- package/skills/ai-research/16-prompt-engineering/instructor/references/validation.md +607 -0
- package/skills/ai-research/16-prompt-engineering/outlines/SKILL.md +652 -0
- package/skills/ai-research/16-prompt-engineering/outlines/references/backends.md +616 -0
- package/skills/ai-research/16-prompt-engineering/outlines/references/examples.md +774 -0
- package/skills/ai-research/16-prompt-engineering/outlines/references/json_generation.md +653 -0
- package/skills/ai-research/17-observability/langsmith/SKILL.md +422 -0
- package/skills/ai-research/17-observability/langsmith/references/advanced-usage.md +549 -0
- package/skills/ai-research/17-observability/langsmith/references/troubleshooting.md +538 -0
- package/skills/ai-research/17-observability/phoenix/SKILL.md +475 -0
- package/skills/ai-research/17-observability/phoenix/references/advanced-usage.md +620 -0
- package/skills/ai-research/17-observability/phoenix/references/troubleshooting.md +539 -0
- package/skills/ai-research/18-multimodal/audiocraft/SKILL.md +564 -0
- package/skills/ai-research/18-multimodal/audiocraft/references/advanced-usage.md +667 -0
- package/skills/ai-research/18-multimodal/audiocraft/references/troubleshooting.md +505 -0
- package/skills/ai-research/18-multimodal/blip-2/SKILL.md +564 -0
- package/skills/ai-research/18-multimodal/blip-2/references/advanced-usage.md +681 -0
- package/skills/ai-research/18-multimodal/blip-2/references/troubleshooting.md +527 -0
- package/skills/ai-research/18-multimodal/clip/SKILL.md +253 -0
- package/skills/ai-research/18-multimodal/clip/references/applications.md +208 -0
- package/skills/ai-research/18-multimodal/cosmos-policy/SKILL.md +402 -0
- package/skills/ai-research/18-multimodal/cosmos-policy/references/libero-commands.md +175 -0
- package/skills/ai-research/18-multimodal/cosmos-policy/references/robocasa-commands.md +147 -0
- package/skills/ai-research/18-multimodal/llava/SKILL.md +304 -0
- package/skills/ai-research/18-multimodal/llava/references/training.md +198 -0
- package/skills/ai-research/18-multimodal/openpi/SKILL.md +480 -0
- package/skills/ai-research/18-multimodal/openpi/references/checkpoints-and-env-map.md +86 -0
- package/skills/ai-research/18-multimodal/openpi/references/config-recipes.md +50 -0
- package/skills/ai-research/18-multimodal/openpi/references/pytorch-gotchas.md +49 -0
- package/skills/ai-research/18-multimodal/openpi/references/remote-client-pattern.md +48 -0
- package/skills/ai-research/18-multimodal/openpi/references/training-debugging.md +46 -0
- package/skills/ai-research/18-multimodal/openvla-oft/SKILL.md +441 -0
- package/skills/ai-research/18-multimodal/openvla-oft/references/aloha-workflow.md +141 -0
- package/skills/ai-research/18-multimodal/openvla-oft/references/config-troubleshooting.md +97 -0
- package/skills/ai-research/18-multimodal/openvla-oft/references/libero-workflow.md +115 -0
- package/skills/ai-research/18-multimodal/openvla-oft/references/paper-and-checkpoints.md +84 -0
- package/skills/ai-research/18-multimodal/segment-anything/SKILL.md +500 -0
- package/skills/ai-research/18-multimodal/segment-anything/references/advanced-usage.md +590 -0
- package/skills/ai-research/18-multimodal/segment-anything/references/troubleshooting.md +485 -0
- package/skills/ai-research/18-multimodal/stable-diffusion/SKILL.md +519 -0
- package/skills/ai-research/18-multimodal/stable-diffusion/references/advanced-usage.md +717 -0
- package/skills/ai-research/18-multimodal/stable-diffusion/references/troubleshooting.md +556 -0
- package/skills/ai-research/18-multimodal/whisper/SKILL.md +317 -0
- package/skills/ai-research/18-multimodal/whisper/references/languages.md +190 -0
- package/skills/ai-research/19-emerging-techniques/knowledge-distillation/SKILL.md +458 -0
- package/skills/ai-research/19-emerging-techniques/knowledge-distillation/references/minillm.md +335 -0
- package/skills/ai-research/19-emerging-techniques/long-context/SKILL.md +536 -0
- package/skills/ai-research/19-emerging-techniques/long-context/references/extension_methods.md +469 -0
- package/skills/ai-research/19-emerging-techniques/long-context/references/fine_tuning.md +612 -0
- package/skills/ai-research/19-emerging-techniques/long-context/references/rope.md +403 -0
- package/skills/ai-research/19-emerging-techniques/model-merging/SKILL.md +497 -0
- package/skills/ai-research/19-emerging-techniques/model-merging/references/coefficient-tuning.md +415 -0
- package/skills/ai-research/19-emerging-techniques/model-merging/references/evaluation.md +463 -0
- package/skills/ai-research/19-emerging-techniques/model-merging/references/examples.md +429 -0
- package/skills/ai-research/19-emerging-techniques/model-merging/references/methods.md +353 -0
- package/skills/ai-research/19-emerging-techniques/model-pruning/SKILL.md +495 -0
- package/skills/ai-research/19-emerging-techniques/model-pruning/references/wanda.md +348 -0
- package/skills/ai-research/19-emerging-techniques/moe-training/SKILL.md +526 -0
- package/skills/ai-research/19-emerging-techniques/moe-training/references/architectures.md +433 -0
- package/skills/ai-research/19-emerging-techniques/moe-training/references/inference.md +349 -0
- package/skills/ai-research/19-emerging-techniques/moe-training/references/training.md +426 -0
- package/skills/ai-research/19-emerging-techniques/speculative-decoding/SKILL.md +467 -0
- package/skills/ai-research/19-emerging-techniques/speculative-decoding/references/lookahead.md +310 -0
- package/skills/ai-research/19-emerging-techniques/speculative-decoding/references/medusa.md +351 -0
- package/skills/ai-research/20-ml-paper-writing/academic-plotting/SKILL.md +479 -0
- package/skills/ai-research/20-ml-paper-writing/academic-plotting/references/data-visualization.md +509 -0
- package/skills/ai-research/20-ml-paper-writing/academic-plotting/references/diagram-generation.md +395 -0
- package/skills/ai-research/20-ml-paper-writing/academic-plotting/references/style-guide.md +305 -0
- package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/SKILL.md +982 -0
- package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/references/checklists.md +348 -0
- package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/references/citation-workflow.md +563 -0
- package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/references/reviewer-guidelines.md +349 -0
- package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/references/sources.md +165 -0
- package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/references/writing-guide.md +477 -0
- package/skills/ai-research/20-ml-paper-writing/presenting-conference-talks/SKILL.md +298 -0
- package/skills/ai-research/20-ml-paper-writing/presenting-conference-talks/references/slide-templates.md +505 -0
- package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/SKILL.md +270 -0
- package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/references/checklist.md +279 -0
- package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/references/reviewer-guidelines.md +116 -0
- package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/references/section-blueprints.md +400 -0
- package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/references/systems-conferences.md +261 -0
- package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/references/writing-patterns.md +231 -0
- package/skills/ai-research/21-research-ideation/brainstorming-research-ideas/SKILL.md +384 -0
- package/skills/ai-research/21-research-ideation/creative-thinking-for-research/SKILL.md +366 -0
- package/skills/ai-research/22-agent-native-research-artifact/compiler/SKILL.md +245 -0
- package/skills/ai-research/22-agent-native-research-artifact/compiler/references/ara-schema.md +439 -0
- package/skills/ai-research/22-agent-native-research-artifact/compiler/references/exploration-tree-spec.md +125 -0
- package/skills/ai-research/22-agent-native-research-artifact/compiler/references/validation-checklist.md +149 -0
- package/skills/ai-research/22-agent-native-research-artifact/research-manager/SKILL.md +324 -0
- package/skills/ai-research/22-agent-native-research-artifact/research-manager/references/event-taxonomy.md +124 -0
- package/skills/ai-research/22-agent-native-research-artifact/research-manager/references/provenance-tags.md +190 -0
- package/skills/ai-research/22-agent-native-research-artifact/research-manager/references/session-protocol.md +162 -0
- package/skills/ai-research/22-agent-native-research-artifact/rigor-reviewer/SKILL.md +322 -0
- package/skills/ai-research/22-agent-native-research-artifact/rigor-reviewer/references/review-dimensions.md +182 -0
- package/skills/ai-research/SKILL.md +101 -0
- package/skills/ai-research/SOURCE +38 -0
- package/skills/ai-research/index/1-frame.md +18 -0
- package/skills/ai-research/index/2-data.md +21 -0
- package/skills/ai-research/index/3-train.md +48 -0
- package/skills/ai-research/index/4-measure.md +25 -0
- package/skills/ai-research/index/5-run.md +23 -0
- package/skills/ai-research/index/6-write.md +35 -0
- package/skills/ai-research/library.json +3456 -0
- package/skills/analyze-app/EVALS.md +82 -0
- package/skills/analyze-app/SKILL.md +188 -0
- package/skills/design-contract/EVALS.md +80 -0
- package/skills/design-contract/SKILL.md +171 -0
- package/skills/design-library/EVALS.md +85 -0
- package/skills/design-library/INDEX.md +59 -0
- package/skills/design-library/SKILL.md +58 -0
- package/skills/design-library/SOURCE +131 -0
- package/skills/design-library/adaptive-interfaces/skills/colour-independence/SKILL.md +90 -0
- package/skills/design-library/adaptive-interfaces/skills/flexible-typography/SKILL.md +83 -0
- package/skills/design-library/adaptive-interfaces/skills/information-density/SKILL.md +87 -0
- package/skills/design-library/adaptive-interfaces/skills/preference-audit/SKILL.md +70 -0
- package/skills/design-library/adaptive-interfaces/skills/responsive-accessibility/SKILL.md +86 -0
- package/skills/design-library/adaptive-interfaces/skills/responsive-review/SKILL.md +76 -0
- package/skills/design-library/adaptive-interfaces/skills/simplified-views/SKILL.md +97 -0
- package/skills/design-library/adaptive-interfaces/skills/specify/SKILL.md +63 -0
- package/skills/design-library/adaptive-interfaces/skills/user-preference-respect/SKILL.md +100 -0
- package/skills/design-library/cognitive-accessibility/skills/adaptive-personalisation/SKILL.md +61 -0
- package/skills/design-library/cognitive-accessibility/skills/assess-load/SKILL.md +48 -0
- package/skills/design-library/cognitive-accessibility/skills/cognitive-load-assessment/SKILL.md +60 -0
- package/skills/design-library/cognitive-accessibility/skills/contextual-help-design/SKILL.md +61 -0
- package/skills/design-library/cognitive-accessibility/skills/error-prevention-recovery/SKILL.md +71 -0
- package/skills/design-library/cognitive-accessibility/skills/focus-attention-design/SKILL.md +67 -0
- package/skills/design-library/cognitive-accessibility/skills/memory-load-reduction/SKILL.md +60 -0
- package/skills/design-library/cognitive-accessibility/skills/plain-language-design/SKILL.md +78 -0
- package/skills/design-library/cognitive-accessibility/skills/review/SKILL.md +56 -0
- package/skills/design-library/cognitive-accessibility/skills/simplify/SKILL.md +39 -0
- package/skills/design-library/cognitive-accessibility/skills/wayfinding-navigation/SKILL.md +64 -0
- package/skills/design-library/design-research/skills/behavioural-analytics/SKILL.md +33 -0
- package/skills/design-library/design-research/skills/qual-quant-triangulation/SKILL.md +33 -0
- package/skills/design-library/inclusive-interaction/skills/audit/SKILL.md +50 -0
- package/skills/design-library/inclusive-interaction/skills/design-flow/SKILL.md +58 -0
- package/skills/design-library/inclusive-interaction/skills/feedback-and-status/SKILL.md +76 -0
- package/skills/design-library/inclusive-interaction/skills/gesture-alternatives/SKILL.md +70 -0
- package/skills/design-library/inclusive-interaction/skills/keyboard-navigation/SKILL.md +99 -0
- package/skills/design-library/inclusive-interaction/skills/keyboard-review/SKILL.md +54 -0
- package/skills/design-library/inclusive-interaction/skills/motion-sensitivity/SKILL.md +79 -0
- package/skills/design-library/inclusive-interaction/skills/multi-modal-input/SKILL.md +70 -0
- package/skills/design-library/inclusive-interaction/skills/touch-target-design/SKILL.md +71 -0
- package/skills/design-library/inclusive-interaction/skills/voice-interaction/SKILL.md +68 -0
- package/skills/design-library/visual-critique/skills/critique-affordance/SKILL.md +45 -0
- package/skills/design-library/visual-critique/skills/critique-brand-consistency/SKILL.md +42 -0
- package/skills/design-library/visual-critique/skills/critique-color/SKILL.md +44 -0
- package/skills/design-library/visual-critique/skills/critique-composition/SKILL.md +46 -0
- package/skills/design-library/visual-critique/skills/critique-information-density/SKILL.md +45 -0
- package/skills/design-library/visual-critique/skills/critique-typography/SKILL.md +45 -0
- package/skills/design-library/visual-critique/skills/critique-visual-hierarchy/SKILL.md +40 -0
- package/skills/feature-audit/EVALS.md +83 -0
- package/skills/feature-audit/SKILL.md +326 -0
- package/skills/harness/EVALS.md +81 -0
- package/skills/harness/SKILL.md +88 -0
- package/skills/i-have-adhd/EVALS.md +80 -0
- package/skills/i-have-adhd/SKILL.md +183 -0
- package/skills/no-ai-slop/EVALS.md +89 -0
- package/skills/no-ai-slop/SKILL.md +209 -0
- package/skills/no-ai-slop/eval.md +52 -0
- package/skills/plan-add/EVALS.md +79 -0
- package/skills/plan-add/SKILL.md +179 -0
- package/skills/plan-add/render_table.py +72 -0
- package/skills/plan-status/EVALS.md +78 -0
- package/skills/plan-status/SKILL.md +52 -0
- package/skills/plan-sync/EVALS.md +80 -0
- package/skills/plan-sync/SKILL.md +69 -0
- package/skills/pm-frameworks/SKILL.md +33 -0
- package/skills/pm-frameworks/SOURCE +39 -0
- package/skills/pm-frameworks/intended-vs-implemented/SKILL.md +42 -0
- package/skills/pm-frameworks/opportunity-solution-tree/SKILL.md +64 -0
- package/skills/ponytail/EVALS.md +80 -0
- package/skills/ponytail/SKILL.md +124 -0
- package/skills/product-analysis/EVALS.md +103 -0
- package/skills/product-analysis/SKILL.md +361 -0
- package/skills/research/EVALS.md +104 -0
- package/skills/research/SKILL.md +570 -0
- package/skills/rl-env/SKILL.md +53 -0
- package/skills/rl-env/SOURCE +41 -0
- package/skills/rl-env/generate-nemo-gym-env/SKILL.md +169 -0
- package/skills/rl-env/generate-nemo-gym-env/references/architecture.md +114 -0
- package/skills/rl-env/generate-openenv-env/SKILL.md +183 -0
- package/skills/rl-env/generate-openenv-env/references/architecture.md +82 -0
- package/skills/rl-env/generate-ors-env/SKILL.md +209 -0
- package/skills/rl-env/generate-ors-env/references/architecture.md +113 -0
- package/skills/rl-env/generate-verifiers-env/SKILL.md +188 -0
- package/skills/rl-env/generate-verifiers-env/references/architecture.md +119 -0
- package/skills/rl-env/rl-env-from-description/SKILL.md +124 -0
- package/skills/rl-env/rl-env-from-description/references/interview.md +75 -0
- package/skills/rl-env/rl-env-from-description/references/nemo_gym.md +41 -0
- package/skills/rl-env/rl-env-from-description/references/openenv.md +35 -0
- package/skills/rl-env/rl-env-from-description/references/ors.md +50 -0
- package/skills/rl-env/rl-env-from-description/references/verifiers.md +39 -0
- package/skills/tezgah-contract/EVALS.md +78 -0
- package/skills/tezgah-contract/SKILL.md +792 -0
- package/statusline.py +129 -0
- package/workflows/graph-impact.js +153 -0
- package/workflows/graph-map.js +158 -0
- package/workflows/graph-review.js +170 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""One seam for TypeSafe (Jev) judgements: `available()` then one batched `ask()`.
|
|
3
|
+
|
|
4
|
+
Three callers want the same thing - a structured judgement over a state tezgah
|
|
5
|
+
would otherwise pay an agent to read: the analyze-app triage, the docs page
|
|
6
|
+
fallback, and the prompt-path skill hint - so the request lives here once,
|
|
7
|
+
stdlib only: one endpoint, one request per call normally, no SDK, no async.
|
|
8
|
+
A transient failure - a timeout, a connection error, a 5xx - gets one more
|
|
9
|
+
attempt and no more; a 4xx and a malformed reply never do (`ask()` below). A hook
|
|
10
|
+
may import this module, and a hook that raises takes a session down, so every
|
|
11
|
+
failure is a `None` instead.
|
|
12
|
+
|
|
13
|
+
Privacy, plainly: the state and the questions leave this machine for
|
|
14
|
+
`api.typesafe.ai` - for the triage the state IS the screen's own text (an admin
|
|
15
|
+
table or a mobile view as captured, plus the `--select` task sentence), so a
|
|
16
|
+
screen carrying personal data is read by a third party. Nothing else leaves -
|
|
17
|
+
no session id, no workspace path, no environment - and the seam does not
|
|
18
|
+
redact the state: sending it is the point, so scrubbing it would hide the risk
|
|
19
|
+
instead of stating it - and that is why the callers are explicit or opt-in, and
|
|
20
|
+
the `judge-off` switch is the off button for the whole path. Two callers redact
|
|
21
|
+
before they call: `bin/tezgah-route` sends its brief through `ti.redact`, and the
|
|
22
|
+
prompt-path skill hint sends the user's prompt redacted and cut at 2,000
|
|
23
|
+
characters, because a brief or a prompt can quote a token and neither is a
|
|
24
|
+
state a person chose to send.
|
|
25
|
+
|
|
26
|
+
The credential has two channels on purpose. `~/.zshenv` exports the env var for
|
|
27
|
+
an interactive shell, but a hook or a bin tool started by a host runs in a
|
|
28
|
+
non-interactive shell where `.zshenv` never runs - the export is absent there,
|
|
29
|
+
and the key file is the channel that survives. That is why the file is read
|
|
30
|
+
rather than the environment trusted.
|
|
31
|
+
|
|
32
|
+
Behind the credential there are two providers. TypeSafe answers in its own
|
|
33
|
+
schema; when no TypeSafe key resolves, the same questions go to an
|
|
34
|
+
OpenAI-compatible chat endpoint - OpenRouter, whose key rides the same two
|
|
35
|
+
channels (`OPENROUTER_API_KEY`, then `~/.config/openrouter/key`) - and its JSON
|
|
36
|
+
reply is mapped back into the shapes the callers already read. That path is a
|
|
37
|
+
fallback, never a peer: it is chosen only when `key()` is empty, it sends the
|
|
38
|
+
same state to a different host, and a reply that does not carry a question's
|
|
39
|
+
answer leaves that question absent, which every caller already reads as no
|
|
40
|
+
judgement.
|
|
41
|
+
|
|
42
|
+
Kill switch: `judge-off`, honoured by `available()`, so a caller can fall back to
|
|
43
|
+
its own deterministic path without knowing why the judgement is gone. It is the
|
|
44
|
+
master: each caller also names its own - `triage-off`, `docs-judge-off` - and
|
|
45
|
+
checks that in front of this one, so one tool's switch never silences another.
|
|
46
|
+
"""
|
|
47
|
+
import json
|
|
48
|
+
import os
|
|
49
|
+
import time
|
|
50
|
+
import urllib.parse
|
|
51
|
+
import urllib.request
|
|
52
|
+
|
|
53
|
+
import tezgah_paths as tp
|
|
54
|
+
|
|
55
|
+
URL = "https://api.typesafe.ai/v1/systemone"
|
|
56
|
+
KEY_FILE = "~/.config/typesafe/key"
|
|
57
|
+
MODEL = "jev-latest"
|
|
58
|
+
# The fallback provider: an OpenAI-compatible chat endpoint, its own key
|
|
59
|
+
# channels, and the cheap judge model this repository already quotes in its
|
|
60
|
+
# measured arm rows (`openrouter/deepseek/deepseek-v4-flash`).
|
|
61
|
+
OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions"
|
|
62
|
+
OPENROUTER_KEY_FILE = "~/.config/openrouter/key"
|
|
63
|
+
FALLBACK_MODEL = "deepseek/deepseek-v4-flash"
|
|
64
|
+
# The contract the fallback asks a chat model to answer in, one shape per
|
|
65
|
+
# question type this repository's callers send (`bin/tezgah-triage` and
|
|
66
|
+
# `hooks/tezgah_skill_pick.py` ask `noul`, `bin/tezgah-docs` and the triage's
|
|
67
|
+
# pair rows ask `choice`). It is prose because a chat endpoint has no schema
|
|
68
|
+
# field to carry it; every field it names is validated on the way back, and a
|
|
69
|
+
# question of any other type reads as unanswered rather than as a guess.
|
|
70
|
+
CHAT_SYSTEM = (
|
|
71
|
+
"You answer questions about the state that follows. Reply with one JSON "
|
|
72
|
+
"object and nothing else: {\"answers\": {\"<id>\": {...}}}, one entry per "
|
|
73
|
+
"question id, in the shape that question's type names:\n"
|
|
74
|
+
"noul -> {\"noul\": <probability 0..1 that the statement is true>}\n"
|
|
75
|
+
"choice -> {\"choice\": \"<the chosen label>\", \"probabilities\": "
|
|
76
|
+
"{\"<label>\": <probability>, ...}, \"confidence\": <0..1>}\n"
|
|
77
|
+
"Every probability is a number in 0..1 and the ones you list for one "
|
|
78
|
+
"question sum to 1. Answer every id you were given.")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# One opener for the module: a redirect that leaves the endpoint's host is
|
|
82
|
+
# refused, because urllib carries the Authorization header across the hop and
|
|
83
|
+
# the endpoint is repointable by `TEZGAH_TYPESAFE_URL`. A refusal surfaces as an
|
|
84
|
+
# HTTPError, which `ask()` already turns into a `None`.
|
|
85
|
+
OPENER = tp.guarded_opener()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def override(name, default):
|
|
89
|
+
"""The URL in env var `name`, else `default` - every endpoint override routes
|
|
90
|
+
through here. An `http://` URL off this machine raises ValueError: the bearer
|
|
91
|
+
key and the state would cross the network in clear (`tp.plain_http`;
|
|
92
|
+
loopback stays allowed for the tests' fakes)."""
|
|
93
|
+
url = os.environ.get(name, "").strip() or default
|
|
94
|
+
if tp.plain_http(url):
|
|
95
|
+
raise ValueError("%s is plain http off this machine: the key and the state "
|
|
96
|
+
"would cross the network in clear" % name)
|
|
97
|
+
return url
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def endpoint():
|
|
101
|
+
"""The evaluation endpoint, repointed by TEZGAH_TYPESAFE_URL (tests)."""
|
|
102
|
+
return override("TEZGAH_TYPESAFE_URL", URL)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def key():
|
|
106
|
+
"""The credential: TYPESAFE_API_KEY, else the key file, else None.
|
|
107
|
+
|
|
108
|
+
The file is stripped: it is written with a trailing newline, and a newline
|
|
109
|
+
inside an Authorization header is a header-injection attempt to the HTTP
|
|
110
|
+
layer, not a typo it will forgive."""
|
|
111
|
+
value = os.environ.get("TYPESAFE_API_KEY", "").strip()
|
|
112
|
+
if value:
|
|
113
|
+
return value
|
|
114
|
+
try:
|
|
115
|
+
with open(os.path.expanduser(KEY_FILE), encoding="utf-8") as fh:
|
|
116
|
+
return fh.read().strip() or None
|
|
117
|
+
except OSError:
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def openrouter_url():
|
|
122
|
+
"""The fallback endpoint, repointed by TEZGAH_OPENROUTER_URL (tests)."""
|
|
123
|
+
return override("TEZGAH_OPENROUTER_URL", OPENROUTER_URL)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def openrouter_key():
|
|
127
|
+
"""The fallback credential: OPENROUTER_API_KEY, else the key file, else None.
|
|
128
|
+
|
|
129
|
+
The same two channels as the TypeSafe key and for the same reason - a hook
|
|
130
|
+
runs where `~/.zshenv` never did - and the same `strip()`, because a newline
|
|
131
|
+
inside an Authorization header is an injection, not a typo."""
|
|
132
|
+
value = os.environ.get("OPENROUTER_API_KEY", "").strip()
|
|
133
|
+
if value:
|
|
134
|
+
return value
|
|
135
|
+
try:
|
|
136
|
+
with open(os.path.expanduser(OPENROUTER_KEY_FILE), encoding="utf-8") as fh:
|
|
137
|
+
return fh.read().strip() or None
|
|
138
|
+
except OSError:
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def fallback_model():
|
|
143
|
+
"""The chat model the fallback asks: TEZGAH_JUDGE_MODEL, else the table's.
|
|
144
|
+
|
|
145
|
+
A Jev id is meaningless to a chat endpoint, so the fallback ignores the
|
|
146
|
+
`model` argument rather than forwarding it, and the model a call really used
|
|
147
|
+
comes back on the result."""
|
|
148
|
+
return os.environ.get("TEZGAH_JUDGE_MODEL", "").strip() or cheap_default()
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def credential():
|
|
152
|
+
"""`(provider, secret)` for the first channel that resolves, else `(None, None)`.
|
|
153
|
+
|
|
154
|
+
TypeSafe wins whenever it resolves, so adding a fallback cannot move a
|
|
155
|
+
machine that already judges with Jev. The pair is returned rather than the
|
|
156
|
+
secret alone so that `available()` and `ask()` cannot disagree about which
|
|
157
|
+
provider a call will use."""
|
|
158
|
+
secret = key()
|
|
159
|
+
if secret:
|
|
160
|
+
return "typesafe", secret
|
|
161
|
+
secret = openrouter_key()
|
|
162
|
+
return ("openrouter", secret) if secret else (None, None)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def available():
|
|
166
|
+
"""True when a judgement can be asked for: a key resolves and no kill switch."""
|
|
167
|
+
return bool(credential()[1]) and not tp.off("judge-off")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def ask(state, questions, *, model=MODEL, timeout=30, attempts=2, deadline=None):
|
|
171
|
+
"""One batched call over `questions`; `{"answers", "usage", "latency_ms",
|
|
172
|
+
"model", "provider"}`.
|
|
173
|
+
|
|
174
|
+
`questions` is the API's own map - id -> `{type, instructions, criteria}` -
|
|
175
|
+
so a caller that needs a per-line or per-state pass sends every question in
|
|
176
|
+
one request and pays for the state once. The reply's usage is carried back
|
|
177
|
+
because a caller quotes what the judgement cost, and the model and provider
|
|
178
|
+
beside it because the fallback answers with a different one than the caller
|
|
179
|
+
named. The model is the one the reply names, else the one asked for: an alias
|
|
180
|
+
such as `jev-latest` hides a silent upgrade the reply's own field shows.
|
|
181
|
+
|
|
182
|
+
One request per call in the normal case, to whichever provider the credential
|
|
183
|
+
resolves - TypeSafe first, the chat fallback only when `key()` is empty. A
|
|
184
|
+
transient failure - a timeout, a connection error, a 5xx - gets one more
|
|
185
|
+
attempt, because a live measurement saw 2 of 50 calls lost that way while the
|
|
186
|
+
same cells answered on retry; a 4xx (a refused credential, a rejected body)
|
|
187
|
+
and a reply that parsed malformed are never retried, since the second request
|
|
188
|
+
would fail identically and only a call that already worked must not be billed
|
|
189
|
+
twice. The ceiling is one, so the worst case is one duplicated request on a
|
|
190
|
+
call that answered nothing anyway. A caller on a hook's budget passes
|
|
191
|
+
`attempts=1` and a `deadline` in seconds: urllib's `timeout` bounds one
|
|
192
|
+
socket operation, not the call, so only the deadline bounds its wall time.
|
|
193
|
+
|
|
194
|
+
A call that ends on a 401, 402 or 5xx marks the provider down for
|
|
195
|
+
`DOWN_FOR` seconds, and until then every call returns None without a
|
|
196
|
+
request (`_down`), so a dead credential is not re-paid on every prompt.
|
|
197
|
+
|
|
198
|
+
Total by design: no key, an unreadable state, a refused request, a timeout,
|
|
199
|
+
a reply that is not the documented shape - all `None`, never an exception."""
|
|
200
|
+
provider, secret = credential()
|
|
201
|
+
if not secret:
|
|
202
|
+
return None
|
|
203
|
+
try:
|
|
204
|
+
if provider == "typesafe":
|
|
205
|
+
used, url = model, endpoint()
|
|
206
|
+
body = json.dumps({"state": state, "model": used,
|
|
207
|
+
"questions": questions}).encode()
|
|
208
|
+
|
|
209
|
+
def send():
|
|
210
|
+
return _request(secret, body, timeout)
|
|
211
|
+
else:
|
|
212
|
+
used, url = fallback_model(), openrouter_url()
|
|
213
|
+
body = json.dumps(_chat_body(state, questions, used)).encode()
|
|
214
|
+
|
|
215
|
+
def send():
|
|
216
|
+
return _chat_request(secret, body, timeout, questions)
|
|
217
|
+
marker = _down_marker(provider, url, secret)
|
|
218
|
+
if _down(marker):
|
|
219
|
+
return None
|
|
220
|
+
except Exception:
|
|
221
|
+
return None
|
|
222
|
+
stop = None if deadline is None else time.monotonic() + deadline
|
|
223
|
+
for attempt in range(attempts):
|
|
224
|
+
try:
|
|
225
|
+
result = _bounded(send, stop)
|
|
226
|
+
except Exception as exc:
|
|
227
|
+
late = stop is not None and time.monotonic() >= stop
|
|
228
|
+
if attempt + 1 >= attempts or late or not _transient(exc):
|
|
229
|
+
code = getattr(exc, "code", None)
|
|
230
|
+
if code in (401, 402) or (isinstance(code, int) and code >= 500):
|
|
231
|
+
_mark_down(marker)
|
|
232
|
+
return None
|
|
233
|
+
continue
|
|
234
|
+
named = result.get("model")
|
|
235
|
+
result["model"] = named if isinstance(named, str) and named else used
|
|
236
|
+
result["provider"] = provider
|
|
237
|
+
return result
|
|
238
|
+
return None
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def _answer(result, id):
|
|
242
|
+
"""The raw answer object for one question id, or None.
|
|
243
|
+
|
|
244
|
+
One guard for every caller, because each of them had its own: a missing
|
|
245
|
+
answer, an answer of the wrong shape and an answer of `null` all have to read
|
|
246
|
+
the same way in every caller, and three copies of that is three places for the
|
|
247
|
+
fourth caller to disagree."""
|
|
248
|
+
answers = result.get("answers") if isinstance(result, dict) else None
|
|
249
|
+
answer = answers.get(id) if isinstance(answers, dict) else None
|
|
250
|
+
return answer if isinstance(answer, dict) else None
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def choice(result, id):
|
|
254
|
+
"""The option a Choice question took, or None.
|
|
255
|
+
|
|
256
|
+
A `null`, an answer of another type and an option that is not a string all read
|
|
257
|
+
as no option taken, rather than as an option a caller then compares with `==`."""
|
|
258
|
+
answer = _answer(result, id)
|
|
259
|
+
value = answer.get("choice") if answer else None
|
|
260
|
+
return value if isinstance(value, str) else None
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def noul(result, id, option=None):
|
|
264
|
+
"""The probability a Noul question came back with, or None.
|
|
265
|
+
|
|
266
|
+
Returned as a `float`, so a caller's arithmetic and its threshold do not have
|
|
267
|
+
to re-check the type the module already checked. With `option`, the
|
|
268
|
+
probability the reply put on that option of a Choice answer instead: a Choice
|
|
269
|
+
prints a distribution rather than one number, and the triage's row for each of
|
|
270
|
+
its focus/active pair is that option's share of it."""
|
|
271
|
+
answer = _answer(result, id)
|
|
272
|
+
if not answer:
|
|
273
|
+
return None
|
|
274
|
+
if option is None:
|
|
275
|
+
value = answer.get("noul")
|
|
276
|
+
else:
|
|
277
|
+
chances = answer.get("probabilities")
|
|
278
|
+
value = chances.get(option) if isinstance(chances, dict) else None
|
|
279
|
+
return float(value) if isinstance(value, (int, float)) else None
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def _transient(exc):
|
|
283
|
+
"""True for a failure a second identical request may not hit again.
|
|
284
|
+
|
|
285
|
+
A 5xx is upstream having a moment; a `URLError`, a timeout or any other
|
|
286
|
+
`OSError` is the link rather than the request. Everything else is
|
|
287
|
+
deterministic and must not be retried - a 4xx, above all a refused
|
|
288
|
+
credential, and a reply that parsed but is malformed."""
|
|
289
|
+
code = getattr(exc, "code", None)
|
|
290
|
+
if isinstance(code, int):
|
|
291
|
+
return code >= 500
|
|
292
|
+
return isinstance(exc, OSError)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def _request(secret, body, timeout):
|
|
296
|
+
"""One POST: the documented return, or the exception `ask()` decides on.
|
|
297
|
+
|
|
298
|
+
Split from `ask()` so the retry re-sends the body already serialized rather
|
|
299
|
+
than rebuilding it, and so the URL parse stays inside `ask()`'s try: a
|
|
300
|
+
scheme-less override raises ValueError there and becomes a None like any
|
|
301
|
+
other failure rather than escaping."""
|
|
302
|
+
request = urllib.request.Request(endpoint(), data=body, headers={
|
|
303
|
+
"Authorization": "Bearer " + secret,
|
|
304
|
+
"Content-Type": "application/json"})
|
|
305
|
+
started = time.monotonic()
|
|
306
|
+
with OPENER.open(request, timeout=timeout) as response:
|
|
307
|
+
data = json.load(response)
|
|
308
|
+
usage = data["usage"]
|
|
309
|
+
return {"answers": data["answers"],
|
|
310
|
+
"usage": {"input_tokens": int(usage["input_tokens"]),
|
|
311
|
+
"output_tokens": int(usage["output_tokens"])},
|
|
312
|
+
"latency_ms": int((time.monotonic() - started) * 1000),
|
|
313
|
+
"model": data.get("model")}
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def _chat_body(state, questions, model):
|
|
317
|
+
"""The chat-completions body for one batched fallback call.
|
|
318
|
+
|
|
319
|
+
`temperature: 0` because a judgement that moves between two identical calls
|
|
320
|
+
is not a measurement, and the JSON-object response format because prose
|
|
321
|
+
around the object is the one failure mode a chat endpoint adds to the
|
|
322
|
+
TypeSafe shape."""
|
|
323
|
+
return {"model": model, "temperature": 0,
|
|
324
|
+
"response_format": {"type": "json_object"},
|
|
325
|
+
"messages": [
|
|
326
|
+
{"role": "system", "content": CHAT_SYSTEM},
|
|
327
|
+
{"role": "user",
|
|
328
|
+
"content": json.dumps({"state": state,
|
|
329
|
+
"questions": questions})}]}
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def _chat_request(secret, body, timeout, questions, url=None):
|
|
333
|
+
"""One POST to an OpenAI-compatible chat endpoint - the fallback's unless
|
|
334
|
+
`url` names another - mapped into the documented return.
|
|
335
|
+
|
|
336
|
+
A reply that carries no message content, or content that is not JSON, raises
|
|
337
|
+
here and `_transient()` refuses to retry it - the same reading as a malformed
|
|
338
|
+
TypeSafe reply. Usage keys come back in the OpenAI spelling and are carried
|
|
339
|
+
in the seam's own (`{"input_tokens", "output_tokens"}`), so a caller's cost
|
|
340
|
+
row reads one usage shape whichever provider answered."""
|
|
341
|
+
request = urllib.request.Request(url or openrouter_url(), data=body, headers={
|
|
342
|
+
"Authorization": "Bearer " + secret,
|
|
343
|
+
"Content-Type": "application/json"})
|
|
344
|
+
started = time.monotonic()
|
|
345
|
+
with OPENER.open(request, timeout=timeout) as response:
|
|
346
|
+
data = json.load(response)
|
|
347
|
+
try:
|
|
348
|
+
content = data["choices"][0]["message"]["content"]
|
|
349
|
+
except (KeyError, IndexError, TypeError) as exc:
|
|
350
|
+
raise ValueError("the reply carried no message content") from exc
|
|
351
|
+
answers = _chat_answers(json.loads(content), questions)
|
|
352
|
+
usage = data.get("usage") or {}
|
|
353
|
+
return {"answers": answers,
|
|
354
|
+
"usage": {"input_tokens": int(usage.get("prompt_tokens") or 0),
|
|
355
|
+
"output_tokens": int(usage.get("completion_tokens") or 0)},
|
|
356
|
+
"latency_ms": int((time.monotonic() - started) * 1000),
|
|
357
|
+
"model": data.get("model")}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def _chat_answers(parsed, questions):
|
|
361
|
+
"""The answers a chat reply carried, filtered to the ids that were asked for.
|
|
362
|
+
|
|
363
|
+
A reply that is not an object, or that carries no answers map, is the same
|
|
364
|
+
failure as a malformed TypeSafe reply, and it raises so `ask()` reads it as
|
|
365
|
+
one. An id whose answer does not match its question's type is dropped rather
|
|
366
|
+
than coerced: a `bool` question answered in prose reads as unanswered, not
|
|
367
|
+
as a zero the triage would then score against."""
|
|
368
|
+
got = parsed.get("answers") if isinstance(parsed, dict) else None
|
|
369
|
+
if not isinstance(got, dict):
|
|
370
|
+
raise ValueError("the reply carried no answers object")
|
|
371
|
+
out = {}
|
|
372
|
+
for qid, question in questions.items():
|
|
373
|
+
kind = question.get("type") if isinstance(question, dict) else None
|
|
374
|
+
clean = _clean_answer(got.get(qid), kind)
|
|
375
|
+
if clean:
|
|
376
|
+
out[qid] = clean
|
|
377
|
+
return out
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def _clean_answer(raw, kind):
|
|
381
|
+
"""One answer in the shape its question type names, or None.
|
|
382
|
+
|
|
383
|
+
The two shapes this repository's callers send - `noul`, the probability a
|
|
384
|
+
statement holds, and `choice`, the label taken - map onto exactly what
|
|
385
|
+
`choice()`/`noul()` already read, so a fallback answer and a TypeSafe answer
|
|
386
|
+
are indistinguishable downstream. Any other type reads as no answer rather
|
|
387
|
+
than as a guess. Probabilities are kept only when they are numbers, because
|
|
388
|
+
`noul()` does the arithmetic on them."""
|
|
389
|
+
if not isinstance(raw, dict):
|
|
390
|
+
return None
|
|
391
|
+
if kind == "noul":
|
|
392
|
+
value = raw.get("noul")
|
|
393
|
+
return {"noul": float(value)} if isinstance(value, (int, float)) else None
|
|
394
|
+
if kind != "choice":
|
|
395
|
+
return None
|
|
396
|
+
if not isinstance(raw.get("choice"), str):
|
|
397
|
+
return None
|
|
398
|
+
answer = {"choice": raw["choice"]}
|
|
399
|
+
chances = raw.get("probabilities")
|
|
400
|
+
if isinstance(chances, dict):
|
|
401
|
+
kept = {str(k): float(v) for k, v in chances.items()
|
|
402
|
+
if isinstance(v, (int, float))}
|
|
403
|
+
if kept:
|
|
404
|
+
answer["probabilities"] = kept
|
|
405
|
+
confidence = raw.get("confidence")
|
|
406
|
+
if isinstance(confidence, (int, float)):
|
|
407
|
+
answer["confidence"] = float(confidence)
|
|
408
|
+
return answer
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def cheap_default():
|
|
412
|
+
"""The cheap row the models table names on `any`, else `FALLBACK_MODEL`.
|
|
413
|
+
|
|
414
|
+
Defined last on purpose: `docs/judge.md` cites this file by line number, so
|
|
415
|
+
new code goes below the last cited line instead of shifting every citation
|
|
416
|
+
after it. The import is lazy and inside this function because
|
|
417
|
+
`tezgah_models` imports this module - a module-level import back would be
|
|
418
|
+
the cycle - and it is guarded because a seam a hook cannot import is worse
|
|
419
|
+
than a stale id."""
|
|
420
|
+
try:
|
|
421
|
+
import tezgah_models
|
|
422
|
+
row = tezgah_models.cheap_model("any")
|
|
423
|
+
except Exception:
|
|
424
|
+
row = None
|
|
425
|
+
return row[0] if row else FALLBACK_MODEL
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
# How long a provider stays marked down after a 401, 402 or 5xx: five minutes,
|
|
429
|
+
# so a dead key or an empty account costs one refusal per five minutes rather
|
|
430
|
+
# than one per prompt, and a provider that comes back is asked again within the
|
|
431
|
+
# same working session. The marker is keyed on the provider, the endpoint and a
|
|
432
|
+
# digest of the credential, so a rotated key is asked at once.
|
|
433
|
+
DOWN_FOR = 300
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def _down_marker(provider, url, secret):
|
|
437
|
+
import hashlib
|
|
438
|
+
digest = hashlib.sha256("\0".join((provider, url, secret)).encode()).hexdigest()
|
|
439
|
+
return os.path.join(tp.cache_dir(), "judge-down", digest[:16])
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def _down(marker):
|
|
443
|
+
"""True while the marker is younger than `DOWN_FOR`; a marker dated in the
|
|
444
|
+
future (a clock step back, a copied cache) and any read error are up."""
|
|
445
|
+
try:
|
|
446
|
+
return 0 <= time.time() - os.path.getmtime(marker) < DOWN_FOR
|
|
447
|
+
except OSError:
|
|
448
|
+
return False
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def _mark_down(marker):
|
|
452
|
+
"""Best effort, like every other write a hook makes: a cache that cannot be
|
|
453
|
+
written costs the next call a request, never an exception."""
|
|
454
|
+
try:
|
|
455
|
+
os.makedirs(os.path.dirname(marker), exist_ok=True)
|
|
456
|
+
with open(marker, "w", encoding="utf-8"):
|
|
457
|
+
pass
|
|
458
|
+
except OSError:
|
|
459
|
+
pass
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def _bounded(send, stop):
|
|
463
|
+
"""`send()`, or TimeoutError once the monotonic `stop` passes.
|
|
464
|
+
|
|
465
|
+
The request runs on a daemon thread joined for the time that is left,
|
|
466
|
+
because no urllib timeout bounds a whole call. ponytail: a thread that
|
|
467
|
+
outlives its deadline is abandoned, not cancelled; it ends with its socket
|
|
468
|
+
timeout or with the process, which for a hook is moments later."""
|
|
469
|
+
if stop is None:
|
|
470
|
+
return send()
|
|
471
|
+
import threading
|
|
472
|
+
box = {}
|
|
473
|
+
|
|
474
|
+
def run():
|
|
475
|
+
try:
|
|
476
|
+
box["ok"] = send()
|
|
477
|
+
except Exception as exc:
|
|
478
|
+
box["err"] = exc
|
|
479
|
+
|
|
480
|
+
worker = threading.Thread(target=run, daemon=True)
|
|
481
|
+
worker.start()
|
|
482
|
+
worker.join(max(0.0, stop - time.monotonic()))
|
|
483
|
+
if worker.is_alive():
|
|
484
|
+
raise TimeoutError("the call outlived its deadline")
|
|
485
|
+
if "err" in box:
|
|
486
|
+
raise box["err"]
|
|
487
|
+
return box["ok"]
|