@tanstack/ai-gemini 0.24.0 → 0.24.1

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.
Files changed (34) hide show
  1. package/README.md +10 -1
  2. package/dist/esm/experimental/text-interactions/adapter.d.ts +8 -5
  3. package/dist/esm/experimental/text-interactions/adapter.js +17 -9
  4. package/dist/esm/experimental/text-interactions/adapter.js.map +1 -1
  5. package/dist/esm/tools/code-execution-tool.js +3 -3
  6. package/dist/esm/tools/code-execution-tool.js.map +1 -1
  7. package/dist/esm/tools/computer-use-tool.js +4 -4
  8. package/dist/esm/tools/computer-use-tool.js.map +1 -1
  9. package/dist/esm/tools/file-search-tool.js +4 -4
  10. package/dist/esm/tools/file-search-tool.js.map +1 -1
  11. package/dist/esm/tools/gemini-provider-tool.d.ts +16 -0
  12. package/dist/esm/tools/gemini-provider-tool.js +42 -0
  13. package/dist/esm/tools/gemini-provider-tool.js.map +1 -0
  14. package/dist/esm/tools/google-maps-tool.js +4 -4
  15. package/dist/esm/tools/google-maps-tool.js.map +1 -1
  16. package/dist/esm/tools/google-search-retriveal-tool.js +4 -4
  17. package/dist/esm/tools/google-search-retriveal-tool.js.map +1 -1
  18. package/dist/esm/tools/google-search-tool.js +4 -4
  19. package/dist/esm/tools/google-search-tool.js.map +1 -1
  20. package/dist/esm/tools/tool-converter.js +5 -2
  21. package/dist/esm/tools/tool-converter.js.map +1 -1
  22. package/dist/esm/tools/url-context-tool.js +3 -3
  23. package/dist/esm/tools/url-context-tool.js.map +1 -1
  24. package/package.json +3 -3
  25. package/src/experimental/text-interactions/adapter.ts +31 -18
  26. package/src/tools/code-execution-tool.ts +9 -6
  27. package/src/tools/computer-use-tool.ts +19 -13
  28. package/src/tools/file-search-tool.ts +13 -7
  29. package/src/tools/gemini-provider-tool.ts +60 -0
  30. package/src/tools/google-maps-tool.ts +13 -7
  31. package/src/tools/google-search-retriveal-tool.ts +15 -7
  32. package/src/tools/google-search-tool.ts +13 -7
  33. package/src/tools/tool-converter.ts +5 -4
  34. package/src/tools/url-context-tool.ts +9 -6
@@ -0,0 +1,16 @@
1
+ import { ProviderTool, Tool } from '@tanstack/ai';
2
+ declare const GEMINI_PROVIDER_TOOL_KINDS: {
3
+ readonly code_execution: "gemini.code_execution";
4
+ readonly computer_use: "gemini.computer_use";
5
+ readonly file_search: "gemini.file_search";
6
+ readonly google_maps: "gemini.google_maps";
7
+ readonly google_search: "gemini.google_search";
8
+ readonly google_search_retrieval: "gemini.google_search_retrieval";
9
+ readonly url_context: "gemini.url_context";
10
+ };
11
+ type GeminiProviderToolKind = keyof typeof GEMINI_PROVIDER_TOOL_KINDS;
12
+ export declare function brandGeminiProviderTool<T extends ProviderTool<'gemini', GeminiProviderToolKind>>(tool: Omit<T, '~provider' | '~toolKind'>, toolKind: T['~toolKind']): T;
13
+ export declare function getGeminiProviderToolKind(tool: Tool): GeminiProviderToolKind | undefined;
14
+ /** Returns adapter metadata without the internal runtime discriminator. */
15
+ export declare function getGeminiProviderToolMetadata(tool: Tool): Tool['metadata'];
16
+ export {};
@@ -0,0 +1,42 @@
1
+ import { brandProviderTool } from "@tanstack/ai";
2
+ //#region src/tools/gemini-provider-tool.ts
3
+ var GEMINI_PROVIDER_TOOL_KINDS = {
4
+ code_execution: "gemini.code_execution",
5
+ computer_use: "gemini.computer_use",
6
+ file_search: "gemini.file_search",
7
+ google_maps: "gemini.google_maps",
8
+ google_search: "gemini.google_search",
9
+ google_search_retrieval: "gemini.google_search_retrieval",
10
+ url_context: "gemini.url_context"
11
+ };
12
+ function brandGeminiProviderTool(tool, toolKind) {
13
+ return brandProviderTool({
14
+ ...tool,
15
+ metadata: {
16
+ ...tool.metadata,
17
+ __kind: GEMINI_PROVIDER_TOOL_KINDS[toolKind]
18
+ }
19
+ });
20
+ }
21
+ function getGeminiProviderToolKind(tool) {
22
+ switch (tool.metadata?.["__kind"]) {
23
+ case "gemini.code_execution": return "code_execution";
24
+ case "gemini.computer_use": return "computer_use";
25
+ case "gemini.file_search": return "file_search";
26
+ case "gemini.google_maps": return "google_maps";
27
+ case "gemini.google_search": return "google_search";
28
+ case "gemini.google_search_retrieval": return "google_search_retrieval";
29
+ case "gemini.url_context": return "url_context";
30
+ default: return;
31
+ }
32
+ }
33
+ /** Returns adapter metadata without the internal runtime discriminator. */
34
+ function getGeminiProviderToolMetadata(tool) {
35
+ if (!tool.metadata) return;
36
+ const { __kind: _kind, ...metadata } = tool.metadata;
37
+ return metadata;
38
+ }
39
+ //#endregion
40
+ export { brandGeminiProviderTool, getGeminiProviderToolKind, getGeminiProviderToolMetadata };
41
+
42
+ //# sourceMappingURL=gemini-provider-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-provider-tool.js","names":[],"sources":["../../../src/tools/gemini-provider-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nconst GEMINI_PROVIDER_TOOL_KINDS = {\n code_execution: 'gemini.code_execution',\n computer_use: 'gemini.computer_use',\n file_search: 'gemini.file_search',\n google_maps: 'gemini.google_maps',\n google_search: 'gemini.google_search',\n google_search_retrieval: 'gemini.google_search_retrieval',\n url_context: 'gemini.url_context',\n} as const\n\ntype GeminiProviderToolKind = keyof typeof GEMINI_PROVIDER_TOOL_KINDS\n\nexport function brandGeminiProviderTool<\n T extends ProviderTool<'gemini', GeminiProviderToolKind>,\n>(tool: Omit<T, '~provider' | '~toolKind'>, toolKind: T['~toolKind']): T {\n return brandProviderTool<T>({\n ...tool,\n metadata: {\n ...tool.metadata,\n __kind: GEMINI_PROVIDER_TOOL_KINDS[toolKind],\n },\n })\n}\n\nexport function getGeminiProviderToolKind(\n tool: Tool,\n): GeminiProviderToolKind | undefined {\n const toolKind = tool.metadata?.['__kind']\n switch (toolKind) {\n case 'gemini.code_execution':\n return 'code_execution'\n case 'gemini.computer_use':\n return 'computer_use'\n case 'gemini.file_search':\n return 'file_search'\n case 'gemini.google_maps':\n return 'google_maps'\n case 'gemini.google_search':\n return 'google_search'\n case 'gemini.google_search_retrieval':\n return 'google_search_retrieval'\n case 'gemini.url_context':\n return 'url_context'\n default:\n return undefined\n }\n}\n\n/** Returns adapter metadata without the internal runtime discriminator. */\nexport function getGeminiProviderToolMetadata(tool: Tool): Tool['metadata'] {\n if (!tool.metadata) {\n return undefined\n }\n const { __kind: _kind, ...metadata } = tool.metadata\n void _kind\n return metadata\n}\n"],"mappings":";;AAGA,IAAM,6BAA6B;CACjC,gBAAgB;CAChB,cAAc;CACd,aAAa;CACb,aAAa;CACb,eAAe;CACf,yBAAyB;CACzB,aAAa;AACf;AAIA,SAAgB,wBAEd,MAA0C,UAA6B;CACvE,OAAO,kBAAqB;EAC1B,GAAG;EACH,UAAU;GACR,GAAG,KAAK;GACR,QAAQ,2BAA2B;EACrC;CACF,CAAC;AACH;AAEA,SAAgB,0BACd,MACoC;CAEpC,QADiB,KAAK,WAAW,WACjC;EACE,KAAK,yBACH,OAAO;EACT,KAAK,uBACH,OAAO;EACT,KAAK,sBACH,OAAO;EACT,KAAK,sBACH,OAAO;EACT,KAAK,wBACH,OAAO;EACT,KAAK,kCACH,OAAO;EACT,KAAK,sBACH,OAAO;EACT,SACE;CACJ;AACF;;AAGA,SAAgB,8BAA8B,MAA8B;CAC1E,IAAI,CAAC,KAAK,UACR;CAEF,MAAM,EAAE,QAAQ,OAAO,GAAG,aAAa,KAAK;CAE5C,OAAO;AACT"}
@@ -1,14 +1,14 @@
1
- import { brandProviderTool } from "@tanstack/ai";
1
+ import { brandGeminiProviderTool, getGeminiProviderToolMetadata } from "./gemini-provider-tool.js";
2
2
  //#region src/tools/google-maps-tool.ts
