ollama source for Momentry Core verification
This commit is contained in:
107
llm/status.go
Normal file
107
llm/status.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package llm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// StatusWriter is a writer that captures error messages from the llama runner process
|
||||
type StatusWriter struct {
|
||||
out io.Writer
|
||||
// StartRunner wires both Stdout and Stderr to the same StatusWriter, and
|
||||
// os/exec serializes Write calls in that case.
|
||||
lastErrMsg atomic.Value
|
||||
}
|
||||
|
||||
const maxCapturedErrorBytes = 8 * 1024
|
||||
|
||||
func NewStatusWriter(out io.Writer) *StatusWriter {
|
||||
return &StatusWriter{
|
||||
out: out,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *StatusWriter) LastError() string {
|
||||
if w == nil {
|
||||
return ""
|
||||
}
|
||||
if v := w.lastErrMsg.Load(); v != nil {
|
||||
return v.(string)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (w *StatusWriter) SetLastError(msg string) {
|
||||
if w == nil {
|
||||
return
|
||||
}
|
||||
w.lastErrMsg.Store(msg)
|
||||
}
|
||||
|
||||
func (w *StatusWriter) AppendError(msg string) {
|
||||
if w == nil || msg == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if current := w.LastError(); current != "" {
|
||||
msg = current + "\n" + msg
|
||||
}
|
||||
|
||||
if len(msg) > maxCapturedErrorBytes {
|
||||
msg = msg[len(msg)-maxCapturedErrorBytes:]
|
||||
if i := strings.IndexByte(msg, '\n'); i >= 0 {
|
||||
msg = msg[i+1:]
|
||||
}
|
||||
}
|
||||
|
||||
w.SetLastError(msg)
|
||||
}
|
||||
|
||||
// TODO - regex matching to detect errors like
|
||||
// libcublasLt.so.11: cannot open shared object file: No such file or directory
|
||||
// TODO - if we later see error lines split across multiple Write calls in real
|
||||
// logs, add a small rolling buffer here to capture those fragments.
|
||||
|
||||
var errorPrefixes = []string{
|
||||
"mlx:",
|
||||
"MLX:",
|
||||
"panic:",
|
||||
"fatal error:",
|
||||
"error:",
|
||||
"Error:",
|
||||
"CUDA error",
|
||||
"ROCm error",
|
||||
"cudaMalloc failed",
|
||||
"\"ERR\"",
|
||||
"error loading model",
|
||||
"GGML_ASSERT",
|
||||
"Deepseek2 does not support K-shift",
|
||||
"signal arrived during cgo execution",
|
||||
"llama_init_from_model:",
|
||||
}
|
||||
|
||||
func (w *StatusWriter) Write(b []byte) (int, error) {
|
||||
var errMsg string
|
||||
errStart := -1
|
||||
var errPrefix string
|
||||
for _, prefix := range errorPrefixes {
|
||||
if i := bytes.Index(b, []byte(prefix)); i >= 0 && (errStart < 0 || i < errStart) {
|
||||
errStart = i
|
||||
errPrefix = prefix
|
||||
}
|
||||
}
|
||||
if errStart >= 0 {
|
||||
line := b[errStart+len(errPrefix):]
|
||||
if j := bytes.IndexByte(line, '\n'); j >= 0 {
|
||||
line = line[:j]
|
||||
}
|
||||
errMsg = errPrefix + string(bytes.TrimRight(line, " \t\r"))
|
||||
}
|
||||
if errMsg != "" {
|
||||
w.AppendError(errMsg)
|
||||
}
|
||||
|
||||
return w.out.Write(b)
|
||||
}
|
||||
Reference in New Issue
Block a user