feat(gemini-web): Replace code-mode with flexible gem-mode

This commit is contained in:
hkfires
2025-10-07 19:36:22 +08:00
parent 39337627b9
commit 43665cb649
6 changed files with 41 additions and 16 deletions

View File

@@ -328,7 +328,7 @@ The server uses a YAML configuration file (`config.yaml`) located in the project
| `openai-compatibility.*.models.*.alias` | string | "" | The alias used in the API. | | `openai-compatibility.*.models.*.alias` | string | "" | The alias used in the API. |
| `gemini-web` | object | {} | Configuration specific to the Gemini Web client. | | `gemini-web` | object | {} | Configuration specific to the Gemini Web client. |
| `gemini-web.context` | boolean | true | Enables conversation context reuse for continuous dialogue. | | `gemini-web.context` | boolean | true | Enables conversation context reuse for continuous dialogue. |
| `gemini-web.code-mode` | boolean | false | Enables code mode for optimized responses in coding-related tasks. | | `gemini-web.gem-mode` | string | "" | Selects a predefined Gem to attach for Gemini Web requests; allowed values: `coding-partner`, `writing-editor`. When empty, no Gem is attached. |
| `gemini-web.max-chars-per-request` | integer | 1,000,000 | The maximum number of characters to send to Gemini Web in a single request. | | `gemini-web.max-chars-per-request` | integer | 1,000,000 | The maximum number of characters to send to Gemini Web in a single request. |
| `gemini-web.disable-continuation-hint` | boolean | false | Disables the continuation hint for split prompts. | | `gemini-web.disable-continuation-hint` | boolean | false | Disables the continuation hint for split prompts. |
@@ -378,7 +378,7 @@ quota-exceeded:
# Gemini Web client configuration # Gemini Web client configuration
gemini-web: gemini-web:
context: true # Enable conversation context reuse context: true # Enable conversation context reuse
code-mode: false # Enable code mode gem-mode: "" # Select Gem: "coding-partner" or "writing-editor"; empty means no Gem
max-chars-per-request: 1000000 # Max characters per request max-chars-per-request: 1000000 # Max characters per request
# API keys for official Generative Language API # API keys for official Generative Language API

View File

@@ -340,7 +340,7 @@ console.log(await claudeResponse.json());
| `openai-compatibility.*.models.*.alias` | string | "" | 在API中使用的别名。 | | `openai-compatibility.*.models.*.alias` | string | "" | 在API中使用的别名。 |
| `gemini-web` | object | {} | Gemini Web 客户端的特定配置。 | | `gemini-web` | object | {} | Gemini Web 客户端的特定配置。 |
| `gemini-web.context` | boolean | true | 是否启用会话上下文重用,以实现连续对话。 | | `gemini-web.context` | boolean | true | 是否启用会话上下文重用,以实现连续对话。 |
| `gemini-web.code-mode` | boolean | false | 是否启用代码模式,优化代码相关任务的响应。 | | `gemini-web.gem-mode` | string | "" | 选择要附加的预设 Gem`coding-partner` 或 `writing-editor`);为空表示不附加。 |
| `gemini-web.max-chars-per-request` | integer | 1,000,000 | 单次请求发送给 Gemini Web 的最大字符数。 | | `gemini-web.max-chars-per-request` | integer | 1,000,000 | 单次请求发送给 Gemini Web 的最大字符数。 |
| `gemini-web.disable-continuation-hint` | boolean | false | 当提示被拆分时,是否禁用连续提示的暗示。 | | `gemini-web.disable-continuation-hint` | boolean | false | 当提示被拆分时,是否禁用连续提示的暗示。 |
@@ -390,7 +390,7 @@ quota-exceeded:
# Gemini Web 客户端配置 # Gemini Web 客户端配置
gemini-web: gemini-web:
context: true # 启用会话上下文重用 context: true # 启用会话上下文重用
code-mode: false # 启用代码模式 gem-mode: "" # 选择 Gem"coding-partner" 或 "writing-editor";为空表示不附加
max-chars-per-request: 1000000 # 单次请求最大字符数 max-chars-per-request: 1000000 # 单次请求最大字符数
# AIStduio Gemini API 的 API 密钥 # AIStduio Gemini API 的 API 密钥

View File

