go-ollama: changed development to dev container and added streaming capabilities to methods v0.1.1
This commit is contained in:
22
.devcontainer/devcontainer.json
Normal file
22
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||||
|
// README at: https://github.com/devcontainers/templates/tree/main/src/go .
|
||||||
|
{
|
||||||
|
"name": "Go",
|
||||||
|
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/go:2-1.25-trixie"
|
||||||
|
|
||||||
|
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||||
|
// "features": {},
|
||||||
|
|
||||||
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
|
// "forwardPorts": [],
|
||||||
|
|
||||||
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
// "postCreateCommand": "go version",
|
||||||
|
|
||||||
|
// Configure tool-specific properties.
|
||||||
|
// "customizations": {},
|
||||||
|
|
||||||
|
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||||
|
// "remoteUser": "root"
|
||||||
|
}
|
||||||
12
.github/dependabot.yml
vendored
Normal file
12
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for more information:
|
||||||
|
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
# https://containers.dev/guide/dependabot
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "devcontainers"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
@@ -13,15 +13,15 @@ type CopyModelRequest struct {
|
|||||||
Destination string `json:"destination"`
|
Destination string `json:"destination"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) CopyModel(reqBody CopyModelRequest) (int, error) {
|
func (o Ollama) CopyModel(reqBody CopyModelRequest) error {
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/create", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/copy", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -31,12 +31,12 @@ func (o Ollama) CopyModel(reqBody CopyModelRequest) (int, error) {
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return resp.StatusCode, errors.New("status code is not 200")
|
return errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
return resp.StatusCode, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ollama
|
package ollama
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -41,15 +42,24 @@ type CreateModelResponse struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) CreateModel(reqBody CreateModelRequest) (CreateModelResponse, int, error) {
|
type CreateModelResponseStream struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Digest string `json:"digest"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
Completed int `json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) CreateModel(reqBody CreateModelRequest) (CreateModelResponse, error) {
|
||||||
|
reqBody.Stream = PtrOf(false)
|
||||||
|
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return CreateModelResponse{}, -1, err
|
return CreateModelResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/create", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/create", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return CreateModelResponse{}, -1, err
|
return CreateModelResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -59,17 +69,68 @@ func (o Ollama) CreateModel(reqBody CreateModelRequest) (CreateModelResponse, in
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return CreateModelResponse{}, -1, err
|
return CreateModelResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return CreateModelResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return CreateModelResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody CreateModelResponse
|
var respBody CreateModelResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return CreateModelResponse{}, -1, err
|
return CreateModelResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) CreateModelStream(reqBody CreateModelRequest, onChunk func(chunk CreateModelResponseStream)) error {
|
||||||
|
reqBody.Stream = PtrOf(true)
|
||||||
|
|
||||||
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/create", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, val := range o.customHeaders {
|
||||||
|
req.Header.Set(key, val)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return errors.New("status code is not 200")
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(resp.Body)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := bytes.TrimSpace(scanner.Bytes())
|
||||||
|
|
||||||
|
var chunk CreateModelResponseStream
|
||||||
|
if err := json.Unmarshal(line, &chunk); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
onChunk(chunk)
|
||||||
|
if chunk.Status == "success" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ type DeleteModelRequest struct {
|
|||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) DeleteModel(reqBody DeleteModelRequest) (int, error) {
|
func (o Ollama) DeleteModel(reqBody DeleteModelRequest) error {
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/delete", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/delete", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -30,12 +30,12 @@ func (o Ollama) DeleteModel(reqBody DeleteModelRequest) (int, error) {
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return resp.StatusCode, errors.New("status code is not 200")
|
return errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
return resp.StatusCode, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ollama
|
package ollama
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -96,15 +97,34 @@ type GenerateChatMessageResponse struct {
|
|||||||
} `json:"logprobs"`
|
} `json:"logprobs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) GenerateChatMessage(reqBody GenerateChatMessageRequest) (GenerateChatMessageResponse, int, error) {
|
type GenerateChatMessageResponseStream struct {
|
||||||
|
Model string `json:"model"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
Message struct {
|
||||||
|
Role string `json:"role"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
Thinking string `json:"thinking"`
|
||||||
|
ToolCalls []struct {
|
||||||
|
Function struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Arguments map[string]any `json:"arguments"`
|
||||||
|
} `json:"function"`
|
||||||
|
} `json:"tool_calls"`
|
||||||
|
Images []string `json:"images"`
|
||||||
|
} `json:"message"`
|
||||||
|
Done bool `json:"done"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) GenerateChatMessage(reqBody GenerateChatMessageRequest) (GenerateChatMessageResponse, error) {
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateChatMessageResponse{}, -1, err
|
return GenerateChatMessageResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/chat", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/chat", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateChatMessageResponse{}, -1, err
|
return GenerateChatMessageResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -114,17 +134,68 @@ func (o Ollama) GenerateChatMessage(reqBody GenerateChatMessageRequest) (Generat
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateChatMessageResponse{}, -1, err
|
return GenerateChatMessageResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return GenerateChatMessageResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return GenerateChatMessageResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody GenerateChatMessageResponse
|
var respBody GenerateChatMessageResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return GenerateChatMessageResponse{}, -1, err
|
return GenerateChatMessageResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) GenerateChatMessageStream(reqBody GenerateChatMessageRequest, onChunk func(chunk GenerateChatMessageResponseStream)) error {
|
||||||
|
reqBody.Stream = PtrOf(true)
|
||||||
|
|
||||||
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/chat", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, val := range o.customHeaders {
|
||||||
|
req.Header.Set(key, val)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return errors.New("status code is not 200")
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(resp.Body)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := bytes.TrimSpace(scanner.Bytes())
|
||||||
|
|
||||||
|
var chunk GenerateChatMessageResponseStream
|
||||||
|
if err := json.Unmarshal(line, &chunk); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
onChunk(chunk)
|
||||||
|
if chunk.Done {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,15 +36,15 @@ type GenerateEmbeddingsResponse struct {
|
|||||||
PromptEvalCount int `json:"prompt_eval_count"`
|
PromptEvalCount int `json:"prompt_eval_count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) GenerateEmbeddings(reqBody GenerateEmbeddingsRequest) (GenerateEmbeddingsResponse, int, error) {
|
func (o Ollama) GenerateEmbeddings(reqBody GenerateEmbeddingsRequest) (GenerateEmbeddingsResponse, error) {
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateEmbeddingsResponse{}, -1, err
|
return GenerateEmbeddingsResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/embed", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/embed", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateEmbeddingsResponse{}, -1, err
|
return GenerateEmbeddingsResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -54,17 +54,17 @@ func (o Ollama) GenerateEmbeddings(reqBody GenerateEmbeddingsRequest) (GenerateE
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateEmbeddingsResponse{}, -1, err
|
return GenerateEmbeddingsResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return GenerateEmbeddingsResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return GenerateEmbeddingsResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody GenerateEmbeddingsResponse
|
var respBody GenerateEmbeddingsResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return GenerateEmbeddingsResponse{}, -1, err
|
return GenerateEmbeddingsResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ollama
|
package ollama
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -16,6 +17,7 @@ type GenerateResponseRequest struct {
|
|||||||
Format string `json:"format,omitempty"`
|
Format string `json:"format,omitempty"`
|
||||||
System string `json:"system,omitempty"`
|
System string `json:"system,omitempty"`
|
||||||
Stream *bool `json:"stream,omitempty"`
|
Stream *bool `json:"stream,omitempty"`
|
||||||
|
Think *bool `json:"think,omitempty"`
|
||||||
Raw *bool `json:"raw,omitempty"`
|
Raw *bool `json:"raw,omitempty"`
|
||||||
KeepAlive string `json:"keep_alive,omitempty"`
|
KeepAlive string `json:"keep_alive,omitempty"`
|
||||||
Options *GenerateResponseRequestOptions `json:"options,omitempty"`
|
Options *GenerateResponseRequestOptions `json:"options,omitempty"`
|
||||||
@@ -59,15 +61,32 @@ type GenerateResponseResponse struct {
|
|||||||
} `json:"logprobs"`
|
} `json:"logprobs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) GenerateResponse(reqBody GenerateResponseRequest) (GenerateResponseResponse, int, error) {
|
type GenerateResponseResponseStream struct {
|
||||||
|
Model string `json:"model"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
Response string `json:"response"`
|
||||||
|
Thinking string `json:"thinking"`
|
||||||
|
Done bool `json:"done"`
|
||||||
|
DoneReason string `json:"done_reason"`
|
||||||
|
TotalDuration int `json:"total_duration"`
|
||||||
|
LoadDuration int `json:"load_duration"`
|
||||||
|
PromptEvalCount int `json:"prompt_eval_count"`
|
||||||
|
PromptEvalDuration int `json:"prompt_eval_duration"`
|
||||||
|
EvalCount int `json:"eval_count"`
|
||||||
|
EvalDuration int `json:"eval_duration"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) GenerateResponse(reqBody GenerateResponseRequest) (GenerateResponseResponse, error) {
|
||||||
|
reqBody.Stream = PtrOf(false)
|
||||||
|
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateResponseResponse{}, -1, err
|
return GenerateResponseResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/generate", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/generate", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateResponseResponse{}, -1, err
|
return GenerateResponseResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -77,17 +96,68 @@ func (o Ollama) GenerateResponse(reqBody GenerateResponseRequest) (GenerateRespo
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GenerateResponseResponse{}, -1, err
|
return GenerateResponseResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return GenerateResponseResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return GenerateResponseResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody GenerateResponseResponse
|
var respBody GenerateResponseResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return GenerateResponseResponse{}, -1, err
|
return GenerateResponseResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) GenerateResponseStream(reqBody GenerateResponseRequest, onChunk func(chunk GenerateResponseResponseStream)) error {
|
||||||
|
reqBody.Stream = PtrOf(true)
|
||||||
|
|
||||||
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/generate", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, val := range o.customHeaders {
|
||||||
|
req.Header.Set(key, val)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return errors.New("status code is not 200")
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(resp.Body)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := bytes.TrimSpace(scanner.Bytes())
|
||||||
|
|
||||||
|
var chunk GenerateResponseResponseStream
|
||||||
|
if err := json.Unmarshal(line, &chunk); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
onChunk(chunk)
|
||||||
|
if chunk.Done {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ type GetVersionResponse struct {
|
|||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) GetVersion() (GetVersionResponse, int, error) {
|
func (o Ollama) GetVersion() (GetVersionResponse, error) {
|
||||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/version", o.baseUrl), nil)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/version", o.baseUrl), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GetVersionResponse{}, -1, err
|
return GetVersionResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -23,17 +23,17 @@ func (o Ollama) GetVersion() (GetVersionResponse, int, error) {
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return GetVersionResponse{}, -1, err
|
return GetVersionResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return GetVersionResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return GetVersionResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody GetVersionResponse
|
var respBody GetVersionResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return GetVersionResponse{}, -1, err
|
return GetVersionResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ type ListModelsResponse struct {
|
|||||||
} `json:"models"`
|
} `json:"models"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) ListModels() (ListModelsResponse, int, error) {
|
func (o Ollama) ListModels() (ListModelsResponse, error) {
|
||||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/tags", o.baseUrl), nil)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/tags", o.baseUrl), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ListModelsResponse{}, -1, err
|
return ListModelsResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -38,17 +38,17 @@ func (o Ollama) ListModels() (ListModelsResponse, int, error) {
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ListModelsResponse{}, -1, err
|
return ListModelsResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return ListModelsResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return ListModelsResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody ListModelsResponse
|
var respBody ListModelsResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return ListModelsResponse{}, -1, err
|
return ListModelsResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ type ListRunningModelsResponse struct {
|
|||||||
} `json:"models"`
|
} `json:"models"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) ListRunningModels() (ListRunningModelsResponse, int, error) {
|
func (o Ollama) ListRunningModels() (ListRunningModelsResponse, error) {
|
||||||
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/ps", o.baseUrl), nil)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/ps", o.baseUrl), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ListRunningModelsResponse{}, -1, err
|
return ListRunningModelsResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -38,17 +38,17 @@ func (o Ollama) ListRunningModels() (ListRunningModelsResponse, int, error) {
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ListRunningModelsResponse{}, -1, err
|
return ListRunningModelsResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return ListRunningModelsResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return ListRunningModelsResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody ListRunningModelsResponse
|
var respBody ListRunningModelsResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return ListRunningModelsResponse{}, -1, err
|
return ListRunningModelsResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ollama
|
package ollama
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -18,15 +19,23 @@ type PullModelResponse struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) PullModel(reqBody PullModelRequest) (PullModelResponse, int, error) {
|
type PullModelResponseStream struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Digest string `json:"digest"`
|
||||||
|
Total int `json:"total"`
|
||||||
|
Completed int `json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) PullModel(reqBody PullModelRequest) (PullModelResponse, error) {
|
||||||
|
reqBody.Stream = PtrOf(false)
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PullModelResponse{}, -1, err
|
return PullModelResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/pull", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/pull", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PullModelResponse{}, -1, err
|
return PullModelResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -36,17 +45,67 @@ func (o Ollama) PullModel(reqBody PullModelRequest) (PullModelResponse, int, err
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PullModelResponse{}, -1, err
|
return PullModelResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return PullModelResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return PullModelResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody PullModelResponse
|
var respBody PullModelResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return PullModelResponse{}, -1, err
|
return PullModelResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) PullModelStream(reqBody PullModelRequest, onChunk func(chunk PullModelResponseStream)) error {
|
||||||
|
reqBody.Stream = PtrOf(true)
|
||||||
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/pull", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, val := range o.customHeaders {
|
||||||
|
req.Header.Set(key, val)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return errors.New("status code is not 200")
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(resp.Body)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := bytes.TrimSpace(scanner.Bytes())
|
||||||
|
|
||||||
|
var chunk PullModelResponseStream
|
||||||
|
if err := json.Unmarshal(line, &chunk); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
onChunk(chunk)
|
||||||
|
if chunk.Status == "success" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ollama
|
package ollama
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
@@ -18,15 +19,23 @@ type PushModelResponse struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) PushModel(reqBody PushModelRequest) (PushModelResponse, int, error) {
|
type PushModelResponseStream struct {
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
Status string `json:"status"`
|
||||||
if err != nil {
|
Digest string `json:"digest"`
|
||||||
return PushModelResponse{}, -1, err
|
Total int `json:"total"`
|
||||||
|
Completed int `json:"completed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/pull", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
func (o Ollama) PushModel(reqBody PushModelRequest) (PushModelResponse, error) {
|
||||||
|
reqBody.Stream = PtrOf(false)
|
||||||
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PushModelResponse{}, -1, err
|
return PushModelResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/push", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
|
if err != nil {
|
||||||
|
return PushModelResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -36,17 +45,68 @@ func (o Ollama) PushModel(reqBody PushModelRequest) (PushModelResponse, int, err
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return PushModelResponse{}, -1, err
|
return PushModelResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return PushModelResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return PushModelResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody PushModelResponse
|
var respBody PushModelResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return PushModelResponse{}, -1, err
|
return PushModelResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Ollama) PushModelStream(reqBody PushModelRequest, onChunk func(chunk PushModelResponseStream)) error {
|
||||||
|
reqBody.Stream = PtrOf(true)
|
||||||
|
|
||||||
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/push", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, val := range o.customHeaders {
|
||||||
|
req.Header.Set(key, val)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return errors.New("status code is not 200")
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(resp.Body)
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := bytes.TrimSpace(scanner.Bytes())
|
||||||
|
|
||||||
|
var chunk PushModelResponseStream
|
||||||
|
if err := json.Unmarshal(line, &chunk); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
onChunk(chunk)
|
||||||
|
if chunk.Status == "success" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,15 +29,15 @@ type ShowModelDetailsResponse struct {
|
|||||||
ModelInfo map[string]any `json:"model_info"`
|
ModelInfo map[string]any `json:"model_info"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o Ollama) ShowModelDetails(reqBody ShowModelDetailsRequest) (ShowModelDetailsResponse, int, error) {
|
func (o Ollama) ShowModelDetails(reqBody ShowModelDetailsRequest) (ShowModelDetailsResponse, error) {
|
||||||
reqBodyBytes, err := json.Marshal(reqBody)
|
reqBodyBytes, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ShowModelDetailsResponse{}, -1, err
|
return ShowModelDetailsResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/show", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/show", o.baseUrl), bytes.NewReader(reqBodyBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ShowModelDetailsResponse{}, -1, err
|
return ShowModelDetailsResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, val := range o.customHeaders {
|
for key, val := range o.customHeaders {
|
||||||
@@ -47,17 +47,17 @@ func (o Ollama) ShowModelDetails(reqBody ShowModelDetailsRequest) (ShowModelDeta
|
|||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ShowModelDetailsResponse{}, -1, err
|
return ShowModelDetailsResponse{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return ShowModelDetailsResponse{}, resp.StatusCode, errors.New("status code is not 200")
|
return ShowModelDetailsResponse{}, errors.New("status code is not 200")
|
||||||
}
|
}
|
||||||
|
|
||||||
var respBody ShowModelDetailsResponse
|
var respBody ShowModelDetailsResponse
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&respBody); err != nil {
|
||||||
return ShowModelDetailsResponse{}, -1, err
|
return ShowModelDetailsResponse{}, err
|
||||||
}
|
}
|
||||||
return respBody, resp.StatusCode, nil
|
return respBody, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user