nlp2sql 0.2.0rc14__tar.gz → 0.2.0rc15__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.
- nlp2sql-0.2.0rc15/CHANGELOG.md +89 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/PKG-INFO +12 -12
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/README.md +6 -6
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docs/API.md +1 -1
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/advanced/test_multiple_providers.py +11 -11
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/getting_started/simple_demo.py +1 -1
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/mcp_server/__init__.py +1 -1
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/mcp_server/pyproject.toml +2 -2
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/pyproject.toml +6 -6
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/__init__.py +7 -7
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/anthropic_adapter.py +65 -22
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/gemini_adapter.py +97 -22
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/openai_adapter.py +159 -34
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/cli.py +12 -7
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/config/settings.py +7 -4
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/core/provider_config.py +6 -3
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_basic.py +15 -12
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_dsl_integration.py +1 -1
- nlp2sql-0.2.0rc15/tests/test_model_defaults.py +284 -0
- nlp2sql-0.2.0rc15/tests/test_provider_compat_llm.py +240 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/uv.lock +6 -6
- nlp2sql-0.2.0rc14/CHANGELOG.md +0 -43
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.claude/commands/db.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.claude/commands/quality.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.claude/commands/test.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.claude/rules/adapters.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.claude/rules/architecture.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.claude/rules/python-style.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.claude/rules/testing.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.claude/settings.json +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.github/workflows/ci.yml +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.github/workflows/publish-pypi.yml +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.github/workflows/publish-testpypi.yml +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.gitignore +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.mcp.json.example +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/.python-version +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/CLAUDE.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/CONTRIBUTING.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/LICENSE +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/SECURITY.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/assets/nlp2sql-logo.png +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/benchmarks/enterprise_benchmark_results.json +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docker/.env.example +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docker/README.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docker/docker-compose.yml +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docker/get-db-urls.sh +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docker/init-schema.sql +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docker/large-schema.sql +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docker/localstack-init.sh +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docker/test-redshift.sh +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docs/ARCHITECTURE.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docs/CONFIGURATION.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docs/ENTERPRISE.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/docs/Redshift.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/README.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/advanced/test_simple_api.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/database_specific/test_odoo_integration.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/default_examples.json +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/documentation/real_world_example.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/getting_started/basic_usage.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/getting_started/test_api_setup.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/schema_management/test_auto_schema.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/schema_management/test_schema_filters_comprehensive.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/.dockerignore +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/.env.example +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/DOCKER_README.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/DOCKER_SETUP.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/DOCKER_TESTING_SUMMARY.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/Dockerfile +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/INDEX.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/README.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/docker/init-ecommerce-schema.sql +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/docker-compose.yml +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/main.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/pyproject.toml +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/examples/strands-fastapi-agent/test-docker-endpoints.sh +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/install-dev.sh +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/mcp_server/README.md +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/mcp_server/example_config.json +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/mcp_server/server.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/default_error_classifier.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/default_repair_policy.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/dict_semantic_resolver.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/file_semantic_resolver.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/local_embedding_adapter.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/noop_semantic_resolver.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/noop_semantic_validator.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/openai_embedding_adapter.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/pgvector_example_repository.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/postgres_repository.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/redshift_adapter.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/regex_query_validator.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/adapters/schema_repository_execution_adapter.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/client.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/config/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/core/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/core/database_prompts.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/core/entities.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/core/result.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/core/runtime.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/core/sql_keywords.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/core/sql_safety.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/exceptions/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/factories/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/factories/repository_factory.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/ai_provider.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/cache.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/embedding_provider.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/error_classifier.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/example_repository.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/query_execution.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/query_optimizer.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/query_safety.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/query_validator.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/repair_policy.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/schema_repository.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/schema_strategy.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/semantic_resolver.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/ports/semantic_validator.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/schema/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/schema/analyzer.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/schema/embedding_manager.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/schema/example_loader.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/schema/example_store.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/schema/manager.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/example_selection_service.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/prompt_assembly_service.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/query_analysis_service.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/query_repair_service.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/query_service.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/semantic_resolution_service.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/semantic_validation_service.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/services/sql_intent_planning_service.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/utils/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/utils/artifact_loader.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/utils/helpers.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/utils/semantic_prompt.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/src/nlp2sql/utils/storage.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/test_tmp/.gitignore +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/conftest.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/mcp/__init__.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/mcp/test_sql_security.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_artifact_loader.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_batch_scoring.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_cli_semantic_support.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_client_hooks.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_column_validation.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_database_prompts.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_embedding_manager.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_integration.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_pgvector_example_repository.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_postgres_integration.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_redshift_integration.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_repository_cache.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_repository_factory.py +0 -0
- {nlp2sql-0.2.0rc14 → nlp2sql-0.2.0rc15}/tests/test_retrieval_pipeline.py +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## Versioning policy
|
|
9
|
+
|
|
10
|
+
- **MAJOR** — incompatible public API changes (removing/renaming a public symbol
|
|
11
|
+
or changing a port/ABC contract in a non-backward-compatible way).
|
|
12
|
+
- **MINOR** — backward-compatible functionality (new adapters, new optional
|
|
13
|
+
parameters, new optional extras).
|
|
14
|
+
- **PATCH** — backward-compatible bug fixes.
|
|
15
|
+
|
|
16
|
+
Pre-1.0 the project ships release candidates (e.g. `0.2.0rcN`). Public surface
|
|
17
|
+
changes — moving/renaming exported symbols, or adding methods to a published
|
|
18
|
+
port such as `ExampleRepositoryPort` — MUST be recorded under `Unreleased`
|
|
19
|
+
before release and called out as **Breaking** if they affect external
|
|
20
|
+
implementers. Backward-compatible shims are preferred over hard breaks while
|
|
21
|
+
pre-1.0.
|
|
22
|
+
|
|
23
|
+
## [Unreleased]
|
|
24
|
+
|
|
25
|
+
## [0.2.0rc15] - 2026-09-18
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- Default chat models refreshed to current, non-retired IDs. **User-visible: cost,
|
|
29
|
+
latency and SQL style change for anyone who does not pin `model`.**
|
|
30
|
+
- OpenAI: `gpt-4o-mini` -> `gpt-5.6-luna` (1.05M context, 922K input, 128K output).
|
|
31
|
+
`gpt-4o-mini` remains callable; pin it with `ProviderConfig(model="gpt-4o-mini")`.
|
|
32
|
+
- Anthropic: `claude-sonnet-4-20250514` (retired by Anthropic on 2026-06-15) ->
|
|
33
|
+
`claude-sonnet-5` (1M context, 128K output).
|
|
34
|
+
- Gemini: `gemini-2.0-flash` (shut down by Google on 2026-06-01) ->
|
|
35
|
+
`gemini-3.6-flash` (1,048,576 context, 65,536 output).
|
|
36
|
+
- `ProviderConfig.DEFAULT_MODELS` is now the single source of truth for provider
|
|
37
|
+
defaults; the adapters, `Settings.get_provider_config()` and `nlp2sql providers list`
|
|
38
|
+
read from it.
|
|
39
|
+
- `AnthropicAdapter` no longer sends `temperature` to the Messages API: Claude 4.7+
|
|
40
|
+
models reject non-default sampling parameters (HTTP 400) and the `anthropic` SDK
|
|
41
|
+
removes the keyword in 1.0. `ProviderConfig(temperature=...)` is still accepted for
|
|
42
|
+
Anthropic but ignored (logged at INFO); explicitly pinned older Claude models now run
|
|
43
|
+
at the API default temperature.
|
|
44
|
+
- `OpenAIAdapter` sends `max_completion_tokens` instead of the deprecated `max_tokens`.
|
|
45
|
+
For reasoning models (every model outside the `gpt-3.5`, `gpt-4` and `chatgpt-4o`
|
|
46
|
+
families, including `gpt-5.6-*`) it sets `reasoning_effort` (default `low`, new
|
|
47
|
+
`reasoning_effort` constructor argument) and omits `temperature`; `gpt-4o`/`gpt-4.1`
|
|
48
|
+
keep receiving `temperature`. Response metadata gains `reasoning_effort` and
|
|
49
|
+
`reasoning_tokens`.
|
|
50
|
+
- Unknown model IDs no longer fall back to crippling context limits (OpenAI 8,192,
|
|
51
|
+
Gemini 30,720, Anthropic 100,000). They resolve by model family where possible and
|
|
52
|
+
otherwise fall back to 128,000 / 1,048,576 (Gemini family) / 200,000, logging a
|
|
53
|
+
warning when the adapter is constructed.
|
|
54
|
+
- `OpenAIAdapter` token counting maps the `gpt-5`, `gpt-4.1`, `gpt-4o` and `o1`-`o4`
|
|
55
|
+
families to `o200k_base` (tiktoken has no entry for `gpt-5.6-*`) and falls back to
|
|
56
|
+
`o200k_base`, never `cl100k_base`, for unknown IDs.
|
|
57
|
+
- `GeminiAdapter` reads token usage from `usage_metadata` instead of issuing extra
|
|
58
|
+
`count_tokens` calls after each response.
|
|
59
|
+
- Minimum dependency versions raised: `openai>=1.58.0` (`reasoning_effort`),
|
|
60
|
+
`tiktoken>=0.7.0` (`o200k_base`), `google-generativeai>=0.8.5` (`usage_metadata`).
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
- `connect()` / `ask()` failed out of the box for Anthropic and Gemini because their
|
|
64
|
+
default model IDs had been retired by the providers.
|
|
65
|
+
- Reasoning/thinking models that exhaust `max_tokens` before emitting content now raise
|
|
66
|
+
an actionable `ProviderException` instead of "Invalid JSON response" or
|
|
67
|
+
"Failed to parse response".
|
|
68
|
+
- `AnthropicAdapter` and `GeminiAdapter` re-raise `ProviderException` after exhausting
|
|
69
|
+
retries instead of surfacing `tenacity.RetryError`.
|
|
70
|
+
|
|
71
|
+
## [0.2.0rc14] - 2026-09-16
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
- `PgvectorExampleRepository`: a Postgres + `pgvector` implementation of
|
|
75
|
+
`ExampleRepositoryPort`, an alternative to the on-disk FAISS `ExampleStore`
|
|
76
|
+
for storing and semantically searching few-shot examples. Stores examples in
|
|
77
|
+
a single table with a `namespace` column (per-database isolation via
|
|
78
|
+
`md5(database_url:schema_name)`, byte-identical to `ExampleStore`), cosine
|
|
79
|
+
distance search over an HNSW index, and idempotent `auto_migrate` DDL.
|
|
80
|
+
- Optional `pgvector` extra: `pip install 'nlp2sql[pgvector]'`.
|
|
81
|
+
- CI: a `pgvector-integration` job that runs the adapter's integration tests
|
|
82
|
+
against a `pgvector/pgvector:pg16` service. The job fails (rather than skips)
|
|
83
|
+
when the database or `vector` extension is unavailable
|
|
84
|
+
(`NLP2SQL_REQUIRE_INTEGRATION`).
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
- `docker/docker-compose.yml`: the `postgres` service image is now
|
|
88
|
+
`pgvector/pgvector:pg16` (drop-in replacement for `postgres:16`, adds the
|
|
89
|
+
`vector` extension) so integration tests run out of the box.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: nlp2sql
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.0rc15
|
|
4
4
|
Summary: Enterprise-ready Natural Language to SQL converter with multi-provider support. Built for production scale (1000+ tables) with Clean Architecture.
|
|
5
5
|
Project-URL: Homepage, https://github.com/luiscarbonel1991/nlp2sql
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/luiscarbonel1991/nlp2sql/issues
|
|
@@ -26,11 +26,11 @@ Requires-Dist: azure-identity>=1.15.0
|
|
|
26
26
|
Requires-Dist: boto3>=1.34.0
|
|
27
27
|
Requires-Dist: click>=8.0.0
|
|
28
28
|
Requires-Dist: faiss-cpu>=1.7.4
|
|
29
|
-
Requires-Dist: google-generativeai>=0.
|
|
29
|
+
Requires-Dist: google-generativeai>=0.8.5
|
|
30
30
|
Requires-Dist: greenlet>=3.2.3
|
|
31
31
|
Requires-Dist: httpx>=0.25.0
|
|
32
32
|
Requires-Dist: numpy>=1.24.0
|
|
33
|
-
Requires-Dist: openai>=1.
|
|
33
|
+
Requires-Dist: openai>=1.58.0
|
|
34
34
|
Requires-Dist: pandas>=2.0.0
|
|
35
35
|
Requires-Dist: psycopg2-binary>=2.9.0
|
|
36
36
|
Requires-Dist: psycopg[binary]>=3.2.13
|
|
@@ -42,12 +42,12 @@ Requires-Dist: sqlalchemy-redshift>=0.7.0
|
|
|
42
42
|
Requires-Dist: sqlalchemy>=2.0.0
|
|
43
43
|
Requires-Dist: structlog>=24.1.0
|
|
44
44
|
Requires-Dist: tenacity>=8.2.0
|
|
45
|
-
Requires-Dist: tiktoken>=0.
|
|
45
|
+
Requires-Dist: tiktoken>=0.7.0
|
|
46
46
|
Provides-Extra: all-embeddings
|
|
47
47
|
Requires-Dist: sentence-transformers>=2.5.0; extra == 'all-embeddings'
|
|
48
48
|
Provides-Extra: all-providers
|
|
49
49
|
Requires-Dist: anthropic>=0.18.0; extra == 'all-providers'
|
|
50
|
-
Requires-Dist: google-generativeai>=0.
|
|
50
|
+
Requires-Dist: google-generativeai>=0.8.5; extra == 'all-providers'
|
|
51
51
|
Provides-Extra: anthropic
|
|
52
52
|
Requires-Dist: anthropic>=0.18.0; extra == 'anthropic'
|
|
53
53
|
Provides-Extra: dev
|
|
@@ -66,7 +66,7 @@ Provides-Extra: embeddings-local
|
|
|
66
66
|
Requires-Dist: sentence-transformers>=2.5.0; extra == 'embeddings-local'
|
|
67
67
|
Provides-Extra: embeddings-openai
|
|
68
68
|
Provides-Extra: gemini
|
|
69
|
-
Requires-Dist: google-generativeai>=0.
|
|
69
|
+
Requires-Dist: google-generativeai>=0.8.5; extra == 'gemini'
|
|
70
70
|
Provides-Extra: mssql
|
|
71
71
|
Requires-Dist: pymssql>=2.2.0; extra == 'mssql'
|
|
72
72
|
Provides-Extra: mysql
|
|
@@ -344,13 +344,13 @@ postgresql://testuser:testpass@localhost:5432/testdb
|
|
|
344
344
|
|
|
345
345
|
## Provider Comparison
|
|
346
346
|
|
|
347
|
-
| Provider | Default Model | Context Size | Best For |
|
|
348
|
-
|
|
349
|
-
| OpenAI | `gpt-
|
|
350
|
-
| Anthropic | `claude-sonnet-
|
|
351
|
-
| Gemini | `gemini-
|
|
347
|
+
| Provider | Default Model | Context Size | Max Output | Best For |
|
|
348
|
+
|----------|---------------|--------------|------------|----------|
|
|
349
|
+
| OpenAI | `gpt-5.6-luna` | 1.05M (922K input) | 128K | Fast, low-cost general purpose usage |
|
|
350
|
+
| Anthropic | `claude-sonnet-5` | 1M | 128K | Larger schemas and long prompts |
|
|
351
|
+
| Gemini | `gemini-3.6-flash` | 1M | 64K | High-volume and very large contexts |
|
|
352
352
|
|
|
353
|
-
|
|
353
|
+
Defaults are pinned snapshot IDs, not floating aliases. Override any of them through `ProviderConfig(model=...)`; for example `gpt-5.6-terra` is the higher-quality OpenAI option.
|
|
354
354
|
|
|
355
355
|
## Lower-Level API
|
|
356
356
|
|
|
@@ -264,13 +264,13 @@ postgresql://testuser:testpass@localhost:5432/testdb
|
|
|
264
264
|
|
|
265
265
|
## Provider Comparison
|
|
266
266
|
|
|
267
|
-
| Provider | Default Model | Context Size | Best For |
|
|
268
|
-
|
|
269
|
-
| OpenAI | `gpt-
|
|
270
|
-
| Anthropic | `claude-sonnet-
|
|
271
|
-
| Gemini | `gemini-
|
|
267
|
+
| Provider | Default Model | Context Size | Max Output | Best For |
|
|
268
|
+
|----------|---------------|--------------|------------|----------|
|
|
269
|
+
| OpenAI | `gpt-5.6-luna` | 1.05M (922K input) | 128K | Fast, low-cost general purpose usage |
|
|
270
|
+
| Anthropic | `claude-sonnet-5` | 1M | 128K | Larger schemas and long prompts |
|
|
271
|
+
| Gemini | `gemini-3.6-flash` | 1M | 64K | High-volume and very large contexts |
|
|
272
272
|
|
|
273
|
-
|
|
273
|
+
Defaults are pinned snapshot IDs, not floating aliases. Override any of them through `ProviderConfig(model=...)`; for example `gpt-5.6-terra` is the higher-quality OpenAI option.
|
|
274
274
|
|
|
275
275
|
## Lower-Level API
|
|
276
276
|
|
|
@@ -22,7 +22,7 @@ async def test_multiple_ai_providers():
|
|
|
22
22
|
# Test configuration for each provider
|
|
23
23
|
providers = [
|
|
24
24
|
{
|
|
25
|
-
"name": "OpenAI
|
|
25
|
+
"name": "OpenAI",
|
|
26
26
|
"provider": "openai",
|
|
27
27
|
"api_key": os.getenv("OPENAI_API_KEY"),
|
|
28
28
|
"env_var": "OPENAI_API_KEY",
|
|
@@ -126,7 +126,7 @@ async def demo_provider_selection():
|
|
|
126
126
|
use_cases = [
|
|
127
127
|
{
|
|
128
128
|
"use_case": "High accuracy complex queries",
|
|
129
|
-
"recommended": "OpenAI
|
|
129
|
+
"recommended": "OpenAI",
|
|
130
130
|
"reason": "Most sophisticated reasoning",
|
|
131
131
|
},
|
|
132
132
|
{
|
|
@@ -137,7 +137,7 @@ async def demo_provider_selection():
|
|
|
137
137
|
{
|
|
138
138
|
"use_case": "Long context/large schemas",
|
|
139
139
|
"recommended": "Anthropic Claude",
|
|
140
|
-
"reason": "
|
|
140
|
+
"reason": "1M token context window",
|
|
141
141
|
},
|
|
142
142
|
{
|
|
143
143
|
"use_case": "Privacy-sensitive data",
|
|
@@ -152,15 +152,15 @@ async def demo_provider_selection():
|
|
|
152
152
|
print(f" Reason: {case['reason']}")
|
|
153
153
|
print()
|
|
154
154
|
|
|
155
|
-
print("Cost Comparison (approx):")
|
|
156
|
-
print(" OpenAI
|
|
157
|
-
print(" Anthropic
|
|
158
|
-
print(" Google
|
|
155
|
+
print("Cost Comparison (approx, per 1M tokens in/out, default models):")
|
|
156
|
+
print(" OpenAI gpt-5.6-luna: $0.20 / $1.20")
|
|
157
|
+
print(" Anthropic claude-sonnet-5: $2 / $10")
|
|
158
|
+
print(" Google gemini-3.6-flash: $0.75 / $3.75")
|
|
159
159
|
print()
|
|
160
|
-
print("Context Limits:")
|
|
161
|
-
print(" OpenAI
|
|
162
|
-
print(" Anthropic
|
|
163
|
-
print(" Google
|
|
160
|
+
print("Context Limits (default models):")
|
|
161
|
+
print(" OpenAI gpt-5.6-luna: 1.05M tokens (922K input)")
|
|
162
|
+
print(" Anthropic claude-sonnet-5: 1M tokens")
|
|
163
|
+
print(" Google gemini-3.6-flash: 1M tokens")
|
|
164
164
|
|
|
165
165
|
|
|
166
166
|
if __name__ == "__main__":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nlp2sql-mcp"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.0rc15"
|
|
4
4
|
description = "MCP server for nlp2sql - Natural Language to SQL conversion"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.9"
|
|
@@ -21,4 +21,4 @@ build-backend = "hatchling.build"
|
|
|
21
21
|
[tool.mcp]
|
|
22
22
|
name = "nlp2sql"
|
|
23
23
|
description = "Convert natural language queries to SQL using multiple AI providers"
|
|
24
|
-
version = "0.2.
|
|
24
|
+
version = "0.2.0rc15"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "nlp2sql"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.0rc15"
|
|
4
4
|
description = "Enterprise-ready Natural Language to SQL converter with multi-provider support. Built for production scale (1000+ tables) with Clean Architecture."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = {text = "MIT"}
|
|
@@ -27,9 +27,9 @@ dependencies = [
|
|
|
27
27
|
"pydantic-settings>=2.0.0",
|
|
28
28
|
"sqlalchemy>=2.0.0",
|
|
29
29
|
"psycopg2-binary>=2.9.0",
|
|
30
|
-
"openai>=1.
|
|
30
|
+
"openai>=1.58.0",
|
|
31
31
|
"anthropic>=0.18.0",
|
|
32
|
-
"google-generativeai>=0.
|
|
32
|
+
"google-generativeai>=0.8.5",
|
|
33
33
|
"boto3>=1.34.0",
|
|
34
34
|
"azure-identity>=1.15.0",
|
|
35
35
|
"numpy>=1.24.0",
|
|
@@ -38,7 +38,7 @@ dependencies = [
|
|
|
38
38
|
"structlog>=24.1.0",
|
|
39
39
|
"httpx>=0.25.0",
|
|
40
40
|
"redis>=5.0.0",
|
|
41
|
-
"tiktoken>=0.
|
|
41
|
+
"tiktoken>=0.7.0",
|
|
42
42
|
"faiss-cpu>=1.7.4",
|
|
43
43
|
"pandas>=2.0.0",
|
|
44
44
|
"greenlet>=3.2.3",
|
|
@@ -52,8 +52,8 @@ mysql = ["pymysql>=1.1.0", "mysql-connector-python>=8.0.0"]
|
|
|
52
52
|
oracle = ["oracledb>=2.0.0"]
|
|
53
53
|
mssql = ["pymssql>=2.2.0"]
|
|
54
54
|
anthropic = ["anthropic>=0.18.0"]
|
|
55
|
-
gemini = ["google-generativeai>=0.
|
|
56
|
-
all-providers = ["anthropic>=0.18.0", "google-generativeai>=0.
|
|
55
|
+
gemini = ["google-generativeai>=0.8.5"]
|
|
56
|
+
all-providers = ["anthropic>=0.18.0", "google-generativeai>=0.8.5"]
|
|
57
57
|
embeddings-local = ["sentence-transformers>=2.5.0"]
|
|
58
58
|
embeddings-openai = []
|
|
59
59
|
all-embeddings = ["sentence-transformers>=2.5.0"]
|
|
@@ -46,7 +46,7 @@ from .ports.semantic_validator import SemanticValidatorPort
|
|
|
46
46
|
from .schema.example_store import ExampleStore
|
|
47
47
|
from .services.query_service import QueryGenerationService
|
|
48
48
|
|
|
49
|
-
__version__ = "0.2.
|
|
49
|
+
__version__ = "0.2.0rc15"
|
|
50
50
|
__author__ = "Luis Carbonel"
|
|
51
51
|
__email__ = "devhighlevel@gmail.com"
|
|
52
52
|
|
|
@@ -227,8 +227,8 @@ def create_query_service(
|
|
|
227
227
|
database_url: Database connection URL
|
|
228
228
|
ai_provider: AI provider to use ('openai', 'anthropic', 'gemini', etc.)
|
|
229
229
|
api_key: API key for the AI provider
|
|
230
|
-
model: Optional model name for the AI provider (e.g., 'gpt-
|
|
231
|
-
'gemini-
|
|
230
|
+
model: Optional model name for the AI provider (e.g., 'gpt-5.6-luna', 'claude-sonnet-5',
|
|
231
|
+
'gemini-3.6-flash'). If None, uses the provider's default model.
|
|
232
232
|
database_type: Type of database
|
|
233
233
|
schema_filters: Optional filters to limit schema scope
|
|
234
234
|
embedding_provider: Optional embedding provider instance
|
|
@@ -383,7 +383,7 @@ async def create_and_initialize_service(
|
|
|
383
383
|
database_url: Database connection URL
|
|
384
384
|
ai_provider: AI provider to use ('openai', 'anthropic', 'gemini', etc.)
|
|
385
385
|
api_key: API key for the AI provider
|
|
386
|
-
model: Optional model name for the AI provider (e.g., 'gpt-
|
|
386
|
+
model: Optional model name for the AI provider (e.g., 'gpt-5.6-luna', 'claude-sonnet-5').
|
|
387
387
|
If None, uses the provider's default model.
|
|
388
388
|
database_type: Type of database
|
|
389
389
|
schema_filters: Optional filters to limit schema scope
|
|
@@ -401,7 +401,7 @@ async def create_and_initialize_service(
|
|
|
401
401
|
"postgresql://user:pass@localhost/db",
|
|
402
402
|
ai_provider="anthropic",
|
|
403
403
|
api_key="your-api-key",
|
|
404
|
-
model="claude-sonnet-
|
|
404
|
+
model="claude-sonnet-5"
|
|
405
405
|
)
|
|
406
406
|
result = await service.generate_sql("Show all users")
|
|
407
407
|
"""
|
|
@@ -459,7 +459,7 @@ async def generate_sql_from_db(
|
|
|
459
459
|
question: Natural language question
|
|
460
460
|
ai_provider: AI provider to use (default: 'openai')
|
|
461
461
|
api_key: API key for the AI provider
|
|
462
|
-
model: Optional model name for the AI provider (e.g., 'gpt-
|
|
462
|
+
model: Optional model name for the AI provider (e.g., 'gpt-5.6-luna').
|
|
463
463
|
If None, uses the provider's default model.
|
|
464
464
|
database_type: Type of database (default: POSTGRES)
|
|
465
465
|
schema_filters: Optional filters to limit schema scope
|
|
@@ -480,7 +480,7 @@ async def generate_sql_from_db(
|
|
|
480
480
|
"Show me all active users",
|
|
481
481
|
ai_provider="openai",
|
|
482
482
|
api_key="your-api-key",
|
|
483
|
-
model="gpt-
|
|
483
|
+
model="gpt-5.6-luna"
|
|
484
484
|
)
|
|
485
485
|
"""
|
|
486
486
|
service = await create_and_initialize_service(
|
|
@@ -8,6 +8,7 @@ import structlog
|
|
|
8
8
|
from tenacity import retry, stop_after_attempt, wait_exponential
|
|
9
9
|
|
|
10
10
|
from ..config.settings import settings
|
|
11
|
+
from ..core.provider_config import ProviderConfig
|
|
11
12
|
from ..exceptions import ProviderException, TokenLimitException
|
|
12
13
|
from ..ports.ai_provider import AIProviderPort, AIProviderType, QueryContext, QueryResponse
|
|
13
14
|
from ..utils.helpers import first_not_none
|
|
@@ -15,11 +16,35 @@ from ..utils.semantic_prompt import format_semantic_context_lines, format_sql_in
|
|
|
15
16
|
|
|
16
17
|
logger = structlog.get_logger()
|
|
17
18
|
|
|
19
|
+
# Maximum input tokens per model. Legacy rows are kept so users who pin an
|
|
20
|
+
# older (or retired) model keep an accurate budget.
|
|
21
|
+
CONTEXT_LIMITS: Dict[str, int] = {
|
|
22
|
+
"claude-sonnet-5": 1_000_000,
|
|
23
|
+
"claude-sonnet-4-20250514": 200_000,
|
|
24
|
+
"claude-opus-4-20250514": 200_000,
|
|
25
|
+
"claude-3-7-sonnet-20250219": 200_000,
|
|
26
|
+
"claude-3-5-sonnet-20241022": 200_000,
|
|
27
|
+
"claude-3-5-haiku-20241022": 200_000,
|
|
28
|
+
"claude-3-opus-20240229": 200_000,
|
|
29
|
+
"claude-3-sonnet-20240229": 200_000,
|
|
30
|
+
"claude-3-haiku-20240307": 200_000,
|
|
31
|
+
"claude-2.1": 200_000,
|
|
32
|
+
"claude-2.0": 100_000,
|
|
33
|
+
}
|
|
34
|
+
# Every Claude model since 2.1 has at least a 200K window.
|
|
35
|
+
DEFAULT_CONTEXT_LIMIT = 200_000
|
|
36
|
+
|
|
18
37
|
|
|
19
38
|
class AnthropicAdapter(AIProviderPort):
|
|
20
|
-
"""Anthropic Claude adapter for natural language to SQL generation.
|
|
39
|
+
"""Anthropic Claude adapter for natural language to SQL generation.
|
|
40
|
+
|
|
41
|
+
Sampling parameters (``temperature``, ``top_p``, ``top_k``) are never sent:
|
|
42
|
+
Claude 4.7+ models reject non-default values with HTTP 400 and the
|
|
43
|
+
``anthropic`` SDK removes the keywords in 1.0. A ``temperature`` passed to
|
|
44
|
+
the constructor is kept for backward compatibility but not forwarded.
|
|
45
|
+
"""
|
|
21
46
|
|
|
22
|
-
DEFAULT_MODEL = "
|
|
47
|
+
DEFAULT_MODEL = ProviderConfig.DEFAULT_MODELS["anthropic"]
|
|
23
48
|
DEFAULT_MAX_TOKENS = 2000
|
|
24
49
|
DEFAULT_TEMPERATURE = 0.1
|
|
25
50
|
|
|
@@ -37,6 +62,15 @@ class AnthropicAdapter(AIProviderPort):
|
|
|
37
62
|
self.model = model or self.DEFAULT_MODEL
|
|
38
63
|
self.max_tokens = first_not_none(max_tokens, self.DEFAULT_MAX_TOKENS)
|
|
39
64
|
self.temperature = first_not_none(temperature, self.DEFAULT_TEMPERATURE)
|
|
65
|
+
self._max_context_size = self._resolve_context_limit(self.model)
|
|
66
|
+
|
|
67
|
+
if temperature is not None:
|
|
68
|
+
# INFO, not WARNING: the CLI always forwards its --temperature default.
|
|
69
|
+
logger.info(
|
|
70
|
+
"Anthropic adapter does not forward temperature (rejected by Claude 4.7+ models)",
|
|
71
|
+
model=self.model,
|
|
72
|
+
temperature=temperature,
|
|
73
|
+
)
|
|
40
74
|
|
|
41
75
|
self.client = anthropic.AsyncAnthropic(api_key=self.api_key)
|
|
42
76
|
|
|
@@ -45,13 +79,36 @@ class AnthropicAdapter(AIProviderPort):
|
|
|
45
79
|
provider="anthropic",
|
|
46
80
|
model=self.model,
|
|
47
81
|
max_tokens=self.max_tokens,
|
|
48
|
-
|
|
82
|
+
context_limit=self._max_context_size,
|
|
49
83
|
)
|
|
50
84
|
|
|
51
85
|
@property
|
|
52
86
|
def provider_type(self) -> AIProviderType:
|
|
53
87
|
return AIProviderType.ANTHROPIC
|
|
54
88
|
|
|
89
|
+
@staticmethod
|
|
90
|
+
def _resolve_context_limit(model: str) -> int:
|
|
91
|
+
"""Exact match, then longest model-family prefix, then a logged fallback."""
|
|
92
|
+
if model in CONTEXT_LIMITS:
|
|
93
|
+
return CONTEXT_LIMITS[model]
|
|
94
|
+
matches = [key for key in CONTEXT_LIMITS if model.startswith(key)]
|
|
95
|
+
if matches:
|
|
96
|
+
family = max(matches, key=len)
|
|
97
|
+
logger.debug(
|
|
98
|
+
"Resolved context limit by model family",
|
|
99
|
+
model=model,
|
|
100
|
+
family=family,
|
|
101
|
+
context_limit=CONTEXT_LIMITS[family],
|
|
102
|
+
)
|
|
103
|
+
return CONTEXT_LIMITS[family]
|
|
104
|
+
logger.warning(
|
|
105
|
+
"Unknown Anthropic model; using fallback context limit",
|
|
106
|
+
model=model,
|
|
107
|
+
context_limit=DEFAULT_CONTEXT_LIMIT,
|
|
108
|
+
hint="pin a model listed in anthropic_adapter.CONTEXT_LIMITS or add it",
|
|
109
|
+
)
|
|
110
|
+
return DEFAULT_CONTEXT_LIMIT
|
|
111
|
+
|
|
55
112
|
def get_token_count(self, text: str) -> int:
|
|
56
113
|
"""Estimate token count for Claude models."""
|
|
57
114
|
# Claude uses similar tokenization to GPT models
|
|
@@ -59,22 +116,10 @@ class AnthropicAdapter(AIProviderPort):
|
|
|
59
116
|
return len(text) // 4
|
|
60
117
|
|
|
61
118
|
def get_max_context_size(self) -> int:
|
|
62
|
-
"""Get maximum context size for the model."""
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"claude-3-7-sonnet-20250219": 200000,
|
|
67
|
-
"claude-3-5-sonnet-20241022": 200000,
|
|
68
|
-
"claude-3-5-haiku-20241022": 200000,
|
|
69
|
-
"claude-3-opus-20240229": 200000,
|
|
70
|
-
"claude-3-sonnet-20240229": 200000,
|
|
71
|
-
"claude-3-haiku-20240307": 200000,
|
|
72
|
-
"claude-2.1": 200000,
|
|
73
|
-
"claude-2.0": 100000,
|
|
74
|
-
}
|
|
75
|
-
return context_limits.get(self.model, 100000)
|
|
76
|
-
|
|
77
|
-
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
|
|
119
|
+
"""Get maximum input context size for the model."""
|
|
120
|
+
return self._max_context_size
|
|
121
|
+
|
|
122
|
+
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10), reraise=True)
|
|
78
123
|
async def generate_query(self, context: QueryContext) -> QueryResponse:
|
|
79
124
|
"""Generate SQL query using Claude."""
|
|
80
125
|
try:
|
|
@@ -88,11 +133,10 @@ class AnthropicAdapter(AIProviderPort):
|
|
|
88
133
|
# Create messages
|
|
89
134
|
messages = [{"role": "user", "content": prompt}]
|
|
90
135
|
|
|
91
|
-
# Call Claude API
|
|
136
|
+
# Call Claude API (no sampling parameters: see class docstring)
|
|
92
137
|
response = await self.client.messages.create(
|
|
93
138
|
model=self.model,
|
|
94
139
|
max_tokens=context.max_tokens,
|
|
95
|
-
temperature=context.temperature,
|
|
96
140
|
system=system_prompt,
|
|
97
141
|
messages=messages,
|
|
98
142
|
)
|
|
@@ -310,7 +354,6 @@ Check for:
|
|
|
310
354
|
message = await self.client.messages.create(
|
|
311
355
|
model=self.model,
|
|
312
356
|
max_tokens=1000,
|
|
313
|
-
temperature=0,
|
|
314
357
|
system="You are a SQL validation expert. Analyze the given SQL query and provide validation results in JSON format only.",
|
|
315
358
|
messages=[{"role": "user", "content": validation_prompt}],
|
|
316
359
|
)
|