Skip to content

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 30 Sep 07:28
· 52 commits to main since this release
d0ae284

   Upgrading from v0.6.0

The module path is now github.com/felinics/twilight. v0.7.0 is the first tag under it, so replace the github.com/memohai/twilight imports and run go get github.com/felinics/twilight@v0.7.0.

The text-generation client layer is removed (#53). Model.Generate and Model.Stream take an sdk.Request and are the only chat entry points. GenerateText, StreamText, MaxSteps, tool execution and approval, and the MCP client are gone; the caller runs tools and loops. ToolArguments, ToolOutput and Request.ProviderOptions hold RFC 8785 canonical JSON (#54), and RawJSONOutput returns an error.

Provider failures are *sdk.APIError: non-2xx responses, error events inside a stream (StatusCode 0), and failed video jobs. Read the cause with sdk.KindOf(err), which returns one of authentication, permission_denied, quota_exhausted, rate_limited, server_error or unknown. The set is open, so a switch on it needs a default branch. Error() has no stable format and no longer starts with api error. Code that matches the error text, such as a regexp on api error 5\d\d to decide whether to retry, stops matching and must move to KindOf. RetryAfter() reads retry-after-ms and Retry-After.

A stream that ends before its terminal event emits an ErrorPart wrapping sdk.ErrStreamIncomplete, followed by a FinishPart with FinishReasonError. It used to end as a success.

Provider.Test returns error: nil when the provider is reachable and accepts the credentials. ProviderTestResult, ProviderStatus and ClassifyProbeStatus are removed. VideoProvider requires Name(), and VideoError has a Kind.

edge.EdgeTTSVoices is replaced by Voices(), which returns a copy.

sdk.WithClientRequestID(ctx, id) sends a caller-chosen request ID to the providers that accept one. Nothing is sent when it is not set.

  • edge:
    • Replace EdgeTTSVoices with Voices(), which returns a copy  -  by @HoneyBBQ (06eb4)
  • provider:
  • sdk:
    • Single-call seam only; typed tool arguments, outputs and provider metadata  -  by @Fodesu in #53 (ce173)
    • The JSON the SDK carries through is RFC 8785 canonical at its entry points  -  by @Fodesu in #54 (cef8f)
    • Report health checks and failed video jobs as errors  -  by @HoneyBBQ (2720a)

   🚀 Features

  • Add request headers and OpenCode Go provider  -  by @akazwz (ed745)
  • opencode-go:
  • provider:
    • Return *sdk.APIError from non-2xx responses  -  by @HoneyBBQ (6e7f3)
    • Return *sdk.APIError from direct HTTP and WebSocket audio paths  -  by @HoneyBBQ (23622)
  • sdk:
    • Export APIError with Kind classification  -  by @HoneyBBQ (a4f89)
    • Send a caller-chosen client request ID to providers that accept one  -  by @HoneyBBQ (138c0)

   🐞 Bug Fixes

  • anthropic:
    • Map the refusal and model_context_window_exceeded stop reasons  -  by @HoneyBBQ (8a59a)
  • ci:
  • completions:
    • Replay reasoning_content on thinking-mode tool calls  -  by @Fodesu in #48 (18a98)
  • errorformat:
    • Classify Google errors by google.api.ErrorReason values only  -  by @HoneyBBQ (a3b29)
    • Read OpenRouter's x-generation-id as the request ID  -  by @HoneyBBQ (27155)
    • Classify Gemini daily quota errors as quota_exhausted  -  by @HoneyBBQ (546c2)
  • headers:
    • Keep sdk free of AWS deps and protect the JSON content type  -  by @akazwz (8fccb)
  • opencode-go:
  • openrouter:
  • provider:
    • Replay invalid tool arguments as {} on string-typed wire fields  -  by @Fodesu in #58 (22d89)
    • Bound the error body NewHTTPError reads; match Copilot test errors by field  -  by @HoneyBBQ (9969f)
    • Leave 501 and 505 unclassified  -  by @HoneyBBQ (7bf57)
    • Read ElevenLabs and MiniMax request IDs from the headers they send on errors  -  by @HoneyBBQ (d267e)
  • sdk:
    • An unidentified reasoning start opens a new block instead of joining the last  -  by @Fodesu in #56 (6487f)
    View changes on GitHub