Skip to content

Releases: ylvict/NOpenCode

v0.3.2

Choose a tag to compare

@github-actions github-actions released this 11 Jun 02:59

v0.3.2

🔧 Maintenance

  • Removed dead code: NOpenCodeHttpClient.ReadSse() was unused — all SSE reading now goes through GetStream() + SseReader
  • Cleaned up ActiveServers stale entries: when TryReuseExisting finds a previously registered server that is no longer healthy, the stale entry is now removed from the static dictionary
  • Unified dependency versions: Microsoft.Extensions.Hosting.Abstractions bumped from 8.0.1 to 10.0.8 to match the rest of the dependency set
  • Removed unused import: System.Collections.Generic from NOpenCodeHttpClient.cs

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 11 Jun 02:47

v0.3.1

🔧 Bug Fixes & Quality Improvements

Linux/Unix CLI Discovery (ServerManager.cs)

  • FindCliViaWhere() renamed to FindCliViaWhich(): uses which on Linux/macOS and where on Windows. Fixes a latent bug where Linux systems fell back to CanRunDirectly() unnecessarily.

Logging Wired Up

  • ServerOptions.Log property added, populated from NOpenCodeBuilder.LogCallback
  • All previously empty catch { } blocks in ServerManager now log the exception via the callback:
    • FindNpmGlobalCli, FindCliViaWhich, CanRunDirectly, IsHealthy, DisposeAsync (instance dispose + kill), CleanupDataDir
  • ServerManager.Start() logs "Reusing existing..." / "Starting opencode serve..."

DI Deadlock Fix (ServiceCollectionExtensions.cs)

  • AddNOpenCode() now wraps builder.Launch() in Task.Run(...) to avoid ASP.NET Core sync context deadlock with .GetAwaiter().GetResult()

WithAutoServer() Documentation

  • Added XML doc explaining this is the default behavior; method exists for explicitness in builder chains

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 11 Jun 02:16

v0.3.0

🚀 New Features

True SSE Streaming for AskStream

OpenCodeSession.AskStream() and AskOperation.AskStream() now perform real SSE streaming instead of buffering the entire response.

  • Sends "stream": true in the request body to POST /session/{id}/message
  • Reads SSE events via SseReader from a response stream (ResponseHeadersRead)
  • event: chunk — each text part is deserialized and passed to onChunk in real time
  • event: complete — the final OpenCodeReply is deserialized and passed to onComplete
  • event: error — throws NOpenCodeException
  • New NOpenCodeHttpClient.PostStream() method added for POST with streaming response

CancellationToken Support

AskOperation.Execute() and AskOperation.ExecuteFull() now accept CancellationToken ct = default, propagated through session creation and message sending. Fully backward compatible.

File Attachments

  • Part model now includes [JsonPropertyName("uri")] property for file reference serialization
  • BuildMessageDict() generates type: "file" parts when MessageOptions.Files is specified
  • AskOperation.WithFiles() correctly forwards attachments to the session's Ask call via MessageOptions

McpClient Enhancements

  • Remove(string name, CancellationToken ct)DELETE /mcp/{name}
  • Update(string name, object config, CancellationToken ct)PATCH /mcp/{name}

Type-Safe ConfigClient.Update

  • Added Update(NOpenCodeConfig config, CancellationToken ct) overload with strong typing
  • The original Update(object patch, CancellationToken) overload remains for backward compatibility

🧪 Testing (24 new tests)

  • StreamingTests.cs (new) — 7 tests covering SseReader: chunk, complete, error, comment lines, multiple events, default type, empty stream
  • NewApiTests.cs (new) — 10 reflection-based API signature tests: CancellationToken overloads, WithFiles chaining, McpClient Remove/Update, ConfigClient typed overload, Part.Uri, MessageOptions.Files
  • ModelTests.cs (updated) — 3 tests for Part.Uri default value and property setter

