@ainetwork/adk-provider-model-gemini 0.3.3 → 0.3.5

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.
package/dist/index.cjs CHANGED
@@ -102,7 +102,7 @@ var GeminiModel = class extends import_modules.BaseModel {
102
102
  contents: messages,
103
103
  config: { tools: [{ functionDeclarations: functions }] }
104
104
  });
105
- return await this.createGeminiStreamAdapter(stream);
105
+ return this.createGeminiStreamAdapter(stream);
106
106
  }
107
107
  // NOTE(yoojin): Need to switch API Stream type to LLMStream.
108
108
  createGeminiStreamAdapter(geminiStream) {
@@ -111,29 +111,48 @@ var GeminiModel = class extends import_modules.BaseModel {
111
111
  };
112
112
  return {
113
113
  async *[Symbol.asyncIterator]() {
114
+ let toolCallIndex = 0;
114
115
  for await (const geminiChunk of geminiStream) {
115
- yield {
116
- delta: {
117
- role: geminiChunk.candidates?.[0]?.content?.role,
118
- content: geminiChunk.candidates?.[0]?.content?.parts?.[0]?.text || void 0,
119
- tool_calls: hasName(
120
- geminiChunk.candidates?.[0]?.content?.parts?.[0]?.functionCall || {}
121
- ) ? [
122
- {
123
- index: 0,
124
- id: geminiChunk.candidates?.[0]?.content?.parts?.[0]?.functionCall?.id || "id",
125
- function: {
126
- name: geminiChunk.candidates?.[0]?.content?.parts?.[0]?.functionCall?.name,
127
- arguments: JSON.stringify(geminiChunk.candidates?.[0]?.content?.parts?.[0]?.functionCall?.args)
128
- }
116
+ const content = geminiChunk.candidates?.[0]?.content;
117
+ if (!content) continue;
118
+ const tool_calls = [];
119
+ let textContent = "";
120
+ for (const part of content.parts || []) {
121
+ if (part.text) {
122
+ textContent += part.text;
123
+ } else if (part.functionCall && hasName(part.functionCall)) {
124
+ tool_calls.push({
125
+ index: toolCallIndex++,
126
+ id: part.functionCall.id || `call_${toolCallIndex}`,
127
+ function: {
128
+ name: part.functionCall.name,
129
+ arguments: JSON.stringify(part.functionCall.args)
129
130
  }
130
- ] : void 0
131
- },
132
- finish_reason: geminiChunk.candidates?.[0]?.finishReason,
133
- metadata: {
134
- provider: "gemini"
131
+ });
135
132
  }
136
- };
133
+ }
134
+ if (textContent) {
135
+ yield {
136
+ delta: {
137
+ role: content.role,
138
+ content: textContent,
139
+ tool_calls: void 0
140
+ },
141
+ finish_reason: geminiChunk.candidates?.[0]?.finishReason,
142
+ metadata: { provider: "gemini" }
143
+ };
144
+ }
145
+ if (tool_calls.length > 0) {
146
+ yield {
147
+ delta: {
148
+ role: content.role,
149
+ content: void 0,
150
+ tool_calls
151
+ },
152
+ finish_reason: geminiChunk.candidates?.[0]?.finishReason,
153
+ metadata: { provider: "gemini" }
154
+ };
155
+ }
137
156
  }
138
157
  }
139
158
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import { BaseModel, ModelFetchOptions } from \"@ainetwork/adk/modules\";\nimport { MessageObject, MessageRole, type ThreadObject } from \"@ainetwork/adk/types/memory\";\nimport type {\n\tLLMStream,\n\tStreamChunk,\n} from \"@ainetwork/adk/types/stream\";\nimport type {\n\tFetchResponse,\n\tToolCall,\n\tConnectorTool,\n} from \"@ainetwork/adk/types/connector\";\nimport {\n\ttype Content,\n\ttype FunctionCall,\n\ttype FunctionDeclaration,\n\ttype GenerateContentResponse,\n\tGoogleGenAI,\n\tModel,\n} from \"@google/genai\";\n\nexport class GeminiModel extends BaseModel<Content, FunctionDeclaration> {\n\tprivate client: GoogleGenAI;\n\tprivate modelName: string;\n\n\tconstructor(apiKey: string, modelName: string) {\n\t\tsuper();\n\t\tthis.client = new GoogleGenAI({ apiKey });\n\t\tthis.modelName = modelName;\n\t}\n\n\tprivate getMessageRole(role: MessageRole) {\n\t\tswitch (role) {\n\t\t\tcase MessageRole.USER:\n\t\t\t\treturn \"user\";\n\t\t\tcase MessageRole.MODEL:\n\t\t\tcase MessageRole.SYSTEM:\n\t\t\t\treturn \"model\";\n\t\t\tdefault:\n\t\t\t\treturn \"model\"; /*FIXME*/\n\t\t}\n\t}\n\n\tgenerateMessages(params: {\n\t\tquery: string;\n\t\tthread?: ThreadObject;\n\t\tsystemPrompt?: string;\n\t}): Content[] {\n\t\tconst { query, thread, systemPrompt } = params;\n\t\tconst messages: Content[] = !systemPrompt\n\t\t\t? []\n\t\t\t: [{ role: \"model\", parts: [{ text: systemPrompt.trim() }] }];\n\t\tconst sessionContent: Content[] = !thread\n\t\t\t? []\n\t\t\t: thread.messages.map((message: MessageObject) => {\n\t\t\t\t\t// TODO: check message.content.type\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: this.getMessageRole(message.role),\n\t\t\t\t\t\tparts: [{ text: message.content.parts[0] }],\n\t\t\t\t\t};\n\t\t\t\t});\n\t\tconst userContent: Content = { role: \"user\", parts: [{ text: query }] };\n\t\treturn messages.concat(sessionContent).concat(userContent);\n\t}\n\n\tappendMessages(messages: Content[], message: string): void {\n\t\tmessages.push({\n\t\t\trole: \"user\",\n\t\t\tparts: [{ text: message }],\n\t\t});\n\t}\n\n\tasync fetch(messages: Content[], options?: ModelFetchOptions): Promise<FetchResponse> {\n\t\tconst response = await this.client.models.generateContent({\n\t\t\tmodel: this.modelName,\n\t\t\tcontents: messages,\n\t\t});\n\n\t\treturn { content: response.text };\n\t}\n\n\tasync fetchWithContextMessage(\n\t\tmessages: Content[],\n\t\tfunctions: FunctionDeclaration[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tif (functions.length > 0) {\n\t\t\tconst response = await this.client.models.generateContent({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tcontents: messages,\n\t\t\t\tconfig: {\n\t\t\t\t\ttools: [{ functionDeclarations: functions }],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst { text, functionCalls } = response;\n\t\t\tconst hasName = (\n\t\t\t\tvalue: FunctionCall,\n\t\t\t): value is FunctionCall & { name: string } => {\n\t\t\t\treturn value.name !== undefined;\n\t\t\t};\n\t\t\tconst toolCalls: ToolCall[] | undefined = functionCalls\n\t\t\t\t?.filter(hasName)\n\t\t\t\t.map((value) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: value.name,\n\t\t\t\t\t\targuments: value.args,\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcontent: text,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}\n\t\treturn await this.fetch(messages);\n\t}\n\n\tasync fetchStreamWithContextMessage(\n\t\tmessages: Content[],\n\t\tfunctions: FunctionDeclaration[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<LLMStream> {\n\t\tconst stream = await this.client.models.generateContentStream({\n\t\t\tmodel: this.modelName,\n\t\t\tcontents: messages,\n\t\t\tconfig: { tools: [{ functionDeclarations: functions }] },\n\t\t});\n\n\t\treturn await this.createGeminiStreamAdapter(stream);\n\t}\n\n\t// NOTE(yoojin): Need to switch API Stream type to LLMStream.\n\tprivate createGeminiStreamAdapter(\n\t\tgeminiStream: AsyncIterable<GenerateContentResponse>,\n\t): LLMStream {\n\t\tconst hasName = (\n\t\t\tvalue: FunctionCall,\n\t\t): value is FunctionCall & { name: string } => {\n\t\t\treturn value.name !== undefined;\n\t\t};\n\n\t\treturn {\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\tfor await (const geminiChunk of geminiStream) {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\trole: geminiChunk.candidates?.[0]?.content?.role,\n\t\t\t\t\t\t\tcontent:\n\t\t\t\t\t\t\t\tgeminiChunk.candidates?.[0]?.content?.parts?.[0]?.text ||\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\ttool_calls: hasName(\n\t\t\t\t\t\t\t\tgeminiChunk.candidates?.[0]?.content?.parts?.[0]\n\t\t\t\t\t\t\t\t\t?.functionCall || {},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t? ([\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tindex: 0,\n\t\t\t\t\t\t\t\t\t\t\tid:\n\t\t\t\t\t\t\t\t\t\t\t\tgeminiChunk.candidates?.[0]?.content?.parts?.[0]\n\t\t\t\t\t\t\t\t\t\t\t\t\t?.functionCall?.id || \"id\",\n\t\t\t\t\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\t\t\t\t\tname: geminiChunk.candidates?.[0]?.content?.parts?.[0]\n\t\t\t\t\t\t\t\t\t\t\t\t\t?.functionCall?.name,\n\t\t\t\t\t\t\t\t\t\t\t\targuments:\n JSON.stringify(geminiChunk.candidates?.[0]?.content?.parts?.[0]\n ?.functionCall?.args),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfinish_reason: geminiChunk.candidates?.[0]?.finishReason as any,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tprovider: \"gemini\",\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\tconvertToolsToFunctions(tools: ConnectorTool[]): FunctionDeclaration[] {\n\t\tconst functions: FunctionDeclaration[] = [];\n\t\tfor (const tool of tools) {\n\t\t\tfunctions.push({\n\t\t\t\tname: tool.toolName,\n\t\t\t\tdescription: tool.description,\n\t\t\t\tparametersJsonSchema: tool.inputSchema,\n\t\t\t});\n\t\t}\n\t\treturn functions;\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import { BaseModel, ModelFetchOptions } from \"@ainetwork/adk/modules\";\nimport { MessageObject, MessageRole, type ThreadObject } from \"@ainetwork/adk/types/memory\";\nimport type {\n\tLLMStream,\n\tStreamChunk,\n\tToolCallDelta,\n} from \"@ainetwork/adk/types/stream\";\nimport type {\n\tFetchResponse,\n\tToolCall,\n\tConnectorTool,\n} from \"@ainetwork/adk/types/connector\";\nimport {\n\ttype Content,\n\ttype FunctionCall,\n\ttype FunctionDeclaration,\n\ttype GenerateContentResponse,\n\tGoogleGenAI,\n\tModel,\n} from \"@google/genai\";\n\nexport class GeminiModel extends BaseModel<Content, FunctionDeclaration> {\n\tprivate client: GoogleGenAI;\n\tprivate modelName: string;\n\n\tconstructor(apiKey: string, modelName: string) {\n\t\tsuper();\n\t\tthis.client = new GoogleGenAI({ apiKey });\n\t\tthis.modelName = modelName;\n\t}\n\n\tprivate getMessageRole(role: MessageRole) {\n\t\tswitch (role) {\n\t\t\tcase MessageRole.USER:\n\t\t\t\treturn \"user\";\n\t\t\tcase MessageRole.MODEL:\n\t\t\tcase MessageRole.SYSTEM:\n\t\t\t\treturn \"model\";\n\t\t\tdefault:\n\t\t\t\treturn \"model\"; /*FIXME*/\n\t\t}\n\t}\n\n\tgenerateMessages(params: {\n\t\tquery: string;\n\t\tthread?: ThreadObject;\n\t\tsystemPrompt?: string;\n\t}): Content[] {\n\t\tconst { query, thread, systemPrompt } = params;\n\t\tconst messages: Content[] = !systemPrompt\n\t\t\t? []\n\t\t\t: [{ role: \"model\", parts: [{ text: systemPrompt.trim() }] }];\n\t\tconst sessionContent: Content[] = !thread\n\t\t\t? []\n\t\t\t: thread.messages.map((message: MessageObject) => {\n\t\t\t\t\t// TODO: check message.content.type\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: this.getMessageRole(message.role),\n\t\t\t\t\t\tparts: [{ text: message.content.parts[0] }],\n\t\t\t\t\t};\n\t\t\t\t});\n\t\tconst userContent: Content = { role: \"user\", parts: [{ text: query }] };\n\t\treturn messages.concat(sessionContent).concat(userContent);\n\t}\n\n\tappendMessages(messages: Content[], message: string): void {\n\t\tmessages.push({\n\t\t\trole: \"user\",\n\t\t\tparts: [{ text: message }],\n\t\t});\n\t}\n\n\tasync fetch(messages: Content[], options?: ModelFetchOptions): Promise<FetchResponse> {\n\t\tconst response = await this.client.models.generateContent({\n\t\t\tmodel: this.modelName,\n\t\t\tcontents: messages,\n\t\t});\n\n\t\treturn { content: response.text };\n\t}\n\n\tasync fetchWithContextMessage(\n\t\tmessages: Content[],\n\t\tfunctions: FunctionDeclaration[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tif (functions.length > 0) {\n\t\t\tconst response = await this.client.models.generateContent({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tcontents: messages,\n\t\t\t\tconfig: {\n\t\t\t\t\ttools: [{ functionDeclarations: functions }],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst { text, functionCalls } = response;\n\t\t\tconst hasName = (\n\t\t\t\tvalue: FunctionCall,\n\t\t\t): value is FunctionCall & { name: string } => {\n\t\t\t\treturn value.name !== undefined;\n\t\t\t};\n\t\t\tconst toolCalls: ToolCall[] | undefined = functionCalls\n\t\t\t\t?.filter(hasName)\n\t\t\t\t.map((value) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: value.name,\n\t\t\t\t\t\targuments: value.args,\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcontent: text,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}\n\t\treturn await this.fetch(messages);\n\t}\n\n\tasync fetchStreamWithContextMessage(\n\t\tmessages: Content[],\n\t\tfunctions: FunctionDeclaration[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<LLMStream> {\n\t\tconst stream = await this.client.models.generateContentStream({\n\t\t\tmodel: this.modelName,\n\t\t\tcontents: messages,\n\t\t\tconfig: { tools: [{ functionDeclarations: functions }] },\n\t\t});\n\n\t\treturn this.createGeminiStreamAdapter(stream);\n\t}\n\n\t// NOTE(yoojin): Need to switch API Stream type to LLMStream.\n\tprivate createGeminiStreamAdapter(\n\t\tgeminiStream: AsyncIterable<GenerateContentResponse>,\n\t): LLMStream {\n\t\tconst hasName = (\n\t\t\tvalue: FunctionCall,\n\t\t): value is FunctionCall & { name: string } => {\n\t\t\treturn value.name !== undefined;\n\t\t};\n\n\t\treturn {\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\tlet toolCallIndex = 0;\n\t\t\t\tfor await (const geminiChunk of geminiStream) {\n\t\t\t\t\tconst content = geminiChunk.candidates?.[0]?.content;\n\t\t\t\t\tif (!content) continue;\n\n\t\t\t\t\tconst tool_calls: ToolCallDelta[] = [];\n\t\t\t\t\tlet textContent = \"\";\n\n\t\t\t\t\t// Process all parts in the array\n\t\t\t\t\tfor (const part of content.parts || []) {\n\t\t\t\t\t\tif (part.text) {\n\t\t\t\t\t\t\ttextContent += part.text;\n\t\t\t\t\t\t} else if (part.functionCall && hasName(part.functionCall)) {\n\t\t\t\t\t\t\ttool_calls.push({\n\t\t\t\t\t\t\t\tindex: toolCallIndex++,\n\t\t\t\t\t\t\t\tid: part.functionCall.id || `call_${toolCallIndex}`,\n\t\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\t\tname: part.functionCall.name,\n\t\t\t\t\t\t\t\t\targuments: JSON.stringify(part.functionCall.args),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t} as unknown as ToolCallDelta);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only yield when there's text content\n\t\t\t\t\tif (textContent) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\t\trole: content.role,\n\t\t\t\t\t\t\t\tcontent: textContent,\n\t\t\t\t\t\t\t\ttool_calls: undefined,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfinish_reason: geminiChunk.candidates?.[0]?.finishReason as any,\n\t\t\t\t\t\t\tmetadata: { provider: \"gemini\" },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only yield when there are tool calls\n\t\t\t\t\tif (tool_calls.length > 0) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\t\trole: content.role,\n\t\t\t\t\t\t\t\tcontent: undefined,\n\t\t\t\t\t\t\t\ttool_calls,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfinish_reason: geminiChunk.candidates?.[0]?.finishReason as any,\n\t\t\t\t\t\t\tmetadata: { provider: \"gemini\" },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\tconvertToolsToFunctions(tools: ConnectorTool[]): FunctionDeclaration[] {\n\t\tconst functions: FunctionDeclaration[] = [];\n\t\tfor (const tool of tools) {\n\t\t\tfunctions.push({\n\t\t\t\tname: tool.toolName,\n\t\t\t\tdescription: tool.description,\n\t\t\t\tparametersJsonSchema: tool.inputSchema,\n\t\t\t});\n\t\t}\n\t\treturn functions;\n\t}\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -80,7 +80,7 @@ var GeminiModel = class extends BaseModel {
80
80
  contents: messages,
81
81
  config: { tools: [{ functionDeclarations: functions }] }
82
82
  });
83
- return await this.createGeminiStreamAdapter(stream);
83
+ return this.createGeminiStreamAdapter(stream);
84
84
  }
85
85
  // NOTE(yoojin): Need to switch API Stream type to LLMStream.
86
86
  createGeminiStreamAdapter(geminiStream) {
@@ -89,29 +89,48 @@ var GeminiModel = class extends BaseModel {
89
89
  };
90
90
  return {
91
91
  async *[Symbol.asyncIterator]() {
92
+ let toolCallIndex = 0;
92
93
  for await (const geminiChunk of geminiStream) {
93
- yield {
94
- delta: {
95
- role: geminiChunk.candidates?.[0]?.content?.role,
96
- content: geminiChunk.candidates?.[0]?.content?.parts?.[0]?.text || void 0,
97
- tool_calls: hasName(
98
- geminiChunk.candidates?.[0]?.content?.parts?.[0]?.functionCall || {}
99
- ) ? [
100
- {
101
- index: 0,
102
- id: geminiChunk.candidates?.[0]?.content?.parts?.[0]?.functionCall?.id || "id",
103
- function: {
104
- name: geminiChunk.candidates?.[0]?.content?.parts?.[0]?.functionCall?.name,
105
- arguments: JSON.stringify(geminiChunk.candidates?.[0]?.content?.parts?.[0]?.functionCall?.args)
106
- }
94
+ const content = geminiChunk.candidates?.[0]?.content;
95
+ if (!content) continue;
96
+ const tool_calls = [];
97
+ let textContent = "";
98
+ for (const part of content.parts || []) {
99
+ if (part.text) {
100
+ textContent += part.text;
101
+ } else if (part.functionCall && hasName(part.functionCall)) {
102
+ tool_calls.push({
103
+ index: toolCallIndex++,
104
+ id: part.functionCall.id || `call_${toolCallIndex}`,
105
+ function: {
106
+ name: part.functionCall.name,
107
+ arguments: JSON.stringify(part.functionCall.args)
107
108
  }
108
- ] : void 0
109
- },
110
- finish_reason: geminiChunk.candidates?.[0]?.finishReason,
111
- metadata: {
112
- provider: "gemini"
109
+ });
113
110
  }
114
- };
111
+ }
112
+ if (textContent) {
113
+ yield {
114
+ delta: {
115
+ role: content.role,
116
+ content: textContent,
117
+ tool_calls: void 0
118
+ },
119
+ finish_reason: geminiChunk.candidates?.[0]?.finishReason,
120
+ metadata: { provider: "gemini" }
121
+ };
122
+ }
123
+ if (tool_calls.length > 0) {
124
+ yield {
125
+ delta: {
126
+ role: content.role,
127
+ content: void 0,
128
+ tool_calls
129
+ },
130
+ finish_reason: geminiChunk.candidates?.[0]?.finishReason,
131
+ metadata: { provider: "gemini" }
132
+ };
133
+ }
115
134
  }
116
135
  }
117
136
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts"],"sourcesContent":["import { BaseModel, ModelFetchOptions } from \"@ainetwork/adk/modules\";\nimport { MessageObject, MessageRole, type ThreadObject } from \"@ainetwork/adk/types/memory\";\nimport type {\n\tLLMStream,\n\tStreamChunk,\n} from \"@ainetwork/adk/types/stream\";\nimport type {\n\tFetchResponse,\n\tToolCall,\n\tConnectorTool,\n} from \"@ainetwork/adk/types/connector\";\nimport {\n\ttype Content,\n\ttype FunctionCall,\n\ttype FunctionDeclaration,\n\ttype GenerateContentResponse,\n\tGoogleGenAI,\n\tModel,\n} from \"@google/genai\";\n\nexport class GeminiModel extends BaseModel<Content, FunctionDeclaration> {\n\tprivate client: GoogleGenAI;\n\tprivate modelName: string;\n\n\tconstructor(apiKey: string, modelName: string) {\n\t\tsuper();\n\t\tthis.client = new GoogleGenAI({ apiKey });\n\t\tthis.modelName = modelName;\n\t}\n\n\tprivate getMessageRole(role: MessageRole) {\n\t\tswitch (role) {\n\t\t\tcase MessageRole.USER:\n\t\t\t\treturn \"user\";\n\t\t\tcase MessageRole.MODEL:\n\t\t\tcase MessageRole.SYSTEM:\n\t\t\t\treturn \"model\";\n\t\t\tdefault:\n\t\t\t\treturn \"model\"; /*FIXME*/\n\t\t}\n\t}\n\n\tgenerateMessages(params: {\n\t\tquery: string;\n\t\tthread?: ThreadObject;\n\t\tsystemPrompt?: string;\n\t}): Content[] {\n\t\tconst { query, thread, systemPrompt } = params;\n\t\tconst messages: Content[] = !systemPrompt\n\t\t\t? []\n\t\t\t: [{ role: \"model\", parts: [{ text: systemPrompt.trim() }] }];\n\t\tconst sessionContent: Content[] = !thread\n\t\t\t? []\n\t\t\t: thread.messages.map((message: MessageObject) => {\n\t\t\t\t\t// TODO: check message.content.type\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: this.getMessageRole(message.role),\n\t\t\t\t\t\tparts: [{ text: message.content.parts[0] }],\n\t\t\t\t\t};\n\t\t\t\t});\n\t\tconst userContent: Content = { role: \"user\", parts: [{ text: query }] };\n\t\treturn messages.concat(sessionContent).concat(userContent);\n\t}\n\n\tappendMessages(messages: Content[], message: string): void {\n\t\tmessages.push({\n\t\t\trole: \"user\",\n\t\t\tparts: [{ text: message }],\n\t\t});\n\t}\n\n\tasync fetch(messages: Content[], options?: ModelFetchOptions): Promise<FetchResponse> {\n\t\tconst response = await this.client.models.generateContent({\n\t\t\tmodel: this.modelName,\n\t\t\tcontents: messages,\n\t\t});\n\n\t\treturn { content: response.text };\n\t}\n\n\tasync fetchWithContextMessage(\n\t\tmessages: Content[],\n\t\tfunctions: FunctionDeclaration[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tif (functions.length > 0) {\n\t\t\tconst response = await this.client.models.generateContent({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tcontents: messages,\n\t\t\t\tconfig: {\n\t\t\t\t\ttools: [{ functionDeclarations: functions }],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst { text, functionCalls } = response;\n\t\t\tconst hasName = (\n\t\t\t\tvalue: FunctionCall,\n\t\t\t): value is FunctionCall & { name: string } => {\n\t\t\t\treturn value.name !== undefined;\n\t\t\t};\n\t\t\tconst toolCalls: ToolCall[] | undefined = functionCalls\n\t\t\t\t?.filter(hasName)\n\t\t\t\t.map((value) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: value.name,\n\t\t\t\t\t\targuments: value.args,\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcontent: text,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}\n\t\treturn await this.fetch(messages);\n\t}\n\n\tasync fetchStreamWithContextMessage(\n\t\tmessages: Content[],\n\t\tfunctions: FunctionDeclaration[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<LLMStream> {\n\t\tconst stream = await this.client.models.generateContentStream({\n\t\t\tmodel: this.modelName,\n\t\t\tcontents: messages,\n\t\t\tconfig: { tools: [{ functionDeclarations: functions }] },\n\t\t});\n\n\t\treturn await this.createGeminiStreamAdapter(stream);\n\t}\n\n\t// NOTE(yoojin): Need to switch API Stream type to LLMStream.\n\tprivate createGeminiStreamAdapter(\n\t\tgeminiStream: AsyncIterable<GenerateContentResponse>,\n\t): LLMStream {\n\t\tconst hasName = (\n\t\t\tvalue: FunctionCall,\n\t\t): value is FunctionCall & { name: string } => {\n\t\t\treturn value.name !== undefined;\n\t\t};\n\n\t\treturn {\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\tfor await (const geminiChunk of geminiStream) {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\trole: geminiChunk.candidates?.[0]?.content?.role,\n\t\t\t\t\t\t\tcontent:\n\t\t\t\t\t\t\t\tgeminiChunk.candidates?.[0]?.content?.parts?.[0]?.text ||\n\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\ttool_calls: hasName(\n\t\t\t\t\t\t\t\tgeminiChunk.candidates?.[0]?.content?.parts?.[0]\n\t\t\t\t\t\t\t\t\t?.functionCall || {},\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t? ([\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tindex: 0,\n\t\t\t\t\t\t\t\t\t\t\tid:\n\t\t\t\t\t\t\t\t\t\t\t\tgeminiChunk.candidates?.[0]?.content?.parts?.[0]\n\t\t\t\t\t\t\t\t\t\t\t\t\t?.functionCall?.id || \"id\",\n\t\t\t\t\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\t\t\t\t\tname: geminiChunk.candidates?.[0]?.content?.parts?.[0]\n\t\t\t\t\t\t\t\t\t\t\t\t\t?.functionCall?.name,\n\t\t\t\t\t\t\t\t\t\t\t\targuments:\n JSON.stringify(geminiChunk.candidates?.[0]?.content?.parts?.[0]\n ?.functionCall?.args),\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t])\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfinish_reason: geminiChunk.candidates?.[0]?.finishReason as any,\n\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\tprovider: \"gemini\",\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\tconvertToolsToFunctions(tools: ConnectorTool[]): FunctionDeclaration[] {\n\t\tconst functions: FunctionDeclaration[] = [];\n\t\tfor (const tool of tools) {\n\t\t\tfunctions.push({\n\t\t\t\tname: tool.toolName,\n\t\t\t\tdescription: tool.description,\n\t\t\t\tparametersJsonSchema: tool.inputSchema,\n\t\t\t});\n\t\t}\n\t\treturn functions;\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../index.ts"],"sourcesContent":["import { BaseModel, ModelFetchOptions } from \"@ainetwork/adk/modules\";\nimport { MessageObject, MessageRole, type ThreadObject } from \"@ainetwork/adk/types/memory\";\nimport type {\n\tLLMStream,\n\tStreamChunk,\n\tToolCallDelta,\n} from \"@ainetwork/adk/types/stream\";\nimport type {\n\tFetchResponse,\n\tToolCall,\n\tConnectorTool,\n} from \"@ainetwork/adk/types/connector\";\nimport {\n\ttype Content,\n\ttype FunctionCall,\n\ttype FunctionDeclaration,\n\ttype GenerateContentResponse,\n\tGoogleGenAI,\n\tModel,\n} from \"@google/genai\";\n\nexport class GeminiModel extends BaseModel<Content, FunctionDeclaration> {\n\tprivate client: GoogleGenAI;\n\tprivate modelName: string;\n\n\tconstructor(apiKey: string, modelName: string) {\n\t\tsuper();\n\t\tthis.client = new GoogleGenAI({ apiKey });\n\t\tthis.modelName = modelName;\n\t}\n\n\tprivate getMessageRole(role: MessageRole) {\n\t\tswitch (role) {\n\t\t\tcase MessageRole.USER:\n\t\t\t\treturn \"user\";\n\t\t\tcase MessageRole.MODEL:\n\t\t\tcase MessageRole.SYSTEM:\n\t\t\t\treturn \"model\";\n\t\t\tdefault:\n\t\t\t\treturn \"model\"; /*FIXME*/\n\t\t}\n\t}\n\n\tgenerateMessages(params: {\n\t\tquery: string;\n\t\tthread?: ThreadObject;\n\t\tsystemPrompt?: string;\n\t}): Content[] {\n\t\tconst { query, thread, systemPrompt } = params;\n\t\tconst messages: Content[] = !systemPrompt\n\t\t\t? []\n\t\t\t: [{ role: \"model\", parts: [{ text: systemPrompt.trim() }] }];\n\t\tconst sessionContent: Content[] = !thread\n\t\t\t? []\n\t\t\t: thread.messages.map((message: MessageObject) => {\n\t\t\t\t\t// TODO: check message.content.type\n\t\t\t\t\treturn {\n\t\t\t\t\t\trole: this.getMessageRole(message.role),\n\t\t\t\t\t\tparts: [{ text: message.content.parts[0] }],\n\t\t\t\t\t};\n\t\t\t\t});\n\t\tconst userContent: Content = { role: \"user\", parts: [{ text: query }] };\n\t\treturn messages.concat(sessionContent).concat(userContent);\n\t}\n\n\tappendMessages(messages: Content[], message: string): void {\n\t\tmessages.push({\n\t\t\trole: \"user\",\n\t\t\tparts: [{ text: message }],\n\t\t});\n\t}\n\n\tasync fetch(messages: Content[], options?: ModelFetchOptions): Promise<FetchResponse> {\n\t\tconst response = await this.client.models.generateContent({\n\t\t\tmodel: this.modelName,\n\t\t\tcontents: messages,\n\t\t});\n\n\t\treturn { content: response.text };\n\t}\n\n\tasync fetchWithContextMessage(\n\t\tmessages: Content[],\n\t\tfunctions: FunctionDeclaration[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<FetchResponse> {\n\t\tif (functions.length > 0) {\n\t\t\tconst response = await this.client.models.generateContent({\n\t\t\t\tmodel: this.modelName,\n\t\t\t\tcontents: messages,\n\t\t\t\tconfig: {\n\t\t\t\t\ttools: [{ functionDeclarations: functions }],\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst { text, functionCalls } = response;\n\t\t\tconst hasName = (\n\t\t\t\tvalue: FunctionCall,\n\t\t\t): value is FunctionCall & { name: string } => {\n\t\t\t\treturn value.name !== undefined;\n\t\t\t};\n\t\t\tconst toolCalls: ToolCall[] | undefined = functionCalls\n\t\t\t\t?.filter(hasName)\n\t\t\t\t.map((value) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: value.name,\n\t\t\t\t\t\targuments: value.args,\n\t\t\t\t\t};\n\t\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcontent: text,\n\t\t\t\ttoolCalls,\n\t\t\t};\n\t\t}\n\t\treturn await this.fetch(messages);\n\t}\n\n\tasync fetchStreamWithContextMessage(\n\t\tmessages: Content[],\n\t\tfunctions: FunctionDeclaration[],\n\t\toptions?: ModelFetchOptions,\n\t): Promise<LLMStream> {\n\t\tconst stream = await this.client.models.generateContentStream({\n\t\t\tmodel: this.modelName,\n\t\t\tcontents: messages,\n\t\t\tconfig: { tools: [{ functionDeclarations: functions }] },\n\t\t});\n\n\t\treturn this.createGeminiStreamAdapter(stream);\n\t}\n\n\t// NOTE(yoojin): Need to switch API Stream type to LLMStream.\n\tprivate createGeminiStreamAdapter(\n\t\tgeminiStream: AsyncIterable<GenerateContentResponse>,\n\t): LLMStream {\n\t\tconst hasName = (\n\t\t\tvalue: FunctionCall,\n\t\t): value is FunctionCall & { name: string } => {\n\t\t\treturn value.name !== undefined;\n\t\t};\n\n\t\treturn {\n\t\t\tasync *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {\n\t\t\t\tlet toolCallIndex = 0;\n\t\t\t\tfor await (const geminiChunk of geminiStream) {\n\t\t\t\t\tconst content = geminiChunk.candidates?.[0]?.content;\n\t\t\t\t\tif (!content) continue;\n\n\t\t\t\t\tconst tool_calls: ToolCallDelta[] = [];\n\t\t\t\t\tlet textContent = \"\";\n\n\t\t\t\t\t// Process all parts in the array\n\t\t\t\t\tfor (const part of content.parts || []) {\n\t\t\t\t\t\tif (part.text) {\n\t\t\t\t\t\t\ttextContent += part.text;\n\t\t\t\t\t\t} else if (part.functionCall && hasName(part.functionCall)) {\n\t\t\t\t\t\t\ttool_calls.push({\n\t\t\t\t\t\t\t\tindex: toolCallIndex++,\n\t\t\t\t\t\t\t\tid: part.functionCall.id || `call_${toolCallIndex}`,\n\t\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\t\tname: part.functionCall.name,\n\t\t\t\t\t\t\t\t\targuments: JSON.stringify(part.functionCall.args),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t} as unknown as ToolCallDelta);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only yield when there's text content\n\t\t\t\t\tif (textContent) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\t\trole: content.role,\n\t\t\t\t\t\t\t\tcontent: textContent,\n\t\t\t\t\t\t\t\ttool_calls: undefined,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfinish_reason: geminiChunk.candidates?.[0]?.finishReason as any,\n\t\t\t\t\t\t\tmetadata: { provider: \"gemini\" },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only yield when there are tool calls\n\t\t\t\t\tif (tool_calls.length > 0) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tdelta: {\n\t\t\t\t\t\t\t\trole: content.role,\n\t\t\t\t\t\t\t\tcontent: undefined,\n\t\t\t\t\t\t\t\ttool_calls,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tfinish_reason: geminiChunk.candidates?.[0]?.finishReason as any,\n\t\t\t\t\t\t\tmetadata: { provider: \"gemini\" },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n\n\tconvertToolsToFunctions(tools: ConnectorTool[]): FunctionDeclaration[] {\n\t\tconst functions: FunctionDeclaration[] = [];\n\t\tfor (const tool of tools) {\n\t\t\tfunctions.push({\n\t\t\t\tname: tool.toolName,\n\t\t\t\tdescription: tool.description,\n\t\t\t\tparametersJsonSchema: tool.inputSchema,\n\t\t\t});\n\t\t}\n\t\treturn functions;\n\t}\n}\n"],"mappings":"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","names":[]}
package/index.ts CHANGED
@@ -3,6 +3,7 @@ import { MessageObject, MessageRole, type ThreadObject } from "@ainetwork/adk/ty
3
3
  import type {
4
4
  LLMStream,
5
5
  StreamChunk,
6
+ ToolCallDelta,
6
7
  } from "@ainetwork/adk/types/stream";
7
8
  import type {
8
9
  FetchResponse,
@@ -126,7 +127,7 @@ export class GeminiModel extends BaseModel<Content, FunctionDeclaration> {
126
127
  config: { tools: [{ functionDeclarations: functions }] },
127
128
  });
128
129
 
129
- return await this.createGeminiStreamAdapter(stream);
130
+ return this.createGeminiStreamAdapter(stream);
130
131
  }
131
132
 
132
133
  // NOTE(yoojin): Need to switch API Stream type to LLMStream.
@@ -141,39 +142,55 @@ export class GeminiModel extends BaseModel<Content, FunctionDeclaration> {
141
142
 
142
143
  return {
143
144
  async *[Symbol.asyncIterator](): AsyncIterator<StreamChunk> {
145
+ let toolCallIndex = 0;
144
146
  for await (const geminiChunk of geminiStream) {
145
- yield {
146
- delta: {
147
- role: geminiChunk.candidates?.[0]?.content?.role,
148
- content:
149
- geminiChunk.candidates?.[0]?.content?.parts?.[0]?.text ||
150
- undefined,
151
- tool_calls: hasName(
152
- geminiChunk.candidates?.[0]?.content?.parts?.[0]
153
- ?.functionCall || {},
154
- )
155
- ? ([
156
- {
157
- index: 0,
158
- id:
159
- geminiChunk.candidates?.[0]?.content?.parts?.[0]
160
- ?.functionCall?.id || "id",
161
- function: {
162
- name: geminiChunk.candidates?.[0]?.content?.parts?.[0]
163
- ?.functionCall?.name,
164
- arguments:
165
- JSON.stringify(geminiChunk.candidates?.[0]?.content?.parts?.[0]
166
- ?.functionCall?.args),
167
- },
168
- },
169
- ])
170
- : undefined,
171
- },
172
- finish_reason: geminiChunk.candidates?.[0]?.finishReason as any,
173
- metadata: {
174
- provider: "gemini",
175
- },
176
- };
147
+ const content = geminiChunk.candidates?.[0]?.content;
148
+ if (!content) continue;
149
+
150
+ const tool_calls: ToolCallDelta[] = [];
151
+ let textContent = "";
152
+
153
+ // Process all parts in the array
154
+ for (const part of content.parts || []) {
155
+ if (part.text) {
156
+ textContent += part.text;
157
+ } else if (part.functionCall && hasName(part.functionCall)) {
158
+ tool_calls.push({
159
+ index: toolCallIndex++,
160
+ id: part.functionCall.id || `call_${toolCallIndex}`,
161
+ function: {
162
+ name: part.functionCall.name,
163
+ arguments: JSON.stringify(part.functionCall.args),
164
+ },
165
+ } as unknown as ToolCallDelta);
166
+ }
167
+ }
168
+
169
+ // Only yield when there's text content
170
+ if (textContent) {
171
+ yield {
172
+ delta: {
173
+ role: content.role,
174
+ content: textContent,
175
+ tool_calls: undefined,
176
+ },
177
+ finish_reason: geminiChunk.candidates?.[0]?.finishReason as any,
178
+ metadata: { provider: "gemini" },
179
+ };
180
+ }
181
+
182
+ // Only yield when there are tool calls
183
+ if (tool_calls.length > 0) {
184
+ yield {
185
+ delta: {
186
+ role: content.role,
187
+ content: undefined,
188
+ tool_calls,
189
+ },
190
+ finish_reason: geminiChunk.candidates?.[0]?.finishReason as any,
191
+ metadata: { provider: "gemini" },
192
+ };
193
+ }
177
194
  }
178
195
  },
179
196
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainetwork/adk-provider-model-gemini",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "author": "AI Network (https://ainetwork.ai)",
5
5
  "type": "module",
6
6
  "engines": {
@@ -21,7 +21,7 @@
21
21
  "clean": "rm -rf dist"
22
22
  },
23
23
  "dependencies": {
24
- "@ainetwork/adk": "^0.3.3",
24
+ "@ainetwork/adk": "^0.3.5",
25
25
  "@google/genai": "^1.11.0"
26
26
  },
27
27
  "devDependencies": {
@@ -31,5 +31,5 @@
31
31
  "publishConfig": {
32
32
  "access": "public"
33
33
  },
34
- "gitHead": "e46af4210c3dc6ea073797d4ba465a24651c8ca2"
34
+ "gitHead": "0361ececa3c7404035d1b67c4830f52fa904d3d8"
35
35
  }