update-1.6.2
ci / test (services/knowledge) (push) Successful in 47s
ci / test (services/agent) (push) Successful in 55s
ci / test (platform/neuroforge) (push) Successful in 56s
ci / docker-build (push) Failing after 1m10s
ci / test (services/control) (push) Successful in 1m26s
release-tag / release-image (push) Successful in 6m43s
ci / test (services/knowledge) (push) Successful in 47s
ci / test (services/agent) (push) Successful in 55s
ci / test (platform/neuroforge) (push) Successful in 56s
ci / docker-build (push) Failing after 1m10s
ci / test (services/control) (push) Successful in 1m26s
release-tag / release-image (push) Successful in 6m43s
This commit is contained in:
@@ -234,6 +234,7 @@ func run() (retErr error) {
|
||||
changed := false
|
||||
for name, dst := range map[string]*string{
|
||||
"OPENAI_API_KEY": &sec.OpenAIAPIKey,
|
||||
"NEUROFORGE_OLLAMA_API_KEY": &sec.OllamaAPIKey,
|
||||
"NEUROFORGE_ADMIN_TOKEN": &sec.AdminToken,
|
||||
"NEUROFORGE_APP_API_KEY": &sec.AppAPIKey,
|
||||
"NEUROFORGE_INTEGRATION_TOKEN": &sec.IntegrationToken,
|
||||
@@ -247,6 +248,14 @@ func run() (retErr error) {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
// OLLAMA_API_KEY is a convenient shared alias. The NeuroForge-specific
|
||||
// variable wins when both are set.
|
||||
if strings.TrimSpace(os.Getenv("NEUROFORGE_OLLAMA_API_KEY")) == "" {
|
||||
if v := strings.TrimSpace(os.Getenv("OLLAMA_API_KEY")); v != "" {
|
||||
sec.OllamaAPIKey = v
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
if err := s.UpdateSecrets(sec); err != nil {
|
||||
return err
|
||||
|
||||
@@ -86,6 +86,7 @@ type workerConfig struct {
|
||||
MaxConcurrency int
|
||||
Hostname string
|
||||
OllamaURL string
|
||||
OllamaAPIKey string
|
||||
OllamaChatModel string
|
||||
OllamaEmbedModel string
|
||||
OllamaNumCtx int
|
||||
@@ -145,6 +146,7 @@ func main() {
|
||||
Heartbeat: heartbeat, ResourceClass: resource, Capabilities: caps,
|
||||
MaxConcurrency: maxConcurrency, Hostname: hostname(),
|
||||
OllamaURL: strings.TrimRight(firstNonEmpty(os.Getenv("NEUROFORGE_WORKER_OLLAMA_URL"), os.Getenv("OLLAMA_BASE_URL"), os.Getenv("OLLAMA_URL")), "/"),
|
||||
OllamaAPIKey: firstNonEmpty(os.Getenv("NEUROFORGE_WORKER_OLLAMA_API_KEY"), os.Getenv("OLLAMA_API_KEY")),
|
||||
OllamaChatModel: firstNonEmpty(os.Getenv("NEUROFORGE_WORKER_OLLAMA_CHAT_MODEL"), os.Getenv("OLLAMA_MODEL")),
|
||||
OllamaEmbedModel: firstNonEmpty(os.Getenv("NEUROFORGE_WORKER_OLLAMA_EMBEDDING_MODEL"), os.Getenv("OLLAMA_EMBEDDING_MODEL")),
|
||||
OllamaNumCtx: envInt("NEUROFORGE_WORKER_OLLAMA_NUM_CTX", 8192),
|
||||
@@ -342,7 +344,7 @@ func ollamaEmbed(ctx context.Context, c *http.Client, cfg workerConfig, p modelE
|
||||
Embeddings [][]float32 `json:"embeddings"`
|
||||
PromptEvalCount int64 `json:"prompt_eval_count"`
|
||||
}
|
||||
if err := postOllama(ctx, c, cfg.OllamaURL+"/api/embed", body, &resp); err != nil {
|
||||
if err := postOllama(ctx, c, cfg.OllamaURL+"/api/embed", cfg.OllamaAPIKey, body, &resp); err != nil {
|
||||
return modelResult{}, err
|
||||
}
|
||||
if len(resp.Embeddings) == 0 || len(resp.Embeddings[0]) == 0 {
|
||||
@@ -385,19 +387,22 @@ func ollamaChat(ctx context.Context, c *http.Client, cfg workerConfig, p modelCh
|
||||
PromptEvalCount int64 `json:"prompt_eval_count"`
|
||||
EvalCount int64 `json:"eval_count"`
|
||||
}
|
||||
if err := postOllama(ctx, c, cfg.OllamaURL+"/api/chat", body, &resp); err != nil {
|
||||
if err := postOllama(ctx, c, cfg.OllamaURL+"/api/chat", cfg.OllamaAPIKey, body, &resp); err != nil {
|
||||
return modelResult{}, err
|
||||
}
|
||||
return modelResult{Text: strings.TrimSpace(resp.Message.Content), Usage: modelUsage{InputTokens: resp.PromptEvalCount, OutputTokens: resp.EvalCount}, Provider: "ollama", Model: model, NodeID: cfg.ID}, nil
|
||||
}
|
||||
|
||||
func postOllama(ctx context.Context, c *http.Client, url string, body any, out any) error {
|
||||
func postOllama(ctx context.Context, c *http.Client, url, apiKey string, body any, out any) error {
|
||||
raw, _ := json.Marshal(body)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(raw))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if token := strings.TrimSpace(apiKey); token != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
}
|
||||
resp, err := c.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPostOllamaSendsBearerToken(t *testing.T) {
|
||||
const token = "ollama-secret"
|
||||
var auth string
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
auth = r.Header.Get("Authorization")
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"ok": true})
|
||||
}))
|
||||
defer srv.Close()
|
||||
var out map[string]any
|
||||
if err := postOllama(context.Background(), srv.Client(), srv.URL, token, map[string]any{"x": 1}, &out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if auth != "Bearer "+token {
|
||||
t.Fatalf("authorization=%q", auth)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user