Skip to content

Commit 9ffab48

Browse files
author
sagitchu
committed
fix: native gem
1 parent ea23b9f commit 9ffab48

4 files changed

Lines changed: 30 additions & 5 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ gemini:
158158
default_temperature: 0.2
159159
top_p: 0.8
160160
max_output_tokens: 1024
161+
162+
# Native Gem (Use Gems created on gemini.google.com)
163+
- id: "my-native-gem"
164+
model: "gemini-2.0-flash"
165+
is_native: true # This flag passes the 'id' to Google's servers
166+
default_temperature: 1.0 # Parameters can still be overridden locally
167+
max_output_tokens: 8192
161168
```
162169
163170
Example request (Chat Completions):

README.zh.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ gemini:
158158
default_temperature: 0.2
159159
top_p: 0.8
160160
max_output_tokens: 1024
161+
162+
# 原生 Gem (使用在 gemini.google.com 上创建的 Gems)
163+
- id: "my-native-gem"
164+
model: "gemini-2.0-flash"
165+
is_native: true # 此标志会将 'id' 传递给 Google 服务器
166+
default_temperature: 1.0 # 仍然可以在本地覆盖参数
167+
max_output_tokens: 8192
161168
```
162169
163170
请求示例(Chat Completions):

app/server/chat.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,8 @@ async def create_chat_completion(
709709
if gem.system_prompt:
710710
_inject_gem_system_prompt(request.messages, gem.system_prompt)
711711

712+
native_gem_id = gem_id if (gem and gem.is_native) else None
713+
712714
try:
713715
model = Model.from_name(actual_model)
714716
except ValueError as exc:
@@ -733,6 +735,7 @@ async def create_chat_completion(
733735
model,
734736
request.messages,
735737
gem_id=gem_id,
738+
native_gem_id=native_gem_id,
736739
)
737740

738741
# Keep track of whether we are using a reused session for fallback logic
@@ -767,7 +770,7 @@ async def create_chat_completion(
767770
try:
768771
client = await pool.acquire()
769772
logger.info(f"[DEBUG_GEM] Initializing new chat session with model={model} using client: {client.id}")
770-
session = client.start_chat(model=model)
773+
session = client.start_chat(model=model, gem=native_gem_id)
771774
messages_to_send = _prepare_messages_for_model(
772775
request.messages, request.tools, request.tool_choice, extra_instructions
773776
)
@@ -845,7 +848,7 @@ async def create_chat_completion(
845848
f"Fallback attempt {i+1}/{max_retries}: Switching to client {retry_client.id}"
846849
)
847850

848-
retry_session = retry_client.start_chat(model=model)
851+
retry_session = retry_client.start_chat(model=model, gem=native_gem_id)
849852
response = await _send_with_split(
850853
retry_session, fallback_model_input, files=fallback_files
851854
)
@@ -982,6 +985,8 @@ async def create_response(
982985
if gem:
983986
_apply_gem_overrides(request_data, gem)
984987

988+
native_gem_id = gem_id if (gem and gem.is_native) else None
989+
985990
structured_requirement = _build_structured_requirement(request_data.response_format)
986991
if structured_requirement and request_data.stream:
987992
logger.debug(
@@ -1064,6 +1069,7 @@ async def create_response(
10641069
model,
10651070
messages,
10661071
gem_id=gem_id,
1072+
native_gem_id=native_gem_id,
10671073
)
10681074

10691075
async def _build_payload(
@@ -1098,7 +1104,7 @@ async def _build_payload(
10981104
try:
10991105
client = await pool.acquire()
11001106
logger.info(f"Initializing new session for responses with client: {client.id}")
1101-
session = client.start_chat(model=model)
1107+
session = client.start_chat(model=model, gem=native_gem_id)
11021108
payload_messages = messages
11031109
model_input, files = await _build_payload(payload_messages, _reuse_session=False)
11041110
except ValueError as e:
@@ -1185,7 +1191,7 @@ async def _build_payload(
11851191
f"Fallback attempt {i+1}/{max_retries}: Switching to client {retry_client.id}"
11861192
)
11871193

1188-
retry_session = retry_client.start_chat(model=model)
1194+
retry_session = retry_client.start_chat(model=model, gem=native_gem_id)
11891195
model_output = await _send_with_split(
11901196
retry_session, fallback_model_input, files=fallback_files
11911197
)
@@ -1432,6 +1438,7 @@ async def _find_reusable_session(
14321438
model: Model,
14331439
messages: list[Message],
14341440
gem_id: str | None = None,
1441+
native_gem_id: str | None = None,
14351442
) -> tuple[ChatSession | None, GeminiClientWrapper | None, list[Message]]:
14361443
"""Find an existing chat session that matches the *longest* prefix of
14371444
``messages`` **whose last element is an assistant/system reply**.
@@ -1463,7 +1470,7 @@ async def _find_reusable_session(
14631470
try:
14641471
if conv := db.find(model.model_name, search_history, gem_id=gem_id):
14651472
client = await pool.acquire(conv.client_id)
1466-
session = client.start_chat(metadata=conv.metadata, model=model)
1473+
session = client.start_chat(metadata=conv.metadata, model=model, gem=native_gem_id)
14671474
remain = messages[search_end:]
14681475
return session, client, remain
14691476
except Exception as e:

app/utils/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class GemDefinition(BaseModel):
5555

5656
id: str = Field(..., description="Unique identifier for the gem")
5757
model: str = Field(..., description="Model name to use when this gem is selected")
58+
is_native: bool = Field(
59+
default=False,
60+
description="If True, this gem ID is passed upstream to Google's servers. If False, it is a local configuration preset.",
61+
)
5862
system_prompt: Optional[str] = Field(
5963
default=None,
6064
description="Optional system prompt injected before user messages",

0 commit comments

Comments
 (0)