From a4da640900b4a8f59242dd03e180064469bfff9b Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Mon, 29 Jun 2026 18:17:06 +1000 Subject: [PATCH] Mark OpenAI clients as deprecated --- sdk_v2/cs/src/Detail/Model.cs | 9 +++++++ sdk_v2/cs/src/IModel.cs | 3 +++ sdk_v2/cs/src/OpenAI/AudioClient.cs | 1 + .../AudioTranscriptionRequestResponseTypes.cs | 2 ++ sdk_v2/cs/src/OpenAI/ChatClient.cs | 1 + .../ChatCompletionRequestResponseTypes.cs | 2 ++ sdk_v2/cs/src/OpenAI/EmbeddingClient.cs | 1 + .../OpenAI/LiveAudioTranscriptionClient.cs | 1 + sdk_v2/js/src/index.ts | 4 +++ sdk_v2/js/src/model.ts | 3 +++ sdk_v2/js/src/openai/audioClient.ts | 4 +++ sdk_v2/js/src/openai/chatClient.ts | 3 +++ sdk_v2/js/src/openai/embeddingClient.ts | 4 +++ sdk_v2/js/src/openai/liveAudioSession.ts | 4 +++ sdk_v2/python/src/foundry_local_sdk/imodel.py | 26 ++++++++++++++++--- .../foundry_local_sdk/openai/audio_client.py | 18 +++++++++++++ .../foundry_local_sdk/openai/chat_client.py | 17 ++++++++++++ .../openai/embedding_client.py | 17 ++++++++++++ .../openai/live_audio_session.py | 18 +++++++++++++ 19 files changed, 135 insertions(+), 3 deletions(-) diff --git a/sdk_v2/cs/src/Detail/Model.cs b/sdk_v2/cs/src/Detail/Model.cs index 3b69c7b9f..b04e92316 100644 --- a/sdk_v2/cs/src/Detail/Model.cs +++ b/sdk_v2/cs/src/Detail/Model.cs @@ -115,6 +115,7 @@ await Utils.CallWithExceptionHandlingAsync( $"Error removing model {Id} from cache", _logger, ct).ConfigureAwait(false); } + [System.Obsolete("Use new ChatSession(model) instead.", error: false)] public async Task GetChatClientAsync(CancellationToken? ct = null) { return await Utils.CallWithExceptionHandlingAsync( @@ -125,11 +126,14 @@ public async Task GetChatClientAsync(CancellationToken? ct = n throw new FoundryLocalException($"Model {Id} is not loaded. Call LoadAsync first."); } +#pragma warning disable CS0618 // OpenAIChatClient is obsolete return new OpenAIChatClient(Id, NativeModel); +#pragma warning restore CS0618 }, "Error getting chat client for model", _logger).ConfigureAwait(false); } + [System.Obsolete("Use new AudioSession(model) instead.", error: false)] public async Task GetAudioClientAsync(CancellationToken? ct = null) { return await Utils.CallWithExceptionHandlingAsync( @@ -140,11 +144,14 @@ public async Task GetAudioClientAsync(CancellationToken? ct = throw new FoundryLocalException($"Model {Id} is not loaded. Call LoadAsync first."); } +#pragma warning disable CS0618 // OpenAIAudioClient is obsolete return new OpenAIAudioClient(Id, NativeModel); +#pragma warning restore CS0618 }, "Error getting audio client for model", _logger).ConfigureAwait(false); } + [System.Obsolete("Use new EmbeddingsSession(model) instead.", error: false)] public async Task GetEmbeddingClientAsync(CancellationToken? ct = null) { return await Utils.CallWithExceptionHandlingAsync( @@ -155,7 +162,9 @@ public async Task GetEmbeddingClientAsync(CancellationTok throw new FoundryLocalException($"Model {Id} is not loaded. Call LoadAsync first."); } +#pragma warning disable CS0618 // OpenAIEmbeddingClient is obsolete return new OpenAIEmbeddingClient(Id, NativeModel); +#pragma warning restore CS0618 }, "Error getting embedding client for model", _logger).ConfigureAwait(false); } diff --git a/sdk_v2/cs/src/IModel.cs b/sdk_v2/cs/src/IModel.cs index 40e926f5d..7ea76b487 100644 --- a/sdk_v2/cs/src/IModel.cs +++ b/sdk_v2/cs/src/IModel.cs @@ -61,6 +61,7 @@ Task DownloadAsync(Action? downloadProgress = null, /// /// Optional cancellation token. /// OpenAI.ChatClient + [System.Obsolete("Use new ChatSession(model) instead.", error: false)] Task GetChatClientAsync(CancellationToken? ct = null); /// @@ -68,6 +69,7 @@ Task DownloadAsync(Action? downloadProgress = null, /// /// Optional cancellation token. /// OpenAI.AudioClient + [System.Obsolete("Use new AudioSession(model) instead.", error: false)] Task GetAudioClientAsync(CancellationToken? ct = null); /// @@ -75,6 +77,7 @@ Task DownloadAsync(Action? downloadProgress = null, /// /// Optional cancellation token. /// OpenAI.EmbeddingClient + [System.Obsolete("Use new EmbeddingsSession(model) instead.", error: false)] Task GetEmbeddingClientAsync(CancellationToken? ct = null); /// diff --git a/sdk_v2/cs/src/OpenAI/AudioClient.cs b/sdk_v2/cs/src/OpenAI/AudioClient.cs index ebfdcdf54..6f3e5ac26 100644 --- a/sdk_v2/cs/src/OpenAI/AudioClient.cs +++ b/sdk_v2/cs/src/OpenAI/AudioClient.cs @@ -20,6 +20,7 @@ namespace Microsoft.AI.Foundry.Local; /// Audio Client that uses the OpenAI API. /// Implemented using Betalgo.Ranul.OpenAI SDK types. /// +[System.Obsolete("OpenAIAudioClient is deprecated. Use AudioSession instead. OpenAI types remain supported for the web-server path.", error: false)] public class OpenAIAudioClient { private readonly string _modelId; diff --git a/sdk_v2/cs/src/OpenAI/AudioTranscriptionRequestResponseTypes.cs b/sdk_v2/cs/src/OpenAI/AudioTranscriptionRequestResponseTypes.cs index 66c8d0d33..30931a844 100644 --- a/sdk_v2/cs/src/OpenAI/AudioTranscriptionRequestResponseTypes.cs +++ b/sdk_v2/cs/src/OpenAI/AudioTranscriptionRequestResponseTypes.cs @@ -22,7 +22,9 @@ internal record AudioTranscriptionCreateRequestExtended : AudioCreateTranscripti { internal static AudioTranscriptionCreateRequestExtended FromUserInput(string modelId, string audioFilePath, +#pragma warning disable CS0618 // OpenAIAudioClient is obsolete OpenAIAudioClient.AudioSettings settings) +#pragma warning restore CS0618 { return new AudioTranscriptionCreateRequestExtended { diff --git a/sdk_v2/cs/src/OpenAI/ChatClient.cs b/sdk_v2/cs/src/OpenAI/ChatClient.cs index b30ded2b0..a21a5706d 100644 --- a/sdk_v2/cs/src/OpenAI/ChatClient.cs +++ b/sdk_v2/cs/src/OpenAI/ChatClient.cs @@ -25,6 +25,7 @@ namespace Microsoft.AI.Foundry.Local; /// Chat Client that uses the OpenAI API. /// Implemented using Betalgo.Ranul.OpenAI SDK types. /// +[System.Obsolete("OpenAIChatClient is deprecated. Use ChatSession instead. OpenAI types remain supported for the web-server path.", error: false)] public class OpenAIChatClient { private readonly string _modelId; diff --git a/sdk_v2/cs/src/OpenAI/ChatCompletionRequestResponseTypes.cs b/sdk_v2/cs/src/OpenAI/ChatCompletionRequestResponseTypes.cs index ffcf8638f..ae711762a 100644 --- a/sdk_v2/cs/src/OpenAI/ChatCompletionRequestResponseTypes.cs +++ b/sdk_v2/cs/src/OpenAI/ChatCompletionRequestResponseTypes.cs @@ -36,7 +36,9 @@ internal class ChatCompletionCreateRequestExtended : ChatCompletionCreateRequest internal static ChatCompletionCreateRequestExtended FromUserInput(string modelId, IEnumerable messages, IEnumerable? tools, +#pragma warning disable CS0618 // OpenAIChatClient is obsolete OpenAIChatClient.ChatSettings settings, +#pragma warning restore CS0618 bool stream) { var request = new ChatCompletionCreateRequestExtended diff --git a/sdk_v2/cs/src/OpenAI/EmbeddingClient.cs b/sdk_v2/cs/src/OpenAI/EmbeddingClient.cs index 009ed25e4..bef445db2 100644 --- a/sdk_v2/cs/src/OpenAI/EmbeddingClient.cs +++ b/sdk_v2/cs/src/OpenAI/EmbeddingClient.cs @@ -18,6 +18,7 @@ namespace Microsoft.AI.Foundry.Local; /// Embedding Client that uses the OpenAI API. /// Implemented using Betalgo.Ranul.OpenAI SDK types. /// +[System.Obsolete("OpenAIEmbeddingClient is deprecated. Use EmbeddingsSession instead. OpenAI types remain supported for the web-server path.", error: false)] public class OpenAIEmbeddingClient { private readonly string _modelId; diff --git a/sdk_v2/cs/src/OpenAI/LiveAudioTranscriptionClient.cs b/sdk_v2/cs/src/OpenAI/LiveAudioTranscriptionClient.cs index e55d710bf..ed02fafe7 100644 --- a/sdk_v2/cs/src/OpenAI/LiveAudioTranscriptionClient.cs +++ b/sdk_v2/cs/src/OpenAI/LiveAudioTranscriptionClient.cs @@ -26,6 +26,7 @@ namespace Microsoft.AI.Foundry.Local.OpenAI; /// Push PCM audio chunks via and consume transcription results /// via . /// +[System.Obsolete("LiveAudioTranscriptionSession is deprecated. Use AudioSession streaming instead. OpenAI types remain supported for the web-server path.", error: false)] public sealed class LiveAudioTranscriptionSession : IAsyncDisposable { private enum SessionState { Created, Started, Stopped, Disposed } diff --git a/sdk_v2/js/src/index.ts b/sdk_v2/js/src/index.ts index f3fc82617..35ca709f4 100644 --- a/sdk_v2/js/src/index.ts +++ b/sdk_v2/js/src/index.ts @@ -18,9 +18,13 @@ export type { ToolChoice, } from "./types.js"; +/** @deprecated Use ChatSession instead. OpenAI types remain supported for the web-server path. */ export { ChatClient, ChatClientSettings } from "./openai/chatClient.js"; +/** @deprecated Use AudioSession instead. OpenAI types remain supported for the web-server path. */ export { AudioClient, AudioClientSettings } from "./openai/audioClient.js"; +/** @deprecated Use EmbeddingsSession instead. OpenAI types remain supported for the web-server path. */ export { EmbeddingClient } from "./openai/embeddingClient.js"; +/** @deprecated Use AudioSession streaming instead. OpenAI types remain supported for the web-server path. */ export { LiveAudioTranscriptionOptions, LiveAudioTranscriptionSession, diff --git a/sdk_v2/js/src/model.ts b/sdk_v2/js/src/model.ts index 3894ef8f9..e8cc8e912 100644 --- a/sdk_v2/js/src/model.ts +++ b/sdk_v2/js/src/model.ts @@ -178,14 +178,17 @@ export class Model implements IModel { this.#native.selectVariant(nativeVariant); } + /** @deprecated Use a `ChatSession` instead. The OpenAI direct client is deprecated. */ createChatClient(): ChatClient { return new ChatClient(this); } + /** @deprecated Use an `AudioSession` instead. The OpenAI direct client is deprecated. */ createAudioClient(): AudioClient { return new AudioClient(this); } + /** @deprecated Use an `EmbeddingsSession` instead. The OpenAI direct client is deprecated. */ createEmbeddingClient(): EmbeddingClient { return new EmbeddingClient(this); } diff --git a/sdk_v2/js/src/openai/audioClient.ts b/sdk_v2/js/src/openai/audioClient.ts index a1765b0ed..6732cd525 100644 --- a/sdk_v2/js/src/openai/audioClient.ts +++ b/sdk_v2/js/src/openai/audioClient.ts @@ -23,6 +23,10 @@ export class AudioClientSettings { } } +/** + * @deprecated The OpenAI direct client is deprecated. Use AudioSession instead. + * OpenAI types remain supported for the web-server path. + */ export class AudioClient { readonly #model: Model; #disposed = false; diff --git a/sdk_v2/js/src/openai/chatClient.ts b/sdk_v2/js/src/openai/chatClient.ts index 41979dc07..acea02c6c 100644 --- a/sdk_v2/js/src/openai/chatClient.ts +++ b/sdk_v2/js/src/openai/chatClient.ts @@ -64,6 +64,9 @@ export class ChatClientSettings { * {@link Model.createChatClient}. The underlying model must already be loaded — call `await model.load()` first. * Each `completeChat` / `completeStreamingChat` call constructs and disposes its own `ChatSession`, * matching the v1 SDK's stateless behaviour — no conversation state is retained on the client. + * + * @deprecated The OpenAI direct client is deprecated. Use ChatSession instead. + * OpenAI types remain supported for the web-server path. */ export class ChatClient { readonly #model: Model; diff --git a/sdk_v2/js/src/openai/embeddingClient.ts b/sdk_v2/js/src/openai/embeddingClient.ts index 2f2e0f845..38bc2961f 100644 --- a/sdk_v2/js/src/openai/embeddingClient.ts +++ b/sdk_v2/js/src/openai/embeddingClient.ts @@ -10,6 +10,10 @@ import { EmbeddingsSession } from "../session.js"; // biome-ignore lint/suspicious/noExplicitAny: OpenAI request/response objects are user-shaped JSON. type Json = any; +/** + * @deprecated The OpenAI direct client is deprecated. Use EmbeddingsSession instead. + * OpenAI types remain supported for the web-server path. + */ export class EmbeddingClient { readonly #model: Model; #disposed = false; diff --git a/sdk_v2/js/src/openai/liveAudioSession.ts b/sdk_v2/js/src/openai/liveAudioSession.ts index 3a4cf7d9d..99f3fd942 100644 --- a/sdk_v2/js/src/openai/liveAudioSession.ts +++ b/sdk_v2/js/src/openai/liveAudioSession.ts @@ -20,6 +20,10 @@ export class LiveAudioTranscriptionOptions { pushQueueCapacity = 100; } +/** + * @deprecated The OpenAI direct client is deprecated. Use AudioSession streaming instead. + * OpenAI types remain supported for the web-server path. + */ export class LiveAudioTranscriptionSession implements AsyncDisposable, Disposable { readonly #model: Model; public settings = new LiveAudioTranscriptionOptions(); diff --git a/sdk_v2/python/src/foundry_local_sdk/imodel.py b/sdk_v2/python/src/foundry_local_sdk/imodel.py index 1807515bb..ac5364f8b 100644 --- a/sdk_v2/python/src/foundry_local_sdk/imodel.py +++ b/sdk_v2/python/src/foundry_local_sdk/imodel.py @@ -7,6 +7,8 @@ from abc import ABC, abstractmethod from typing import TYPE_CHECKING, Callable +from typing_extensions import deprecated + from foundry_local_sdk.exception import FoundryLocalException from foundry_local_sdk.model_info import DeviceType, ModelInfo, Runtime @@ -106,15 +108,27 @@ def unload(self) -> None: @abstractmethod def get_chat_client(self) -> "ChatClient": - """Get an OpenAI API-compatible ChatClient.""" + """Get an OpenAI API-compatible ChatClient. + + .. deprecated:: + Use ``ChatSession`` instead. OpenAI types remain supported for the web-server path. + """ @abstractmethod def get_audio_client(self) -> "AudioClient": - """Get an OpenAI API-compatible AudioClient.""" + """Get an OpenAI API-compatible AudioClient. + + .. deprecated:: + Use ``AudioSession`` instead. OpenAI types remain supported for the web-server path. + """ @abstractmethod def get_embedding_client(self) -> "EmbeddingClient": - """Get an OpenAI API-compatible EmbeddingClient.""" + """Get an OpenAI API-compatible EmbeddingClient. + + .. deprecated:: + Use ``EmbeddingsSession`` instead. OpenAI types remain supported for the web-server path. + """ @property @abstractmethod @@ -400,14 +414,20 @@ def select_variant(self, variant: IModel) -> None: # OpenAI client factories # ------------------------------------------------------------------ + @deprecated("The OpenAI direct client is deprecated; use ChatSession. OpenAI types remain supported " + "for the web-server path.") def get_chat_client(self) -> "ChatClient": from foundry_local_sdk.openai.chat_client import ChatClient return ChatClient(self.info.id, self) + @deprecated("The OpenAI direct client is deprecated; use ChatSession. OpenAI types remain supported " + "for the web-server path.") def get_audio_client(self) -> "AudioClient": from foundry_local_sdk.openai.audio_client import AudioClient return AudioClient(self.info.id, self) + @deprecated("The OpenAI direct client is deprecated; use EmbeddingsSession. OpenAI types remain " + "supported for the web-server path.") def get_embedding_client(self) -> "EmbeddingClient": from foundry_local_sdk.openai.embedding_client import EmbeddingClient return EmbeddingClient(self.info.id, self) diff --git a/sdk_v2/python/src/foundry_local_sdk/openai/audio_client.py b/sdk_v2/python/src/foundry_local_sdk/openai/audio_client.py index be060c145..bcdce11e6 100644 --- a/sdk_v2/python/src/foundry_local_sdk/openai/audio_client.py +++ b/sdk_v2/python/src/foundry_local_sdk/openai/audio_client.py @@ -6,9 +6,12 @@ from __future__ import annotations import json +import warnings from dataclasses import dataclass from typing import TYPE_CHECKING, Generator +from typing_extensions import deprecated + if TYPE_CHECKING: from foundry_local_sdk.imodel import IModel from foundry_local_sdk.openai.live_audio_session import LiveAudioTranscriptionSession @@ -42,9 +45,18 @@ class AudioTranscriptionResponse: text: str +@deprecated( + "The OpenAI direct client is deprecated; use AudioSession. OpenAI types remain supported " + "for the web-server path." +) class AudioClient: """OpenAI-compatible audio transcription client backed by Foundry Local Core. + .. deprecated:: + The OpenAI direct client is deprecated; use + :class:`foundry_local_sdk.session.AudioSession`. OpenAI types remain + supported for the web-server path. + Each call creates a fresh native session (stateless — no session history). Supports non-streaming and streaming transcription of audio files. @@ -54,6 +66,12 @@ class AudioClient: """ def __init__(self, model_id: str, model: IModel) -> None: + warnings.warn( + "The OpenAI direct client is deprecated; use AudioSession. OpenAI types remain " + "supported for the web-server path.", + DeprecationWarning, + stacklevel=2, + ) self.model_id = model_id # Hold the IModel reference so the underlying native model pointer # cannot be released out from under us. diff --git a/sdk_v2/python/src/foundry_local_sdk/openai/chat_client.py b/sdk_v2/python/src/foundry_local_sdk/openai/chat_client.py index bcd7a9778..2ee4e7f12 100644 --- a/sdk_v2/python/src/foundry_local_sdk/openai/chat_client.py +++ b/sdk_v2/python/src/foundry_local_sdk/openai/chat_client.py @@ -6,11 +6,13 @@ from __future__ import annotations import json +import warnings from typing import TYPE_CHECKING, Any, Generator from openai.types.chat.chat_completion_message_param import ChatCompletionMessageParam from openai.types.chat import ChatCompletion from openai.types.chat.chat_completion_chunk import ChatCompletionChunk +from typing_extensions import deprecated if TYPE_CHECKING: from foundry_local_sdk.imodel import IModel @@ -115,9 +117,18 @@ def _validate_tool_choice(self, tool_choice: dict[str, Any] | None) -> None: raise ValueError(f'ToolChoice with type "{choice_type}" should not have a name property.') +@deprecated( + "The OpenAI direct client is deprecated; use ChatSession. OpenAI types remain supported " + "for the web-server path." +) class ChatClient: """OpenAI-compatible chat completions client backed by Foundry Local Core. + .. deprecated:: + The OpenAI direct client is deprecated; use + :class:`foundry_local_sdk.session.ChatSession`. OpenAI types remain + supported for the web-server path. + Each call creates a fresh native session (stateless — no turn history). Supports non-streaming and streaming completions with optional tool calling. @@ -127,6 +138,12 @@ class ChatClient: """ def __init__(self, model_id: str, model: IModel) -> None: + warnings.warn( + "The OpenAI direct client is deprecated; use ChatSession. OpenAI types remain " + "supported for the web-server path.", + DeprecationWarning, + stacklevel=2, + ) self.model_id = model_id # Hold the IModel reference so the underlying native model pointer # cannot be released out from under us. diff --git a/sdk_v2/python/src/foundry_local_sdk/openai/embedding_client.py b/sdk_v2/python/src/foundry_local_sdk/openai/embedding_client.py index 49d992052..3c91aa7cc 100644 --- a/sdk_v2/python/src/foundry_local_sdk/openai/embedding_client.py +++ b/sdk_v2/python/src/foundry_local_sdk/openai/embedding_client.py @@ -6,17 +6,28 @@ from __future__ import annotations import json +import warnings from typing import TYPE_CHECKING from openai.types import CreateEmbeddingResponse +from typing_extensions import deprecated if TYPE_CHECKING: from foundry_local_sdk.imodel import IModel +@deprecated( + "The OpenAI direct client is deprecated; use EmbeddingsSession. OpenAI types remain supported " + "for the web-server path." +) class EmbeddingClient: """OpenAI-compatible embedding client backed by Foundry Local Core. + .. deprecated:: + The OpenAI direct client is deprecated; use + :class:`foundry_local_sdk.session.EmbeddingsSession`. OpenAI types + remain supported for the web-server path. + Each call creates a fresh native session (stateless — no session history). Attributes: @@ -24,6 +35,12 @@ class EmbeddingClient: """ def __init__(self, model_id: str, model: IModel) -> None: + warnings.warn( + "The OpenAI direct client is deprecated; use EmbeddingsSession. OpenAI types remain " + "supported for the web-server path.", + DeprecationWarning, + stacklevel=2, + ) self.model_id = model_id # Hold the IModel reference so the underlying native model pointer # cannot be released out from under us. diff --git a/sdk_v2/python/src/foundry_local_sdk/openai/live_audio_session.py b/sdk_v2/python/src/foundry_local_sdk/openai/live_audio_session.py index 216bbb030..7ed1cff53 100644 --- a/sdk_v2/python/src/foundry_local_sdk/openai/live_audio_session.py +++ b/sdk_v2/python/src/foundry_local_sdk/openai/live_audio_session.py @@ -35,9 +35,12 @@ import queue import threading +import warnings from enum import IntEnum from typing import TYPE_CHECKING, Iterator +from typing_extensions import deprecated + from foundry_local_sdk.exception import FoundryLocalException from foundry_local_sdk.openai.live_audio_types import ( LiveAudioTranscriptionOptions, @@ -68,9 +71,18 @@ class _State(IntEnum): DISPOSED = 3 +@deprecated( + "The OpenAI direct client is deprecated; use AudioSession. OpenAI types remain supported " + "for the web-server path." +) class LiveAudioTranscriptionSession: """Session for real-time audio streaming ASR (Automatic Speech Recognition). + .. deprecated:: + The OpenAI direct client is deprecated; use + :class:`foundry_local_sdk.session.AudioSession` for streaming + transcription. OpenAI types remain supported for the web-server path. + Audio data from a microphone (or other source) is pushed in as PCM chunks via :meth:`append`, and transcription results are returned as a synchronous iterator via :meth:`get_stream`. @@ -107,6 +119,12 @@ class LiveAudioTranscriptionSession: """ def __init__(self, model_id: str, model: "IModel") -> None: + warnings.warn( + "The OpenAI direct client is deprecated; use AudioSession. OpenAI types remain " + "supported for the web-server path.", + DeprecationWarning, + stacklevel=2, + ) self.model_id = model_id # Hold the IModel reference so the underlying native model pointer # cannot be released out from under us while this session is alive.