prompture 1.13.5.dev1__tar.gz → 1.13.5.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.13.5.dev1 → prompture-1.13.5.dev2}/.env.copy +6 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/PKG-INFO +63 -4
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/README.md +62 -3
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/llms.txt +1 -1
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/_version.py +2 -2
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/setup_cmd.py +1 -1
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/data/references/search.md +8 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/data/references/web.md +12 -2
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/__init__.py +3 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/_types.py +16 -0
- prompture-1.13.5.dev2/prompture/tools/web/cache.py +296 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/fetch.py +23 -15
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/health.py +27 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/platform.py +33 -1
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/__init__.py +35 -1
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/search.py +41 -2
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture.egg-info/PKG-INFO +63 -4
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture.egg-info/SOURCES.txt +1 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture.egg-info/scm_file_list.json +2 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/add-driver/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/add-driver/references/driver-template.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/add-example/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/add-field/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/add-persona/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/add-test/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/add-tool/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/create-pr/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/run-tests/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/scaffold-extraction/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.claude/skills/update-pricing/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.gitattributes +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/FUNDING.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/ISSUE_TEMPLATE/pricing_cost_mismatch.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/ISSUE_TEMPLATE/provider_driver_bug.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/ISSUE_TEMPLATE/schema_extraction_failure.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/scripts/update_docs_version.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/scripts/update_wrapper_version.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/workflows/dev.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/workflows/documentation.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/workflows/pricing-freshness.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/workflows/publish.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.github/workflows/security.yml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/.safety-project.ini +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/AGENTS.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/BREAKING_CHANGES.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/CLAUDE.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/CONTRIBUTING.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/LICENSE +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/MANIFEST.in +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/ROADMAP.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/SECURITY.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/VERSION +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/dev.ps1 +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/dev.sh +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/mypy_errors.txt +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/README.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/llm_to_json/README.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/llm_to_json/llm_to_json/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/llm_to_json/pyproject.toml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/llm_to_json/test.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/llm_to_toon/README.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/llm_to_toon/llm_to_toon/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/llm_to_toon/pyproject.toml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/packages/llm_to_toon/test.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/__main__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/_internal/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/_internal/json_encoder.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/agent.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/assistant.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/async_agent.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/async_conversation.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/async_deep_agent.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/conversation.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/deep/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/deep/planner.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/deep/subagents.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/deep/summarizer.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/deep/vfs.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/deep_agent.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/deep_prompts.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/deep_state.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/live_events.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/persona.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/review_loop.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/simulated_tools.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/skill_miner.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/skills.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/tool_grammars.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/tools_schema.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/agents/types.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/aio/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/bridges/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/bridges/tukuy_backend.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/backends.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/builtin_checks.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/challenge.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/errors.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/health.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/http.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/probe.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/capabilities/url_safety.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/checkpoints/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/checkpoints/core.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/checkpoints/stores.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/checkpoints/types.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/citations/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/citations/core.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/citations/types.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/cli.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/doctor_cmd.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/formatters.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/mcp_cmd.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/research_cmd.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/runner.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/server.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/skill_cmd.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/cli/transcribe_cmd.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/automations.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/calls.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/capacity.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/coding_tools.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/hook.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/live.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/local.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/memory.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/reuse.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/router.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/routing_policy.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/server.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/summary.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/companion/tool_routing.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/dataset/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/dataset/dedup.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/dataset/evol.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/dataset/filters.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/dataset/formats.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/dataset/schemas.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/dataset/seed.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/dataset/synth.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/doctor/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/doctor/core.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/doctor/providers.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/_media_usage.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/_ollama_options.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/_openai_compat.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/_openai_compat_stream.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/_openai_responses.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/_prompt_cache.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/_prompted_tool_stream.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/_usage_reporting.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/aggregator_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/airllm_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/assemblyai_stt_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_aggregator_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_airllm_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_assemblyai_stt_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_azure_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_bedrock_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_bfl_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_cachibot_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_cartesia_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_claude_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_cohere_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_cohere_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_cohere_rerank_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_deepgram_stt_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_deepgram_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_deepseek_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_elevenlabs_stt_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_elevenlabs_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_embedding_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_fal_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_fal_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_google_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_google_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_google_vertexai_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_grok_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_grok_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_grok_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_groq_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_hugging_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_ideogram_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_img_gen_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_jina_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_jina_rerank_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_kev_decision_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_kling_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_kling_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_laya_decision_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_lmstudio_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_local_http_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_luma_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_minimax_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_minimax_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_mistral_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_mistral_moderation_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_modelscope_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_moonshot_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_muapi_aggregator_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_mxbai_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_mxbai_rerank_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_nomic_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_ollama_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_ollama_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_openai_compatible_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_openai_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_openai_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_openai_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_openai_moderation_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_openai_stt_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_openai_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_openrouter_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_pika_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_runway_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_runway_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_runway_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_stability_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_stt_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_systemone_compatible_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_tts_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_typesafe_decision_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_video_gen_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_voyage_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_voyage_rerank_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/async_zai_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/audio_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/azure_config.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/azure_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/bedrock_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/bfl_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/cachibot_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/cartesia_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/claude_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/cohere_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/cohere_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/cohere_rerank_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/decision_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/decision_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/deepgram_stt_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/deepgram_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/deepseek_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/driver_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/elevenlabs_stt_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/elevenlabs_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/embedding_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/embedding_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/fal_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/fal_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/google_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/google_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/google_vertexai_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/grok_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/grok_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/grok_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/groq_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/hugging_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/ideogram_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/img_gen_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/img_gen_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/jina_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/jina_rerank_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/job_runner.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/kev_decision_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/kling_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/kling_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/laya_decision_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/lipsync_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/lipsync_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/lmstudio_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/local_http_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/luma_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/media_capabilities.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/minimax_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/minimax_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/mistral_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/mistral_moderation_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/modelscope_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/moderation_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/moderation_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/moonshot_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/muapi_aggregator_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/music_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/music_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/mxbai_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/mxbai_rerank_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/nomic_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/ollama_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/ollama_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/openai_compatible_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/openai_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/openai_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/openai_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/openai_moderation_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/openai_stt_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/openai_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/openrouter_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/pika_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/provider_branding.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/provider_descriptors.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/rerank_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/rerank_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/runway_audio_transform_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/runway_capabilities.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/runway_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/runway_tts_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/runway_video_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/stability_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/stt_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/systemone_compatible_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/tts_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/typesafe_decision_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/vertex_img_gen_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/video_gen_base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/video_gen_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/vision_helpers.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/voyage_embedding_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/voyage_rerank_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/drivers/zai_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/eval/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/eval/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/eval/faithfulness.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/eval/judge.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/eval/pairwise.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/eval/self_consistency.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/exceptions.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/context.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/context_eval.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/data/document_qa_policies.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/data/extraction_contacts.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/data/tool_task_inventory.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/fixtures.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/gates.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/harness.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/improve/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/improve/candidates.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/improve/optimizer.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/improve/promotion.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/improve/scorecard.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/integration.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/outcomes.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/policy.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/sandbox.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/scoring.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/strategies/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/strategies/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/strategies/critique.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/strategies/direct.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/strategies/registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/strategies/retrieve.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/execution/types.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/_usage.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/async_core.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/code_extraction.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/core.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/few_shot.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/fields.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/reasoning.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/strategy.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/streaming.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/tools.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/tukuy_bridge.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/extraction/validator.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/gateway/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/gateway/anthropic_format.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/gateway/gemini_format.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/gateway/openai_format.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/gateway/reasoning_cache.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/gateway/responses_format.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/groups/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/groups/async_groups.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/groups/consensus.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/groups/debate.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/groups/fusion.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/groups/groups.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/groups/types.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/imaging/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/imaging/enhance.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/imaging/negative.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/imaging/set_planner.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/imaging/style_presets.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/accounts.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/billing.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/budget.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/cache.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/callbacks.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/capabilities.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/coding_agent_activity.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/coding_agent_events.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/coding_agent_readers.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/coding_agent_specs.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/coding_agent_usage.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/coding_agents.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/compression.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/cost_mixin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/credentials.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/discovery.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/environment.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/ledger.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/logging.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/media_pricing.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/media_rates.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/model_rates.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/otel.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/pricing.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/provider_env.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rate_limits.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/anthropic.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/azure.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/bedrock.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/cerebras.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/cohere.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/deepinfra.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/deepseek.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/fireworks.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/google.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/google_vertexai.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/groq.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/jina.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/kev.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/laya.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/mistral.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/mixedbread.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/moonshot.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/nomic.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/nvidia.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/openai.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/openrouter.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/perplexity.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/sambanova.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/siliconflow.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/together.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/typesafe.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/voyage.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/rates/xai.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/session.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/settings.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/token_counting.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/tracker.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/tukuy_backend.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/infra/updates.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/chunking.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/detect.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/document.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/parsers/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/parsers/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/parsers/csv_parser.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/parsers/docx.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/parsers/html.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/parsers/markdown.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/parsers/pdf.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/ingestion/parsers/xlsx.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/integrations/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/integrations/mcp_bridge.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/integrations/tukuy_bridge.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/jobs.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/kg/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/kg/core.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/kg/stores.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/kg/types.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/mcp/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/mcp/client.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/mcp/health.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/mcp/hub.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/mcp/importers.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/mcp/server.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/mcp/tools.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/agent_tools.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/audio.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/hosting.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/image.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/errors.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/ffmpeg.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/groq_stt.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/health.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/sources.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/summarize.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/tools.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/understand/transcribe.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/media/video.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pages/01-why-prompture.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pages/02-installation.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pages/03-quickstart.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pages/04-toon-input.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pages/05-test-harness.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pages/06-stability.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pages/07-migration.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/persistence/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/persistence/history.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/persistence/serialization.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/persistence/store.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pipeline/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pipeline/pipeline.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pipeline/resolver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/pipeline/routing.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/_aliases.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/anthropic_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/audio_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/cloud_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/decision_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/embedding_rerank_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/extras_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/google_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/image_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/local_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/openai_compatible_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/openai_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/builtins/video_plugin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/plugins/discovery.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/py.typed +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/character.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/chunker_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/contextual.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/markdown.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/recursive.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/semantic.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/chunkers/token.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/documents.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loader_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/csv_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/docx_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/epub_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/html_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/json_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/markdown_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/pdf_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/text_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/loaders/xlsx_loader.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/pipeline.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/_fusion.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/hybrid.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/hyde.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/mmr.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/multi_query.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/retriever_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/similarity.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/retrievers/step_back.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/chroma.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/faiss.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/pgvector.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/pinecone.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/qdrant.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/vectorstore_registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/rag/vectorstores/weaviate.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/refusal/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/refusal/detector.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/refusal/evaluator.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/refusal/markers.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/agent.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/budget.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/events.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/planner.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/ranking.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/report.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/synthesis.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/research/tools.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/async_driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/backoff.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/breaker.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/driver.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/errors.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/explain.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/headroom.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/keys.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/router.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/strategies.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/resilience/virtual.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/generator.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/templates/Dockerfile.j2 +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/templates/README.md.j2 +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/templates/config.py.j2 +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/templates/env.example.j2 +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/templates/main.py.j2 +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/templates/models.py.j2 +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/scaffold/templates/requirements.txt.j2 +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/security/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/security/injection.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/security/redaction.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/session_memory/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/session_memory/core.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/session_memory/project.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/session_memory/stores.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/session_memory/types.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/data/SKILL.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/data/references/dev.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/data/references/finance.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/data/references/mcp.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/data/references/media.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/skill/data/references/models.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/swarm/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/swarm/environment.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/swarm/memory.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/swarm/scheduler.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/swarm/swarm.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/swarm/swarm_agent.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/swarm/types.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/testing/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/testing/driver_contract.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/cli/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/cli/adapter.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/cli/builtin.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/cli/config.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/cli/health.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/code_exec.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/named.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/packs.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/_common.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/_mcp_http.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/html2md.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/_media.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/arxiv.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/base.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/feeds.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/github.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/hackernews.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/podcasts.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/wikipedia.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/readers/youtube.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web/toolkit.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/tools/web_search.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/__init__.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/architect.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/engine.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/errors.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/model.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/nodes.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/recovery.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/references.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/registry.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/scheduler.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture/workflow/state.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture.egg-info/dependency_links.txt +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture.egg-info/entry_points.txt +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture.egg-info/requires.txt +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture.egg-info/top_level.txt +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/prompture_cost_tracking.md +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/pyproject.toml +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/requirements.txt +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/scripts/check_pricing_freshness.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/setup.cfg +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/specs/basic_extraction.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/specs/schema_validation.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/specs/strategy_comparison.json +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/test.py +0 -0
- {prompture-1.13.5.dev1 → prompture-1.13.5.dev2}/test_version_diagnosis.py +0 -0
|
@@ -252,6 +252,12 @@ PROMPTURE_SEARCH_PROVIDERS=
|
|
|
252
252
|
PROMPTURE_FETCH_BACKENDS=
|
|
253
253
|
# Allow tools to reach private/loopback addresses (off by default).
|
|
254
254
|
PROMPTURE_WEB_ALLOW_PRIVATE=
|
|
255
|
+
# Local cache for search / fetch / reader results: disk (default, shared
|
|
256
|
+
# across processes), memory (this process only) or off. Lifetimes depend on
|
|
257
|
+
# the content: minutes for weather/prices/news, days for papers/transcripts.
|
|
258
|
+
PROMPTURE_WEB_CACHE=
|
|
259
|
+
# Where the disk cache lives (default ~/.prompture/cache/web_cache.db).
|
|
260
|
+
PROMPTURE_WEB_CACHE_PATH=
|
|
255
261
|
|
|
256
262
|
# ─── Media understanding (transcripts / summaries) ───────────────────────────
|
|
257
263
|
# Uses the first configured STT key: GROQ_API_KEY ▸ OPENAI_API_KEY ▸
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: prompture
|
|
3
|
-
Version: 1.13.5.
|
|
3
|
+
Version: 1.13.5.dev2
|
|
4
4
|
Summary: Ask LLMs to return structured JSON and run cross-model tests. API-first.
|
|
5
5
|
Author-email: Juan Denis <juan@vene.co>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -162,6 +162,37 @@ print(person.name) # Maria
|
|
|
162
162
|
> | `ollama/llama3.1:8b`, … (local) | no extra needed | — (set `OLLAMA_HOST` if non-default) |
|
|
163
163
|
> | everything in one go | `pip install "prompture[all]"` | provider-specific |
|
|
164
164
|
|
|
165
|
+
## Agents That Can Search, Read, Watch and Listen
|
|
166
|
+
|
|
167
|
+
Prompture also gives agents working capabilities, and **none of them need an
|
|
168
|
+
API key to start**. Keys only raise limits and quality.
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from prompture import Agent
|
|
172
|
+
|
|
173
|
+
agent = Agent(
|
|
174
|
+
"openai/gpt-4o-mini",
|
|
175
|
+
tools=["web:all", "pack:dev", "mcp:exa"], # search, read any URL, transcribe, GitHub/HN/arXiv, MCP
|
|
176
|
+
system_prompt="Cite every fact with a URL you opened.",
|
|
177
|
+
)
|
|
178
|
+
print(agent.run("Summarize https://youtu.be/<id> and find related papers").output)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
prompture doctor # what works on this machine and how to fix the rest
|
|
183
|
+
prompture research "What changed in Python 3.13?" --depth quick # cited multi-source report
|
|
184
|
+
prompture transcribe talk.mp3 --summary # timestamped transcript + key points
|
|
185
|
+
prompture mcp add --preset exa # mount MCP servers by name
|
|
186
|
+
prompture skill install # teach your coding agent all of this
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- **Web:** keyless search, fetch and readers for YouTube, GitHub, Hacker News, arXiv, Wikipedia, feeds and podcasts
|
|
190
|
+
- **Fails over, never just fails:** every capability tries the next backend on auth, quota or rate-limit errors and tells you which one served the result
|
|
191
|
+
- **Cached locally:** repeat searches and static pages come back instantly; weather, prices and news expire in minutes, papers and transcripts in days
|
|
192
|
+
- **Safe by default:** public URLs only, size caps, secret scrubbing, and audio never goes to a second provider without your consent
|
|
193
|
+
|
|
194
|
+
Full guide: [Capabilities](#capabilities).
|
|
195
|
+
|
|
165
196
|
## Prompture Desk: Usage in Your Tray
|
|
166
197
|
|
|
167
198
|
**See what your LLM calls cost, live, from your tray.** [Prompture Desk](https://github.com/jhd3197/Prompture-Desk) tracks tokens and spend per provider and project, rate-limit headroom, balances, and your coding tools (Claude Code, Codex, …). Windows, macOS and Linux.
|
|
@@ -194,8 +225,7 @@ No setup: Desk runs `prompture companion` (Prompture 1.13+) on localhost for you
|
|
|
194
225
|
**Agents, tools, RAG**
|
|
195
226
|
- Stateful conversations with sync + async support
|
|
196
227
|
- Function calling and streaming across providers, with prompt-based simulation for models without native tool use
|
|
197
|
-
- Drop-in tools: sandboxed `python_execute` (Tukuy)
|
|
198
|
-
- Mount tools by name: `tools=["web:all", "mcp:exa", "pack:finance", "cli:gh"]`; `ResearchAgent` for cited multi-source research
|
|
228
|
+
- Drop-in tools: sandboxed `python_execute` (Tukuy) plus the [capability layer](#capabilities) below
|
|
199
229
|
- `DeepAgent` with planning, virtual filesystem, sub-agents, and auto-summarization — no LangChain
|
|
200
230
|
- Full RAG stack — loaders, chunkers, vector stores, hybrid dense+BM25 retrieval, end-to-end `RAGPipeline` — see [RAG](#rag)
|
|
201
231
|
|
|
@@ -204,8 +234,16 @@ No setup: Desk runs `prompture companion` (Prompture 1.13+) on localhost for you
|
|
|
204
234
|
- `RefusalDetector` / `RefusalEvaluator` for cross-provider alignment scoring
|
|
205
235
|
- `generate_qa_dataset()` — synthetic JSONL datasets ready for Unsloth, Axolotl, TRL
|
|
206
236
|
|
|
207
|
-
**
|
|
237
|
+
**Capabilities** — see [Capabilities](#capabilities)
|
|
238
|
+
- Keyless `web_search`, `web_fetch` and `read_url` (YouTube, GitHub, HN, arXiv, Wikipedia, feeds, podcasts), with failover across keyed providers
|
|
239
|
+
- Local web cache with content-aware lifetimes: minutes for weather, prices and news, days for papers and transcripts
|
|
240
|
+
- `transcribe` / `summarize_media` for video, podcasts and audio, with timestamped key points
|
|
241
|
+
- `ResearchAgent` / `prompture research` — cited multi-source reports within fetch, token, cost and time budgets
|
|
242
|
+
- MCP hub, wrapped CLI tools (`gh`, `yt-dlp`) and domain packs (finance, news, dev, places), mounted by name: `tools=["mcp:exa", "pack:finance", "cli:gh"]`
|
|
208
243
|
- `prompture doctor` — what works on this machine (providers, tools, media, MCP servers, binaries), which backend is active, and the exact fix for anything that isn't
|
|
244
|
+
- `prompture setup` with an owner-only credential store and profiles; `prompture skill install` teaches coding agents to use all of it
|
|
245
|
+
|
|
246
|
+
**Ops**
|
|
209
247
|
- Resilient routing — `resilient()` retries transient errors, honors `Retry-After`, rotates API keys, trips circuit breakers and fails over across models; every response records who served it — see [Resilient Routing](#resilient-routing)
|
|
210
248
|
- [Prompture Desk](#prompture-desk-usage-in-your-tray) — desktop tray app: usage per provider and project, rate limits and balances, live calls
|
|
211
249
|
- [prompture-hub](#prompture-hub-gateway--dashboard) — optional companion app: web dashboard, scoped per-app keys, spend caps and per-call metering (`pip install prompture[hub]`)
|
|
@@ -2103,6 +2141,27 @@ agent = Agent("openai/gpt-4o", tools=["web:all"])
|
|
|
2103
2141
|
refused, redirects are re-checked per hop, bodies are size-capped and
|
|
2104
2142
|
challenge pages move to the next backend.
|
|
2105
2143
|
|
|
2144
|
+
**Local cache.** Results are cached in `~/.prompture/cache/web_cache.db`, so a
|
|
2145
|
+
repeated search or page comes back instantly, even from another process. Each
|
|
2146
|
+
entry lives as long as that kind of content stays true:
|
|
2147
|
+
|
|
2148
|
+
| Content | Lifetime |
|
|
2149
|
+
|---|---|
|
|
2150
|
+
| Searches about weather, prices, scores, news, "today", or `recency_days <= 1` | 10 min |
|
|
2151
|
+
| Fast-moving pages (Hacker News, Reddit, X, status pages), GitHub issues/PRs | 10 min |
|
|
2152
|
+
| Feeds | 15 min |
|
|
2153
|
+
| Platform search (GitHub, HN, arXiv, YouTube) | 30 min |
|
|
2154
|
+
| Ordinary pages / searches within `recency_days <= 7` | 1 h |
|
|
2155
|
+
| Other searches | 6 h |
|
|
2156
|
+
| Wikipedia, podcast episodes | 1 day |
|
|
2157
|
+
| Papers, PDFs, DOIs, commit-pinned GitHub files, YouTube transcripts | 7 days |
|
|
2158
|
+
|
|
2159
|
+
Cached results say so (`route["cached"]`, `cache_age_s`, and "cached 3 min
|
|
2160
|
+
ago" in the Markdown footer). Errors and empty results are never stored. Pass
|
|
2161
|
+
`use_cache=False` or `cache_ttl=<seconds>` per call, set
|
|
2162
|
+
`PROMPTURE_WEB_CACHE=memory|off` to change the store, and
|
|
2163
|
+
`clear_web_cache()` or `prompture reset` to empty it.
|
|
2164
|
+
|
|
2106
2165
|
### Media understanding: transcripts and summaries
|
|
2107
2166
|
|
|
2108
2167
|
```python
|
|
@@ -45,6 +45,37 @@ print(person.name) # Maria
|
|
|
45
45
|
> | `ollama/llama3.1:8b`, … (local) | no extra needed | — (set `OLLAMA_HOST` if non-default) |
|
|
46
46
|
> | everything in one go | `pip install "prompture[all]"` | provider-specific |
|
|
47
47
|
|
|
48
|
+
## Agents That Can Search, Read, Watch and Listen
|
|
49
|
+
|
|
50
|
+
Prompture also gives agents working capabilities, and **none of them need an
|
|
51
|
+
API key to start**. Keys only raise limits and quality.
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from prompture import Agent
|
|
55
|
+
|
|
56
|
+
agent = Agent(
|
|
57
|
+
"openai/gpt-4o-mini",
|
|
58
|
+
tools=["web:all", "pack:dev", "mcp:exa"], # search, read any URL, transcribe, GitHub/HN/arXiv, MCP
|
|
59
|
+
system_prompt="Cite every fact with a URL you opened.",
|
|
60
|
+
)
|
|
61
|
+
print(agent.run("Summarize https://youtu.be/<id> and find related papers").output)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
prompture doctor # what works on this machine and how to fix the rest
|
|
66
|
+
prompture research "What changed in Python 3.13?" --depth quick # cited multi-source report
|
|
67
|
+
prompture transcribe talk.mp3 --summary # timestamped transcript + key points
|
|
68
|
+
prompture mcp add --preset exa # mount MCP servers by name
|
|
69
|
+
prompture skill install # teach your coding agent all of this
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- **Web:** keyless search, fetch and readers for YouTube, GitHub, Hacker News, arXiv, Wikipedia, feeds and podcasts
|
|
73
|
+
- **Fails over, never just fails:** every capability tries the next backend on auth, quota or rate-limit errors and tells you which one served the result
|
|
74
|
+
- **Cached locally:** repeat searches and static pages come back instantly; weather, prices and news expire in minutes, papers and transcripts in days
|
|
75
|
+
- **Safe by default:** public URLs only, size caps, secret scrubbing, and audio never goes to a second provider without your consent
|
|
76
|
+
|
|
77
|
+
Full guide: [Capabilities](#capabilities).
|
|
78
|
+
|
|
48
79
|
## Prompture Desk: Usage in Your Tray
|
|
49
80
|
|
|
50
81
|
**See what your LLM calls cost, live, from your tray.** [Prompture Desk](https://github.com/jhd3197/Prompture-Desk) tracks tokens and spend per provider and project, rate-limit headroom, balances, and your coding tools (Claude Code, Codex, …). Windows, macOS and Linux.
|
|
@@ -77,8 +108,7 @@ No setup: Desk runs `prompture companion` (Prompture 1.13+) on localhost for you
|
|
|
77
108
|
**Agents, tools, RAG**
|
|
78
109
|
- Stateful conversations with sync + async support
|
|
79
110
|
- Function calling and streaming across providers, with prompt-based simulation for models without native tool use
|
|
80
|
-
- Drop-in tools: sandboxed `python_execute` (Tukuy)
|
|
81
|
-
- Mount tools by name: `tools=["web:all", "mcp:exa", "pack:finance", "cli:gh"]`; `ResearchAgent` for cited multi-source research
|
|
111
|
+
- Drop-in tools: sandboxed `python_execute` (Tukuy) plus the [capability layer](#capabilities) below
|
|
82
112
|
- `DeepAgent` with planning, virtual filesystem, sub-agents, and auto-summarization — no LangChain
|
|
83
113
|
- Full RAG stack — loaders, chunkers, vector stores, hybrid dense+BM25 retrieval, end-to-end `RAGPipeline` — see [RAG](#rag)
|
|
84
114
|
|
|
@@ -87,8 +117,16 @@ No setup: Desk runs `prompture companion` (Prompture 1.13+) on localhost for you
|
|
|
87
117
|
- `RefusalDetector` / `RefusalEvaluator` for cross-provider alignment scoring
|
|
88
118
|
- `generate_qa_dataset()` — synthetic JSONL datasets ready for Unsloth, Axolotl, TRL
|
|
89
119
|
|
|
90
|
-
**
|
|
120
|
+
**Capabilities** — see [Capabilities](#capabilities)
|
|
121
|
+
- Keyless `web_search`, `web_fetch` and `read_url` (YouTube, GitHub, HN, arXiv, Wikipedia, feeds, podcasts), with failover across keyed providers
|
|
122
|
+
- Local web cache with content-aware lifetimes: minutes for weather, prices and news, days for papers and transcripts
|
|
123
|
+
- `transcribe` / `summarize_media` for video, podcasts and audio, with timestamped key points
|
|
124
|
+
- `ResearchAgent` / `prompture research` — cited multi-source reports within fetch, token, cost and time budgets
|
|
125
|
+
- MCP hub, wrapped CLI tools (`gh`, `yt-dlp`) and domain packs (finance, news, dev, places), mounted by name: `tools=["mcp:exa", "pack:finance", "cli:gh"]`
|
|
91
126
|
- `prompture doctor` — what works on this machine (providers, tools, media, MCP servers, binaries), which backend is active, and the exact fix for anything that isn't
|
|
127
|
+
- `prompture setup` with an owner-only credential store and profiles; `prompture skill install` teaches coding agents to use all of it
|
|
128
|
+
|
|
129
|
+
**Ops**
|
|
92
130
|
- Resilient routing — `resilient()` retries transient errors, honors `Retry-After`, rotates API keys, trips circuit breakers and fails over across models; every response records who served it — see [Resilient Routing](#resilient-routing)
|
|
93
131
|
- [Prompture Desk](#prompture-desk-usage-in-your-tray) — desktop tray app: usage per provider and project, rate limits and balances, live calls
|
|
94
132
|
- [prompture-hub](#prompture-hub-gateway--dashboard) — optional companion app: web dashboard, scoped per-app keys, spend caps and per-call metering (`pip install prompture[hub]`)
|
|
@@ -1986,6 +2024,27 @@ agent = Agent("openai/gpt-4o", tools=["web:all"])
|
|
|
1986
2024
|
refused, redirects are re-checked per hop, bodies are size-capped and
|
|
1987
2025
|
challenge pages move to the next backend.
|
|
1988
2026
|
|
|
2027
|
+
**Local cache.** Results are cached in `~/.prompture/cache/web_cache.db`, so a
|
|
2028
|
+
repeated search or page comes back instantly, even from another process. Each
|
|
2029
|
+
entry lives as long as that kind of content stays true:
|
|
2030
|
+
|
|
2031
|
+
| Content | Lifetime |
|
|
2032
|
+
|---|---|
|
|
2033
|
+
| Searches about weather, prices, scores, news, "today", or `recency_days <= 1` | 10 min |
|
|
2034
|
+
| Fast-moving pages (Hacker News, Reddit, X, status pages), GitHub issues/PRs | 10 min |
|
|
2035
|
+
| Feeds | 15 min |
|
|
2036
|
+
| Platform search (GitHub, HN, arXiv, YouTube) | 30 min |
|
|
2037
|
+
| Ordinary pages / searches within `recency_days <= 7` | 1 h |
|
|
2038
|
+
| Other searches | 6 h |
|
|
2039
|
+
| Wikipedia, podcast episodes | 1 day |
|
|
2040
|
+
| Papers, PDFs, DOIs, commit-pinned GitHub files, YouTube transcripts | 7 days |
|
|
2041
|
+
|
|
2042
|
+
Cached results say so (`route["cached"]`, `cache_age_s`, and "cached 3 min
|
|
2043
|
+
ago" in the Markdown footer). Errors and empty results are never stored. Pass
|
|
2044
|
+
`use_cache=False` or `cache_ttl=<seconds>` per call, set
|
|
2045
|
+
`PROMPTURE_WEB_CACHE=memory|off` to change the store, and
|
|
2046
|
+
`clear_web_cache()` or `prompture reset` to empty it.
|
|
2047
|
+
|
|
1989
2048
|
### Media understanding: transcripts and summaries
|
|
1990
2049
|
|
|
1991
2050
|
```python
|
|
@@ -39,7 +39,7 @@ Model strings are `provider/model` (e.g. `openai/gpt-4o-mini`, `claude/claude-ha
|
|
|
39
39
|
- `prompture.drivers`: one driver per provider; `get_driver_for_model("provider/model")`
|
|
40
40
|
- `prompture.resilience`: `resilient()`, `classify_error`, combos and virtual models
|
|
41
41
|
- `prompture.capabilities`: `BackendChain`, `probe_command`, `HealthStatus`, `safe_get`, `normalize_public_http_url`
|
|
42
|
-
- `prompture.tools.web`: `web_search`, `web_fetch`, `read_url`, `search_platform`, `WebToolkit`
|
|
42
|
+
- `prompture.tools.web`: `web_search`, `web_fetch`, `read_url`, `search_platform`, `WebToolkit`, local cache (`clear_web_cache`, `cache_info`, `PROMPTURE_WEB_CACHE`)
|
|
43
43
|
- `prompture.media.understand`: `transcribe`, `summarize_media`
|
|
44
44
|
- `prompture.mcp`: MCP client/server and `hub` (`MCPHub`, `resolve_mcp_tools`)
|
|
45
45
|
- `prompture.tools.cli`, `prompture.tools.packs`: `CLITool`, domain packs
|
|
@@ -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.13.5.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 13, 5, '
|
|
21
|
+
__version__ = version = '1.13.5.dev2'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 13, 5, 'dev2')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -550,7 +550,7 @@ _STATE_DESCRIPTIONS = {
|
|
|
550
550
|
"credentials.yaml": "stored credentials and settings",
|
|
551
551
|
"mcp.json": "named MCP servers",
|
|
552
552
|
"usage": "usage ledger databases",
|
|
553
|
-
"cache": "model-rate, response and plan-usage caches",
|
|
553
|
+
"cache": "model-rate, response, web and plan-usage caches",
|
|
554
554
|
"update_check.json": "update-check state",
|
|
555
555
|
"companion.json": "local companion address and token",
|
|
556
556
|
"companion-prefs.json": "companion preferences",
|
|
@@ -65,6 +65,14 @@ The report only cites pages it actually opened. Model defaults to
|
|
|
65
65
|
`PROMPTURE_RESEARCH_MODEL`, then the first configured provider's cheap model.
|
|
66
66
|
Other agents can call it as a tool: `tools=[research_tool(depth="quick")]`.
|
|
67
67
|
|
|
68
|
+
## Cache
|
|
69
|
+
|
|
70
|
+
Results are cached locally (`~/.prompture/cache/web_cache.db`). Volatile
|
|
71
|
+
searches (weather, prices, scores, news, "today", `recency_days <= 1`) live 10
|
|
72
|
+
minutes; others live hours. A cached result has `route["cached"] is True` and
|
|
73
|
+
`route["cache_age_s"]` — say so when it matters ("from a search 5 min ago").
|
|
74
|
+
For something that must be live right now, pass `use_cache=False`.
|
|
75
|
+
|
|
68
76
|
## When search fails
|
|
69
77
|
|
|
70
78
|
1. `prompture doctor --only tools --json` → look at the `web_search` row.
|
|
@@ -41,8 +41,18 @@ if page.truncated:
|
|
|
41
41
|
more = web_fetch(page.url, start=page.next_start) # paging
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Long pages end with `[truncated — call again with start=N]
|
|
45
|
-
|
|
44
|
+
Long pages end with `[truncated — call again with start=N]`; paging reads
|
|
45
|
+
from the cache, not the network. `compress=True` trims boilerplate for agent
|
|
46
|
+
loops.
|
|
47
|
+
|
|
48
|
+
## Cache
|
|
49
|
+
|
|
50
|
+
`web_fetch`, `read_url` and `search_platform` share a local cache whose
|
|
51
|
+
lifetime follows the content: 10 minutes for Hacker News, Reddit, X, status
|
|
52
|
+
pages and GitHub issues/PRs, 1 hour for ordinary pages, 1 day for Wikipedia,
|
|
53
|
+
7 days for papers, PDFs, DOIs and YouTube transcripts. Cached results carry
|
|
54
|
+
`route["cached"]` and `route["cache_age_s"]`. Use `use_cache=False` when the
|
|
55
|
+
user needs the page as it is right now; `PROMPTURE_WEB_CACHE=off` disables it.
|
|
46
56
|
|
|
47
57
|
## Safety (don't work around these)
|
|
48
58
|
|
|
@@ -22,6 +22,7 @@ from __future__ import annotations
|
|
|
22
22
|
|
|
23
23
|
from ._mcp_http import MCPError, MCPHttpClient
|
|
24
24
|
from ._types import SearchResponse, SearchResult
|
|
25
|
+
from .cache import cache_info, clear_web_cache
|
|
25
26
|
from .fetch import (
|
|
26
27
|
FETCH_BACKENDS,
|
|
27
28
|
FETCH_OVERRIDE_ENV,
|
|
@@ -99,7 +100,9 @@ __all__ = [
|
|
|
99
100
|
"afetch",
|
|
100
101
|
"aread_url",
|
|
101
102
|
"asearch",
|
|
103
|
+
"cache_info",
|
|
102
104
|
"clear_fetch_cache",
|
|
105
|
+
"clear_web_cache",
|
|
103
106
|
"fetch_chain",
|
|
104
107
|
"find_feed_links",
|
|
105
108
|
"get_reader",
|
|
@@ -30,9 +30,25 @@ def _route_footer(served_by: str, route: dict[str, Any], verb: str = "served by"
|
|
|
30
30
|
failed = [a.get("backend") for a in route.get("attempts", []) if a.get("status") == "error"]
|
|
31
31
|
if route.get("fallback") and failed:
|
|
32
32
|
footer += f" (fallback after {', '.join(dict.fromkeys(str(f) for f in failed))} failed)"
|
|
33
|
+
if route.get("cached"):
|
|
34
|
+
footer += f", cached {_age_text(route.get('cache_age_s'))}"
|
|
33
35
|
return footer + "_"
|
|
34
36
|
|
|
35
37
|
|
|
38
|
+
def _age_text(age: Any) -> str:
|
|
39
|
+
try:
|
|
40
|
+
seconds = float(age)
|
|
41
|
+
except (TypeError, ValueError):
|
|
42
|
+
return "earlier"
|
|
43
|
+
if seconds < 60:
|
|
44
|
+
return "just now"
|
|
45
|
+
if seconds < 3600:
|
|
46
|
+
return f"{int(seconds // 60)} min ago"
|
|
47
|
+
if seconds < 86400:
|
|
48
|
+
return f"{int(seconds // 3600)} h ago"
|
|
49
|
+
return f"{int(seconds // 86400)} d ago"
|
|
50
|
+
|
|
51
|
+
|
|
36
52
|
@dataclass
|
|
37
53
|
class SearchResponse:
|
|
38
54
|
"""Search results plus the route that produced them.
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"""Local cache for web search, fetch, URL readers and platform search.
|
|
2
|
+
|
|
3
|
+
Repeated questions shouldn't cost a network round trip, but a weather or
|
|
4
|
+
price query must not be served from yesterday. Each entry gets a lifetime
|
|
5
|
+
from :func:`ttl_for`, based on how fast that kind of content changes:
|
|
6
|
+
|
|
7
|
+
===================================================== ==========
|
|
8
|
+
Content Lifetime
|
|
9
|
+
===================================================== ==========
|
|
10
|
+
Volatile searches (weather, prices, scores, news, 10 min
|
|
11
|
+
"today", ``recency_days <= 1``)
|
|
12
|
+
Recent-window searches (``recency_days <= 7``) 1 h
|
|
13
|
+
Other searches 6 h
|
|
14
|
+
Platform search (GitHub, HN, arXiv, YouTube) 30 min
|
|
15
|
+
Fast-moving pages (HN, Reddit, X, status pages) 10 min
|
|
16
|
+
Ordinary pages 1 h
|
|
17
|
+
Wikipedia 1 day
|
|
18
|
+
Papers, PDFs, DOIs, commit-pinned GitHub files, 7 days
|
|
19
|
+
YouTube transcripts
|
|
20
|
+
GitHub issues / pull requests, HN items 10 min
|
|
21
|
+
Feeds 15 min
|
|
22
|
+
Podcast episodes 1 day
|
|
23
|
+
===================================================== ==========
|
|
24
|
+
|
|
25
|
+
``PROMPTURE_WEB_CACHE`` picks the store: ``disk`` (default, SQLite at
|
|
26
|
+
``~/.prompture/cache/web_cache.db`` — shared across processes and CLI runs),
|
|
27
|
+
``memory`` (this process only) or ``off``. ``PROMPTURE_WEB_CACHE_PATH``
|
|
28
|
+
moves the database. Every function also takes ``use_cache=False`` and
|
|
29
|
+
``cache_ttl=<seconds>``. Errors and challenge pages are never cached, and a
|
|
30
|
+
cached result says so: ``route["cached"] is True`` with ``cache_age_s``.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
import hashlib
|
|
36
|
+
import json
|
|
37
|
+
import logging
|
|
38
|
+
import re
|
|
39
|
+
import threading
|
|
40
|
+
import time
|
|
41
|
+
from pathlib import Path
|
|
42
|
+
from typing import Any
|
|
43
|
+
from urllib.parse import urlsplit
|
|
44
|
+
|
|
45
|
+
from ...infra.cache import CacheBackend, MemoryCacheBackend, SQLiteCacheBackend
|
|
46
|
+
|
|
47
|
+
logger = logging.getLogger("prompture.tools.web.cache")
|
|
48
|
+
|
|
49
|
+
CACHE_ENV = "PROMPTURE_WEB_CACHE"
|
|
50
|
+
CACHE_PATH_ENV = "PROMPTURE_WEB_CACHE_PATH"
|
|
51
|
+
DEFAULT_PATH = Path.home() / ".prompture" / "cache" / "web_cache.db"
|
|
52
|
+
MAX_ENTRIES = 5000
|
|
53
|
+
MEMORY_ENTRIES = 512
|
|
54
|
+
# Pages above this size stay out of the disk cache (still served, just not stored).
|
|
55
|
+
MAX_VALUE_BYTES = 2 * 1024 * 1024
|
|
56
|
+
|
|
57
|
+
MINUTE = 60
|
|
58
|
+
HOUR = 60 * MINUTE
|
|
59
|
+
DAY = 24 * HOUR
|
|
60
|
+
|
|
61
|
+
# Queries whose answers change by the hour.
|
|
62
|
+
_VOLATILE_QUERY = re.compile(
|
|
63
|
+
r"\b(weather|forecast|temperature|rain|snow|today|tonight|tomorrow|yesterday|right now|currently|"
|
|
64
|
+
r"live|breaking|latest|news|headlines?|price|prices|stock|stocks|shares?|quote|exchange rate|crypto|"
|
|
65
|
+
r"bitcoin|score|scores|standings|results|traffic|outage|status|election|polls?|this (week|month))\b",
|
|
66
|
+
re.IGNORECASE,
|
|
67
|
+
)
|
|
68
|
+
_VOLATILE_HOSTS = (
|
|
69
|
+
"news.ycombinator.com",
|
|
70
|
+
"reddit.com",
|
|
71
|
+
"x.com",
|
|
72
|
+
"twitter.com",
|
|
73
|
+
"status.",
|
|
74
|
+
"weather.",
|
|
75
|
+
"finance.yahoo.com",
|
|
76
|
+
)
|
|
77
|
+
_STATIC_HOSTS = ("arxiv.org", "doi.org", "export.arxiv.org", "openreview.net", "aclanthology.org")
|
|
78
|
+
_SHA_PATH = re.compile(r"/[0-9a-f]{40}(/|$)")
|
|
79
|
+
|
|
80
|
+
_lock = threading.Lock()
|
|
81
|
+
_store: tuple[tuple[str, str], CacheBackend | None] | None = None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# ---------------------------------------------------------------------------
|
|
85
|
+
# Lifetimes
|
|
86
|
+
# ---------------------------------------------------------------------------
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _host(url: str) -> str:
|
|
90
|
+
try:
|
|
91
|
+
return (urlsplit(url).hostname or "").lower()
|
|
92
|
+
except ValueError:
|
|
93
|
+
return ""
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def search_ttl(query: str, recency_days: int | None = None) -> int:
|
|
97
|
+
"""Lifetime for a web search: short for volatile topics, hours otherwise."""
|
|
98
|
+
if recency_days is not None and recency_days <= 1:
|
|
99
|
+
return 10 * MINUTE
|
|
100
|
+
if _VOLATILE_QUERY.search(query or ""):
|
|
101
|
+
return 10 * MINUTE
|
|
102
|
+
if recency_days is not None and recency_days <= 7:
|
|
103
|
+
return HOUR
|
|
104
|
+
return 6 * HOUR
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def page_ttl(url: str) -> int:
|
|
108
|
+
"""Lifetime for a fetched page, from how static its URL looks."""
|
|
109
|
+
host = _host(url)
|
|
110
|
+
path = urlsplit(url).path.lower() if url else ""
|
|
111
|
+
if any(host == h or host.endswith("." + h) or (h.endswith(".") and host.startswith(h)) for h in _VOLATILE_HOSTS):
|
|
112
|
+
return 10 * MINUTE
|
|
113
|
+
if any(host == h or host.endswith("." + h) for h in _STATIC_HOSTS) or path.endswith(".pdf"):
|
|
114
|
+
return 7 * DAY
|
|
115
|
+
if host in ("github.com", "raw.githubusercontent.com") and _SHA_PATH.search(path):
|
|
116
|
+
return 7 * DAY
|
|
117
|
+
if host.endswith("wikipedia.org"):
|
|
118
|
+
return DAY
|
|
119
|
+
return HOUR
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def read_ttl(url: str, reader: str, kind: str = "page") -> int:
|
|
123
|
+
"""Lifetime for a :func:`read_url` result, per reader and content kind."""
|
|
124
|
+
reader = (reader or "").lower()
|
|
125
|
+
if reader == "youtube":
|
|
126
|
+
return 7 * DAY # a published video's transcript doesn't change
|
|
127
|
+
if reader == "arxiv":
|
|
128
|
+
return 7 * DAY
|
|
129
|
+
if reader == "wikipedia":
|
|
130
|
+
return DAY
|
|
131
|
+
if reader == "podcasts":
|
|
132
|
+
return DAY
|
|
133
|
+
if reader == "feeds":
|
|
134
|
+
return 15 * MINUTE
|
|
135
|
+
if reader == "hackernews":
|
|
136
|
+
return 10 * MINUTE
|
|
137
|
+
if reader == "github":
|
|
138
|
+
if kind in ("issue", "pull_request", "pr", "discussion") or re.search(r"/(issues|pull|discussions)/", url):
|
|
139
|
+
return 10 * MINUTE
|
|
140
|
+
return page_ttl(url)
|
|
141
|
+
return page_ttl(url)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
PLATFORM_TTL = 30 * MINUTE
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def ttl_for(kind: str, **context: Any) -> int:
|
|
148
|
+
"""Lifetime in seconds for an entry of *kind* (``search``, ``fetch``, ``read``, ``platform``)."""
|
|
149
|
+
if kind == "search":
|
|
150
|
+
return search_ttl(context.get("query", ""), context.get("recency_days"))
|
|
151
|
+
if kind == "fetch":
|
|
152
|
+
return page_ttl(context.get("url", ""))
|
|
153
|
+
if kind == "read":
|
|
154
|
+
return read_ttl(context.get("url", ""), context.get("reader", ""), context.get("result_kind", "page"))
|
|
155
|
+
if kind == "platform":
|
|
156
|
+
return PLATFORM_TTL
|
|
157
|
+
return HOUR
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
# ---------------------------------------------------------------------------
|
|
161
|
+
# Store
|
|
162
|
+
# ---------------------------------------------------------------------------
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _setting(name: str) -> str | None:
|
|
166
|
+
try:
|
|
167
|
+
from ...infra.credentials import get_config_value
|
|
168
|
+
|
|
169
|
+
value = get_config_value(name)
|
|
170
|
+
except Exception:
|
|
171
|
+
import os
|
|
172
|
+
|
|
173
|
+
value = os.environ.get(name)
|
|
174
|
+
return value.strip() if isinstance(value, str) and value.strip() else None
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def cache_mode() -> str:
|
|
178
|
+
"""``disk`` (default), ``memory`` or ``off``."""
|
|
179
|
+
mode = (_setting(CACHE_ENV) or "disk").lower()
|
|
180
|
+
if mode in ("0", "false", "no", "none", "disabled"):
|
|
181
|
+
return "off"
|
|
182
|
+
return mode if mode in ("disk", "memory", "off") else "disk"
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def cache_path() -> Path:
|
|
186
|
+
custom = _setting(CACHE_PATH_ENV)
|
|
187
|
+
return Path(custom).expanduser() if custom else DEFAULT_PATH
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _backend() -> CacheBackend | None:
|
|
191
|
+
"""The active store, rebuilt when the mode or path changes."""
|
|
192
|
+
global _store
|
|
193
|
+
signature = (cache_mode(), str(cache_path()))
|
|
194
|
+
with _lock:
|
|
195
|
+
if _store is not None and _store[0] == signature:
|
|
196
|
+
return _store[1]
|
|
197
|
+
mode, path = signature
|
|
198
|
+
backend: CacheBackend | None
|
|
199
|
+
if mode == "off":
|
|
200
|
+
backend = None
|
|
201
|
+
elif mode == "memory":
|
|
202
|
+
backend = MemoryCacheBackend(maxsize=MEMORY_ENTRIES)
|
|
203
|
+
else:
|
|
204
|
+
try:
|
|
205
|
+
backend = SQLiteCacheBackend(db_path=path, max_entries=MAX_ENTRIES)
|
|
206
|
+
except Exception as exc: # read-only home, locked file, ...
|
|
207
|
+
logger.warning("web cache: disk store unavailable (%s); using memory", exc)
|
|
208
|
+
backend = MemoryCacheBackend(maxsize=MEMORY_ENTRIES)
|
|
209
|
+
_store = (signature, backend)
|
|
210
|
+
return backend
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def make_key(kind: str, *parts: Any) -> str:
|
|
214
|
+
"""Stable key for *kind* and its arguments."""
|
|
215
|
+
raw = json.dumps([kind, *parts], sort_keys=True, default=str, ensure_ascii=False)
|
|
216
|
+
return f"web:{kind}:" + hashlib.sha256(raw.encode("utf-8")).hexdigest()
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def get(key: str) -> tuple[Any, float] | None:
|
|
220
|
+
"""Return ``(value, age_seconds)`` for a live entry, else ``None``."""
|
|
221
|
+
backend = _backend()
|
|
222
|
+
if backend is None:
|
|
223
|
+
return None
|
|
224
|
+
try:
|
|
225
|
+
entry = backend.get(key)
|
|
226
|
+
except Exception as exc:
|
|
227
|
+
logger.debug("web cache read failed: %s", exc)
|
|
228
|
+
return None
|
|
229
|
+
if not isinstance(entry, dict) or "value" not in entry:
|
|
230
|
+
return None
|
|
231
|
+
return entry["value"], max(0.0, time.time() - float(entry.get("stored_at", time.time())))
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def put(key: str, value: Any, ttl: float) -> None:
|
|
235
|
+
"""Store a JSON-serializable *value* for *ttl* seconds (``<= 0`` skips)."""
|
|
236
|
+
backend = _backend()
|
|
237
|
+
if backend is None or ttl <= 0:
|
|
238
|
+
return
|
|
239
|
+
entry = {"stored_at": time.time(), "value": value}
|
|
240
|
+
if isinstance(backend, SQLiteCacheBackend):
|
|
241
|
+
try:
|
|
242
|
+
if len(json.dumps(entry, default=str)) > MAX_VALUE_BYTES:
|
|
243
|
+
return
|
|
244
|
+
except (TypeError, ValueError):
|
|
245
|
+
return
|
|
246
|
+
try:
|
|
247
|
+
backend.set(key, entry, ttl=int(ttl))
|
|
248
|
+
except Exception as exc:
|
|
249
|
+
logger.debug("web cache write failed: %s", exc)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def mark_cached(route: dict[str, Any] | None, age: float) -> dict[str, Any]:
|
|
253
|
+
"""Copy of *route* flagged as served from the cache."""
|
|
254
|
+
return {**(route or {}), "cached": True, "cache_age_s": round(age, 1)}
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def clear_web_cache() -> None:
|
|
258
|
+
"""Drop every cached search, page, reader result and platform search."""
|
|
259
|
+
backend = _backend()
|
|
260
|
+
if backend is not None:
|
|
261
|
+
backend.clear()
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def cache_info() -> dict[str, Any]:
|
|
265
|
+
"""Mode, location and entry count (for doctor / debugging).
|
|
266
|
+
|
|
267
|
+
Read-only: it never creates the cache database.
|
|
268
|
+
"""
|
|
269
|
+
mode = cache_mode()
|
|
270
|
+
path = cache_path()
|
|
271
|
+
info: dict[str, Any] = {"mode": mode, "path": str(path) if mode == "disk" else None, "entries": None}
|
|
272
|
+
if mode == "disk":
|
|
273
|
+
if not path.exists():
|
|
274
|
+
info["entries"] = 0
|
|
275
|
+
return info
|
|
276
|
+
try:
|
|
277
|
+
import sqlite3
|
|
278
|
+
|
|
279
|
+
conn = sqlite3.connect(f"file:{path.as_posix()}?mode=ro", uri=True, timeout=2)
|
|
280
|
+
try:
|
|
281
|
+
info["entries"] = conn.execute("SELECT COUNT(*) FROM cache").fetchone()[0]
|
|
282
|
+
finally:
|
|
283
|
+
conn.close()
|
|
284
|
+
except Exception:
|
|
285
|
+
info["entries"] = None
|
|
286
|
+
elif mode == "memory":
|
|
287
|
+
with _lock:
|
|
288
|
+
backend = _store[1] if _store is not None and _store[0] == (mode, str(path)) else None
|
|
289
|
+
info["entries"] = len(backend._data) if isinstance(backend, MemoryCacheBackend) else 0
|
|
290
|
+
return info
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def _reset_for_tests() -> None:
|
|
294
|
+
global _store
|
|
295
|
+
with _lock:
|
|
296
|
+
_store = None
|