@@ -90,10 +90,8 @@ quota-exceeded:
# # Disable the short continuation hint appended to intermediate chunks # # Disable the short continuation hint appended to intermediate chunks
# # when splitting long prompts. Default is false (hint enabled by default). # # when splitting long prompts. Default is false (hint enabled by default).
# disable-continuation-hint: false # disable-continuation-hint: false
# # Code mode: # # Gem selection (Gem Mode):
# # - true: enable XML wrapping hint and attach the coding-partner Gem. # # - "coding-partner": attach the predefined Coding partner Gem
# # Thought merging (<think> into visible content) applies to STREAMING only; # # - "writing-editor": attach the predefined Writing editor Gem
# # non-stream responses keep reasoning/thought parts separate for clients # # - empty: do not attach any Gem
# # that expect explicit reasoning fields. # gem-mode: ""
# # - false: disable XML hint and keep <think> separate
# code-mode: false

View File

@@ -62,10 +62,19 @@ type GeminiWebConfig struct {
// Defaults to true if not set in YAML (see LoadConfig). // Defaults to true if not set in YAML (see LoadConfig).
Context bool `yaml:"context" json:"context"` Context bool `yaml:"context" json:"context"`
// CodeMode, when true, enables coding mode behaviors for Gemini Web: // GemMode selects a predefined Gem to attach for Gemini Web requests.
// - Attach the predefined "Coding partner" Gem // Allowed values:
// - Enable XML wrapping hint for tool markup // - "coding-partner"
// - Merge <think> content into visible content for tool-friendly output // - "writing-editor"
// When empty, no Gem is attached by configuration.
// This is independent from CodeMode below, which is kept for backwards compatibility.
GemMode string `yaml:"gem-mode" json:"gem-mode"`
// CodeMode enables legacy coding-mode behaviors for Gemini Web.
// Backwards compatibility: when true, the service behaves as before by
// attaching the predefined "Coding partner" Gem and enabling extra
// conveniences (e.g., XML wrapping hints). Prefer GemMode for selecting
// a Gem going forward.
CodeMode bool `yaml:"code-mode" json:"code-mode"` CodeMode bool `yaml:"code-mode" json:"code-mode"`
// MaxCharsPerRequest caps the number of characters (runes) sent to // MaxCharsPerRequest caps the number of characters (runes) sent to

View File

@@ -696,7 +696,22 @@ func (s *GeminiWebState) findReusableSession(modelName string, msgs []RoleText)
} }
func (s *GeminiWebState) getConfiguredGem() *Gem { func (s *GeminiWebState) getConfiguredGem() *Gem {
if s.cfg != nil && s.cfg.GeminiWeb.CodeMode { if s.cfg == nil {
return nil
}
// New behavior: attach Gem based on explicit GemMode selection.
// Only attaches the Gem; does not toggle any other behavior.
if gm := strings.ToLower(strings.TrimSpace(s.cfg.GeminiWeb.GemMode)); gm != "" {
switch gm {
case "coding-partner":
return &Gem{ID: "coding-partner", Name: "Coding partner", Predefined: true}
case "writing-editor":
return &Gem{ID: "writing-editor", Name: "Writing editor", Predefined: true}
}
}
// Backwards compatibility: legacy CodeMode still attaches Coding partner
// and may enable extra behaviors elsewhere.
if s.cfg.GeminiWeb.CodeMode {
return &Gem{ID: "coding-partner", Name: "Coding partner", Predefined: true} return &Gem{ID: "coding-partner", Name: "Coding partner", Predefined: true}
} }
return nil return nil

View File

@@ -521,6 +521,9 @@ func (w *Watcher) reloadConfig() bool {
if oldConfig.GeminiWeb.DisableContinuationHint != newConfig.GeminiWeb.DisableContinuationHint { if oldConfig.GeminiWeb.DisableContinuationHint != newConfig.GeminiWeb.DisableContinuationHint {
log.Debugf(" gemini-web.disable-continuation-hint: %t -> %t", oldConfig.GeminiWeb.DisableContinuationHint, newConfig.GeminiWeb.DisableContinuationHint) log.Debugf(" gemini-web.disable-continuation-hint: %t -> %t", oldConfig.GeminiWeb.DisableContinuationHint, newConfig.GeminiWeb.DisableContinuationHint)
} }
if oldConfig.GeminiWeb.GemMode != newConfig.GeminiWeb.GemMode {
log.Debugf(" gemini-web.gem-mode: %s -> %s", oldConfig.GeminiWeb.GemMode, newConfig.GeminiWeb.GemMode)
}
if oldConfig.GeminiWeb.CodeMode != newConfig.GeminiWeb.CodeMode { if oldConfig.GeminiWeb.CodeMode != newConfig.GeminiWeb.CodeMode {
log.Debugf(" gemini-web.code-mode: %t -> %t", oldConfig.GeminiWeb.CodeMode, newConfig.GeminiWeb.CodeMode) log.Debugf(" gemini-web.code-mode: %t -> %t", oldConfig.GeminiWeb.CodeMode, newConfig.GeminiWeb.CodeMode)
} }