prompture 1.0.45.dev2__tar.gz → 1.0.46.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/PKG-INFO +1 -1
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/_version.py +2 -2
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/__init__.py +2 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/discovery.py +22 -7
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/model_rates.py +158 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture.egg-info/PKG-INFO +1 -1
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/add-driver/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/add-driver/references/driver-template.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/add-example/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/add-field/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/add-persona/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/add-test/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/add-tool/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/run-tests/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/scaffold-extraction/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.claude/skills/update-pricing/SKILL.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.env.copy +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.github/FUNDING.yml +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.github/scripts/update_docs_version.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.github/scripts/update_wrapper_version.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.github/workflows/dev.yml +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.github/workflows/documentation.yml +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.github/workflows/publish.yml +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.github/workflows/security.yml +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/.safety-project.ini +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/CLAUDE.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/CONTRIBUTING.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/LICENSE +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/MANIFEST.in +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/README.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/ROADMAP.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/SECURITY.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/dev.ps1 +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/dev.sh +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/_static/custom.css +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/_templates/footer.html +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/api/core.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/api/drivers.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/api/field_definitions.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/api/index.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/api/runner.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/api/tools.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/api/validator.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/conf.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/contributing.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/examples.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/field_definitions_reference.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/index.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/installation.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/quickstart.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/docs/source/toon_input_guide.rst +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/mypy_errors.txt +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/README.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_json/README.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_json/llm_to_json/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_json/pyproject.toml +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_json/test.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_toon/README.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_toon/llm_to_toon/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_toon/pyproject.toml +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_toon/test.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/agent.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/async_agent.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/async_conversation.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/conversation.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/persona.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/simulated_tools.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/skills.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/tools_schema.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/agents/types.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/aio/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/bridges/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/bridges/tukuy_backend.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/cli/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/cli/cli.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/cli/runner.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/cli/server.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/airllm_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_airllm_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_azure_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_cachibot_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_claude_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_elevenlabs_stt_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_elevenlabs_tts_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_embedding_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_google_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_google_img_gen_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_grok_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_grok_img_gen_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_groq_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_hugging_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_img_gen_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_lmstudio_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_local_http_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_modelscope_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_moonshot_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_ollama_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_ollama_embedding_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_embedding_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_img_gen_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_stt_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_tts_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openrouter_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_registry.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_stability_img_gen_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_stt_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_tts_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_zai_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/audio_registry.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/azure_config.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/azure_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/cachibot_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/claude_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/elevenlabs_stt_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/elevenlabs_tts_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/embedding_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/embedding_registry.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/google_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/google_img_gen_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/grok_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/grok_img_gen_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/groq_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/hugging_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/img_gen_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/img_gen_registry.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/lmstudio_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/local_http_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/modelscope_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/moonshot_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/ollama_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/ollama_embedding_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/openai_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/openai_embedding_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/openai_img_gen_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/openai_stt_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/openai_tts_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/openrouter_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/registry.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/stability_img_gen_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/stt_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/tts_base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/vision_helpers.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/zai_driver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/exceptions.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/extraction/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/extraction/async_core.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/extraction/core.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/extraction/fields.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/extraction/reasoning.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/extraction/tools.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/extraction/validator.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/groups/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/groups/async_groups.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/groups/consensus.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/groups/debate.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/groups/groups.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/groups/types.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/budget.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/cache.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/callbacks.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/cost_mixin.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/ledger.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/logging.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/provider_env.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/rates/anthropic.json +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/rates/google.json +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/rates/groq.json +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/rates/openai.json +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/rates/xai.json +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/session.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/settings.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/infra/tracker.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/chunking.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/detect.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/document.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/parsers/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/parsers/base.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/parsers/csv_parser.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/parsers/docx.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/parsers/html.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/parsers/markdown.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/parsers/pdf.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/ingestion/parsers/xlsx.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/integrations/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/integrations/tukuy_bridge.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/media/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/media/audio.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/media/image.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/persistence/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/persistence/history.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/persistence/serialization.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/persistence/store.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/pipeline/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/pipeline/pipeline.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/pipeline/resolver.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/pipeline/routing.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/py.typed +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/__init__.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/generator.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/templates/Dockerfile.j2 +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/templates/README.md.j2 +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/templates/config.py.j2 +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/templates/env.example.j2 +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/templates/main.py.j2 +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/templates/models.py.j2 +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/scaffold/templates/requirements.txt.j2 +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture.egg-info/SOURCES.txt +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture.egg-info/dependency_links.txt +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture.egg-info/entry_points.txt +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture.egg-info/requires.txt +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture.egg-info/top_level.txt +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture_cost_tracking.md +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/pyproject.toml +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/requirements.txt +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/setup.cfg +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/test.py +0 -0
- {prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/test_version_diagnosis.py +0 -0
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.0.
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 0,
|
|
31
|
+
__version__ = version = '1.0.46.dev1'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 0, 46, 'dev1')
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -31,6 +31,7 @@ from .model_rates import (
|
|
|
31
31
|
ModelCapabilities,
|
|
32
32
|
get_model_capabilities,
|
|
33
33
|
get_model_info,
|
|
34
|
+
get_model_lifecycle,
|
|
34
35
|
get_model_rates,
|
|
35
36
|
refresh_rates_cache,
|
|
36
37
|
)
|
|
@@ -69,6 +70,7 @@ __all__ = [
|
|
|
69
70
|
"get_cache",
|
|
70
71
|
"get_model_capabilities",
|
|
71
72
|
"get_model_info",
|
|
73
|
+
"get_model_lifecycle",
|
|
72
74
|
"get_model_rates",
|
|
73
75
|
"get_recently_used_models",
|
|
74
76
|
"get_tracker",
|
|
@@ -166,7 +166,8 @@ def get_available_models(
|
|
|
166
166
|
return cached # type: ignore[no-any-return]
|
|
167
167
|
|
|
168
168
|
logger.debug("Discovery cache miss for key=%s — querying providers", cache_key)
|
|
169
|
-
|
|
169
|
+
# Maps model string → source ("api", "static", "catalog"). First source wins.
|
|
170
|
+
model_sources: dict[str, str] = {}
|
|
170
171
|
configured_providers: set[str] = set()
|
|
171
172
|
# Providers where list_models() returned an authoritative model list.
|
|
172
173
|
# For these, we trust the API response and skip MODEL_PRICING / models.dev additions.
|
|
@@ -265,7 +266,9 @@ def get_available_models(
|
|
|
265
266
|
api_succeeded = True
|
|
266
267
|
api_authoritative_providers.add(provider)
|
|
267
268
|
for model_id in api_models:
|
|
268
|
-
|
|
269
|
+
model_str = f"{provider}/{model_id}"
|
|
270
|
+
if model_str not in model_sources:
|
|
271
|
+
model_sources[model_str] = "api"
|
|
269
272
|
except Exception as e:
|
|
270
273
|
logger.warning("list_models() failed for %s: %s", provider, e)
|
|
271
274
|
|
|
@@ -277,7 +280,9 @@ def get_available_models(
|
|
|
277
280
|
for model_id in pricing:
|
|
278
281
|
if model_id == "default":
|
|
279
282
|
continue
|
|
280
|
-
|
|
283
|
+
model_str = f"{provider}/{model_id}"
|
|
284
|
+
if model_str not in model_sources:
|
|
285
|
+
model_sources[model_str] = "static"
|
|
281
286
|
|
|
282
287
|
except Exception as e:
|
|
283
288
|
logger.warning(f"Error detecting models for provider {provider}: {e}")
|
|
@@ -293,9 +298,11 @@ def get_available_models(
|
|
|
293
298
|
for prompture_name, api_name in PROVIDER_MAP.items():
|
|
294
299
|
if prompture_name in configured_providers and prompture_name not in api_authoritative_providers:
|
|
295
300
|
for model_id in get_all_provider_models(api_name):
|
|
296
|
-
|
|
301
|
+
model_str = f"{prompture_name}/{model_id}"
|
|
302
|
+
if model_str not in model_sources:
|
|
303
|
+
model_sources[model_str] = "catalog"
|
|
297
304
|
|
|
298
|
-
sorted_models = sorted(
|
|
305
|
+
sorted_models = sorted(model_sources.keys())
|
|
299
306
|
|
|
300
307
|
# --- verified_only filtering ---
|
|
301
308
|
verified_set: set[str] | None = None
|
|
@@ -316,8 +323,8 @@ def get_available_models(
|
|
|
316
323
|
_discovery_cache.set(cache_key, sorted_models, ttl=ttl)
|
|
317
324
|
return sorted_models
|
|
318
325
|
|
|
319
|
-
# Build enriched dicts with capabilities from models.dev
|
|
320
|
-
from .model_rates import get_model_capabilities
|
|
326
|
+
# Build enriched dicts with capabilities and lifecycle from models.dev
|
|
327
|
+
from .model_rates import get_model_capabilities, get_model_lifecycle
|
|
321
328
|
|
|
322
329
|
# Fetch all ledger stats for annotation (keyed by model_name)
|
|
323
330
|
ledger_stats: dict[str, dict[str, Any]] = {}
|
|
@@ -348,12 +355,20 @@ def get_available_models(
|
|
|
348
355
|
caps = get_model_capabilities(provider, model_id)
|
|
349
356
|
caps_dict = dataclasses.asdict(caps) if caps is not None else None
|
|
350
357
|
|
|
358
|
+
lifecycle = get_model_lifecycle(provider, model_id)
|
|
359
|
+
|
|
351
360
|
entry: dict[str, Any] = {
|
|
352
361
|
"model": model_str,
|
|
353
362
|
"provider": provider,
|
|
354
363
|
"model_id": model_id,
|
|
355
364
|
"capabilities": caps_dict,
|
|
365
|
+
"source": model_sources.get(model_str, "unknown"),
|
|
356
366
|
"verified": verified_set is not None and model_str in verified_set,
|
|
367
|
+
"status": lifecycle.get("status") if lifecycle else None,
|
|
368
|
+
"family": lifecycle.get("family") if lifecycle else None,
|
|
369
|
+
"release_date": lifecycle.get("release_date") if lifecycle else None,
|
|
370
|
+
"superseded_by": lifecycle.get("superseded_by") if lifecycle else None,
|
|
371
|
+
"end_of_support": lifecycle.get("end_of_support") if lifecycle else None,
|
|
357
372
|
}
|
|
358
373
|
|
|
359
374
|
stats = ledger_stats.get(model_str)
|
|
@@ -44,6 +44,10 @@ _lock = threading.Lock()
|
|
|
44
44
|
_data: Optional[dict[str, Any]] = None
|
|
45
45
|
_loaded = False
|
|
46
46
|
|
|
47
|
+
# Lifecycle cache: maps models.dev provider name → {model_id: lifecycle_dict}
|
|
48
|
+
_lifecycle_cache: dict[str, dict[str, dict[str, Any]]] = {}
|
|
49
|
+
_lifecycle_lock = threading.Lock()
|
|
50
|
+
|
|
47
51
|
|
|
48
52
|
def _get_ttl_days() -> int:
|
|
49
53
|
"""Get TTL from settings if available, otherwise default to 7."""
|
|
@@ -321,6 +325,9 @@ def refresh_rates_cache(force: bool = False) -> bool:
|
|
|
321
325
|
_data = fresh
|
|
322
326
|
_write_cache(fresh)
|
|
323
327
|
_loaded = True
|
|
328
|
+
# Clear lifecycle cache so it's recomputed from fresh data
|
|
329
|
+
with _lifecycle_lock:
|
|
330
|
+
_lifecycle_cache.clear()
|
|
324
331
|
return True
|
|
325
332
|
|
|
326
333
|
return False
|
|
@@ -482,3 +489,154 @@ def get_model_capabilities(provider: str, model_id: str) -> Optional[ModelCapabi
|
|
|
482
489
|
|
|
483
490
|
# models.dev unavailable — fall back to KB
|
|
484
491
|
return kb_entry
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
# ── Model Lifecycle / Deprecation ──────────────────────────────────────────
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
def _compute_family_status(provider_api_name: str) -> dict[str, dict[str, Any]]:
|
|
498
|
+
"""Compute lifecycle status for every model of a provider from models.dev data.
|
|
499
|
+
|
|
500
|
+
Groups models by ``family`` field, sorts each family by ``release_date``
|
|
501
|
+
descending, and assigns statuses:
|
|
502
|
+
|
|
503
|
+
- ``"current"`` — newest model in the family (or has ``"(latest)"`` marker).
|
|
504
|
+
- ``"legacy"`` — >6 months old with a newer sibling.
|
|
505
|
+
- ``"deprecated"`` — >18 months old with a newer sibling, or explicitly
|
|
506
|
+
marked ``status: "deprecated"`` in models.dev.
|
|
507
|
+
|
|
508
|
+
Returns a dict mapping ``model_id`` → lifecycle metadata dict with keys:
|
|
509
|
+
``status``, ``family``, ``release_date``, ``superseded_by``, ``end_of_support``.
|
|
510
|
+
"""
|
|
511
|
+
from datetime import timedelta
|
|
512
|
+
|
|
513
|
+
data = _ensure_loaded()
|
|
514
|
+
if data is None:
|
|
515
|
+
return {}
|
|
516
|
+
|
|
517
|
+
provider_data = data.get(provider_api_name)
|
|
518
|
+
if not isinstance(provider_data, dict):
|
|
519
|
+
return {}
|
|
520
|
+
|
|
521
|
+
models = provider_data.get("models", provider_data)
|
|
522
|
+
if not isinstance(models, dict):
|
|
523
|
+
return {}
|
|
524
|
+
|
|
525
|
+
now = datetime.now(timezone.utc)
|
|
526
|
+
|
|
527
|
+
# Build per-family lists: {family: [(model_id, entry, release_date, is_latest_marker), ...]}
|
|
528
|
+
families: dict[str, list[tuple[str, dict[str, Any], Optional[datetime], bool]]] = {}
|
|
529
|
+
for model_id, entry in models.items():
|
|
530
|
+
if not isinstance(entry, dict):
|
|
531
|
+
continue
|
|
532
|
+
|
|
533
|
+
family = entry.get("family") or _infer_family(model_id)
|
|
534
|
+
name = entry.get("name", "")
|
|
535
|
+
is_latest_marker = "(latest)" in name.lower() if name else False
|
|
536
|
+
|
|
537
|
+
release_date: Optional[datetime] = None
|
|
538
|
+
raw_date = entry.get("release_date")
|
|
539
|
+
if raw_date:
|
|
540
|
+
with contextlib.suppress(Exception):
|
|
541
|
+
release_date = datetime.fromisoformat(str(raw_date).replace("Z", "+00:00"))
|
|
542
|
+
if release_date.tzinfo is None:
|
|
543
|
+
release_date = release_date.replace(tzinfo=timezone.utc)
|
|
544
|
+
|
|
545
|
+
families.setdefault(family, []).append((model_id, entry, release_date, is_latest_marker))
|
|
546
|
+
|
|
547
|
+
result: dict[str, dict[str, Any]] = {}
|
|
548
|
+
|
|
549
|
+
for family, members in families.items():
|
|
550
|
+
# Sort by release_date descending (None dates go last)
|
|
551
|
+
members.sort(key=lambda m: m[2] or datetime.min.replace(tzinfo=timezone.utc), reverse=True)
|
|
552
|
+
|
|
553
|
+
# Identify the "current" model: explicit (latest) marker wins, else newest by date
|
|
554
|
+
current_idx = 0
|
|
555
|
+
for i, (_, _, _, is_latest) in enumerate(members):
|
|
556
|
+
if is_latest:
|
|
557
|
+
current_idx = i
|
|
558
|
+
break
|
|
559
|
+
|
|
560
|
+
for i, (model_id, entry, release_date, _) in enumerate(members):
|
|
561
|
+
# Check explicit status from models.dev
|
|
562
|
+
explicit_status = entry.get("status")
|
|
563
|
+
if isinstance(explicit_status, str) and explicit_status.lower() == "deprecated":
|
|
564
|
+
status = "deprecated"
|
|
565
|
+
elif i == current_idx:
|
|
566
|
+
status = "current"
|
|
567
|
+
elif release_date is not None:
|
|
568
|
+
age = now - release_date
|
|
569
|
+
has_newer = i > current_idx # there's a newer sibling
|
|
570
|
+
if has_newer and age > timedelta(days=548): # ~18 months
|
|
571
|
+
status = "deprecated"
|
|
572
|
+
elif has_newer and age > timedelta(days=183): # ~6 months
|
|
573
|
+
status = "legacy"
|
|
574
|
+
else:
|
|
575
|
+
status = "current"
|
|
576
|
+
else:
|
|
577
|
+
# No date info — if not the current one, mark as unknown
|
|
578
|
+
status = "current" if i == current_idx else "unknown"
|
|
579
|
+
|
|
580
|
+
# Compute superseded_by: next newer model in the family
|
|
581
|
+
superseded_by: Optional[str] = None
|
|
582
|
+
if i > current_idx and i > 0:
|
|
583
|
+
superseded_by = members[i - 1][0]
|
|
584
|
+
|
|
585
|
+
# Estimate end_of_support for legacy/deprecated: release_date + 24 months
|
|
586
|
+
end_of_support: Optional[str] = None
|
|
587
|
+
if status in ("legacy", "deprecated") and release_date is not None:
|
|
588
|
+
eos = release_date + timedelta(days=730) # ~24 months
|
|
589
|
+
end_of_support = eos.strftime("%Y-%m-%d")
|
|
590
|
+
|
|
591
|
+
result[model_id] = {
|
|
592
|
+
"status": status,
|
|
593
|
+
"family": family,
|
|
594
|
+
"release_date": release_date.strftime("%Y-%m-%d") if release_date else None,
|
|
595
|
+
"superseded_by": superseded_by,
|
|
596
|
+
"end_of_support": end_of_support,
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
return result
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
def _infer_family(model_id: str) -> str:
|
|
603
|
+
"""Infer a family name from a model ID by stripping date/version suffixes.
|
|
604
|
+
|
|
605
|
+
Examples:
|
|
606
|
+
- ``claude-3-haiku-20240307`` → ``claude-3-haiku``
|
|
607
|
+
- ``gpt-4o-2024-08-06`` → ``gpt-4o``
|
|
608
|
+
- ``gemini-1.5-pro`` → ``gemini-1.5-pro`` (no suffix to strip)
|
|
609
|
+
"""
|
|
610
|
+
import re
|
|
611
|
+
|
|
612
|
+
# Strip trailing date patterns: -YYYYMMDD or -YYYY-MM-DD
|
|
613
|
+
stripped = re.sub(r"-\d{4}-?\d{2}-?\d{2}$", "", model_id)
|
|
614
|
+
return stripped
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
def get_model_lifecycle(provider: str, model_id: str) -> Optional[dict[str, Any]]:
|
|
618
|
+
"""Return lifecycle/deprecation metadata for a model.
|
|
619
|
+
|
|
620
|
+
Returns a dict with keys: ``status``, ``family``, ``release_date``,
|
|
621
|
+
``superseded_by``, ``end_of_support``. Returns ``None`` for unknown models.
|
|
622
|
+
|
|
623
|
+
Results are cached per-provider; call :func:`refresh_rates_cache` to clear.
|
|
624
|
+
"""
|
|
625
|
+
api_provider = PROVIDER_MAP.get(provider, provider)
|
|
626
|
+
|
|
627
|
+
with _lifecycle_lock:
|
|
628
|
+
if api_provider not in _lifecycle_cache:
|
|
629
|
+
_lifecycle_cache[api_provider] = _compute_family_status(api_provider)
|
|
630
|
+
|
|
631
|
+
family_status = _lifecycle_cache.get(api_provider, {})
|
|
632
|
+
|
|
633
|
+
# Exact match
|
|
634
|
+
if model_id in family_status:
|
|
635
|
+
return dict(family_status[model_id])
|
|
636
|
+
|
|
637
|
+
# Try base model fallback (date-stripped)
|
|
638
|
+
base = _strip_to_base_model(model_id)
|
|
639
|
+
if base is not None and base in family_status:
|
|
640
|
+
return dict(family_status[base])
|
|
641
|
+
|
|
642
|
+
return None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_json/llm_to_json/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/packages/llm_to_toon/llm_to_toon/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_elevenlabs_stt_driver.py
RENAMED
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_elevenlabs_tts_driver.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_google_img_gen_driver.py
RENAMED
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_grok_img_gen_driver.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_local_http_driver.py
RENAMED
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_modelscope_driver.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_ollama_embedding_driver.py
RENAMED
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_embedding_driver.py
RENAMED
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_img_gen_driver.py
RENAMED
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_stt_driver.py
RENAMED
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openai_tts_driver.py
RENAMED
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_openrouter_driver.py
RENAMED
|
File without changes
|
|
File without changes
|
{prompture-1.0.45.dev2 → prompture-1.0.46.dev1}/prompture/drivers/async_stability_img_gen_driver.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|