diff --git a/PLUGIN_DEVELOPMENT.md b/PLUGIN_DEVELOPMENT.md index 37a375c..70f563a 100644 --- a/PLUGIN_DEVELOPMENT.md +++ b/PLUGIN_DEVELOPMENT.md @@ -36,7 +36,7 @@ build-backend = "hatchling.build" [project] name = "abc-provider-NAME" -version = "2025.09.04" # Match abc-cli version format +version = "2026.07.15" # Match abc-cli version format description = "NAME LLM provider for abc-cli" readme = "README.md" requires-python = ">=3.8" diff --git a/README.md b/README.md index 15ba276..c09bdd7 100644 --- a/README.md +++ b/README.md @@ -328,4 +328,4 @@ Prompt crafting by Eric Hammond ## Version -Current version: 2025.09.04 +Current version: 2026.07.15 diff --git a/abc_cli/abc_generate.py b/abc_cli/abc_generate.py index 33ce255..4ab2fda 100755 --- a/abc_cli/abc_generate.py +++ b/abc_cli/abc_generate.py @@ -29,7 +29,7 @@ # Entry point group for LLM providers PROVIDER_ENTRY_POINT = 'abc.llm_providers' -VERSION: str = "abc (AI Bash Command) version 2026.04.12" +VERSION: str = "abc (AI Bash Command) version 2026.07.15" PROGRAM_NAME: str = "abc" # Config file diff --git a/abc_provider_anthropic/abc_provider_anthropic/llm_provider.py b/abc_provider_anthropic/abc_provider_anthropic/llm_provider.py index 66e3a31..f20344c 100644 --- a/abc_provider_anthropic/abc_provider_anthropic/llm_provider.py +++ b/abc_provider_anthropic/abc_provider_anthropic/llm_provider.py @@ -5,8 +5,7 @@ from abc_cli import LLMProvider -DEFAULT_MODEL = 'claude-opus-4-5' -DEFAULT_TEMPERATURE = 0.0 +DEFAULT_MODEL = 'claude-opus-4-8' DEFAULT_MAX_TOKENS = 1000 class AnthropicProvider(LLMProvider): @@ -23,7 +22,12 @@ def __init__(self, config: Dict[str, str]): self.api_key = config['api_key'] self.model = config.get('model', DEFAULT_MODEL) - self.temperature = float(config.get('temperature', DEFAULT_TEMPERATURE)) + # Newer Claude models (Opus 4.7+, Sonnet 5, Fable 5) reject the + # `temperature` parameter. Only send it when the user explicitly + # configures one; otherwise omit it entirely. + self.temperature = ( + float(config['temperature']) if 'temperature' in config else None + ) self.max_tokens = int(config.get('max_tokens', DEFAULT_MAX_TOKENS)) self.client = anthropic.Anthropic(api_key=self.api_key) @@ -34,12 +38,11 @@ def generate_command( system_prompt: str, ) -> str: """Generate command using Anthropic Claude.""" - message = self.client.messages.create( - model=self.model, - max_tokens=self.max_tokens, - temperature=self.temperature, - system=system_prompt, - messages=[ + request_params = { + "model": self.model, + "max_tokens": self.max_tokens, + "system": system_prompt, + "messages": [ { "role": "user", "content": [ @@ -50,7 +53,11 @@ def generate_command( ] } ] - ) + } + if self.temperature is not None: + request_params["temperature"] = self.temperature + + message = self.client.messages.create(**request_params) return message.content[0].text.strip() def get_config_schema(self) -> Dict: @@ -74,8 +81,7 @@ def get_config_schema(self) -> Dict: }, "temperature": { "type": "string", - "description": "Sampling temperature", - "default": DEFAULT_TEMPERATURE + "description": "Sampling temperature (omitted unless set; unsupported by newer Claude models)" }, "max_tokens": { "type": "string", diff --git a/abc_provider_anthropic/pyproject.toml b/abc_provider_anthropic/pyproject.toml index 63fa368..d09215b 100644 --- a/abc_provider_anthropic/pyproject.toml +++ b/abc_provider_anthropic/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "abc-provider-anthropic" -version = "2026.04.12" +version = "2026.07.15" description = "Anthropic LLM provider for abc-cli" readme = "README.md" requires-python = ">=3.8" diff --git a/abc_provider_anthropic/tests/test_provider.py b/abc_provider_anthropic/tests/test_provider.py index e1c171f..91a71ee 100644 --- a/abc_provider_anthropic/tests/test_provider.py +++ b/abc_provider_anthropic/tests/test_provider.py @@ -40,7 +40,7 @@ def test_init_minimal_config(): provider = AnthropicProvider(MOCK_CONFIG) assert provider.api_key == MOCK_API_KEY assert provider.model == DEFAULT_MODEL - assert provider.temperature == 0.0 + assert provider.temperature is None assert provider.max_tokens == 1000 def test_init_full_config(): @@ -96,6 +96,27 @@ def test_generate_command(mock_anthropic): assert call_kwargs["system"] == "You are a CLI assistant" assert len(call_kwargs["messages"]) == 1 assert "list files" in call_kwargs["messages"][0]["content"][0]["text"] + # Temperature must be omitted by default — newer Claude models reject it + assert "temperature" not in call_kwargs + +@patch('anthropic.Anthropic') +def test_generate_command_with_temperature(mock_anthropic): + """Test temperature is sent only when explicitly configured.""" + mock_message = Mock() + mock_message.content = [Mock(text="ls -l\n##DANGERLEVEL=0## Safe command")] + mock_client = Mock() + mock_client.messages.create.return_value = mock_message + mock_anthropic.return_value = mock_client + + provider = AnthropicProvider(MOCK_CONFIG_FULL) + provider.generate_command( + description="list files", + context={"shell": "bash"}, + system_prompt="You are a CLI assistant" + ) + + call_kwargs = mock_client.messages.create.call_args.kwargs + assert call_kwargs["temperature"] == 0.5 @patch('anthropic.Anthropic') def test_generate_command_api_error(mock_anthropic): diff --git a/abc_provider_aws_bedrock/abc_provider_aws_bedrock/__init__.py b/abc_provider_aws_bedrock/abc_provider_aws_bedrock/__init__.py index 709ccbb..9d275d6 100644 --- a/abc_provider_aws_bedrock/abc_provider_aws_bedrock/__init__.py +++ b/abc_provider_aws_bedrock/abc_provider_aws_bedrock/__init__.py @@ -2,4 +2,4 @@ from .llm_provider import AWSBedrockProvider, PROVIDER_NAME -__version__ = "2026.04.12" +__version__ = "2026.07.15" diff --git a/abc_provider_aws_bedrock/pyproject.toml b/abc_provider_aws_bedrock/pyproject.toml index 78ba751..4da342b 100644 --- a/abc_provider_aws_bedrock/pyproject.toml +++ b/abc_provider_aws_bedrock/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "abc-provider-aws-bedrock" -version = "2026.04.12" # Match current abc-cli version +version = "2026.07.15" # Match current abc-cli version description = "AWS Bedrock LLM provider plugin for abc-cli" readme = "README.md" requires-python = ">=3.8" diff --git a/abc_provider_openai/abc_provider_openai/__init__.py b/abc_provider_openai/abc_provider_openai/__init__.py index 64df117..722996a 100644 --- a/abc_provider_openai/abc_provider_openai/__init__.py +++ b/abc_provider_openai/abc_provider_openai/__init__.py @@ -6,4 +6,4 @@ from .llm_provider import OpenAIProvider __all__ = ["OpenAIProvider"] -__version__ = "2026.04.12" \ No newline at end of file +__version__ = "2026.07.15" \ No newline at end of file diff --git a/abc_provider_openai/pyproject.toml b/abc_provider_openai/pyproject.toml index b467d0c..1d2ba78 100644 --- a/abc_provider_openai/pyproject.toml +++ b/abc_provider_openai/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "abc-provider-openai" -version = "2026.04.12" +version = "2026.07.15" description = "OpenAI LLM provider for abc-cli" readme = "README.md" requires-python = ">=3.8" diff --git a/flake.nix b/flake.nix index e95e0e0..855a392 100644 --- a/flake.nix +++ b/flake.nix @@ -16,7 +16,7 @@ # Build the core abc-cli package abc-cli = python.pkgs.buildPythonApplication rec { pname = "abc-cli"; - version = "2025.09.04"; + version = "2026.07.15"; format = "pyproject"; src = ./.; @@ -55,7 +55,7 @@ # Build provider packages abc-provider-anthropic = python.pkgs.buildPythonPackage rec { pname = "abc-provider-anthropic"; - version = "2025.09.04"; + version = "2026.07.15"; format = "pyproject"; src = ./abc_provider_anthropic; @@ -74,7 +74,7 @@ abc-provider-aws-bedrock = python.pkgs.buildPythonPackage rec { pname = "abc-provider-aws-bedrock"; - version = "2025.09.04"; + version = "2026.07.15"; format = "pyproject"; src = ./abc_provider_aws_bedrock; diff --git a/pyproject.toml b/pyproject.toml index 43a9409..719b1da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "abc-cli" -version = "2026.04.12" +version = "2026.07.15" description = "AI bash/zsh/tcsh Command" readme = "README.md" requires-python = ">=3.8"