prompture 1.9.1.dev1__tar.gz → 1.9.1.dev2__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.9.1.dev1 → prompture-1.9.1.dev2}/PKG-INFO +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/_version.py +2 -2
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/agent.py +17 -6
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/assistant.py +15 -3
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/async_agent.py +45 -7
- prompture-1.9.1.dev2/prompture/drivers/_media_usage.py +118 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/aggregator_base.py +60 -8
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_aggregator_base.py +60 -8
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_base.py +6 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_cohere_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_embedding_base.py +6 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_img_gen_base.py +6 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_jina_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_mxbai_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_nomic_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_openai_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_video_gen_base.py +6 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_voyage_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/base.py +5 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/cohere_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/embedding_base.py +6 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/img_gen_base.py +6 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/jina_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/lipsync_base.py +44 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/music_base.py +41 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/mxbai_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/nomic_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/openai_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/video_gen_base.py +6 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/voyage_embedding_driver.py +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/__init__.py +4 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/cost_mixin.py +5 -2
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/tracker.py +63 -2
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/jobs.py +8 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/semantic.py +2 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/base.py +25 -2
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/chroma.py +3 -3
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/faiss.py +3 -3
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/pgvector.py +3 -3
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/pinecone.py +3 -3
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/qdrant.py +3 -3
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/weaviate.py +3 -3
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/nodes.py +16 -2
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture.egg-info/PKG-INFO +1 -1
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture.egg-info/SOURCES.txt +1 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/add-driver/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/add-driver/references/driver-template.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/add-example/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/add-field/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/add-persona/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/add-test/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/add-tool/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/create-pr/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/run-tests/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/scaffold-extraction/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.claude/skills/update-pricing/SKILL.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.env.copy +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/FUNDING.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/ISSUE_TEMPLATE/pricing_cost_mismatch.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/ISSUE_TEMPLATE/provider_driver_bug.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/ISSUE_TEMPLATE/schema_extraction_failure.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/scripts/update_docs_version.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/scripts/update_wrapper_version.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/workflows/dev.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/workflows/documentation.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/workflows/pricing-freshness.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/workflows/publish.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.github/workflows/security.yml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/.safety-project.ini +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/AGENTS.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/BREAKING_CHANGES.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/CLAUDE.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/CONTRIBUTING.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/LICENSE +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/MANIFEST.in +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/README.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/ROADMAP.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/SECURITY.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/VERSION +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/dev.ps1 +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/dev.sh +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/mypy_errors.txt +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/README.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/llm_to_json/README.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/llm_to_json/llm_to_json/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/llm_to_json/pyproject.toml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/llm_to_json/test.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/llm_to_toon/README.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/llm_to_toon/llm_to_toon/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/llm_to_toon/pyproject.toml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/packages/llm_to_toon/test.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/_internal/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/_internal/json_encoder.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/async_conversation.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/async_deep_agent.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/conversation.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/deep/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/deep/planner.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/deep/subagents.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/deep/summarizer.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/deep/vfs.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/deep_agent.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/deep_prompts.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/deep_state.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/live_events.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/persona.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/review_loop.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/simulated_tools.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/skill_miner.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/skills.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/tool_grammars.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/tools_schema.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/agents/types.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/aio/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/bridges/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/bridges/tukuy_backend.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/checkpoints/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/checkpoints/core.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/checkpoints/stores.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/checkpoints/types.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/citations/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/citations/core.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/citations/types.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/cli/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/cli/cli.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/cli/formatters.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/cli/runner.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/cli/server.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/dataset/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/dataset/dedup.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/dataset/evol.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/dataset/filters.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/dataset/formats.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/dataset/schemas.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/dataset/seed.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/dataset/synth.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/_openai_compat.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/_openai_compat_stream.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/_prompt_cache.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/_prompted_tool_stream.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/airllm_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/assemblyai_stt_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_airllm_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_assemblyai_stt_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_azure_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_bedrock_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_bfl_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_cachibot_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_cartesia_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_claude_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_cohere_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_cohere_rerank_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_deepgram_stt_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_deepgram_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_deepseek_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_elevenlabs_stt_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_elevenlabs_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_fal_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_fal_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_google_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_google_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_google_vertexai_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_grok_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_grok_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_grok_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_groq_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_hugging_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_ideogram_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_jina_rerank_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_kling_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_kling_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_lmstudio_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_local_http_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_luma_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_minimax_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_minimax_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_mistral_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_mistral_moderation_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_modelscope_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_moonshot_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_muapi_aggregator_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_mxbai_rerank_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_ollama_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_ollama_embedding_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_openai_compatible_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_openai_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_openai_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_openai_moderation_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_openai_stt_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_openai_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_openrouter_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_pika_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_runway_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_runway_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_runway_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_stability_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_stt_base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_tts_base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_voyage_rerank_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_zai_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/audio_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/azure_config.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/azure_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/bedrock_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/bfl_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/cachibot_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/cartesia_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/claude_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/cohere_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/cohere_rerank_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/deepgram_stt_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/deepgram_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/deepseek_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/driver_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/elevenlabs_stt_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/elevenlabs_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/embedding_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/fal_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/fal_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/google_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/google_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/google_vertexai_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/grok_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/grok_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/grok_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/groq_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/hugging_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/ideogram_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/img_gen_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/jina_rerank_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/job_runner.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/kling_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/kling_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/lipsync_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/lmstudio_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/local_http_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/luma_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/media_capabilities.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/minimax_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/minimax_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/mistral_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/mistral_moderation_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/modelscope_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/moderation_base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/moderation_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/moonshot_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/muapi_aggregator_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/music_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/mxbai_rerank_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/ollama_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/ollama_embedding_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/openai_compatible_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/openai_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/openai_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/openai_moderation_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/openai_stt_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/openai_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/openrouter_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/pika_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/provider_branding.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/provider_descriptors.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/rerank_base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/rerank_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/runway_audio_transform_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/runway_capabilities.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/runway_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/runway_tts_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/runway_video_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/stability_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/stt_base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/tts_base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/vertex_img_gen_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/video_gen_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/vision_helpers.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/voyage_rerank_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/zai_driver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/eval/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/eval/base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/eval/faithfulness.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/eval/judge.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/eval/pairwise.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/eval/self_consistency.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/exceptions.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/async_core.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/code_extraction.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/core.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/few_shot.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/fields.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/reasoning.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/strategy.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/streaming.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/tools.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/tukuy_bridge.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/extraction/validator.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/groups/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/groups/async_groups.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/groups/consensus.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/groups/debate.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/groups/groups.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/groups/types.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/imaging/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/imaging/enhance.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/imaging/negative.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/imaging/set_planner.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/imaging/style_presets.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/budget.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/cache.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/callbacks.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/capabilities.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/coding_agent_events.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/coding_agent_specs.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/coding_agents.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/discovery.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/ledger.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/logging.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/media_pricing.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/media_rates.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/model_rates.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/pricing.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/provider_env.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/anthropic.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/azure.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/bedrock.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/cerebras.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/cohere.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/deepinfra.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/deepseek.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/fireworks.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/google.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/google_vertexai.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/groq.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/jina.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/mistral.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/mixedbread.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/moonshot.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/nomic.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/nvidia.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/openai.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/openrouter.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/perplexity.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/sambanova.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/siliconflow.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/together.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/voyage.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/rates/xai.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/session.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/settings.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/infra/tukuy_backend.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/chunking.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/detect.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/document.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/parsers/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/parsers/base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/parsers/csv_parser.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/parsers/docx.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/parsers/html.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/parsers/markdown.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/parsers/pdf.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/ingestion/parsers/xlsx.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/integrations/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/integrations/mcp_bridge.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/integrations/tukuy_bridge.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/kg/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/kg/core.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/kg/stores.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/kg/types.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/mcp/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/mcp/client.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/mcp/server.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/mcp/tools.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/media/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/media/agent_tools.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/media/audio.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/media/hosting.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/media/image.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/media/video.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pages/01-why-prompture.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pages/02-installation.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pages/03-quickstart.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pages/04-toon-input.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pages/05-test-harness.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pages/06-stability.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pages/07-migration.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/persistence/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/persistence/history.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/persistence/serialization.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/persistence/store.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pipeline/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pipeline/pipeline.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pipeline/resolver.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/pipeline/routing.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/_aliases.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/anthropic_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/audio_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/cloud_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/embedding_rerank_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/extras_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/google_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/image_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/local_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/openai_compatible_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/openai_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/builtins/video_plugin.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/plugins/discovery.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/py.typed +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/character.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/chunker_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/contextual.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/markdown.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/recursive.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/chunkers/token.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/documents.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loader_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/csv_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/docx_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/epub_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/html_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/json_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/markdown_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/pdf_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/text_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/loaders/xlsx_loader.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/pipeline.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/_fusion.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/base.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/hybrid.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/hyde.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/mmr.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/multi_query.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/retriever_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/similarity.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/retrievers/step_back.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/rag/vectorstores/vectorstore_registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/refusal/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/refusal/detector.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/refusal/evaluator.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/refusal/markers.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/generator.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/templates/Dockerfile.j2 +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/templates/README.md.j2 +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/templates/config.py.j2 +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/templates/env.example.j2 +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/templates/main.py.j2 +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/templates/models.py.j2 +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/scaffold/templates/requirements.txt.j2 +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/security/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/security/injection.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/security/redaction.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/session_memory/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/session_memory/core.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/session_memory/stores.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/session_memory/types.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/swarm/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/swarm/environment.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/swarm/memory.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/swarm/scheduler.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/swarm/swarm.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/swarm/swarm_agent.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/swarm/types.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/testing/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/testing/driver_contract.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/tools/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/tools/code_exec.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/tools/web_search.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/__init__.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/architect.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/engine.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/errors.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/model.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/references.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/registry.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/scheduler.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/workflow/state.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture.egg-info/dependency_links.txt +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture.egg-info/entry_points.txt +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture.egg-info/requires.txt +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture.egg-info/top_level.txt +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture_cost_tracking.md +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/pyproject.toml +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/requirements.txt +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/scripts/check_pricing_freshness.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/setup.cfg +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/specs/basic_extraction.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/specs/schema_validation.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/specs/strategy_comparison.json +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/test.py +0 -0
- {prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/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.9.1.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 9, 1, '
|
|
21
|
+
__version__ = version = '1.9.1.dev2'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 9, 1, 'dev2')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -133,7 +133,9 @@ def _get_first_param_name(fn: Callable[..., Any]) -> str:
|
|
|
133
133
|
return ""
|
|
134
134
|
|
|
135
135
|
|
|
136
|
-
def _parse_simulated_tool_call(
|
|
136
|
+
def _parse_simulated_tool_call(
|
|
137
|
+
content: str, known_tools: Any | None = None
|
|
138
|
+
) -> tuple[str, dict[str, Any]] | None:
|
|
137
139
|
"""Recognise a prompted (simulated) tool call recorded as assistant text.
|
|
138
140
|
|
|
139
141
|
Drivers without ``supports_tool_use`` go through
|
|
@@ -154,10 +156,17 @@ def _parse_simulated_tool_call(content: str) -> tuple[str, dict[str, Any]] | Non
|
|
|
154
156
|
return None
|
|
155
157
|
if not isinstance(obj, dict):
|
|
156
158
|
return None
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
if obj.get("type") != "tool_call":
|
|
160
|
+
# Inferred shape (no discriminator), which parse_simulated_response
|
|
161
|
+
# also accepts when the model omits "type".
|
|
162
|
+
if not ("name" in obj and "arguments" in obj):
|
|
163
|
+
return None
|
|
164
|
+
# A structured ANSWER can legitimately carry name+arguments keys (a
|
|
165
|
+
# schema echo, a function description). When the caller can tell us
|
|
166
|
+
# which tools exist, only reclassify when the name matches one —
|
|
167
|
+
# otherwise the model's final output would silently vanish.
|
|
168
|
+
if known_tools is not None and obj.get("name") not in known_tools:
|
|
169
|
+
return None
|
|
161
170
|
name = obj.get("name")
|
|
162
171
|
args = obj.get("arguments", {})
|
|
163
172
|
if not isinstance(name, str) or not name or not isinstance(args, dict):
|
|
@@ -1176,7 +1185,9 @@ class Agent(Generic[DepsType]):
|
|
|
1176
1185
|
)
|
|
1177
1186
|
all_tool_calls.append({"name": name, "arguments": args, "id": tc.get("id", "")})
|
|
1178
1187
|
else:
|
|
1179
|
-
simulated = _parse_simulated_tool_call(
|
|
1188
|
+
simulated = _parse_simulated_tool_call(
|
|
1189
|
+
content, known_tools=(self._tools.names if self._tools else None)
|
|
1190
|
+
)
|
|
1180
1191
|
if simulated is not None:
|
|
1181
1192
|
# Prompted tool call: same step shape as the native path
|
|
1182
1193
|
# so a host sees one run, not two dialects.
|
|
@@ -384,13 +384,25 @@ class Assistant:
|
|
|
384
384
|
) -> AssistantResult:
|
|
385
385
|
agent = self._build_async_agent(call_vars=call_vars)
|
|
386
386
|
result: AgentResult = await agent.run(prompt, deps=deps)
|
|
387
|
+
# AgentResult.usage is a DICT (prompt_tokens/completion_tokens/cost) —
|
|
388
|
+
# getattr on a dict returns the default, so the attribute-style reads
|
|
389
|
+
# left cost_usd/input_tokens/output_tokens permanently None on the LLM
|
|
390
|
+
# backend and every host that trusted them recorded $0.00 forever.
|
|
387
391
|
usage = getattr(result, "usage", None)
|
|
392
|
+
if isinstance(usage, dict):
|
|
393
|
+
cost_usd = usage.get("cost")
|
|
394
|
+
input_tokens = usage.get("prompt_tokens")
|
|
395
|
+
output_tokens = usage.get("completion_tokens")
|
|
396
|
+
else:
|
|
397
|
+
cost_usd = getattr(usage, "total_cost_usd", None) if usage else None
|
|
398
|
+
input_tokens = getattr(usage, "input_tokens", None) if usage else None
|
|
399
|
+
output_tokens = getattr(usage, "output_tokens", None) if usage else None
|
|
388
400
|
return AssistantResult(
|
|
389
401
|
output=getattr(result, "output", "") or "",
|
|
390
402
|
backend="llm",
|
|
391
|
-
cost_usd=
|
|
392
|
-
input_tokens=
|
|
393
|
-
output_tokens=
|
|
403
|
+
cost_usd=cost_usd,
|
|
404
|
+
input_tokens=input_tokens,
|
|
405
|
+
output_tokens=output_tokens,
|
|
394
406
|
session_id=None,
|
|
395
407
|
raw=result,
|
|
396
408
|
)
|
|
@@ -56,7 +56,7 @@ _DEFAULT_MAX_AGENT_DEPTH = 5
|
|
|
56
56
|
|
|
57
57
|
# Share the same ContextVar with the sync Agent so depth tracking crosses
|
|
58
58
|
# agent boundaries (e.g. a sync Agent calling an AsyncAgent as a tool).
|
|
59
|
-
from .agent import _agent_depth
|
|
59
|
+
from .agent import _agent_depth, _parse_simulated_tool_call
|
|
60
60
|
|
|
61
61
|
# ------------------------------------------------------------------
|
|
62
62
|
# Helpers
|
|
@@ -1150,8 +1150,15 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
1150
1150
|
for rec in tool_timings or []:
|
|
1151
1151
|
timings_by_name.setdefault(rec.get("name", ""), []).append(rec)
|
|
1152
1152
|
|
|
1153
|
+
# Name of a simulated tool call awaiting its result, which the prompted
|
|
1154
|
+
# loop records as the next user message rather than a "tool" message.
|
|
1155
|
+
pending_sim_tool: str | None = None
|
|
1156
|
+
|
|
1153
1157
|
for msg in messages:
|
|
1154
1158
|
role = msg.get("role", "")
|
|
1159
|
+
# Claim (and clear) any simulated call left by the previous message.
|
|
1160
|
+
sim_tool = pending_sim_tool
|
|
1161
|
+
pending_sim_tool = None
|
|
1155
1162
|
# Extract usage from message meta if present
|
|
1156
1163
|
msg_meta = msg.get("meta")
|
|
1157
1164
|
step_usage = None
|
|
@@ -1204,14 +1211,45 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
1204
1211
|
)
|
|
1205
1212
|
all_tool_calls.append({"name": name, "arguments": args, "id": tc.get("id", "")})
|
|
1206
1213
|
else:
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1214
|
+
simulated = _parse_simulated_tool_call(
|
|
1215
|
+
content, known_tools=(self._tools.names if self._tools else None)
|
|
1216
|
+
)
|
|
1217
|
+
if simulated is not None:
|
|
1218
|
+
# Prompted tool call: same step shape as the native path
|
|
1219
|
+
# so a host sees one run, not two dialects.
|
|
1220
|
+
sim_name, sim_args = simulated
|
|
1221
|
+
steps.append(
|
|
1222
|
+
AgentStep(
|
|
1223
|
+
step_type=StepType.tool_call,
|
|
1224
|
+
timestamp=now,
|
|
1225
|
+
content="",
|
|
1226
|
+
tool_name=sim_name,
|
|
1227
|
+
tool_args=sim_args,
|
|
1228
|
+
usage=step_usage,
|
|
1229
|
+
)
|
|
1213
1230
|
)
|
|
1231
|
+
all_tool_calls.append({"name": sim_name, "arguments": sim_args, "id": ""})
|
|
1232
|
+
pending_sim_tool = sim_name
|
|
1233
|
+
else:
|
|
1234
|
+
steps.append(
|
|
1235
|
+
AgentStep(
|
|
1236
|
+
step_type=StepType.output,
|
|
1237
|
+
timestamp=now,
|
|
1238
|
+
content=content,
|
|
1239
|
+
usage=step_usage,
|
|
1240
|
+
)
|
|
1241
|
+
)
|
|
1242
|
+
|
|
1243
|
+
elif role == "user" and sim_tool is not None:
|
|
1244
|
+
# The prompted loop stores a tool result as a user message.
|
|
1245
|
+
steps.append(
|
|
1246
|
+
AgentStep(
|
|
1247
|
+
step_type=StepType.tool_result,
|
|
1248
|
+
timestamp=now,
|
|
1249
|
+
content=msg.get("content", "") or "",
|
|
1250
|
+
tool_name=sim_tool,
|
|
1214
1251
|
)
|
|
1252
|
+
)
|
|
1215
1253
|
|
|
1216
1254
|
elif role == "tool":
|
|
1217
1255
|
tool_call_id = msg.get("tool_call_id")
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Shared usage recording for media driver hook wrappers.
|
|
2
|
+
|
|
3
|
+
Media calls bill per image / second / job rather than per token, so the text
|
|
4
|
+
drivers' ``_auto_record_usage`` doesn't fit — but the spend is just as real,
|
|
5
|
+
and until this helper existed it never reached the usage tracker: media cost
|
|
6
|
+
lived only on the immediate response ``meta`` and vanished unless the caller
|
|
7
|
+
kept it. Every media ``*_with_hooks`` wrapper now records one
|
|
8
|
+
:class:`~prompture.infra.tracker.UsageEvent` (zero tokens, ``cost`` from meta,
|
|
9
|
+
unit count in ``metadata``) through the same global tracker as text calls, so
|
|
10
|
+
sinks and the SQLite ledger see the whole picture.
|
|
11
|
+
|
|
12
|
+
Fire-and-forget, mirroring the text bases: recording must never break the
|
|
13
|
+
generation it measures.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def record_embedding_driver_usage(
|
|
22
|
+
driver: Any,
|
|
23
|
+
meta: dict[str, Any] | None,
|
|
24
|
+
elapsed_ms: float,
|
|
25
|
+
*,
|
|
26
|
+
text_count: int,
|
|
27
|
+
status: str = "success",
|
|
28
|
+
error: Exception | None = None,
|
|
29
|
+
) -> None:
|
|
30
|
+
"""Record one embedding call as a usage event. Never raises.
|
|
31
|
+
|
|
32
|
+
Embeddings are input-only, so the token count lands on both
|
|
33
|
+
``prompt_tokens`` and ``total_tokens``.
|
|
34
|
+
"""
|
|
35
|
+
try:
|
|
36
|
+
from ..infra.ledger import _resolve_api_key_hash
|
|
37
|
+
from ..infra.tracker import UsageEvent, get_tracker
|
|
38
|
+
|
|
39
|
+
tracker = get_tracker()
|
|
40
|
+
if not tracker._enabled:
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
meta = meta or {}
|
|
44
|
+
driver_name = str(meta.get("model_name") or getattr(driver, "model", driver.__class__.__name__))
|
|
45
|
+
|
|
46
|
+
if "/" in driver_name:
|
|
47
|
+
provider, model = driver_name.split("/", 1)
|
|
48
|
+
else:
|
|
49
|
+
cls_name = driver.__class__.__name__.removeprefix("Async")
|
|
50
|
+
provider = cls_name.removesuffix("Driver").lower()
|
|
51
|
+
model = driver_name
|
|
52
|
+
|
|
53
|
+
model_name = f"{provider}/{model}" if provider else model
|
|
54
|
+
tokens = int(meta.get("total_tokens") or 0)
|
|
55
|
+
|
|
56
|
+
event = UsageEvent(
|
|
57
|
+
model_name=model_name,
|
|
58
|
+
provider=provider,
|
|
59
|
+
api_key_hash=_resolve_api_key_hash(model_name),
|
|
60
|
+
prompt_tokens=tokens,
|
|
61
|
+
total_tokens=tokens,
|
|
62
|
+
cost=float(meta.get("cost") or 0.0),
|
|
63
|
+
elapsed_ms=elapsed_ms,
|
|
64
|
+
status=status,
|
|
65
|
+
error_type=type(error).__name__ if error else None,
|
|
66
|
+
metadata={"modality": "embedding", "count": text_count},
|
|
67
|
+
)
|
|
68
|
+
tracker.record(event)
|
|
69
|
+
except Exception:
|
|
70
|
+
pass # fire-and-forget
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def record_media_usage(
|
|
74
|
+
driver: Any,
|
|
75
|
+
meta: dict[str, Any] | None,
|
|
76
|
+
elapsed_ms: float,
|
|
77
|
+
*,
|
|
78
|
+
modality: str,
|
|
79
|
+
count_key: str,
|
|
80
|
+
status: str = "success",
|
|
81
|
+
error: Exception | None = None,
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Record one media generation as a usage event. Never raises."""
|
|
84
|
+
try:
|
|
85
|
+
from ..infra.ledger import _resolve_api_key_hash
|
|
86
|
+
from ..infra.tracker import UsageEvent, get_tracker
|
|
87
|
+
|
|
88
|
+
tracker = get_tracker()
|
|
89
|
+
if not tracker._enabled:
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
meta = meta or {}
|
|
93
|
+
driver_name = str(meta.get("model_name") or getattr(driver, "model", driver.__class__.__name__))
|
|
94
|
+
|
|
95
|
+
if "/" in driver_name:
|
|
96
|
+
provider, model = driver_name.split("/", 1)
|
|
97
|
+
else:
|
|
98
|
+
# Same class-name fallback as the text bases, Async prefix stripped
|
|
99
|
+
# so async twins attribute to the same provider.
|
|
100
|
+
cls_name = driver.__class__.__name__.removeprefix("Async")
|
|
101
|
+
provider = cls_name.removesuffix("Driver").lower()
|
|
102
|
+
model = driver_name
|
|
103
|
+
|
|
104
|
+
model_name = f"{provider}/{model}" if provider else model
|
|
105
|
+
|
|
106
|
+
event = UsageEvent(
|
|
107
|
+
model_name=model_name,
|
|
108
|
+
provider=provider,
|
|
109
|
+
api_key_hash=_resolve_api_key_hash(model_name),
|
|
110
|
+
cost=float(meta.get("cost") or 0.0),
|
|
111
|
+
elapsed_ms=elapsed_ms,
|
|
112
|
+
status=status,
|
|
113
|
+
error_type=type(error).__name__ if error else None,
|
|
114
|
+
metadata={"modality": modality, "count": int(meta.get(count_key) or 0)},
|
|
115
|
+
)
|
|
116
|
+
tracker.record(event)
|
|
117
|
+
except Exception:
|
|
118
|
+
pass # fire-and-forget
|
|
@@ -194,7 +194,12 @@ class AggregatorClient:
|
|
|
194
194
|
return file_url
|
|
195
195
|
|
|
196
196
|
# ── Job handle / resume ──
|
|
197
|
-
def _make_handle(
|
|
197
|
+
def _make_handle(
|
|
198
|
+
self, slug: str, request_id: str, modality: str, *, pricing: dict[str, Any] | None = None
|
|
199
|
+
) -> JobHandle:
|
|
200
|
+
# `pricing` captures the quote inputs (n / duration / resolution) at
|
|
201
|
+
# submit time, so a resume from another process can still price the
|
|
202
|
+
# job — the provider result carries none of them.
|
|
198
203
|
return JobHandle(
|
|
199
204
|
task_id=request_id,
|
|
200
205
|
provider=self.PROVIDER,
|
|
@@ -204,6 +209,7 @@ class AggregatorClient:
|
|
|
204
209
|
endpoint=self.endpoint,
|
|
205
210
|
polling_url=self.result_url(request_id),
|
|
206
211
|
submitted_at=time.time(),
|
|
212
|
+
extra={"pricing": pricing} if pricing else {},
|
|
207
213
|
)
|
|
208
214
|
|
|
209
215
|
def get_job_status(self, handle: JobHandle) -> str:
|
|
@@ -229,11 +235,23 @@ class AggregatorClient:
|
|
|
229
235
|
MediaAsset(kind=kind, url=u, model=handle.model, provenance={"request_id": handle.task_id})
|
|
230
236
|
for u in self.extract_urls(raw)
|
|
231
237
|
]
|
|
238
|
+
meta: dict[str, Any] = {"request_id": handle.task_id, "model_name": f"{self.PROVIDER}/{handle.model}"}
|
|
239
|
+
if status == JobStatus.COMPLETED.value:
|
|
240
|
+
# Price from the quote inputs captured at submit time (handle.extra)
|
|
241
|
+
# — without this, every async job reported zero cost at every
|
|
242
|
+
# stage of its lifecycle.
|
|
243
|
+
pricing = (handle.extra or {}).get("pricing") or {}
|
|
244
|
+
meta["cost"] = self._media_cost(
|
|
245
|
+
handle.model,
|
|
246
|
+
n=int(pricing.get("n") or max(len(assets), 1)),
|
|
247
|
+
duration_seconds=float(pricing.get("duration_seconds") or 0.0),
|
|
248
|
+
resolution=pricing.get("resolution"),
|
|
249
|
+
)
|
|
232
250
|
return JobResult(
|
|
233
251
|
handle=handle.with_status(status),
|
|
234
252
|
status=status,
|
|
235
253
|
assets=assets,
|
|
236
|
-
meta=
|
|
254
|
+
meta=meta,
|
|
237
255
|
raw=raw,
|
|
238
256
|
)
|
|
239
257
|
|
|
@@ -250,6 +268,32 @@ class AggregatorClient:
|
|
|
250
268
|
resolution=resolution,
|
|
251
269
|
)
|
|
252
270
|
|
|
271
|
+
def _effective_duration(self, slug: str, options: dict[str, Any]) -> float:
|
|
272
|
+
"""The duration the provider will actually bill for.
|
|
273
|
+
|
|
274
|
+
An explicit ``duration`` option wins; otherwise the model's declared
|
|
275
|
+
capability default — the provider runs its default clip length and
|
|
276
|
+
bills for it whether or not the caller passed the option, so pricing
|
|
277
|
+
with 0 was quoting $0 for real spend.
|
|
278
|
+
"""
|
|
279
|
+
raw = options.get("duration")
|
|
280
|
+
if raw:
|
|
281
|
+
try:
|
|
282
|
+
return float(raw)
|
|
283
|
+
except (TypeError, ValueError):
|
|
284
|
+
pass
|
|
285
|
+
try:
|
|
286
|
+
from .media_capabilities import get_model_schema
|
|
287
|
+
|
|
288
|
+
info = get_model_schema(f"{self.PROVIDER}/{slug}")
|
|
289
|
+
spec = (info.inputs or {}).get("duration") if info else None
|
|
290
|
+
default = getattr(spec, "default", None)
|
|
291
|
+
if default:
|
|
292
|
+
return float(default)
|
|
293
|
+
except Exception:
|
|
294
|
+
pass
|
|
295
|
+
return 0.0
|
|
296
|
+
|
|
253
297
|
# ── Media input resolution (for conditioned ops: i2i / i2v / lipsync) ──
|
|
254
298
|
def _coerce_media_url(self, source: Any, *, explicit: str | None = None, filename: str = "input.bin") -> str | None:
|
|
255
299
|
"""Resolve a media input to a hosted URL.
|
|
@@ -321,7 +365,9 @@ class AggregatorImageDriver(AggregatorClient, ImageGenDriver):
|
|
|
321
365
|
def _pending_image(
|
|
322
366
|
self, slug: str, request_id: str, submitted: dict[str, Any], options: dict[str, Any]
|
|
323
367
|
) -> dict[str, Any]:
|
|
324
|
-
handle = self._make_handle(
|
|
368
|
+
handle = self._make_handle(
|
|
369
|
+
slug, request_id, "image", pricing={"n": int(options.get("n") or 1)}
|
|
370
|
+
)
|
|
325
371
|
return {
|
|
326
372
|
"images": [],
|
|
327
373
|
"meta": {
|
|
@@ -399,9 +445,13 @@ class AggregatorVideoDriver(AggregatorClient, VideoGenDriver):
|
|
|
399
445
|
slug = options.get("model", self.model)
|
|
400
446
|
payload = self.build_video_payload(prompt, options)
|
|
401
447
|
request_id, submitted = self._submit(slug, payload)
|
|
448
|
+
duration = self._effective_duration(slug, options)
|
|
402
449
|
|
|
403
450
|
if request_id is not None and not options.get("poll", True):
|
|
404
|
-
handle = self._make_handle(
|
|
451
|
+
handle = self._make_handle(
|
|
452
|
+
slug, request_id, "video",
|
|
453
|
+
pricing={"n": 1, "duration_seconds": duration, "resolution": options.get("resolution")},
|
|
454
|
+
)
|
|
405
455
|
return {
|
|
406
456
|
"videos": [],
|
|
407
457
|
"meta": {
|
|
@@ -428,7 +478,6 @@ class AggregatorVideoDriver(AggregatorClient, VideoGenDriver):
|
|
|
428
478
|
)
|
|
429
479
|
)
|
|
430
480
|
videos = [video_from_url(u) for u in self.extract_urls(result)]
|
|
431
|
-
duration = float(options.get("duration", 0) or 0)
|
|
432
481
|
cost = self._media_cost(slug, n=1, duration_seconds=duration, resolution=options.get("resolution"))
|
|
433
482
|
return {
|
|
434
483
|
"videos": videos,
|
|
@@ -509,8 +558,12 @@ class AggregatorLipsyncDriver(AggregatorClient, LipsyncDriver):
|
|
|
509
558
|
payload = self.build_lipsync_payload(options, audio_url=audio_url, image_url=image_url, video_url=video_url)
|
|
510
559
|
|
|
511
560
|
request_id, submitted = self._submit(slug, payload)
|
|
561
|
+
duration = self._effective_duration(slug, options)
|
|
512
562
|
if request_id is not None and not options.get("poll", True):
|
|
513
|
-
handle = self._make_handle(
|
|
563
|
+
handle = self._make_handle(
|
|
564
|
+
slug, request_id, "lipsync",
|
|
565
|
+
pricing={"n": 1, "duration_seconds": duration},
|
|
566
|
+
)
|
|
514
567
|
return {
|
|
515
568
|
"videos": [],
|
|
516
569
|
"meta": {
|
|
@@ -535,7 +588,6 @@ class AggregatorLipsyncDriver(AggregatorClient, LipsyncDriver):
|
|
|
535
588
|
)
|
|
536
589
|
)
|
|
537
590
|
videos = [video_from_url(u) for u in self.extract_urls(result)]
|
|
538
|
-
duration = float(options.get("duration", 0) or 0)
|
|
539
591
|
cost = self._media_cost(slug, n=1, duration_seconds=duration)
|
|
540
592
|
return {
|
|
541
593
|
"videos": videos,
|
|
@@ -604,7 +656,7 @@ class AggregatorMusicDriver(AggregatorClient, MusicGenDriver):
|
|
|
604
656
|
request_id, submitted = self._submit(slug, payload)
|
|
605
657
|
|
|
606
658
|
if request_id is not None and not options.get("poll", True):
|
|
607
|
-
handle = self._make_handle(slug, request_id, "music")
|
|
659
|
+
handle = self._make_handle(slug, request_id, "music", pricing={"n": 1})
|
|
608
660
|
return {
|
|
609
661
|
"audio": [],
|
|
610
662
|
"meta": {
|
|
@@ -149,7 +149,12 @@ class AsyncAggregatorClient:
|
|
|
149
149
|
raise RuntimeError(f"{self.PROVIDER} upload returned no URL: {dj}")
|
|
150
150
|
return file_url
|
|
151
151
|
|
|
152
|
-
def _make_handle(
|
|
152
|
+
def _make_handle(
|
|
153
|
+
self, slug: str, request_id: str, modality: str, *, pricing: dict[str, Any] | None = None
|
|
154
|
+
) -> JobHandle:
|
|
155
|
+
# `pricing` captures the quote inputs (n / duration / resolution) at
|
|
156
|
+
# submit time, so a resume from another process can still price the
|
|
157
|
+
# job — the provider result carries none of them.
|
|
153
158
|
return JobHandle(
|
|
154
159
|
task_id=request_id,
|
|
155
160
|
provider=self.PROVIDER,
|
|
@@ -159,6 +164,7 @@ class AsyncAggregatorClient:
|
|
|
159
164
|
endpoint=self.endpoint,
|
|
160
165
|
polling_url=self.result_url(request_id),
|
|
161
166
|
submitted_at=time.time(),
|
|
167
|
+
extra={"pricing": pricing} if pricing else {},
|
|
162
168
|
)
|
|
163
169
|
|
|
164
170
|
async def get_job_status(self, handle: JobHandle) -> str:
|
|
@@ -187,11 +193,23 @@ class AsyncAggregatorClient:
|
|
|
187
193
|
MediaAsset(kind=kind, url=u, model=handle.model, provenance={"request_id": handle.task_id})
|
|
188
194
|
for u in self.extract_urls(raw)
|
|
189
195
|
]
|
|
196
|
+
meta: dict[str, Any] = {"request_id": handle.task_id, "model_name": f"{self.PROVIDER}/{handle.model}"}
|
|
197
|
+
if status == JobStatus.COMPLETED.value:
|
|
198
|
+
# Price from the quote inputs captured at submit time (handle.extra)
|
|
199
|
+
# — without this, every async job reported zero cost at every
|
|
200
|
+
# stage of its lifecycle.
|
|
201
|
+
pricing = (handle.extra or {}).get("pricing") or {}
|
|
202
|
+
meta["cost"] = self._media_cost(
|
|
203
|
+
handle.model,
|
|
204
|
+
n=int(pricing.get("n") or max(len(assets), 1)),
|
|
205
|
+
duration_seconds=float(pricing.get("duration_seconds") or 0.0),
|
|
206
|
+
resolution=pricing.get("resolution"),
|
|
207
|
+
)
|
|
190
208
|
return JobResult(
|
|
191
209
|
handle=handle.with_status(status),
|
|
192
210
|
status=status,
|
|
193
211
|
assets=assets,
|
|
194
|
-
meta=
|
|
212
|
+
meta=meta,
|
|
195
213
|
raw=raw,
|
|
196
214
|
)
|
|
197
215
|
|
|
@@ -202,6 +220,32 @@ class AsyncAggregatorClient:
|
|
|
202
220
|
|
|
203
221
|
return estimate_media_cost(f"{self.PROVIDER}/{slug}", n=n, duration_seconds=duration_seconds, resolution=resolution)
|
|
204
222
|
|
|
223
|
+
def _effective_duration(self, slug: str, options: dict[str, Any]) -> float:
|
|
224
|
+
"""The duration the provider will actually bill for.
|
|
225
|
+
|
|
226
|
+
An explicit ``duration`` option wins; otherwise the model's declared
|
|
227
|
+
capability default — the provider runs its default clip length and
|
|
228
|
+
bills for it whether or not the caller passed the option, so pricing
|
|
229
|
+
with 0 was quoting $0 for real spend.
|
|
230
|
+
"""
|
|
231
|
+
raw = options.get("duration")
|
|
232
|
+
if raw:
|
|
233
|
+
try:
|
|
234
|
+
return float(raw)
|
|
235
|
+
except (TypeError, ValueError):
|
|
236
|
+
pass
|
|
237
|
+
try:
|
|
238
|
+
from .media_capabilities import get_model_schema
|
|
239
|
+
|
|
240
|
+
info = get_model_schema(f"{self.PROVIDER}/{slug}")
|
|
241
|
+
spec = (info.inputs or {}).get("duration") if info else None
|
|
242
|
+
default = getattr(spec, "default", None)
|
|
243
|
+
if default:
|
|
244
|
+
return float(default)
|
|
245
|
+
except Exception:
|
|
246
|
+
pass
|
|
247
|
+
return 0.0
|
|
248
|
+
|
|
205
249
|
async def _coerce_media_url(
|
|
206
250
|
self, source: Any, *, explicit: str | None = None, filename: str = "input.bin"
|
|
207
251
|
) -> str | None:
|
|
@@ -268,7 +312,9 @@ class AsyncAggregatorImageDriver(AsyncAggregatorClient, AsyncImageGenDriver):
|
|
|
268
312
|
if request_id is None:
|
|
269
313
|
return self._finalize_image(slug, None, submitted, options)
|
|
270
314
|
if not options.get("poll", True):
|
|
271
|
-
handle = self._make_handle(
|
|
315
|
+
handle = self._make_handle(
|
|
316
|
+
slug, request_id, "image", pricing={"n": int(options.get("n") or 1)}
|
|
317
|
+
)
|
|
272
318
|
return {
|
|
273
319
|
"images": [],
|
|
274
320
|
"meta": {
|
|
@@ -335,10 +381,14 @@ class AsyncAggregatorVideoDriver(AsyncAggregatorClient, AsyncVideoGenDriver):
|
|
|
335
381
|
self._require_key()
|
|
336
382
|
slug = options.get("model", self.model)
|
|
337
383
|
payload = self.build_video_payload(prompt, options)
|
|
384
|
+
duration = self._effective_duration(slug, options)
|
|
338
385
|
async with httpx.AsyncClient(timeout=120.0) as client:
|
|
339
386
|
request_id, submitted = await self._submit(client, slug, payload)
|
|
340
387
|
if request_id is not None and not options.get("poll", True):
|
|
341
|
-
handle = self._make_handle(
|
|
388
|
+
handle = self._make_handle(
|
|
389
|
+
slug, request_id, "video",
|
|
390
|
+
pricing={"n": 1, "duration_seconds": duration, "resolution": options.get("resolution")},
|
|
391
|
+
)
|
|
342
392
|
return {
|
|
343
393
|
"videos": [],
|
|
344
394
|
"meta": {
|
|
@@ -365,7 +415,6 @@ class AsyncAggregatorVideoDriver(AsyncAggregatorClient, AsyncVideoGenDriver):
|
|
|
365
415
|
)
|
|
366
416
|
)
|
|
367
417
|
videos = [video_from_url(u) for u in self.extract_urls(result)]
|
|
368
|
-
duration = float(options.get("duration", 0) or 0)
|
|
369
418
|
cost = self._media_cost(slug, n=1, duration_seconds=duration, resolution=options.get("resolution"))
|
|
370
419
|
return {
|
|
371
420
|
"videos": videos,
|
|
@@ -441,10 +490,14 @@ class AsyncAggregatorLipsyncDriver(AsyncAggregatorClient, AsyncLipsyncDriver):
|
|
|
441
490
|
category = "video" if video_url else "image"
|
|
442
491
|
payload = self.build_lipsync_payload(options, audio_url=audio_url, image_url=image_url, video_url=video_url)
|
|
443
492
|
|
|
493
|
+
duration = self._effective_duration(slug, options)
|
|
444
494
|
async with httpx.AsyncClient(timeout=120.0) as client:
|
|
445
495
|
request_id, submitted = await self._submit(client, slug, payload)
|
|
446
496
|
if request_id is not None and not options.get("poll", True):
|
|
447
|
-
handle = self._make_handle(
|
|
497
|
+
handle = self._make_handle(
|
|
498
|
+
slug, request_id, "lipsync",
|
|
499
|
+
pricing={"n": 1, "duration_seconds": duration},
|
|
500
|
+
)
|
|
448
501
|
return {
|
|
449
502
|
"videos": [],
|
|
450
503
|
"meta": {
|
|
@@ -469,7 +522,6 @@ class AsyncAggregatorLipsyncDriver(AsyncAggregatorClient, AsyncLipsyncDriver):
|
|
|
469
522
|
)
|
|
470
523
|
)
|
|
471
524
|
videos = [video_from_url(u) for u in self.extract_urls(result)]
|
|
472
|
-
duration = float(options.get("duration", 0) or 0)
|
|
473
525
|
cost = self._media_cost(slug, n=1, duration_seconds=duration)
|
|
474
526
|
return {
|
|
475
527
|
"videos": videos,
|
|
@@ -534,7 +586,7 @@ class AsyncAggregatorMusicDriver(AsyncAggregatorClient, AsyncMusicGenDriver):
|
|
|
534
586
|
async with httpx.AsyncClient(timeout=120.0) as client:
|
|
535
587
|
request_id, submitted = await self._submit(client, slug, payload)
|
|
536
588
|
if request_id is not None and not options.get("poll", True):
|
|
537
|
-
handle = self._make_handle(slug, request_id, "music")
|
|
589
|
+
handle = self._make_handle(slug, request_id, "music", pricing={"n": 1})
|
|
538
590
|
return {
|
|
539
591
|
"audio": [],
|
|
540
592
|
"meta": {
|
|
@@ -286,7 +286,12 @@ class AsyncDriver(ABC):
|
|
|
286
286
|
if "/" in driver_name:
|
|
287
287
|
provider, model = driver_name.split("/", 1)
|
|
288
288
|
else:
|
|
289
|
-
|
|
289
|
+
# Class-name fallback. Strip the Async prefix first:
|
|
290
|
+
# AsyncClaudeDriver is still the "claude" provider, and
|
|
291
|
+
# "asyncclaude" vs "claude" would split one provider's
|
|
292
|
+
# spend into two rows.
|
|
293
|
+
cls_name = self.__class__.__name__.removeprefix("Async")
|
|
294
|
+
provider = cls_name.removesuffix("Driver").lower()
|
|
290
295
|
model = driver_name
|
|
291
296
|
|
|
292
297
|
model_name = f"{provider}/{model}" if provider else model
|
{prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_cohere_embedding_driver.py
RENAMED
|
@@ -102,7 +102,7 @@ class AsyncCohereEmbeddingDriver(EmbeddingCostMixin, AsyncEmbeddingDriver):
|
|
|
102
102
|
"dimensions": actual_dims,
|
|
103
103
|
"total_tokens": total_tokens,
|
|
104
104
|
"input_tokens": total_tokens,
|
|
105
|
-
"cost": round(cost,
|
|
105
|
+
"cost": round(cost, 12),
|
|
106
106
|
"raw_response": last_resp,
|
|
107
107
|
},
|
|
108
108
|
}
|
|
@@ -7,6 +7,7 @@ import time
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
9
|
from ..infra.callbacks import DriverCallbacks
|
|
10
|
+
from ._media_usage import record_embedding_driver_usage
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger("prompture.async_embedding_driver")
|
|
12
13
|
|
|
@@ -54,6 +55,10 @@ class AsyncEmbeddingDriver:
|
|
|
54
55
|
"on_error",
|
|
55
56
|
{"error": exc, "text_count": len(texts), "options": options, "driver": driver_name},
|
|
56
57
|
)
|
|
58
|
+
record_embedding_driver_usage(
|
|
59
|
+
self, {}, (time.perf_counter() - t0) * 1000,
|
|
60
|
+
text_count=len(texts), status="error", error=exc,
|
|
61
|
+
)
|
|
57
62
|
raise
|
|
58
63
|
elapsed_ms = (time.perf_counter() - t0) * 1000
|
|
59
64
|
meta = resp.get("meta", {})
|
|
@@ -75,6 +80,7 @@ class AsyncEmbeddingDriver:
|
|
|
75
80
|
"elapsed_ms": elapsed_ms,
|
|
76
81
|
},
|
|
77
82
|
)
|
|
83
|
+
record_embedding_driver_usage(self, meta, elapsed_ms, text_count=len(texts))
|
|
78
84
|
return resp
|
|
79
85
|
|
|
80
86
|
# ------------------------------------------------------------------
|
|
@@ -7,6 +7,7 @@ import time
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
9
|
from ..infra.callbacks import DriverCallbacks
|
|
10
|
+
from ._media_usage import record_media_usage
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger("prompture.async_img_gen_driver")
|
|
12
13
|
|
|
@@ -59,6 +60,10 @@ class AsyncImageGenDriver:
|
|
|
59
60
|
"on_error",
|
|
60
61
|
{"error": exc, "prompt_length": len(prompt), "options": options, "driver": driver_name},
|
|
61
62
|
)
|
|
63
|
+
record_media_usage(
|
|
64
|
+
self, {}, (time.perf_counter() - t0) * 1000,
|
|
65
|
+
modality="image", count_key="image_count", status="error", error=exc,
|
|
66
|
+
)
|
|
62
67
|
raise
|
|
63
68
|
elapsed_ms = (time.perf_counter() - t0) * 1000
|
|
64
69
|
meta = resp.get("meta", {})
|
|
@@ -78,6 +83,7 @@ class AsyncImageGenDriver:
|
|
|
78
83
|
"elapsed_ms": elapsed_ms,
|
|
79
84
|
},
|
|
80
85
|
)
|
|
86
|
+
record_media_usage(self, meta, elapsed_ms, modality="image", count_key="image_count")
|
|
81
87
|
return resp
|
|
82
88
|
|
|
83
89
|
# ------------------------------------------------------------------
|
{prompture-1.9.1.dev1 → prompture-1.9.1.dev2}/prompture/drivers/async_jina_embedding_driver.py
RENAMED
|
@@ -90,7 +90,7 @@ class AsyncJinaEmbeddingDriver(EmbeddingCostMixin, AsyncEmbeddingDriver):
|
|
|
90
90
|
"dimensions": actual_dims,
|
|
91
91
|
"total_tokens": total_tokens,
|
|
92
92
|
"input_tokens": total_tokens,
|
|
93
|
-
"cost": round(cost,
|
|
93
|
+
"cost": round(cost, 12),
|
|
94
94
|
"raw_response": last_resp,
|
|
95
95
|
},
|
|
96
96
|
}
|