@paean-ai/adk 0.2.25 → 0.2.27

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.
@@ -40,11 +40,13 @@ class Gemini extends BaseLlm {
40
40
  this.headers = headers;
41
41
  this.isGemini3Preview = isGemini3PreviewModel(model);
42
42
  const canReadEnv = typeof process === "object";
43
+ const aiStudioApiKey = canReadEnv ? process.env["AI_STUDIO_API_KEY"] : void 0;
44
+ const useAiStudioMode = !!aiStudioApiKey;
43
45
  this.apiEndpoint = apiEndpoint;
44
46
  if (!this.apiEndpoint && canReadEnv) {
45
47
  this.apiEndpoint = process.env["GEMINI_API_ENDPOINT"];
46
48
  }
47
- if (!this.apiEndpoint && this.isGemini3Preview) {
49
+ if (!this.apiEndpoint && this.isGemini3Preview && !useAiStudioMode) {
48
50
  this.apiEndpoint = GEMINI3_PREVIEW_API_ENDPOINT;
49
51
  logger.info(`Using Gemini 3 preview endpoint: ${this.apiEndpoint}`);
50
52
  }
@@ -55,6 +57,15 @@ class Gemini extends BaseLlm {
55
57
  useVertexAI = vertexAIfromEnv.toLowerCase() === "true" || vertexAIfromEnv === "1";
56
58
  }
57
59
  }
60
+ if (useAiStudioMode) {
61
+ if (useVertexAI) {
62
+ logger.info(
63
+ "AI_STUDIO_API_KEY set \u2014 overriding Vertex AI mode to use AI Studio (generativelanguage.googleapis.com)"
64
+ );
65
+ }
66
+ useVertexAI = false;
67
+ this.apiKey = aiStudioApiKey;
68
+ }
58
69
  if (this.isGemini3Preview && useVertexAI) {
59
70
  const availableApiKey = apiKey || (canReadEnv ? process.env["GOOGLE_GENAI_API_KEY"] || process.env["GEMINI_API_KEY"] : void 0);
60
71
  if (availableApiKey) {
@@ -233,10 +244,10 @@ class Gemini extends BaseLlm {
233
244
  }
234
245
  if (hasFunctionCalls) {
235
246
  if (pendingFCResponse && ((_i = pendingFCResponse.content) == null ? void 0 : _i.parts)) {
236
- const newFCParts = (((_j = llmResponse.content) == null ? void 0 : _j.parts) || []).filter(
237
- (p) => p.functionCall
247
+ const newParts = (((_j = llmResponse.content) == null ? void 0 : _j.parts) || []).filter(
248
+ (p) => p.functionCall || p.thoughtSignature
238
249
  );
239
- pendingFCResponse.content.parts.push(...newFCParts);
250
+ pendingFCResponse.content.parts.push(...newParts);
240
251
  pendingFCResponse.usageMetadata = llmResponse.usageMetadata;
241
252
  } else {
242
253
  pendingFCResponse = llmResponse;
@@ -257,7 +268,14 @@ class Gemini extends BaseLlm {
257
268
  const partsWithSig = pendingFCResponse.content.parts.filter(
258
269
  (p) => p.thoughtSignature
259
270
  ).length;
260
- if (partsWithSig === 0) {
271
+ if (partsWithSig === 0 && thoughtSignature) {
272
+ for (const part of pendingFCResponse.content.parts) {
273
+ if (part.functionCall) {
274
+ part.thoughtSignature = thoughtSignature;
275
+ break;
276
+ }
277
+ }
278
+ } else if (partsWithSig === 0) {
261
279
  logger.warn(
262
280
  `[Gemini3] No thoughtSignature on merged function call parts \u2014 may cause 400 on next request`
263
281
  );
@@ -436,6 +454,7 @@ class Gemini extends BaseLlm {
436
454
  return new GeminiLlmConnection(liveSession);
437
455
  }
438
456
  preprocessRequest(llmRequest) {
457
+ var _a;
439
458
  if (this.apiBackend === GoogleLLMVariant.GEMINI_API) {
440
459
  if (llmRequest.config) {
441
460
  llmRequest.config.labels = void 0;
@@ -449,6 +468,22 @@ class Gemini extends BaseLlm {
449
468
  }
450
469
  }
451
470
  }
471
+ if (((_a = llmRequest.config) == null ? void 0 : _a.tools) && llmRequest.config.tools.length > 1) {
472
+ const hasBuiltInSearch = llmRequest.config.tools.some(
473
+ (t) => "googleSearch" in t || "googleSearchRetrieval" in t
474
+ );
475
+ const hasFunctionDeclarations = llmRequest.config.tools.some(
476
+ (t) => "functionDeclarations" in t
477
+ );
478
+ if (hasBuiltInSearch && hasFunctionDeclarations) {
479
+ logger.warn(
480
+ "Gemini API (AI Studio) does not support combining built-in search tools with custom function declarations. Removing built-in search tool from this request."
481
+ );
482
+ llmRequest.config.tools = llmRequest.config.tools.filter(
483
+ (t) => !("googleSearch" in t) && !("googleSearchRetrieval" in t)
484
+ );
485
+ }
486
+ }
452
487
  }
453
488
  }
454
489
  }
@@ -3,6 +3,7 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import { FinishReason } from "@google/genai";
6
7
  function createLlmResponse(response) {
7
8
  var _a;
8
9
  const usageMetadata = response.usageMetadata;
@@ -16,6 +17,12 @@ function createLlmResponse(response) {
16
17
  finishReason: candidate.finishReason
17
18
  };
18
19
  }
20
+ if (candidate.finishReason === FinishReason.STOP) {
21
+ return {
22
+ usageMetadata,
23
+ finishReason: candidate.finishReason
24
+ };
25
+ }
19
26
  return {
20
27
  errorCode: candidate.finishReason,
21
28
  errorMessage: candidate.finishMessage,
@@ -16,7 +16,7 @@ function getBooleanEnvVar(envVar) {
16
16
  return false;
17
17
  }
18
18
  const envVarValue = (process.env[envVar] || "").toLowerCase();
19
- return ["true", "1"].includes(envVar.toLowerCase());
19
+ return ["true", "1"].includes(envVarValue);
20
20
  }
21
21
  export {
22
22
  GoogleLLMVariant,
@@ -20,6 +20,10 @@ export interface GeminiParams {
20
20
  /**
21
21
  * The API key to use for the Gemini API. If not provided, it will look for
22
22
  * the GOOGLE_GENAI_API_KEY or GEMINI_API_KEY environment variable.
23
+ *
24
+ * Alternatively, set AI_STUDIO_API_KEY env var to force all models
25
+ * (including Gemini 3 preview) through the standard AI Studio endpoint
26
+ * (generativelanguage.googleapis.com) instead of aiplatform.googleapis.com.
23
27
  */
24
28
  apiKey?: string;
25
29
  /**
@@ -371,6 +371,7 @@ function mergeParallelFunctionResponseEvents(functionResponseEvents) {
371
371
  const actionsList = functionResponseEvents.map((event) => event.actions || {});
372
372
  const mergedActions = mergeEventActions(actionsList);
373
373
  return createEvent({
374
+ invocationId: baseEvent.invocationId,
374
375
  author: baseEvent.author,
375
376
  branch: baseEvent.branch,
376
377
  content: { role: "user", parts: mergedParts },
@@ -453,6 +453,9 @@ function runPreProcessor(invocationContext, llmRequest) {
453
453
  }
454
454
  const codeExecutorContext = new CodeExecutorContext(new State(invocationContext.session.state));
455
455
  if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
456
+ logger.warn(
457
+ "[CodeExecutor] Pre-processor skipped: error count exceeded max retry attempts (".concat(codeExecutor.errorRetryAttempts, ") for invocation ").concat(invocationContext.invocationId)
458
+ );
456
459
  return;
457
460
  }
458
461
  const allInputFiles = extractAndReplaceInlineFiles(codeExecutorContext, llmRequest);
@@ -521,6 +524,9 @@ function runPostProcessor(invocationContext, llmResponse) {
521
524
  }
522
525
  const codeExecutorContext = new CodeExecutorContext(new State(invocationContext.session.state));
523
526
  if (codeExecutorContext.getErrorCount(invocationContext.invocationId) >= codeExecutor.errorRetryAttempts) {
527
+ logger.warn(
528
+ "[CodeExecutor] Post-processor skipped: error count exceeded max retry attempts (".concat(codeExecutor.errorRetryAttempts, ") for invocation ").concat(invocationContext.invocationId)
529
+ );
524
530
  return;
525
531
  }
526
532
  const responseContent = llmResponse.content;
@@ -1104,6 +1110,7 @@ const _LlmAgent = class _LlmAgent extends BaseAgent {
1104
1110
  const allEmpty = llmResponse.content.parts.every(
1105
1111
  (p) => {
1106
1112
  if (p.functionCall || p.functionResponse || p.executableCode || p.codeExecutionResult) return false;
1113
+ if (p.inlineData || p.fileData) return false;
1107
1114
  if ("text" in p && typeof p.text === "string" && p.text.length > 0) return false;
1108
1115
  return true;
1109
1116
  }
@@ -24,7 +24,7 @@ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
24
  */
25
25
  import { createEventActions } from "./event_actions.js";
26
26
  function createEvent(params = {}) {
27
- const event = __spreadProps(__spreadValues({}, params), {
27
+ return __spreadProps(__spreadValues({}, params), {
28
28
  id: params.id || createNewEventId(),
29
29
  invocationId: params.invocationId || "",
30
30
  author: params.author,
@@ -33,7 +33,6 @@ function createEvent(params = {}) {
33
33
  branch: params.branch,
34
34
  timestamp: params.timestamp || Date.now()
35
35
  });
36
- return event;
37
36
  }
38
37
  function isFinalResponse(event) {
39
38
  if (event.actions.skipSummarization || event.longRunningToolIds && event.longRunningToolIds.length > 0) {