### Minimal Example: Thread, Turn, and Streaming Deltas Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md Demonstrates starting a Codex client, initiating a thread with workspace write access, starting a turn with text input, and processing streaming agent message deltas. Ensure the Codex CLI and .NET SDK are installed. ```csharp using JKToolKit.CodexSDK.AppServer; using JKToolKit.CodexSDK.AppServer.Notifications; using JKToolKit.CodexSDK.Models; await using var codex = await CodexAppServerClient.StartAsync(new CodexAppServerClientOptions { DefaultClientInfo = new("my_app", "My App", "1.0.0") }); var thread = await codex.StartThreadAsync(new ThreadStartOptions { Cwd = "", Model = CodexModel.Gpt53Codex, ApprovalPolicy = CodexApprovalPolicy.Never, Sandbox = CodexSandboxMode.WorkspaceWrite }); await using var turn = await codex.StartTurnAsync(thread.Id, new TurnStartOptions { Input = [TurnInputItem.Text("Summarize this repo.")] }); await foreach (var e in turn.Events()) { if (e is AgentMessageDeltaNotification d) Console.Write(d.Delta); } var completed = await turn.Completion; Console.WriteLine($ ``` ```csharp Done: {completed.Status} ``` -------------------------------- ### Example Usage of CodexSdk Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/002-sdk-facade/spec.md Demonstrates how to create and use the CodexSdk, configure its facades, start a session, and interact with the AppServer and McpServer. Requires appropriate using directives. ```csharp using JKToolKit.CodexSDK; using JKToolKit.CodexSDK.Exec; using JKToolKit.CodexSDK.Exec.Protocol; using JKToolKit.CodexSDK.Models; await using var sdk = CodexSdk.Create(b => { b.ConfigureExec(o => o.SessionsRootDirectory = ""); b.ConfigureAppServer(o => o.DefaultClientInfo = new("my_app", "My App", "1.0")); }); await using var session = await sdk.Exec.StartSessionAsync( new CodexSessionOptions("", "Summarize this repo") { Model = CodexModel.Gpt52Codex, ReasoningEffort = CodexReasoningEffort.Medium }); await foreach (var evt in session.GetEventsAsync(EventStreamOptions.Default)) { // ... } await using var app = await sdk.AppServer.StartAsync(); await using var mcp = await sdk.McpServer.StartAsync(); ``` -------------------------------- ### Start SSH App Server with Password Authentication Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md Configures SSH app server launch with password authentication. Requires 'sshpass' to be installed and the password to be provided. ```csharp Launch = CodexLaunchRemote.SshAppServer(new CodexSshAppServerOptions { Host = "devbox", Username = "codex", Password = "" }); ``` -------------------------------- ### Start App-Server Client Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Unification/Outline.md The AppServer client can be started using its dedicated class, maintaining the same API and namespace. ```csharp await using var codex = await CodexAppServerClient.StartAsync(new CodexAppServerClientOptions()); ... ``` -------------------------------- ### Start App Server Client with Endpoint Configuration Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md An alternative method to start the App Server client using endpoint-based configuration, suitable when direct endpoint details are available. ```csharp await using var codex = await CodexAppServerClient.StartAsync(new CodexAppServerClientOptions { Endpoint = new CodexAppServerWebSocketEndpoint(new Uri("ws://127.0.0.1:4500")) }); ``` -------------------------------- ### Install Agent Framework Adapter Package Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AgentFramework.md Install the adapter package using the .NET CLI. This package depends on several other core packages. ```bash dotnet add package JKToolKit.CodexSDK.AgentFramework ``` -------------------------------- ### Basic MCP Server Client Usage Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/McpServer/README.md Demonstrates how to start the MCP server client, list available tools, start a new session with Codex, and follow up with a reply. Requires necessary using statements for the SDK and models. ```csharp using JKToolKit.CodexSDK.McpServer; using JKToolKit.CodexSDK.Models; await using var codex = await CodexMcpServerClient.StartAsync(new CodexMcpServerClientOptions()); var tools = await codex.ListToolsAsync(); var run = await codex.StartSessionAsync(new CodexMcpStartOptions { Prompt = "Run tests and summarize failures.", Cwd = "", Sandbox = CodexSandboxMode.WorkspaceWrite, ApprovalPolicy = CodexApprovalPolicy.Never }); Console.WriteLine(run.Text); var followUp = await codex.ReplyAsync(run.ThreadId, "Now propose fixes."); Console.WriteLine(followUp.Text); ``` -------------------------------- ### Start New Session and Stream Events Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/specs/001-codex-dotnet-wrapper/quickstart.md This C# code demonstrates how to start a new Codex session with specific options and stream events as they occur. Ensure the WorkingDirectory exists and the Codex CLI is installed and accessible. ```csharp using System.Threading; using JKToolKit.CodexSDK.Exec; using JKToolKit.CodexSDK.Models; // Create client with defaults (uses PATH / default sessions root) await using var client = new CodexClient(); // Configure session var options = new CodexSessionOptions { WorkingDirectory = @"C:\Projects\MyRepo", // required, must exist Prompt = "Generate integration tests for the Countries controller", Model = CodexModel.Parse("gpt-5.1-codex"), ReasoningEffort = CodexReasoningEffort.Medium }; // Start session await using var session = await client.StartSessionAsync(options, CancellationToken.None); Console.WriteLine($"Session started: {session.Info.Id}"); // Stream events as they occur await foreach (var evt in session.GetEventsAsync(EventStreamOptions.Default, CancellationToken.None)) { switch (evt) { case UserMessageEvent userMsg: Console.WriteLine($"USER: {userMsg.Text}"); break; case AgentReasoningEvent reasoning: Console.WriteLine($"THINKING: {reasoning.Text}"); break; case AgentMessageEvent agentMsg: Console.WriteLine($"AGENT: {agentMsg.Text}"); break; case TokenCountEvent tokens: Console.WriteLine($"Tokens - In: {tokens.InputTokens}, Out: {tokens.OutputTokens}"); break; } } ``` -------------------------------- ### Start a Codex Session with Options Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Initial/Plan.md Use ICodexClient to start a new Codex session. Configure session parameters like repository root, prompt, model, and reasoning effort. Additional options can be passed via AdditionalOptions. ```csharp var sessionOptions = new CodexSessionOptions { RepoRoot = repoRoot, Prompt = prompt, Model = settings.CheapModel ? "gpt-5.1-codex-mini" : settings.Model, ReasoningEffort = ReasoningEffort.Medium, AdditionalOptions = settings.ParseCodexOptions() }; await using var session = await _codexClient.StartSessionAsync(sessionOptions, ct); ``` -------------------------------- ### Start SSH App Server with Explicit Options Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md Starts an SSH app server with explicit configuration options, including identity file, username, and port. Useful for non-default SSH configurations. ```csharp await using var keyedSsh = await CodexAppServerClient.StartAsync(new CodexAppServerClientOptions { Launch = CodexLaunchRemote.SshAppServer(new CodexSshAppServerOptions { Host = "codex-devbox", // Host alias or real host ConfigFile = "/home/me/.ssh/config", // Optional: ssh -F IdentityFile = "/home/me/.ssh/codex", // Optional: ssh -i Username = "codex", // Optional: ssh -l Port = 2222, // Optional: ssh -p RemoteWorkingDirectory = "/workspace" }) }); ``` -------------------------------- ### Install Semantic Kernel Adapter Package Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/SemanticKernel.md Install the adapter package into your project that owns Semantic Kernel plugins. ```bash dotnet add package JKToolKit.CodexSDK.SemanticKernel ``` -------------------------------- ### Start MCP Server Client Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Unification/Outline.md The MCP Server client can be started using its dedicated class, maintaining the same API and namespace. ```csharp await using var codex = await CodexMcpServerClient.StartAsync(new CodexMcpServerClientOptions()); ... ``` -------------------------------- ### Start Codex Session and Stream Events Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/exec.md Launches a Codex session, streams events, and handles different event types like agent messages, response items, and token counts. Requires setup of CodexClient and CodexSessionOptions. ```csharp using JKToolKit.CodexSDK.Exec; using JKToolKit.CodexSDK.Exec.Notifications; using JKToolKit.CodexSDK.Exec.Protocol; using JKToolKit.CodexSDK.Models; await using var client = new CodexClient(new CodexClientOptions()); var options = new CodexSessionOptions("", "Write a hello world program") { Model = CodexModel.Gpt53Codex, ReasoningEffort = CodexReasoningEffort.Medium }; await using var session = await client.StartSessionAsync(options); await foreach (var evt in session.GetEventsAsync(EventStreamOptions.Default)) { switch (evt) { case AgentMessageEvent msg: Console.WriteLine(msg.Text); break; case ResponseItemEvent item when item.Payload is MessageResponseItemPayload m: Console.WriteLine(string.Join("\n", m.TextParts)); break; case TokenCountEvent tokens: Console.WriteLine($"Tokens: {tokens.InputTokens} in, {tokens.OutputTokens} out"); break; } } ``` -------------------------------- ### ICodexProcessLauncher.StartAsync Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Initial/Plan.md Launches a new Codex process with the specified start information and cancellation token. It configures standard input, output, and error redirection, and disables shell execution for a cleaner process start. ```APIDOC ## ICodexProcessLauncher.StartAsync ### Description Launches a new Codex process with the specified start information and cancellation token. It configures standard input, output, and error redirection, and disables shell execution for a cleaner process start. ### Method Task<(Process Process, string? StdoutBuffer, string? StderrBuffer)> ### Endpoint N/A (SDK Method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response Returns a tuple containing the launched Process object, a string buffer for standard output, and a string buffer for standard error. #### Response Example None ``` -------------------------------- ### Start and interact with Codex App Server Client Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Extended/Spec.md Demonstrates how to start a session with the Codex App Server client, initiate a thread with specific options, and process agent messages asynchronously. Use this for deep integration scenarios within a .NET application. ```csharp await using var codex = await CodexAppServerClient.StartAsync(new() { Launch = CodexLaunch.CodexOnPath().WithArgs("app-server"), DefaultClientInfo = new("my_product", "My Product", "1.0.0"), }); var thread = await codex.StartThreadAsync(new ThreadStartOptions { Model = "gpt-5.1-codex", Cwd = repoPath, ApprovalPolicy = CodexApprovalPolicy.Never, }); await using var turn = await codex.StartTurnAsync(thread.Id, new TurnStartOptions { Input = [ TurnInputItem.Text("Summarize this repo.") ], }); await foreach (var e in turn.Events(ct)) { if (e is AgentMessageDeltaEvent d) Console.Write(d.Delta); } var completed = await turn.Completion; Console.WriteLine($"\nDone: {completed.Status}"); ``` -------------------------------- ### Add NCodexSDK Package Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Unification/Outline.md After integration, users install the unified SDK package using the dotnet CLI. ```bash dotnet add package NCodexSDK ``` -------------------------------- ### Start a New Codex Session Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Initial/Plan.md Initiates a new Codex session by launching a process, feeding it a prompt, and waiting for session metadata. Use this when starting a fresh interaction with Codex. ```csharp public async Task StartSessionAsync( CodexSessionOptions options, CancellationToken cancellationToken) { var startTime = DateTimeOffset.UtcNow; var startInfo = _startInfoBuilder.BuildExecuteStartInfo(options); var sessionFileTask = _sessionLocator.WaitForNewSessionFileAsync(startTime, cancellationToken); var (process, _, _) = await _processLauncher.StartAsync(startInfo, cancellationToken); // write prompt to stdin await process.StandardInput.WriteAsync(options.Prompt); await process.StandardInput.FlushAsync(); process.StandardInput.Close(); var logPath = await sessionFileTask; // read session_meta var meta = await GetSessionMetaAsync(logPath, cancellationToken); var info = new CodexSessionInfo( meta.SessionId, logPath, meta.Timestamp, options.RepoRoot, options.Model, humanLabel: null); return new CodexSessionHandle(info, process, _jsonlTailer, _eventParser, _options, _logger); } ``` -------------------------------- ### Start Remote App Server via SSH Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md Launches a remote app server using SSH. Use this when the SDK starts the app-server process but runs Codex work on another host. Do not allocate a TTY. ```csharp using JKToolKit.CodexSDK.AppServer; await using var ssh = await CodexAppServerClient.StartAsync(new CodexAppServerClientOptions { Launch = CodexLaunchRemote.SshAppServer( host: "devbox", remoteWorkingDirectory: "/home/me/project") }); ``` -------------------------------- ### StartSessionAsync Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Initial/Plan.md Starts a new Codex session. This method orchestrates the capture of timestamps, parallel initiation of session file waiting and process starting, building process start information, launching the Codex process, feeding the prompt to stdin, and waiting for session metadata. It returns a CodexSessionHandle containing information about the live session. ```APIDOC ## StartSessionAsync ### Description Starts a new Codex session by launching the Codex process, waiting for session metadata, and returning a handle to the active session. ### Method `CodexClient.StartSessionAsync` ### Parameters - **options** (`CodexSessionOptions`) - Required - Options for configuring the new session, including the prompt. - **cancellationToken** (`CancellationToken`) - Required - Token to monitor for cancellation requests. ### Request Example ```csharp // Assuming CodexClient and CodexSessionOptions are initialized var handle = await client.StartSessionAsync(sessionOptions, cancellationToken); ``` ### Response #### Success Response - **CodexSessionHandle** - An object containing information about the newly started session, including the live process, log path, and associated tools. ``` -------------------------------- ### Start and Attach to Docker WebSocket App Server Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AgentFramework.md Starts a detached Docker WebSocket app-server using a manager and attaches an agent to it. This allows for persistent remote app servers that can be managed independently. ```csharp using JKToolKit.CodexSDK.AgentFramework.Agents; using JKToolKit.CodexSDK.AgentFramework.Agents.Remote; using JKToolKit.CodexSDK.AppServer.Remote; using JKToolKit.CodexSDK.AppServer.Remote.Registry; using JKToolKit.CodexSDK.Models; using Microsoft.Agents.AI; var registry = new JsonFileCodexRemoteAppServerRegistry("codexsdk-appservers.json"); var manager = new CodexRemoteAppServerManager(registry); var entry = await manager.StartDockerContainerWebSocketAsync(new CodexDockerContainerWebSocketAppServerOptions { Image = "codex-dev", WorkingDirectory = "/workspace", CodexHome = "/home/codex/.codex", AdditionalDockerRunArguments = [ "-v", "/host/project:/workspace", "-v", "/host/.codex:/home/codex/.codex" ] }); AIAgent remoteAgent = new CodexAgentClient().AsAIAgent(new CodexAIAgentOptions { Model = "gpt-5.5", Cwd = "/workspace", ApprovalPolicy = CodexApprovalPolicy.Never, Instructions = "Work in the managed remote app-server.", RemoteAppServer = new CodexAgentRemoteAppServerOptions { Manager = manager, EntryId = entry.Id } }); Console.WriteLine(await remoteAgent.RunAsync("Run pwd and summarize the result.")); await manager.StopAsync(entry.Id, new CodexRemoteStopOptions { RemoveFromRegistry = true }); ``` -------------------------------- ### Start Resilient Codex App Server Client and a Thread Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md Illustrates how to resolve and start the resilient Codex App Server Client using a factory, and then initiate a new thread. This pattern is used when automatic restart capabilities are required. ```csharp var resilientFactory = sp.GetRequiredService(); await using var codex = await resilientFactory.StartAsync(); var thread = await codex.StartThreadAsync(new ThreadStartOptions { /* ... */ }); ``` -------------------------------- ### Install Semantic Kernel Core Package Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/SemanticKernel.md If your project does not already reference Semantic Kernel's core package, add it as well. ```bash dotnet add package Microsoft.SemanticKernel.Core --version 1.75.0 ``` -------------------------------- ### Install JKToolKit.CodexSDK Package Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/README.md Use this command to add the JKToolKit.CodexSDK package to your .NET project. ```bash dotnet add package JKToolKit.CodexSDK ``` -------------------------------- ### Check .NET SDK Version Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/README.md Verify that the installed .NET SDK version meets the repository's target requirement, which is .NET 10. ```bash dotnet --version ``` -------------------------------- ### Start Exec Session Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Unification/Outline.md The 'codex exec' pipeline remains unchanged and can be initiated with the CodexClient. ```csharp await using var client = new CodexClient(new CodexClientOptions()); await using var session = await client.StartSessionAsync(new CodexSessionOptions(repo, prompt)); await foreach (var e in session.GetEventsAsync()) { ... } ``` -------------------------------- ### Read Effective Merged Configuration Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md This example demonstrates how to read the effective merged configuration for a given directory, including layered project configurations. It shows how to access resolved MCP servers. ```csharp var cfg = await codex.ReadConfigAsync(new ConfigReadOptions { IncludeLayers = true, Cwd = "" }); // Effective MCP servers as resolved for that cwd (when present) var mcp = cfg.McpServers; ``` -------------------------------- ### Start a Code Review Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md Initiates a code review process for a specified thread and commit. The review can be delivered inline, and its completion can be awaited. ```csharp var review = await codex.StartReviewAsync(new ReviewStartOptions { ThreadId = thread.Id, Delivery = ReviewDelivery.Inline, Target = new ReviewTarget.Commit("1234567deadbeef", title: "Polish tui colors") }); await review.Turn.Completion; ``` -------------------------------- ### Manage MCP Servers on App Server Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md Provides examples for managing MCP servers, including listing their status, reloading configurations from disk, and initiating OAuth login flows for authentication. ```csharp // List configured MCP servers + tools/resources/auth status var status = await codex.ListMcpServerStatusAsync(new McpServerStatusListOptions()); // Reload MCP server config from disk and queue a refresh for loaded threads await codex.ReloadMcpServersAsync(); // Start an OAuth login flow for a configured server (completion arrives as a notification) var login = await codex.StartMcpServerOauthLoginAsync(new McpServerOauthLoginOptions { Name = "my-server" }); Console.WriteLine(login.AuthorizationUrl); ``` -------------------------------- ### DI Smoke Test with AddCodexSdk Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/DI-and-Overrides.md Perform a smoke test by registering the Codex SDK using `AddCodexSdk` and verifying that core components can start. Requires minimal logging registrations. ```csharp @' using JKToolKit.CodexSDK; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; var services = new ServiceCollection(); // Minimal logging registrations (the SDK depends on ILogger via DI) services.AddSingleton(NullLoggerFactory.Instance); services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)); services.AddCodexSdk(); // ServiceProvider must be disposed asynchronously because CodexSdk is IAsyncDisposable. await using var sp = services.BuildServiceProvider(); var sdk = sp.GetRequiredService(); // Just ensure all facades can start; keep it quick. using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(60)); await using var app = await sdk.AppServer.StartAsync(cts.Token); await using var mcp = await sdk.McpServer.StartAsync(cts.Token); Console.WriteLine("ok"); '@ | Set-Content .\Program.cs dotnet run ``` -------------------------------- ### Run Facade Routing Demo Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/Facade.md Execute the .NET demo project to test the SDK's review routing. This command includes a timeout of 600 seconds. ```powershell dotnet run --project src/JKToolKit.CodexSDK.Demo -- sdk-review-route --timeout-seconds 600 ``` -------------------------------- ### Create and Configure CodexSdk (Non-DI) Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/002-sdk-facade/quickstart.md Use `CodexSdk.Create` to instantiate the SDK once. Configure optional settings like the executable path and mode-specific options. This method supports starting sessions for Exec mode or servers for AppServer and McpServer modes. ```csharp using JKToolKit.CodexSDK; using JKToolKit.CodexSDK.Exec; using JKToolKit.CodexSDK.Models; await using var sdk = CodexSdk.Create(b => { // One place to set the Codex executable path (optional) b.CodexExecutablePath = ""; // Mode-specific config (optional) b.ConfigureExec(o => { o.SessionsRootDirectory = ""; }); b.ConfigureAppServer(o => { o.DefaultClientInfo = new("my_app", "My App", "1.0.0"); }); }); // Exec mode await using var session = await sdk.Exec.StartSessionAsync( new CodexSessionOptions("", "Summarize this repository") { Model = CodexModel.Gpt52Codex, ReasoningEffort = CodexReasoningEffort.Medium }); await foreach (var evt in session.GetEventsAsync(EventStreamOptions.Default)) { // ... } // AppServer mode await using var app = await sdk.AppServer.StartAsync(); // McpServer mode await using var mcp = await sdk.McpServer.StartAsync(); ``` -------------------------------- ### Install Codex CLI Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/README.md Ensure the Codex CLI is installed and accessible by checking its version. This is a prerequisite for using many SDK features. ```bash codex --version ``` -------------------------------- ### Thread Management: Start Thread Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/AppServer.md Starts a new thread with an initial turn. Copy the returned thread ID for subsequent thread operations. ```powershell dotnet run --project src/JKToolKit.CodexSDK.Demo -- appserver-thread start --seed "Say 'hi'." --timeout-seconds 60 ``` -------------------------------- ### Manual Alternative for Creating Test File Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/README.md Manually create a directory and a markdown file for a manual testing run. ```powershell New-Item -ItemType Directory -Force .tmp/manual_testing | Out-Null # Example run number: Set-Content .tmp/manual_testing/0001.md -Value "# Manual Testing Run 0001`n" ``` -------------------------------- ### Run Turn with Structured Output Schema Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md This example demonstrates how to run a turn with a specific JSON output schema and deserialize the response into a strongly-typed DTO. It's useful for ensuring strict output formats from the assistant. ```csharp using JKToolKit.CodexSDK.AppServer; using JKToolKit.CodexSDK.StructuredOutputs; public sealed record MyResult(string Answer); var thread = await codex.StartThreadAsync(new ThreadStartOptions { Cwd = "" }); var result = await codex.RunTurnStructuredAsync(thread.Id, new TurnStartOptions { Input = [TurnInputItem.Text("Return JSON only.")] }); Console.WriteLine(result.Value.Answer); ``` -------------------------------- ### Run JKToolKit.CodexSDK Demo Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/README.md Execute the demo project for JKToolKit.CodexSDK using this command. Replace "Your prompt here" with your desired prompt. ```bash dotnet run --project src/JKToolKit.CodexSDK.Demo -- "Your prompt here" ``` -------------------------------- ### Review/Start App Server Turn Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/AppServer.md Initiates a review process on the app server using a custom target for speed. Use this to quickly test review workflows. ```powershell dotnet run --project src/JKToolKit.CodexSDK.Demo -- appserver-review --target custom --instructions "Say 'ok' and nothing else." --timeout-seconds 60 ``` -------------------------------- ### App Server Client Demo Initialization Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Extended/Spec.md Demonstrates the basic steps for initializing and using the Codex App Server client in a console application. ```csharp start client, create thread, start turn, stream deltas, print final ``` -------------------------------- ### Initialize and Use Semantic Kernel with Codex SDK Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/SemanticKernel.md This C# code demonstrates initializing Semantic Kernel, creating an adapter for Codex dynamic tools, and starting a Codex SDK app server with the adapter's approval handler and dynamic tools. It then initiates a thread and a turn for processing user input. ```csharp using JKToolKit.CodexSDK; using JKToolKit.CodexSDK.AppServer; using JKToolKit.CodexSDK.Models; using JKToolKit.CodexSDK.SemanticKernel; using Microsoft.SemanticKernel; var kernelBuilder = Kernel.CreateBuilder(); kernelBuilder.Plugins.AddFromObject(new OrderPizzaPlugin(), "OrderPizza"); var kernel = kernelBuilder.Build(); var skTools = SemanticKernelCodexToolAdapter.Create(kernel); await using var sdk = CodexSdk.Create(builder => { builder.ConfigureAppServer(o => { o.ExperimentalApi = true; o.ApprovalHandler = skTools.ApprovalHandler; }); }); await using var codex = await sdk.AppServer.StartAsync(); var thread = await codex.StartThreadAsync(new ThreadStartOptions { Cwd = Environment.CurrentDirectory, Sandbox = CodexSandboxMode.ReadOnly, ApprovalPolicy = CodexApprovalPolicy.Never, DynamicTools = skTools.DynamicTools }); await using var turn = await codex.StartTurnAsync(thread.Id, new TurnStartOptions { Input = [TurnInputItem.Text("Order one large pepperoni pizza and checkout.")] }); ``` -------------------------------- ### Run JKToolKit.CodexSDK Demo App (App Server - Streaming) Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/README.md Launch the demo application in App Server mode with real-time delta notifications. This is suitable for rich IDE or product integrations. ```bash dotnet run --project src/JKToolKit.CodexSDK.Demo -- appserver-stream --repo "" ``` -------------------------------- ### Codex MCP Server Client API Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Extended/Spec.md Defines the public API for the Codex MCP Server client, including methods for starting the client, listing tools, starting sessions, replying, and calling tools. ```csharp public sealed class CodexMcpServerClient : IAsyncDisposable { public static Task StartAsync( CodexMcpServerClientOptions options, CancellationToken ct = default); public Task> ListToolsAsync(CancellationToken ct = default); public Task StartSessionAsync( CodexMcpStartOptions options, CancellationToken ct = default); public Task ReplyAsync( string threadId, string prompt, CancellationToken ct = default); // escape hatch public Task CallToolAsync(string toolName, object arguments, CancellationToken ct = default); } ``` -------------------------------- ### Build JKToolKit.CodexSDK from Source Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/specs/001-codex-dotnet-wrapper/quickstart.md Follow these steps to clone the repository and build the SDK from source. ```bash git clone https://github.com/yourorg/Codex-Dotnet.git cd Codex-Dotnet dotnet build src/JKToolKit.CodexSDK/JKToolKit.CodexSDK.csproj ``` -------------------------------- ### Initialize Codex Agent with Basic Tools Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AgentFramework.md Initializes a Codex agent with basic instructions and a tool for remembering project context. ```csharp AIAgent agent = new CodexAgentClient().AsAIAgent( instructions: "Remember useful project context.", tools: [AIFunctionFactory.Create(RememberTopic)]); ``` -------------------------------- ### MCP Server Client Demo Initialization Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Extended/Spec.md Demonstrates the basic steps for initializing and using the Codex MCP Server client in a console application. ```csharp list tools, run codex, extract threadId, run codex-reply ``` -------------------------------- ### Start and interact with Codex MCP Server Client Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Extended/Spec.md Shows how to initiate a session with the Codex MCP Server client and perform follow-up actions using reply. This pattern is suitable when using Codex as a tool within your application. ```csharp await using var codex = await CodexMcpServerClient.StartAsync(new() { Launch = CodexLaunch.CodexOnPath().WithArgs("mcp-server") }); var run = await codex.StartSessionAsync(new CodexMcpStartOptions { Prompt = "Run tests and summarize failures.", Sandbox = CodexSandboxMode.WorkspaceWrite, ApprovalPolicy = CodexApprovalPolicy.Never, Cwd = repoPath }); Console.WriteLine(run.Text); var followUp = await codex.ReplyAsync(run.ThreadId, "Now propose fixes."); Console.WriteLine(followUp.Text); ``` -------------------------------- ### Start Remote App Server via Docker Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AppServer/README.md Launches a remote app server within a Docker container. Use this when the SDK starts the app-server process but runs Codex work in a container on another host. Do not allocate a TTY. ```csharp using JKToolKit.CodexSDK.AppServer; await using var docker = await CodexAppServerClient.StartAsync(new CodexAppServerClientOptions { Launch = CodexLaunchRemote.DockerAppServer( container: "codex-dev", workingDirectory: "/workspace", codexHome: "/home/codex/.codex") }); ``` -------------------------------- ### Create and Manage Agent Sessions Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AgentFramework.md Demonstrates how to create, run, serialize, and deserialize agent sessions for multi-turn conversations. Sessions maintain conversation history and context across multiple agent interactions. ```csharp AgentSession session = await agent.CreateSessionAsync(); Console.WriteLine(await agent.RunAsync("My name is Alice.", session)); Console.WriteLine(await agent.RunAsync("What is my name?", session)); JsonElement serialized = await agent.SerializeSessionAsync(session); AgentSession resumed = await agent.DeserializeSessionAsync(serialized); ``` -------------------------------- ### App-server: Stream Deltas Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/README.md Starts streaming deltas from the app-server. Includes a timeout to prevent indefinite execution. ```powershell dotnet run --project src/JKToolKit.CodexSDK.Demo -- appserver-stream --timeout-seconds 60 ``` -------------------------------- ### ICodexClient Interface Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Initial/Plan.md Defines the contract for interacting with Codex sessions, including starting, resuming, attaching, and listing sessions. ```csharp public interface ICodexClient : IAsyncDisposable { Task StartSessionAsync( CodexSessionOptions options, CancellationToken cancellationToken = default); Task ResumeSessionAsync( string sessionId, CancellationToken cancellationToken = default); Task AttachToLogAsync( string logPath, CancellationToken cancellationToken = default); IAsyncEnumerable ListSessionsAsync( SessionFilter? filter = null, CancellationToken cancellationToken = default); } ``` -------------------------------- ### EventStreamOptions Record Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Initial/Plan.md Controls the starting point for reading event streams, allowing specification by timestamp or byte offset. ```csharp public sealed record EventStreamOptions { /// Start reading from the beginning of the file (default: true) public bool FromBeginning { get; init; } = true; /// If not from beginning, start after this timestamp or byte offset public DateTimeOffset? AfterTimestamp { get; init; } public long? FromByteOffset { get; init; } } ``` -------------------------------- ### Run JKToolKit.CodexSDK Demo App (MCP Server) Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/README.md Execute the demo application in MCP Server mode. This is designed for plugging Codex into MCP toolchains and managing tool discovery. ```bash dotnet run --project src/JKToolKit.CodexSDK.Demo -- mcpserver --repo "" ``` -------------------------------- ### Duplicate DI Registration in Public Extensions Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Unification/Followup.md Example of duplicated DI registration for core infrastructure services in ServiceCollectionExtensions.cs. ```csharp services.TryAddSingleton() services.TryAddSingleton() (and for server modes) StdioProcessFactory ``` -------------------------------- ### Duplicate Bootstrap Logic in AppServer Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Unification/Followup.md Example of duplicate bootstrap logic in CodexAppServerClient.cs. This logic is also present in McpServer. ```csharp RealFileSystem DefaultCodexPathProvider StdioProcessFactory JsonRpcConnection ``` -------------------------------- ### App Server Core Operations Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Extended/Spec.md Implementation of core operations for the app server client, including starting and interrupting turns. ```csharp Implement thread/start, turn/start, turn/interrupt ``` -------------------------------- ### Configure Agent with ChatClientAgentOptions Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AgentFramework.md Sets up an agent using Agent Framework's ChatClientAgentOptions, including model, name, description, chat options, and history provider. This is useful when integrating with existing Agent Framework configurations. ```csharp AIAgent agent = sdk.AsAIAgent( model: "gpt-5.5", options: new ChatClientAgentOptions { Name = "CodexAgent", Description = "Codex with Agent Framework tools.", ChatOptions = new ChatOptions { Instructions = "You are a helpful assistant.", Tools = [getWeather] }, ChatHistoryProvider = new InMemoryChatHistoryProvider() }); ``` -------------------------------- ### CodexMcpServerFacade Class Definition Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/002-sdk-facade/spec.md Defines the CodexMcpServerFacade, offering methods to start the Codex MCP server, with and without specific client options. ```csharp using System.Threading; using System.Threading.Tasks; using JKToolKit.CodexSDK.McpServer; public sealed class CodexMcpServerFacade { public Task StartAsync(CancellationToken ct = default); public Task StartAsync(CodexMcpServerClientOptions options, CancellationToken ct = default); } ``` -------------------------------- ### Create a Codex-backed Agent Framework Agent Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/AgentFramework.md Demonstrates how to create an AI agent backed by CodexSDK within the Agent Framework. It shows defining a function tool and configuring the Codex SDK. ```csharp using System.Text.Json; using JKToolKit.CodexSDK; using JKToolKit.CodexSDK.AgentFramework.Agents; using JKToolKit.CodexSDK.Models; using Microsoft.Agents.AI; using Microsoft.Extensions.AI; AIFunction getWeather = AIFunctionFactory.Create( (Func)(location => $"Weather in {location}: cloudy."), name: "get_weather", description: "Gets the weather for a location."); await using var sdk = CodexSdk.Create(builder => { builder.ConfigureAppServer(options => { options.CodexHomeDirectory = Environment.GetEnvironmentVariable("CODEX_HOME"); }); }); AIAgent agent = sdk .AsAIAgent( model: "gpt-5.5", instructions: "You are a helpful assistant.", tools: [getWeather]); Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?")); ``` -------------------------------- ### CodexAppServerFacade Class Definition Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/002-sdk-facade/spec.md Defines the CodexAppServerFacade, providing methods to start the Codex application server, with and without specific client options. ```csharp using System.Threading; using System.Threading.Tasks; using JKToolKit.CodexSDK.AppServer; public sealed class CodexAppServerFacade { public Task StartAsync(CancellationToken ct = default); public Task StartAsync(CodexAppServerClientOptions options, CancellationToken ct = default); } ``` -------------------------------- ### Run JKToolKit.CodexSDK Demo App (App Server - Approval) Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/README.md Execute the demo application in App Server mode, configuring a timeout for approval processes. This is useful for workflows requiring human-in-the-loop validation. ```bash dotnet run --project src/JKToolKit.CodexSDK.Demo -- appserver-approval --timeout-seconds 30 ``` -------------------------------- ### Run Exec Session and Follow Output Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Runbooks/Manual-Testing/Exec.md Executes a short prompt to start a session, streams events, and ensures graceful shutdown. Verifies session ID, log file, event streaming, and non-hanging process exit. ```powershell dotnet run --project src/JKToolKit.CodexSDK.Demo -- exec --prompt "Say 'ok' and nothing else." --reasoning low ``` -------------------------------- ### Codex CLI for New Session Source: https://github.com/jkamsker/jktoolkit.codexsdk/blob/master/docs/Tasks/Initial/Plan.md Command-line interface structure for starting a new Codex session, including repository root and model specification. ```text codex exec [additional options] --cd --model \ --config model_reasoning_effort= - ```