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 class — OpenCode, 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