| 
									
										
										
										
											2023-07-04 03:22:44 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | import ( | 
					
						
							| 
									
										
										
										
											2023-07-20 06:00:28 +08:00
										 |  |  | 	"encoding/json" | 
					
						
							| 
									
										
										
										
											2024-04-21 10:11:06 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2023-07-20 06:00:28 +08:00
										 |  |  | 	"math" | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 	"reflect" | 
					
						
							| 
									
										
										
										
											2023-11-30 01:56:42 +08:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2023-07-08 06:29:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 00:09:45 +08:00
										 |  |  | type StatusError struct { | 
					
						
							| 
									
										
										
										
											2023-07-21 02:45:12 +08:00
										 |  |  | 	StatusCode   int | 
					
						
							|  |  |  | 	Status       string | 
					
						
							|  |  |  | 	ErrorMessage string `json:"error"` | 
					
						
							| 
									
										
										
										
											2023-07-19 00:09:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (e StatusError) Error() string { | 
					
						
							| 
									
										
										
										
											2023-07-21 02:45:12 +08:00
										 |  |  | 	switch { | 
					
						
							|  |  |  | 	case e.Status != "" && e.ErrorMessage != "": | 
					
						
							|  |  |  | 		return fmt.Sprintf("%s: %s", e.Status, e.ErrorMessage) | 
					
						
							|  |  |  | 	case e.Status != "": | 
					
						
							|  |  |  | 		return e.Status | 
					
						
							|  |  |  | 	case e.ErrorMessage != "": | 
					
						
							|  |  |  | 		return e.ErrorMessage | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		// this should not happen
 | 
					
						
							|  |  |  | 		return "something went wrong, please see the ollama server logs for details" | 
					
						
							| 
									
										
										
										
											2023-07-19 00:09:45 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 05:56:22 +08:00
										 |  |  | type ImageData []byte | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-11 01:31:55 +08:00
										 |  |  | // GenerateRequest describes a request sent by [Client.Generate]. While you
 | 
					
						
							|  |  |  | // have to specify the Model and Prompt fields, all the other fields have
 | 
					
						
							|  |  |  | // reasonable defaults for basic uses.
 | 
					
						
							| 
									
										
										
										
											2023-07-17 08:02:22 +08:00
										 |  |  | type GenerateRequest struct { | 
					
						
							| 
									
										
										
										
											2024-04-11 01:31:55 +08:00
										 |  |  | 	// Model is the model name; it should be a name familiar to Ollama from
 | 
					
						
							|  |  |  | 	// the library at https://ollama.com/library
 | 
					
						
							|  |  |  | 	Model string `json:"model"` | 
					
						
							| 
									
										
										
										
											2023-07-17 08:02:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-11 01:31:55 +08:00
										 |  |  | 	// Prompt is the textual prompt to send to the model.
 | 
					
						
							|  |  |  | 	Prompt string `json:"prompt"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// System overrides the model's default system message/prompt.
 | 
					
						
							|  |  |  | 	System string `json:"system"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Template overrides the model's default prompt template.
 | 
					
						
							|  |  |  | 	Template string `json:"template"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Context is the context parameter returned from a previous call to
 | 
					
						
							|  |  |  | 	// Generate call. It can be used to keep a short conversational memory.
 | 
					
						
							|  |  |  | 	Context []int `json:"context,omitempty"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Stream specifies whether the response is streaming; it is true by default.
 | 
					
						
							|  |  |  | 	Stream *bool `json:"stream,omitempty"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Raw set to true means that no formatting will be applied to the prompt.
 | 
					
						
							|  |  |  | 	Raw bool `json:"raw,omitempty"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Format specifies the format to return a response in.
 | 
					
						
							|  |  |  | 	Format string `json:"format"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// KeepAlive controls how long the model will stay loaded in memory following
 | 
					
						
							|  |  |  | 	// this request.
 | 
					
						
							|  |  |  | 	KeepAlive *Duration `json:"keep_alive,omitempty"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Images is an optional list of base64-encoded images accompanying this
 | 
					
						
							|  |  |  | 	// request, for multimodal models.
 | 
					
						
							|  |  |  | 	Images []ImageData `json:"images,omitempty"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Options lists model-specific options. For example, temperature can be
 | 
					
						
							|  |  |  | 	// set through this field, if the model supports it.
 | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 	Options map[string]interface{} `json:"options"` | 
					
						
							| 
									
										
										
										
											2023-07-17 08:02:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | type ChatRequest struct { | 
					
						
							| 
									
										
										
										
											2024-01-27 06:28:02 +08:00
										 |  |  | 	Model     string    `json:"model"` | 
					
						
							|  |  |  | 	Messages  []Message `json:"messages"` | 
					
						
							|  |  |  | 	Stream    *bool     `json:"stream,omitempty"` | 
					
						
							|  |  |  | 	Format    string    `json:"format"` | 
					
						
							|  |  |  | 	KeepAlive *Duration `json:"keep_alive,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Options map[string]interface{} `json:"options"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Message struct { | 
					
						
							| 
									
										
										
										
											2023-12-13 05:28:58 +08:00
										 |  |  | 	Role    string      `json:"role"` // one of ["system", "user", "assistant"]
 | 
					
						
							|  |  |  | 	Content string      `json:"content"` | 
					
						
							| 
									
										
										
										
											2023-12-19 03:23:38 +08:00
										 |  |  | 	Images  []ImageData `json:"images,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type ChatResponse struct { | 
					
						
							|  |  |  | 	Model     string    `json:"model"` | 
					
						
							|  |  |  | 	CreatedAt time.Time `json:"created_at"` | 
					
						
							| 
									
										
										
										
											2023-12-19 03:23:38 +08:00
										 |  |  | 	Message   Message   `json:"message"` | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Done bool `json:"done"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Metrics | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type Metrics struct { | 
					
						
							|  |  |  | 	TotalDuration      time.Duration `json:"total_duration,omitempty"` | 
					
						
							|  |  |  | 	LoadDuration       time.Duration `json:"load_duration,omitempty"` | 
					
						
							|  |  |  | 	PromptEvalCount    int           `json:"prompt_eval_count,omitempty"` | 
					
						
							|  |  |  | 	PromptEvalDuration time.Duration `json:"prompt_eval_duration,omitempty"` | 
					
						
							|  |  |  | 	EvalCount          int           `json:"eval_count,omitempty"` | 
					
						
							|  |  |  | 	EvalDuration       time.Duration `json:"eval_duration,omitempty"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-26 02:41:25 +08:00
										 |  |  | // Options specified in GenerateRequest, if you add a new option here add it to the API docs also
 | 
					
						
							| 
									
										
										
										
											2023-11-09 08:44:36 +08:00
										 |  |  | type Options struct { | 
					
						
							|  |  |  | 	Runner | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Predict options used at runtime
 | 
					
						
							|  |  |  | 	NumKeep          int      `json:"num_keep,omitempty"` | 
					
						
							|  |  |  | 	Seed             int      `json:"seed,omitempty"` | 
					
						
							|  |  |  | 	NumPredict       int      `json:"num_predict,omitempty"` | 
					
						
							|  |  |  | 	TopK             int      `json:"top_k,omitempty"` | 
					
						
							|  |  |  | 	TopP             float32  `json:"top_p,omitempty"` | 
					
						
							|  |  |  | 	TFSZ             float32  `json:"tfs_z,omitempty"` | 
					
						
							|  |  |  | 	TypicalP         float32  `json:"typical_p,omitempty"` | 
					
						
							|  |  |  | 	RepeatLastN      int      `json:"repeat_last_n,omitempty"` | 
					
						
							|  |  |  | 	Temperature      float32  `json:"temperature,omitempty"` | 
					
						
							|  |  |  | 	RepeatPenalty    float32  `json:"repeat_penalty,omitempty"` | 
					
						
							|  |  |  | 	PresencePenalty  float32  `json:"presence_penalty,omitempty"` | 
					
						
							|  |  |  | 	FrequencyPenalty float32  `json:"frequency_penalty,omitempty"` | 
					
						
							|  |  |  | 	Mirostat         int      `json:"mirostat,omitempty"` | 
					
						
							|  |  |  | 	MirostatTau      float32  `json:"mirostat_tau,omitempty"` | 
					
						
							|  |  |  | 	MirostatEta      float32  `json:"mirostat_eta,omitempty"` | 
					
						
							|  |  |  | 	PenalizeNewline  bool     `json:"penalize_newline,omitempty"` | 
					
						
							|  |  |  | 	Stop             []string `json:"stop,omitempty"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Runner options which must be set when the model is loaded into memory
 | 
					
						
							|  |  |  | type Runner struct { | 
					
						
							| 
									
										
										
										
											2024-04-05 23:49:04 +08:00
										 |  |  | 	UseNUMA   bool `json:"numa,omitempty"` | 
					
						
							|  |  |  | 	NumCtx    int  `json:"num_ctx,omitempty"` | 
					
						
							|  |  |  | 	NumBatch  int  `json:"num_batch,omitempty"` | 
					
						
							|  |  |  | 	NumGQA    int  `json:"num_gqa,omitempty"` | 
					
						
							|  |  |  | 	NumGPU    int  `json:"num_gpu,omitempty"` | 
					
						
							|  |  |  | 	MainGPU   int  `json:"main_gpu,omitempty"` | 
					
						
							|  |  |  | 	LowVRAM   bool `json:"low_vram,omitempty"` | 
					
						
							|  |  |  | 	F16KV     bool `json:"f16_kv,omitempty"` | 
					
						
							|  |  |  | 	LogitsAll bool `json:"logits_all,omitempty"` | 
					
						
							|  |  |  | 	VocabOnly bool `json:"vocab_only,omitempty"` | 
					
						
							|  |  |  | 	UseMMap   bool `json:"use_mmap,omitempty"` | 
					
						
							|  |  |  | 	UseMLock  bool `json:"use_mlock,omitempty"` | 
					
						
							|  |  |  | 	NumThread int  `json:"num_thread,omitempty"` | 
					
						
							| 
									
										
										
										
											2024-04-10 07:15:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Unused: RopeFrequencyBase is ignored. Instead the value in the model will be used
 | 
					
						
							|  |  |  | 	RopeFrequencyBase float32 `json:"rope_frequency_base,omitempty"` | 
					
						
							|  |  |  | 	// Unused: RopeFrequencyScale is ignored. Instead the value in the model will be used
 | 
					
						
							|  |  |  | 	RopeFrequencyScale float32 `json:"rope_frequency_scale,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-11-09 08:44:36 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-09 03:13:22 +08:00
										 |  |  | type EmbeddingRequest struct { | 
					
						
							| 
									
										
										
										
											2024-01-27 06:28:02 +08:00
										 |  |  | 	Model     string    `json:"model"` | 
					
						
							|  |  |  | 	Prompt    string    `json:"prompt"` | 
					
						
							|  |  |  | 	KeepAlive *Duration `json:"keep_alive,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-08-09 03:13:22 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Options map[string]interface{} `json:"options"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type EmbeddingResponse struct { | 
					
						
							|  |  |  | 	Embedding []float64 `json:"embedding"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 08:02:22 +08:00
										 |  |  | type CreateRequest struct { | 
					
						
							| 
									
										
										
										
											2024-04-05 23:49:04 +08:00
										 |  |  | 	Model        string `json:"model"` | 
					
						
							|  |  |  | 	Path         string `json:"path"` | 
					
						
							|  |  |  | 	Modelfile    string `json:"modelfile"` | 
					
						
							|  |  |  | 	Stream       *bool  `json:"stream,omitempty"` | 
					
						
							|  |  |  | 	Quantization string `json:"quantization,omitempty"` | 
					
						
							| 
									
										
										
										
											2024-01-12 06:07:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Name is deprecated, see Model
 | 
					
						
							|  |  |  | 	Name string `json:"name"` | 
					
						
							| 
									
										
										
										
											2023-07-17 08:02:22 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-21 07:09:23 +08:00
										 |  |  | type DeleteRequest struct { | 
					
						
							| 
									
										
										
										
											2024-01-12 06:07:54 +08:00
										 |  |  | 	Model string `json:"model"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Name is deprecated, see Model
 | 
					
						
							| 
									
										
										
										
											2023-07-21 07:09:23 +08:00
										 |  |  | 	Name string `json:"name"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 02:04:17 +08:00
										 |  |  | type ShowRequest struct { | 
					
						
							| 
									
										
										
										
											2024-01-05 09:23:11 +08:00
										 |  |  | 	Model    string `json:"model"` | 
					
						
							|  |  |  | 	System   string `json:"system"` | 
					
						
							|  |  |  | 	Template string `json:"template"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Options map[string]interface{} `json:"options"` | 
					
						
							| 
									
										
										
										
											2024-01-12 06:07:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Name is deprecated, see Model
 | 
					
						
							|  |  |  | 	Name string `json:"name"` | 
					
						
							| 
									
										
										
										
											2023-09-07 02:04:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type ShowResponse struct { | 
					
						
							| 
									
										
										
										
											2023-12-12 05:56:22 +08:00
										 |  |  | 	License    string       `json:"license,omitempty"` | 
					
						
							|  |  |  | 	Modelfile  string       `json:"modelfile,omitempty"` | 
					
						
							|  |  |  | 	Parameters string       `json:"parameters,omitempty"` | 
					
						
							|  |  |  | 	Template   string       `json:"template,omitempty"` | 
					
						
							|  |  |  | 	System     string       `json:"system,omitempty"` | 
					
						
							|  |  |  | 	Details    ModelDetails `json:"details,omitempty"` | 
					
						
							| 
									
										
										
										
											2024-01-26 04:12:36 +08:00
										 |  |  | 	Messages   []Message    `json:"messages,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-09-07 02:04:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-24 23:27:28 +08:00
										 |  |  | type CopyRequest struct { | 
					
						
							|  |  |  | 	Source      string `json:"source"` | 
					
						
							|  |  |  | 	Destination string `json:"destination"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-07 00:24:49 +08:00
										 |  |  | type PullRequest struct { | 
					
						
							| 
									
										
										
										
											2024-01-12 06:07:54 +08:00
										 |  |  | 	Model    string `json:"model"` | 
					
						
							| 
									
										
										
										
											2023-07-22 06:42:19 +08:00
										 |  |  | 	Insecure bool   `json:"insecure,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-10-12 00:54:27 +08:00
										 |  |  | 	Username string `json:"username"` | 
					
						
							|  |  |  | 	Password string `json:"password"` | 
					
						
							|  |  |  | 	Stream   *bool  `json:"stream,omitempty"` | 
					
						
							| 
									
										
										
										
											2024-01-12 06:07:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Name is deprecated, see Model
 | 
					
						
							|  |  |  | 	Name string `json:"name"` | 
					
						
							| 
									
										
										
										
											2023-07-07 00:24:49 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:51:30 +08:00
										 |  |  | type ProgressResponse struct { | 
					
						
							| 
									
										
										
										
											2023-07-21 07:09:23 +08:00
										 |  |  | 	Status    string `json:"status"` | 
					
						
							|  |  |  | 	Digest    string `json:"digest,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-09-29 01:00:34 +08:00
										 |  |  | 	Total     int64  `json:"total,omitempty"` | 
					
						
							|  |  |  | 	Completed int64  `json:"completed,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-07-07 02:18:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 08:02:22 +08:00
										 |  |  | type PushRequest struct { | 
					
						
							| 
									
										
										
										
											2024-01-12 06:07:54 +08:00
										 |  |  | 	Model    string `json:"model"` | 
					
						
							| 
									
										
										
										
											2023-07-22 06:42:19 +08:00
										 |  |  | 	Insecure bool   `json:"insecure,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-10-12 00:54:27 +08:00
										 |  |  | 	Username string `json:"username"` | 
					
						
							|  |  |  | 	Password string `json:"password"` | 
					
						
							|  |  |  | 	Stream   *bool  `json:"stream,omitempty"` | 
					
						
							| 
									
										
										
										
											2024-01-12 06:07:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Name is deprecated, see Model
 | 
					
						
							|  |  |  | 	Name string `json:"name"` | 
					
						
							| 
									
										
										
										
											2023-07-17 08:02:22 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-07-07 08:09:48 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 00:09:45 +08:00
										 |  |  | type ListResponse struct { | 
					
						
							| 
									
										
										
										
											2023-08-30 23:10:27 +08:00
										 |  |  | 	Models []ModelResponse `json:"models"` | 
					
						
							| 
									
										
										
										
											2023-07-19 00:09:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 23:10:27 +08:00
										 |  |  | type ModelResponse struct { | 
					
						
							| 
									
										
										
										
											2023-12-12 05:56:22 +08:00
										 |  |  | 	Name       string       `json:"name"` | 
					
						
							| 
									
										
										
										
											2024-01-19 06:32:55 +08:00
										 |  |  | 	Model      string       `json:"model"` | 
					
						
							| 
									
										
										
										
											2023-12-12 05:56:22 +08:00
										 |  |  | 	ModifiedAt time.Time    `json:"modified_at"` | 
					
						
							|  |  |  | 	Size       int64        `json:"size"` | 
					
						
							|  |  |  | 	Digest     string       `json:"digest"` | 
					
						
							|  |  |  | 	Details    ModelDetails `json:"details,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-07-19 00:09:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-11 02:34:25 +08:00
										 |  |  | type TokenResponse struct { | 
					
						
							|  |  |  | 	Token string `json:"token"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-08 06:29:17 +08:00
										 |  |  | type GenerateResponse struct { | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	Model     string    `json:"model"` | 
					
						
							|  |  |  | 	CreatedAt time.Time `json:"created_at"` | 
					
						
							| 
									
										
										
										
											2023-10-12 00:54:27 +08:00
										 |  |  | 	Response  string    `json:"response"` | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-14 02:02:53 +08:00
										 |  |  | 	Done    bool  `json:"done"` | 
					
						
							|  |  |  | 	Context []int `json:"context,omitempty"` | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | 	Metrics | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 05:56:22 +08:00
										 |  |  | type ModelDetails struct { | 
					
						
							| 
									
										
										
										
											2024-01-26 04:12:36 +08:00
										 |  |  | 	ParentModel       string   `json:"parent_model"` | 
					
						
							| 
									
										
										
										
											2023-12-12 05:56:22 +08:00
										 |  |  | 	Format            string   `json:"format"` | 
					
						
							|  |  |  | 	Family            string   `json:"family"` | 
					
						
							|  |  |  | 	Families          []string `json:"families"` | 
					
						
							|  |  |  | 	ParameterSize     string   `json:"parameter_size"` | 
					
						
							|  |  |  | 	QuantizationLevel string   `json:"quantization_level"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | func (m *Metrics) Summary() { | 
					
						
							|  |  |  | 	if m.TotalDuration > 0 { | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "total duration:       %v\n", m.TotalDuration) | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | 	if m.LoadDuration > 0 { | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "load duration:        %v\n", m.LoadDuration) | 
					
						
							| 
									
										
										
										
											2023-07-19 03:02:02 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | 	if m.PromptEvalCount > 0 { | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "prompt eval count:    %d token(s)\n", m.PromptEvalCount) | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | 	if m.PromptEvalDuration > 0 { | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "prompt eval duration: %s\n", m.PromptEvalDuration) | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "prompt eval rate:     %.2f tokens/s\n", float64(m.PromptEvalCount)/m.PromptEvalDuration.Seconds()) | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | 	if m.EvalCount > 0 { | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "eval count:           %d token(s)\n", m.EvalCount) | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 03:57:33 +08:00
										 |  |  | 	if m.EvalDuration > 0 { | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "eval duration:        %s\n", m.EvalDuration) | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "eval rate:            %.2f tokens/s\n", float64(m.EvalCount)/m.EvalDuration.Seconds()) | 
					
						
							| 
									
										
										
										
											2023-07-13 09:18:06 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-07-07 08:09:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-21 10:11:06 +08:00
										 |  |  | var ErrInvalidOpts = errors.New("invalid options") | 
					
						
							| 
									
										
										
										
											2024-04-30 07:14:07 +08:00
										 |  |  | var ErrInvalidHostPort = errors.New("invalid port specified in OLLAMA_HOST") | 
					
						
							| 
									
										
										
										
											2023-10-12 23:18:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | func (opts *Options) FromMap(m map[string]interface{}) error { | 
					
						
							|  |  |  | 	valueOpts := reflect.ValueOf(opts).Elem() // names of the fields in the options struct
 | 
					
						
							|  |  |  | 	typeOpts := reflect.TypeOf(opts).Elem()   // types of the fields in the options struct
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// build map of json struct tags to their types
 | 
					
						
							|  |  |  | 	jsonOpts := make(map[string]reflect.StructField) | 
					
						
							|  |  |  | 	for _, field := range reflect.VisibleFields(typeOpts) { | 
					
						
							|  |  |  | 		jsonTag := strings.Split(field.Tag.Get("json"), ",")[0] | 
					
						
							|  |  |  | 		if jsonTag != "" { | 
					
						
							|  |  |  | 			jsonOpts[jsonTag] = field | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-12 23:18:11 +08:00
										 |  |  | 	invalidOpts := []string{} | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 	for key, val := range m { | 
					
						
							|  |  |  | 		if opt, ok := jsonOpts[key]; ok { | 
					
						
							|  |  |  | 			field := valueOpts.FieldByName(opt.Name) | 
					
						
							|  |  |  | 			if field.IsValid() && field.CanSet() { | 
					
						
							| 
									
										
										
										
											2023-08-18 06:50:46 +08:00
										 |  |  | 				if val == nil { | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 				switch field.Kind() { | 
					
						
							|  |  |  | 				case reflect.Int: | 
					
						
							| 
									
										
										
										
											2023-08-11 07:18:55 +08:00
										 |  |  | 					switch t := val.(type) { | 
					
						
							|  |  |  | 					case int64: | 
					
						
							|  |  |  | 						field.SetInt(t) | 
					
						
							|  |  |  | 					case float64: | 
					
						
							|  |  |  | 						// when JSON unmarshals numbers, it uses float64, not int
 | 
					
						
							|  |  |  | 						field.SetInt(int64(t)) | 
					
						
							|  |  |  | 					default: | 
					
						
							| 
									
										
										
										
											2023-10-14 04:57:10 +08:00
										 |  |  | 						return fmt.Errorf("option %q must be of type integer", key) | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				case reflect.Bool: | 
					
						
							|  |  |  | 					val, ok := val.(bool) | 
					
						
							|  |  |  | 					if !ok { | 
					
						
							| 
									
										
										
										
											2023-10-14 04:57:10 +08:00
										 |  |  | 						return fmt.Errorf("option %q must be of type boolean", key) | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					field.SetBool(val) | 
					
						
							|  |  |  | 				case reflect.Float32: | 
					
						
							|  |  |  | 					// JSON unmarshals to float64
 | 
					
						
							|  |  |  | 					val, ok := val.(float64) | 
					
						
							|  |  |  | 					if !ok { | 
					
						
							| 
									
										
										
										
											2023-10-14 04:57:10 +08:00
										 |  |  | 						return fmt.Errorf("option %q must be of type float32", key) | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					field.SetFloat(val) | 
					
						
							|  |  |  | 				case reflect.String: | 
					
						
							|  |  |  | 					val, ok := val.(string) | 
					
						
							|  |  |  | 					if !ok { | 
					
						
							| 
									
										
										
										
											2023-10-14 04:57:10 +08:00
										 |  |  | 						return fmt.Errorf("option %q must be of type string", key) | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					field.SetString(val) | 
					
						
							|  |  |  | 				case reflect.Slice: | 
					
						
							|  |  |  | 					// JSON unmarshals to []interface{}, not []string
 | 
					
						
							|  |  |  | 					val, ok := val.([]interface{}) | 
					
						
							|  |  |  | 					if !ok { | 
					
						
							| 
									
										
										
										
											2023-10-14 04:57:10 +08:00
										 |  |  | 						return fmt.Errorf("option %q must be of type array", key) | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					// convert []interface{} to []string
 | 
					
						
							|  |  |  | 					slice := make([]string, len(val)) | 
					
						
							|  |  |  | 					for i, item := range val { | 
					
						
							|  |  |  | 						str, ok := item.(string) | 
					
						
							|  |  |  | 						if !ok { | 
					
						
							| 
									
										
										
										
											2023-10-14 04:57:10 +08:00
										 |  |  | 							return fmt.Errorf("option %q must be of an array of strings", key) | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						slice[i] = str | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					field.Set(reflect.ValueOf(slice)) | 
					
						
							|  |  |  | 				default: | 
					
						
							|  |  |  | 					return fmt.Errorf("unknown type loading config params: %v", field.Kind()) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-10-12 23:18:11 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			invalidOpts = append(invalidOpts, key) | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-10-12 23:18:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if len(invalidOpts) > 0 { | 
					
						
							|  |  |  | 		return fmt.Errorf("%w: %v", ErrInvalidOpts, strings.Join(invalidOpts, ", ")) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-08-02 01:36:31 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-08 06:29:17 +08:00
										 |  |  | func DefaultOptions() Options { | 
					
						
							|  |  |  | 	return Options{ | 
					
						
							| 
									
										
										
										
											2023-10-03 02:53:16 +08:00
										 |  |  | 		// options set on request to runner
 | 
					
						
							| 
									
										
										
										
											2024-04-26 07:02:30 +08:00
										 |  |  | 		NumPredict: -1, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// set a minimal num_keep to avoid issues on context shifts
 | 
					
						
							|  |  |  | 		NumKeep:          4, | 
					
						
							| 
									
										
										
										
											2023-07-08 06:29:17 +08:00
										 |  |  | 		Temperature:      0.8, | 
					
						
							|  |  |  | 		TopK:             40, | 
					
						
							|  |  |  | 		TopP:             0.9, | 
					
						
							|  |  |  | 		TFSZ:             1.0, | 
					
						
							|  |  |  | 		TypicalP:         1.0, | 
					
						
							| 
									
										
										
										
											2023-10-03 02:53:16 +08:00
										 |  |  | 		RepeatLastN:      64, | 
					
						
							|  |  |  | 		RepeatPenalty:    1.1, | 
					
						
							|  |  |  | 		PresencePenalty:  0.0, | 
					
						
							|  |  |  | 		FrequencyPenalty: 0.0, | 
					
						
							| 
									
										
										
										
											2023-07-08 06:29:17 +08:00
										 |  |  | 		Mirostat:         0, | 
					
						
							|  |  |  | 		MirostatTau:      5.0, | 
					
						
							|  |  |  | 		MirostatEta:      0.1, | 
					
						
							| 
									
										
										
										
											2023-07-20 03:47:15 +08:00
										 |  |  | 		PenalizeNewline:  true, | 
					
						
							| 
									
										
										
										
											2023-10-03 02:53:16 +08:00
										 |  |  | 		Seed:             -1, | 
					
						
							| 
									
										
										
										
											2023-07-08 06:29:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 22:39:58 +08:00
										 |  |  | 		Runner: Runner{ | 
					
						
							|  |  |  | 			// options set when the model is loaded
 | 
					
						
							| 
									
										
										
										
											2024-04-05 23:49:04 +08:00
										 |  |  | 			NumCtx:    2048, | 
					
						
							|  |  |  | 			NumBatch:  512, | 
					
						
							|  |  |  | 			NumGPU:    -1, // -1 here indicates that NumGPU should be set dynamically
 | 
					
						
							|  |  |  | 			NumGQA:    1, | 
					
						
							|  |  |  | 			NumThread: 0, // let the runtime decide
 | 
					
						
							|  |  |  | 			LowVRAM:   false, | 
					
						
							|  |  |  | 			F16KV:     true, | 
					
						
							|  |  |  | 			UseMLock:  false, | 
					
						
							|  |  |  | 			UseMMap:   true, | 
					
						
							|  |  |  | 			UseNUMA:   false, | 
					
						
							| 
									
										
										
										
											2023-10-19 22:39:58 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-07-08 06:29:17 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-07-04 03:22:44 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-07-20 06:00:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | type Duration struct { | 
					
						
							|  |  |  | 	time.Duration | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (d *Duration) UnmarshalJSON(b []byte) (err error) { | 
					
						
							|  |  |  | 	var v any | 
					
						
							|  |  |  | 	if err := json.Unmarshal(b, &v); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	d.Duration = 5 * time.Minute | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch t := v.(type) { | 
					
						
							|  |  |  | 	case float64: | 
					
						
							|  |  |  | 		if t < 0 { | 
					
						
							| 
									
										
										
										
											2024-02-14 07:40:32 +08:00
										 |  |  | 			d.Duration = time.Duration(math.MaxInt64) | 
					
						
							| 
									
										
										
										
											2024-01-27 06:28:02 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			d.Duration = time.Duration(t * float64(time.Second)) | 
					
						
							| 
									
										
										
										
											2023-07-20 06:00:28 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	case string: | 
					
						
							|  |  |  | 		d.Duration, err = time.ParseDuration(t) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-01-27 06:28:02 +08:00
										 |  |  | 		if d.Duration < 0 { | 
					
						
							| 
									
										
										
										
											2024-02-14 07:40:32 +08:00
										 |  |  | 			d.Duration = time.Duration(math.MaxInt64) | 
					
						
							| 
									
										
										
										
											2024-01-27 06:28:02 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-07-20 06:00:28 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-11-30 01:56:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // FormatParams converts specified parameter options to their correct types
 | 
					
						
							|  |  |  | func FormatParams(params map[string][]string) (map[string]interface{}, error) { | 
					
						
							|  |  |  | 	opts := Options{} | 
					
						
							|  |  |  | 	valueOpts := reflect.ValueOf(&opts).Elem() // names of the fields in the options struct
 | 
					
						
							|  |  |  | 	typeOpts := reflect.TypeOf(opts)           // types of the fields in the options struct
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// build map of json struct tags to their types
 | 
					
						
							|  |  |  | 	jsonOpts := make(map[string]reflect.StructField) | 
					
						
							|  |  |  | 	for _, field := range reflect.VisibleFields(typeOpts) { | 
					
						
							|  |  |  | 		jsonTag := strings.Split(field.Tag.Get("json"), ",")[0] | 
					
						
							|  |  |  | 		if jsonTag != "" { | 
					
						
							|  |  |  | 			jsonOpts[jsonTag] = field | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	out := make(map[string]interface{}) | 
					
						
							|  |  |  | 	// iterate params and set values based on json struct tags
 | 
					
						
							|  |  |  | 	for key, vals := range params { | 
					
						
							|  |  |  | 		if opt, ok := jsonOpts[key]; !ok { | 
					
						
							|  |  |  | 			return nil, fmt.Errorf("unknown parameter '%s'", key) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			field := valueOpts.FieldByName(opt.Name) | 
					
						
							|  |  |  | 			if field.IsValid() && field.CanSet() { | 
					
						
							|  |  |  | 				switch field.Kind() { | 
					
						
							|  |  |  | 				case reflect.Float32: | 
					
						
							|  |  |  | 					floatVal, err := strconv.ParseFloat(vals[0], 32) | 
					
						
							|  |  |  | 					if err != nil { | 
					
						
							|  |  |  | 						return nil, fmt.Errorf("invalid float value %s", vals) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					out[key] = float32(floatVal) | 
					
						
							|  |  |  | 				case reflect.Int: | 
					
						
							|  |  |  | 					intVal, err := strconv.ParseInt(vals[0], 10, 64) | 
					
						
							|  |  |  | 					if err != nil { | 
					
						
							|  |  |  | 						return nil, fmt.Errorf("invalid int value %s", vals) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					out[key] = intVal | 
					
						
							|  |  |  | 				case reflect.Bool: | 
					
						
							|  |  |  | 					boolVal, err := strconv.ParseBool(vals[0]) | 
					
						
							|  |  |  | 					if err != nil { | 
					
						
							|  |  |  | 						return nil, fmt.Errorf("invalid bool value %s", vals) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					out[key] = boolVal | 
					
						
							|  |  |  | 				case reflect.String: | 
					
						
							|  |  |  | 					out[key] = vals[0] | 
					
						
							|  |  |  | 				case reflect.Slice: | 
					
						
							|  |  |  | 					// TODO: only string slices are supported right now
 | 
					
						
							|  |  |  | 					out[key] = vals | 
					
						
							|  |  |  | 				default: | 
					
						
							|  |  |  | 					return nil, fmt.Errorf("unknown type %s for %s", field.Kind(), key) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return out, nil | 
					
						
							|  |  |  | } |