diff --git a/docs/docs/providers/datasetio/remote_nvidia.mdx b/docs/docs/providers/datasetio/remote_nvidia.mdx index ba5522fce..9ffd72a58 100644 --- a/docs/docs/providers/datasetio/remote_nvidia.mdx +++ b/docs/docs/providers/datasetio/remote_nvidia.mdx @@ -14,7 +14,7 @@ NVIDIA's dataset I/O provider for accessing datasets from NVIDIA's data platform | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | The NVIDIA API key. | +| `api_key` | `` | No | | The NVIDIA API key. | | `dataset_namespace` | `str \| None` | No | default | The NVIDIA dataset namespace. | | `project_id` | `str \| None` | No | test-project | The NVIDIA project ID. | | `datasets_url` | `` | No | http://nemo.test | Base URL for the NeMo Dataset API | diff --git a/docs/docs/providers/files/remote_s3.mdx b/docs/docs/providers/files/remote_s3.mdx index 9de31df44..adf4bced0 100644 --- a/docs/docs/providers/files/remote_s3.mdx +++ b/docs/docs/providers/files/remote_s3.mdx @@ -17,7 +17,7 @@ AWS S3-based file storage provider for scalable cloud file management with metad | `bucket_name` | `` | No | | S3 bucket name to store files | | `region` | `` | No | us-east-1 | AWS region where the bucket is located | | `aws_access_key_id` | `str \| None` | No | | AWS access key ID (optional if using IAM roles) | -| `aws_secret_access_key` | `` | No | | AWS secret access key (optional if using IAM roles) | +| `aws_secret_access_key` | `` | No | | AWS secret access key (optional if using IAM roles) | | `endpoint_url` | `str \| None` | No | | Custom S3 endpoint URL (for MinIO, LocalStack, etc.) | | `auto_create_bucket` | `` | No | False | Automatically create the S3 bucket if it doesn't exist | | `metadata_store` | `utils.sqlstore.sqlstore.SqliteSqlStoreConfig \| utils.sqlstore.sqlstore.PostgresSqlStoreConfig` | No | sqlite | SQL store configuration for file metadata | diff --git a/docs/docs/providers/inference/remote_anthropic.mdx b/docs/docs/providers/inference/remote_anthropic.mdx index 72deb298c..f795ad3f1 100644 --- a/docs/docs/providers/inference/remote_anthropic.mdx +++ b/docs/docs/providers/inference/remote_anthropic.mdx @@ -14,7 +14,7 @@ Anthropic inference provider for accessing Claude models and Anthropic's AI serv | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | API key for Anthropic models | +| `api_key` | `` | No | | API key for Anthropic models | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_azure.mdx b/docs/docs/providers/inference/remote_azure.mdx index 1085e4ad4..0eb0ea755 100644 --- a/docs/docs/providers/inference/remote_azure.mdx +++ b/docs/docs/providers/inference/remote_azure.mdx @@ -21,7 +21,7 @@ https://learn.microsoft.com/en-us/azure/ai-foundry/openai/overview | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | Azure API key for Azure | +| `api_key` | `` | No | | Azure API key for Azure | | `api_base` | `` | No | | Azure API base for Azure (e.g., https://your-resource-name.openai.azure.com) | | `api_version` | `str \| None` | No | | Azure API version for Azure (e.g., 2024-12-01-preview) | | `api_type` | `str \| None` | No | azure | Azure API type for Azure (e.g., azure) | diff --git a/docs/docs/providers/inference/remote_bedrock.mdx b/docs/docs/providers/inference/remote_bedrock.mdx index 627be48e5..ff1ed5ad8 100644 --- a/docs/docs/providers/inference/remote_bedrock.mdx +++ b/docs/docs/providers/inference/remote_bedrock.mdx @@ -15,8 +15,8 @@ AWS Bedrock inference provider for accessing various AI models through AWS's man | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `aws_access_key_id` | `str \| None` | No | | The AWS access key to use. Default use environment variable: AWS_ACCESS_KEY_ID | -| `aws_secret_access_key` | `` | No | | The AWS secret access key to use. Default use environment variable: AWS_SECRET_ACCESS_KEY | -| `aws_session_token` | `` | No | | The AWS session token to use. Default use environment variable: AWS_SESSION_TOKEN | +| `aws_secret_access_key` | `` | No | | The AWS secret access key to use. Default use environment variable: AWS_SECRET_ACCESS_KEY | +| `aws_session_token` | `` | No | | The AWS session token to use. Default use environment variable: AWS_SESSION_TOKEN | | `region_name` | `str \| None` | No | | The default AWS Region to use, for example, us-west-1 or us-west-2.Default use environment variable: AWS_DEFAULT_REGION | | `profile_name` | `str \| None` | No | | The profile name that contains credentials to use.Default use environment variable: AWS_PROFILE | | `total_max_attempts` | `int \| None` | No | | An integer representing the maximum number of attempts that will be made for a single request, including the initial attempt. Default use environment variable: AWS_MAX_ATTEMPTS | diff --git a/docs/docs/providers/inference/remote_cerebras.mdx b/docs/docs/providers/inference/remote_cerebras.mdx index 7c96e5115..d9cc93aef 100644 --- a/docs/docs/providers/inference/remote_cerebras.mdx +++ b/docs/docs/providers/inference/remote_cerebras.mdx @@ -15,7 +15,7 @@ Cerebras inference provider for running models on Cerebras Cloud platform. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `base_url` | `` | No | https://api.cerebras.ai | Base URL for the Cerebras API | -| `api_key` | `` | No | | Cerebras API Key | +| `api_key` | `` | No | | Cerebras API Key | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_databricks.mdx b/docs/docs/providers/inference/remote_databricks.mdx index fb3783720..7f736db9d 100644 --- a/docs/docs/providers/inference/remote_databricks.mdx +++ b/docs/docs/providers/inference/remote_databricks.mdx @@ -15,7 +15,7 @@ Databricks inference provider for running models on Databricks' unified analytic | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `url` | `` | No | | The URL for the Databricks model serving endpoint | -| `api_token` | `` | No | | The Databricks API token | +| `api_token` | `` | No | | The Databricks API token | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_fireworks.mdx b/docs/docs/providers/inference/remote_fireworks.mdx index 73698f28c..0f37ccbc2 100644 --- a/docs/docs/providers/inference/remote_fireworks.mdx +++ b/docs/docs/providers/inference/remote_fireworks.mdx @@ -16,7 +16,7 @@ Fireworks AI inference provider for Llama models and other AI models on the Fire |-------|------|----------|---------|-------------| | `allowed_models` | `list[str \| None` | No | | List of models that should be registered with the model registry. If None, all models are allowed. | | `url` | `` | No | https://api.fireworks.ai/inference/v1 | The URL for the Fireworks server | -| `api_key` | `` | No | | The Fireworks.ai API Key | +| `api_key` | `` | No | | The Fireworks.ai API Key | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_gemini.mdx b/docs/docs/providers/inference/remote_gemini.mdx index 538a9f29b..d9a2f3e8d 100644 --- a/docs/docs/providers/inference/remote_gemini.mdx +++ b/docs/docs/providers/inference/remote_gemini.mdx @@ -14,7 +14,7 @@ Google Gemini inference provider for accessing Gemini models and Google's AI ser | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | API key for Gemini models | +| `api_key` | `` | No | | API key for Gemini models | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_groq.mdx b/docs/docs/providers/inference/remote_groq.mdx index 2f80ab7ca..b6d29496e 100644 --- a/docs/docs/providers/inference/remote_groq.mdx +++ b/docs/docs/providers/inference/remote_groq.mdx @@ -14,7 +14,7 @@ Groq inference provider for ultra-fast inference using Groq's LPU technology. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | The Groq API key | +| `api_key` | `` | No | | The Groq API key | | `url` | `` | No | https://api.groq.com | The URL for the Groq AI server | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_hf_endpoint.mdx b/docs/docs/providers/inference/remote_hf_endpoint.mdx index 93468fdbc..d036c17d7 100644 --- a/docs/docs/providers/inference/remote_hf_endpoint.mdx +++ b/docs/docs/providers/inference/remote_hf_endpoint.mdx @@ -15,7 +15,7 @@ HuggingFace Inference Endpoints provider for dedicated model serving. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `endpoint_name` | `` | No | | The name of the Hugging Face Inference Endpoint in the format of '{namespace}/{endpoint_name}' (e.g. 'my-cool-org/meta-llama-3-1-8b-instruct-rce'). Namespace is optional and will default to the user account if not provided. | -| `api_token` | `` | No | | Your Hugging Face user access token (will default to locally saved token if not provided) | +| `api_token` | `` | No | | Your Hugging Face user access token (will default to locally saved token if not provided) | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_hf_serverless.mdx b/docs/docs/providers/inference/remote_hf_serverless.mdx index 80753ed05..1a3c17715 100644 --- a/docs/docs/providers/inference/remote_hf_serverless.mdx +++ b/docs/docs/providers/inference/remote_hf_serverless.mdx @@ -15,7 +15,7 @@ HuggingFace Inference API serverless provider for on-demand model inference. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `huggingface_repo` | `` | No | | The model ID of the model on the Hugging Face Hub (e.g. 'meta-llama/Meta-Llama-3.1-70B-Instruct') | -| `api_token` | `` | No | | Your Hugging Face user access token (will default to locally saved token if not provided) | +| `api_token` | `` | No | | Your Hugging Face user access token (will default to locally saved token if not provided) | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_llama-openai-compat.mdx b/docs/docs/providers/inference/remote_llama-openai-compat.mdx index 478b7dadb..491774844 100644 --- a/docs/docs/providers/inference/remote_llama-openai-compat.mdx +++ b/docs/docs/providers/inference/remote_llama-openai-compat.mdx @@ -14,7 +14,7 @@ Llama OpenAI-compatible provider for using Llama models with OpenAI API format. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | The Llama API key | +| `api_key` | `` | No | | The Llama API key | | `openai_compat_api_base` | `` | No | https://api.llama.com/compat/v1/ | The URL for the Llama API server | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_nvidia.mdx b/docs/docs/providers/inference/remote_nvidia.mdx index c51da9547..9aee22e9a 100644 --- a/docs/docs/providers/inference/remote_nvidia.mdx +++ b/docs/docs/providers/inference/remote_nvidia.mdx @@ -15,7 +15,7 @@ NVIDIA inference provider for accessing NVIDIA NIM models and AI services. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `url` | `` | No | https://integrate.api.nvidia.com | A base url for accessing the NVIDIA NIM | -| `api_key` | `` | No | | The NVIDIA API key, only needed of using the hosted service | +| `api_key` | `` | No | | The NVIDIA API key, only needed of using the hosted service | | `timeout` | `` | No | 60 | Timeout for the HTTP requests | | `append_api_version` | `` | No | True | When set to false, the API version will not be appended to the base_url. By default, it is true. | diff --git a/docs/docs/providers/inference/remote_openai.mdx b/docs/docs/providers/inference/remote_openai.mdx index 79e9d9ccc..f82bea154 100644 --- a/docs/docs/providers/inference/remote_openai.mdx +++ b/docs/docs/providers/inference/remote_openai.mdx @@ -14,7 +14,7 @@ OpenAI inference provider for accessing GPT models and other OpenAI services. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | API key for OpenAI models | +| `api_key` | `` | No | | API key for OpenAI models | | `base_url` | `` | No | https://api.openai.com/v1 | Base URL for OpenAI API | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_passthrough.mdx b/docs/docs/providers/inference/remote_passthrough.mdx index f35f746db..efaa01d04 100644 --- a/docs/docs/providers/inference/remote_passthrough.mdx +++ b/docs/docs/providers/inference/remote_passthrough.mdx @@ -15,7 +15,7 @@ Passthrough inference provider for connecting to any external inference service | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `url` | `` | No | | The URL for the passthrough endpoint | -| `api_key` | `` | No | | API Key for the passthrouth endpoint | +| `api_key` | `` | No | | API Key for the passthrouth endpoint | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_runpod.mdx b/docs/docs/providers/inference/remote_runpod.mdx index 8028f0228..1def462f6 100644 --- a/docs/docs/providers/inference/remote_runpod.mdx +++ b/docs/docs/providers/inference/remote_runpod.mdx @@ -15,7 +15,7 @@ RunPod inference provider for running models on RunPod's cloud GPU platform. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `url` | `str \| None` | No | | The URL for the Runpod model serving endpoint | -| `api_token` | `` | No | | The API token | +| `api_token` | `` | No | | The API token | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_sambanova.mdx b/docs/docs/providers/inference/remote_sambanova.mdx index 2a63cab16..b5d64e6d9 100644 --- a/docs/docs/providers/inference/remote_sambanova.mdx +++ b/docs/docs/providers/inference/remote_sambanova.mdx @@ -15,7 +15,7 @@ SambaNova inference provider for running models on SambaNova's dataflow architec | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `url` | `` | No | https://api.sambanova.ai/v1 | The URL for the SambaNova AI server | -| `api_key` | `` | No | | The SambaNova cloud API Key | +| `api_key` | `` | No | | The SambaNova cloud API Key | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_together.mdx b/docs/docs/providers/inference/remote_together.mdx index 912cf0291..0669a1112 100644 --- a/docs/docs/providers/inference/remote_together.mdx +++ b/docs/docs/providers/inference/remote_together.mdx @@ -16,7 +16,7 @@ Together AI inference provider for open-source models and collaborative AI devel |-------|------|----------|---------|-------------| | `allowed_models` | `list[str \| None` | No | | List of models that should be registered with the model registry. If None, all models are allowed. | | `url` | `` | No | https://api.together.xyz/v1 | The URL for the Together AI server | -| `api_key` | `` | No | | The Together AI API Key | +| `api_key` | `` | No | | The Together AI API Key | ## Sample Configuration diff --git a/docs/docs/providers/inference/remote_vllm.mdx b/docs/docs/providers/inference/remote_vllm.mdx index 4db289376..ed317806a 100644 --- a/docs/docs/providers/inference/remote_vllm.mdx +++ b/docs/docs/providers/inference/remote_vllm.mdx @@ -16,7 +16,7 @@ Remote vLLM inference provider for connecting to vLLM servers. |-------|------|----------|---------|-------------| | `url` | `str \| None` | No | | The URL for the vLLM model serving endpoint | | `max_tokens` | `` | No | 4096 | Maximum number of tokens to generate. | -| `api_token` | `` | No | | The API token | +| `api_token` | `` | No | ********** | The API token | | `tls_verify` | `bool \| str` | No | True | Whether to verify TLS certificates. Can be a boolean or a path to a CA certificate file. | | `refresh_models` | `` | No | False | Whether to refresh models periodically | diff --git a/docs/docs/providers/inference/remote_watsonx.mdx b/docs/docs/providers/inference/remote_watsonx.mdx index 2584a78ac..c1ab57a7b 100644 --- a/docs/docs/providers/inference/remote_watsonx.mdx +++ b/docs/docs/providers/inference/remote_watsonx.mdx @@ -15,7 +15,7 @@ IBM WatsonX inference provider for accessing AI models on IBM's WatsonX platform | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `url` | `` | No | https://us-south.ml.cloud.ibm.com | A base url for accessing the watsonx.ai | -| `api_key` | `` | No | | The watsonx API key | +| `api_key` | `` | No | | The watsonx API key | | `project_id` | `str \| None` | No | | The Project ID key | | `timeout` | `` | No | 60 | Timeout for the HTTP requests | diff --git a/docs/docs/providers/post_training/remote_nvidia.mdx b/docs/docs/providers/post_training/remote_nvidia.mdx index 451b1b258..64951b0be 100644 --- a/docs/docs/providers/post_training/remote_nvidia.mdx +++ b/docs/docs/providers/post_training/remote_nvidia.mdx @@ -14,7 +14,7 @@ NVIDIA's post-training provider for fine-tuning models on NVIDIA's platform. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | The NVIDIA API key. | +| `api_key` | `` | No | | The NVIDIA API key. | | `dataset_namespace` | `str \| None` | No | default | The NVIDIA dataset namespace. | | `project_id` | `str \| None` | No | test-example-model@v1 | The NVIDIA project ID. | | `customizer_url` | `str \| None` | No | | Base URL for the NeMo Customizer API | diff --git a/docs/docs/providers/safety/remote_bedrock.mdx b/docs/docs/providers/safety/remote_bedrock.mdx index d5362ccd9..e068f1fed 100644 --- a/docs/docs/providers/safety/remote_bedrock.mdx +++ b/docs/docs/providers/safety/remote_bedrock.mdx @@ -15,8 +15,8 @@ AWS Bedrock safety provider for content moderation using AWS's safety services. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `aws_access_key_id` | `str \| None` | No | | The AWS access key to use. Default use environment variable: AWS_ACCESS_KEY_ID | -| `aws_secret_access_key` | `` | No | | The AWS secret access key to use. Default use environment variable: AWS_SECRET_ACCESS_KEY | -| `aws_session_token` | `` | No | | The AWS session token to use. Default use environment variable: AWS_SESSION_TOKEN | +| `aws_secret_access_key` | `` | No | | The AWS secret access key to use. Default use environment variable: AWS_SECRET_ACCESS_KEY | +| `aws_session_token` | `` | No | | The AWS session token to use. Default use environment variable: AWS_SESSION_TOKEN | | `region_name` | `str \| None` | No | | The default AWS Region to use, for example, us-west-1 or us-west-2.Default use environment variable: AWS_DEFAULT_REGION | | `profile_name` | `str \| None` | No | | The profile name that contains credentials to use.Default use environment variable: AWS_PROFILE | | `total_max_attempts` | `int \| None` | No | | An integer representing the maximum number of attempts that will be made for a single request, including the initial attempt. Default use environment variable: AWS_MAX_ATTEMPTS | diff --git a/docs/docs/providers/safety/remote_sambanova.mdx b/docs/docs/providers/safety/remote_sambanova.mdx index c63e2160c..3a5a0db7d 100644 --- a/docs/docs/providers/safety/remote_sambanova.mdx +++ b/docs/docs/providers/safety/remote_sambanova.mdx @@ -15,7 +15,7 @@ SambaNova's safety provider for content moderation and safety filtering. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `url` | `` | No | https://api.sambanova.ai/v1 | The URL for the SambaNova AI server | -| `api_key` | `` | No | | The SambaNova cloud API Key | +| `api_key` | `` | No | | The SambaNova cloud API Key | ## Sample Configuration diff --git a/docs/docs/providers/scoring/inline_braintrust.mdx b/docs/docs/providers/scoring/inline_braintrust.mdx index b035c259a..93779b7ac 100644 --- a/docs/docs/providers/scoring/inline_braintrust.mdx +++ b/docs/docs/providers/scoring/inline_braintrust.mdx @@ -14,7 +14,7 @@ Braintrust scoring provider for evaluation and scoring using the Braintrust plat | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `openai_api_key` | `` | No | | The OpenAI API Key | +| `openai_api_key` | `` | No | | The OpenAI API Key | ## Sample Configuration diff --git a/docs/docs/providers/tool_runtime/remote_bing-search.mdx b/docs/docs/providers/tool_runtime/remote_bing-search.mdx index 02ed6af2c..b7dabdd47 100644 --- a/docs/docs/providers/tool_runtime/remote_bing-search.mdx +++ b/docs/docs/providers/tool_runtime/remote_bing-search.mdx @@ -14,7 +14,7 @@ Bing Search tool for web search capabilities using Microsoft's search engine. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | The Bing API key | +| `api_key` | `` | No | | The Bing API key | | `top_k` | `` | No | 3 | | ## Sample Configuration diff --git a/docs/docs/providers/tool_runtime/remote_brave-search.mdx b/docs/docs/providers/tool_runtime/remote_brave-search.mdx index ccb7f3e23..084ae20f5 100644 --- a/docs/docs/providers/tool_runtime/remote_brave-search.mdx +++ b/docs/docs/providers/tool_runtime/remote_brave-search.mdx @@ -14,7 +14,7 @@ Brave Search tool for web search capabilities with privacy-focused results. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | The Brave Search API Key | +| `api_key` | `` | No | | The Brave Search API Key | | `max_results` | `` | No | 3 | The maximum number of results to return | ## Sample Configuration diff --git a/docs/docs/providers/tool_runtime/remote_tavily-search.mdx b/docs/docs/providers/tool_runtime/remote_tavily-search.mdx index 7947c42c8..1c3429983 100644 --- a/docs/docs/providers/tool_runtime/remote_tavily-search.mdx +++ b/docs/docs/providers/tool_runtime/remote_tavily-search.mdx @@ -14,7 +14,7 @@ Tavily Search tool for AI-optimized web search with structured results. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | The Tavily Search API Key | +| `api_key` | `` | No | | The Tavily Search API Key | | `max_results` | `` | No | 3 | The maximum number of results to return | ## Sample Configuration diff --git a/docs/docs/providers/tool_runtime/remote_wolfram-alpha.mdx b/docs/docs/providers/tool_runtime/remote_wolfram-alpha.mdx index 2dd58f043..312d34c8a 100644 --- a/docs/docs/providers/tool_runtime/remote_wolfram-alpha.mdx +++ b/docs/docs/providers/tool_runtime/remote_wolfram-alpha.mdx @@ -14,7 +14,7 @@ Wolfram Alpha tool for computational knowledge and mathematical calculations. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `api_key` | `` | No | | The WolframAlpha API Key | +| `api_key` | `` | No | | The WolframAlpha API Key | ## Sample Configuration diff --git a/docs/docs/providers/vector_io/remote_milvus.mdx b/docs/docs/providers/vector_io/remote_milvus.mdx index 7f7c08122..b69e729fe 100644 --- a/docs/docs/providers/vector_io/remote_milvus.mdx +++ b/docs/docs/providers/vector_io/remote_milvus.mdx @@ -406,7 +406,7 @@ For more details on TLS configuration, refer to the [TLS setup guide](https://mi | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `uri` | `` | No | | The URI of the Milvus server | -| `token` | `str \| None` | No | | The token of the Milvus server | +| `token` | `` | No | | The token of the Milvus server | | `consistency_level` | `` | No | Strong | The consistency level of the Milvus server | | `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | Config for KV store backend | | `config` | `dict` | No | `{}` | This configuration allows additional fields to be passed through to the underlying Milvus client. See the [Milvus](https://milvus.io/docs/install-overview.md) documentation for more details about Milvus in general. | diff --git a/docs/docs/providers/vector_io/remote_pgvector.mdx b/docs/docs/providers/vector_io/remote_pgvector.mdx index 2853cddeb..6d3157753 100644 --- a/docs/docs/providers/vector_io/remote_pgvector.mdx +++ b/docs/docs/providers/vector_io/remote_pgvector.mdx @@ -217,7 +217,7 @@ See [PGVector's documentation](https://github.com/pgvector/pgvector) for more de | `port` | `int \| None` | No | 5432 | | | `db` | `str \| None` | No | postgres | | | `user` | `str \| None` | No | postgres | | -| `password` | `` | No | ********** | | +| `password` | `` | No | ********** | | | `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig, annotation=NoneType, required=False, default='sqlite', discriminator='type'` | No | | Config for KV store backend (SQLite only for now) | ## Sample Configuration diff --git a/docs/docs/providers/vector_io/remote_qdrant.mdx b/docs/docs/providers/vector_io/remote_qdrant.mdx index c344dfe2e..330bfce2e 100644 --- a/docs/docs/providers/vector_io/remote_qdrant.mdx +++ b/docs/docs/providers/vector_io/remote_qdrant.mdx @@ -22,7 +22,7 @@ Please refer to the inline provider documentation. | `grpc_port` | `` | No | 6334 | | | `prefer_grpc` | `` | No | False | | | `https` | `bool \| None` | No | | | -| `api_key` | `` | No | | The API key for the Qdrant instance | +| `api_key` | `` | No | | The API key for the Qdrant instance | | `prefix` | `str \| None` | No | | | | `timeout` | `int \| None` | No | | | | `host` | `str \| None` | No | | | diff --git a/llama_stack/core/secret_types.py b/llama_stack/core/secret_types.py deleted file mode 100644 index e1700d783..000000000 --- a/llama_stack/core/secret_types.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under the terms described in the LICENSE file in -# the root directory of this source tree. - -from pydantic.types import SecretStr - - -class MySecretStr(SecretStr): - """A SecretStr that can accept None values to avoid mypy type errors. - - This is useful for optional secret fields where you want to avoid - explicit None checks in consuming code. - - We chose to not use the SecretStr from pydantic because it does not allow None values and will - let the provider's library fail if the secret is not provided. - """ - - def __init__(self, secret_value: str | None = None) -> None: - SecretStr.__init__(self, secret_value) # type: ignore[arg-type] diff --git a/llama_stack/core/stack.py b/llama_stack/core/stack.py index 3b93f9913..9c147eebd 100644 --- a/llama_stack/core/stack.py +++ b/llama_stack/core/stack.py @@ -288,6 +288,12 @@ def _convert_string_to_proper_type_with_config(value: str, path: str, provider_c field_name = path.split(".")[-1] if "." in path else path config_class = provider_context["config_class"] + # Only instantiate if the class hasn't been instantiated already + # This handles the case we entered replace_env_vars() with a dict, which + # could happen if we use a sample_run_config() method that returns a dict. Our unit tests do + # this on the adhoc config spec creation. + if isinstance(config_class, str): + config_class = instantiate_class_type(config_class) if hasattr(config_class, "model_fields") and field_name in config_class.model_fields: field_info = config_class.model_fields[field_name] @@ -563,7 +569,9 @@ def run_config_from_adhoc_config_spec( # call method "sample_run_config" on the provider spec config class provider_config_type = instantiate_class_type(provider_spec.config_class) provider_config = replace_env_vars( - provider_config_type.sample_run_config(__distro_dir__=distro_dir), provider_registry=provider_registry + provider_config_type.sample_run_config(__distro_dir__=distro_dir), + provider_registry=provider_registry, + current_provider_context=provider_spec.model_dump(), ) provider_configs_by_api[api_str] = [ diff --git a/llama_stack/providers/inline/scoring/braintrust/__init__.py b/llama_stack/providers/inline/scoring/braintrust/__init__.py index 77c09c615..2f3dce966 100644 --- a/llama_stack/providers/inline/scoring/braintrust/__init__.py +++ b/llama_stack/providers/inline/scoring/braintrust/__init__.py @@ -5,16 +5,15 @@ # the root directory of this source tree. from typing import Any -from pydantic import BaseModel +from pydantic import BaseModel, SecretStr from llama_stack.core.datatypes import Api -from llama_stack.core.secret_types import MySecretStr from .config import BraintrustScoringConfig class BraintrustProviderDataValidator(BaseModel): - openai_api_key: MySecretStr + openai_api_key: SecretStr async def get_provider_impl( diff --git a/llama_stack/providers/inline/scoring/braintrust/braintrust.py b/llama_stack/providers/inline/scoring/braintrust/braintrust.py index 8d80b5920..7f2b1e205 100644 --- a/llama_stack/providers/inline/scoring/braintrust/braintrust.py +++ b/llama_stack/providers/inline/scoring/braintrust/braintrust.py @@ -17,7 +17,7 @@ from autoevals.ragas import ( ContextRelevancy, Faithfulness, ) -from pydantic import BaseModel +from pydantic import BaseModel, SecretStr from llama_stack.apis.datasetio import DatasetIO from llama_stack.apis.datasets import Datasets @@ -31,7 +31,6 @@ from llama_stack.apis.scoring import ( from llama_stack.apis.scoring_functions import ScoringFn, ScoringFnParams from llama_stack.core.datatypes import Api from llama_stack.core.request_headers import NeedsRequestProviderData -from llama_stack.core.secret_types import MySecretStr from llama_stack.providers.datatypes import ScoringFunctionsProtocolPrivate from llama_stack.providers.utils.common.data_schema_validator import ( get_valid_schemas, @@ -153,7 +152,7 @@ class BraintrustScoringImpl( raise ValueError( 'Pass OpenAI API Key in the header X-LlamaStack-Provider-Data as { "openai_api_key": }' ) - self.config.openai_api_key = MySecretStr(provider_data.openai_api_key) + self.config.openai_api_key = SecretStr(provider_data.openai_api_key) os.environ["OPENAI_API_KEY"] = self.config.openai_api_key.get_secret_value() diff --git a/llama_stack/providers/inline/scoring/braintrust/config.py b/llama_stack/providers/inline/scoring/braintrust/config.py index 3520ffb08..a3fb937f6 100644 --- a/llama_stack/providers/inline/scoring/braintrust/config.py +++ b/llama_stack/providers/inline/scoring/braintrust/config.py @@ -5,13 +5,11 @@ # the root directory of this source tree. from typing import Any -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr class BraintrustScoringConfig(BaseModel): - openai_api_key: MySecretStr = Field( + openai_api_key: SecretStr = Field( description="The OpenAI API Key", ) diff --git a/llama_stack/providers/remote/datasetio/nvidia/config.py b/llama_stack/providers/remote/datasetio/nvidia/config.py index aa1ac163d..03a51f59b 100644 --- a/llama_stack/providers/remote/datasetio/nvidia/config.py +++ b/llama_stack/providers/remote/datasetio/nvidia/config.py @@ -8,16 +8,14 @@ import os import warnings from typing import Any -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr class NvidiaDatasetIOConfig(BaseModel): """Configuration for NVIDIA DatasetIO implementation.""" - api_key: MySecretStr = Field( - default_factory=lambda: MySecretStr(os.getenv("NVIDIA_API_KEY", "")), + api_key: SecretStr = Field( + default_factory=lambda: SecretStr(os.getenv("NVIDIA_API_KEY", "")), description="The NVIDIA API key.", ) diff --git a/llama_stack/providers/remote/files/s3/config.py b/llama_stack/providers/remote/files/s3/config.py index e8fc452d8..83bec65d8 100644 --- a/llama_stack/providers/remote/files/s3/config.py +++ b/llama_stack/providers/remote/files/s3/config.py @@ -6,9 +6,8 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig, SqlStoreConfig @@ -18,7 +17,7 @@ class S3FilesImplConfig(BaseModel): bucket_name: str = Field(description="S3 bucket name to store files") region: str = Field(default="us-east-1", description="AWS region where the bucket is located") aws_access_key_id: str | None = Field(default=None, description="AWS access key ID (optional if using IAM roles)") - aws_secret_access_key: MySecretStr = Field(description="AWS secret access key (optional if using IAM roles)") + aws_secret_access_key: SecretStr = Field(description="AWS secret access key (optional if using IAM roles)") endpoint_url: str | None = Field(default=None, description="Custom S3 endpoint URL (for MinIO, LocalStack, etc.)") auto_create_bucket: bool = Field( default=False, description="Automatically create the S3 bucket if it doesn't exist" diff --git a/llama_stack/providers/remote/inference/anthropic/anthropic.py b/llama_stack/providers/remote/inference/anthropic/anthropic.py index 41f65ade7..6d769879e 100644 --- a/llama_stack/providers/remote/inference/anthropic/anthropic.py +++ b/llama_stack/providers/remote/inference/anthropic/anthropic.py @@ -28,7 +28,7 @@ class AnthropicInferenceAdapter(OpenAIMixin, LiteLLMOpenAIMixin): LiteLLMOpenAIMixin.__init__( self, litellm_provider_name="anthropic", - api_key_from_config=config.api_key.get_secret_value() if config.api_key else None, + api_key_from_config=config.api_key, provider_data_api_key_field="anthropic_api_key", ) self.config = config diff --git a/llama_stack/providers/remote/inference/anthropic/config.py b/llama_stack/providers/remote/inference/anthropic/config.py index eb77b328f..25b2dbbcf 100644 --- a/llama_stack/providers/remote/inference/anthropic/config.py +++ b/llama_stack/providers/remote/inference/anthropic/config.py @@ -6,21 +6,20 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type class AnthropicProviderDataValidator(BaseModel): - anthropic_api_key: MySecretStr = Field( + anthropic_api_key: SecretStr = Field( description="API key for Anthropic models", ) @json_schema_type class AnthropicConfig(BaseModel): - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="API key for Anthropic models", ) diff --git a/llama_stack/providers/remote/inference/azure/config.py b/llama_stack/providers/remote/inference/azure/config.py index ab53e85c2..fe9d61d53 100644 --- a/llama_stack/providers/remote/inference/azure/config.py +++ b/llama_stack/providers/remote/inference/azure/config.py @@ -7,14 +7,13 @@ import os from typing import Any -from pydantic import BaseModel, Field, HttpUrl +from pydantic import BaseModel, Field, HttpUrl, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type class AzureProviderDataValidator(BaseModel): - azure_api_key: MySecretStr = Field( + azure_api_key: SecretStr = Field( description="Azure API key for Azure", ) azure_api_base: HttpUrl = Field( @@ -32,7 +31,7 @@ class AzureProviderDataValidator(BaseModel): @json_schema_type class AzureConfig(BaseModel): - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="Azure API key for Azure", ) api_base: HttpUrl = Field( diff --git a/llama_stack/providers/remote/inference/cerebras/config.py b/llama_stack/providers/remote/inference/cerebras/config.py index 5c5de27a5..519bd9119 100644 --- a/llama_stack/providers/remote/inference/cerebras/config.py +++ b/llama_stack/providers/remote/inference/cerebras/config.py @@ -7,9 +7,8 @@ import os from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type DEFAULT_BASE_URL = "https://api.cerebras.ai" @@ -21,8 +20,8 @@ class CerebrasImplConfig(BaseModel): default=os.environ.get("CEREBRAS_BASE_URL", DEFAULT_BASE_URL), description="Base URL for the Cerebras API", ) - api_key: MySecretStr = Field( - default=MySecretStr(os.environ.get("CEREBRAS_API_KEY")), + api_key: SecretStr = Field( + default=SecretStr(os.environ.get("CEREBRAS_API_KEY")), description="Cerebras API Key", ) diff --git a/llama_stack/providers/remote/inference/databricks/config.py b/llama_stack/providers/remote/inference/databricks/config.py index 92b250034..2e2b0ff11 100644 --- a/llama_stack/providers/remote/inference/databricks/config.py +++ b/llama_stack/providers/remote/inference/databricks/config.py @@ -6,9 +6,8 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type @@ -18,7 +17,7 @@ class DatabricksImplConfig(BaseModel): default=None, description="The URL for the Databricks model serving endpoint", ) - api_token: MySecretStr = Field( + api_token: SecretStr = Field( description="The Databricks API token", ) diff --git a/llama_stack/providers/remote/inference/fireworks/config.py b/llama_stack/providers/remote/inference/fireworks/config.py index 14f2dffc1..c0f5d11d1 100644 --- a/llama_stack/providers/remote/inference/fireworks/config.py +++ b/llama_stack/providers/remote/inference/fireworks/config.py @@ -6,9 +6,8 @@ from typing import Any -from pydantic import Field +from pydantic import Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.providers.utils.inference.model_registry import RemoteInferenceProviderConfig from llama_stack.schema_utils import json_schema_type @@ -19,7 +18,7 @@ class FireworksImplConfig(RemoteInferenceProviderConfig): default="https://api.fireworks.ai/inference/v1", description="The URL for the Fireworks server", ) - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The Fireworks.ai API Key", ) diff --git a/llama_stack/providers/remote/inference/gemini/config.py b/llama_stack/providers/remote/inference/gemini/config.py index a90fb93cb..ddb3aee8a 100644 --- a/llama_stack/providers/remote/inference/gemini/config.py +++ b/llama_stack/providers/remote/inference/gemini/config.py @@ -6,21 +6,20 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type class GeminiProviderDataValidator(BaseModel): - gemini_api_key: MySecretStr = Field( + gemini_api_key: SecretStr = Field( description="API key for Gemini models", ) @json_schema_type class GeminiConfig(BaseModel): - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="API key for Gemini models", ) diff --git a/llama_stack/providers/remote/inference/gemini/gemini.py b/llama_stack/providers/remote/inference/gemini/gemini.py index b02d0d611..673811d8c 100644 --- a/llama_stack/providers/remote/inference/gemini/gemini.py +++ b/llama_stack/providers/remote/inference/gemini/gemini.py @@ -20,7 +20,7 @@ class GeminiInferenceAdapter(OpenAIMixin, LiteLLMOpenAIMixin): LiteLLMOpenAIMixin.__init__( self, litellm_provider_name="gemini", - api_key_from_config=config.api_key.get_secret_value() if config.api_key else None, + api_key_from_config=config.api_key, provider_data_api_key_field="gemini_api_key", ) self.config = config diff --git a/llama_stack/providers/remote/inference/groq/config.py b/llama_stack/providers/remote/inference/groq/config.py index c3c3fd580..e19ee8b7b 100644 --- a/llama_stack/providers/remote/inference/groq/config.py +++ b/llama_stack/providers/remote/inference/groq/config.py @@ -6,21 +6,20 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type class GroqProviderDataValidator(BaseModel): - groq_api_key: MySecretStr = Field( + groq_api_key: SecretStr = Field( description="API key for Groq models", ) @json_schema_type class GroqConfig(BaseModel): - api_key: MySecretStr = Field( + api_key: SecretStr = Field( # The Groq client library loads the GROQ_API_KEY environment variable by default description="The Groq API key", ) diff --git a/llama_stack/providers/remote/inference/llama_openai_compat/config.py b/llama_stack/providers/remote/inference/llama_openai_compat/config.py index 863988dd6..7291c81d2 100644 --- a/llama_stack/providers/remote/inference/llama_openai_compat/config.py +++ b/llama_stack/providers/remote/inference/llama_openai_compat/config.py @@ -6,21 +6,20 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type class LlamaProviderDataValidator(BaseModel): - llama_api_key: MySecretStr = Field( + llama_api_key: SecretStr = Field( description="API key for api.llama models", ) @json_schema_type class LlamaCompatConfig(BaseModel): - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The Llama API key", ) diff --git a/llama_stack/providers/remote/inference/nvidia/config.py b/llama_stack/providers/remote/inference/nvidia/config.py index 2f6dfe9f3..9ca2ffdd6 100644 --- a/llama_stack/providers/remote/inference/nvidia/config.py +++ b/llama_stack/providers/remote/inference/nvidia/config.py @@ -7,9 +7,8 @@ import os from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type @@ -40,8 +39,8 @@ class NVIDIAConfig(BaseModel): default_factory=lambda: os.getenv("NVIDIA_BASE_URL", "https://integrate.api.nvidia.com"), description="A base url for accessing the NVIDIA NIM", ) - api_key: MySecretStr = Field( - default_factory=lambda: MySecretStr(os.getenv("NVIDIA_API_KEY", "")), + api_key: SecretStr = Field( + default_factory=lambda: SecretStr(os.getenv("NVIDIA_API_KEY", "")), description="The NVIDIA API key, only needed of using the hosted service", ) timeout: int = Field( diff --git a/llama_stack/providers/remote/inference/openai/config.py b/llama_stack/providers/remote/inference/openai/config.py index c8d6be9c2..d7bf9c341 100644 --- a/llama_stack/providers/remote/inference/openai/config.py +++ b/llama_stack/providers/remote/inference/openai/config.py @@ -6,21 +6,20 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type class OpenAIProviderDataValidator(BaseModel): - openai_api_key: MySecretStr = Field( + openai_api_key: SecretStr = Field( description="API key for OpenAI models", ) @json_schema_type class OpenAIConfig(BaseModel): - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="API key for OpenAI models", ) base_url: str = Field( diff --git a/llama_stack/providers/remote/inference/passthrough/config.py b/llama_stack/providers/remote/inference/passthrough/config.py index dee3b9173..443b3bba3 100644 --- a/llama_stack/providers/remote/inference/passthrough/config.py +++ b/llama_stack/providers/remote/inference/passthrough/config.py @@ -6,9 +6,8 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type @@ -19,7 +18,7 @@ class PassthroughImplConfig(BaseModel): description="The URL for the passthrough endpoint", ) - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="API Key for the passthrouth endpoint", ) diff --git a/llama_stack/providers/remote/inference/runpod/config.py b/llama_stack/providers/remote/inference/runpod/config.py index eaabe4e33..12b8b4ba7 100644 --- a/llama_stack/providers/remote/inference/runpod/config.py +++ b/llama_stack/providers/remote/inference/runpod/config.py @@ -6,9 +6,8 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type @@ -18,7 +17,7 @@ class RunpodImplConfig(BaseModel): default=None, description="The URL for the Runpod model serving endpoint", ) - api_token: MySecretStr = Field( + api_token: SecretStr = Field( description="The API token", ) diff --git a/llama_stack/providers/remote/inference/sambanova/config.py b/llama_stack/providers/remote/inference/sambanova/config.py index 10e28c3ac..e0e4aa2cf 100644 --- a/llama_stack/providers/remote/inference/sambanova/config.py +++ b/llama_stack/providers/remote/inference/sambanova/config.py @@ -6,14 +6,13 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type class SambaNovaProviderDataValidator(BaseModel): - sambanova_api_key: MySecretStr = Field( + sambanova_api_key: SecretStr = Field( description="Sambanova Cloud API key", ) @@ -24,7 +23,7 @@ class SambaNovaImplConfig(BaseModel): default="https://api.sambanova.ai/v1", description="The URL for the SambaNova AI server", ) - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The SambaNova cloud API Key", ) diff --git a/llama_stack/providers/remote/inference/sambanova/sambanova.py b/llama_stack/providers/remote/inference/sambanova/sambanova.py index 4d8fd11cd..a8e39ebd6 100644 --- a/llama_stack/providers/remote/inference/sambanova/sambanova.py +++ b/llama_stack/providers/remote/inference/sambanova/sambanova.py @@ -29,7 +29,7 @@ class SambaNovaInferenceAdapter(OpenAIMixin, LiteLLMOpenAIMixin): LiteLLMOpenAIMixin.__init__( self, litellm_provider_name="sambanova", - api_key_from_config=self.config.api_key.get_secret_value() if self.config.api_key else None, + api_key_from_config=self.config.api_key, provider_data_api_key_field="sambanova_api_key", openai_compat_api_base=self.config.url, download_images=True, # SambaNova requires base64 image encoding diff --git a/llama_stack/providers/remote/inference/tgi/config.py b/llama_stack/providers/remote/inference/tgi/config.py index a1f4c19f3..8cd0e15b3 100644 --- a/llama_stack/providers/remote/inference/tgi/config.py +++ b/llama_stack/providers/remote/inference/tgi/config.py @@ -5,9 +5,8 @@ # the root directory of this source tree. -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type @@ -33,7 +32,7 @@ class InferenceEndpointImplConfig(BaseModel): endpoint_name: str = Field( description="The name of the Hugging Face Inference Endpoint in the format of '{namespace}/{endpoint_name}' (e.g. 'my-cool-org/meta-llama-3-1-8b-instruct-rce'). Namespace is optional and will default to the user account if not provided.", ) - api_token: MySecretStr = Field( + api_token: SecretStr = Field( description="Your Hugging Face user access token (will default to locally saved token if not provided)", ) @@ -55,7 +54,7 @@ class InferenceAPIImplConfig(BaseModel): huggingface_repo: str = Field( description="The model ID of the model on the Hugging Face Hub (e.g. 'meta-llama/Meta-Llama-3.1-70B-Instruct')", ) - api_token: MySecretStr = Field( + api_token: SecretStr = Field( description="Your Hugging Face user access token (will default to locally saved token if not provided)", ) diff --git a/llama_stack/providers/remote/inference/tgi/tgi.py b/llama_stack/providers/remote/inference/tgi/tgi.py index 239fdce4e..27597900f 100644 --- a/llama_stack/providers/remote/inference/tgi/tgi.py +++ b/llama_stack/providers/remote/inference/tgi/tgi.py @@ -8,6 +8,7 @@ from collections.abc import AsyncGenerator from huggingface_hub import AsyncInferenceClient, HfApi +from pydantic import SecretStr from llama_stack.apis.common.content_types import ( InterleavedContent, @@ -34,7 +35,6 @@ from llama_stack.apis.inference import ( ) from llama_stack.apis.models import Model from llama_stack.apis.models.models import ModelType -from llama_stack.core.secret_types import MySecretStr from llama_stack.log import get_logger from llama_stack.models.llama.sku_list import all_registered_models from llama_stack.providers.datatypes import ModelsProtocolPrivate @@ -79,7 +79,7 @@ class _HfAdapter( ModelsProtocolPrivate, ): url: str - api_key: MySecretStr + api_key: SecretStr hf_client: AsyncInferenceClient max_tokens: int @@ -337,7 +337,7 @@ class TGIAdapter(_HfAdapter): self.max_tokens = endpoint_info["max_total_tokens"] self.model_id = endpoint_info["model_id"] self.url = f"{config.url.rstrip('/')}/v1" - self.api_key = MySecretStr("NO_KEY") + self.api_key = SecretStr("NO_KEY") class InferenceAPIAdapter(_HfAdapter): diff --git a/llama_stack/providers/remote/inference/together/config.py b/llama_stack/providers/remote/inference/together/config.py index a2fa8f76e..b39092913 100644 --- a/llama_stack/providers/remote/inference/together/config.py +++ b/llama_stack/providers/remote/inference/together/config.py @@ -6,9 +6,8 @@ from typing import Any -from pydantic import Field +from pydantic import Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.providers.utils.inference.model_registry import RemoteInferenceProviderConfig from llama_stack.schema_utils import json_schema_type @@ -19,7 +18,7 @@ class TogetherImplConfig(RemoteInferenceProviderConfig): default="https://api.together.xyz/v1", description="The URL for the Together AI server", ) - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The Together AI API Key", ) diff --git a/llama_stack/providers/remote/inference/vertexai/vertexai.py b/llama_stack/providers/remote/inference/vertexai/vertexai.py index dd1971df4..581a00f29 100644 --- a/llama_stack/providers/remote/inference/vertexai/vertexai.py +++ b/llama_stack/providers/remote/inference/vertexai/vertexai.py @@ -8,9 +8,9 @@ from typing import Any import google.auth.transport.requests from google.auth import default +from pydantic import SecretStr from llama_stack.apis.inference import ChatCompletionRequest -from llama_stack.core.secret_types import MySecretStr from llama_stack.providers.utils.inference.litellm_openai_mixin import ( LiteLLMOpenAIMixin, ) @@ -24,12 +24,12 @@ class VertexAIInferenceAdapter(OpenAIMixin, LiteLLMOpenAIMixin): LiteLLMOpenAIMixin.__init__( self, litellm_provider_name="vertex_ai", - api_key_from_config=MySecretStr(None), # Vertex AI uses ADC, not API keys + api_key_from_config=SecretStr(""), # Vertex AI uses ADC, not API keys provider_data_api_key_field="vertex_project", # Use project for validation ) self.config = config - def get_api_key(self) -> MySecretStr: + def get_api_key(self) -> SecretStr: """ Get an access token for Vertex AI using Application Default Credentials. @@ -40,11 +40,11 @@ class VertexAIInferenceAdapter(OpenAIMixin, LiteLLMOpenAIMixin): # Get default credentials - will read from GOOGLE_APPLICATION_CREDENTIALS credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"]) credentials.refresh(google.auth.transport.requests.Request()) - return MySecretStr(credentials.token) + return SecretStr(credentials.token) except Exception: # If we can't get credentials, return empty string to let LiteLLM handle it # This allows the LiteLLM mixin to work with ADC directly - return MySecretStr("") + return SecretStr("") def get_base_url(self) -> str: """ diff --git a/llama_stack/providers/remote/inference/vllm/__init__.py b/llama_stack/providers/remote/inference/vllm/__init__.py index e47597c8f..9c29795ca 100644 --- a/llama_stack/providers/remote/inference/vllm/__init__.py +++ b/llama_stack/providers/remote/inference/vllm/__init__.py @@ -4,15 +4,13 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr from .config import VLLMInferenceAdapterConfig class VLLMProviderDataValidator(BaseModel): - vllm_api_token: MySecretStr = Field( + vllm_api_token: SecretStr = Field( description="API token for vLLM models", ) diff --git a/llama_stack/providers/remote/inference/vllm/config.py b/llama_stack/providers/remote/inference/vllm/config.py index 7cc3ebebb..828c87d69 100644 --- a/llama_stack/providers/remote/inference/vllm/config.py +++ b/llama_stack/providers/remote/inference/vllm/config.py @@ -6,9 +6,8 @@ from pathlib import Path -from pydantic import BaseModel, Field, field_validator +from pydantic import BaseModel, Field, SecretStr, field_validator -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type @@ -22,7 +21,8 @@ class VLLMInferenceAdapterConfig(BaseModel): default=4096, description="Maximum number of tokens to generate.", ) - api_token: MySecretStr = Field( + api_token: SecretStr = Field( + default=SecretStr("fake"), description="The API token", ) tls_verify: bool | str = Field( diff --git a/llama_stack/providers/remote/inference/watsonx/config.py b/llama_stack/providers/remote/inference/watsonx/config.py index 64421c856..a28de1226 100644 --- a/llama_stack/providers/remote/inference/watsonx/config.py +++ b/llama_stack/providers/remote/inference/watsonx/config.py @@ -7,9 +7,8 @@ import os from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type @@ -25,8 +24,8 @@ class WatsonXConfig(BaseModel): default_factory=lambda: os.getenv("WATSONX_BASE_URL", "https://us-south.ml.cloud.ibm.com"), description="A base url for accessing the watsonx.ai", ) - api_key: MySecretStr = Field( - default_factory=lambda: MySecretStr(os.getenv("WATSONX_API_KEY", "")), + api_key: SecretStr = Field( + default_factory=lambda: SecretStr(os.getenv("WATSONX_API_KEY", "")), description="The watsonx API key", ) project_id: str | None = Field( diff --git a/llama_stack/providers/remote/post_training/nvidia/config.py b/llama_stack/providers/remote/post_training/nvidia/config.py index 1730b779f..f194ab437 100644 --- a/llama_stack/providers/remote/post_training/nvidia/config.py +++ b/llama_stack/providers/remote/post_training/nvidia/config.py @@ -7,9 +7,7 @@ import os from typing import Any -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr # TODO: add default values for all fields @@ -17,8 +15,8 @@ from llama_stack.core.secret_types import MySecretStr class NvidiaPostTrainingConfig(BaseModel): """Configuration for NVIDIA Post Training implementation.""" - api_key: MySecretStr = Field( - default_factory=lambda: MySecretStr(os.getenv("NVIDIA_API_KEY", "")), + api_key: SecretStr = Field( + default_factory=lambda: SecretStr(os.getenv("NVIDIA_API_KEY", "")), description="The NVIDIA API key.", ) diff --git a/llama_stack/providers/remote/safety/sambanova/config.py b/llama_stack/providers/remote/safety/sambanova/config.py index ff58decfd..bf474ba81 100644 --- a/llama_stack/providers/remote/safety/sambanova/config.py +++ b/llama_stack/providers/remote/safety/sambanova/config.py @@ -6,14 +6,13 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.schema_utils import json_schema_type class SambaNovaProviderDataValidator(BaseModel): - sambanova_api_key: MySecretStr = Field( + sambanova_api_key: SecretStr = Field( description="Sambanova Cloud API key", ) @@ -24,7 +23,7 @@ class SambaNovaSafetyConfig(BaseModel): default="https://api.sambanova.ai/v1", description="The URL for the SambaNova AI server", ) - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The SambaNova cloud API Key", ) diff --git a/llama_stack/providers/remote/tool_runtime/bing_search/config.py b/llama_stack/providers/remote/tool_runtime/bing_search/config.py index 54b3a9d52..591e9586c 100644 --- a/llama_stack/providers/remote/tool_runtime/bing_search/config.py +++ b/llama_stack/providers/remote/tool_runtime/bing_search/config.py @@ -6,15 +6,13 @@ from typing import Any -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr class BingSearchToolConfig(BaseModel): """Configuration for Bing Search Tool Runtime""" - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The Bing API key", ) top_k: int = 3 diff --git a/llama_stack/providers/remote/tool_runtime/brave_search/config.py b/llama_stack/providers/remote/tool_runtime/brave_search/config.py index 8fbc42154..bc93bc7f6 100644 --- a/llama_stack/providers/remote/tool_runtime/brave_search/config.py +++ b/llama_stack/providers/remote/tool_runtime/brave_search/config.py @@ -6,13 +6,11 @@ from typing import Any -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr class BraveSearchToolConfig(BaseModel): - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The Brave Search API Key", ) max_results: int = Field( diff --git a/llama_stack/providers/remote/tool_runtime/tavily_search/config.py b/llama_stack/providers/remote/tool_runtime/tavily_search/config.py index c2e31e5d3..5afd19bfa 100644 --- a/llama_stack/providers/remote/tool_runtime/tavily_search/config.py +++ b/llama_stack/providers/remote/tool_runtime/tavily_search/config.py @@ -6,13 +6,11 @@ from typing import Any -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr class TavilySearchToolConfig(BaseModel): - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The Tavily Search API Key", ) max_results: int = Field( diff --git a/llama_stack/providers/remote/tool_runtime/wolfram_alpha/config.py b/llama_stack/providers/remote/tool_runtime/wolfram_alpha/config.py index eea5ffdd2..980b30411 100644 --- a/llama_stack/providers/remote/tool_runtime/wolfram_alpha/config.py +++ b/llama_stack/providers/remote/tool_runtime/wolfram_alpha/config.py @@ -6,15 +6,13 @@ from typing import Any -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr class WolframAlphaToolConfig(BaseModel): """Configuration for WolframAlpha Tool Runtime""" - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The WolframAlpha API Key", ) diff --git a/llama_stack/providers/remote/vector_io/milvus/config.py b/llama_stack/providers/remote/vector_io/milvus/config.py index 899d3678d..83daae779 100644 --- a/llama_stack/providers/remote/vector_io/milvus/config.py +++ b/llama_stack/providers/remote/vector_io/milvus/config.py @@ -6,7 +6,7 @@ from typing import Any -from pydantic import BaseModel, ConfigDict, Field +from pydantic import BaseModel, ConfigDict, Field, SecretStr from llama_stack.providers.utils.kvstore.config import KVStoreConfig, SqliteKVStoreConfig from llama_stack.schema_utils import json_schema_type @@ -15,7 +15,7 @@ from llama_stack.schema_utils import json_schema_type @json_schema_type class MilvusVectorIOConfig(BaseModel): uri: str = Field(description="The URI of the Milvus server") - token: str | None = Field(description="The token of the Milvus server") + token: SecretStr = Field(description="The token of the Milvus server") consistency_level: str = Field(description="The consistency level of the Milvus server", default="Strong") kvstore: KVStoreConfig = Field(description="Config for KV store backend") diff --git a/llama_stack/providers/remote/vector_io/pgvector/config.py b/llama_stack/providers/remote/vector_io/pgvector/config.py index ee4ef40d0..1c6d0ed52 100644 --- a/llama_stack/providers/remote/vector_io/pgvector/config.py +++ b/llama_stack/providers/remote/vector_io/pgvector/config.py @@ -6,9 +6,8 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.providers.utils.kvstore.config import ( KVStoreConfig, SqliteKVStoreConfig, @@ -22,7 +21,7 @@ class PGVectorVectorIOConfig(BaseModel): port: int | None = Field(default=5432) db: str | None = Field(default="postgres") user: str | None = Field(default="postgres") - password: MySecretStr = Field(default=MySecretStr("mysecretpassword")) + password: SecretStr = Field(default=SecretStr("mysecretpassword")) kvstore: KVStoreConfig | None = Field(description="Config for KV store backend (SQLite only for now)", default=None) @classmethod diff --git a/llama_stack/providers/remote/vector_io/qdrant/config.py b/llama_stack/providers/remote/vector_io/qdrant/config.py index 58044e248..8a0be3ab4 100644 --- a/llama_stack/providers/remote/vector_io/qdrant/config.py +++ b/llama_stack/providers/remote/vector_io/qdrant/config.py @@ -6,9 +6,8 @@ from typing import Any -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.providers.utils.kvstore.config import ( KVStoreConfig, SqliteKVStoreConfig, @@ -24,7 +23,7 @@ class QdrantVectorIOConfig(BaseModel): grpc_port: int = 6334 prefer_grpc: bool = False https: bool | None = None - api_key: MySecretStr = Field( + api_key: SecretStr = Field( description="The API key for the Qdrant instance", ) prefix: str | None = None diff --git a/llama_stack/providers/remote/vector_io/qdrant/qdrant.py b/llama_stack/providers/remote/vector_io/qdrant/qdrant.py index ec3869495..0ba7c51f8 100644 --- a/llama_stack/providers/remote/vector_io/qdrant/qdrant.py +++ b/llama_stack/providers/remote/vector_io/qdrant/qdrant.py @@ -173,7 +173,7 @@ class QdrantVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolP self._qdrant_lock = asyncio.Lock() async def initialize(self) -> None: - client_config = self.config.model_dump(exclude_none=True, exclude={"kvstore"}) + client_config = self.config.model_dump(exclude_none=True, exclude={"kvstore"}, mode="json") self.client = AsyncQdrantClient(**client_config) self.kvstore = await kvstore_impl(self.config.kvstore) diff --git a/llama_stack/providers/utils/bedrock/config.py b/llama_stack/providers/utils/bedrock/config.py index ae4018b80..2a5c8e882 100644 --- a/llama_stack/providers/utils/bedrock/config.py +++ b/llama_stack/providers/utils/bedrock/config.py @@ -6,9 +6,7 @@ import os -from pydantic import BaseModel, Field - -from llama_stack.core.secret_types import MySecretStr +from pydantic import BaseModel, Field, SecretStr class BedrockBaseConfig(BaseModel): @@ -16,12 +14,12 @@ class BedrockBaseConfig(BaseModel): default_factory=lambda: os.getenv("AWS_ACCESS_KEY_ID"), description="The AWS access key to use. Default use environment variable: AWS_ACCESS_KEY_ID", ) - aws_secret_access_key: MySecretStr = Field( - default_factory=lambda: MySecretStr(os.getenv("AWS_SECRET_ACCESS_KEY", "")), + aws_secret_access_key: SecretStr = Field( + default_factory=lambda: SecretStr(os.getenv("AWS_SECRET_ACCESS_KEY", "")), description="The AWS secret access key to use. Default use environment variable: AWS_SECRET_ACCESS_KEY", ) - aws_session_token: MySecretStr = Field( - default_factory=lambda: MySecretStr(os.getenv("AWS_SESSION_TOKEN", "")), + aws_session_token: SecretStr = Field( + default_factory=lambda: SecretStr(os.getenv("AWS_SESSION_TOKEN", "")), description="The AWS session token to use. Default use environment variable: AWS_SESSION_TOKEN", ) region_name: str | None = Field( diff --git a/llama_stack/providers/utils/inference/litellm_openai_mixin.py b/llama_stack/providers/utils/inference/litellm_openai_mixin.py index a5d320e41..8bdfbbbc9 100644 --- a/llama_stack/providers/utils/inference/litellm_openai_mixin.py +++ b/llama_stack/providers/utils/inference/litellm_openai_mixin.py @@ -8,6 +8,7 @@ from collections.abc import AsyncGenerator, AsyncIterator from typing import Any import litellm +from pydantic import SecretStr from llama_stack.apis.common.content_types import ( InterleavedContent, @@ -39,7 +40,6 @@ from llama_stack.apis.inference import ( ToolPromptFormat, ) from llama_stack.core.request_headers import NeedsRequestProviderData -from llama_stack.core.secret_types import MySecretStr from llama_stack.log import get_logger from llama_stack.providers.utils.inference.model_registry import ModelRegistryHelper, ProviderModelEntry from llama_stack.providers.utils.inference.openai_compat import ( @@ -69,7 +69,7 @@ class LiteLLMOpenAIMixin( def __init__( self, litellm_provider_name: str, - api_key_from_config: MySecretStr, + api_key_from_config: SecretStr, provider_data_api_key_field: str, model_entries: list[ProviderModelEntry] | None = None, openai_compat_api_base: str | None = None, @@ -255,7 +255,7 @@ class LiteLLMOpenAIMixin( **get_sampling_options(request.sampling_params), } - def get_api_key(self) -> MySecretStr: + def get_api_key(self) -> SecretStr: provider_data = self.get_request_provider_data() key_field = self.provider_data_api_key_field if provider_data and getattr(provider_data, key_field, None): diff --git a/llama_stack/providers/utils/inference/openai_mixin.py b/llama_stack/providers/utils/inference/openai_mixin.py index 4bb7a28c5..d63f147bc 100644 --- a/llama_stack/providers/utils/inference/openai_mixin.py +++ b/llama_stack/providers/utils/inference/openai_mixin.py @@ -11,6 +11,7 @@ from collections.abc import AsyncIterator from typing import Any from openai import NOT_GIVEN, AsyncOpenAI +from pydantic import SecretStr from llama_stack.apis.inference import ( Model, @@ -24,7 +25,6 @@ from llama_stack.apis.inference import ( OpenAIResponseFormatParam, ) from llama_stack.apis.models import ModelType -from llama_stack.core.secret_types import MySecretStr from llama_stack.log import get_logger from llama_stack.providers.utils.inference.model_registry import ModelRegistryHelper from llama_stack.providers.utils.inference.openai_compat import prepare_openai_completion_params @@ -71,14 +71,14 @@ class OpenAIMixin(ModelRegistryHelper, ABC): allowed_models: list[str] = [] @abstractmethod - def get_api_key(self) -> MySecretStr: + def get_api_key(self) -> SecretStr: """ Get the API key. This method must be implemented by child classes to provide the API key for authenticating with the OpenAI API or compatible endpoints. - :return: The API key as a MySecretStr + :return: The API key as a SecretStr """ pass diff --git a/llama_stack/providers/utils/kvstore/config.py b/llama_stack/providers/utils/kvstore/config.py index a8dd1a99a..baab4e372 100644 --- a/llama_stack/providers/utils/kvstore/config.py +++ b/llama_stack/providers/utils/kvstore/config.py @@ -8,9 +8,8 @@ import re from enum import Enum from typing import Annotated, Literal -from pydantic import BaseModel, Field, field_validator +from pydantic import BaseModel, Field, SecretStr, field_validator -from llama_stack.core.secret_types import MySecretStr from llama_stack.core.utils.config_dirs import RUNTIME_BASE_DIR @@ -75,7 +74,7 @@ class PostgresKVStoreConfig(CommonConfig): port: int = 5432 db: str = "llamastack" user: str - password: MySecretStr = MySecretStr("") + password: SecretStr = SecretStr("") ssl_mode: str | None = None ca_cert_path: str | None = None table_name: str = "llamastack_kvstore" @@ -119,7 +118,7 @@ class MongoDBKVStoreConfig(CommonConfig): port: int = 27017 db: str = "llamastack" user: str | None = None - password: MySecretStr = MySecretStr("") + password: SecretStr = SecretStr("") collection_name: str = "llamastack_kvstore" @classmethod diff --git a/llama_stack/providers/utils/sqlstore/sqlstore.py b/llama_stack/providers/utils/sqlstore/sqlstore.py index 3bcd8f40d..6eaafccfe 100644 --- a/llama_stack/providers/utils/sqlstore/sqlstore.py +++ b/llama_stack/providers/utils/sqlstore/sqlstore.py @@ -9,9 +9,8 @@ from enum import StrEnum from pathlib import Path from typing import Annotated, Literal -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr -from llama_stack.core.secret_types import MySecretStr from llama_stack.core.utils.config_dirs import RUNTIME_BASE_DIR from .api import SqlStore @@ -64,7 +63,7 @@ class PostgresSqlStoreConfig(SqlAlchemySqlStoreConfig): port: int = 5432 db: str = "llamastack" user: str - password: MySecretStr = MySecretStr("") + password: SecretStr = SecretStr("") @property def engine_str(self) -> str: diff --git a/tests/unit/providers/files/conftest.py b/tests/unit/providers/files/conftest.py index 46282e3dc..696ee7ba7 100644 --- a/tests/unit/providers/files/conftest.py +++ b/tests/unit/providers/files/conftest.py @@ -7,6 +7,7 @@ import boto3 import pytest from moto import mock_aws +from pydantic import SecretStr from llama_stack.providers.remote.files.s3 import S3FilesImplConfig, get_adapter_impl from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig @@ -43,6 +44,7 @@ def s3_config(tmp_path): region="not-a-region", auto_create_bucket=True, metadata_store=SqliteSqlStoreConfig(db_path=db_path.as_posix()), + aws_secret_access_key=SecretStr("fake"), ) diff --git a/tests/unit/providers/inference/bedrock/test_config.py b/tests/unit/providers/inference/bedrock/test_config.py index 1b8639f2e..903b6957a 100644 --- a/tests/unit/providers/inference/bedrock/test_config.py +++ b/tests/unit/providers/inference/bedrock/test_config.py @@ -17,7 +17,7 @@ class TestBedrockBaseConfig: # Basic creds should be None assert config.aws_access_key_id is None - assert config.aws_secret_access_key is None + assert not config.aws_secret_access_key assert config.region_name is None # Timeouts get defaults @@ -39,7 +39,7 @@ class TestBedrockBaseConfig: config = BedrockBaseConfig() assert config.aws_access_key_id == "AKIATEST123" - assert config.aws_secret_access_key == "secret123" + assert config.aws_secret_access_key.get_secret_value() == "secret123" assert config.region_name == "us-west-2" assert config.total_max_attempts == 5 assert config.retry_mode == "adaptive" diff --git a/tests/unit/providers/inference/test_inference_client_caching.py b/tests/unit/providers/inference/test_inference_client_caching.py index 974d55ade..5084ad5f3 100644 --- a/tests/unit/providers/inference/test_inference_client_caching.py +++ b/tests/unit/providers/inference/test_inference_client_caching.py @@ -7,6 +7,8 @@ import json from unittest.mock import MagicMock +from pydantic import SecretStr + from llama_stack.core.request_headers import request_provider_data_context from llama_stack.providers.remote.inference.groq.config import GroqConfig from llama_stack.providers.remote.inference.groq.groq import GroqInferenceAdapter @@ -21,7 +23,7 @@ from llama_stack.providers.remote.inference.together.together import TogetherInf def test_groq_provider_openai_client_caching(): """Ensure the Groq provider does not cache api keys across client requests""" - config = GroqConfig() + config = GroqConfig(api_key=SecretStr("")) inference_adapter = GroqInferenceAdapter(config) inference_adapter.__provider_spec__ = MagicMock() @@ -33,13 +35,13 @@ def test_groq_provider_openai_client_caching(): with request_provider_data_context( {"x-llamastack-provider-data": json.dumps({inference_adapter.provider_data_api_key_field: api_key})} ): - assert inference_adapter.client.api_key.get_secret_value() == api_key + assert inference_adapter.client.api_key == api_key def test_openai_provider_openai_client_caching(): """Ensure the OpenAI provider does not cache api keys across client requests""" - config = OpenAIConfig() + config = OpenAIConfig(api_key=SecretStr("")) inference_adapter = OpenAIInferenceAdapter(config) inference_adapter.__provider_spec__ = MagicMock() @@ -52,13 +54,13 @@ def test_openai_provider_openai_client_caching(): {"x-llamastack-provider-data": json.dumps({inference_adapter.provider_data_api_key_field: api_key})} ): openai_client = inference_adapter.client - assert openai_client.api_key.get_secret_value() == api_key + assert openai_client.api_key == api_key def test_together_provider_openai_client_caching(): """Ensure the Together provider does not cache api keys across client requests""" - config = TogetherImplConfig() + config = TogetherImplConfig(api_key=SecretStr("")) inference_adapter = TogetherInferenceAdapter(config) inference_adapter.__provider_spec__ = MagicMock() @@ -76,7 +78,7 @@ def test_together_provider_openai_client_caching(): def test_llama_compat_provider_openai_client_caching(): """Ensure the LlamaCompat provider does not cache api keys across client requests""" - config = LlamaCompatConfig() + config = LlamaCompatConfig(api_key=SecretStr("")) inference_adapter = LlamaCompatInferenceAdapter(config) inference_adapter.__provider_spec__ = MagicMock() @@ -86,4 +88,4 @@ def test_llama_compat_provider_openai_client_caching(): for api_key in ["test1", "test2"]: with request_provider_data_context({"x-llamastack-provider-data": json.dumps({"llama_api_key": api_key})}): - assert inference_adapter.client.api_key.get_secret_value() == api_key + assert inference_adapter.client.api_key == api_key diff --git a/tests/unit/providers/inference/test_litellm_openai_mixin.py b/tests/unit/providers/inference/test_litellm_openai_mixin.py index 48bf5ce38..cf7623dd1 100644 --- a/tests/unit/providers/inference/test_litellm_openai_mixin.py +++ b/tests/unit/providers/inference/test_litellm_openai_mixin.py @@ -8,20 +8,19 @@ import json from unittest.mock import MagicMock import pytest -from pydantic import BaseModel, Field +from pydantic import BaseModel, Field, SecretStr from llama_stack.core.request_headers import request_provider_data_context -from llama_stack.core.secret_types import MySecretStr from llama_stack.providers.utils.inference.litellm_openai_mixin import LiteLLMOpenAIMixin # Test fixtures and helper classes class TestConfig(BaseModel): - api_key: MySecretStr | None = Field(default=None) + api_key: SecretStr | None = Field(default=None) class TestProviderDataValidator(BaseModel): - test_api_key: MySecretStr | None = Field(default=None) + test_api_key: SecretStr | None = Field(default=None) class TestLiteLLMAdapter(LiteLLMOpenAIMixin): @@ -37,7 +36,7 @@ class TestLiteLLMAdapter(LiteLLMOpenAIMixin): @pytest.fixture def adapter_with_config_key(): """Fixture to create adapter with API key in config""" - config = TestConfig(api_key=MySecretStr("config-api-key")) + config = TestConfig(api_key=SecretStr("config-api-key")) adapter = TestLiteLLMAdapter(config) adapter.__provider_spec__ = MagicMock() adapter.__provider_spec__.provider_data_validator = ( diff --git a/tests/unit/providers/inference/test_openai_base_url_config.py b/tests/unit/providers/inference/test_openai_base_url_config.py index 40c789073..e7b5a5267 100644 --- a/tests/unit/providers/inference/test_openai_base_url_config.py +++ b/tests/unit/providers/inference/test_openai_base_url_config.py @@ -7,14 +7,9 @@ import os from unittest.mock import MagicMock, patch -from llama_stack.core.secret_types import MySecretStr - - -# Wrapper for backward compatibility in tests -def replace_env_vars_compat(config, path=""): - return replace_env_vars_compat(config, path, None, None) - +from pydantic import SecretStr +from llama_stack.core.stack import replace_env_vars from llama_stack.providers.remote.inference.openai.config import OpenAIConfig from llama_stack.providers.remote.inference.openai.openai import OpenAIInferenceAdapter @@ -42,7 +37,7 @@ class TestOpenAIBaseURLConfig: """Test that the adapter uses base URL from OPENAI_BASE_URL environment variable.""" # Use sample_run_config which has proper environment variable syntax config_data = OpenAIConfig.sample_run_config(api_key="test-key") - processed_config = replace_env_vars_compat(config_data) + processed_config = replace_env_vars(config_data) config = OpenAIConfig.model_validate(processed_config) adapter = OpenAIInferenceAdapter(config) @@ -66,14 +61,14 @@ class TestOpenAIBaseURLConfig: adapter = OpenAIInferenceAdapter(config) # Mock the get_api_key method since it's delegated to LiteLLMOpenAIMixin - adapter.get_api_key = MagicMock(return_value=MySecretStr("test-key")) + adapter.get_api_key = MagicMock(return_value=SecretStr("test-key")) # Access the client property to trigger AsyncOpenAI initialization _ = adapter.client # Verify AsyncOpenAI was called with the correct base_url mock_openai_class.assert_called_once_with( - api_key=MySecretStr("test-key"), + api_key=SecretStr("test-key").get_secret_value(), base_url=custom_url, ) @@ -85,7 +80,7 @@ class TestOpenAIBaseURLConfig: adapter = OpenAIInferenceAdapter(config) # Mock the get_api_key method - adapter.get_api_key = MagicMock(return_value=MySecretStr("test-key")) + adapter.get_api_key = MagicMock(return_value=SecretStr("test-key")) # Mock a model object that will be returned by models.list() mock_model = MagicMock() @@ -108,7 +103,7 @@ class TestOpenAIBaseURLConfig: # Verify the client was created with the custom URL mock_openai_class.assert_called_with( - api_key=MySecretStr("test-key"), + api_key=SecretStr("test-key").get_secret_value(), base_url=custom_url, ) @@ -121,12 +116,12 @@ class TestOpenAIBaseURLConfig: """Test that setting OPENAI_BASE_URL environment variable affects where model availability is checked.""" # Use sample_run_config which has proper environment variable syntax config_data = OpenAIConfig.sample_run_config(api_key="test-key") - processed_config = replace_env_vars_compat(config_data) + processed_config = replace_env_vars(config_data) config = OpenAIConfig.model_validate(processed_config) adapter = OpenAIInferenceAdapter(config) # Mock the get_api_key method - adapter.get_api_key = MagicMock(return_value=MySecretStr("test-key")) + adapter.get_api_key = MagicMock(return_value=SecretStr("test-key")) # Mock a model object that will be returned by models.list() mock_model = MagicMock() @@ -149,6 +144,6 @@ class TestOpenAIBaseURLConfig: # Verify the client was created with the environment variable URL mock_openai_class.assert_called_with( - api_key=MySecretStr("test-key"), + api_key=SecretStr("test-key").get_secret_value(), base_url="https://proxy.openai.com/v1", ) diff --git a/tests/unit/providers/inference/test_remote_vllm.py b/tests/unit/providers/inference/test_remote_vllm.py index 4dc2e0c16..52a771fae 100644 --- a/tests/unit/providers/inference/test_remote_vllm.py +++ b/tests/unit/providers/inference/test_remote_vllm.py @@ -26,6 +26,7 @@ from openai.types.chat.chat_completion_chunk import ( ChoiceDeltaToolCallFunction as OpenAIChoiceDeltaToolCallFunction, ) from openai.types.model import Model as OpenAIModel +from pydantic import SecretStr from llama_stack.apis.inference import ( ChatCompletionRequest, @@ -688,31 +689,35 @@ async def test_should_refresh_models(): """ # Test case 1: refresh_models is True, api_token is None - config1 = VLLMInferenceAdapterConfig(url="http://test.localhost", api_token=None, refresh_models=True) + config1 = VLLMInferenceAdapterConfig(url="http://test.localhost", api_token=SecretStr(""), refresh_models=True) adapter1 = VLLMInferenceAdapter(config1) result1 = await adapter1.should_refresh_models() assert result1 is True, "should_refresh_models should return True when refresh_models is True" # Test case 2: refresh_models is True, api_token is empty string - config2 = VLLMInferenceAdapterConfig(url="http://test.localhost", api_token="", refresh_models=True) + config2 = VLLMInferenceAdapterConfig(url="http://test.localhost", api_token=SecretStr(""), refresh_models=True) adapter2 = VLLMInferenceAdapter(config2) result2 = await adapter2.should_refresh_models() assert result2 is True, "should_refresh_models should return True when refresh_models is True" # Test case 3: refresh_models is True, api_token is "fake" (default) - config3 = VLLMInferenceAdapterConfig(url="http://test.localhost", api_token="fake", refresh_models=True) + config3 = VLLMInferenceAdapterConfig(url="http://test.localhost", api_token=SecretStr("fake"), refresh_models=True) adapter3 = VLLMInferenceAdapter(config3) result3 = await adapter3.should_refresh_models() assert result3 is True, "should_refresh_models should return True when refresh_models is True" # Test case 4: refresh_models is True, api_token is real token - config4 = VLLMInferenceAdapterConfig(url="http://test.localhost", api_token="real-token-123", refresh_models=True) + config4 = VLLMInferenceAdapterConfig( + url="http://test.localhost", api_token=SecretStr("real-token-123"), refresh_models=True + ) adapter4 = VLLMInferenceAdapter(config4) result4 = await adapter4.should_refresh_models() assert result4 is True, "should_refresh_models should return True when refresh_models is True" # Test case 5: refresh_models is False, api_token is real token - config5 = VLLMInferenceAdapterConfig(url="http://test.localhost", api_token="real-token-456", refresh_models=False) + config5 = VLLMInferenceAdapterConfig( + url="http://test.localhost", api_token=SecretStr("real-token-456"), refresh_models=False + ) adapter5 = VLLMInferenceAdapter(config5) result5 = await adapter5.should_refresh_models() assert result5 is False, "should_refresh_models should return False when refresh_models is False" @@ -735,7 +740,7 @@ async def test_provider_data_var_context_propagation(vllm_inference_adapter): # Mock provider data to return test data mock_provider_data = MagicMock() - mock_provider_data.vllm_api_token = "test-token-123" + mock_provider_data.vllm_api_token = SecretStr("test-token-123") mock_provider_data.vllm_url = "http://test-server:8000/v1" mock_get_provider_data.return_value = mock_provider_data diff --git a/tests/unit/providers/nvidia/test_parameters.py b/tests/unit/providers/nvidia/test_parameters.py index ad381da26..d58809211 100644 --- a/tests/unit/providers/nvidia/test_parameters.py +++ b/tests/unit/providers/nvidia/test_parameters.py @@ -9,6 +9,7 @@ import warnings from unittest.mock import patch import pytest +from pydantic import SecretStr from llama_stack.apis.post_training.post_training import ( DataConfig, @@ -32,7 +33,7 @@ class TestNvidiaParameters: """Setup and teardown for each test method.""" os.environ["NVIDIA_CUSTOMIZER_URL"] = "http://nemo.test" - config = NvidiaPostTrainingConfig(customizer_url=os.environ["NVIDIA_CUSTOMIZER_URL"], api_key=None) + config = NvidiaPostTrainingConfig(customizer_url=os.environ["NVIDIA_CUSTOMIZER_URL"], api_key=SecretStr("")) self.adapter = NvidiaPostTrainingAdapter(config) self.make_request_patcher = patch( diff --git a/tests/unit/providers/nvidia/test_supervised_fine_tuning.py b/tests/unit/providers/nvidia/test_supervised_fine_tuning.py index 91148605d..0f756c7d4 100644 --- a/tests/unit/providers/nvidia/test_supervised_fine_tuning.py +++ b/tests/unit/providers/nvidia/test_supervised_fine_tuning.py @@ -9,6 +9,7 @@ import warnings from unittest.mock import patch import pytest +from pydantic import SecretStr from llama_stack.apis.post_training.post_training import ( DataConfig, @@ -34,7 +35,7 @@ def nvidia_post_training_adapter(): """Fixture to create and configure the NVIDIA post training adapter.""" os.environ["NVIDIA_CUSTOMIZER_URL"] = "http://nemo.test" # needed for nemo customizer - config = NvidiaPostTrainingConfig(customizer_url=os.environ["NVIDIA_CUSTOMIZER_URL"], api_key=None) + config = NvidiaPostTrainingConfig(customizer_url=os.environ["NVIDIA_CUSTOMIZER_URL"], api_key=SecretStr("")) adapter = NvidiaPostTrainingAdapter(config) with patch.object(adapter, "_make_request") as mock_make_request: diff --git a/tests/unit/server/test_replace_env_vars.py b/tests/unit/server/test_replace_env_vars.py index 0c9bec860..14b3b7231 100644 --- a/tests/unit/server/test_replace_env_vars.py +++ b/tests/unit/server/test_replace_env_vars.py @@ -8,10 +8,7 @@ import os import pytest - -# Wrapper for backward compatibility in tests -def replace_env_vars_compat(config, path=""): - return replace_env_vars_compat(config, path, None, None) +from llama_stack.core.stack import replace_env_vars @pytest.fixture @@ -35,54 +32,52 @@ def setup_env_vars(): def test_simple_replacement(setup_env_vars): - assert replace_env_vars_compat("${env.TEST_VAR}") == "test_value" + assert replace_env_vars("${env.TEST_VAR}") == "test_value" def test_default_value_when_not_set(setup_env_vars): - assert replace_env_vars_compat("${env.NOT_SET:=default}") == "default" + assert replace_env_vars("${env.NOT_SET:=default}") == "default" def test_default_value_when_set(setup_env_vars): - assert replace_env_vars_compat("${env.TEST_VAR:=default}") == "test_value" + assert replace_env_vars("${env.TEST_VAR:=default}") == "test_value" def test_default_value_when_empty(setup_env_vars): - assert replace_env_vars_compat("${env.EMPTY_VAR:=default}") == "default" + assert replace_env_vars("${env.EMPTY_VAR:=default}") == "default" def test_none_value_when_empty(setup_env_vars): - assert replace_env_vars_compat("${env.EMPTY_VAR:=}") is None + assert replace_env_vars("${env.EMPTY_VAR:=}") is None def test_value_when_set(setup_env_vars): - assert replace_env_vars_compat("${env.TEST_VAR:=}") == "test_value" + assert replace_env_vars("${env.TEST_VAR:=}") == "test_value" def test_empty_var_no_default(setup_env_vars): - assert replace_env_vars_compat("${env.EMPTY_VAR_NO_DEFAULT:+}") is None + assert replace_env_vars("${env.EMPTY_VAR_NO_DEFAULT:+}") is None def test_conditional_value_when_set(setup_env_vars): - assert replace_env_vars_compat("${env.TEST_VAR:+conditional}") == "conditional" + assert replace_env_vars("${env.TEST_VAR:+conditional}") == "conditional" def test_conditional_value_when_not_set(setup_env_vars): - assert replace_env_vars_compat("${env.NOT_SET:+conditional}") is None + assert replace_env_vars("${env.NOT_SET:+conditional}") is None def test_conditional_value_when_empty(setup_env_vars): - assert replace_env_vars_compat("${env.EMPTY_VAR:+conditional}") is None + assert replace_env_vars("${env.EMPTY_VAR:+conditional}") is None def test_conditional_value_with_zero(setup_env_vars): - assert replace_env_vars_compat("${env.ZERO_VAR:+conditional}") == "conditional" + assert replace_env_vars("${env.ZERO_VAR:+conditional}") == "conditional" def test_mixed_syntax(setup_env_vars): - assert replace_env_vars_compat("${env.TEST_VAR:=default} and ${env.NOT_SET:+conditional}") == "test_value and " - assert ( - replace_env_vars_compat("${env.NOT_SET:=default} and ${env.TEST_VAR:+conditional}") == "default and conditional" - ) + assert replace_env_vars("${env.TEST_VAR:=default} and ${env.NOT_SET:+conditional}") == "test_value and " + assert replace_env_vars("${env.NOT_SET:=default} and ${env.TEST_VAR:+conditional}") == "default and conditional" def test_nested_structures(setup_env_vars): @@ -92,11 +87,11 @@ def test_nested_structures(setup_env_vars): "key3": {"nested": "${env.NOT_SET:+conditional}"}, } expected = {"key1": "test_value", "key2": ["default", "conditional"], "key3": {"nested": None}} - assert replace_env_vars_compat(data) == expected + assert replace_env_vars(data) == expected def test_explicit_strings_preserved(setup_env_vars): # Explicit strings that look like numbers/booleans should remain strings data = {"port": "8080", "enabled": "true", "count": "123", "ratio": "3.14"} expected = {"port": "8080", "enabled": "true", "count": "123", "ratio": "3.14"} - assert replace_env_vars_compat(data) == expected + assert replace_env_vars(data) == expected