🔧 Internal Improvements

  • NOpenCodeHttpClient.PostStream() — POST with HttpCompletionOption.ResponseHeadersRead for streaming response
  • OpenCodeSession.BuildMessageDict() — restructured to support file parts and "stream": true
  • InternalsVisibleTo added for NOpenCode.Tests to enable testing of internal types (SseReader, NOpenCodeHttpClient)
  • Added using System.IO / using System.Text.Json to OpenCodeSession.cs

v0.2.2

Choose a tag to compare

@github-actions github-actions released this 07 Jun 14:36

What's Changed

  • Bump Microsoft.Bcl.AsyncInterfaces and 2 others by @dependabot[bot] in #11
  • Bump Microsoft.NET.Test.Sdk from 17.14.1 to 18.6.0 by @dependabot[bot] in #10
  • Bump Microsoft.Bcl.AsyncInterfaces and 3 others by @dependabot[bot] in #9
  • Bump Microsoft.Extensions.Hosting from 8.0.1 to 10.0.8 by @dependabot[bot] in #8
  • Bump coverlet.collector from 6.0.4 to 10.0.1 by @dependabot[bot] in #5
  • chore(deps): bump github/codeql-action from 3 to 4 by @dependabot[bot] in #4
  • chore(deps): bump actions/setup-dotnet from 4 to 5 by @dependabot[bot] in #3
  • chore(deps): bump actions/checkout from 4 to 6 by @dependabot[bot] in #2
  • chore(deps): bump actions/setup-node from 4 to 6 by @dependabot[bot] in #1

New Contributors

Full Changelog: v0.2.1...v0.2.2

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 04 Jun 06:27

Changes

  • NOpenCodeBuilder.AnyFreeSelector is now public — consumers and tests filtering OpenCodeClient.Models can reuse the same predicate the SDK uses internally for WithAnyFreeModel() and the default Launch() selection. The -free suffix that defines "free tier" now lives in exactly one place.
  • Integration tests no longer hardcode provider ids or model suffixes — replaced "opencode" with Providers.OpenCode and the inline m.Id.EndsWith("-free") with NOpenCodeBuilder.AnyFreeSelector, so the tests stay in sync with the SDK.
  • Removed <NoWarn>CS0618</NoWarn> from integration test csproj — the test project no longer calls any obsolete API; all WithModel(string) usages have been migrated to the new WithModel(selector) overload.

v0.2.0 — Resilient model selection & new Providers API

Choose a tag to compare

@ylvict ylvict released this 04 Jun 06:02

Highlights

  • Resilient model selection by default. OpenCode.Configure().Launch() now auto-picks a free-tier model from the opencode provider at launch time, so your code no longer breaks when upstream renames or versions a model.
  • Capability-based model selection. Pick models by predicate (WithModel(selector)) or by free tier (WithAnyFreeModel(provider)) instead of hardcoding a stringly-typed model id.
  • New Providers constants class with 20 well-known upstream provider ids (Providers.OpenCode, Providers.Anthropic, Providers.OpenAI, ...), giving you IntelliSense and compile-time typo protection.

Breaking Changes for users upgrading from 0.1.x

WithModel(string) is now [Obsolete]

.WithModel("opencode/deepseek-v4-flash-free")  // CS0618 warning

The overload is kept for backward compatibility but emits a compile-time warning. Migration: drop the call entirely (the new default is already resilient), or switch to a capability-based overload:

.Launch()                                   // uses the default free-model selection
// or
.WithAnyFreeModel()                         // explicit free-tier, default provider
.WithAnyFreeModel(Providers.Anthropic)      // explicit free-tier, custom provider
.WithModel(m => m.Id.EndsWith("-free"))     // custom predicate

Default model at Launch() changed

If you previously called OpenCode.Configure().Launch() without specifying a model, the opencode server's default was used. As of 0.2.0 the SDK auto-picks the first free-tier model from the opencode provider. To restore the previous behaviour, pin a model explicitly with WithModel(...).