3
3
  function convertGoogleMapsToolToAdapterFormat(tool) {
4
- return { googleMaps: tool.metadata };
4
+ return { googleMaps: getGeminiProviderToolMetadata(tool) };
5
5
  }
6
6
  function googleMapsTool(config) {
7
- return brandProviderTool({
7
+ return brandGeminiProviderTool({
8
8
  name: "google_maps",
9
9
  description: "",
10
10
  metadata: config
11
- });
11
+ }, "google_maps");
12
12
  }
13
13
  //#endregion
14
14
  export { convertGoogleMapsToolToAdapterFormat, googleMapsTool };
@@ -1 +1 @@
1
- {"version":3,"file":"google-maps-tool.js","names":[],"sources":["../../../src/tools/google-maps-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { GoogleMaps } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type GoogleMapsToolConfig = GoogleMaps\n\n/** @deprecated Renamed to `GoogleMapsToolConfig`. Will be removed in a future release. */\nexport type GoogleMapsTool = GoogleMapsToolConfig\n\nexport type GeminiGoogleMapsTool = ProviderTool<'gemini', 'google_maps'>\n\nexport function convertGoogleMapsToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as GoogleMapsToolConfig\n return {\n googleMaps: metadata,\n }\n}\n\nexport function googleMapsTool(\n config?: GoogleMapsToolConfig,\n): GeminiGoogleMapsTool {\n return brandProviderTool<GeminiGoogleMapsTool>({\n name: 'google_maps',\n description: '',\n metadata: config,\n })\n}\n"],"mappings":";;AAWA,SAAgB,qCAAqC,MAAY;CAE/D,OAAO,EACL,YAFe,KAAK,SAGtB;AACF;AAEA,SAAgB,eACd,QACsB;CACtB,OAAO,kBAAwC;EAC7C,MAAM;EACN,aAAa;EACb,UAAU;CACZ,CAAC;AACH"}
1
+ {"version":3,"file":"google-maps-tool.js","names":[],"sources":["../../../src/tools/google-maps-tool.ts"],"sourcesContent":["import {\n brandGeminiProviderTool,\n getGeminiProviderToolMetadata,\n} from './gemini-provider-tool'\nimport type { GoogleMaps } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type GoogleMapsToolConfig = GoogleMaps\n\n/** @deprecated Renamed to `GoogleMapsToolConfig`. Will be removed in a future release. */\nexport type GoogleMapsTool = GoogleMapsToolConfig\n\nexport type GeminiGoogleMapsTool = ProviderTool<'gemini', 'google_maps'>\n\nexport function convertGoogleMapsToolToAdapterFormat(tool: Tool) {\n const metadata = getGeminiProviderToolMetadata(tool) as GoogleMapsToolConfig\n return {\n googleMaps: metadata,\n }\n}\n\nexport function googleMapsTool(\n config?: GoogleMapsToolConfig,\n): GeminiGoogleMapsTool {\n return brandGeminiProviderTool<GeminiGoogleMapsTool>(\n {\n name: 'google_maps',\n description: '',\n metadata: config,\n },\n 'google_maps',\n )\n}\n"],"mappings":";;AAcA,SAAgB,qCAAqC,MAAY;CAE/D,OAAO,EACL,YAFe,8BAA8B,IAEjC,EACd;AACF;AAEA,SAAgB,eACd,QACsB;CACtB,OAAO,wBACL;EACE,MAAM;EACN,aAAa;EACb,UAAU;CACZ,GACA,aACF;AACF"}
@@ -1,14 +1,14 @@
1
- import { brandProviderTool } from "@tanstack/ai";
1
+ import { brandGeminiProviderTool, getGeminiProviderToolMetadata } from "./gemini-provider-tool.js";
2
2
  //#region src/tools/google-search-retriveal-tool.ts
3
3
  function convertGoogleSearchRetrievalToolToAdapterFormat(tool) {
4
- return { googleSearchRetrieval: tool.metadata };
4
+ return { googleSearchRetrieval: getGeminiProviderToolMetadata(tool) };
5
5
  }
