@tanstack/ai-gemini 0.10.10 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,191 @@
1
+ import type { Interactions } from '@google/genai'
2
+ import type { CustomEvent, StreamChunk } from '@tanstack/ai'
3
+
4
+ /**
5
+ * `CUSTOM` event carrying the server-assigned Interactions API id. Emitted
6
+ * immediately before `RUN_FINISHED` on a successful run; pass `interactionId`
7
+ * back as `modelOptions.previous_interaction_id` to continue the conversation.
8
+ */
9
+ export interface GeminiInteractionIdEvent extends Omit<
10
+ CustomEvent,
11
+ 'name' | 'value'
12
+ > {
13
+ name: 'gemini.interactionId'
14
+ value: { interactionId: string }
15
+ }
16
+
17
+ /**
18
+ * `CUSTOM` event carrying a raw `google_search_call` content delta from the
19
+ * Interactions API. Payload shape is owned by `@google/genai`.
20
+ */
21
+ export interface GeminiGoogleSearchCallEvent extends Omit<
22
+ CustomEvent,
23
+ 'name' | 'value'
24
+ > {
25
+ name: 'gemini.googleSearchCall'
26
+ value: Interactions.ContentDelta.GoogleSearchCallDelta
27
+ }
28
+
29
+ /**
30
+ * `CUSTOM` event carrying a raw `google_search_result` content delta from
31
+ * the Interactions API.
32
+ */
33
+ export interface GeminiGoogleSearchResultEvent extends Omit<
34
+ CustomEvent,
35
+ 'name' | 'value'
36
+ > {
37
+ name: 'gemini.googleSearchResult'
38
+ value: Interactions.ContentDelta.GoogleSearchResultDelta
39
+ }
40
+
41
+ /**
42
+ * `CUSTOM` event carrying a raw `code_execution_call` content delta from
43
+ * the Interactions API.
44
+ */
45
+ export interface GeminiCodeExecutionCallEvent extends Omit<
46
+ CustomEvent,
47
+ 'name' | 'value'
48
+ > {
49
+ name: 'gemini.codeExecutionCall'
50
+ value: Interactions.ContentDelta.CodeExecutionCallDelta
51
+ }
52
+
53
+ /**
54
+ * `CUSTOM` event carrying a raw `code_execution_result` content delta from
55
+ * the Interactions API.
56
+ */
57
+ export interface GeminiCodeExecutionResultEvent extends Omit<
58
+ CustomEvent,
59
+ 'name' | 'value'
60
+ > {
61
+ name: 'gemini.codeExecutionResult'
62
+ value: Interactions.ContentDelta.CodeExecutionResultDelta
63
+ }
64
+
65
+ /**
66
+ * `CUSTOM` event carrying a raw `url_context_call` content delta from the
67
+ * Interactions API.
68
+ */
69
+ export interface GeminiUrlContextCallEvent extends Omit<
70
+ CustomEvent,
71
+ 'name' | 'value'
72
+ > {
73
+ name: 'gemini.urlContextCall'
74
+ value: Interactions.ContentDelta.URLContextCallDelta
75
+ }
76
+
77
+ /**
78
+ * `CUSTOM` event carrying a raw `url_context_result` content delta from the
79
+ * Interactions API.
80
+ */
81
+ export interface GeminiUrlContextResultEvent extends Omit<
82
+ CustomEvent,
83
+ 'name' | 'value'
84
+ > {
85
+ name: 'gemini.urlContextResult'
86
+ value: Interactions.ContentDelta.URLContextResultDelta
87
+ }
88
+
89
+ /**
90
+ * `CUSTOM` event carrying a raw `file_search_call` content delta from the
91
+ * Interactions API.
92
+ */
93
+ export interface GeminiFileSearchCallEvent extends Omit<
94
+ CustomEvent,
95
+ 'name' | 'value'
96
+ > {
97
+ name: 'gemini.fileSearchCall'
98
+ value: Interactions.ContentDelta.FileSearchCallDelta
99
+ }
100
+
101
+ /**
102
+ * `CUSTOM` event carrying a raw `file_search_result` content delta from the
103
+ * Interactions API.
104
+ */
105
+ export interface GeminiFileSearchResultEvent extends Omit<
106
+ CustomEvent,
107
+ 'name' | 'value'
108
+ > {
109
+ name: 'gemini.fileSearchResult'
110
+ value: Interactions.ContentDelta.FileSearchResultDelta
111
+ }
112
+
113
+ /**
114
+ * Discriminated union of every `CUSTOM` event the
115
+ * `geminiTextInteractions()` adapter emits.
116
+ *
117
+ * Each variant carries the lifecycle fields `model?` / `timestamp?` /
118
+ * `rawEvent?` from {@link CustomEvent} so a single narrow against the
119
+ * `StreamChunk` union yields a fully typed payload — no helper or `as`
120
+ * cast required:
121
+ *
122
+ * ```ts
123
+ * for await (const chunk of stream as GeminiInteractionsStream) {
124
+ * if (chunk.type === 'CUSTOM' && chunk.name === 'gemini.interactionId') {
125
+ * chunk.value.interactionId // string
126
+ * }
127
+ * }
128
+ * ```
129
+ *
130
+ * The four tool-delta variant pairs (`google_search`, `code_execution`,
131
+ * `url_context`, `file_search`) forward the raw
132
+ * `Interactions.ContentDelta.*Delta` payload from `@google/genai` so
133
+ * consumers stay in sync with SDK shape changes automatically.
134
+ * `computer_use` is accepted as a request tool but the API does not
135
+ * stream per-delta CUSTOM events for it.
136
+ */
137
+ export type GeminiInteractionsCustomEvent =
138
+ | GeminiInteractionIdEvent
139
+ | GeminiGoogleSearchCallEvent
140
+ | GeminiGoogleSearchResultEvent
141
+ | GeminiCodeExecutionCallEvent
142
+ | GeminiCodeExecutionResultEvent
143
+ | GeminiUrlContextCallEvent
144
+ | GeminiUrlContextResultEvent
145
+ | GeminiFileSearchCallEvent
146
+ | GeminiFileSearchResultEvent
147
+
148
+ /** String-literal union of the event names in {@link GeminiInteractionsCustomEvent}. */
149
+ export type GeminiInteractionsCustomEventName =
150
+ GeminiInteractionsCustomEvent['name']
151
+
152
+ /**
153
+ * Look up the typed `value` payload for a specific event name.
154
+ *
155
+ * ```ts
156
+ * const v: GeminiInteractionsCustomEventValue<'gemini.interactionId'>
157
+ * // ^? { interactionId: string }
158
+ * ```
159
+ */
160
+ export type GeminiInteractionsCustomEventValue<
161
+ TName extends GeminiInteractionsCustomEventName,
162
+ > = Extract<GeminiInteractionsCustomEvent, { name: TName }>['value']
163
+
164
+ /**
165
+ * Public stream type for `chatStream` results from the
166
+ * `geminiTextInteractions()` adapter. Yields the standard
167
+ * {@link StreamChunk} lifecycle events plus the Gemini-specific
168
+ * `CUSTOM` events declared in {@link GeminiInteractionsCustomEvent},
169
+ * so a single discriminated narrow on `chunk.name` gives a typed
170
+ * `chunk.value`:
171
+ *
172
+ * ```ts
173
+ * import type { GeminiInteractionsStream } from '@tanstack/ai-gemini/experimental'
174
+ *
175
+ * for await (const chunk of stream as GeminiInteractionsStream) {
176
+ * if (chunk.type === 'CUSTOM' && chunk.name === 'gemini.interactionId') {
177
+ * chunk.value.interactionId // typed as string
178
+ * }
179
+ * }
180
+ * ```
181
+ *
182
+ * Caveat: server tools may emit arbitrary user-defined custom events via
183
+ * `emitCustomEvent(name, value)`. Those flow through the stream at
184
+ * runtime but are intentionally absent from this union — including a
185
+ * bare {@link CustomEvent} would collapse `chunk.value` back to `any`
186
+ * after the narrow. Branch on `CUSTOM` outside the literal-`name`
187
+ * narrows or cast explicitly if you rely on `emitCustomEvent`.
188
+ */
189
+ export type GeminiInteractionsStream = AsyncIterable<
190
+ Exclude<StreamChunk, CustomEvent> | GeminiInteractionsCustomEvent
191
+ >
@@ -0,0 +1,26 @@
1
+ import type { Interactions } from '@google/genai'
2
+
3
+ /**
4
+ * Provider options for `geminiTextInteractions()`. Derived from the SDK's
5
+ * own `interactions.create` param shape so field types (including the
6
+ * allowed `response_modalities` values and the `generation_config` schema)
7
+ * stay in sync with `@google/genai` automatically.
8
+ *
9
+ * `input`, `model`, `tools`, `stream`, and `api_version` are intentionally
10
+ * omitted — the adapter derives those from its constructor args and the
11
+ * chat options.
12
+ *
13
+ * @see https://ai.google.dev/gemini-api/docs/interactions
14
+ * @experimental Interactions API is in Beta.
15
+ */
16
+ export type ExternalTextInteractionsProviderOptions = Pick<
17
+ Interactions.CreateModelInteractionParamsStreaming,
18
+ | 'previous_interaction_id'
19
+ | 'store'
20
+ | 'background'
21
+ | 'system_instruction'
22
+ | 'response_modalities'
23
+ | 'response_format'
24
+ | 'response_mime_type'
25
+ | 'generation_config'
26
+ >
package/src/index.ts CHANGED
@@ -62,7 +62,10 @@ export {
62
62
  } from './adapters/audio'