New Features

  • WithModel(Func<ModelInfo, bool> selector, string provider = Providers.OpenCode) — pick the first model from a provider that matches a caller-supplied predicate. Resolution happens at Launch() time via OpenCodeClient.Models.List().
  • WithAnyFreeModel(string provider = Providers.OpenCode) — convenience that resolves to the first model whose id ends with -free. Use it when you want to switch the free-model default to a non-opencode provider.
  • Providers constants classOpenCode, Anthropic, OpenAI, GitHubCopilot, GoogleVertex, AmazonBedrock, Azure, DeepSeek, Groq, OpenRouter, Ollama, LMStudio, Cerebras, Minimax, MoonshotAI, NVIDIA, HuggingFace, Helicone, VercelGateway, XAI. For providers not listed, pass the raw id as a string — the server is the source of truth and you can discover all currently connected providers via OpenCodeClient.Providers.List().

Bug Fixes

  • CI: dotnet test in ci.yml is now scoped to the unit-test project, so PR builds no longer fail on opencode-dependent integration tests. Integration tests run on a daily schedule and via workflow_dispatch.
  • Integration tests: opencode server is now started in the same step as the test run, so it survives the GitHub Actions step boundary that was killing it mid-test.
  • Models.List: removed a no-op ternary (provider != null ? "/config/providers" : "/config/providers") with identical branches and a meaningless $ interpolation.
  • Release workflow: gh release create now has contents: write so the GitHub release step no longer 403s.

Tooling & CI

  • New scheduled integration tests (daily) for NuGet package + free-model availability — surfaces upstream model churn before users do.
  • Added Dependabot, CodeQL, .editorconfig, .gitattributes.

Documentation

  • READMEs (EN + ZH) updated to drop hardcoded model ids and use Providers.OpenCode.
  • Fixed a pre-existing duplicate ### 多轮对话 section in README.zh.md.

Full diff: v0.1.3...v0.2.0

v0.1.3 — Initial Release

Choose a tag to compare

@ylvict ylvict released this 03 Jun 01:37

NOpenCode is a .NET SDK that brings OpenCode's AI engine into your application services. Express your intent in natural language — NOpenCode bridges your application logic with AI.

Features

  • Zero setup — auto-discovers or starts \opencode serve\ for you
  • Natural language API — plain-English interface for AI interactions
  • Multi-turn sessions — context-aware follow-up conversations
  • Streaming — receive AI responses chunk by chunk in real time
  • File & code search — ripgrep, filename lookup, symbol search
  • Session lifecycle — create, fork, share, diff, revert, summarize
  • Provider & model discovery — query available models, providers, agents
  • MCP server management — dynamically add and list MCP servers
  • Event monitoring — subscribe to SSE event streams
  • DI integration — \AddNOpenCode()\ for ASP.NET Core / console hosts
  • .NET Standard 2.0 — compatible with .NET Framework 4.6.1+ and all modern .NET

Getting Started

dotnet add package NOpenCode
using NOpenCode;

string answer = await OpenCode.Ask("What's the capital of France?");
Console.WriteLine(answer);

What's Changed in v0.1.3

✨ New

  • Initial NuGet publish (v0.1.0 → v0.1.3)
  • Full SDK with all clients and models
  • 10 example projects demonstrating every API feature
  • Examples CI workflow — builds and runs all examples on every commit

📦 Packaging

  • NuGet package includes README.md (no more missing readme warning)
  • Added NuGet search tags for SEO: opencode, ai, sdk, llm, chat, copilot, assistant, dotnet, csharp

🐛 Bug Fixes

  • Token usage display — tokens now correctly read from \info.tokens\ in API response
  • Find API — handles new response format where \path, \lines, and \match\ are objects with \ ext\ field
  • MCP API — uses new \ ype\ + \command\ array format
  • Model API — \Provider.Models\ is a dictionary ({ [key: string]: Model }), not a list

📝 Documentation

  • Added Chinese README (README.zh.md) with cross-language links
  • Emoji badges on all section headers for visual clarity
  • Added CI, Examples, and NuGet version badges to README
  • Simplified and repositioned SDK description
  • All examples updated to use lightweight prompts for fast execution