Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d8a19dd67 | ||
|
|
a02b388b1a |
@@ -85,7 +85,7 @@ var llmTransport = &http.Transport{
|
||||
}
|
||||
|
||||
var defCfg = Cfg{"https://api.kilo.ai/api/openrouter", "openrouter/free", "-", 0.7, 300, 120, 1000, true, "auto", 262144, map[string]string{"reasoning_effort": "high"}}
|
||||
const opencodeAgentVersion = "opencode/1.18.30"
|
||||
const opencodeAgentVersion = "opencode/1.18.31"
|
||||
|
||||
func atoiD(s string, d int) int {
|
||||
if v, e := strconv.Atoi(strings.TrimSpace(s)); e == nil {
|
||||
@@ -105,7 +105,10 @@ func queryModelsContextWindow(cfg *Cfg) int {
|
||||
req, err := http.NewRequest("GET", strings.TrimRight(cfg.Endpoint, "/")+"/models", nil)
|
||||
if err != nil { return 0 }
|
||||
req.Header.Set("User-Agent", opencodeAgentVersion)
|
||||
req.Header.Set("X-Session-ID", projectID())
|
||||
req.Header.Set("X-Session-Id", projectID())
|
||||
req.Header.Set("x-opencode-project", projectID())
|
||||
req.Header.Set("x-opencode-client", "cli")
|
||||
req.Header.Set("x-opencode-session", opencodeSessionID())
|
||||
if cfg.APIKey != "" && cfg.APIKey != "-" { req.Header.Set("Authorization", "Bearer "+cfg.APIKey) }
|
||||
resp, err := client.Do(req)
|
||||
if err != nil || resp.StatusCode >= 400 { return 0 }
|
||||
@@ -178,7 +181,10 @@ func listModels(cfg *Cfg) (string, error) {
|
||||
req, err := http.NewRequest("GET", strings.TrimRight(cfg.Endpoint, "/")+"/models", nil)
|
||||
if err != nil { return "", err }
|
||||
req.Header.Set("User-Agent", opencodeAgentVersion)
|
||||
req.Header.Set("X-Session-ID", projectID())
|
||||
req.Header.Set("X-Session-Id", projectID())
|
||||
req.Header.Set("x-opencode-project", projectID())
|
||||
req.Header.Set("x-opencode-client", "cli")
|
||||
req.Header.Set("x-opencode-session", opencodeSessionID())
|
||||
if cfg.APIKey != "" && cfg.APIKey != "-" { req.Header.Set("Authorization", "Bearer "+cfg.APIKey) }
|
||||
resp, err := client.Do(req)
|
||||
if err != nil { return "", err }
|
||||
@@ -1047,7 +1053,10 @@ func llm(ctx context.Context, cfg *Cfg, msgs []Message, tools []map[string]any)
|
||||
req, _ := http.NewRequestWithContext(ctx, "POST", strings.TrimRight(cfg.Endpoint, "/")+"/chat/completions", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("User-Agent", opencodeAgentVersion)
|
||||
req.Header.Set("X-Session-ID", projectID())
|
||||
req.Header.Set("X-Session-Id", projectID())
|
||||
req.Header.Set("x-opencode-project", projectID())
|
||||
req.Header.Set("x-opencode-client", "cli")
|
||||
req.Header.Set("x-opencode-session", opencodeSessionID())
|
||||
if cfg.APIKey != "" && cfg.APIKey != "-" { req.Header.Set("Authorization", "Bearer "+cfg.APIKey) }
|
||||
resp, err = client.Do(req)
|
||||
var is4xxClientErr bool
|
||||
@@ -1612,6 +1621,16 @@ func projectID() string {
|
||||
return hex.EncodeToString(h[:])
|
||||
}
|
||||
|
||||
func opencodeSessionID() string {
|
||||
pid := projectID()
|
||||
if len(pid) > 26 {
|
||||
pid = pid[:26]
|
||||
} else if len(pid) < 26 {
|
||||
pid = (pid + "0123456789abcdef0123456789")[:26]
|
||||
}
|
||||
return "ses_" + pid
|
||||
}
|
||||
|
||||
func saveSession(msgs []Message, sid string) (string, string) {
|
||||
sid = strings.TrimSpace(sid)
|
||||
if sid == "" {
|
||||
|
||||
+25
-2
@@ -1147,11 +1147,13 @@ func TestCol(t *testing.T) {
|
||||
// ---------- llm / AL / summarize / compact via httptest (no real network) ----------
|
||||
|
||||
func TestLLMNonStreamingAndHeaders(t *testing.T) {
|
||||
var gotPath, gotAuth, gotUA string
|
||||
var gotPath, gotAuth, gotUA, gotOCClient, gotOCSession string
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
gotPath = r.URL.Path
|
||||
gotAuth = r.Header.Get("Authorization")
|
||||
gotUA = r.Header.Get("User-Agent")
|
||||
gotOCClient = r.Header.Get("x-opencode-client")
|
||||
gotOCSession = r.Header.Get("x-opencode-session")
|
||||
w.Write([]byte(`{"choices":[{"message":{"role":"assistant","content":"hi","reasoning_content":"think"}}]}`))
|
||||
}))
|
||||
defer srv.Close()
|
||||
@@ -1170,14 +1172,35 @@ func TestLLMNonStreamingAndHeaders(t *testing.T) {
|
||||
if gotAuth != "Bearer secret" {
|
||||
t.Errorf("auth = %q", gotAuth)
|
||||
}
|
||||
if !strings.Contains(gotUA, "opencode/1.18.30") {
|
||||
if !strings.Contains(gotUA, "opencode/1.18.31") {
|
||||
t.Errorf("user-agent = %q", gotUA)
|
||||
}
|
||||
if gotOCClient != "cli" {
|
||||
t.Errorf("x-opencode-client = %q, want cli", gotOCClient)
|
||||
}
|
||||
if gotOCSession != opencodeSessionID() {
|
||||
t.Errorf("x-opencode-session = %q, want %q", gotOCSession, opencodeSessionID())
|
||||
}
|
||||
if m.Content == nil || *m.Content != "hi" || m.ReasoningContent != "think" {
|
||||
t.Errorf("message = %+v", m)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpencodeSessionID(t *testing.T) {
|
||||
sid := opencodeSessionID()
|
||||
if !strings.HasPrefix(sid, "ses_") {
|
||||
t.Fatalf("session id does not start with ses_: %q", sid)
|
||||
}
|
||||
if len(sid) != 30 {
|
||||
t.Fatalf("session id length = %d, want 30: %q", len(sid), sid)
|
||||
}
|
||||
for _, c := range sid[4:] {
|
||||
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
|
||||
t.Fatalf("invalid character %c in session id %q", c, sid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLLMNoAuthHeaderWhenNoKey(t *testing.T) {
|
||||
var gotAuth string
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user