Skip to content

Commit 73832e5

Browse files
committed
feat: add support for Gemini thinking capabilities and simplify welcome UI
- Added `ThoughtSignature` and `ChunkTypeThinking` support for Google Gemini provider. - Properly parse and accumulate Gemini thinking outputs. - Echo `ThoughtSignature` back to Gemini in tool calls. - Simplified the welcome UI by removing the bottom hint line and adjusting spacing. Signed-off-by: Meng Yan <myan@redhat.com>
1 parent 5c450de commit 73832e5

4 files changed

Lines changed: 29 additions & 25 deletions

File tree

internal/app/render/message.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,7 @@ func RenderWelcome() string {
7070
slashStyle.Render("/") +
7171
bracketStyle.Render(">")
7272

73-
hintStyle := lipgloss.NewStyle().Foreground(theme.CurrentTheme.TextDisabled)
74-
75-
var sb strings.Builder
76-
sb.WriteString("\n")
77-
sb.WriteString(icon + "\n")
78-
sb.WriteString("\n")
79-
sb.WriteString(" " + hintStyle.Render("Enter to send · Esc to stop · Shift+Tab mode · Ctrl+C exit") + "\n")
80-
81-
return sb.String()
73+
return "\n" + icon
8274
}
8375

8476
// OperationModeParams holds the parameters needed for rendering mode status.

internal/app/view.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,8 @@ func (m model) View() string {
8282
var view strings.Builder
8383
if chatSection != "" {
8484
view.WriteString(chatSection)
85-
view.WriteString("\n")
86-
} else if m.conv.CommittedCount > 0 {
87-
view.WriteString("\n")
8885
}
86+
view.WriteString("\n")
8987
view.WriteString(separator)
9088
view.WriteString("\n")
9189
view.WriteString(inputView)

internal/message/message.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ type ImageData struct {
5252

5353
// ToolCall represents a tool call from the model.
5454
type ToolCall struct {
55-
ID string `json:"id"`
56-
Name string `json:"name"`
57-
Input string `json:"input"`
55+
ID string `json:"id"`
56+
Name string `json:"name"`
57+
Input string `json:"input"`
58+
ThoughtSignature []byte `json:"thought_signature,omitempty"` // Google Gemini: opaque signature to echo back
5859
}
5960

6061
// ToolResult represents the result of a tool execution.

internal/provider/google/client.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,17 @@ func (c *Client) Stream(ctx context.Context, opts provider.CompletionOptions) <-
8585
args = nil
8686
}
8787
}
88-
parts = append(parts, &genai.Part{
88+
p := &genai.Part{
8989
FunctionCall: &genai.FunctionCall{
9090
ID: tc.ID,
9191
Name: tc.Name,
9292
Args: args,
9393
},
94-
})
94+
}
95+
if len(tc.ThoughtSignature) > 0 {
96+
p.ThoughtSignature = tc.ThoughtSignature
97+
}
98+
parts = append(parts, p)
9599
}
96100
} else if len(msg.Images) > 0 {
97101
// Multimodal message with images
@@ -184,13 +188,21 @@ func (c *Client) Stream(ctx context.Context, opts provider.CompletionOptions) <-
184188
}
185189

186190
for _, part := range candidate.Content.Parts {
187-
// Handle text
191+
// Handle text (distinguish thinking from regular text)
188192
if part.Text != "" {
189-
ch <- message.StreamChunk{
190-
Type: message.ChunkTypeText,
191-
Text: part.Text,
193+
if part.Thought {
194+
ch <- message.StreamChunk{
195+
Type: message.ChunkTypeThinking,
196+
Text: part.Text,
197+
}
198+
response.Thinking += part.Text
199+
} else {
200+
ch <- message.StreamChunk{
201+
Type: message.ChunkTypeText,
202+
Text: part.Text,
203+
}
204+
response.Content += part.Text
192205
}
193-
response.Content += part.Text
194206
}
195207

196208
// Handle function calls
@@ -211,9 +223,10 @@ func (c *Client) Stream(ctx context.Context, opts provider.CompletionOptions) <-
211223
}
212224

213225
response.ToolCalls = append(response.ToolCalls, message.ToolCall{
214-
ID: fc.ID,
215-
Name: fc.Name,
216-
Input: string(argsJSON),
226+
ID: fc.ID,
227+
Name: fc.Name,
228+
Input: string(argsJSON),
229+
ThoughtSignature: part.ThoughtSignature,
217230
})
218231
}
219232
}

0 commit comments

Comments
 (0)