fix(mypy): resolve OpenAI SDK and provider type issues (#3936)

## Summary
- Fix OpenAI SDK NotGiven/Omit type mismatches in embeddings calls
- Fix incorrect OpenAIChatCompletionChunk import in vllm provider
- Refactor to avoid type:ignore comments by using conditional kwargs

## Changes
**openai_mixin.py (9 errors fixed):**
- Build kwargs conditionally for embeddings.create() to avoid
NotGiven/Omit mismatch
- Only include parameters when they have actual values (not None)

**gemini.py (9 errors fixed):**
- Apply same conditional kwargs pattern
- Add missing Any import

**vllm.py (2 errors fixed):**
- Use correct OpenAIChatCompletionChunk from llama_stack.apis.inference
- Remove incorrect alias from openai package

## Technical Notes
The OpenAI SDK has a type system quirk where `NOT_GIVEN` has type
`NotGiven` but parameter signatures expect `Omit`. By only passing
parameters with actual values, we avoid this mismatch entirely without
needing `# type: ignore` comments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Ashwin Bharambe 2025-10-28 10:54:29 -07:00 committed by GitHub
parent d009dc29f7
commit 1d385b5b75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 60 additions and 41 deletions

View file

@ -4,14 +4,19 @@
# This source code is licensed under the terms described in the LICENSE file in
# the root directory of this source tree.
from __future__ import annotations
import uuid
from datetime import UTC, datetime
from typing import Annotated, Any
from typing import TYPE_CHECKING, Annotated, Any, cast
import boto3
from botocore.exceptions import BotoCoreError, ClientError, NoCredentialsError
from fastapi import Depends, File, Form, Response, UploadFile
if TYPE_CHECKING:
from mypy_boto3_s3.client import S3Client
from llama_stack.apis.common.errors import ResourceNotFoundError
from llama_stack.apis.common.responses import Order
from llama_stack.apis.files import (
@ -34,7 +39,7 @@ from .config import S3FilesImplConfig
# TODO: provider data for S3 credentials
def _create_s3_client(config: S3FilesImplConfig) -> boto3.client:
def _create_s3_client(config: S3FilesImplConfig) -> S3Client:
try:
s3_config = {
"region_name": config.region,
@ -52,13 +57,16 @@ def _create_s3_client(config: S3FilesImplConfig) -> boto3.client:
}
)
return boto3.client("s3", **s3_config)
# Both cast and type:ignore are needed here:
# - cast tells mypy the return type for downstream usage (S3Client vs generic client)
# - type:ignore suppresses the call-overload error from boto3's complex overloaded signatures
return cast("S3Client", boto3.client("s3", **s3_config)) # type: ignore[call-overload]
except (BotoCoreError, NoCredentialsError) as e:
raise RuntimeError(f"Failed to initialize S3 client: {e}") from e
async def _create_bucket_if_not_exists(client: boto3.client, config: S3FilesImplConfig) -> None:
async def _create_bucket_if_not_exists(client: S3Client, config: S3FilesImplConfig) -> None:
try:
client.head_bucket(Bucket=config.bucket_name)
except ClientError as e:
@ -76,7 +84,7 @@ async def _create_bucket_if_not_exists(client: boto3.client, config: S3FilesImpl
else:
client.create_bucket(
Bucket=config.bucket_name,
CreateBucketConfiguration={"LocationConstraint": config.region},
CreateBucketConfiguration=cast(Any, {"LocationConstraint": config.region}),
)
except ClientError as create_error:
raise RuntimeError(
@ -128,7 +136,7 @@ class S3FilesImpl(Files):
def __init__(self, config: S3FilesImplConfig, policy: list[AccessRule]) -> None:
self._config = config
self.policy = policy
self._client: boto3.client | None = None
self._client: S3Client | None = None
self._sql_store: AuthorizedSqlStore | None = None
def _now(self) -> int:
@ -184,7 +192,7 @@ class S3FilesImpl(Files):
pass
@property
def client(self) -> boto3.client:
def client(self) -> S3Client:
assert self._client is not None, "Provider not initialized"
return self._client