Add ModifiedAt Field to /api/show (#5033)

* Add Mod Time to Show

* Error Handling
This commit is contained in:
royjhan 2024-06-15 20:53:56 -07:00 committed by GitHub
parent c7b77004e3
commit 89c79bec8c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 21 deletions

View file

@ -238,6 +238,7 @@ type ShowResponse struct {
System string `json:"system,omitempty"` System string `json:"system,omitempty"`
Details ModelDetails `json:"details,omitempty"` Details ModelDetails `json:"details,omitempty"`
Messages []Message `json:"messages,omitempty"` Messages []Message `json:"messages,omitempty"`
ModifiedAt time.Time `json:"modified_at,omitempty"`
} }
// CopyRequest is the request passed to [Client.Copy]. // CopyRequest is the request passed to [Client.Copy].

View file

@ -646,9 +646,12 @@ func (s *Server) ShowModelHandler(c *gin.Context) {
resp, err := GetModelInfo(req) resp, err := GetModelInfo(req)
if err != nil { if err != nil {
if os.IsNotExist(err) { switch {
case os.IsNotExist(err):
c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found", req.Model)}) c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found", req.Model)})
} else { case err.Error() == "invalid model name":
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
default:
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
} }
return return
@ -658,44 +661,55 @@ func (s *Server) ShowModelHandler(c *gin.Context) {
} }
func GetModelInfo(req api.ShowRequest) (*api.ShowResponse, error) { func GetModelInfo(req api.ShowRequest) (*api.ShowResponse, error) {
model, err := GetModel(req.Model) m, err := GetModel(req.Model)
if err != nil { if err != nil {
return nil, err return nil, err
} }
modelDetails := api.ModelDetails{ modelDetails := api.ModelDetails{
ParentModel: model.ParentModel, ParentModel: m.ParentModel,
Format: model.Config.ModelFormat, Format: m.Config.ModelFormat,
Family: model.Config.ModelFamily, Family: m.Config.ModelFamily,
Families: model.Config.ModelFamilies, Families: m.Config.ModelFamilies,
ParameterSize: model.Config.ModelType, ParameterSize: m.Config.ModelType,
QuantizationLevel: model.Config.FileType, QuantizationLevel: m.Config.FileType,
} }
if req.System != "" { if req.System != "" {
model.System = req.System m.System = req.System
} }
if req.Template != "" { if req.Template != "" {
model.Template = req.Template m.Template = req.Template
} }
msgs := make([]api.Message, 0) msgs := make([]api.Message, 0)
for _, msg := range model.Messages { for _, msg := range m.Messages {
msgs = append(msgs, api.Message{Role: msg.Role, Content: msg.Content}) msgs = append(msgs, api.Message{Role: msg.Role, Content: msg.Content})
} }
n := model.ParseName(req.Model)
if !n.IsValid() {
return nil, fmt.Errorf("invalid model name")
}
manifest, err := ParseNamedManifest(n)
if err != nil {
return nil, err
}
resp := &api.ShowResponse{ resp := &api.ShowResponse{
License: strings.Join(model.License, "\n"), License: strings.Join(m.License, "\n"),
System: model.System, System: m.System,
Template: model.Template, Template: m.Template,
Details: modelDetails, Details: modelDetails,
Messages: msgs, Messages: msgs,
ModifiedAt: manifest.fi.ModTime(),
} }
var params []string var params []string
cs := 30 cs := 30
for k, v := range model.Options { for k, v := range m.Options {
switch val := v.(type) { switch val := v.(type) {
case []interface{}: case []interface{}:
for _, nv := range val { for _, nv := range val {
@ -709,15 +723,15 @@ func GetModelInfo(req api.ShowRequest) (*api.ShowResponse, error) {
for k, v := range req.Options { for k, v := range req.Options {
if _, ok := req.Options[k]; ok { if _, ok := req.Options[k]; ok {
model.Options[k] = v m.Options[k] = v
} }
} }
var sb strings.Builder var sb strings.Builder
fmt.Fprintln(&sb, "# Modelfile generated by \"ollama show\"") fmt.Fprintln(&sb, "# Modelfile generated by \"ollama show\"")
fmt.Fprintln(&sb, "# To build a new Modelfile based on this, replace FROM with:") fmt.Fprintln(&sb, "# To build a new Modelfile based on this, replace FROM with:")
fmt.Fprintf(&sb, "# FROM %s\n\n", model.ShortName) fmt.Fprintf(&sb, "# FROM %s\n\n", m.ShortName)
fmt.Fprint(&sb, model.String()) fmt.Fprint(&sb, m.String())
resp.Modelfile = sb.String() resp.Modelfile = sb.String()
return resp, nil return resp, nil