From 9bb7df7af7232f99381bd1359fbc2b892cd270d8 Mon Sep 17 00:00:00 2001 From: hkfires <10558748+hkfires@users.noreply.github.com> Date: Tue, 7 Oct 2025 20:23:33 +0800 Subject: [PATCH] feat(gemini-web): Enable config hot-reload and fix Gem selection --- internal/provider/gemini-web/client.go | 16 +++++++++------- internal/provider/gemini-web/state.go | 7 +++++++ internal/runtime/executor/gemini_web_executor.go | 4 ++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/internal/provider/gemini-web/client.go b/internal/provider/gemini-web/client.go index f2a8cf2a..4f453268 100644 --- a/internal/provider/gemini-web/client.go +++ b/internal/provider/gemini-web/client.go @@ -380,6 +380,15 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model, } inner := []any{item0, nil, item2} + // Attach Gem first to keep index alignment with reference implementation + // so the Gemini Web UI can recognize the selected Gem. + if gem != nil { + // pad with 16 nils then gem ID + for i := 0; i < 16; i++ { + inner = append(inner, nil) + } + inner = append(inner, gem.ID) + } requestedModel := strings.ToLower(model.Name) if chat != nil && chat.RequestedModel() != "" { requestedModel = chat.RequestedModel() @@ -388,13 +397,6 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model, inner = ensureAnyLen(inner, 49) inner[49] = 14 } - if gem != nil { - // pad with 16 nils then gem ID - for i := 0; i < 16; i++ { - inner = append(inner, nil) - } - inner = append(inner, gem.ID) - } innerJSON, _ := json.Marshal(inner) outer := []any{nil, string(innerJSON)} outerJSON, _ := json.Marshal(outer) diff --git a/internal/provider/gemini-web/state.go b/internal/provider/gemini-web/state.go index 4e6c6616..dca69992 100644 --- a/internal/provider/gemini-web/state.go +++ b/internal/provider/gemini-web/state.go @@ -1030,3 +1030,10 @@ func FindReusableSessionIn(items map[string]ConversationRecord, index map[string } return ConversationRecord{}, nil, 0, false } + +// SetConfig updates the configuration reference used by the state. +// This allows hot-reload of configuration to take effect for existing +// runtime states that were cached on auth during previous requests. +func (s *GeminiWebState) SetConfig(cfg *config.Config) { + s.cfg = cfg +} diff --git a/internal/runtime/executor/gemini_web_executor.go b/internal/runtime/executor/gemini_web_executor.go index d7023f2d..435b346f 100644 --- a/internal/runtime/executor/gemini_web_executor.go +++ b/internal/runtime/executor/gemini_web_executor.go @@ -168,6 +168,8 @@ func (e *GeminiWebExecutor) stateFor(auth *cliproxyauth.Auth) (*geminiwebapi.Gem return nil, fmt.Errorf("gemini-web executor: auth is nil") } if runtime, ok := auth.Runtime.(*geminiWebRuntime); ok && runtime != nil && runtime.state != nil { + // Hot-reload: ensure cached state sees the latest config + runtime.state.SetConfig(e.cfg) return runtime.state, nil } @@ -175,6 +177,8 @@ func (e *GeminiWebExecutor) stateFor(auth *cliproxyauth.Auth) (*geminiwebapi.Gem defer e.mu.Unlock() if runtime, ok := auth.Runtime.(*geminiWebRuntime); ok && runtime != nil && runtime.state != nil { + // Hot-reload: ensure cached state sees the latest config + runtime.state.SetConfig(e.cfg) return runtime.state, nil }