6
6
  function googleSearchRetrievalTool(config) {
7
- return brandProviderTool({
7
+ return brandGeminiProviderTool({
8
8
  name: "google_search_retrieval",
9
9
  description: "",
10
10
  metadata: config
11
- });
11
+ }, "google_search_retrieval");
12
12
  }
13
13
  //#endregion
14
14
  export { convertGoogleSearchRetrievalToolToAdapterFormat, googleSearchRetrievalTool };
@@ -1 +1 @@
1
- {"version":3,"file":"google-search-retriveal-tool.js","names":[],"sources":["../../../src/tools/google-search-retriveal-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { GoogleSearchRetrieval } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type GoogleSearchRetrievalToolConfig = GoogleSearchRetrieval\n\n/** @deprecated Renamed to `GoogleSearchRetrievalToolConfig`. Will be removed in a future release. */\nexport type GoogleSearchRetrievalTool = GoogleSearchRetrievalToolConfig\n\nexport type GeminiGoogleSearchRetrievalTool = ProviderTool<\n 'gemini',\n 'google_search_retrieval'\n>\n\nexport function convertGoogleSearchRetrievalToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as GoogleSearchRetrievalToolConfig\n return {\n googleSearchRetrieval: metadata,\n }\n}\n\nexport function googleSearchRetrievalTool(\n config?: GoogleSearchRetrievalToolConfig,\n): GeminiGoogleSearchRetrievalTool {\n return brandProviderTool<GeminiGoogleSearchRetrievalTool>({\n name: 'google_search_retrieval',\n description: '',\n metadata: config,\n })\n}\n"],"mappings":";;AAcA,SAAgB,gDAAgD,MAAY;CAE1E,OAAO,EACL,uBAFe,KAAK,SAGtB;AACF;AAEA,SAAgB,0BACd,QACiC;CACjC,OAAO,kBAAmD;EACxD,MAAM;EACN,aAAa;EACb,UAAU;CACZ,CAAC;AACH"}
1
+ {"version":3,"file":"google-search-retriveal-tool.js","names":[],"sources":["../../../src/tools/google-search-retriveal-tool.ts"],"sourcesContent":["import {\n brandGeminiProviderTool,\n getGeminiProviderToolMetadata,\n} from './gemini-provider-tool'\nimport type { GoogleSearchRetrieval } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type GoogleSearchRetrievalToolConfig = GoogleSearchRetrieval\n\n/** @deprecated Renamed to `GoogleSearchRetrievalToolConfig`. Will be removed in a future release. */\nexport type GoogleSearchRetrievalTool = GoogleSearchRetrievalToolConfig\n\nexport type GeminiGoogleSearchRetrievalTool = ProviderTool<\n 'gemini',\n 'google_search_retrieval'\n>\n\nexport function convertGoogleSearchRetrievalToolToAdapterFormat(tool: Tool) {\n const metadata = getGeminiProviderToolMetadata(\n tool,\n ) as GoogleSearchRetrievalToolConfig\n return {\n googleSearchRetrieval: metadata,\n }\n}\n\nexport function googleSearchRetrievalTool(\n config?: GoogleSearchRetrievalToolConfig,\n): GeminiGoogleSearchRetrievalTool {\n return brandGeminiProviderTool<GeminiGoogleSearchRetrievalTool>(\n {\n name: 'google_search_retrieval',\n description: '',\n metadata: config,\n },\n 'google_search_retrieval',\n )\n}\n"],"mappings":";;AAiBA,SAAgB,gDAAgD,MAAY;CAI1E,OAAO,EACL,uBAJe,8BACf,IAGuB,EACzB;AACF;AAEA,SAAgB,0BACd,QACiC;CACjC,OAAO,wBACL;EACE,MAAM;EACN,aAAa;EACb,UAAU;CACZ,GACA,yBACF;AACF"}
@@ -1,14 +1,14 @@
1
- import { brandProviderTool } from "@tanstack/ai";
1
+ import { brandGeminiProviderTool, getGeminiProviderToolMetadata } from "./gemini-provider-tool.js";
2
2
  //#region src/tools/google-search-tool.ts
3
3
  function convertGoogleSearchToolToAdapterFormat(tool) {
4
- return { googleSearch: tool.metadata };
4
+ return { googleSearch: getGeminiProviderToolMetadata(tool) };
5
5
  }
6
6
  function googleSearchTool(config) {
7
- return brandProviderTool({
7
+ return brandGeminiProviderTool({
8
8
  name: "google_search",
9
9
  description: "",
10
10
  metadata: config
11
- });
11
+ }, "google_search");
12
12
  }
13
13
  //#endregion
14
14
  export { convertGoogleSearchToolToAdapterFormat, googleSearchTool };
@@ -1 +1 @@
1
- {"version":3,"file":"google-search-tool.js","names":[],"sources":["../../../src/tools/google-search-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { GoogleSearch } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type GoogleSearchToolConfig = GoogleSearch\n\n/** @deprecated Renamed to `GoogleSearchToolConfig`. Will be removed in a future release. */\nexport type GoogleSearchTool = GoogleSearchToolConfig\n\nexport type GeminiGoogleSearchTool = ProviderTool<'gemini', 'google_search'>\n\nexport function convertGoogleSearchToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as GoogleSearchToolConfig\n return {\n googleSearch: metadata,\n }\n}\n\nexport function googleSearchTool(\n config?: GoogleSearchToolConfig,\n): GeminiGoogleSearchTool {\n return brandProviderTool<GeminiGoogleSearchTool>({\n name: 'google_search',\n description: '',\n metadata: config,\n })\n}\n"],"mappings":";;AAWA,SAAgB,uCAAuC,MAAY;CAEjE,OAAO,EACL,cAFe,KAAK,SAGtB;AACF;AAEA,SAAgB,iBACd,QACwB;CACxB,OAAO,kBAA0C;EAC/C,MAAM;EACN,aAAa;EACb,UAAU;CACZ,CAAC;AACH"}
1
+ {"version":3,"file":"google-search-tool.js","names":[],"sources":["../../../src/tools/google-search-tool.ts"],"sourcesContent":["import {\n brandGeminiProviderTool,\n getGeminiProviderToolMetadata,\n} from './gemini-provider-tool'\nimport type { GoogleSearch } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type GoogleSearchToolConfig = GoogleSearch\n\n/** @deprecated Renamed to `GoogleSearchToolConfig`. Will be removed in a future release. */\nexport type GoogleSearchTool = GoogleSearchToolConfig\n\nexport type GeminiGoogleSearchTool = ProviderTool<'gemini', 'google_search'>\n\nexport function convertGoogleSearchToolToAdapterFormat(tool: Tool) {\n const metadata = getGeminiProviderToolMetadata(tool) as GoogleSearchToolConfig\n return {\n googleSearch: metadata,\n }\n}\n\nexport function googleSearchTool(\n config?: GoogleSearchToolConfig,\n): GeminiGoogleSearchTool {\n return brandGeminiProviderTool<GeminiGoogleSearchTool>(\n {\n name: 'google_search',\n description: '',\n metadata: config,\n },\n 'google_search',\n )\n}\n"],"mappings":";;AAcA,SAAgB,uCAAuC,MAAY;CAEjE,OAAO,EACL,cAFe,8BAA8B,IAE/B,EAChB;AACF;AAEA,SAAgB,iBACd,QACwB;CACxB,OAAO,wBACL;EACE,MAAM;EACN,aAAa;EACb,UAAU;CACZ,GACA,eACF;AACF"}
@@ -1,3 +1,4 @@
1
+ import { getGeminiProviderToolKind } from "./gemini-provider-tool.js";
1
2
  import { convertCodeExecutionToolToAdapterFormat } from "./code-execution-tool.js";
