// Package model provides a vendor-agnostic LLM adapter layer for Cyrene v2. // // It defines a normalized Message/Request/Response vocabulary, a single // Adapter interface implemented by OpenAIChatAdapter (which speaks the // OpenAI-compatible /chat/completions protocol used by OpenAI, DashScope/百炼, // local gateways and proxies), a per-role Router, an automatic fallback Chain, // multimodal (vision) detection, and per-call CallRecord accounting. // // The full tool loop (schema registration, argument binding, result re-feed) is // deferred to M2; this package only carries interface-level placeholders // (ToolSpec) so the wire contract is ready without executing any loop. package model import "time" // Role identifies who authored a message. The values are vendor-agnostic and // translated to each provider's own role vocabulary by the adapter. type Role string const ( // RoleSystem is a system/instruction message. RoleSystem Role = "system" // RoleUser is an end-user message. RoleUser Role = "user" // RoleAssistant is an assistant (model) message. RoleAssistant Role = "assistant" // RoleTool is a tool-result message (reserved for the M2 tool loop). RoleTool Role = "tool" ) // ContentType describes the kind of payload inside a Content part. type ContentType string const ( // ContentTypeText is a plain-text content part. ContentTypeText ContentType = "text" // ContentTypeImage is an image content part. ContentTypeImage ContentType = "image_url" ) // Content is a single, possibly multimodal, part of a message. type Content struct { // Type distinguishes a text part from an image part. Type ContentType // Text is the text payload when Type == ContentTypeText. Text string // ImageURL is the image source when Type == ContentTypeImage. It may be a // data: URI or an http(s):// URL. ImageURL string } // Message is a single conversation turn, normalized across providers. type Message struct { Role Role // Content carries one or more parts. A text-only message uses a single // ContentTypeText part. Content []Content // ToolCallID and ToolCallName are reserved as interface-level placeholders // for the M2 tool loop; they are ignored by current adapters. ToolCallID string ToolCallName string } // TextMessage builds a text-only message. func TextMessage(role Role, text string) Message { return Message{Role: role, Content: []Content{{Type: ContentTypeText, Text: text}}} } // ImageMessage builds a message carrying optional text plus an image. imageURL // may be a data: URI or an http(s):// URL. An empty text omits the text part. func ImageMessage(role Role, text, imageURL string) Message { parts := make([]Content, 0, 2) if text != "" { parts = append(parts, Content{Type: ContentTypeText, Text: text}) } parts = append(parts, Content{Type: ContentTypeImage, ImageURL: imageURL}) return Message{Role: role, Content: parts} } // ToolSpec is an interface-level placeholder for a tool/function schema. The // full tool loop (registration, argument binding, result re-feed) is M2; here // it only lets a request advertise tools to the provider in the wire contract. type ToolSpec struct { Name string Description string // Parameters is the JSON Schema for the tool arguments. Populated from M2. Parameters any } // Request is a completion request, normalized across providers. type Request struct { // Model overrides the adapter's configured default model. Empty means the // adapter default (or the chain step model) applies. Model string Messages []Message // Temperature is the sampling temperature. nil means the provider default. Temperature *float64 // MaxTokens caps the generated tokens. Zero means the provider default. MaxTokens int // Purpose labels the call for CallRecord accounting (e.g. "chat"). Purpose string // Tools is the interface-level placeholder for M2 function calling. Tools []ToolSpec } // Response is a normalized completion result. type Response struct { // Model is the model that produced the response. Model string Content string // Message is the normalized assistant message. Message Message // PromptTokens, CompletionTokens and TotalTokens report provider usage when // available; zero when the provider does not return it. PromptTokens int CompletionTokens int TotalTokens int } // CallRecord describes a single successfully completed LLM call, for the M9 // monitor/frontend. A failed attempt emits no record. type CallRecord struct { // Model is the model that served the request. Model string // Purpose labels what the call was for. Purpose string // Tokens is the total token consumption reported by the provider. Tokens int // TookMs is the end-to-end call latency in milliseconds. TookMs int64 } // Options carries per-call knobs layered on top of the Request. type Options struct { // Timeout bounds a single HTTP call. Zero uses the adapter client timeout. Timeout time.Duration }