prompture 1.12.4.dev1__tar.gz → 1.12.5.dev1__tar.gz
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.
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/PKG-INFO +1 -1
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/_version.py +2 -2
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/cli/cli.py +10 -3
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/companion/__init__.py +4 -1
- prompture-1.12.5.dev1/prompture/companion/coding_tools.py +188 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/companion/local.py +36 -8
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/companion/server.py +157 -9
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/companion/summary.py +24 -14
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/__init__.py +14 -0
- prompture-1.12.5.dev1/prompture/infra/coding_agent_readers.py +860 -0
- prompture-1.12.5.dev1/prompture/infra/coding_agent_usage.py +422 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture.egg-info/PKG-INFO +1 -1
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture.egg-info/SOURCES.txt +3 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture.egg-info/scm_file_list.json +5 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/add-driver/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/add-driver/references/driver-template.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/add-example/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/add-field/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/add-persona/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/add-test/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/add-tool/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/create-pr/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/run-tests/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/scaffold-extraction/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.claude/skills/update-pricing/SKILL.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.env.copy +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/FUNDING.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/ISSUE_TEMPLATE/pricing_cost_mismatch.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/ISSUE_TEMPLATE/provider_driver_bug.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/ISSUE_TEMPLATE/schema_extraction_failure.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/scripts/update_docs_version.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/scripts/update_wrapper_version.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/workflows/dev.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/workflows/documentation.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/workflows/pricing-freshness.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/workflows/publish.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.github/workflows/security.yml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/.safety-project.ini +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/AGENTS.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/BREAKING_CHANGES.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/CLAUDE.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/CONTRIBUTING.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/LICENSE +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/MANIFEST.in +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/README.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/ROADMAP.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/SECURITY.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/VERSION +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/dev.ps1 +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/dev.sh +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/mypy_errors.txt +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/README.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/llm_to_json/README.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/llm_to_json/llm_to_json/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/llm_to_json/pyproject.toml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/llm_to_json/test.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/llm_to_toon/README.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/llm_to_toon/llm_to_toon/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/llm_to_toon/pyproject.toml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/packages/llm_to_toon/test.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/__main__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/_internal/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/_internal/json_encoder.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/agent.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/assistant.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/async_agent.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/async_conversation.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/async_deep_agent.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/conversation.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/deep/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/deep/planner.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/deep/subagents.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/deep/summarizer.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/deep/vfs.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/deep_agent.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/deep_prompts.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/deep_state.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/live_events.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/persona.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/review_loop.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/simulated_tools.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/skill_miner.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/skills.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/tool_grammars.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/tools_schema.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/agents/types.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/aio/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/bridges/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/bridges/tukuy_backend.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/checkpoints/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/checkpoints/core.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/checkpoints/stores.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/checkpoints/types.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/citations/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/citations/core.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/citations/types.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/cli/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/cli/formatters.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/cli/runner.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/cli/server.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/companion/live.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/dataset/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/dataset/dedup.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/dataset/evol.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/dataset/filters.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/dataset/formats.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/dataset/schemas.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/dataset/seed.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/dataset/synth.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/_media_usage.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/_openai_compat.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/_openai_compat_stream.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/_openai_responses.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/_prompt_cache.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/_prompted_tool_stream.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/_usage_reporting.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/aggregator_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/airllm_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/assemblyai_stt_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_aggregator_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_airllm_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_assemblyai_stt_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_azure_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_bedrock_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_bfl_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_cachibot_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_cartesia_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_claude_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_cohere_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_cohere_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_cohere_rerank_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_deepgram_stt_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_deepgram_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_deepseek_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_elevenlabs_stt_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_elevenlabs_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_embedding_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_fal_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_fal_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_google_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_google_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_google_vertexai_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_grok_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_grok_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_grok_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_groq_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_hugging_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_ideogram_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_img_gen_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_jina_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_jina_rerank_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_kev_decision_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_kling_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_kling_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_laya_decision_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_lmstudio_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_local_http_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_luma_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_minimax_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_minimax_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_mistral_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_mistral_moderation_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_modelscope_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_moonshot_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_muapi_aggregator_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_mxbai_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_mxbai_rerank_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_nomic_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_ollama_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_ollama_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_openai_compatible_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_openai_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_openai_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_openai_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_openai_moderation_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_openai_stt_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_openai_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_openrouter_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_pika_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_runway_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_runway_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_runway_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_stability_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_stt_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_systemone_compatible_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_tts_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_typesafe_decision_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_video_gen_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_voyage_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_voyage_rerank_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/async_zai_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/audio_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/azure_config.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/azure_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/bedrock_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/bfl_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/cachibot_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/cartesia_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/claude_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/cohere_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/cohere_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/cohere_rerank_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/decision_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/decision_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/deepgram_stt_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/deepgram_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/deepseek_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/driver_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/elevenlabs_stt_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/elevenlabs_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/embedding_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/embedding_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/fal_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/fal_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/google_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/google_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/google_vertexai_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/grok_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/grok_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/grok_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/groq_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/hugging_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/ideogram_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/img_gen_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/img_gen_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/jina_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/jina_rerank_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/job_runner.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/kev_decision_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/kling_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/kling_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/laya_decision_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/lipsync_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/lipsync_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/lmstudio_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/local_http_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/luma_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/media_capabilities.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/minimax_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/minimax_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/mistral_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/mistral_moderation_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/modelscope_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/moderation_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/moderation_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/moonshot_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/muapi_aggregator_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/music_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/music_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/mxbai_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/mxbai_rerank_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/nomic_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/ollama_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/ollama_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/openai_compatible_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/openai_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/openai_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/openai_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/openai_moderation_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/openai_stt_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/openai_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/openrouter_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/pika_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/provider_branding.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/provider_descriptors.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/rerank_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/rerank_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/runway_audio_transform_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/runway_capabilities.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/runway_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/runway_tts_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/runway_video_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/stability_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/stt_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/systemone_compatible_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/tts_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/typesafe_decision_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/vertex_img_gen_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/video_gen_base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/video_gen_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/vision_helpers.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/voyage_embedding_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/voyage_rerank_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/drivers/zai_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/eval/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/eval/base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/eval/faithfulness.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/eval/judge.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/eval/pairwise.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/eval/self_consistency.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/exceptions.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/context.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/context_eval.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/data/document_qa_policies.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/data/extraction_contacts.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/data/tool_task_inventory.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/fixtures.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/gates.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/harness.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/improve/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/improve/candidates.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/improve/optimizer.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/improve/promotion.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/improve/scorecard.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/integration.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/outcomes.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/policy.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/sandbox.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/scoring.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/strategies/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/strategies/base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/strategies/critique.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/strategies/direct.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/strategies/registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/strategies/retrieve.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/execution/types.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/_usage.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/async_core.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/code_extraction.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/core.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/few_shot.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/fields.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/reasoning.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/strategy.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/streaming.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/tools.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/tukuy_bridge.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/extraction/validator.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/gateway/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/gateway/anthropic_format.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/gateway/openai_format.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/gateway/reasoning_cache.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/gateway/responses_format.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/groups/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/groups/async_groups.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/groups/consensus.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/groups/debate.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/groups/fusion.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/groups/groups.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/groups/types.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/imaging/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/imaging/enhance.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/imaging/negative.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/imaging/set_planner.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/imaging/style_presets.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/accounts.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/billing.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/budget.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/cache.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/callbacks.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/capabilities.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/coding_agent_events.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/coding_agent_specs.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/coding_agents.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/compression.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/cost_mixin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/discovery.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/ledger.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/logging.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/media_pricing.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/media_rates.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/model_rates.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/otel.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/pricing.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/provider_env.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rate_limits.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/anthropic.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/azure.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/bedrock.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/cerebras.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/cohere.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/deepinfra.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/deepseek.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/fireworks.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/google.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/google_vertexai.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/groq.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/jina.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/kev.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/laya.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/mistral.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/mixedbread.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/moonshot.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/nomic.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/nvidia.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/openai.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/openrouter.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/perplexity.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/sambanova.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/siliconflow.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/together.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/typesafe.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/voyage.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/rates/xai.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/session.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/settings.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/token_counting.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/tracker.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/infra/tukuy_backend.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/chunking.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/detect.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/document.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/parsers/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/parsers/base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/parsers/csv_parser.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/parsers/docx.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/parsers/html.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/parsers/markdown.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/parsers/pdf.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/ingestion/parsers/xlsx.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/integrations/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/integrations/mcp_bridge.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/integrations/tukuy_bridge.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/jobs.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/kg/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/kg/core.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/kg/stores.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/kg/types.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/mcp/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/mcp/client.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/mcp/server.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/mcp/tools.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/media/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/media/agent_tools.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/media/audio.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/media/hosting.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/media/image.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/media/video.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pages/01-why-prompture.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pages/02-installation.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pages/03-quickstart.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pages/04-toon-input.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pages/05-test-harness.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pages/06-stability.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pages/07-migration.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/persistence/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/persistence/history.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/persistence/serialization.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/persistence/store.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pipeline/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pipeline/pipeline.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pipeline/resolver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/pipeline/routing.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/_aliases.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/anthropic_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/audio_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/cloud_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/decision_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/embedding_rerank_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/extras_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/google_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/image_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/local_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/openai_compatible_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/openai_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/builtins/video_plugin.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/plugins/discovery.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/py.typed +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/character.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/chunker_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/contextual.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/markdown.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/recursive.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/semantic.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/chunkers/token.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/documents.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loader_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/csv_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/docx_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/epub_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/html_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/json_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/markdown_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/pdf_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/text_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/loaders/xlsx_loader.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/pipeline.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/_fusion.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/hybrid.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/hyde.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/mmr.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/multi_query.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/retriever_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/similarity.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/retrievers/step_back.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/base.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/chroma.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/faiss.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/pgvector.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/pinecone.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/qdrant.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/vectorstore_registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/rag/vectorstores/weaviate.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/refusal/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/refusal/detector.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/refusal/evaluator.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/refusal/markers.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/async_driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/backoff.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/breaker.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/driver.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/errors.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/explain.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/headroom.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/keys.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/router.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/strategies.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/resilience/virtual.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/generator.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/templates/Dockerfile.j2 +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/templates/README.md.j2 +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/templates/config.py.j2 +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/templates/env.example.j2 +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/templates/main.py.j2 +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/templates/models.py.j2 +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/scaffold/templates/requirements.txt.j2 +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/security/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/security/injection.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/security/redaction.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/session_memory/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/session_memory/core.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/session_memory/stores.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/session_memory/types.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/swarm/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/swarm/environment.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/swarm/memory.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/swarm/scheduler.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/swarm/swarm.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/swarm/swarm_agent.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/swarm/types.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/testing/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/testing/driver_contract.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/tools/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/tools/code_exec.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/tools/web_search.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/__init__.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/architect.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/engine.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/errors.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/model.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/nodes.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/recovery.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/references.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/registry.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/scheduler.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture/workflow/state.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture.egg-info/dependency_links.txt +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture.egg-info/entry_points.txt +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture.egg-info/requires.txt +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture.egg-info/top_level.txt +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/prompture_cost_tracking.md +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/pyproject.toml +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/requirements.txt +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/scripts/check_pricing_freshness.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/setup.cfg +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/specs/basic_extraction.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/specs/schema_validation.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/specs/strategy_comparison.json +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/test.py +0 -0
- {prompture-1.12.4.dev1 → prompture-1.12.5.dev1}/test_version_diagnosis.py +0 -0
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.12.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 12,
|
|
21
|
+
__version__ = version = '1.12.5.dev1'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 12, 5, 'dev1')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -212,7 +212,12 @@ def test_suite(specfile: str, providers: str | None, models: str | None, fmt: st
|
|
|
212
212
|
type=int,
|
|
213
213
|
help="Stop when this process exits (used by apps that start the companion for themselves).",
|
|
214
214
|
)
|
|
215
|
-
|
|
215
|
+
@click.option(
|
|
216
|
+
"--coding-tools/--no-coding-tools",
|
|
217
|
+
default=True,
|
|
218
|
+
help="Also count the usage local coding agents (Claude Code, Codex, Kimi Code, …) log on disk (default: on).",
|
|
219
|
+
)
|
|
220
|
+
def companion(port: int, db_path: str | None, exit_with_pid: int | None, coding_tools: bool) -> None:
|
|
216
221
|
"""Serve this machine's Prompture usage to desktop companions (no hub needed).
|
|
217
222
|
|
|
218
223
|
Reads the usage ledger every Prompture call writes to, plus rate-limit
|
|
@@ -221,13 +226,15 @@ def companion(port: int, db_path: str | None, exit_with_pid: int | None) -> None
|
|
|
221
226
|
written to ~/.prompture/companion.json. If a companion is already running,
|
|
222
227
|
this prints its address and exits.
|
|
223
228
|
"""
|
|
224
|
-
from ..companion import CompanionServer, LedgerSource, running_instance
|
|
229
|
+
from ..companion import CodingToolSource, CompanionServer, LedgerSource, running_instance
|
|
225
230
|
|
|
226
231
|
existing = running_instance()
|
|
227
232
|
if existing:
|
|
228
233
|
click.echo(f"Prompture companion already running at {existing['url']} (pid {existing.get('pid')}).")
|
|
229
234
|
return
|
|
230
|
-
server = CompanionServer(
|
|
235
|
+
server = CompanionServer(
|
|
236
|
+
LedgerSource(db_path), port=port, coding_tools=CodingToolSource() if coding_tools else None
|
|
237
|
+
)
|
|
231
238
|
click.echo(f"Prompture companion on {server.url} - ledger {server.ledger.db_path}")
|
|
232
239
|
click.echo("Address and token in ~/.prompture/companion.json. Ctrl+C to stop.")
|
|
233
240
|
if exit_with_pid:
|
|
@@ -6,12 +6,14 @@ Two servers speak it:
|
|
|
6
6
|
adds keys, projects, alert rules and controls.
|
|
7
7
|
- **the local companion** (``prompture companion``) — no hub needed; reports
|
|
8
8
|
this machine's Prompture usage from the usage ledger, rate-limit headroom and
|
|
9
|
-
provider account balances
|
|
9
|
+
provider account balances, plus the usage local coding agents (Claude Code,
|
|
10
|
+
Codex, Kimi Code, Gemini CLI, Qwen Code, OpenCode, Cline, …) log on disk.
|
|
10
11
|
|
|
11
12
|
This package holds what both share — the live event bus, the spend / limits
|
|
12
13
|
aggregations and the API version — plus the local server itself.
|
|
13
14
|
"""
|
|
14
15
|
|
|
16
|
+
from .coding_tools import CodingToolSource
|
|
15
17
|
from .live import LiveBus, get_bus, new_request_id, sse_event, visible
|
|
16
18
|
from .local import LedgerSource
|
|
17
19
|
from .server import CompanionServer, read_state, running_instance
|
|
@@ -29,6 +31,7 @@ from .summary import (
|
|
|
29
31
|
__all__ = [
|
|
30
32
|
"COMPANION_API_VERSION",
|
|
31
33
|
"PERIODS",
|
|
34
|
+
"CodingToolSource",
|
|
32
35
|
"CompanionServer",
|
|
33
36
|
"LedgerSource",
|
|
34
37
|
"LiveBus",
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""Usage from coding agents that don't run through Prompture, for the companion.
|
|
2
|
+
|
|
3
|
+
The reading happens in the engine — :mod:`prompture.infra.coding_agent_usage`
|
|
4
|
+
and one reader per agent in :mod:`prompture.infra.coding_agent_readers`
|
|
5
|
+
(Claude Code, Codex, Kimi Code, Gemini CLI, Qwen Code, OpenCode, Cline,
|
|
6
|
+
Roo Code, Continue; Cursor and Antigravity are detected only). This module
|
|
7
|
+
adapts it to the companion API:
|
|
8
|
+
|
|
9
|
+
- calls join the ledger's rows in ``/v1/spend`` and stream as
|
|
10
|
+
``request.finished`` events tagged with the agent (``key_name``, ``tool``);
|
|
11
|
+
- plan windows (Codex from its logs; Claude Code only when opted in) join
|
|
12
|
+
``/v1/limits`` as ``source: "plan"`` targets;
|
|
13
|
+
- ``/v1/tools`` lists every agent: installed, runnable by Prompture, and its
|
|
14
|
+
usage for the period.
|
|
15
|
+
|
|
16
|
+
Costs are what the same tokens would cost on the API; subscriptions don't
|
|
17
|
+
bill per token. Only token counts, model names, times and folder names are
|
|
18
|
+
read — never prompts, replies or tool output.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import json
|
|
24
|
+
import logging
|
|
25
|
+
import os
|
|
26
|
+
import threading
|
|
27
|
+
import time
|
|
28
|
+
from datetime import datetime, timedelta, timezone
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
from typing import Any
|
|
31
|
+
|
|
32
|
+
from ..infra.coding_agent_usage import AgentCall, CodingAgentUsage, UsageReader, coding_agents_overview
|
|
33
|
+
from .live import LiveBus
|
|
34
|
+
from .summary import UsageRow, window_start
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger("prompture.companion")
|
|
37
|
+
|
|
38
|
+
#: Seconds an installed-agents answer is reused (it looks up executables on PATH).
|
|
39
|
+
OVERVIEW_TTL = 60.0
|
|
40
|
+
#: How far back calls are kept: a year of activity, plus a week of slack.
|
|
41
|
+
RETENTION = timedelta(days=372)
|
|
42
|
+
#: Companion choices that outlive a restart (today: whether Claude plan windows are fetched).
|
|
43
|
+
PREFS_FILE = Path.home() / ".prompture" / "companion-prefs.json"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _load_prefs(path: Path) -> dict[str, Any]:
|
|
47
|
+
try:
|
|
48
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
49
|
+
except (OSError, ValueError):
|
|
50
|
+
return {}
|
|
51
|
+
return data if isinstance(data, dict) else {}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def call_event(call: AgentCall, name: str) -> dict[str, Any]:
|
|
55
|
+
"""A ``request.finished`` payload for an agent call, shaped like the ledger's."""
|
|
56
|
+
return {
|
|
57
|
+
"request_id": call.id,
|
|
58
|
+
"ts": call.ts.isoformat(),
|
|
59
|
+
"key_id": None,
|
|
60
|
+
"key_name": name,
|
|
61
|
+
"model": call.model,
|
|
62
|
+
"served_by": None,
|
|
63
|
+
"project": call.project,
|
|
64
|
+
"status": "ok",
|
|
65
|
+
"error": None,
|
|
66
|
+
"prompt_tokens": call.input_tokens,
|
|
67
|
+
"completion_tokens": call.output_tokens,
|
|
68
|
+
"cost_usd": call.cost_usd,
|
|
69
|
+
"latency_ms": 0,
|
|
70
|
+
"attempts": 1,
|
|
71
|
+
"fallback": False,
|
|
72
|
+
"deprioritized": [],
|
|
73
|
+
"tool": call.agent,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class CodingToolSource:
|
|
78
|
+
"""Every local coding agent's usage, as the companion needs it.
|
|
79
|
+
|
|
80
|
+
With no arguments every registered reader runs. ``claude_dir`` /
|
|
81
|
+
``codex_dir`` (tests, custom locations) restrict it to Claude Code and
|
|
82
|
+
Codex at those folders; ``readers`` sets the list explicitly.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
def __init__(
|
|
86
|
+
self,
|
|
87
|
+
claude_dir: str | Path | None = None,
|
|
88
|
+
codex_dir: str | Path | None = None,
|
|
89
|
+
*,
|
|
90
|
+
plan_usage: bool | None = None,
|
|
91
|
+
cache_dir: str | Path | None = None,
|
|
92
|
+
readers: list[UsageReader] | None = None,
|
|
93
|
+
prefs_file: str | Path | None = PREFS_FILE,
|
|
94
|
+
) -> None:
|
|
95
|
+
from ..infra.coding_agent_readers import ClaudeCodeReader, CodexReader
|
|
96
|
+
from ..infra.coding_agent_usage import USAGE_READERS
|
|
97
|
+
|
|
98
|
+
self.prefs_file = Path(prefs_file) if prefs_file else None
|
|
99
|
+
explicit_dirs = bool(claude_dir or codex_dir)
|
|
100
|
+
if plan_usage is None and not explicit_dirs and "PROMPTURE_CLAUDE_PLAN_USAGE" not in os.environ:
|
|
101
|
+
# The environment wins; otherwise the choice made in a companion app.
|
|
102
|
+
plan_usage = bool(_load_prefs(self.prefs_file).get("claude_plan_usage")) if self.prefs_file else None
|
|
103
|
+
if readers is None:
|
|
104
|
+
claude = ClaudeCodeReader(claude_dir, plan_usage=plan_usage, cache_dir=cache_dir)
|
|
105
|
+
codex = CodexReader(codex_dir)
|
|
106
|
+
if explicit_dirs:
|
|
107
|
+
readers = [claude, codex]
|
|
108
|
+
else:
|
|
109
|
+
others = [cls() for agent, cls in USAGE_READERS.items() if agent not in ("claude", "codex")]
|
|
110
|
+
readers = [claude, codex, *others]
|
|
111
|
+
self.usage = CodingAgentUsage(readers, retention=RETENTION)
|
|
112
|
+
self.names = {r.agent: r.display_name for r in readers}
|
|
113
|
+
self._overview: tuple[float, list[dict[str, Any]]] | None = None
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def plan_usage(self) -> bool:
|
|
117
|
+
"""Whether Claude Code's plan windows are fetched (opt-in; see ``ClaudeCodeReader``)."""
|
|
118
|
+
return any(getattr(r, "plan_usage", False) for r in self.usage.readers)
|
|
119
|
+
|
|
120
|
+
def set_claude_plan_usage(self, enabled: bool) -> None:
|
|
121
|
+
"""Turn Claude Code's plan windows on or off, and remember the choice."""
|
|
122
|
+
for reader in self.usage.readers:
|
|
123
|
+
if hasattr(reader, "plan_usage"):
|
|
124
|
+
reader.plan_usage = enabled
|
|
125
|
+
if not enabled:
|
|
126
|
+
reader._plan = None # forget the last answer too
|
|
127
|
+
if self.prefs_file:
|
|
128
|
+
prefs = _load_prefs(self.prefs_file)
|
|
129
|
+
prefs["claude_plan_usage"] = enabled
|
|
130
|
+
try:
|
|
131
|
+
self.prefs_file.parent.mkdir(parents=True, exist_ok=True)
|
|
132
|
+
self.prefs_file.write_text(json.dumps(prefs), encoding="utf-8")
|
|
133
|
+
except OSError:
|
|
134
|
+
logger.debug("could not save companion prefs", exc_info=True)
|
|
135
|
+
|
|
136
|
+
def refresh(self, *, force: bool = False) -> list[AgentCall]:
|
|
137
|
+
"""Read what the logs gained since the last scan; returns the new calls."""
|
|
138
|
+
return self.usage.refresh(force=force)
|
|
139
|
+
|
|
140
|
+
def calls(self, period: str = "day", now: datetime | None = None, offset_minutes: int = 0) -> list[AgentCall]:
|
|
141
|
+
return self.usage.calls(window_start(period, now, offset_minutes))
|
|
142
|
+
|
|
143
|
+
def rows(self, period: str = "day", now: datetime | None = None, offset_minutes: int = 0) -> list[UsageRow]:
|
|
144
|
+
"""Calls in the current ``period`` window, as usage rows."""
|
|
145
|
+
return [
|
|
146
|
+
UsageRow(model=c.model, cost_usd=c.cost_usd, tokens=c.tokens, project=c.project)
|
|
147
|
+
for c in self.calls(period, now, offset_minutes)
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
def rate_limits(self) -> dict[str, dict[str, Any]]:
|
|
151
|
+
"""Plan windows keyed like provider targets: ``openai/codex``, ``claude/claude-code``."""
|
|
152
|
+
self.usage.refresh()
|
|
153
|
+
return self.usage.plan_limits()
|
|
154
|
+
|
|
155
|
+
def event(self, call: AgentCall) -> dict[str, Any]:
|
|
156
|
+
return call_event(call, self.names.get(call.agent, call.agent))
|
|
157
|
+
|
|
158
|
+
def tools(self, period: str = "day", now: datetime | None = None, offset_minutes: int = 0) -> dict[str, Any]:
|
|
159
|
+
"""``/v1/tools``: each agent's usage for the period, plus what is installed."""
|
|
160
|
+
if self._overview is None or time.monotonic() - self._overview[0] > OVERVIEW_TTL:
|
|
161
|
+
try:
|
|
162
|
+
self._overview = (time.monotonic(), coding_agents_overview())
|
|
163
|
+
except Exception:
|
|
164
|
+
logger.debug("coding agent overview failed", exc_info=True)
|
|
165
|
+
self._overview = (time.monotonic(), [])
|
|
166
|
+
start = window_start(period, now, offset_minutes)
|
|
167
|
+
return {
|
|
168
|
+
"period": period,
|
|
169
|
+
"start": start.isoformat(),
|
|
170
|
+
"agents": self.usage.summary(start),
|
|
171
|
+
"installed": [a for a in self._overview[1] if a["installed"]],
|
|
172
|
+
"claude_plan_usage": self.plan_usage,
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
def events_since(self, since: datetime, limit: int = 500) -> list[dict[str, Any]]:
|
|
176
|
+
"""``request.finished`` payloads for calls at or after ``since``, newest last."""
|
|
177
|
+
return [self.event(c) for c in self.usage.calls(since)[-limit:]]
|
|
178
|
+
|
|
179
|
+
def tail(self, bus: LiveBus, stop: threading.Event, interval: float = 3.0) -> None:
|
|
180
|
+
"""Publish a ``request.finished`` event for every call logged from now on."""
|
|
181
|
+
self.refresh(force=True)
|
|
182
|
+
while not stop.wait(interval):
|
|
183
|
+
try:
|
|
184
|
+
for call in sorted(self.refresh(force=True), key=lambda c: c.ts):
|
|
185
|
+
if datetime.now(timezone.utc) - call.ts < timedelta(minutes=30):
|
|
186
|
+
bus.publish("request.finished", self.event(call))
|
|
187
|
+
except Exception: # a bad log line must never stop the companion
|
|
188
|
+
logger.debug("coding tool scan failed", exc_info=True)
|
|
@@ -80,9 +80,9 @@ class LedgerSource:
|
|
|
80
80
|
project=_project(r["tags"]),
|
|
81
81
|
)
|
|
82
82
|
|
|
83
|
-
def rows(self, period: str = "day", now: datetime | None = None) -> list[UsageRow]:
|
|
84
|
-
"""Calls in the current UTC ``
|
|
85
|
-
start = window_start(period, now).isoformat()
|
|
83
|
+
def rows(self, period: str = "day", now: datetime | None = None, offset_minutes: int = 0) -> list[UsageRow]:
|
|
84
|
+
"""Calls in the current ``period`` window (UTC unless ``offset_minutes`` is given)."""
|
|
85
|
+
start = window_start(period, now, offset_minutes).isoformat()
|
|
86
86
|
return [
|
|
87
87
|
self._row(r)
|
|
88
88
|
for r in self._query(
|
|
@@ -91,6 +91,23 @@ class LedgerSource:
|
|
|
91
91
|
)
|
|
92
92
|
]
|
|
93
93
|
|
|
94
|
+
def daily(self, since: datetime, offset_minutes: int = 0) -> dict[str, dict[str, Any]]:
|
|
95
|
+
"""Calls, tokens and cost per local day since ``since``.
|
|
96
|
+
|
|
97
|
+
``offset_minutes`` is the reader's UTC offset as JavaScript reports it
|
|
98
|
+
(minutes *behind* UTC, e.g. 240 for UTC-4), so days break at local midnight.
|
|
99
|
+
"""
|
|
100
|
+
rows = self._query(
|
|
101
|
+
"SELECT date(timestamp, ?) AS day, COUNT(*) AS n, SUM(total_tokens) AS tokens, SUM(cost) AS cost "
|
|
102
|
+
"FROM usage_events WHERE timestamp >= ? GROUP BY day",
|
|
103
|
+
(f"{-offset_minutes:+d} minutes", since.isoformat()),
|
|
104
|
+
)
|
|
105
|
+
return {
|
|
106
|
+
r["day"]: {"requests": int(r["n"]), "tokens": int(r["tokens"] or 0), "cost_usd": float(r["cost"] or 0.0)}
|
|
107
|
+
for r in rows
|
|
108
|
+
if r["day"]
|
|
109
|
+
}
|
|
110
|
+
|
|
94
111
|
def rate_limits(self) -> dict[str, dict[str, Any]]:
|
|
95
112
|
"""Latest rate-limit snapshot per model, from recent calls' metadata."""
|
|
96
113
|
out: dict[str, dict[str, Any]] = {}
|
|
@@ -109,14 +126,25 @@ class LedgerSource:
|
|
|
109
126
|
rows = self._query("SELECT MAX(rowid) AS last FROM usage_events")
|
|
110
127
|
return int(rows[0]["last"] or 0) if rows else 0
|
|
111
128
|
|
|
129
|
+
_EVENT_COLUMNS = (
|
|
130
|
+
"SELECT rowid, id, timestamp, model_name, cost, prompt_tokens, completion_tokens, total_tokens, "
|
|
131
|
+
"elapsed_ms, status, error_message, tags, metadata FROM usage_events "
|
|
132
|
+
)
|
|
133
|
+
|
|
112
134
|
def events_after(self, rowid: int) -> list[tuple[int, dict[str, Any]]]:
|
|
113
135
|
"""``request.finished`` payloads for rows newer than *rowid*."""
|
|
136
|
+
return self._events(self._EVENT_COLUMNS + "WHERE rowid > ? ORDER BY rowid", (rowid,))
|
|
137
|
+
|
|
138
|
+
def events_since(self, since: datetime, limit: int = 500) -> list[dict[str, Any]]:
|
|
139
|
+
"""``request.finished`` payloads for calls at or after ``since``, newest last."""
|
|
140
|
+
rows = self._events(
|
|
141
|
+
self._EVENT_COLUMNS + "WHERE timestamp >= ? ORDER BY rowid DESC LIMIT ?", (since.isoformat(), limit)
|
|
142
|
+
)
|
|
143
|
+
return [event for _, event in reversed(rows)]
|
|
144
|
+
|
|
145
|
+
def _events(self, sql: str, params: tuple) -> list[tuple[int, dict[str, Any]]]:
|
|
114
146
|
out = []
|
|
115
|
-
for r in self._query(
|
|
116
|
-
"SELECT rowid, id, timestamp, model_name, cost, prompt_tokens, completion_tokens, total_tokens, "
|
|
117
|
-
"elapsed_ms, status, error_message, tags, metadata FROM usage_events WHERE rowid > ? ORDER BY rowid",
|
|
118
|
-
(rowid,),
|
|
119
|
-
):
|
|
147
|
+
for r in self._query(sql, params):
|
|
120
148
|
meta = _meta(r["metadata"])
|
|
121
149
|
route = meta.get("route") if isinstance(meta.get("route"), dict) else {}
|
|
122
150
|
attempts = sum(1 for a in route.get("attempts", []) if a.get("outcome") in ("ok", "error")) or 1
|
|
@@ -9,6 +9,11 @@ Prompture usage with no hub at all:
|
|
|
9
9
|
- ``GET /v1/spend?period=day|week|month`` and ``GET /v1/limits``.
|
|
10
10
|
- ``GET /v1/alerts`` — always empty; alert rules live in the hub.
|
|
11
11
|
|
|
12
|
+
With a :class:`~.coding_tools.CodingToolSource` it also counts the calls local
|
|
13
|
+
coding agents (Claude Code, Codex, Kimi Code, Gemini CLI, …) log on disk, adds
|
|
14
|
+
their plan windows to the limits, and serves ``GET /v1/tools?period=`` — each
|
|
15
|
+
agent's usage plus which agents are installed.
|
|
16
|
+
|
|
12
17
|
It listens on ``127.0.0.1`` only, on a free port the OS picks, and writes the
|
|
13
18
|
address and a random bearer token to ``~/.prompture/companion.json`` (readable
|
|
14
19
|
only by the current user on POSIX). Readers take both from there. Only the
|
|
@@ -29,9 +34,10 @@ from pathlib import Path
|
|
|
29
34
|
from typing import Any
|
|
30
35
|
from urllib.parse import parse_qs, urlparse
|
|
31
36
|
|
|
37
|
+
from .coding_tools import CodingToolSource
|
|
32
38
|
from .live import LiveBus, get_bus, sse_event
|
|
33
39
|
from .local import LedgerSource
|
|
34
|
-
from .summary import COMPANION_API_VERSION, PERIODS, account_limits, provider_limits, summarize_spend
|
|
40
|
+
from .summary import COMPANION_API_VERSION, PERIODS, UsageRow, account_limits, provider_limits, summarize_spend
|
|
35
41
|
|
|
36
42
|
logger = logging.getLogger("prompture.companion")
|
|
37
43
|
|
|
@@ -39,13 +45,23 @@ STATE_FILE = Path.home() / ".prompture" / "companion.json"
|
|
|
39
45
|
HEARTBEAT_SECONDS = 15.0
|
|
40
46
|
|
|
41
47
|
#: What a client can rely on from this server. The hub advertises more.
|
|
42
|
-
FEATURES = {
|
|
48
|
+
FEATURES = {
|
|
49
|
+
"live": "/v1/live",
|
|
50
|
+
"limits": "/v1/limits",
|
|
51
|
+
"spend": "/v1/spend",
|
|
52
|
+
"alerts": "/v1/alerts",
|
|
53
|
+
"tools": "/v1/tools",
|
|
54
|
+
"activity": "/v1/activity",
|
|
55
|
+
"recent": "/v1/recent",
|
|
56
|
+
}
|
|
43
57
|
CAPABILITIES = {
|
|
44
58
|
"running_calls": False, # the ledger only sees calls after they finish
|
|
45
59
|
"projects": True,
|
|
46
60
|
"key_controls": False,
|
|
47
61
|
"provider_controls": False,
|
|
48
62
|
"alert_rules": False,
|
|
63
|
+
"coding_tools": False,
|
|
64
|
+
"activity": True,
|
|
49
65
|
}
|
|
50
66
|
|
|
51
67
|
|
|
@@ -58,14 +74,14 @@ def _version() -> str:
|
|
|
58
74
|
return "0"
|
|
59
75
|
|
|
60
76
|
|
|
61
|
-
def info() -> dict[str, Any]:
|
|
77
|
+
def info(coding_tools: bool = False) -> dict[str, Any]:
|
|
62
78
|
return {
|
|
63
79
|
"service": "prompture",
|
|
64
80
|
"mode": "local",
|
|
65
81
|
"version": _version(),
|
|
66
82
|
"api_version": COMPANION_API_VERSION,
|
|
67
83
|
"features": dict(FEATURES),
|
|
68
|
-
"capabilities":
|
|
84
|
+
"capabilities": {**CAPABILITIES, "coding_tools": coding_tools},
|
|
69
85
|
}
|
|
70
86
|
|
|
71
87
|
|
|
@@ -87,6 +103,14 @@ def _write_state(path: Path, data: dict[str, Any]) -> None:
|
|
|
87
103
|
os.replace(tmp, path)
|
|
88
104
|
|
|
89
105
|
|
|
106
|
+
def _tz_offset(query: dict[str, str]) -> int:
|
|
107
|
+
"""``tz_offset`` (minutes behind UTC, as JavaScript reports it); 0 = UTC windows."""
|
|
108
|
+
try:
|
|
109
|
+
return min(840, max(-840, int(query.get("tz_offset", "0"))))
|
|
110
|
+
except ValueError:
|
|
111
|
+
return 0
|
|
112
|
+
|
|
113
|
+
|
|
90
114
|
class _Handler(BaseHTTPRequestHandler):
|
|
91
115
|
server: CompanionServer # type: ignore[assignment]
|
|
92
116
|
protocol_version = "HTTP/1.1"
|
|
@@ -108,22 +132,66 @@ class _Handler(BaseHTTPRequestHandler):
|
|
|
108
132
|
token = header[7:].strip() if header.lower().startswith("bearer ") else ""
|
|
109
133
|
return bool(token) and secrets.compare_digest(token, self.server.token)
|
|
110
134
|
|
|
135
|
+
def do_POST(self) -> None:
|
|
136
|
+
url = urlparse(self.path)
|
|
137
|
+
if not self._authorized():
|
|
138
|
+
return self._json(401, {"detail": "Missing or wrong companion token (see ~/.prompture/companion.json)."})
|
|
139
|
+
if url.path == "/v1/tools/claude-plan" and self.server.coding_tools is not None:
|
|
140
|
+
try:
|
|
141
|
+
length = int(self.headers.get("Content-Length") or 0)
|
|
142
|
+
body = json.loads(self.rfile.read(length) or b"{}")
|
|
143
|
+
except ValueError:
|
|
144
|
+
return self._json(400, {"detail": "Body must be JSON."})
|
|
145
|
+
if not isinstance(body, dict) or not isinstance(body.get("enabled"), bool):
|
|
146
|
+
return self._json(422, {"detail": 'Send {"enabled": true|false}.'})
|
|
147
|
+
self.server.coding_tools.set_claude_plan_usage(body["enabled"])
|
|
148
|
+
return self._json(200, {"claude_plan_usage": self.server.coding_tools.plan_usage})
|
|
149
|
+
return self._json(404, {"detail": "Not found"})
|
|
150
|
+
|
|
111
151
|
def do_GET(self) -> None:
|
|
112
152
|
url = urlparse(self.path)
|
|
113
153
|
query = {k: v[-1] for k, v in parse_qs(url.query).items()}
|
|
114
154
|
if url.path == "/v1/companion/info":
|
|
115
|
-
return self._json(200, info())
|
|
155
|
+
return self._json(200, info(self.server.coding_tools is not None))
|
|
116
156
|
if not self._authorized():
|
|
117
157
|
return self._json(401, {"detail": "Missing or wrong companion token (see ~/.prompture/companion.json)."})
|
|
118
158
|
if url.path == "/v1/spend":
|
|
119
159
|
period = query.get("period", "day")
|
|
120
160
|
if period not in PERIODS:
|
|
121
161
|
return self._json(422, {"detail": "period must be day, week or month"})
|
|
122
|
-
|
|
162
|
+
sources = query.get("sources", "all")
|
|
163
|
+
if sources not in ("all", "api"):
|
|
164
|
+
return self._json(422, {"detail": "sources must be all or api"})
|
|
165
|
+
# "api": only calls made through Prompture, billed per token — what budgets measure.
|
|
166
|
+
offset = _tz_offset(query)
|
|
167
|
+
rows = self.server.rows(period, api_only=sources == "api", offset_minutes=offset)
|
|
168
|
+
return self._json(200, summarize_spend(rows, period, offset_minutes=offset))
|
|
123
169
|
if url.path == "/v1/limits":
|
|
124
170
|
return self._json(200, self.server.limits(accounts=query.get("accounts", "true") != "false"))
|
|
125
171
|
if url.path == "/v1/alerts":
|
|
126
172
|
return self._json(200, [])
|
|
173
|
+
if url.path == "/v1/recent":
|
|
174
|
+
try:
|
|
175
|
+
minutes = min(24 * 60, max(1, int(query.get("minutes", "30"))))
|
|
176
|
+
except ValueError:
|
|
177
|
+
return self._json(422, {"detail": "minutes must be an integer"})
|
|
178
|
+
return self._json(200, self.server.recent(minutes))
|
|
179
|
+
if url.path == "/v1/activity":
|
|
180
|
+
try:
|
|
181
|
+
days = min(400, max(1, int(query.get("days", "371"))))
|
|
182
|
+
offset = min(840, max(-840, int(query.get("tz_offset", "0"))))
|
|
183
|
+
except ValueError:
|
|
184
|
+
return self._json(422, {"detail": "days and tz_offset must be integers"})
|
|
185
|
+
return self._json(200, self.server.activity(days, offset))
|
|
186
|
+
if url.path == "/v1/tools":
|
|
187
|
+
if self.server.coding_tools is None:
|
|
188
|
+
return self._json(
|
|
189
|
+
404, {"detail": "Coding-tool usage is off (companion started with --no-coding-tools)."}
|
|
190
|
+
)
|
|
191
|
+
period = query.get("period", "day")
|
|
192
|
+
if period not in PERIODS:
|
|
193
|
+
return self._json(422, {"detail": "period must be day, week or month"})
|
|
194
|
+
return self._json(200, self.server.coding_tools.tools(period, offset_minutes=_tz_offset(query)))
|
|
127
195
|
if url.path == "/v1/live":
|
|
128
196
|
return self._live(query)
|
|
129
197
|
return self._json(404, {"detail": "Not found"})
|
|
@@ -196,25 +264,105 @@ class CompanionServer(ThreadingHTTPServer):
|
|
|
196
264
|
token: str | None = None,
|
|
197
265
|
bus: LiveBus | None = None,
|
|
198
266
|
state_path: Path | None = STATE_FILE,
|
|
267
|
+
coding_tools: CodingToolSource | None = None,
|
|
199
268
|
) -> None:
|
|
200
269
|
super().__init__(("127.0.0.1", port), _Handler)
|
|
201
270
|
self.ledger = ledger or LedgerSource()
|
|
202
271
|
self.token = token or secrets.token_urlsafe(32)
|
|
203
272
|
self.bus = bus or get_bus()
|
|
204
273
|
self.state_path = state_path
|
|
274
|
+
self.coding_tools = coding_tools
|
|
205
275
|
self.stopping = threading.Event()
|
|
206
276
|
|
|
207
277
|
@property
|
|
208
278
|
def url(self) -> str:
|
|
209
279
|
return f"http://127.0.0.1:{self.server_address[1]}"
|
|
210
280
|
|
|
281
|
+
def rows(self, period: str, *, api_only: bool = False, offset_minutes: int = 0) -> list[UsageRow]:
|
|
282
|
+
"""The ledger's rows for *period*, plus coding-tool calls when enabled (unless ``api_only``)."""
|
|
283
|
+
rows = self.ledger.rows(period, offset_minutes=offset_minutes)
|
|
284
|
+
if self.coding_tools is not None and not api_only:
|
|
285
|
+
rows += self.coding_tools.rows(period, offset_minutes=offset_minutes)
|
|
286
|
+
return rows
|
|
287
|
+
|
|
288
|
+
def rate_limits(self) -> dict[str, dict[str, Any]]:
|
|
289
|
+
limits = self.ledger.rate_limits()
|
|
290
|
+
if self.coding_tools is not None:
|
|
291
|
+
try:
|
|
292
|
+
limits.update(self.coding_tools.rate_limits())
|
|
293
|
+
except Exception: # coding-tool limits are extra context, never a failure
|
|
294
|
+
logger.debug("coding tool limits failed", exc_info=True)
|
|
295
|
+
return limits
|
|
296
|
+
|
|
297
|
+
def _tail(self) -> None:
|
|
298
|
+
threading.Thread(target=self.ledger.tail, args=(self.bus, self.stopping), daemon=True).start()
|
|
299
|
+
if self.coding_tools is not None:
|
|
300
|
+
threading.Thread(target=self.coding_tools.tail, args=(self.bus, self.stopping), daemon=True).start()
|
|
301
|
+
|
|
302
|
+
def recent(self, minutes: int = 30, limit: int = 500) -> list[dict[str, Any]]:
|
|
303
|
+
"""Calls that finished in the last ``minutes``, oldest first, as ``request.finished`` payloads.
|
|
304
|
+
|
|
305
|
+
Lets a client that just connected fill its recent-calls view before new
|
|
306
|
+
calls stream in over ``/v1/live``.
|
|
307
|
+
"""
|
|
308
|
+
from datetime import datetime, timedelta, timezone
|
|
309
|
+
|
|
310
|
+
since = datetime.now(timezone.utc) - timedelta(minutes=minutes)
|
|
311
|
+
events = self.ledger.events_since(since, limit)
|
|
312
|
+
if self.coding_tools is not None:
|
|
313
|
+
events += self.coding_tools.events_since(since, limit)
|
|
314
|
+
events.sort(key=lambda e: str(e.get("ts") or ""))
|
|
315
|
+
return [{"type": "request.finished", **e} for e in events[-limit:]]
|
|
316
|
+
|
|
317
|
+
def activity(self, days: int = 371, offset_minutes: int = 0) -> dict[str, Any]:
|
|
318
|
+
"""Per-day totals for the last ``days`` local days: Prompture calls plus coding tools.
|
|
319
|
+
|
|
320
|
+
Only days with activity are listed; each names what contributed
|
|
321
|
+
(``sources``: "Prompture" and each coding agent, by tokens).
|
|
322
|
+
"""
|
|
323
|
+
from datetime import datetime, timedelta, timezone
|
|
324
|
+
|
|
325
|
+
local_now = datetime.now(timezone.utc) - timedelta(minutes=offset_minutes)
|
|
326
|
+
first_day = local_now.date() - timedelta(days=days - 1)
|
|
327
|
+
since = datetime.combine(first_day, datetime.min.time(), timezone.utc) + timedelta(minutes=offset_minutes)
|
|
328
|
+
merged: dict[str, dict[str, Any]] = {}
|
|
329
|
+
|
|
330
|
+
def add(day: str, requests: int, tokens: int, cost: float, name: str) -> None:
|
|
331
|
+
d = merged.setdefault(day, {"date": day, "requests": 0, "tokens": 0, "cost_usd": 0.0, "sources": {}})
|
|
332
|
+
d["requests"] += requests
|
|
333
|
+
d["tokens"] += tokens
|
|
334
|
+
d["cost_usd"] += cost
|
|
335
|
+
s = d["sources"].setdefault(name, {"name": name, "requests": 0, "tokens": 0, "cost_usd": 0.0})
|
|
336
|
+
s["requests"] += requests
|
|
337
|
+
s["tokens"] += tokens
|
|
338
|
+
s["cost_usd"] += cost
|
|
339
|
+
|
|
340
|
+
for day, t in self.ledger.daily(since, offset_minutes).items():
|
|
341
|
+
add(day, t["requests"], t["tokens"], t["cost_usd"], "Prompture")
|
|
342
|
+
if self.coding_tools is not None:
|
|
343
|
+
names = self.coding_tools.names
|
|
344
|
+
for day, t in self.coding_tools.usage.daily(since, offset_minutes).items():
|
|
345
|
+
for agent, a in t["agents"].items():
|
|
346
|
+
add(day, a["requests"], a["tokens"], a["cost_usd"], names.get(agent, agent))
|
|
347
|
+
out = []
|
|
348
|
+
for day in sorted(merged):
|
|
349
|
+
if day < first_day.isoformat():
|
|
350
|
+
continue
|
|
351
|
+
d = merged[day]
|
|
352
|
+
d["cost_usd"] = round(d["cost_usd"], 6)
|
|
353
|
+
d["sources"] = sorted(
|
|
354
|
+
({**s, "cost_usd": round(s["cost_usd"], 6)} for s in d["sources"].values()), key=lambda s: -s["tokens"]
|
|
355
|
+
)
|
|
356
|
+
out.append(d)
|
|
357
|
+
return {"start": first_day.isoformat(), "end": local_now.date().isoformat(), "days": out}
|
|
358
|
+
|
|
211
359
|
def limits(self, *, accounts: bool = True) -> dict[str, Any]:
|
|
212
360
|
from datetime import datetime, timezone
|
|
213
361
|
|
|
214
362
|
body: dict[str, Any] = {
|
|
215
363
|
"generated_at": datetime.now(timezone.utc).isoformat(),
|
|
216
364
|
"keys": [],
|
|
217
|
-
"providers": provider_limits(self.
|
|
365
|
+
"providers": provider_limits(self.rate_limits()),
|
|
218
366
|
"accounts": None,
|
|
219
367
|
"paused_providers": [],
|
|
220
368
|
}
|
|
@@ -228,7 +376,7 @@ class CompanionServer(ThreadingHTTPServer):
|
|
|
228
376
|
|
|
229
377
|
def start_background(self) -> threading.Thread:
|
|
230
378
|
"""Start tailing the ledger and serving on background threads (for tests and embedding)."""
|
|
231
|
-
|
|
379
|
+
self._tail()
|
|
232
380
|
thread = threading.Thread(target=self.serve_forever, daemon=True)
|
|
233
381
|
thread.start()
|
|
234
382
|
return thread
|
|
@@ -237,7 +385,7 @@ class CompanionServer(ThreadingHTTPServer):
|
|
|
237
385
|
"""Serve until interrupted, advertising the address in the state file."""
|
|
238
386
|
if self.state_path is not None:
|
|
239
387
|
_write_state(self.state_path, {"url": self.url, "token": self.token, "pid": os.getpid()})
|
|
240
|
-
|
|
388
|
+
self._tail()
|
|
241
389
|
try:
|
|
242
390
|
self.serve_forever()
|
|
243
391
|
finally:
|