Skip to content
skyl

Describing a Request

Everything that goes into a model call, and what each provider does with it.

A skyl.Request is the one shape every provider accepts. This chapter covers each field: what it means, what happens when you leave it zero, and — where it matters — which adapters quietly do something different with it.

In this chapter

  • How to make a call and read the answer
  • How roles work, and why there is no system role
  • What the four content parts are, and why the interface is closed
  • How system prompts and multi-turn conversations are represented
  • How to send images, and which adapters accept which form
  • Why Temperature is a pointer, and what that pointer means
  • Why model IDs are opaque strings that skyl never validates

Your first call#

Three parts: build a provider, wrap it in a client, send a request.

goCompiles
client := skyl.New(openai.New(os.Getenv("OPENAI_API_KEY")))

resp, err := client.Complete(ctx, &skyl.Request{
	Model:     "gpt-5.6",
	MaxTokens: 1024,
	Messages:  []skyl.Message{skyl.UserText("Explain Go channels in two sentences.")},
})
client := skyl.New(openai.New(os.Getenv("OPENAI_API_KEY")))

resp, err := client.Complete(ctx, &skyl.Request{
	Model:     "gpt-5.6",
	MaxTokens: 1024,
	Messages:  []skyl.Message{skyl.UserText("Explain Go channels in two sentences.")},
})

Read Your First Call for what Complete validates before it sends anything, and what comes back.

Read more →

Messages and roles#

There are three roles — user, assistant and tool — and deliberately no system.

Messages: []skyl.Message{
	skyl.UserText("What is a nil map?"),
	skyl.AssistantText("A map that is declared but not allocated."),
	skyl.UserText("Can I read from one?"),
}
Messages: []skyl.Message{
	skyl.UserText("What is a nil map?"),
	skyl.AssistantText("A map that is declared but not allocated."),
	skyl.UserText("Can I read from one?"),
}

Read Messages and Roles for why skyl does not police role ordering, and what happens when a provider dislikes your shape.

Read more →

Content parts#

A message is a role plus an ordered list of parts, because vendors disagree about whether content is a string or a list of typed blocks. skyl models the superset.

skyl.Message{
	Role: skyl.RoleAssistant,
	Parts: []skyl.Part{
		skyl.Text{Text: "Let me look that up."},
		skyl.ToolCall{ID: "call_1", Name: "get_weather", Arguments: args},
	},
}
skyl.Message{
	Role: skyl.RoleAssistant,
	Parts: []skyl.Part{
		skyl.Text{Text: "Let me look that up."},
		skyl.ToolCall{ID: "call_1", Name: "get_weather", Arguments: args},
	},
}

Read Content Parts for the four implementations and why the Part interface is closed.

Read more →

System prompts#

System is a field rather than a message, because Anthropic wants a top-level parameter, OpenAI wants a leading message, and Gemini wants systemInstruction.

goCompiles
req := &skyl.Request{
	Model:  "claude-opus-5",
	System: "You are a terse Go expert. Answer in one sentence.",
	Messages: []skyl.Message{skyl.UserText("What is a nil map?")},
}
req := &skyl.Request{
	Model:  "claude-opus-5",
	System: "You are a terse Go expert. Answer in one sentence.",
	Messages: []skyl.Message{skyl.UserText("What is a nil map?")},
}

Read System Prompts for where each adapter places it and what that means for token accounting.

Read more →

Multi-turn conversations#

Append both turns each round. Response.Message is already in the shape a request takes, so it replays verbatim.

Read Multi-Turn Conversations for context-window management and why you should not prefill an assistant turn.

Read more →

Images#

Read Images and Multimodal — Gemini rejects URL images outright, and setting both Data and URL silently drops one of them.

Read more →

Sampling parameters#

Temperature and TopP are *float64, and a non-nil value is always sent — even to models that reject it.

Read Sampling Parameters for why skyl refuses to silently drop a field you set.

Read more →

Model IDs#

Read Model IDs Are Just Strings for the most consequential decision in the project, and the price it charges you.

Read more →

What’s next?

Start with Your First Call. If you already have a call working and want to know what comes back, skip ahead to Reading a Response.

Edit this page on GitHub