Skip to content
skyl

Response

A provider-agnostic model reply, always carrying the untouched body.

Response is what a successful Complete returns. Two of its fields are guaranteed on every adapter and every call; the rest are best-effort, because providers differ in what they disclose.

Reference#

type Response struct
FieldTypeDescription
IDstringThe provider's identifier for this response, when it supplies one. It is what a provider's support team will ask you for.
Zero value: the provider gave no ID
ProviderstringThe adapter that produced this response, for example "anthropic".
ModelstringThe model that actually served the request, read from the response rather than echoed from the request — providers can and do serve a different model than the one asked for.
MessageMessageThe assistant's turn. Append it to your conversation before sending tool results; every provider rejects a tool result that does not follow the call it answers.
StopReasonStopReasonWhy generation ended.
Zero value: StopUnknown means the provider reported something skyl does not model
UsageUsageToken consumption. Zero means "not reported", not "zero tokens".
Rawjson.RawMessageThe provider's untouched response body. Always populated, so skyl's abstraction is never the reason you cannot ship.

Methods#

Caveats

  • Provider and Raw are always populated. Raw is the provider's untouched body, so nothing they sent is ever lost — only unmodelled.
  • Model is read from the response, not echoed from the request. Providers substitute: aliases resolve to dated snapshots, and capacity fallback happens.
  • Usage zero means "not reported", not "zero tokens".
  • Reasoning content is dropped from Message by all four adapters. It stays in Raw.
  • Both methods are nil-safe on a nil *Response.
  • A Response from CollectStream has no Raw, because it is assembled from events rather than one body.

Usage#

Reading the answer

goCompiles
resp, err := client.Complete(ctx, req)
if err != nil {
	return err
}
fmt.Println(resp.Text())
fmt.Printf("%d in / %d out\n", resp.Usage.InputTokens, resp.Usage.OutputTokens)
resp, err := client.Complete(ctx, req)
if err != nil {
	return err
}
fmt.Println(resp.Text())
fmt.Printf("%d in / %d out\n", resp.Usage.InputTokens, resp.Usage.OutputTokens)

Continuing a conversation

goCompiles
// Append the response message itself — reconstructing it with AssistantText
// would silently drop any tool calls it contains.
req.Messages = append(req.Messages, resp.Message)
// Append the response message itself — reconstructing it with AssistantText
// would silently drop any tool calls it contains.
req.Messages = append(req.Messages, resp.Message)

Checking why it stopped

goCompiles
switch resp.StopReason {
case skyl.StopMaxTokens:
	return "", fmt.Errorf("truncated at %d tokens", req.MaxTokens)
case skyl.StopToolUse:
	// The model wants a tool run; Text() may be empty.
case skyl.StopRefusal:
	return "", fmt.Errorf("the model declined: %s", resp.Text())
}
switch resp.StopReason {
case skyl.StopMaxTokens:
	return "", fmt.Errorf("truncated at %d tokens", req.MaxTokens)
case skyl.StopToolUse:
	// The model wants a tool run; Text() may be empty.
case skyl.StopRefusal:
	return "", fmt.Errorf("the model declined: %s", resp.Text())
}

Reading a field skyl does not model

goCompiles
var raw struct {
	SystemFingerprint string `json:"system_fingerprint"`
}
if err := json.Unmarshal(resp.Raw, &raw); err != nil {
	return err
}
var raw struct {
	SystemFingerprint string `json:"system_fingerprint"`
}
if err := json.Unmarshal(resp.Raw, &raw); err != nil {
	return err
}

Troubleshooting#

Text() is empty and there was no error

Check StopReason. StopToolUse means the model produced calls rather than prose — normal. StopRefusal means it declined without explaining.

resp.Model differs from what I asked for

Normal. Aliases resolve to dated snapshots, and providers fall back under load. Group your metrics by resp.Model so two snapshots are not merged into one line. See Which Model Actually Answered.

Where is the model's reasoning?

Dropped from Message by every adapter, and present in Raw. Streaming on Anthropic is the only place skyl surfaces it as structured data, via EventThinkingDelta.

Raw is nil

You are looking at a Response from CollectStream, which assembles one from events. There is no single provider body to expose.

Edit this page on GitHub