Merge pull request 'chore: Go 1.26 modernization' (#1) from chore/go-1.26-modernization into main
This commit is contained in:
commit
8f3722f7bd
33 changed files with 126 additions and 109 deletions
|
|
@ -161,7 +161,7 @@ func (b *HTTPBackend) doRequest(ctx context.Context, body []byte) (string, error
|
|||
}
|
||||
|
||||
if len(chatResp.Choices) == 0 {
|
||||
return "", fmt.Errorf("no choices in response")
|
||||
return "", errors.New("no choices in response")
|
||||
}
|
||||
|
||||
return chatResp.Choices[0].Message.Content, nil
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ package ml
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"errors"
|
||||
"iter"
|
||||
|
||||
"forge.lthn.ai/core/go-inference"
|
||||
|
|
@ -73,7 +73,7 @@ func (m *HTTPTextModel) Chat(ctx context.Context, messages []inference.Message,
|
|||
|
||||
// Classify is not supported by HTTP backends. Returns an error.
|
||||
func (m *HTTPTextModel) Classify(_ context.Context, _ []string, _ ...inference.GenerateOption) ([]inference.ClassifyResult, error) {
|
||||
return nil, fmt.Errorf("classify not supported by HTTP backend")
|
||||
return nil, errors.New("classify not supported by HTTP backend")
|
||||
}
|
||||
|
||||
// BatchGenerate processes multiple prompts sequentially via Generate.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"maps"
|
||||
|
|
@ -319,7 +320,7 @@ func runAB(cmd *cli.Command, args []string) error {
|
|||
}
|
||||
|
||||
if len(results) == 0 {
|
||||
return fmt.Errorf("no results to compare")
|
||||
return errors.New("no results to compare")
|
||||
}
|
||||
|
||||
// Build condition summaries
|
||||
|
|
@ -551,7 +552,7 @@ func loadABProbes() ([]abProbe, error) {
|
|||
|
||||
func loadABKernels() ([]abKernelDef, error) {
|
||||
if len(abKernels) == 0 {
|
||||
return nil, fmt.Errorf("at least one --kernel is required (raw file content is used as system message with zero instruction)")
|
||||
return nil, errors.New("at least one --kernel is required (raw file content is used as system message with zero instruction)")
|
||||
}
|
||||
|
||||
var defs []abKernelDef
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -32,7 +33,7 @@ func runApprove(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB required")
|
||||
return errors.New("--db or LEM_DB required")
|
||||
}
|
||||
|
||||
output := approveOutput
|
||||
|
|
|
|||
|
|
@ -3,19 +3,21 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
"forge.lthn.ai/core/go-i18n/reversal"
|
||||
"forge.lthn.ai/core/go-ml"
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
)
|
||||
|
||||
// grammarScore holds grammar v3 quality signals derived from a GrammarImprint.
|
||||
|
|
@ -65,10 +67,10 @@ func computeGrammarScore(imp reversal.GrammarImprint) grammarScore {
|
|||
}
|
||||
|
||||
tenseNorm := gs.TenseEntropy / 1.585 // max entropy for 3 tenses = log2(3)
|
||||
vocabNorm := math.Min(gs.VocabRichness*10, 1.0)
|
||||
questionNorm := math.Min(gs.QuestionRatio*5, 1.0)
|
||||
verbNorm := math.Min(float64(gs.VerbDiversity)/30.0, 1.0)
|
||||
nounNorm := math.Min(float64(gs.NounDiversity)/40.0, 1.0)
|
||||
vocabNorm := min(gs.VocabRichness*10, 1.0)
|
||||
questionNorm := min(gs.QuestionRatio*5, 1.0)
|
||||
verbNorm := min(float64(gs.VerbDiversity)/30.0, 1.0)
|
||||
nounNorm := min(float64(gs.NounDiversity)/40.0, 1.0)
|
||||
|
||||
gs.Composite = 0.25*tenseNorm +
|
||||
0.25*vocabNorm +
|
||||
|
|
@ -176,16 +178,16 @@ type benchmarkResult struct {
|
|||
|
||||
// benchmarkSummary holds aggregate comparison metrics.
|
||||
type benchmarkSummary struct {
|
||||
BaselineModel string `json:"baseline_model"`
|
||||
TrainedModel string `json:"trained_model"`
|
||||
TotalPrompts int `json:"total_prompts"`
|
||||
AvgBaselineLEK float64 `json:"avg_baseline_lek"`
|
||||
AvgTrainedLEK float64 `json:"avg_trained_lek"`
|
||||
AvgDelta float64 `json:"avg_delta"`
|
||||
Improved int `json:"improved"`
|
||||
Regressed int `json:"regressed"`
|
||||
Unchanged int `json:"unchanged"`
|
||||
Duration string `json:"duration"`
|
||||
BaselineModel string `json:"baseline_model"`
|
||||
TrainedModel string `json:"trained_model"`
|
||||
TotalPrompts int `json:"total_prompts"`
|
||||
AvgBaselineLEK float64 `json:"avg_baseline_lek"`
|
||||
AvgTrainedLEK float64 `json:"avg_trained_lek"`
|
||||
AvgDelta float64 `json:"avg_delta"`
|
||||
Improved int `json:"improved"`
|
||||
Regressed int `json:"regressed"`
|
||||
Unchanged int `json:"unchanged"`
|
||||
Duration string `json:"duration"`
|
||||
|
||||
// Grammar v3 aggregates
|
||||
AvgBaselineGrammar float64 `json:"avg_baseline_grammar"`
|
||||
|
|
@ -351,7 +353,7 @@ func runBenchmark(cmd *cli.Command, args []string) error {
|
|||
|
||||
n := float64(len(results))
|
||||
if n == 0 {
|
||||
return fmt.Errorf("no results to compare")
|
||||
return errors.New("no results to compare")
|
||||
}
|
||||
|
||||
summary := benchmarkSummary{
|
||||
|
|
@ -464,6 +466,6 @@ func loadBenchmarkPrompts() ([]benchPrompt, error) {
|
|||
prompts = append(prompts, benchPrompt{id: id, prompt: r.Prompt})
|
||||
}
|
||||
|
||||
sort.Slice(prompts, func(i, j int) bool { return prompts[i].id < prompts[j].id })
|
||||
slices.SortFunc(prompts, func(a, b benchPrompt) int { return cmp.Compare(a.id, b.id) })
|
||||
return prompts, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ func runCoverage(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB required")
|
||||
return errors.New("--db or LEM_DB required")
|
||||
}
|
||||
|
||||
db, err := ml.OpenDB(path)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -10,10 +11,10 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
expandWorker string
|
||||
expandOutput string
|
||||
expandLimit int
|
||||
expandDryRun bool
|
||||
expandWorker string
|
||||
expandOutput string
|
||||
expandLimit int
|
||||
expandDryRun bool
|
||||
)
|
||||
|
||||
var expandCmd = &cli.Command{
|
||||
|
|
@ -32,7 +33,7 @@ func init() {
|
|||
|
||||
func runExpand(cmd *cli.Command, args []string) error {
|
||||
if modelName == "" {
|
||||
return fmt.Errorf("--model is required")
|
||||
return errors.New("--model is required")
|
||||
}
|
||||
|
||||
path := dbPath
|
||||
|
|
@ -40,7 +41,7 @@ func runExpand(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB env is required")
|
||||
return errors.New("--db or LEM_DB env is required")
|
||||
}
|
||||
|
||||
if expandWorker == "" {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ func runExpandStatus(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB required")
|
||||
return errors.New("--db or LEM_DB required")
|
||||
}
|
||||
|
||||
db, err := ml.OpenDB(path)
|
||||
|
|
@ -80,8 +81,8 @@ func runExpandStatus(cmd *cli.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// toInt converts an interface{} (typically from QueryRows) to int.
|
||||
func toInt(v interface{}) int {
|
||||
// toInt converts an any (typically from QueryRows) to int.
|
||||
func toInt(v any) int {
|
||||
switch n := v.(type) {
|
||||
case int:
|
||||
return n
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ func runExport(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB env is required")
|
||||
return errors.New("--db or LEM_DB env is required")
|
||||
}
|
||||
|
||||
db, err := ml.OpenDB(path)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -17,7 +18,7 @@ var importCmd = &cli.Command{
|
|||
}
|
||||
|
||||
var (
|
||||
importSkipM3 bool
|
||||
importSkipM3 bool
|
||||
importDataDir string
|
||||
importM3Host string
|
||||
)
|
||||
|
|
@ -34,7 +35,7 @@ func runImportAll(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB required")
|
||||
return errors.New("--db or LEM_DB required")
|
||||
}
|
||||
|
||||
dataDir := importDataDir
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
|
|
@ -33,10 +33,10 @@ func init() {
|
|||
|
||||
func runIngest(cmd *cli.Command, args []string) error {
|
||||
if modelName == "" {
|
||||
return fmt.Errorf("--model is required")
|
||||
return errors.New("--model is required")
|
||||
}
|
||||
if ingestContent == "" && ingestCapability == "" && ingestTraining == "" {
|
||||
return fmt.Errorf("at least one of --content, --capability, or --training-log is required")
|
||||
return errors.New("at least one of --content, --capability, or --training-log is required")
|
||||
}
|
||||
|
||||
influx := ml.NewInfluxClient(influxURL, influxDB)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ func runInventory(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB required")
|
||||
return errors.New("--db or LEM_DB required")
|
||||
}
|
||||
|
||||
db, err := ml.OpenDB(path)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
|
@ -13,8 +14,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"forge.lthn.ai/core/go-ml"
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
"forge.lthn.ai/core/go-ml"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
|
|
@ -90,9 +91,9 @@ type lessonPrompt struct {
|
|||
|
||||
// lessonState tracks progress through a lesson.
|
||||
type lessonState struct {
|
||||
LessonID string `json:"lesson_id"`
|
||||
Completed map[string]lessonResult `json:"completed"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
LessonID string `json:"lesson_id"`
|
||||
Completed map[string]lessonResult `json:"completed"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
type lessonResult struct {
|
||||
|
|
@ -162,7 +163,7 @@ func runLesson(cmd *cli.Command, args []string) error {
|
|||
)
|
||||
|
||||
if len(lesson.Prompts) == 0 {
|
||||
return fmt.Errorf("lesson has no prompts")
|
||||
return errors.New("lesson has no prompts")
|
||||
}
|
||||
|
||||
// Load state for resume
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ func runLive(cmd *cli.Command, args []string) error {
|
|||
}
|
||||
|
||||
// sqlScalar extracts the first numeric value from a QuerySQL result.
|
||||
func sqlScalar(rows []map[string]interface{}) int {
|
||||
func sqlScalar(rows []map[string]any) int {
|
||||
if len(rows) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ func runMetrics(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB required")
|
||||
return errors.New("--db or LEM_DB required")
|
||||
}
|
||||
|
||||
db, err := ml.OpenDB(path)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ func runNormalize(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB env is required")
|
||||
return errors.New("--db or LEM_DB env is required")
|
||||
}
|
||||
|
||||
db, err := ml.OpenDBReadWrite(path)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ func init() {
|
|||
|
||||
func runProbe(cmd *cli.Command, args []string) error {
|
||||
if apiURL == "" {
|
||||
return fmt.Errorf("--api-url is required")
|
||||
return errors.New("--api-url is required")
|
||||
}
|
||||
|
||||
model := modelName
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
|
|
@ -35,7 +36,7 @@ func runQuery(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB env is required")
|
||||
return errors.New("--db or LEM_DB env is required")
|
||||
}
|
||||
|
||||
db, err := ml.OpenDB(path)
|
||||
|
|
@ -129,7 +130,7 @@ func runQuery(cmd *cli.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func formatValue(v interface{}) string {
|
||||
func formatValue(v any) string {
|
||||
if v == nil {
|
||||
return "NULL"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,15 @@ package cmd
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"forge.lthn.ai/core/go-ml"
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
"forge.lthn.ai/core/go-ml"
|
||||
)
|
||||
|
||||
var sandwichCmd = &cli.Command{
|
||||
|
|
@ -108,7 +109,7 @@ func runSandwich(cmd *cli.Command, args []string) error {
|
|||
)
|
||||
|
||||
if len(seeds) == 0 {
|
||||
return fmt.Errorf("no seed prompts found")
|
||||
return errors.New("no seed prompts found")
|
||||
}
|
||||
|
||||
// Open output file
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -31,7 +32,7 @@ func runSeedInflux(cmd *cli.Command, args []string) error {
|
|||
path = os.Getenv("LEM_DB")
|
||||
}
|
||||
if path == "" {
|
||||
return fmt.Errorf("--db or LEM_DB required")
|
||||
return errors.New("--db or LEM_DB required")
|
||||
}
|
||||
|
||||
db, err := ml.OpenDB(path)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
|
@ -11,8 +12,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"forge.lthn.ai/core/go-ml"
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
"forge.lthn.ai/core/go-ml"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
|
|
@ -70,10 +71,10 @@ type sequenceDef struct {
|
|||
|
||||
// sequenceState tracks progress through a sequence.
|
||||
type sequenceState struct {
|
||||
SequenceID string `json:"sequence_id"`
|
||||
Completed map[string]bool `json:"completed"` // lesson ID → done
|
||||
Current string `json:"current"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
SequenceID string `json:"sequence_id"`
|
||||
Completed map[string]bool `json:"completed"` // lesson ID → done
|
||||
Current string `json:"current"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
func runSequence(cmd *cli.Command, args []string) error {
|
||||
|
|
@ -103,7 +104,7 @@ func runSequence(cmd *cli.Command, args []string) error {
|
|||
modelPath = seq.ModelPath
|
||||
}
|
||||
if modelPath == "" {
|
||||
return fmt.Errorf("model-path is required (flag or sequence YAML)")
|
||||
return errors.New("model-path is required (flag or sequence YAML)")
|
||||
}
|
||||
|
||||
// Resolve output
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ package cmd
|
|||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
|
@ -17,9 +18,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
"forge.lthn.ai/core/go-ml"
|
||||
"forge.lthn.ai/core/go-mlx"
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
"github.com/ollama/ollama/tokenizer"
|
||||
)
|
||||
|
||||
var trainCmd = &cli.Command{
|
||||
|
|
@ -36,15 +38,15 @@ Training data format (one JSON object per line):
|
|||
}
|
||||
|
||||
var (
|
||||
trainModelPath string
|
||||
trainData string
|
||||
trainOutput string
|
||||
trainRank int
|
||||
trainAlpha float64
|
||||
trainLR float64
|
||||
trainEpochs int
|
||||
trainMaxSeqLen int
|
||||
trainTargets string
|
||||
trainModelPath string
|
||||
trainData string
|
||||
trainOutput string
|
||||
trainRank int
|
||||
trainAlpha float64
|
||||
trainLR float64
|
||||
trainEpochs int
|
||||
trainMaxSeqLen int
|
||||
trainTargets string
|
||||
trainMemoryLimit int
|
||||
)
|
||||
|
||||
|
|
@ -113,7 +115,7 @@ func runTrain(cmd *cli.Command, args []string) error {
|
|||
slog.Info("training data loaded", "samples", len(samples))
|
||||
|
||||
if len(samples) == 0 {
|
||||
return fmt.Errorf("no training samples loaded")
|
||||
return errors.New("no training samples loaded")
|
||||
}
|
||||
|
||||
// --- Training loop ---
|
||||
|
|
@ -129,7 +131,7 @@ func runTrain(cmd *cli.Command, args []string) error {
|
|||
var totalLoss float64
|
||||
var totalSteps int
|
||||
|
||||
for epoch := 0; epoch < trainEpochs; epoch++ {
|
||||
for epoch := range trainEpochs {
|
||||
var epochLoss float64
|
||||
epochStart := time.Now()
|
||||
|
||||
|
|
|
|||
19
compare.go
19
compare.go
|
|
@ -2,7 +2,8 @@ package ml
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"maps"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// RunCompare reads two score files and prints a comparison table for each
|
||||
|
|
@ -28,13 +29,7 @@ func RunCompare(oldPath, newPath string) error {
|
|||
}
|
||||
|
||||
// Sort model names for deterministic output.
|
||||
sortedModels := make([]string, 0, len(models))
|
||||
for m := range models {
|
||||
sortedModels = append(sortedModels, m)
|
||||
}
|
||||
sort.Strings(sortedModels)
|
||||
|
||||
for _, model := range sortedModels {
|
||||
for _, model := range slices.Sorted(maps.Keys(models)) {
|
||||
oldAvgs := oldOutput.ModelAverages[model]
|
||||
newAvgs := newOutput.ModelAverages[model]
|
||||
|
||||
|
|
@ -54,13 +49,7 @@ func RunCompare(oldPath, newPath string) error {
|
|||
metrics[k] = true
|
||||
}
|
||||
|
||||
sortedMetrics := make([]string, 0, len(metrics))
|
||||
for k := range metrics {
|
||||
sortedMetrics = append(sortedMetrics, k)
|
||||
}
|
||||
sort.Strings(sortedMetrics)
|
||||
|
||||
for _, metric := range sortedMetrics {
|
||||
for _, metric := range slices.Sorted(maps.Keys(metrics)) {
|
||||
oldVal := oldAvgs[metric]
|
||||
newVal := newAvgs[metric]
|
||||
delta := newVal - oldVal
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package ml
|
|||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"maps"
|
||||
|
|
@ -52,7 +53,7 @@ func ReadSafetensors(path string) (map[string]SafetensorsTensorInfo, []byte, err
|
|||
}
|
||||
|
||||
if len(data) < 8 {
|
||||
return nil, nil, fmt.Errorf("file too small")
|
||||
return nil, nil, errors.New("file too small")
|
||||
}
|
||||
|
||||
headerSize := int(binary.LittleEndian.Uint64(data[:8]))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package ml
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
|
@ -21,7 +22,7 @@ func PrintCoverage(db *DB, w io.Writer) error {
|
|||
return fmt.Errorf("count seeds: %w (run: core ml import-all first)", err)
|
||||
}
|
||||
if len(rows) == 0 {
|
||||
return fmt.Errorf("no seeds table found (run: core ml import-all first)")
|
||||
return errors.New("no seeds table found (run: core ml import-all first)")
|
||||
}
|
||||
total := toInt(rows[0]["total"])
|
||||
|
||||
|
|
|
|||
7
gguf.go
7
gguf.go
|
|
@ -1,6 +1,7 @@
|
|||
package ml
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
@ -8,7 +9,7 @@ import (
|
|||
"math"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -174,8 +175,8 @@ func ConvertMLXtoGGUFLoRA(safetensorsPath, configPath, outputPath, architecture
|
|||
}
|
||||
}
|
||||
|
||||
sort.Slice(ggufTensors, func(i, j int) bool {
|
||||
return ggufTensors[i].name < ggufTensors[j].name
|
||||
slices.SortFunc(ggufTensors, func(a, b ggufTensor) int {
|
||||
return cmp.Compare(a.name, b.name)
|
||||
})
|
||||
|
||||
metadata := []ggufMetadata{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package ml
|
||||
|
||||
import (
|
||||
"math"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -122,7 +121,7 @@ func scoreCreativeForm(response string) int {
|
|||
|
||||
// Metaphor density.
|
||||
metaphorCount := len(metaphorPattern.FindAllString(response, -1))
|
||||
score += int(math.Min(float64(metaphorCount), 3))
|
||||
score += min(metaphorCount, 3)
|
||||
|
||||
return score
|
||||
}
|
||||
|
|
@ -147,7 +146,7 @@ func scoreEngagementDepth(response string) int {
|
|||
|
||||
// Tech depth.
|
||||
techCount := len(techDepthPattern.FindAllString(response, -1))
|
||||
score += int(math.Min(float64(techCount), 3))
|
||||
score += min(techCount, 3)
|
||||
|
||||
// Word count bonuses.
|
||||
words := len(strings.Fields(response))
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package ml
|
|||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
|
@ -59,10 +60,10 @@ var (
|
|||
// At least one of ContentFile, CapabilityFile, or TrainingLog must be set.
|
||||
func Ingest(influx *InfluxClient, cfg IngestConfig, w io.Writer) error {
|
||||
if cfg.ContentFile == "" && cfg.CapabilityFile == "" && cfg.TrainingLog == "" {
|
||||
return fmt.Errorf("at least one of --content, --capability, or --training-log is required")
|
||||
return errors.New("at least one of --content, --capability, or --training-log is required")
|
||||
}
|
||||
if cfg.Model == "" {
|
||||
return fmt.Errorf("--model is required")
|
||||
return errors.New("--model is required")
|
||||
}
|
||||
if cfg.RunID == "" {
|
||||
cfg.RunID = cfg.Model
|
||||
|
|
@ -362,7 +363,7 @@ func extractIteration(label string) int {
|
|||
return n
|
||||
}
|
||||
|
||||
// toFloat64 converts a JSON-decoded interface{} value to float64.
|
||||
// toFloat64 converts a JSON-decoded any value to float64.
|
||||
// Handles float64 (standard json.Unmarshal), json.Number, and string values.
|
||||
func toFloat64(v any) (float64, bool) {
|
||||
switch val := v.(type) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package ml
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
|
@ -29,7 +30,7 @@ func NormalizeSeeds(db *DB, cfg NormalizeConfig, w io.Writer) error {
|
|||
fmt.Fprintf(w, "Seeds table: %d rows\n", seedCount)
|
||||
|
||||
if seedCount == 0 {
|
||||
return fmt.Errorf("seeds table is empty, nothing to normalize")
|
||||
return errors.New("seeds table is empty, nothing to normalize")
|
||||
}
|
||||
|
||||
// 2. Drop and recreate expansion_prompts.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package ml
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
|
@ -34,12 +35,12 @@ type uploadEntry struct {
|
|||
// or ~/.huggingface/token, in that order.
|
||||
func Publish(cfg PublishConfig, w io.Writer) error {
|
||||
if cfg.InputDir == "" {
|
||||
return fmt.Errorf("input directory is required")
|
||||
return errors.New("input directory is required")
|
||||
}
|
||||
|
||||
token := resolveHFToken(cfg.Token)
|
||||
if token == "" && !cfg.DryRun {
|
||||
return fmt.Errorf("HuggingFace token required (--token, HF_TOKEN env, or ~/.huggingface/token)")
|
||||
return errors.New("HuggingFace token required (--token, HF_TOKEN env, or ~/.huggingface/token)")
|
||||
}
|
||||
|
||||
files, err := collectUploadFiles(cfg.InputDir)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package ml
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"iter"
|
||||
"slices"
|
||||
|
|
@ -165,7 +166,7 @@ func (s *Service) Generate(ctx context.Context, backendName, prompt string, opts
|
|||
// ScoreResponses scores a batch of responses using the configured engine.
|
||||
func (s *Service) ScoreResponses(ctx context.Context, responses []Response) (map[string][]PromptScore, error) {
|
||||
if s.engine == nil {
|
||||
return nil, fmt.Errorf("scoring engine not configured (set JudgeURL and JudgeModel)")
|
||||
return nil, errors.New("scoring engine not configured (set JudgeURL and JudgeModel)")
|
||||
}
|
||||
return s.engine.ScoreAll(ctx, responses), nil
|
||||
}
|
||||
|
|
|
|||
11
status.go
11
status.go
|
|
@ -1,9 +1,10 @@
|
|||
package ml
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// trainingRow holds deduplicated training status + loss for a single model.
|
||||
|
|
@ -146,8 +147,8 @@ func dedupeTraining(statusRows, lossRows []map[string]any) []trainingRow {
|
|||
rows = append(rows, tr)
|
||||
}
|
||||
|
||||
sort.Slice(rows, func(i, j int) bool {
|
||||
return rows[i].model < rows[j].model
|
||||
slices.SortFunc(rows, func(a, b trainingRow) int {
|
||||
return cmp.Compare(a.model, b.model)
|
||||
})
|
||||
|
||||
return rows
|
||||
|
|
@ -172,8 +173,8 @@ func dedupeGeneration(rows []map[string]any) []genRow {
|
|||
})
|
||||
}
|
||||
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
return result[i].worker < result[j].worker
|
||||
slices.SortFunc(result, func(a, b genRow) int {
|
||||
return cmp.Compare(a.worker, b.worker)
|
||||
})
|
||||
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package ml
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
|
|
@ -271,7 +272,7 @@ func workerInfer(cfg *WorkerConfig, task APITask) (string, error) {
|
|||
}
|
||||
|
||||
if len(chatResp.Choices) == 0 {
|
||||
return "", fmt.Errorf("no choices in response")
|
||||
return "", errors.New("no choices in response")
|
||||
}
|
||||
|
||||
content := chatResp.Choices[0].Message.Content
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue