diff --git a/main.go b/main.go index a20ae55..9f85343 100644 --- a/main.go +++ b/main.go @@ -107,8 +107,8 @@ func queryModelsContextWindow(cfg *Cfg) int { req.Header.Set("User-Agent", opencodeAgentVersion) req.Header.Set("X-Session-Id", projectID()) req.Header.Set("x-opencode-project", projectID()) - req.Header.Set("x-opencode-client", opencodeAgentVersion) - req.Header.Set("x-opencode-session", 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 } @@ -183,8 +183,8 @@ func listModels(cfg *Cfg) (string, error) { req.Header.Set("User-Agent", opencodeAgentVersion) req.Header.Set("X-Session-Id", projectID()) req.Header.Set("x-opencode-project", projectID()) - req.Header.Set("x-opencode-client", opencodeAgentVersion) - req.Header.Set("x-opencode-session", 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 } @@ -1055,8 +1055,8 @@ func llm(ctx context.Context, cfg *Cfg, msgs []Message, tools []map[string]any) req.Header.Set("User-Agent", opencodeAgentVersion) req.Header.Set("X-Session-Id", projectID()) req.Header.Set("x-opencode-project", projectID()) - req.Header.Set("x-opencode-client", opencodeAgentVersion) - req.Header.Set("x-opencode-session", 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 @@ -1621,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 == "" { diff --git a/main_test.go b/main_test.go index cb2c7d1..6350173 100644 --- a/main_test.go +++ b/main_test.go @@ -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() @@ -1173,11 +1175,32 @@ func TestLLMNonStreamingAndHeaders(t *testing.T) { 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) {