[GH-ISSUE #3223] Go client marshals ChatRequest.KeepAlive into wrong data type #48497

Closed
opened 2026-04-28 08:44:12 -05:00 by GiteaMirror · 1 comment
Owner

Originally created by @jankammerath on GitHub (Mar 18, 2024).
Original GitHub issue: https://github.com/ollama/ollama/issues/3223

As described by @jmorganca in https://github.com/ollama/ollama/issues/2343, the keep_alive field can be 0, -1 or another value indicating how long the model shall stay in memory.

The following Go code defines the keep_alive field as another struct with a Duration in it.
7ed3e94105/api/types.go (L45)

The current implementation results in the keep_alive being marshaled into {"Duration":86400000000000}

Here's a Playground example on how the ChatRequest struct is marshaled into JSON in the current implementation.

// You can edit this code!
// Click here and start typing.
package main

import (
	"encoding/json"
	"fmt"
	"time"
)

type Duration struct {
	time.Duration
}

type ChatRequest struct {
	Model     string    `json:"model"`
	KeepAlive *Duration `json:"keep_alive,omitempty"`

	Options map[string]interface{} `json:"options"`
}

func main() {
	request := ChatRequest{
		Model: "model-name",
		// keep alive for 24 hours
		KeepAlive: &Duration{Duration: time.Hour * 24},
	}

	jsonData, err := json.Marshal(request)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(string(jsonData))
}

The output of this is as follows.

{"model":"model-name","keep_alive":{"Duration":86400000000000},"options":null}

A possible solution could be to change the keep_alive field to an int64.

Originally created by @jankammerath on GitHub (Mar 18, 2024). Original GitHub issue: https://github.com/ollama/ollama/issues/3223 As described by @jmorganca in https://github.com/ollama/ollama/issues/2343, the `keep_alive` field can be `0`, `-1` or another value indicating how long the model shall stay in memory. The following Go code defines the `keep_alive` field as another struct with a Duration in it. https://github.com/ollama/ollama/blob/7ed3e941058a47464a1ee97cd16f464eb788e396/api/types.go#L45 The current implementation results in the `keep_alive` being marshaled into `{"Duration":86400000000000}` Here's a Playground example on how the `ChatRequest` struct is marshaled into JSON in the current implementation. ``` // You can edit this code! // Click here and start typing. package main import ( "encoding/json" "fmt" "time" ) type Duration struct { time.Duration } type ChatRequest struct { Model string `json:"model"` KeepAlive *Duration `json:"keep_alive,omitempty"` Options map[string]interface{} `json:"options"` } func main() { request := ChatRequest{ Model: "model-name", // keep alive for 24 hours KeepAlive: &Duration{Duration: time.Hour * 24}, } jsonData, err := json.Marshal(request) if err != nil { fmt.Println(err) } fmt.Println(string(jsonData)) } ``` The output of this is as follows. `{"model":"model-name","keep_alive":{"Duration":86400000000000},"options":null}` A possible solution could be to change the `keep_alive` field to an `int64`.
Author
Owner

@mxyng commented on GitHub (Mar 19, 2024):

@jmorganca is correct but he's missing some context. keep_alive has type Duration which has a custom JSON unmarshaler that transforms a number, e.g. -1, into a Duration. Since you're using the Go type directly, this does not apply. Duration also doesn't not have a custom marshaler which is why it's gets marshaled into "keep_alive": {"Duration": ...}

<!-- gh-comment-id:2006469679 --> @mxyng commented on GitHub (Mar 19, 2024): @jmorganca is correct but he's missing some context. `keep_alive` has type Duration which has a custom JSON unmarshaler that transforms a number, e.g. -1, into a Duration. Since you're using the Go type directly, this does not apply. Duration also doesn't not have a custom marshaler which is why it's gets marshaled into `"keep_alive": {"Duration": ...}`
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/ollama#48497