157 lines
3.8 KiB
Go
157 lines
3.8 KiB
Go
package gollama
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
"time"
|
|
|
|
"github.com/ollama/ollama/api"
|
|
)
|
|
|
|
// Model describes a locally available Ollama model.
|
|
type Model struct {
|
|
Name string
|
|
Size int64
|
|
ModifiedAt time.Time
|
|
Digest string
|
|
Family string
|
|
ParameterSize string
|
|
Quantization string
|
|
}
|
|
|
|
// ModelInfo contains detailed information from Ollama's show endpoint.
|
|
type ModelInfo struct {
|
|
Name string
|
|
License string
|
|
Modelfile string
|
|
Parameters string
|
|
Template string
|
|
System string
|
|
ModifiedAt time.Time
|
|
}
|
|
|
|
// ModelNames returns sorted names of locally available models.
|
|
func (c *Client) ModelNames(ctx context.Context) ([]string, error) {
|
|
models, err := c.Models(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
names := make([]string, len(models))
|
|
for i, m := range models {
|
|
names[i] = m.Name
|
|
}
|
|
sort.Strings(names)
|
|
return names, nil
|
|
}
|
|
|
|
// Models returns locally available models with metadata.
|
|
func (c *Client) Models(ctx context.Context) ([]Model, error) {
|
|
resp, err := c.api.List(ctx)
|
|
if err != nil {
|
|
return nil, wrapError("list", "", err)
|
|
}
|
|
out := make([]Model, 0, len(resp.Models))
|
|
for _, m := range resp.Models {
|
|
out = append(out, listModelToModel(m))
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func listModelToModel(m api.ListModelResponse) Model {
|
|
name := m.Name
|
|
if name == "" {
|
|
name = m.Model
|
|
}
|
|
return Model{
|
|
Name: name,
|
|
Size: m.Size,
|
|
ModifiedAt: m.ModifiedAt,
|
|
Digest: m.Digest,
|
|
Family: m.Details.Family,
|
|
ParameterSize: m.Details.ParameterSize,
|
|
Quantization: m.Details.QuantizationLevel,
|
|
}
|
|
}
|
|
|
|
// Pull downloads a model and blocks until complete.
|
|
func (c *Client) Pull(ctx context.Context, name string) error {
|
|
return c.PullWithProgress(ctx, name, nil)
|
|
}
|
|
|
|
// PullWithProgress downloads a model, optionally reporting progress.
|
|
func (c *Client) PullWithProgress(ctx context.Context, name string, fn func(Progress) error) error {
|
|
stream := false
|
|
req := &api.PullRequest{Model: name, Stream: &stream}
|
|
err := c.api.Pull(ctx, req, func(p api.ProgressResponse) error {
|
|
if fn == nil {
|
|
return nil
|
|
}
|
|
return fn(Progress{
|
|
Status: p.Status,
|
|
Digest: p.Digest,
|
|
Total: p.Total,
|
|
Completed: p.Completed,
|
|
})
|
|
})
|
|
return wrapError("pull", name, err)
|
|
}
|
|
|
|
// Show returns detailed information about a model.
|
|
func (c *Client) Show(ctx context.Context, name string) (*ModelInfo, error) {
|
|
resp, err := c.api.Show(ctx, &api.ShowRequest{Model: name})
|
|
if err != nil {
|
|
return nil, wrapError("show", name, err)
|
|
}
|
|
return &ModelInfo{
|
|
Name: name,
|
|
License: resp.License,
|
|
Modelfile: resp.Modelfile,
|
|
Parameters: resp.Parameters,
|
|
Template: resp.Template,
|
|
System: resp.System,
|
|
ModifiedAt: resp.ModifiedAt,
|
|
}, nil
|
|
}
|
|
|
|
// ModelDefaults parses a model's modelfile parameters into an OptionSet.
|
|
func (c *Client) ModelDefaults(ctx context.Context, name string) (OptionSet, error) {
|
|
info, err := c.Show(ctx, name)
|
|
if err != nil {
|
|
return OptionSet{}, err
|
|
}
|
|
return parseModelfileParameters(info.Parameters)
|
|
}
|
|
|
|
// Delete removes a model from the local Ollama instance.
|
|
func (c *Client) Delete(ctx context.Context, name string) error {
|
|
return wrapError("delete", name, c.api.Delete(ctx, &api.DeleteRequest{Model: name}))
|
|
}
|
|
|
|
// RunningModel describes a model currently loaded in memory.
|
|
type RunningModel struct {
|
|
Name string
|
|
Size int64
|
|
Expires time.Time
|
|
}
|
|
|
|
// RunningModels returns models currently loaded in Ollama memory.
|
|
func (c *Client) RunningModels(ctx context.Context) ([]RunningModel, error) {
|
|
resp, err := c.api.ListRunning(ctx)
|
|
if err != nil {
|
|
return nil, wrapError("list_running", "", err)
|
|
}
|
|
out := make([]RunningModel, 0, len(resp.Models))
|
|
for _, m := range resp.Models {
|
|
name := m.Name
|
|
if name == "" {
|
|
name = m.Model
|
|
}
|
|
out = append(out, RunningModel{
|
|
Name: name,
|
|
Size: m.Size,
|
|
Expires: m.ExpiresAt,
|
|
})
|
|
}
|
|
return out, nil
|
|
}
|