Add AI configuration file support (#911) - #985
Conversation
Add support for storing AI provider settings in ~/.scalene/config.json, addressing the need for persistent configuration across sessions. Features: - New `scalene config` CLI command with list/set/get/clear/path subcommands - Configuration priority: env vars > config file > defaults - Support for all AI providers: OpenAI, Anthropic, Gemini, Azure, AWS Bedrock, Ollama - Extended GUI to support custom models, URLs, and default provider from config New files: - scalene/scalene_ai_config.py: Core configuration module Modified files: - scalene/scalene_parseargs.py: Added config subcommand handling - scalene/scalene_utility.py: Use centralized config loading - scalene/scalene-gui/*: Extended to support additional config fields - CLAUDE.md: Updated documentation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
| display_value = value[:8] + "..." if len(value) > 8 else "***" | ||
| else: | ||
| display_value = value | ||
| print(f"{key}: {display_value} (from {source})") |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
This autofix suggestion was applied.
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix the problem, we need to ensure that sensitive configuration values (API keys, secrets) are never printed in clear text, even partially. The existing logic in _handle_config_command already distinguishes sensitive keys by checking whether "key" or "secret" appears in the key name; we can strengthen that logic so it never exposes any part of the actual value. Instead, for such keys we should always print a constant placeholder such as "***" or "(set)", regardless of the value length.
Concretely, in scalene/scalene_parseargs.py:
- In the
"list"subcommand loop (lines 980–986), change the masking for"key"/"secret"keys fromvalue[:8] + "..." if len(value) > 8 else "***"to a fixed placeholder such as"***", so no characters from the secret are shown. - In the
"get"subcommand (lines 1011–1017), similarly change the masking logic for sensitive keys to always show a fixed placeholder, never the first 8 characters of the secret. - The
"set"subcommand already prints"***"for keys containing"key"or"secret", so no change is needed there.
No new functions or imports are needed; we only adjust the string formatting logic in the two relevant branches.
| @@ -980,7 +980,8 @@ | ||
| for key, value in sorted(config.items()): | ||
| # Mask sensitive values | ||
| if "key" in key or "secret" in key: | ||
| display_value = value[:8] + "..." if len(value) > 8 else "***" | ||
| # Never reveal any part of secret values | ||
| display_value = "***" | ||
| else: | ||
| display_value = value | ||
| print(f" {key}: {display_value}") | ||
| @@ -1011,7 +1012,8 @@ | ||
| if value: | ||
| # Mask sensitive values | ||
| if "key" in key or "secret" in key: | ||
| display_value = value[:8] + "..." if len(value) > 8 else "***" | ||
| # Do not reveal any portion of secret values | ||
| display_value = "***" | ||
| else: | ||
| display_value = value | ||
| print(f"{key}: {display_value} (from {source})") |
| from scalene.scalene_ai_config import ( | ||
| VALID_CONFIG_KEYS, | ||
| clear_config, | ||
| get_all_ai_config, | ||
| get_config_file, | ||
| get_config_source, | ||
| get_config_value, | ||
| list_config, | ||
| set_config_value, | ||
| ) |
Check notice
Code scanning / CodeQL
Unused import Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 months ago
To fix an unused import, remove only the unused symbol from the import statement, keeping the rest of the imports unchanged so existing behavior is preserved.
Concretely, in scalene/scalene_parseargs.py on the from scalene.scalene_ai_config import (...) block (lines 13–22 in your snippet), delete get_all_ai_config from the parenthesized list. Do not touch the other imported names (VALID_CONFIG_KEYS, clear_config, get_config_file, get_config_source, get_config_value, list_config, set_config_value), as they may be used elsewhere in the file. No new methods, imports, or definitions are needed; we are only simplifying the existing import.
| @@ -13,7 +13,6 @@ | ||
| from scalene.scalene_ai_config import ( | ||
| VALID_CONFIG_KEYS, | ||
| clear_config, | ||
| get_all_ai_config, | ||
| get_config_file, | ||
| get_config_source, | ||
| get_config_value, |
…sensitive information Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Summary
Addresses #911 - Add configuration file support for Scalene's AI-powered optimization features.
This PR adds support for storing AI provider settings in
~/.scalene/config.json, allowing users to:Changes
New
scalene configCLI commandConfiguration Priority
Values are resolved in this order:
~/.scalene/config.json)Supported Configuration Keys
openai_api_key,anthropic_api_key,gemini_api_key,azure_api_key,aws_access_key,aws_secret_keyopenai_model,anthropic_model,gemini_model,azure_model,aws_model,ollama_modelopenai_url,anthropic_url,azure_api_url,ollama_host,ollama_portaws_region,azure_api_version,default_providerFiles Changed
scalene/scalene_ai_config.py- Core configuration modulescalene/scalene_parseargs.py- Added config subcommandscalene/scalene_utility.py- Use centralized config loadingscalene/scalene-gui/*- Extended GUI support for config fieldsCLAUDE.md- DocumentationTest plan
scalene config --helpshows usagescalene config set/get/list/clear/pathcommands work correctly~/.scalene/config.json🤖 Generated with Claude Code