Files
ha-openai-compatible/custom_components/openai_compatible/strings.json
T
Adam SmithandClaude Opus 5 9d8d1970f7 fix: drop the URL from the base_url description for hassfest
The LAN-address scrub replaced 10.10.70.133 with litellm.local in
strings.json, which broke the hassfest job that had been green:

  [ERROR] [TRANSLATIONS] Invalid strings.json: the string should not
  contain URLs, please use description placeholders instead at
  'config.step.user.data_description.base_url'

The rule is not new -- the previous text was equally a URL. It slipped
through because script/hassfest/translations.py's RE_URL requires an
alphabetic TLD ([a-z]{2,5}), so "http://10.10.70.133:4000/v1" never
matched (".133" is not alphabetic) while "http://litellm.local:4000/v1"
does. Verified by running core's actual regex against both strings, so
the scrub did not introduce a violation so much as stop hiding one.

Rather than wire up a description placeholder for what is only an
example, the description now describes the field without any URL:
concrete endpoint examples live in the README, which has no such
constraint. The reauth_confirm step picks this up automatically -- it
references the user step's strings via [%key:...%] rather than copying
them.

Also re-ran core's RE_URL over every string in strings.json, not just
the one hassfest named: 0 remaining violations, so this should not
bounce again on a second string.

Local: 138 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NxJYWgGJtCw13qUHZtG8ki
2026-09-17 22:09:29 -04:00

332 lines
16 KiB
JSON

