@@ -16,12 +16,23 @@ import (
1616)
1717
1818const (
19- freebuffProvider = "freebuff"
20- freebuffModel = "deepseek/deepseek-v4-flash"
21- freebuffAgent = "base3-free-deepseek-flash"
22- freebuffPrompt = "You are Buffy, the coding agent behind Codebuff."
19+ freebuffProvider = "freebuff"
20+ freebuffDeepSeekV4ProModel = "deepseek/deepseek-v4-pro"
21+ freebuffDeepSeekV4FlashModel = "deepseek/deepseek-v4-flash"
22+ freebuffGPT56LunaModel = "openai/gpt-5.6-luna"
23+ freebuffMiniMaxM3Model = "minimax/minimax-m3"
24+ freebuffMiMo25Model = "mimo/mimo-v2.5"
25+ freebuffPrompt = "You are Buffy, the coding agent behind Codebuff."
2326)
2427
28+ var freebuffAgentByModel = map [string ]string {
29+ freebuffDeepSeekV4ProModel : "base3-free-deepseek" ,
30+ freebuffDeepSeekV4FlashModel : "base3-free-deepseek-flash" ,
31+ freebuffGPT56LunaModel : "base3-free-luna" ,
32+ freebuffMiniMaxM3Model : "base3-free-minimax-m3" ,
33+ freebuffMiMo25Model : "base3-free-mimo" ,
34+ }
35+
2536type freebuffSession struct {
2637 Status string `json:"status"`
2738 Model string `json:"model"`
@@ -37,7 +48,8 @@ func (e *OpenAICompatExecutor) isFreebuff() bool {
3748}
3849
3950func (e * OpenAICompatExecutor ) prepareFreebuffRequest (ctx context.Context , client * http.Client , auth * cliproxyauth.Auth , baseURL , apiKey , model string , payload []byte ) ([]byte , string , error ) {
40- if model != freebuffModel {
51+ agentID , ok := freebuffAgentByModel [model ]
52+ if ! ok {
4153 return nil , "" , fmt .Errorf ("freebuff: unsupported model %q" , model )
4254 }
4355
@@ -62,7 +74,7 @@ func (e *OpenAICompatExecutor) prepareFreebuffRequest(ctx context.Context, clien
6274 if err != nil {
6375 return nil , "" , err
6476 }
65- runID , err := e .startFreebuffRun (ctx , client , auth , baseURL , apiKey )
77+ runID , err := e .startFreebuffRun (ctx , client , auth , baseURL , apiKey , agentID )
6678 if err != nil {
6779 return nil , "" , err
6880 }
@@ -80,20 +92,30 @@ func (e *OpenAICompatExecutor) prepareFreebuffRequest(ctx context.Context, clien
8092}
8193
8294func (e * OpenAICompatExecutor ) freebuffInstance (ctx context.Context , client * http.Client , auth * cliproxyauth.Auth , baseURL , apiKey , model string ) (string , error ) {
83- // ponytail: one account owns one session; shard locks by credential only if acquisition latency matters.
84- e .freebuffMu .Lock ()
85- defer e .freebuffMu .Unlock ()
8695 var session freebuffSession
87- if err := e .freebuffJSON (ctx , client , auth , http .MethodGet , strings .TrimSuffix (baseURL , "/" )+ "/freebuff/session" , apiKey , nil , nil , & session ); err != nil {
96+ sessionURL := strings .TrimSuffix (baseURL , "/" ) + "/freebuff/session"
97+ if err := e .freebuffJSON (ctx , client , auth , http .MethodGet , sessionURL , apiKey , nil , nil , & session ); err != nil {
8898 var statusError statusErr
8999 if ! errors .As (err , & statusError ) || statusError .StatusCode () != http .StatusNotFound {
90100 return "" , err
91101 }
92102 session .Status = "none"
93103 }
104+ if session .Status == "active" && session .Model == model {
105+ if session .InstanceID == "" {
106+ return "" , fmt .Errorf ("freebuff: active session returned no instanceId" )
107+ }
108+ return session .InstanceID , nil
109+ }
110+ if session .Status == "active" || session .Status == "ended" {
111+ if err := e .freebuffJSON (ctx , client , auth , http .MethodDelete , sessionURL , apiKey , nil , nil , nil ); err != nil {
112+ return "" , err
113+ }
114+ session .Status = "none"
115+ }
94116 if session .Status == "none" {
95117 headers := http.Header {"x-freebuff-model" : []string {model }}
96- if err := e .freebuffJSON (ctx , client , auth , http .MethodPost , strings . TrimSuffix ( baseURL , "/" ) + "/freebuff/session" , apiKey , headers , nil , & session ); err != nil {
118+ if err := e .freebuffJSON (ctx , client , auth , http .MethodPost , sessionURL , apiKey , headers , nil , & session ); err != nil {
97119 return "" , err
98120 }
99121 }
@@ -103,8 +125,8 @@ func (e *OpenAICompatExecutor) freebuffInstance(ctx context.Context, client *htt
103125 return session .InstanceID , nil
104126}
105127
106- func (e * OpenAICompatExecutor ) startFreebuffRun (ctx context.Context , client * http.Client , auth * cliproxyauth.Auth , baseURL , apiKey string ) (string , error ) {
107- body , err := json .Marshal (map [string ]any {"action" : "START" , "agentId" : freebuffAgent , "ancestorRunIds" : []string {}})
128+ func (e * OpenAICompatExecutor ) startFreebuffRun (ctx context.Context , client * http.Client , auth * cliproxyauth.Auth , baseURL , apiKey , agentID string ) (string , error ) {
129+ body , err := json .Marshal (map [string ]any {"action" : "START" , "agentId" : agentID , "ancestorRunIds" : []string {}})
108130 if err != nil {
109131 return "" , err
110132 }
0 commit comments