diff --git a/dotnet/docs/OPENAI-CONNECTOR-MIGRATION.md b/dotnet/docs/OPENAI-CONNECTOR-MIGRATION.md
index 00cf243fc193..7393de26ca58 100644
--- a/dotnet/docs/OPENAI-CONNECTOR-MIGRATION.md
+++ b/dotnet/docs/OPENAI-CONNECTOR-MIGRATION.md
@@ -73,6 +73,22 @@ We have the two only specific cases where we attempted to auto-correct the endpo
+ http://any-host-and-port/v1
```
+### 5.1 OpenAI-Compatible Endpoints Example (e.g., PZERO)
+
+When connecting to third-party OpenAI-compatible endpoints such as PZERO (`https://api.pzero.studio/v1`), provide the `/v1` root endpoint, API key, and model ID:
+
+```csharp
+using Microsoft.SemanticKernel;
+
+var builder = Kernel.CreateBuilder();
+builder.AddOpenAIChatCompletion(
+ modelId: "deepseek-v4-flash",
+ endpoint: new Uri("https://api.pzero.studio/v1"),
+ apiKey: Environment.GetEnvironmentVariable("PZERO_API_KEY")!
+);
+var kernel = builder.Build();
+```
+
## 6. SemanticKernel MetaPackage
To be retro compatible with the new OpenAI and AzureOpenAI Connectors, our `Microsoft.SemanticKernel` meta package changed its dependency to use the new `Microsoft.SemanticKernel.Connectors.AzureOpenAI` package that depends on the `Microsoft.SemanticKernel.Connectors.OpenAI` package. This way if you are using the metapackage, no change is needed to get access to `Azure` related types.
@@ -181,15 +197,14 @@ The type also changed from `CompletionsUsage` to `ChatTokenUsage`.
```diff
- Before
- var usage = FunctionResult.Metadata?["Usage"] as CompletionsUsage;
-- var completionTokesn = usage?.CompletionTokens ?? 0;
+- var completionTokens = usage?.CompletionTokens ?? 0;
- var promptTokens = usage?.PromptTokens ?? 0;
+ After
+ var usage = FunctionResult.Metadata?["Usage"] as ChatTokenUsage;
+ var promptTokens = usage?.InputTokens ?? 0;
-+ var completionTokens = completionTokens: usage?.OutputTokens ?? 0;
-
-totalTokens: usage?.TotalTokens ?? 0;
++ var completionTokens = usage?.OutputTokens ?? 0;
++ var totalTokens = usage?.TotalTokens ?? 0;
```
#### 9.9 OpenAIClient
diff --git a/dotnet/samples/Concepts/ChatCompletion/PZero_ChatCompletion.cs b/dotnet/samples/Concepts/ChatCompletion/PZero_ChatCompletion.cs
new file mode 100644
index 000000000000..8661b0dd8126
--- /dev/null
+++ b/dotnet/samples/Concepts/ChatCompletion/PZero_ChatCompletion.cs
@@ -0,0 +1,92 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+using Microsoft.SemanticKernel;
+using Microsoft.SemanticKernel.ChatCompletion;
+using Microsoft.SemanticKernel.Connectors.OpenAI;
+
+namespace ChatCompletion;
+
+///
+/// This example shows how to use the OpenAI connector with PZERO's OpenAI-compatible endpoint.
+///
+/// - Get a key from https://pzero.studio/agents
+/// - Set the environment variable PZERO_API_KEY with your key
+/// - Configure the endpoint to https://api.pzero.studio/v1
+/// - Run the example
+///
+///
+public class PZero_ChatCompletion(ITestOutputHelper output) : BaseTest(output)
+{
+ ///
+ /// This example shows how to configure PZERO OpenAI-compatible endpoint with Kernel InvokeAsync.
+ ///
+ [Fact]
+ public async Task UsingKernelWithPZero()
+ {
+ Console.WriteLine($"======== PZERO - Chat Completion - {nameof(UsingKernelWithPZero)} ========");
+
+ var apiKey = Environment.GetEnvironmentVariable("PZERO_API_KEY");
+ if (string.IsNullOrEmpty(apiKey))
+ {
+ Console.WriteLine("PZERO_API_KEY environment variable is not set. Skipping execution.");
+ return;
+ }
+
+ var modelId = "deepseek-v4-flash";
+ var endpoint = new Uri("https://api.pzero.studio/v1");
+
+ var kernel = Kernel.CreateBuilder()
+ .AddOpenAIChatCompletion(
+ modelId: modelId,
+ endpoint: endpoint,
+ apiKey: apiKey)
+ .Build();
+
+ var prompt = @"Rewrite the text between triple backticks into a business email. Use a professional tone, be clear and concise.
+ Sign the email as AI Assistant.
+
+ Text: ```{{$input}}```";
+
+ var mailFunction = kernel.CreateFunctionFromPrompt(prompt, new OpenAIPromptExecutionSettings
+ {
+ TopP = 0.5,
+ MaxTokens = 1000,
+ });
+
+ var response = await kernel.InvokeAsync(mailFunction, new() { ["input"] = "Tell David that I will complete the report by Friday." });
+ Console.WriteLine(response);
+ }
+
+ ///
+ /// Sample showing how to use directly with a against PZERO.
+ ///
+ [Fact]
+ public async Task UsingServiceNonStreamingWithPZero()
+ {
+ Console.WriteLine($"======== PZERO - Chat Completion - {nameof(UsingServiceNonStreamingWithPZero)} ========");
+
+ var apiKey = Environment.GetEnvironmentVariable("PZERO_API_KEY");
+ if (string.IsNullOrEmpty(apiKey))
+ {
+ Console.WriteLine("PZERO_API_KEY environment variable is not set. Skipping execution.");
+ return;
+ }
+
+ var modelId = "deepseek-v4-flash";
+ var endpoint = new Uri("https://api.pzero.studio/v1");
+
+ OpenAIChatCompletionService chatService = new(modelId: modelId, endpoint: endpoint, apiKey: apiKey);
+
+ Console.WriteLine("Chat content:");
+ Console.WriteLine("------------------------");
+
+ var chatHistory = new ChatHistory("You are a helpful assistant.");
+
+ chatHistory.AddUserMessage("Hello! Can you summarize the purpose of Semantic Kernel in one sentence?");
+ this.OutputLastMessage(chatHistory);
+
+ var reply = await chatService.GetChatMessageContentAsync(chatHistory);
+ chatHistory.Add(reply);
+ this.OutputLastMessage(chatHistory);
+ }
+}
diff --git a/dotnet/samples/Concepts/README.md b/dotnet/samples/Concepts/README.md
index 77fe10e7a8ab..1241f0a5f235 100644
--- a/dotnet/samples/Concepts/README.md
+++ b/dotnet/samples/Concepts/README.md
@@ -97,6 +97,7 @@ dotnet test -l "console;verbosity=detailed" --filter "FullyQualifiedName=ChatCom
- [OpenAI_RepeatedFunctionCalling](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/ChatCompletion/OpenAI_RepeatedFunctionCalling.cs)
- [OpenAI_StructuredOutputs](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/ChatCompletion/OpenAI_StructuredOutputs.cs)
- [OpenAI_UsingLogitBias](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/ChatCompletion/OpenAI_UsingLogitBias.cs)
+- [PZero_ChatCompletion](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Concepts/ChatCompletion/PZero_ChatCompletion.cs)
### DependencyInjection - Examples on using `DI Container`
diff --git a/python/samples/concepts/chat_completion/pzero_chat_completion.py b/python/samples/concepts/chat_completion/pzero_chat_completion.py
new file mode 100644
index 000000000000..7962ba3bc970
--- /dev/null
+++ b/python/samples/concepts/chat_completion/pzero_chat_completion.py
@@ -0,0 +1,59 @@
+# Copyright (c) Microsoft. All rights reserved.
+
+import asyncio
+import os
+
+from openai import AsyncOpenAI
+
+from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
+from semantic_kernel.contents.chat_history import ChatHistory
+from semantic_kernel.functions.kernel_arguments import KernelArguments
+from semantic_kernel.kernel import Kernel
+
+# This concept sample shows how to use the OpenAI connector with PZERO's
+# OpenAI-compatible endpoint: https://api.pzero.studio/v1
+# Get an API key from https://pzero.studio/agents and set PZERO_API_KEY.
+
+system_message = """
+You are a helpful and concise AI assistant.
+"""
+
+kernel = Kernel()
+
+service_id = "pzero-deepseek"
+
+api_key = os.environ.get("PZERO_API_KEY", "your-pzero-api-key")
+endpoint = "https://api.pzero.studio/v1"
+model_id = "deepseek-v4-flash"
+
+open_ai_client: AsyncOpenAI = AsyncOpenAI(
+ api_key=api_key,
+ base_url=endpoint,
+)
+kernel.add_service(OpenAIChatCompletion(service_id=service_id, ai_model_id=model_id, async_client=open_ai_client))
+
+settings = kernel.get_prompt_execution_settings_from_service_id(service_id)
+settings.max_tokens = 1000
+settings.temperature = 0.7
+
+chat_function = kernel.add_function(
+ plugin_name="ChatBot",
+ function_name="Chat",
+ prompt="{{$chat_history}}{{$user_input}}",
+ template_format="semantic-kernel",
+ prompt_execution_settings=settings,
+)
+
+
+async def main() -> None:
+ chat_history = ChatHistory(system_message=system_message)
+ user_message = "What is Semantic Kernel in one sentence?"
+ chat_history.add_user_message(user_message)
+
+ answer = await kernel.invoke(chat_function, KernelArguments(user_input=user_message, chat_history=chat_history))
+ print(f"User:> {user_message}")
+ print(f"Assistant:> {answer}")
+
+
+if __name__ == "__main__":
+ asyncio.run(main())