{
"config": {
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"credentials_in_url": "The base URL must not contain a username or password. Put authentication in the API key field instead.",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"invalid_base_url": "That does not look like a valid http(s) URL.",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"step": {
"reauth_confirm": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"base_url": "[%key:component::openai_compatible::config::step::user::data::base_url%]"
},
"data_description": {
"api_key": "[%key:component::openai_compatible::config::step::user::data_description::api_key%]",
"base_url": "[%key:component::openai_compatible::config::step::user::data_description::base_url%]"
},
"description": "Reauthentication required. Please enter your updated API key and confirm the API base URL."
},
"user": {
"data": {
"api_key": "[%key:common::config_flow::data::api_key%]",
"base_url": "API base URL"
},
"data_description": {
"api_key": "Your OpenAI API key.",
"base_url": "The base URL of the OpenAI-compatible API, including any version path such as /v1. The endpoint must implement the Responses API."
},
"description": "Set up OpenAI Conversation integration by providing your OpenAI API key. Instructions to obtain an API key can be found [here]({instructions_url})."
}
}
},
"config_subentries": {
"ai_task_data": {
"abort": {
"entry_not_loaded": "[%key:component::openai_compatible::config_subentries::conversation::abort::entry_not_loaded%]",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
},
"entry_type": "AI task",
"error": {
"code_interpreter_minimal_reasoning": "[%key:component::openai_compatible::config_subentries::conversation::error::code_interpreter_minimal_reasoning%]",
"model_not_supported": "[%key:component::openai_compatible::config_subentries::conversation::error::model_not_supported%]",
"web_search_minimal_reasoning": "[%key:component::openai_compatible::config_subentries::conversation::error::web_search_minimal_reasoning%]"
},
"initiate_flow": {
"reconfigure": "Reconfigure AI task",
"user": "Add AI task"
},
"step": {
"additional": {
"data": {
"chat_model": "[%key:common::generic::model%]",
"max_tokens": "[%key:component::openai_compatible::config_subentries::conversation::step::additional::data::max_tokens%]",
"store_responses": "[%key:component::openai_compatible::config_subentries::conversation::step::additional::data::store_responses%]",
"temperature": "[%key:component::openai_compatible::config_subentries::conversation::step::additional::data::temperature%]",
"top_p": "[%key:component::openai_compatible::config_subentries::conversation::step::additional::data::top_p%]"
},
"data_description": {
"store_responses": "[%key:component::openai_compatible::config_subentries::conversation::step::additional::data_description::store_responses%]"
},
"title": "[%key:component::openai_compatible::config_subentries::conversation::step::additional::title%]"
},
"init": {
"data": {
"name": "[%key:common::config_flow::data::name%]",
"recommended": "[%key:component::openai_compatible::config_subentries::conversation::step::init::data::recommended%]"
}
},
"model": {
"data": {
"code_interpreter": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::code_interpreter%]",
"image_model": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::image_model%]",
"inline_citations": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::inline_citations%]",
"pro_mode": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::pro_mode%]",
"reasoning_effort": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::reasoning_effort%]",
"reasoning_summary": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::reasoning_summary%]",
"search_context_size": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::search_context_size%]",
"service_tier": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::service_tier%]",
"user_location": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::user_location%]",
"web_search": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data::web_search%]"
},
"data_description": {
"code_interpreter": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::code_interpreter%]",
"image_model": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::image_model%]",
"inline_citations": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::inline_citations%]",
"pro_mode": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::pro_mode%]",
"reasoning_effort": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::reasoning_effort%]",
"reasoning_summary": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::reasoning_summary%]",
"search_context_size": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::search_context_size%]",
"service_tier": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::service_tier%]",
"user_location": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::user_location%]",
"web_search": "[%key:component::openai_compatible::config_subentries::conversation::step::model::data_description::web_search%]"
},
"title": "[%key:component::openai_compatible::config_subentries::conversation::step::model::title%]"
}
}
},
"conversation": {
"abort": {
"entry_not_loaded": "Cannot add things while the configuration is disabled.",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
},
"entry_type": "Conversation agent",
"error": {
"code_interpreter_minimal_reasoning": "Code interpreter is not supported with minimal reasoning effort",
"model_not_supported": "This model is not supported, please select a different model",
"web_search_minimal_reasoning": "Web search is currently not supported with minimal reasoning effort"
},
"initiate_flow": {
"reconfigure": "Reconfigure conversation agent",
"user": "Add conversation agent"
},
"step": {
"additional": {
"data": {
"chat_model": "[%key:common::generic::model%]",
"max_tokens": "Maximum tokens to return in response",
"store_responses": "Store requests and responses in OpenAI",
"temperature": "Temperature",
"top_p": "Top P"
},
"data_description": {
"store_responses": "If enabled, requests and responses are stored by OpenAI and visible in your OpenAI dashboard logs"
},
"title": "Additional settings"
},
"init": {
"data": {
"llm_hass_api": "[%key:common::config_flow::data::llm_hass_api%]",
"name": "[%key:common::config_flow::data::name%]",
"prompt": "[%key:common::config_flow::data::prompt%]",
"recommended": "Recommended model settings"
},
"data_description": {
"prompt": "Instruct how the LLM should respond. This can be a template."
}
},
"model": {
"data": {
"code_interpreter": "Enable code interpreter tool",
"image_model": "Image generation model",
"inline_citations": "Include links in web search results",
"pro_mode": "Pro mode",
"reasoning_effort": "Reasoning effort",
"reasoning_summary": "Reasoning summary",
"search_context_size": "Search context size",
"service_tier": "Service tier",
"user_location": "Include home location",
"web_search": "Enable web search"
},
"data_description": {
"code_interpreter": "This tool, also known as the python tool to the model, allows it to run code to answer questions",
"image_model": "The model to use when generating images",
"inline_citations": "If disabled, additional prompt is added to ask the model to not include source citations",
"pro_mode": "Perform more model work to improve reliability on difficult tasks and return a single final answer",
"reasoning_effort": "How many reasoning tokens the model should generate before creating a response to the prompt",
"reasoning_summary": "Controls the length and detail of reasoning summaries provided by the model",
"search_context_size": "High level guidance for the amount of context window space to use for the search",
"service_tier": "Controls the cost and response time",
"user_location": "Refine search results based on geography",
"web_search": "Allow the model to search the web for the latest information before generating a response"
},
"title": "Model-specific options"
}
}
},
"stt": {
"abort": {
"entry_not_loaded": "[%key:component::openai_compatible::config_subentries::conversation::abort::entry_not_loaded%]",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
},
"entry_type": "Speech-to-text",
"initiate_flow": {
"reconfigure": "Reconfigure speech-to-text service",
"user": "Add speech-to-text service"
},
"step": {
"init": {
"data": {
"chat_model": "Model",
"name": "[%key:common::config_flow::data::name%]",
"prompt": "[%key:common::config_flow::data::prompt%]"
},
"data_description": {
"chat_model": "The model to use to transcribe speech.",
"prompt": "Use this prompt to improve the quality of the transcripts. Translate to the pipeline language for best results. See the documentation for more details."
}
}
}
},
"tts": {
"abort": {
"entry_not_loaded": "[%key:component::openai_compatible::config_subentries::conversation::abort::entry_not_loaded%]",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]"
},
"entry_type": "Text-to-speech",
"initiate_flow": {
"reconfigure": "Reconfigure text-to-speech service",
"user": "Add text-to-speech service"
},
"step": {
"init": {
"data": {
"name": "[%key:common::config_flow::data::name%]",
"prompt": "[%key:common::config_flow::data::prompt%]",
"tts_speed": "Speed"
},
"data_description": {
"prompt": "Control aspects of speech, including accent, emotional range, intonation, impressions, speed of speech, tone, whispering, and more",
"tts_speed": "Speed of the generated speech"
}
}
}
}
},
"exceptions": {
"invalid_config_entry": {
"message": "Invalid config entry provided. Got {config_entry}"
}
},
"issues": {
"deprecated_generate_content": {
"description": "Action 'openai_compatible.generate_content' is deprecated and will be removed in the 2026.9.0 release. Please use the 'ai_task.generate_data' action instead",
"title": "Deprecated 'generate_content' action"
},
"deprecated_generate_image": {
"description": "Action 'openai_compatible.generate_image' is deprecated and will be removed in the 2026.9.0 release. Please use the 'ai_task.generate_image' action instead",
"title": "Deprecated 'generate_image' action"
},
"organization_verification_required": {
"description": "Your organization must be verified to use this model. Please go to {platform_settings} and select Verify Organization. If you just verified, it can take up to 15 minutes for access to propagate.",
"title": "Organization verification required"
}
},
"selector": {
"reasoning_effort": {
"options": {
"high": "[%key:common::state::high%]",
"low": "[%key:common::state::low%]",
"max": "Max",
"medium": "[%key:common::state::medium%]",
"minimal": "Minimal",
"none": "None",
"xhigh": "X-High"
}
},
"reasoning_summary": {
"options": {
"auto": "[%key:common::state::auto%]",
"concise": "Concise",
"detailed": "Detailed",
"off": "[%key:common::state::off%]"
}
},
"search_context_size": {
"options": {
"high": "[%key:common::state::high%]",
"low": "[%key:common::state::low%]",
"medium": "[%key:common::state::medium%]"
}
},
"service_tier": {
"options": {
"auto": "[%key:common::state::auto%]",
"default": "Standard",
"flex": "Flex",
"priority": "Priority"
}
},
"verbosity": {
"options": {
"high": "[%key:common::state::high%]",
"low": "[%key:common::state::low%]",
"medium": "[%key:common::state::medium%]"
}
}
},
"services": {
"generate_content": {
"description": "Sends a conversational query to ChatGPT including any attached image or PDF files (deprecated)",
"fields": {
"config_entry": {
"description": "The config entry to use for this action",
"name": "Config entry"
},
"filenames": {
"description": "List of files to upload",
"name": "Files"
},
"prompt": {
"description": "The prompt to send",
"name": "Prompt"
}
},
"name": "Generate content (deprecated)"
},
"generate_image": {
"description": "Turns a prompt into an image (deprecated)",
"fields": {
"config_entry": {
"description": "The config entry to use for this action",
"name": "Config entry"
},
"prompt": {
"description": "The text to turn into an image",
"example": "A photo of a dog",
"name": "Prompt"
},
"quality": {
"description": "The quality of the image that will be generated",
"name": "Quality"
},
"size": {
"description": "The size of the image to generate",
"name": "Size"
},
"style": {
"description": "The style of the generated image",
"name": "Style"
}
},
"name": "Generate image (deprecated)"
}
}
}