Unified · Split
| @@ -380,6 +380,15 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model, · 379 unmodified lines | |||
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | inner := []any{item0, nil, item2} | 382 | inner := []any{item0, nil, item2} |
| 383 | // Attach Gem first to keep index alignment with reference implementation | ||
| 384 | // so the Gemini Web UI can recognize the selected Gem. | ||
| 385 | if gem != nil { | ||
| 386 | // pad with 16 nils then gem ID | ||
| 387 | for i := 0; i < 16; i++ { | ||
| 388 | inner = append(inner, nil) | ||
| 389 | } | ||
| 390 | inner = append(inner, gem.ID) | ||
| 391 | } | ||
| 383 | requestedModel := strings.ToLower(model.Name) | 392 | requestedModel := strings.ToLower(model.Name) |
| 384 | if chat != nil && chat.RequestedModel() != "" { | 393 | if chat != nil && chat.RequestedModel() != "" { |
| 385 | requestedModel = chat.RequestedModel() | 394 | requestedModel = chat.RequestedModel() |
| @@ -388,13 +397,6 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model, · 2 unmodified lines | |||
| 388 | inner = ensureAnyLen(inner, 49) | 397 | inner = ensureAnyLen(inner, 49) |
| 389 | inner[49] = 14 | 398 | inner[49] = 14 |
| 390 | } | 399 | } |
| 391 | if gem != nil { | ||
| 392 | // pad with 16 nils then gem ID | ||
| 393 | for i := 0; i < 16; i++ { | ||
| 394 | inner = append(inner, nil) | ||
| 395 | } | ||
| 396 | inner = append(inner, gem.ID) | ||
| 397 | } | ||
| 398 | innerJSON, _ := json.Marshal(inner) | 400 | innerJSON, _ := json.Marshal(inner) |
| 399 | outer := []any{nil, string(innerJSON)} | 401 | outer := []any{nil, string(innerJSON)} |
| 400 | outerJSON, _ := json.Marshal(outer) | 402 | outerJSON, _ := json.Marshal(outer) |
| @@ -1030,3 +1030,10 @@ func FindReusableSessionIn(items map[string]ConversationRecord, index map[string · 1029 unmodified lines | |||
| 1030 | } | 1030 | } |
| 1031 | return ConversationRecord{}, nil, 0, false | 1031 | return ConversationRecord{}, nil, 0, false |
| 1032 | } | 1032 | } |
| 1033 | |||
| 1034 | // SetConfig updates the configuration reference used by the state. | ||
| 1035 | // This allows hot-reload of configuration to take effect for existing | ||
| 1036 | // runtime states that were cached on auth during previous requests. | ||
| 1037 | func (s *GeminiWebState) SetConfig(cfg *config.Config) { | ||
| 1038 | s.cfg = cfg | ||
| 1039 | } | ||
| @@ -168,6 +168,8 @@ func (e *GeminiWebExecutor) stateFor(auth *cliproxyauth.Auth) (*geminiwebapi.Gem · 167 unmodified lines | |||
| 168 | return nil, fmt.Errorf("gemini-web executor: auth is nil") | 168 | return nil, fmt.Errorf("gemini-web executor: auth is nil") |
| 169 | } | 169 | } |
| 170 | if runtime, ok := auth.Runtime.(*geminiWebRuntime); ok && runtime != nil && runtime.state != nil { | 170 | if runtime, ok := auth.Runtime.(*geminiWebRuntime); ok && runtime != nil && runtime.state != nil { |
| 171 | // Hot-reload: ensure cached state sees the latest config | ||
| 172 | runtime.state.SetConfig(e.cfg) | ||
| 171 | return runtime.state, nil | 173 | return runtime.state, nil |
| 172 | } | 174 | } |
| 173 | 175 | ||
| @@ -175,6 +177,8 @@ func (e *GeminiWebExecutor) stateFor(auth *cliproxyauth.Auth) (*geminiwebapi.Gem · 1 unmodified line | |||
| 175 | defer e.mu.Unlock() | 177 | defer e.mu.Unlock() |
| 176 | 178 | ||
| 177 | if runtime, ok := auth.Runtime.(*geminiWebRuntime); ok && runtime != nil && runtime.state != nil { | 179 | if runtime, ok := auth.Runtime.(*geminiWebRuntime); ok && runtime != nil && runtime.state != nil { |
| 180 | // Hot-reload: ensure cached state sees the latest config | ||
| 181 | runtime.state.SetConfig(e.cfg) | ||
| 178 | return runtime.state, nil | 182 | return runtime.state, nil |
| 179 | } | 183 | } |
| 180 | 184 | ||