Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/flat-buttons-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/ai-gemini': patch
---

Fix thinking output for Gemini Text adapter
6 changes: 6 additions & 0 deletions .changeset/goofy-cities-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@tanstack/ai-gemini': patch
'@tanstack/ai': patch
---

fixed an issue with gemini and thought chunks processing
4 changes: 2 additions & 2 deletions examples/ts-react-chat/src/lib/model-selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export const MODEL_OPTIONS: Array<ModelOption> = [
},
{
provider: 'gemini',
model: 'gemini-exp-1206',
label: 'Gemini - Exp 1206 (Pro)',
model: 'gemini-2.5-flash',
label: 'Gemini 2.5 - Flash',
},

// Ollama
Expand Down
7 changes: 7 additions & 0 deletions examples/ts-react-chat/src/routes/api.tanchat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,17 @@ export const Route = createFileRoute('/api/tanchat')({
adapter: geminiText(
(model || 'gemini-2.5-flash') as 'gemini-2.5-flash',
),
modelOptions: {
thinkingConfig: {
includeThoughts: true,
thinkingBudget: 100,
},
},
}),
grok: () =>
createChatOptions({
adapter: grokText((model || 'grok-3') as 'grok-3'),
modelOptions: {},
}),
ollama: () =>
createChatOptions({
Expand Down
50 changes: 36 additions & 14 deletions packages/typescript/ai-gemini/src/adapters/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
GenerateContentResponse,
GoogleGenAI,
Part,
ThinkingLevel,
} from '@google/genai'
import type {
ContentPart,
Expand Down Expand Up @@ -212,15 +213,26 @@ export class GeminiTextAdapter<

for (const part of parts) {
if (part.text) {
accumulatedContent += part.text
yield {
type: 'content',
id: generateId(this.name),
model,
timestamp,
delta: part.text,
content: accumulatedContent,
role: 'assistant',
if (part.thought) {
yield {
type: 'thinking',
content: part.text,
delta: part.text,
id: generateId(this.name),
model,
timestamp,
}
} else {
accumulatedContent += part.text
yield {
type: 'content',
id: generateId(this.name),
model,
timestamp,
delta: part.text,
content: accumulatedContent,
role: 'assistant',
}
}
}

Expand Down Expand Up @@ -476,19 +488,29 @@ export class GeminiTextAdapter<
})
}

private mapCommonOptionsToGemini(options: TextOptions) {
const providerOpts = options.modelOptions
private mapCommonOptionsToGemini(
options: TextOptions<GeminiTextProviderOptions>,
) {
const modelOpts = options.modelOptions
const thinkingConfig = modelOpts?.thinkingConfig
const requestOptions: GenerateContentParameters = {
model: options.model,
contents: this.formatMessages(options.messages),
config: {
...providerOpts,
...modelOpts,
temperature: options.temperature,
topP: options.topP,
maxOutputTokens: options.maxTokens,
thinkingConfig: thinkingConfig
? {
...thinkingConfig,
thinkingLevel: thinkingConfig.thinkingLevel
? // Enum is provided by the SDK, we use it for the type but cast it to string constants, here we just cast them back
(thinkingConfig.thinkingLevel as ThinkingLevel)
: undefined,
}
: undefined,
systemInstruction: options.systemPrompts?.join('\n'),
...((providerOpts as Record<string, unknown> | undefined)
?.generationConfig as Record<string, unknown> | undefined),
tools: convertToolsToProviderFormat(options.tools),
},
}
Expand Down
72 changes: 39 additions & 33 deletions packages/typescript/ai-gemini/src/model-meta.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type {
GeminiCachedContentOptions,
GeminiGenerationConfigOptions,
GeminiCommonConfigOptions,
GeminiSafetyOptions,
GeminiStructuredOutputOptions,
GeminiThinkingAdvancedOptions,
GeminiThinkingOptions,
GeminiToolConfigOptions,
} from './text/text-provider-options'
Expand Down Expand Up @@ -77,10 +78,11 @@ const GEMINI_3_PRO = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
GeminiThinkingOptions &
GeminiThinkingAdvancedOptions
>

const GEMINI_3_FLASH = {
Expand Down Expand Up @@ -114,10 +116,11 @@ const GEMINI_3_FLASH = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
GeminiThinkingOptions &
GeminiThinkingAdvancedOptions
>

const GEMINI_3_PRO_IMAGE = {
Expand Down Expand Up @@ -147,10 +150,11 @@ const GEMINI_3_PRO_IMAGE = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
GeminiThinkingOptions &
GeminiThinkingAdvancedOptions
>

const GEMINI_2_5_PRO = {
Expand Down Expand Up @@ -185,7 +189,7 @@ const GEMINI_2_5_PRO = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
Expand All @@ -212,7 +216,7 @@ const GEMINI_2_5_PRO_TTS = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions
>

Expand Down Expand Up @@ -248,7 +252,7 @@ const GEMINI_2_5_FLASH = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
Expand Down Expand Up @@ -285,7 +289,7 @@ const GEMINI_2_5_FLASH_PREVIEW = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
Expand Down Expand Up @@ -318,7 +322,7 @@ const GEMINI_2_5_FLASH_IMAGE = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions
>
/**
Expand Down Expand Up @@ -377,7 +381,7 @@ const GEMINI_2_5_FLASH_TTS = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions
>

Expand Down Expand Up @@ -412,7 +416,7 @@ const GEMINI_2_5_FLASH_LITE = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
Expand Down Expand Up @@ -448,7 +452,7 @@ const GEMINI_2_5_FLASH_LITE_PREVIEW = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
Expand Down Expand Up @@ -484,7 +488,7 @@ const GEMINI_2_FLASH = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions
>
Expand Down Expand Up @@ -515,7 +519,7 @@ const GEMINI_2_FLASH_IMAGE = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions
>
/*
Expand Down Expand Up @@ -579,7 +583,7 @@ const GEMINI_2_FLASH_LITE = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions
>
Expand All @@ -603,7 +607,7 @@ const IMAGEN_4_GENERATE = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions
>

Expand All @@ -626,7 +630,7 @@ const IMAGEN_4_GENERATE_ULTRA = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions
>

Expand All @@ -649,7 +653,7 @@ const IMAGEN_4_GENERATE_FAST = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions
>

Expand All @@ -671,7 +675,7 @@ const IMAGEN_3 = {
} as const satisfies ModelMeta<
GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions
>
/**
Expand Down Expand Up @@ -909,55 +913,57 @@ export type GeminiChatModelProviderOptionsByName = {
// Models with thinking and structured output support
[GEMINI_3_PRO.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
GeminiThinkingOptions &
GeminiThinkingAdvancedOptions
[GEMINI_3_FLASH.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
GeminiThinkingOptions &
GeminiThinkingAdvancedOptions
[GEMINI_2_5_PRO.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
[GEMINI_2_5_FLASH.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
[GEMINI_2_5_FLASH_PREVIEW.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
[GEMINI_2_5_FLASH_LITE.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
[GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions &
GeminiThinkingOptions
// Models with structured output but no thinking support
[GEMINI_2_FLASH.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions
[GEMINI_2_FLASH_LITE.name]: GeminiToolConfigOptions &
GeminiSafetyOptions &
GeminiGenerationConfigOptions &
GeminiCommonConfigOptions &
GeminiCachedContentOptions &
GeminiStructuredOutputOptions
}
Expand Down
Loading
Loading