63
63
 
64
64
  // Re-export models from model-meta for convenience
65
- export { GEMINI_MODELS } from './model-meta'
65
+ export {
66
+ GEMINI_MODELS,
67
+ GEMINI_COMBINED_TOOLS_AND_SCHEMA_MODELS,
68
+ } from './model-meta'
66
69
  export { GEMINI_MODELS as GeminiTextModels } from './model-meta'
67
70
  export { GEMINI_IMAGE_MODELS as GeminiImageModels } from './model-meta'
68
71
  export { GEMINI_TTS_MODELS as GeminiTTSModels } from './model-meta'
package/src/model-meta.ts CHANGED
@@ -1015,6 +1015,21 @@ export const GEMINI_MODELS = [
1015
1015
  GEMINI_3_5_FLASH.name,
1016
1016
  ] as const
1017
1017
 
1018
+ /**
1019
+ * Gemini models that support combining `tools` + `responseSchema` in a
1020
+ * single streaming `generateContent` call (per issue #605). Per the
1021
+ * provider matrix, Gemini 3.x natively interleaves the schema-constrained
1022
+ * answer with function-calling on one pass; Gemini 2.x is unsupported /
1023
+ * brittle and keeps the engine's legacy finalization fallback.
1024
+ */
1025
+ export const GEMINI_COMBINED_TOOLS_AND_SCHEMA_MODELS = new Set<string>([
1026
+ GEMINI_3_1_PRO.name,
1027
+ GEMINI_3_PRO.name,
1028
+ GEMINI_3_FLASH.name,
1029
+ GEMINI_3_1_FLASH_LITE.name,
1030
+ GEMINI_3_5_FLASH.name,
1031
+ ])
1032
+
1018
1033
  export type GeminiModels = (typeof GEMINI_MODELS)[number]
1019
1034
 
1020
1035
  export type GeminiImageModels = (typeof GEMINI_IMAGE_MODELS)[number]