summaryrefslogtreecommitdiff
path: root/internal/cli
diff options
context:
space:
mode:
Diffstat (limited to 'internal/cli')
-rw-r--r--internal/cli/llm.go31
-rw-r--r--internal/cli/run.go19
-rw-r--r--internal/cli/serve.go25
3 files changed, 70 insertions, 5 deletions
diff --git a/internal/cli/llm.go b/internal/cli/llm.go
new file mode 100644
index 0000000..04fe902
--- /dev/null
+++ b/internal/cli/llm.go
@@ -0,0 +1,31 @@
+package cli
+
+import (
+ "log/slog"
+ "net/http"
+ "time"
+
+ "github.com/thepeterstone/claudomator/internal/config"
+ "github.com/thepeterstone/claudomator/internal/llm"
+)
+
+// buildLocalLLMClient returns an *llm.Client when a local model endpoint is
+// configured. Returns nil when LocalModel.Endpoint is empty so callers can
+// gate on `if c != nil` to skip registering LocalRunner / using the LLM
+// classifier path.
+func buildLocalLLMClient(cfg config.LocalModel, logger *slog.Logger) *llm.Client {
+ if cfg.Endpoint == "" {
+ return nil
+ }
+ timeout := 60 * time.Second
+ if cfg.TimeoutSeconds > 0 {
+ timeout = time.Duration(cfg.TimeoutSeconds) * time.Second
+ }
+ return &llm.Client{
+ Endpoint: cfg.Endpoint,
+ Model: cfg.Model,
+ APIKey: cfg.APIKey,
+ HTTPClient: &http.Client{Timeout: timeout},
+ Logger: logger,
+ }
+}
diff --git a/internal/cli/run.go b/internal/cli/run.go
index 49aa28e..2d7c3d7 100644
--- a/internal/cli/run.go
+++ b/internal/cli/run.go
@@ -84,9 +84,24 @@ func runTasks(file string, parallel int, dryRun bool) error {
LogDir: cfg.LogDir,
},
}
+
+ localClient := buildLocalLLMClient(cfg.LocalModel, logger)
+ if localClient != nil {
+ runners["local"] = &executor.LocalRunner{
+ Client: localClient,
+ Logger: logger,
+ LogDir: cfg.LogDir,
+ DefaultTemperature: cfg.LocalModel.DefaultTemperature,
+ }
+ }
+
pool := executor.NewPool(parallel, runners, store, logger)
- if cfg.GeminiBinaryPath != "" {
- pool.Classifier = &executor.Classifier{GeminiBinaryPath: cfg.GeminiBinaryPath}
+ pool.Classifier = &executor.Classifier{
+ LLM: localClient,
+ GeminiBinaryPath: cfg.GeminiBinaryPath,
+ }
+ if localClient != nil {
+ pool.LLM = localClient
}
// Handle graceful shutdown.
diff --git a/internal/cli/serve.go b/internal/cli/serve.go
index 94f0c5d..5101b81 100644
--- a/internal/cli/serve.go
+++ b/internal/cli/serve.go
@@ -71,10 +71,25 @@ func serve(addr string) error {
APIURL: apiURL,
},
}
-
+
+ localClient := buildLocalLLMClient(cfg.LocalModel, logger)
+ if localClient != nil {
+ runners["local"] = &executor.LocalRunner{
+ Client: localClient,
+ Logger: logger,
+ LogDir: cfg.LogDir,
+ DefaultTemperature: cfg.LocalModel.DefaultTemperature,
+ }
+ logger.Info("local runner registered", "endpoint", cfg.LocalModel.Endpoint, "model", cfg.LocalModel.Model)
+ }
+
pool := executor.NewPool(cfg.MaxConcurrent, runners, store, logger)
- if cfg.GeminiBinaryPath != "" {
- pool.Classifier = &executor.Classifier{GeminiBinaryPath: cfg.GeminiBinaryPath}
+ pool.Classifier = &executor.Classifier{
+ LLM: localClient,
+ GeminiBinaryPath: cfg.GeminiBinaryPath,
+ }
+ if localClient != nil {
+ pool.LLM = localClient
}
pool.RecoverStaleRunning(context.Background())
pool.RecoverStaleQueued(context.Background())
@@ -87,6 +102,10 @@ func serve(addr string) error {
if cfg.WorkspaceRoot != "" {
srv.SetWorkspaceRoot(cfg.WorkspaceRoot)
}
+ if cfg.LocalModel.UseForElaborate() {
+ srv.SetLLM(localClient)
+ logger.Info("elaboration prefers local llm", "endpoint", cfg.LocalModel.Endpoint)
+ }
srv.SetGitHubWebhookConfig(cfg.WebhookSecret, cfg.Projects)
// Register scripts.