Compare commits

..

1 Commits

Author SHA1 Message Date
Patrick Devine
7550fd1b7f use a pulsating spinner 2023-11-20 17:27:53 -08:00
5 changed files with 42 additions and 53 deletions

View File

@@ -216,10 +216,6 @@ See the [API documentation](./docs/api.md) for all endpoints.
## Community Integrations
### Mobile
- [Mobile Artificial Intelligence Distribution](https://github.com/MaidFoundation/Maid) (Maid)
### Web & Desktop
- [HTML UI](https://github.com/rtcfirefly/ollama-ui)
@@ -240,8 +236,6 @@ See the [API documentation](./docs/api.md) for all endpoints.
- [ollama.nvim](https://github.com/nomnivore/ollama.nvim)
- [ogpt.nvim](https://github.com/huynle/ogpt.nvim)
- [gptel Emacs client](https://github.com/karthink/gptel)
- [ollama package for archlinux](https://archlinux.org/packages/extra/x86_64/ollama/)
- [Oatmeal](https://github.com/dustinblackman/oatmeal)
### Libraries

14
main.go
View File

@@ -2,11 +2,25 @@ package main
import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
"github.com/jmorganca/ollama/cmd"
"github.com/spf13/cobra"
)
func main() {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT)
go func() {
<-sigChan
fmt.Print("\033[?25h")
os.Exit(0)
}()
cobra.CheckErr(cmd.NewCLI().ExecuteContext(context.Background()))
}

View File

@@ -42,19 +42,6 @@ func NewBar(message string, maxValue, initialValue int64) *Bar {
}
}
// formatDuration limits the rendering of a time.Duration to 2 units
func formatDuration(d time.Duration) string {
if d >= 100*time.Hour {
return "99h+"
}
if d >= time.Hour {
return fmt.Sprintf("%dh%dm", int(d.Hours()), int(d.Minutes())%60)
}
return d.Round(time.Second).String()
}
func (b *Bar) String() string {
termWidth, _, err := term.GetSize(int(os.Stderr.Fd()))
if err != nil {
@@ -78,42 +65,39 @@ func (b *Bar) String() string {
}
fmt.Fprintf(&pre, "%3.0f%% ", math.Floor(b.percent()))
fmt.Fprintf(&suf, "(%s/%s", format.HumanBytes(b.currentValue), format.HumanBytes(b.maxValue))
stats := b.Stats()
rate := stats.rate
if stats.value > b.initialValue && stats.value < b.maxValue {
fmt.Fprintf(&suf, ", %s/s", format.HumanBytes(int64(rate)))
rate := int64(stats.rate)
if rate > 0 {
fmt.Fprintf(&suf, ", %s/s", format.HumanBytes(rate))
}
fmt.Fprintf(&suf, ")")
var timing string
if stats.value > b.initialValue && stats.value < b.maxValue {
timing = fmt.Sprintf("[%s:%s]", formatDuration(time.Since(b.started)), formatDuration(stats.remaining))
elapsed := time.Since(b.started)
if b.percent() < 100 && rate > 0 {
fmt.Fprintf(&suf, " [%s:%s]", elapsed.Round(time.Second), stats.remaining)
} else {
fmt.Fprintf(&suf, " ")
}
// 44 is the maximum width for the stats on the right of the progress bar
pad := 44 - suf.Len() - len(timing)
if pad > 0 {
suf.WriteString(strings.Repeat(" ", pad))
}
suf.WriteString(timing)
mid.WriteString("▕")
// add 3 extra spaces: 2 boundary characters and 1 space at the end
f := termWidth - pre.Len() - suf.Len() - 3
n := int(float64(f) * b.percent() / 100)
if f > 0 {
mid.WriteString("▕")
if n > 0 {
mid.WriteString(strings.Repeat("█", n))
if f-n > 0 {
mid.WriteString(strings.Repeat(" ", f-n))
}
mid.WriteString("▏")
}
if f-n > 0 {
mid.WriteString(strings.Repeat(" ", f-n))
}
mid.WriteString("▏")
return pre.String() + mid.String() + suf.String()
}
@@ -156,8 +140,6 @@ func (b *Bar) Stats() Stats {
var remaining time.Duration
if rate > 0 {
remaining = time.Second * time.Duration((float64(b.maxValue-b.currentValue))/(float64(rate)))
} else {
remaining = time.Duration(math.MaxInt64)
}
b.stats = Stats{

View File

@@ -81,9 +81,6 @@ func (p *Progress) render() error {
p.mu.Lock()
defer p.mu.Unlock()
fmt.Fprint(p.w, "\033[?25l")
defer fmt.Fprint(p.w, "\033[?25h")
// clear already rendered progress lines
for i := 0; i < p.pos; i++ {
if i > 0 {
@@ -107,6 +104,9 @@ func (p *Progress) render() error {
func (p *Progress) start() {
p.ticker = time.NewTicker(100 * time.Millisecond)
fmt.Fprint(p.w, "\033[?25l")
defer fmt.Fprintln(p.w, "\033[?25h")
for range p.ticker.C {
p.render()
}

View File

@@ -10,8 +10,6 @@ type Spinner struct {
message string
messageWidth int
parts []string
value int
ticker *time.Ticker
@@ -22,10 +20,8 @@ type Spinner struct {
func NewSpinner(message string) *Spinner {
s := &Spinner{
message: message,
parts: []string{
"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏",
},
started: time.Now(),
value: 231,
}
go s.start()
return s
@@ -48,18 +44,21 @@ func (s *Spinner) String() string {
}
if s.stopped.IsZero() {
spinner := s.parts[s.value]
sb.WriteString(spinner)
sb.WriteString(" ")
sb.WriteString(fmt.Sprintf("\033[48;5;%dm ", s.value))
sb.WriteString("\033[0m")
}
return sb.String()
}
func (s *Spinner) start() {
s.ticker = time.NewTicker(100 * time.Millisecond)
s.ticker = time.NewTicker(40 * time.Millisecond)
for range s.ticker.C {
s.value = (s.value + 1) % len(s.parts)
if s.value < 255 {
s.value++
} else {
s.value = 231
}
if !s.stopped.IsZero() {
return
}