2
3
  import { convertComputerUseToolToAdapterFormat } from "./computer-use-tool.js";
3
4
  import { convertFileSearchToolToAdapterFormat } from "./file-search-tool.js";
@@ -5,6 +6,7 @@ import { convertGoogleMapsToolToAdapterFormat } from "./google-maps-tool.js";
5
6
  import { convertGoogleSearchRetrievalToolToAdapterFormat } from "./google-search-retriveal-tool.js";
6
7
  import { convertGoogleSearchToolToAdapterFormat } from "./google-search-tool.js";
7
8
  import { convertUrlContextToolToAdapterFormat } from "./url-context-tool.js";
9
+ import { assertUniqueToolNames } from "@tanstack/ai/adapter-internals";
8
10
  //#region src/tools/tool-converter.ts
9
11
  /**
10
12
  * Converts standard Tool format to Gemini-specific tool format
@@ -27,9 +29,10 @@ import { convertUrlContextToolToAdapterFormat } from "./url-context-tool.js";
27
29
  */
28
30
  function convertToolsToProviderFormat(tools) {
29
31
  if (!tools || tools.length === 0) return [];
32
+ assertUniqueToolNames(tools);
30
33
  const result = [];
31
34
  const functionDeclarations = [];
32
- for (const tool of tools) switch (tool.name) {
35
+ for (const tool of tools) switch (getGeminiProviderToolKind(tool)) {
33
36
  case "code_execution":
34
37
  result.push(convertCodeExecutionToolToAdapterFormat(tool));
35
38
  break;
@@ -51,7 +54,7 @@ function convertToolsToProviderFormat(tools) {
51
54
  case "url_context":
52
55
  result.push(convertUrlContextToolToAdapterFormat(tool));
53
56
  break;
54
- default:
57
+ case void 0:
55
58
  if (!tool.description) throw new Error(`Tool ${tool.name} requires a description for Gemini adapter`);
56
59
  functionDeclarations.push({
57
60
  name: tool.name,
@@ -1 +1 @@
1
- {"version":3,"file":"tool-converter.js","names":[],"sources":["../../../src/tools/tool-converter.ts"],"sourcesContent":["import { convertCodeExecutionToolToAdapterFormat } from './code-execution-tool'\nimport { convertComputerUseToolToAdapterFormat } from './computer-use-tool'\nimport { convertFileSearchToolToAdapterFormat } from './file-search-tool'\nimport { convertGoogleMapsToolToAdapterFormat } from './google-maps-tool'\nimport { convertGoogleSearchRetrievalToolToAdapterFormat } from './google-search-retriveal-tool'\nimport { convertGoogleSearchToolToAdapterFormat } from './google-search-tool'\nimport { convertUrlContextToolToAdapterFormat } from './url-context-tool'\nimport type { Tool } from '@tanstack/ai'\nimport type { ToolUnion } from '@google/genai'\n\n/**\n * Converts standard Tool format to Gemini-specific tool format\n *\n * @param tools - Array of standard Tool objects\n * @returns Array of Gemini-specific tool definitions\n *\n * @example\n * ```typescript\n * const tools: Tool[] = [{\n * name: \"get_weather\",\n * description: \"Get weather for a location\",\n * inputSchema: z.object({\n * location: z.string()\n * })\n * }];\n *\n * const geminiTools = convertToolsToProviderFormat(tools);\n * ```\n */\nexport function convertToolsToProviderFormat<TTool extends Tool>(\n tools: Array<TTool> | undefined,\n): Array<ToolUnion> {\n if (!tools || tools.length === 0) {\n return []\n }\n const result: Array<ToolUnion> = []\n const functionDeclarations: Array<{\n name: string\n description?: string\n parameters?: any\n }> = []\n\n // Process each tool and group function declarations together\n for (const tool of tools) {\n const name = tool.name\n\n switch (name) {\n case 'code_execution':\n result.push(convertCodeExecutionToolToAdapterFormat(tool))\n break\n case 'computer_use':\n result.push(convertComputerUseToolToAdapterFormat(tool))\n break\n case 'file_search':\n result.push(convertFileSearchToolToAdapterFormat(tool))\n break\n case 'google_maps':\n result.push(convertGoogleMapsToolToAdapterFormat(tool))\n break\n case 'google_search_retrieval':\n result.push(convertGoogleSearchRetrievalToolToAdapterFormat(tool))\n break\n case 'google_search':\n result.push(convertGoogleSearchToolToAdapterFormat(tool))\n break\n case 'url_context':\n result.push(convertUrlContextToolToAdapterFormat(tool))\n break\n default:\n // Collect function declarations to group together\n // Description is required for Gemini function declarations\n if (!tool.description) {\n throw new Error(\n `Tool ${tool.name} requires a description for Gemini adapter`,\n )\n }\n\n // Tool schemas are already converted to JSON Schema in the ai layer\n functionDeclarations.push({\n name: tool.name,\n description: tool.description,\n parameters: tool.inputSchema ?? {\n type: 'object',\n properties: {},\n required: [],\n },\n })\n break\n }\n }\n\n // If we have function declarations, add them as a single tool\n if (functionDeclarations.length > 0) {\n result.push({\n functionDeclarations: functionDeclarations,\n })\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,6BACd,OACkB;CAClB,IAAI,CAAC,SAAS,MAAM,WAAW,GAC7B,OAAO,CAAC;CAEV,MAAM,SAA2B,CAAC;CAClC,MAAM,uBAID,CAAC;CAGN,KAAK,MAAM,QAAQ,OAGjB,QAFa,KAAK,MAElB;EACE,KAAK;GACH,OAAO,KAAK,wCAAwC,IAAI,CAAC;GACzD;EACF,KAAK;GACH,OAAO,KAAK,sCAAsC,IAAI,CAAC;GACvD;EACF,KAAK;GACH,OAAO,KAAK,qCAAqC,IAAI,CAAC;GACtD;EACF,KAAK;GACH,OAAO,KAAK,qCAAqC,IAAI,CAAC;GACtD;EACF,KAAK;GACH,OAAO,KAAK,gDAAgD,IAAI,CAAC;GACjE;EACF,KAAK;GACH,OAAO,KAAK,uCAAuC,IAAI,CAAC;GACxD;EACF,KAAK;GACH,OAAO,KAAK,qCAAqC,IAAI,CAAC;GACtD;EACF;GAGE,IAAI,CAAC,KAAK,aACR,MAAM,IAAI,MACR,QAAQ,KAAK,KAAK,2CACpB;GAIF,qBAAqB,KAAK;IACxB,MAAM,KAAK;IACX,aAAa,KAAK;IAClB,YAAY,KAAK,eAAe;KAC9B,MAAM;KACN,YAAY,CAAC;KACb,UAAU,CAAC;IACb;GACF,CAAC;CAEL;CAIF,IAAI,qBAAqB,SAAS,GAChC,OAAO,KAAK,EACY,qBACxB,CAAC;CAGH,OAAO;AACT"}
1
+ {"version":3,"file":"tool-converter.js","names":[],"sources":["../../../src/tools/tool-converter.ts"],"sourcesContent":["import { assertUniqueToolNames } from '@tanstack/ai/adapter-internals'\nimport { convertCodeExecutionToolToAdapterFormat } from './code-execution-tool'\nimport { convertComputerUseToolToAdapterFormat } from './computer-use-tool'\nimport { convertFileSearchToolToAdapterFormat } from './file-search-tool'\nimport { getGeminiProviderToolKind } from './gemini-provider-tool'\nimport { convertGoogleMapsToolToAdapterFormat } from './google-maps-tool'\nimport { convertGoogleSearchRetrievalToolToAdapterFormat } from './google-search-retriveal-tool'\nimport { convertGoogleSearchToolToAdapterFormat } from './google-search-tool'\nimport { convertUrlContextToolToAdapterFormat } from './url-context-tool'\nimport type { Tool } from '@tanstack/ai'\nimport type { ToolUnion } from '@google/genai'\n\n/**\n * Converts standard Tool format to Gemini-specific tool format\n *\n * @param tools - Array of standard Tool objects\n * @returns Array of Gemini-specific tool definitions\n *\n * @example\n * ```typescript\n * const tools: Tool[] = [{\n * name: \"get_weather\",\n * description: \"Get weather for a location\",\n * inputSchema: z.object({\n * location: z.string()\n * })\n * }];\n *\n * const geminiTools = convertToolsToProviderFormat(tools);\n * ```\n */\nexport function convertToolsToProviderFormat<TTool extends Tool>(\n tools: Array<TTool> | undefined,\n): Array<ToolUnion> {\n if (!tools || tools.length === 0) {\n return []\n }\n assertUniqueToolNames(tools)\n const result: Array<ToolUnion> = []\n const functionDeclarations: Array<{\n name: string\n description?: string\n parameters?: any\n }> = []\n\n // Process each tool and group function declarations together\n for (const tool of tools) {\n switch (getGeminiProviderToolKind(tool)) {\n case 'code_execution':\n result.push(convertCodeExecutionToolToAdapterFormat(tool))\n break\n case 'computer_use':\n result.push(convertComputerUseToolToAdapterFormat(tool))\n break\n case 'file_search':\n result.push(convertFileSearchToolToAdapterFormat(tool))\n break\n case 'google_maps':\n result.push(convertGoogleMapsToolToAdapterFormat(tool))\n break\n case 'google_search_retrieval':\n result.push(convertGoogleSearchRetrievalToolToAdapterFormat(tool))\n break\n case 'google_search':\n result.push(convertGoogleSearchToolToAdapterFormat(tool))\n break\n case 'url_context':\n result.push(convertUrlContextToolToAdapterFormat(tool))\n break\n case undefined:\n // Collect function declarations to group together\n // Description is required for Gemini function declarations\n if (!tool.description) {\n throw new Error(\n `Tool ${tool.name} requires a description for Gemini adapter`,\n )\n }\n\n // Tool schemas are already converted to JSON Schema in the ai layer\n functionDeclarations.push({\n name: tool.name,\n description: tool.description,\n parameters: tool.inputSchema ?? {\n type: 'object',\n properties: {},\n required: [],\n },\n })\n break\n }\n }\n\n // If we have function declarations, add them as a single tool\n if (functionDeclarations.length > 0) {\n result.push({\n functionDeclarations: functionDeclarations,\n })\n }\n\n return result\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,6BACd,OACkB;CAClB,IAAI,CAAC,SAAS,MAAM,WAAW,GAC7B,OAAO,CAAC;CAEV,sBAAsB,KAAK;CAC3B,MAAM,SAA2B,CAAC;CAClC,MAAM,uBAID,CAAC;CAGN,KAAK,MAAM,QAAQ,OACjB,QAAQ,0BAA0B,IAAI,GAAtC;EACE,KAAK;GACH,OAAO,KAAK,wCAAwC,IAAI,CAAC;GACzD;EACF,KAAK;GACH,OAAO,KAAK,sCAAsC,IAAI,CAAC;GACvD;EACF,KAAK;GACH,OAAO,KAAK,qCAAqC,IAAI,CAAC;GACtD;EACF,KAAK;GACH,OAAO,KAAK,qCAAqC,IAAI,CAAC;GACtD;EACF,KAAK;GACH,OAAO,KAAK,gDAAgD,IAAI,CAAC;GACjE;EACF,KAAK;GACH,OAAO,KAAK,uCAAuC,IAAI,CAAC;GACxD;EACF,KAAK;GACH,OAAO,KAAK,qCAAqC,IAAI,CAAC;GACtD;EACF,KAAK,KAAA;GAGH,IAAI,CAAC,KAAK,aACR,MAAM,IAAI,MACR,QAAQ,KAAK,KAAK,2CACpB;GAIF,qBAAqB,KAAK;IACxB,MAAM,KAAK;IACX,aAAa,KAAK;IAClB,YAAY,KAAK,eAAe;KAC9B,MAAM;KACN,YAAY,CAAC;KACb,UAAU,CAAC;IACb;GACF,CAAC;CAEL;CAIF,IAAI,qBAAqB,SAAS,GAChC,OAAO,KAAK,EACY,qBACxB,CAAC;CAGH,OAAO;AACT"}
@@ -1,14 +1,14 @@
1
- import { brandProviderTool } from "@tanstack/ai";
1
+ import { brandGeminiProviderTool } from "./gemini-provider-tool.js";
2
2
  //#region src/tools/url-context-tool.ts
3
3
  function convertUrlContextToolToAdapterFormat(_tool) {
4
4
  return { urlContext: {} };
5
5
  }
6
6
  function urlContextTool() {
7
- return brandProviderTool({
7
+ return brandGeminiProviderTool({
8
8
  name: "url_context",
9
9
  description: "",
10
10
  metadata: {}
11
- });
11
+ }, "url_context");
12
12
  }
13
13
  //#endregion
14
14
  export { convertUrlContextToolToAdapterFormat, urlContextTool };
@@ -1 +1 @@
1
- {"version":3,"file":"url-context-tool.js","names":[],"sources":["../../../src/tools/url-context-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport interface UrlContextToolConfig {}\n\n/** @deprecated Renamed to `UrlContextToolConfig`. Will be removed in a future release. */\nexport type UrlContextTool = UrlContextToolConfig\n\nexport type GeminiUrlContextTool = ProviderTool<'gemini', 'url_context'>\n\nexport function convertUrlContextToolToAdapterFormat(_tool: Tool) {\n return {\n urlContext: {},\n }\n}\n\nexport function urlContextTool(): GeminiUrlContextTool {\n return brandProviderTool<GeminiUrlContextTool>({\n name: 'url_context',\n description: '',\n metadata: {},\n })\n}\n"],"mappings":";;AAUA,SAAgB,qCAAqC,OAAa;CAChE,OAAO,EACL,YAAY,CAAC,EACf;AACF;AAEA,SAAgB,iBAAuC;CACrD,OAAO,kBAAwC;EAC7C,MAAM;EACN,aAAa;EACb,UAAU,CAAC;CACb,CAAC;AACH"}
1
+ {"version":3,"file":"url-context-tool.js","names":[],"sources":["../../../src/tools/url-context-tool.ts"],"sourcesContent":["import { brandGeminiProviderTool } from './gemini-provider-tool'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport interface UrlContextToolConfig {}\n\n/** @deprecated Renamed to `UrlContextToolConfig`. Will be removed in a future release. */\nexport type UrlContextTool = UrlContextToolConfig\n\nexport type GeminiUrlContextTool = ProviderTool<'gemini', 'url_context'>\n\nexport function convertUrlContextToolToAdapterFormat(_tool: Tool) {\n return {\n urlContext: {},\n }\n}\n\nexport function urlContextTool(): GeminiUrlContextTool {\n return brandGeminiProviderTool<GeminiUrlContextTool>(\n {\n name: 'url_context',\n description: '',\n metadata: {},\n },\n 'url_context',\n )\n}\n"],"mappings":";;AAUA,SAAgB,qCAAqC,OAAa;CAChE,OAAO,EACL,YAAY,CAAC,EACf;AACF;AAEA,SAAgB,iBAAuC;CACrD,OAAO,wBACL;EACE,MAAM;EACN,aAAa;EACb,UAAU,CAAC;CACb,GACA,aACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-gemini",
3
- "version": "0.24.0",
3
+ "version": "0.24.1",
4
4
  "description": "Google Gemini adapter for TanStack AI chat, images, speech, audio generation, and structured outputs.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -59,13 +59,13 @@
59
59
  "@tanstack/ai-utils": "^0.4.0"
60
60
  },
61
61
  "peerDependencies": {
62
- "@tanstack/ai": "^0.45.0"
62
+ "@tanstack/ai": "^0.46.0"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@vitest/coverage-v8": "4.1.10",
66
66
  "vite": "^8.2.1",
67
67
  "zod": "^4.2.0",
68
- "@tanstack/ai": "0.45.0"
68
+ "@tanstack/ai": "0.46.0"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "vite build",
@@ -6,6 +6,11 @@ import {
6
6
  generateId,
7
7
  getGeminiApiKeyFromEnv,
8
8
  } from '../../utils/client'
9
+ import {
10
+ getGeminiProviderToolKind,
11
+ getGeminiProviderToolMetadata,
12
+ } from '../../tools/gemini-provider-tool'
13
+ import { assertUniqueToolNames } from '@tanstack/ai/adapter-internals'
9
14
  import type { InternalLogger } from '@tanstack/ai/adapter-internals'
10
15
  import type {
11
16
  GeminiChatModelToolCapabilitiesByName,
@@ -122,9 +127,9 @@ type ResolveInputModalities<TModel extends string> =
122
127
 
123
128
  /**
124
129
  * Resolve tool capabilities for a specific model. Reuses the chat-model
125
- * capability map: `google_maps` / `google_search_retrieval` /
126
- * `mcp_server` are rejected at runtime by `convertToolsToInteractionsFormat`,
127
- * but per-model gating happens here at compile time.
130
+ * capability map: `google_maps` / `google_search_retrieval` are rejected at
131
+ * runtime by `convertToolsToInteractionsFormat`, but per-model gating happens
132
+ * here at compile time.
128
133
  */
129
134
  type ResolveToolCapabilities<TModel extends string> =
130
135
  TModel extends keyof GeminiChatModelToolCapabilitiesByName
@@ -153,8 +158,11 @@ type ResolveToolCapabilities<TModel extends string> =
153
158
  * corresponding per-tool variants) carrying the raw Interactions delta;
154
159
  * see {@link GeminiInteractionsCustomEvent}. `computer_use` is accepted
155
160
  * in the request but the Interactions API does not currently stream
156
- * per-delta CUSTOM events for it. `google_search_retrieval`,
157
- * `google_maps`, and `mcp_server` are not supported on this adapter.
161
+ * per-delta CUSTOM events for it. The `google_search_retrieval` and
162
+ * `google_maps` provider-tool factories are not supported on this adapter and
163
+ * throw a targeted error. There is no Gemini `mcp_server` factory, so a tool
164
+ * merely *named* `mcp_server` is an ordinary function and is sent as a function
165
+ * declaration like any other.
158
166
  *
159
167
  * @experimental Interactions API is in Beta per Google; shapes may change.
160
168
  * @see https://ai.google.dev/gemini-api/docs/interactions
@@ -781,20 +789,29 @@ function convertToolsToInteractionsFormat<TTool extends Tool>(
781
789
  tools: Array<TTool> | undefined,
782
790
  ): Array<InteractionsTool> | undefined {
783
791
  if (!tools || tools.length === 0) return undefined
792
+ assertUniqueToolNames(tools)
784
793
 
785
794
  const result: Array<InteractionsTool> = []
786
795
 
787
796
  for (const tool of tools) {
788
- switch (tool.name) {
797
+ switch (getGeminiProviderToolKind(tool)) {
789
798
  case 'google_search': {
790
- const metadata = (tool.metadata ?? {}) as {
791
- search_types?: Array<'web_search' | 'image_search'>
799
+ const metadata = (getGeminiProviderToolMetadata(tool) ?? {}) as {
800
+ searchTypes?: {
801
+ webSearch?: unknown
802
+ imageSearch?: unknown
803
+ }
804
+ }
805
+ const searchTypes: Array<'web_search' | 'image_search'> = []
806
+ if (metadata.searchTypes?.webSearch !== undefined) {
807
+ searchTypes.push('web_search')
808
+ }
809
+ if (metadata.searchTypes?.imageSearch !== undefined) {
810
+ searchTypes.push('image_search')
792
811
  }
793
812
  result.push({
794
813
  type: 'google_search',
795
- ...(metadata.search_types
796
- ? { search_types: metadata.search_types }
797
- : {}),
814
+ ...(searchTypes.length > 0 ? { search_types: searchTypes } : {}),
798
815
  })
799
816
  break
800
817
  }
@@ -807,7 +824,7 @@ function convertToolsToInteractionsFormat<TTool extends Tool>(
807
824
  break
808
825
  }
809
826
  case 'file_search': {
810
- const metadata = (tool.metadata ?? {}) as {
827
+ const metadata = (getGeminiProviderToolMetadata(tool) ?? {}) as {
811
828
  fileSearchStoreNames?: Array<string>
812
829
  topK?: number
813
830
  metadataFilter?: string
@@ -825,7 +842,7 @@ function convertToolsToInteractionsFormat<TTool extends Tool>(
825
842
  break
826
843
  }
827
844
  case 'computer_use': {
828
- const metadata = (tool.metadata ?? {}) as {
845
+ const metadata = (getGeminiProviderToolMetadata(tool) ?? {}) as {
829
846
  environment?: string
830
847
  excludedPredefinedFunctions?: Array<string>
831
848
  }
@@ -856,11 +873,7 @@ function convertToolsToInteractionsFormat<TTool extends Tool>(
856
873
  throw new Error(
857
874
  '`google_maps` is not yet supported on the Gemini Interactions API. Use `geminiText()` for Google Maps grounding.',
858
875
  )
859
- case 'mcp_server':
860
- throw new Error(
861
- '`mcp_server` is not yet supported on the `geminiTextInteractions()` adapter.',
862
- )
863
- default: {
876
+ case undefined: {
864
877
  if (!tool.description) {
865
878
  throw new Error(
866
879
  `Tool ${tool.name} requires a description for the Gemini Interactions adapter`,
@@ -1,4 +1,4 @@
1
- import { brandProviderTool } from '@tanstack/ai'
1
+ import { brandGeminiProviderTool } from './gemini-provider-tool'
2
2
  import type { ProviderTool, Tool } from '@tanstack/ai'
3
3
 
4
4
  export interface CodeExecutionToolConfig {}
@@ -15,9 +15,12 @@ export function convertCodeExecutionToolToAdapterFormat(_tool: Tool) {
15
15
  }
16
16
 
17
17
  export function codeExecutionTool(): GeminiCodeExecutionTool {
18
- return brandProviderTool<GeminiCodeExecutionTool>({
19
- name: 'code_execution',
20
- description: '',
21
- metadata: {},
22
- })
18
+ return brandGeminiProviderTool<GeminiCodeExecutionTool>(
19
+ {
20
+ name: 'code_execution',
21
+ description: '',
22
+ metadata: {},
23
+ },
24
+ 'code_execution',
25
+ )
23
26
  }
@@ -1,4 +1,7 @@
1
- import { brandProviderTool } from '@tanstack/ai'
1
+ import {
2
+ brandGeminiProviderTool,
3
+ getGeminiProviderToolMetadata,
4
+ } from './gemini-provider-tool'
2
5
  import type { ComputerUse } from '@google/genai'
3
6
  import type { ProviderTool, Tool } from '@tanstack/ai'
4
7
 
@@ -10,7 +13,7 @@ export type ComputerUseTool = ComputerUseToolConfig
10
13
  export type GeminiComputerUseTool = ProviderTool<'gemini', 'computer_use'>
11
14
 
12
15
  export function convertComputerUseToolToAdapterFormat(tool: Tool) {
13
- const metadata = tool.metadata as ComputerUseToolConfig
16
+ const metadata = getGeminiProviderToolMetadata(tool) as ComputerUseToolConfig
14
17
  // Vendor `ComputerUse` fields are `field?: T` (no `| undefined`) under EOPT,
15
18
  // so spread each field conditionally rather than emitting explicit
16
19
  // `undefined`s on the wire payload.
@@ -29,16 +32,19 @@ export function convertComputerUseToolToAdapterFormat(tool: Tool) {
29
32
  export function computerUseTool(
30
33
  config: ComputerUseToolConfig,
31
34
  ): GeminiComputerUseTool {
32
- return brandProviderTool<GeminiComputerUseTool>({
33
- name: 'computer_use',
34
- description: '',
35
- metadata: {
36
- ...(config.environment !== undefined && {
37
- environment: config.environment,
38
- }),
39
- ...(config.excludedPredefinedFunctions !== undefined && {
40
- excludedPredefinedFunctions: config.excludedPredefinedFunctions,
41
- }),
35
+ return brandGeminiProviderTool<GeminiComputerUseTool>(
36
+ {
37
+ name: 'computer_use',
38
+ description: '',
39
+ metadata: {
40
+ ...(config.environment !== undefined && {
41
+ environment: config.environment,
42
+ }),
43
+ ...(config.excludedPredefinedFunctions !== undefined && {
44
+ excludedPredefinedFunctions: config.excludedPredefinedFunctions,
45
+ }),
46
+ },
42
47
  },
43
- })
48
+ 'computer_use',
49
+ )
44
50
  }
@@ -1,4 +1,7 @@
1
- import { brandProviderTool } from '@tanstack/ai'
1
+ import {
2
+ brandGeminiProviderTool,
3
+ getGeminiProviderToolMetadata,
4
+ } from './gemini-provider-tool'
2
5
  import type { FileSearch } from '@google/genai'
3
6
  import type { ProviderTool, Tool } from '@tanstack/ai'
4
7
 
@@ -10,7 +13,7 @@ export type FileSearchTool = FileSearchToolConfig
10
13
  export type GeminiFileSearchTool = ProviderTool<'gemini', 'file_search'>
11
14
 
12
15
  export function convertFileSearchToolToAdapterFormat(tool: Tool) {
13
- const metadata = tool.metadata as FileSearchToolConfig
16
+ const metadata = getGeminiProviderToolMetadata(tool) as FileSearchToolConfig
14
17
  return {
15
18
  fileSearch: metadata,
16
19
  }
@@ -19,9 +22,12 @@ export function convertFileSearchToolToAdapterFormat(tool: Tool) {
19
22
  export function fileSearchTool(
20
23
  config: FileSearchToolConfig,
21
24
  ): GeminiFileSearchTool {
22
- return brandProviderTool<GeminiFileSearchTool>({
23
- name: 'file_search',
24
- description: '',
25
- metadata: config,
26
- })
25
+ return brandGeminiProviderTool<GeminiFileSearchTool>(
26
+ {
27
+ name: 'file_search',
28
+ description: '',
29
+ metadata: config,
30
+ },
31
+ 'file_search',
32
+ )
27
33
  }
@@ -0,0 +1,60 @@
1
+ import { brandProviderTool } from '@tanstack/ai'
2
+ import type { ProviderTool, Tool } from '@tanstack/ai'
3
+
4
+ const GEMINI_PROVIDER_TOOL_KINDS = {
5
+ code_execution: 'gemini.code_execution',
6
+ computer_use: 'gemini.computer_use',
7
+ file_search: 'gemini.file_search',
8
+ google_maps: 'gemini.google_maps',
9
+ google_search: 'gemini.google_search',
10
+ google_search_retrieval: 'gemini.google_search_retrieval',
11
+ url_context: 'gemini.url_context',
12
+ } as const
13
+
14
+ type GeminiProviderToolKind = keyof typeof GEMINI_PROVIDER_TOOL_KINDS
15
+
16
+ export function brandGeminiProviderTool<
17
+ T extends ProviderTool<'gemini', GeminiProviderToolKind>,
18
+ >(tool: Omit<T, '~provider' | '~toolKind'>, toolKind: T['~toolKind']): T {
19
+ return brandProviderTool<T>({
20
+ ...tool,
21
+ metadata: {
22
+ ...tool.metadata,
23
+ __kind: GEMINI_PROVIDER_TOOL_KINDS[toolKind],
24
+ },
25
+ })
26
+ }
27
+
28
+ export function getGeminiProviderToolKind(
29
+ tool: Tool,
30
+ ): GeminiProviderToolKind | undefined {
31
+ const toolKind = tool.metadata?.['__kind']
32
+ switch (toolKind) {
33
+ case 'gemini.code_execution':
34
+ return 'code_execution'
35
+ case 'gemini.computer_use':
36
+ return 'computer_use'
37
+ case 'gemini.file_search':
38
+ return 'file_search'
39
+ case 'gemini.google_maps':
40
+ return 'google_maps'
41
+ case 'gemini.google_search':
42
+ return 'google_search'
43
+ case 'gemini.google_search_retrieval':
44
+ return 'google_search_retrieval'
45
+ case 'gemini.url_context':
46
+ return 'url_context'
47
+ default:
48
+ return undefined
49
+ }
50
+ }
51
+
52
+ /** Returns adapter metadata without the internal runtime discriminator. */
53
+ export function getGeminiProviderToolMetadata(tool: Tool): Tool['metadata'] {
54
+ if (!tool.metadata) {
55
+ return undefined
56
+ }
57
+ const { __kind: _kind, ...metadata } = tool.metadata
58
+ void _kind
59
+ return metadata
60
+ }
@@ -1,4 +1,7 @@
1
- import { brandProviderTool } from '@tanstack/ai'
1
+ import {
2
+ brandGeminiProviderTool,
3
+ getGeminiProviderToolMetadata,
4
+ } from './gemini-provider-tool'
2
5
  import type { GoogleMaps } from '@google/genai'
3
6
  import type { ProviderTool, Tool } from '@tanstack/ai'
4
7
 
@@ -10,7 +13,7 @@ export type GoogleMapsTool = GoogleMapsToolConfig
10
13
  export type GeminiGoogleMapsTool = ProviderTool<'gemini', 'google_maps'>
11
14
 
12
15
  export function convertGoogleMapsToolToAdapterFormat(tool: Tool) {
13
- const metadata = tool.metadata as GoogleMapsToolConfig
16
+ const metadata = getGeminiProviderToolMetadata(tool) as GoogleMapsToolConfig
14
17
  return {
15
18
  googleMaps: metadata,
16
19
  }
@@ -19,9 +22,12 @@ export function convertGoogleMapsToolToAdapterFormat(tool: Tool) {
19
22
  export function googleMapsTool(
20
23
  config?: GoogleMapsToolConfig,
21
24
  ): GeminiGoogleMapsTool {
22
- return brandProviderTool<GeminiGoogleMapsTool>({
23
- name: 'google_maps',
24
- description: '',
25
- metadata: config,
26
- })
25
+ return brandGeminiProviderTool<GeminiGoogleMapsTool>(
26
+ {
27
+ name: 'google_maps',
28
+ description: '',
29
+ metadata: config,
30
+ },
31
+ 'google_maps',
32
+ )
27
33
  }
@@ -1,4 +1,7 @@
1
- import { brandProviderTool } from '@tanstack/ai'
1
+ import {
2
+ brandGeminiProviderTool,
3
+ getGeminiProviderToolMetadata,
4
+ } from './gemini-provider-tool'
2
5
  import type { GoogleSearchRetrieval } from '@google/genai'
3
6
  import type { ProviderTool, Tool } from '@tanstack/ai'
4
7
 
@@ -13,7 +16,9 @@ export type GeminiGoogleSearchRetrievalTool = ProviderTool<
13
16
  >
14
17
 
15
18
  export function convertGoogleSearchRetrievalToolToAdapterFormat(tool: Tool) {
16
- const metadata = tool.metadata as GoogleSearchRetrievalToolConfig
19
+ const metadata = getGeminiProviderToolMetadata(
20
+ tool,
21
+ ) as GoogleSearchRetrievalToolConfig
17
22
  return {
18
23
  googleSearchRetrieval: metadata,
19
24
  }
@@ -22,9 +27,12 @@ export function convertGoogleSearchRetrievalToolToAdapterFormat(tool: Tool) {
22
27
  export function googleSearchRetrievalTool(
23
28
  config?: GoogleSearchRetrievalToolConfig,
24
29
  ): GeminiGoogleSearchRetrievalTool {
25
- return brandProviderTool<GeminiGoogleSearchRetrievalTool>({
26
- name: 'google_search_retrieval',
27
- description: '',
28
- metadata: config,
29
- })
30
+ return brandGeminiProviderTool<GeminiGoogleSearchRetrievalTool>(
31
+ {
32
+ name: 'google_search_retrieval',
33
+ description: '',
34
+ metadata: config,
35
+ },
36
+ 'google_search_retrieval',
37
+ )
30
38
  }