cmd.go 1.78 KB
Newer Older
Jeffrey Morgan's avatar
Jeffrey Morgan committed
1
2
3
4
package cmd

import (
	"context"
Bruce MacDonald's avatar
Bruce MacDonald committed
5
	"fmt"
Jeffrey Morgan's avatar
Jeffrey Morgan committed
6
7
8
9
10
	"log"
	"net"
	"os"
	"path"

Jeffrey Morgan's avatar
Jeffrey Morgan committed
11
12
	"github.com/jmorganca/ollama/api"
	"github.com/jmorganca/ollama/server"
Jeffrey Morgan's avatar
Jeffrey Morgan committed
13
	"github.com/spf13/cobra"
Jeffrey Morgan's avatar
Jeffrey Morgan committed
14
15
)

Bruce MacDonald's avatar
Bruce MacDonald committed
16
func cacheDir() string {
Jeffrey Morgan's avatar
Jeffrey Morgan committed
17
18
19
20
21
	home, err := os.UserHomeDir()
	if err != nil {
		panic(err)
	}

Bruce MacDonald's avatar
Bruce MacDonald committed
22
	return path.Join(home, ".ollama")
Jeffrey Morgan's avatar
Jeffrey Morgan committed
23
24
}

Bruce MacDonald's avatar
Bruce MacDonald committed
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
func run(model string) error {
	client, err := NewAPIClient()
	if err != nil {
		return err
	}
	pr := api.PullRequest{
		Model: model,
	}
	callback := func(progress string) {
		fmt.Println(progress)
	}
	_, err = client.Pull(context.Background(), &pr, callback)
	return err
}

Jeffrey Morgan's avatar
Jeffrey Morgan committed
40
func serve() error {
Michael Yang's avatar
Michael Yang committed
41
	ln, err := net.Listen("tcp", "127.0.0.1:11434")
Jeffrey Morgan's avatar
Jeffrey Morgan committed
42
43
44
45
46
47
48
49
	if err != nil {
		return err
	}

	return server.Serve(ln)
}

func NewAPIClient() (*api.Client, error) {
Jeffrey Morgan's avatar
Jeffrey Morgan committed
50
	return &api.Client{
Michael Yang's avatar
Michael Yang committed
51
		URL: "http://localhost:11434",
Jeffrey Morgan's avatar
Jeffrey Morgan committed
52
53
54
55
56
57
58
	}, nil
}

func NewCLI() *cobra.Command {
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	rootCmd := &cobra.Command{
Jeffrey Morgan's avatar
Jeffrey Morgan committed
59
		Use:   "ollama",
60
		Short: "Large language model runner",
Jeffrey Morgan's avatar
Jeffrey Morgan committed
61
62
63
64
65
66
		CompletionOptions: cobra.CompletionOptions{
			DisableDefaultCmd: true,
		},
		PersistentPreRun: func(cmd *cobra.Command, args []string) {
			// Disable usage printing on errors
			cmd.SilenceUsage = true
Bruce MacDonald's avatar
Bruce MacDonald committed
67
68
69
70
			// create the models directory and it's parent
			if err := os.MkdirAll(path.Join(cacheDir(), "models"), 0o700); err != nil {
				panic(err)
			}
Jeffrey Morgan's avatar
Jeffrey Morgan committed
71
72
73
74
75
76
		},
	}

	cobra.EnableCommandSorting = false

	runCmd := &cobra.Command{
Bruce MacDonald's avatar
Bruce MacDonald committed
77
		Use:   "run MODEL",
Jeffrey Morgan's avatar
Jeffrey Morgan committed
78
		Short: "Run a model",
Bruce MacDonald's avatar
Bruce MacDonald committed
79
80
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
Bruce MacDonald's avatar
Bruce MacDonald committed
81
			return run(args[0])
Jeffrey Morgan's avatar
Jeffrey Morgan committed
82
83
84
85
86
87
88
89
		},
	}

	serveCmd := &cobra.Command{
		Use:     "serve",
		Aliases: []string{"start"},
		Short:   "Start ollama",
		RunE: func(cmd *cobra.Command, args []string) error {
Jeffrey Morgan's avatar
Jeffrey Morgan committed
90
			return serve()
Jeffrey Morgan's avatar
Jeffrey Morgan committed
91
92
93
94
95
		},
	}

	rootCmd.AddCommand(
		serveCmd,
96
		runCmd,
Jeffrey Morgan's avatar
Jeffrey Morgan committed
97
98
99
100
	)

	return rootCmd
}