@google/gemini-cli-a2a-server 0.47.0-nightly.20260609.g0567b25a2 → 0.47.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.
- package/dist/a2a-server.mjs +325 -219
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/dist/a2a-server.mjs
CHANGED
|
@@ -130526,7 +130526,7 @@ function supportsMultimodalFunctionResponse(model, config3) {
|
|
|
130526
130526
|
}
|
|
130527
130527
|
return model.startsWith("gemini-3-");
|
|
130528
130528
|
}
|
|
130529
|
-
var PREVIEW_GEMINI_MODEL, PREVIEW_GEMINI_3_1_MODEL, PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, PREVIEW_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_3_5_FLASH_MODEL, SECONDARY_GEMINI_3_5_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, PREVIEW_GEMINI_FLASH_LITE_MODEL, GEMMA_4_31B_IT_MODEL, GEMMA_4_26B_A4B_IT_MODEL, PREVIEW_GEMINI_MODEL_AUTO, DEFAULT_GEMINI_MODEL_AUTO, GEMINI_MODEL_ALIAS_AUTO, GEMINI_MODEL_ALIAS_PRO, GEMINI_MODEL_ALIAS_FLASH, GEMINI_MODEL_ALIAS_FLASH_LITE, DEFAULT_GEMINI_EMBEDDING_MODEL, DEFAULT_THINKING_MODE;
|
|
130529
|
+
var PREVIEW_GEMINI_MODEL, PREVIEW_GEMINI_3_1_MODEL, PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, PREVIEW_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_3_5_FLASH_MODEL, SECONDARY_GEMINI_3_5_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, PREVIEW_GEMINI_FLASH_LITE_MODEL, GEMMA_4_31B_IT_MODEL, GEMMA_4_26B_A4B_IT_MODEL, PREVIEW_GEMINI_MODEL_AUTO, DEFAULT_GEMINI_MODEL_AUTO, GEMINI_MODEL_ALIAS_AUTO, GEMINI_MODEL_ALIAS_PRO, GEMINI_MODEL_ALIAS_FLASH, GEMINI_MODEL_ALIAS_FLASH_LITE, DEFAULT_GEMINI_EMBEDDING_MODEL, DEFAULT_THINKING_MODE, CCPA_AI_MODEL_MAPPINGS;
|
|
130530
130530
|
var init_models = __esm({
|
|
130531
130531
|
"packages/core/dist/src/config/models.js"() {
|
|
130532
130532
|
"use strict";
|
|
@@ -130550,6 +130550,9 @@ var init_models = __esm({
|
|
|
130550
130550
|
GEMINI_MODEL_ALIAS_FLASH_LITE = "flash-lite";
|
|
130551
130551
|
DEFAULT_GEMINI_EMBEDDING_MODEL = "gemini-embedding-001";
|
|
130552
130552
|
DEFAULT_THINKING_MODE = 8192;
|
|
130553
|
+
CCPA_AI_MODEL_MAPPINGS = {
|
|
130554
|
+
[DEFAULT_GEMINI_3_5_FLASH_MODEL]: SECONDARY_GEMINI_3_5_FLASH_MODEL
|
|
130555
|
+
};
|
|
130553
130556
|
}
|
|
130554
130557
|
});
|
|
130555
130558
|
|
|
@@ -211657,8 +211660,8 @@ var GIT_COMMIT_INFO, CLI_VERSION;
|
|
|
211657
211660
|
var init_git_commit = __esm({
|
|
211658
211661
|
"packages/core/dist/src/generated/git-commit.js"() {
|
|
211659
211662
|
"use strict";
|
|
211660
|
-
GIT_COMMIT_INFO = "
|
|
211661
|
-
CLI_VERSION = "0.47.0
|
|
211663
|
+
GIT_COMMIT_INFO = "74c6d8e02";
|
|
211664
|
+
CLI_VERSION = "0.47.0";
|
|
211662
211665
|
}
|
|
211663
211666
|
});
|
|
211664
211667
|
|
|
@@ -282475,6 +282478,203 @@ var init_sessionOperations = __esm({
|
|
|
282475
282478
|
}
|
|
282476
282479
|
});
|
|
282477
282480
|
|
|
282481
|
+
// packages/core/dist/src/utils/partUtils.js
|
|
282482
|
+
function partToString(value, options) {
|
|
282483
|
+
if (!value) {
|
|
282484
|
+
return "";
|
|
282485
|
+
}
|
|
282486
|
+
if (typeof value === "string") {
|
|
282487
|
+
return value;
|
|
282488
|
+
}
|
|
282489
|
+
if (Array.isArray(value)) {
|
|
282490
|
+
return value.map((part2) => partToString(part2, options)).join("");
|
|
282491
|
+
}
|
|
282492
|
+
const part = value;
|
|
282493
|
+
if (options?.verbose) {
|
|
282494
|
+
if (part.videoMetadata !== void 0) {
|
|
282495
|
+
return `[Video Metadata]`;
|
|
282496
|
+
}
|
|
282497
|
+
if (part.thought !== void 0) {
|
|
282498
|
+
return `[Thought: ${part.thought}]`;
|
|
282499
|
+
}
|
|
282500
|
+
if (part.codeExecutionResult !== void 0) {
|
|
282501
|
+
return `[Code Execution Result]`;
|
|
282502
|
+
}
|
|
282503
|
+
if (part.executableCode !== void 0) {
|
|
282504
|
+
return `[Executable Code]`;
|
|
282505
|
+
}
|
|
282506
|
+
if (part.fileData !== void 0) {
|
|
282507
|
+
return `[File Data]`;
|
|
282508
|
+
}
|
|
282509
|
+
if (part.functionCall !== void 0) {
|
|
282510
|
+
return `[Function Call: ${part.functionCall.name}]`;
|
|
282511
|
+
}
|
|
282512
|
+
if (part.functionResponse !== void 0) {
|
|
282513
|
+
return `[Function Response: ${part.functionResponse.name}]`;
|
|
282514
|
+
}
|
|
282515
|
+
if (part.inlineData !== void 0) {
|
|
282516
|
+
const mimeType = part.inlineData.mimeType ?? "unknown";
|
|
282517
|
+
const data = part.inlineData.data ?? "";
|
|
282518
|
+
const bytes = Math.ceil(data.length * 3 / 4);
|
|
282519
|
+
const kb = (bytes / 1024).toFixed(1);
|
|
282520
|
+
const category = mimeType.startsWith("audio/") ? "Audio" : mimeType.startsWith("video/") ? "Video" : mimeType.startsWith("image/") ? "Image" : "Media";
|
|
282521
|
+
return `[${category}: ${mimeType}, ${kb} KB]`;
|
|
282522
|
+
}
|
|
282523
|
+
}
|
|
282524
|
+
return part.text ?? "";
|
|
282525
|
+
}
|
|
282526
|
+
function updatePart(part, updates) {
|
|
282527
|
+
return { ...part, ...updates };
|
|
282528
|
+
}
|
|
282529
|
+
function cloneFunctionResponse(resp) {
|
|
282530
|
+
return { ...resp };
|
|
282531
|
+
}
|
|
282532
|
+
function cloneFunctionCall(call) {
|
|
282533
|
+
return { ...call };
|
|
282534
|
+
}
|
|
282535
|
+
function getResponseText(response) {
|
|
282536
|
+
if (response.candidates && response.candidates.length > 0) {
|
|
282537
|
+
const candidate = response.candidates[0];
|
|
282538
|
+
if (candidate.content && candidate.content.parts && candidate.content.parts.length > 0) {
|
|
282539
|
+
return candidate.content.parts.filter((part) => part.text && !part.thought).map((part) => part.text).join("");
|
|
282540
|
+
}
|
|
282541
|
+
}
|
|
282542
|
+
return null;
|
|
282543
|
+
}
|
|
282544
|
+
var init_partUtils = __esm({
|
|
282545
|
+
"packages/core/dist/src/utils/partUtils.js"() {
|
|
282546
|
+
"use strict";
|
|
282547
|
+
}
|
|
282548
|
+
});
|
|
282549
|
+
|
|
282550
|
+
// packages/core/dist/src/core/geminiRequest.js
|
|
282551
|
+
function partListUnionToString(value) {
|
|
282552
|
+
return partToString(value, { verbose: true });
|
|
282553
|
+
}
|
|
282554
|
+
var init_geminiRequest = __esm({
|
|
282555
|
+
"packages/core/dist/src/core/geminiRequest.js"() {
|
|
282556
|
+
"use strict";
|
|
282557
|
+
init_node();
|
|
282558
|
+
init_partUtils();
|
|
282559
|
+
}
|
|
282560
|
+
});
|
|
282561
|
+
|
|
282562
|
+
// packages/core/dist/src/core/agentChatHistory.js
|
|
282563
|
+
var AgentChatHistory;
|
|
282564
|
+
var init_agentChatHistory = __esm({
|
|
282565
|
+
"packages/core/dist/src/core/agentChatHistory.js"() {
|
|
282566
|
+
"use strict";
|
|
282567
|
+
AgentChatHistory = class {
|
|
282568
|
+
history = [];
|
|
282569
|
+
constructor(initialTurns = []) {
|
|
282570
|
+
this.history = [...initialTurns];
|
|
282571
|
+
}
|
|
282572
|
+
/**
|
|
282573
|
+
* Adds a new turn to the history.
|
|
282574
|
+
* Every turn must have a durable ID, usually provided by the ChatRecordingService.
|
|
282575
|
+
*/
|
|
282576
|
+
push(turn) {
|
|
282577
|
+
this.history.push(turn);
|
|
282578
|
+
}
|
|
282579
|
+
/**
|
|
282580
|
+
* Overwrites the entire history with a new list of turns.
|
|
282581
|
+
*/
|
|
282582
|
+
set(turns) {
|
|
282583
|
+
this.history = [...turns];
|
|
282584
|
+
}
|
|
282585
|
+
clear() {
|
|
282586
|
+
this.history = [];
|
|
282587
|
+
}
|
|
282588
|
+
get() {
|
|
282589
|
+
return this.history;
|
|
282590
|
+
}
|
|
282591
|
+
/**
|
|
282592
|
+
* Returns a copy of the raw Gemini Content[] for API consumption.
|
|
282593
|
+
*/
|
|
282594
|
+
getContents() {
|
|
282595
|
+
return this.history.map((h3) => h3.content);
|
|
282596
|
+
}
|
|
282597
|
+
map(callback) {
|
|
282598
|
+
return this.history.map(callback);
|
|
282599
|
+
}
|
|
282600
|
+
flatMap(callback) {
|
|
282601
|
+
return this.history.flatMap(callback);
|
|
282602
|
+
}
|
|
282603
|
+
get length() {
|
|
282604
|
+
return this.history.length;
|
|
282605
|
+
}
|
|
282606
|
+
};
|
|
282607
|
+
}
|
|
282608
|
+
});
|
|
282609
|
+
|
|
282610
|
+
// packages/core/dist/src/utils/cryptoUtils.js
|
|
282611
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
282612
|
+
function deriveStableId(sourceIds) {
|
|
282613
|
+
const sortedIds = [...sourceIds].sort();
|
|
282614
|
+
return createHash8("sha256").update(sortedIds.join("|")).digest("hex").slice(0, 32);
|
|
282615
|
+
}
|
|
282616
|
+
var init_cryptoUtils = __esm({
|
|
282617
|
+
"packages/core/dist/src/utils/cryptoUtils.js"() {
|
|
282618
|
+
"use strict";
|
|
282619
|
+
}
|
|
282620
|
+
});
|
|
282621
|
+
|
|
282622
|
+
// packages/core/dist/src/utils/sessionUtils.js
|
|
282623
|
+
function ensureStableToolIds(history) {
|
|
282624
|
+
for (let i4 = 0; i4 < history.length; i4++) {
|
|
282625
|
+
const turn = history[i4];
|
|
282626
|
+
const parts2 = turn.content.parts || [];
|
|
282627
|
+
for (let partIdx = 0; partIdx < parts2.length; partIdx++) {
|
|
282628
|
+
const part = parts2[partIdx];
|
|
282629
|
+
if (part.functionCall && !part.functionCall.id) {
|
|
282630
|
+
const name3 = part.functionCall.name;
|
|
282631
|
+
const nextTurn = history[i4 + 1];
|
|
282632
|
+
let pairedId;
|
|
282633
|
+
if (nextTurn?.content.role === "user") {
|
|
282634
|
+
const matchingResp = nextTurn.content.parts?.find((p3) => p3.functionResponse && p3.functionResponse.name === name3 && !p3.functionResponse.id);
|
|
282635
|
+
if (matchingResp) {
|
|
282636
|
+
pairedId = `synth_${name3}_${deriveStableId([turn.id, i4.toString(), partIdx.toString()])}`;
|
|
282637
|
+
part.functionCall.id = pairedId;
|
|
282638
|
+
matchingResp.functionResponse.id = pairedId;
|
|
282639
|
+
}
|
|
282640
|
+
}
|
|
282641
|
+
if (!part.functionCall.id) {
|
|
282642
|
+
part.functionCall.id = `synth_${name3}_${deriveStableId([turn.id, i4.toString(), partIdx.toString()])}`;
|
|
282643
|
+
}
|
|
282644
|
+
}
|
|
282645
|
+
if (part.functionResponse && !part.functionResponse.id) {
|
|
282646
|
+
const name3 = part.functionResponse.name;
|
|
282647
|
+
const prevTurn = history[i4 - 1];
|
|
282648
|
+
if (prevTurn?.content.role === "model") {
|
|
282649
|
+
const matchingCall = prevTurn.content.parts?.find((p3) => p3.functionCall && p3.functionCall.name === name3 && !p3.functionCall.id);
|
|
282650
|
+
if (matchingCall) {
|
|
282651
|
+
const pairedId = `synth_${name3}_${deriveStableId([prevTurn.id, (i4 - 1).toString(), partIdx.toString()])}`;
|
|
282652
|
+
matchingCall.functionCall.id = pairedId;
|
|
282653
|
+
part.functionResponse.id = pairedId;
|
|
282654
|
+
}
|
|
282655
|
+
}
|
|
282656
|
+
if (!part.functionResponse.id) {
|
|
282657
|
+
part.functionResponse.id = `synth_orph_${name3}_${deriveStableId([turn.id, i4.toString(), partIdx.toString()])}`;
|
|
282658
|
+
}
|
|
282659
|
+
}
|
|
282660
|
+
}
|
|
282661
|
+
}
|
|
282662
|
+
}
|
|
282663
|
+
function isIgnoredUserContent(trimmedContent) {
|
|
282664
|
+
return trimmedContent.length === 0 || trimmedContent.startsWith("/") || trimmedContent.startsWith("?") || trimmedContent.startsWith("<session_context>") || trimmedContent.startsWith("<hook_context>");
|
|
282665
|
+
}
|
|
282666
|
+
var init_sessionUtils = __esm({
|
|
282667
|
+
"packages/core/dist/src/utils/sessionUtils.js"() {
|
|
282668
|
+
"use strict";
|
|
282669
|
+
init_node();
|
|
282670
|
+
init_chatRecordingService();
|
|
282671
|
+
init_geminiRequest();
|
|
282672
|
+
init_geminiRequest();
|
|
282673
|
+
init_agentChatHistory();
|
|
282674
|
+
init_cryptoUtils();
|
|
282675
|
+
}
|
|
282676
|
+
});
|
|
282677
|
+
|
|
282478
282678
|
// packages/core/dist/src/services/chatRecordingService.js
|
|
282479
282679
|
import path28 from "node:path";
|
|
282480
282680
|
import * as fs34 from "node:fs";
|
|
@@ -282504,6 +282704,19 @@ function isPartialMetadataRecord(record2) {
|
|
|
282504
282704
|
function isTextPart(part) {
|
|
282505
282705
|
return isStringProperty(part, "text");
|
|
282506
282706
|
}
|
|
282707
|
+
function isResumableMessageRecord(message) {
|
|
282708
|
+
const contentString = message.content ? partListUnionToString(message.content) : "";
|
|
282709
|
+
if (message.type === "user") {
|
|
282710
|
+
return !isIgnoredUserContent(contentString.trim());
|
|
282711
|
+
}
|
|
282712
|
+
if (message.type === "gemini") {
|
|
282713
|
+
return contentString.trim().length > 0 || (message.toolCalls?.length ?? 0) > 0 || (message.thoughts?.length ?? 0) > 0;
|
|
282714
|
+
}
|
|
282715
|
+
return false;
|
|
282716
|
+
}
|
|
282717
|
+
function hasResumableConversationContent(messages) {
|
|
282718
|
+
return messages.some((message) => isResumableMessageRecord(message));
|
|
282719
|
+
}
|
|
282507
282720
|
async function loadConversationRecord(filePath, options) {
|
|
282508
282721
|
if (!fs34.existsSync(filePath)) {
|
|
282509
282722
|
return null;
|
|
@@ -282565,12 +282778,12 @@ async function loadConversationRecord(filePath, options) {
|
|
|
282565
282778
|
}
|
|
282566
282779
|
const id = record2.id;
|
|
282567
282780
|
const isUser = hasProperty(record2, "type") && record2.type === "user";
|
|
282568
|
-
const
|
|
282781
|
+
const isResumable = isResumableMessageRecord(record2);
|
|
282569
282782
|
if (options?.metadataOnly) {
|
|
282570
282783
|
messageIds.push(id);
|
|
282571
|
-
messageKinds.set(id, { isUser,
|
|
282784
|
+
messageKinds.set(id, { isUser, isResumable });
|
|
282572
282785
|
}
|
|
282573
|
-
if (!firstUserMessageStr && isUser && hasProperty(record2, "content") && record2["content"]) {
|
|
282786
|
+
if (!firstUserMessageStr && isUser && hasProperty(record2, "content") && record2["content"] && isResumable) {
|
|
282574
282787
|
const rawContent = record2["content"];
|
|
282575
282788
|
if (Array.isArray(rawContent)) {
|
|
282576
282789
|
firstUserMessageStr = rawContent.map((p3) => isTextPart(p3) ? p3["text"] : "").join("");
|
|
@@ -282601,14 +282814,17 @@ async function loadConversationRecord(filePath, options) {
|
|
|
282601
282814
|
if (isMessageRecord(msg)) {
|
|
282602
282815
|
const id = msg.id;
|
|
282603
282816
|
const isUser = msg.type === "user";
|
|
282604
|
-
const
|
|
282817
|
+
const isResumable = isResumableMessageRecord(msg);
|
|
282605
282818
|
if (options?.metadataOnly) {
|
|
282606
282819
|
messageIds.push(id);
|
|
282607
|
-
messageKinds.set(id, {
|
|
282820
|
+
messageKinds.set(id, {
|
|
282821
|
+
isUser,
|
|
282822
|
+
isResumable
|
|
282823
|
+
});
|
|
282608
282824
|
} else {
|
|
282609
282825
|
messagesMap.set(id, msg);
|
|
282610
282826
|
}
|
|
282611
|
-
if (!firstUserMessageStr && isUser && msg.content && (Array.isArray(msg.content) || typeof msg.content === "string")) {
|
|
282827
|
+
if (!firstUserMessageStr && isUser && isResumable && msg.content && (Array.isArray(msg.content) || typeof msg.content === "string")) {
|
|
282612
282828
|
if (Array.isArray(msg.content)) {
|
|
282613
282829
|
firstUserMessageStr = msg.content.map((p3) => isTextPart(p3) ? p3.text : "").join("");
|
|
282614
282830
|
} else {
|
|
@@ -282629,14 +282845,17 @@ async function loadConversationRecord(filePath, options) {
|
|
|
282629
282845
|
if (isMessageRecord(msg)) {
|
|
282630
282846
|
const id = msg.id;
|
|
282631
282847
|
const isUser = msg.type === "user";
|
|
282632
|
-
const
|
|
282848
|
+
const isResumable = isResumableMessageRecord(msg);
|
|
282633
282849
|
if (options?.metadataOnly) {
|
|
282634
282850
|
messageIds.push(id);
|
|
282635
|
-
messageKinds.set(id, {
|
|
282851
|
+
messageKinds.set(id, {
|
|
282852
|
+
isUser,
|
|
282853
|
+
isResumable
|
|
282854
|
+
});
|
|
282636
282855
|
} else {
|
|
282637
282856
|
messagesMap.set(id, msg);
|
|
282638
282857
|
}
|
|
282639
|
-
if (!firstUserMessageStr && isUser && msg.content && (Array.isArray(msg.content) || typeof msg.content === "string")) {
|
|
282858
|
+
if (!firstUserMessageStr && isUser && isResumable && msg.content && (Array.isArray(msg.content) || typeof msg.content === "string")) {
|
|
282640
282859
|
if (Array.isArray(msg.content)) {
|
|
282641
282860
|
firstUserMessageStr = msg.content.map((p3) => isTextPart(p3) ? p3.text : "").join("");
|
|
282642
282861
|
} else {
|
|
@@ -282654,7 +282873,7 @@ async function loadConversationRecord(filePath, options) {
|
|
|
282654
282873
|
return await parseLegacyRecordFallback(filePath, options);
|
|
282655
282874
|
}
|
|
282656
282875
|
const loadedMessages = Array.from(messagesMap.values());
|
|
282657
|
-
const metadataFirstUserMessage = loadedMessages.find((message) => message.type === "user") ?? null;
|
|
282876
|
+
const metadataFirstUserMessage = loadedMessages.find((message) => message.type === "user" && isResumableMessageRecord(message)) ?? null;
|
|
282658
282877
|
let fallbackFirstUserMessage = firstUserMessageStr;
|
|
282659
282878
|
if (!fallbackFirstUserMessage && metadataFirstUserMessage) {
|
|
282660
282879
|
const rawContent = metadataFirstUserMessage.content;
|
|
@@ -282665,7 +282884,7 @@ async function loadConversationRecord(filePath, options) {
|
|
|
282665
282884
|
}
|
|
282666
282885
|
}
|
|
282667
282886
|
const userMessageCount = options?.metadataOnly ? Array.from(messageKinds.values()).filter((m3) => m3.isUser).length : loadedMessages.filter((m3) => m3.type === "user").length;
|
|
282668
|
-
const
|
|
282887
|
+
const hasResumableContent = options?.metadataOnly ? Array.from(messageKinds.values()).some((m3) => m3.isResumable) : hasResumableConversationContent(loadedMessages);
|
|
282669
282888
|
return {
|
|
282670
282889
|
sessionId: metadata2.sessionId,
|
|
282671
282890
|
projectHash: metadata2.projectHash,
|
|
@@ -282680,7 +282899,7 @@ async function loadConversationRecord(filePath, options) {
|
|
|
282680
282899
|
userMessageCount,
|
|
282681
282900
|
memoryScratchpadIsStale: isTrackingMemoryScratchpadFreshness ? memoryScratchpadIsStale : void 0,
|
|
282682
282901
|
firstUserMessage: fallbackFirstUserMessage,
|
|
282683
|
-
|
|
282902
|
+
hasResumableContent
|
|
282684
282903
|
};
|
|
282685
282904
|
} catch (error2) {
|
|
282686
282905
|
debugLogger.error("Error loading conversation record from JSONL:", error2);
|
|
@@ -282696,7 +282915,7 @@ async function parseLegacyRecordFallback(filePath, options) {
|
|
|
282696
282915
|
const legacyRecord = parsed;
|
|
282697
282916
|
if (options?.metadataOnly) {
|
|
282698
282917
|
let fallbackFirstUserMessageStr;
|
|
282699
|
-
const firstUserMessage = legacyRecord.messages?.find((m3) => m3.type === "user");
|
|
282918
|
+
const firstUserMessage = legacyRecord.messages?.find((m3) => m3.type === "user" && isResumableMessageRecord(m3));
|
|
282700
282919
|
if (firstUserMessage) {
|
|
282701
282920
|
const rawContent = firstUserMessage.content;
|
|
282702
282921
|
if (Array.isArray(rawContent)) {
|
|
@@ -282711,13 +282930,13 @@ async function parseLegacyRecordFallback(filePath, options) {
|
|
|
282711
282930
|
messageCount: legacyRecord.messages?.length || 0,
|
|
282712
282931
|
userMessageCount: legacyRecord.messages?.filter((m3) => m3.type === "user").length || 0,
|
|
282713
282932
|
firstUserMessage: fallbackFirstUserMessageStr,
|
|
282714
|
-
|
|
282933
|
+
hasResumableContent: legacyRecord.messages?.some((m3) => isResumableMessageRecord(m3)) || false
|
|
282715
282934
|
};
|
|
282716
282935
|
}
|
|
282717
282936
|
return {
|
|
282718
282937
|
...legacyRecord,
|
|
282719
282938
|
userMessageCount: legacyRecord.messages?.filter((m3) => m3.type === "user").length || 0,
|
|
282720
|
-
|
|
282939
|
+
hasResumableContent: legacyRecord.messages?.some((m3) => isResumableMessageRecord(m3)) || false
|
|
282721
282940
|
};
|
|
282722
282941
|
}
|
|
282723
282942
|
} catch {
|
|
@@ -282734,6 +282953,8 @@ var init_chatRecordingService = __esm({
|
|
|
282734
282953
|
init_errors2();
|
|
282735
282954
|
init_sessionOperations();
|
|
282736
282955
|
init_debugLogger();
|
|
282956
|
+
init_geminiRequest();
|
|
282957
|
+
init_sessionUtils();
|
|
282737
282958
|
init_chatRecordingTypes();
|
|
282738
282959
|
init_chatRecordingTypes();
|
|
282739
282960
|
ENOSPC_WARNING_MESSAGE = "Chat recording disabled: No space left on device. The conversation will continue but will not be saved to disk. Free up disk space and restart to enable recording.";
|
|
@@ -283062,6 +283283,20 @@ var init_chatRecordingService = __esm({
|
|
|
283062
283283
|
throw error2;
|
|
283063
283284
|
}
|
|
283064
283285
|
}
|
|
283286
|
+
/**
|
|
283287
|
+
* Deletes the current session only if it has no resumable conversation
|
|
283288
|
+
* content. This removes abandoned startup-only sessions while preserving any
|
|
283289
|
+
* session with a real user prompt, model response, or tool activity.
|
|
283290
|
+
*/
|
|
283291
|
+
async deleteCurrentSessionIfNotResumableAsync() {
|
|
283292
|
+
if (!this.conversationFile || !this.cachedConversation) {
|
|
283293
|
+
return;
|
|
283294
|
+
}
|
|
283295
|
+
if (hasResumableConversationContent(this.cachedConversation.messages)) {
|
|
283296
|
+
return;
|
|
283297
|
+
}
|
|
283298
|
+
await this.deleteCurrentSessionAsync();
|
|
283299
|
+
}
|
|
283065
283300
|
/**
|
|
283066
283301
|
* Rewinds the conversation to the state just before the specified message ID.
|
|
283067
283302
|
* All messages from (and including) the specified ID onwards are removed.
|
|
@@ -285521,75 +285756,6 @@ var init_converter = __esm({
|
|
|
285521
285756
|
}
|
|
285522
285757
|
});
|
|
285523
285758
|
|
|
285524
|
-
// packages/core/dist/src/utils/partUtils.js
|
|
285525
|
-
function partToString(value, options) {
|
|
285526
|
-
if (!value) {
|
|
285527
|
-
return "";
|
|
285528
|
-
}
|
|
285529
|
-
if (typeof value === "string") {
|
|
285530
|
-
return value;
|
|
285531
|
-
}
|
|
285532
|
-
if (Array.isArray(value)) {
|
|
285533
|
-
return value.map((part2) => partToString(part2, options)).join("");
|
|
285534
|
-
}
|
|
285535
|
-
const part = value;
|
|
285536
|
-
if (options?.verbose) {
|
|
285537
|
-
if (part.videoMetadata !== void 0) {
|
|
285538
|
-
return `[Video Metadata]`;
|
|
285539
|
-
}
|
|
285540
|
-
if (part.thought !== void 0) {
|
|
285541
|
-
return `[Thought: ${part.thought}]`;
|
|
285542
|
-
}
|
|
285543
|
-
if (part.codeExecutionResult !== void 0) {
|
|
285544
|
-
return `[Code Execution Result]`;
|
|
285545
|
-
}
|
|
285546
|
-
if (part.executableCode !== void 0) {
|
|
285547
|
-
return `[Executable Code]`;
|
|
285548
|
-
}
|
|
285549
|
-
if (part.fileData !== void 0) {
|
|
285550
|
-
return `[File Data]`;
|
|
285551
|
-
}
|
|
285552
|
-
if (part.functionCall !== void 0) {
|
|
285553
|
-
return `[Function Call: ${part.functionCall.name}]`;
|
|
285554
|
-
}
|
|
285555
|
-
if (part.functionResponse !== void 0) {
|
|
285556
|
-
return `[Function Response: ${part.functionResponse.name}]`;
|
|
285557
|
-
}
|
|
285558
|
-
if (part.inlineData !== void 0) {
|
|
285559
|
-
const mimeType = part.inlineData.mimeType ?? "unknown";
|
|
285560
|
-
const data = part.inlineData.data ?? "";
|
|
285561
|
-
const bytes = Math.ceil(data.length * 3 / 4);
|
|
285562
|
-
const kb = (bytes / 1024).toFixed(1);
|
|
285563
|
-
const category = mimeType.startsWith("audio/") ? "Audio" : mimeType.startsWith("video/") ? "Video" : mimeType.startsWith("image/") ? "Image" : "Media";
|
|
285564
|
-
return `[${category}: ${mimeType}, ${kb} KB]`;
|
|
285565
|
-
}
|
|
285566
|
-
}
|
|
285567
|
-
return part.text ?? "";
|
|
285568
|
-
}
|
|
285569
|
-
function updatePart(part, updates) {
|
|
285570
|
-
return { ...part, ...updates };
|
|
285571
|
-
}
|
|
285572
|
-
function cloneFunctionResponse(resp) {
|
|
285573
|
-
return { ...resp };
|
|
285574
|
-
}
|
|
285575
|
-
function cloneFunctionCall(call) {
|
|
285576
|
-
return { ...call };
|
|
285577
|
-
}
|
|
285578
|
-
function getResponseText(response) {
|
|
285579
|
-
if (response.candidates && response.candidates.length > 0) {
|
|
285580
|
-
const candidate = response.candidates[0];
|
|
285581
|
-
if (candidate.content && candidate.content.parts && candidate.content.parts.length > 0) {
|
|
285582
|
-
return candidate.content.parts.filter((part) => part.text && !part.thought).map((part) => part.text).join("");
|
|
285583
|
-
}
|
|
285584
|
-
}
|
|
285585
|
-
return null;
|
|
285586
|
-
}
|
|
285587
|
-
var init_partUtils = __esm({
|
|
285588
|
-
"packages/core/dist/src/utils/partUtils.js"() {
|
|
285589
|
-
"use strict";
|
|
285590
|
-
}
|
|
285591
|
-
});
|
|
285592
|
-
|
|
285593
285759
|
// packages/core/dist/src/utils/generateContentResponseUtilities.js
|
|
285594
285760
|
function createFunctionResponsePart(callId, toolName, output) {
|
|
285595
285761
|
return {
|
|
@@ -332683,7 +332849,7 @@ function getVersion() {
|
|
|
332683
332849
|
}
|
|
332684
332850
|
versionPromise = (async () => {
|
|
332685
332851
|
const pkgJson = await getPackageJson(__dirname4);
|
|
332686
|
-
return "0.47.0
|
|
332852
|
+
return "0.47.0";
|
|
332687
332853
|
})();
|
|
332688
332854
|
return versionPromise;
|
|
332689
332855
|
}
|
|
@@ -334505,7 +334671,7 @@ var init_promptIdContext = __esm({
|
|
|
334505
334671
|
});
|
|
334506
334672
|
|
|
334507
334673
|
// packages/core/dist/src/utils/llm-edit-fixer.js
|
|
334508
|
-
import { createHash as
|
|
334674
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
334509
334675
|
async function generateJsonWithTimeout(client, params, timeoutMs) {
|
|
334510
334676
|
try {
|
|
334511
334677
|
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
@@ -334526,7 +334692,7 @@ async function generateJsonWithTimeout(client, params, timeoutMs) {
|
|
|
334526
334692
|
}
|
|
334527
334693
|
async function FixLLMEditWithInstruction(instruction, old_string, new_string, error2, current_content, baseLlmClient, abortSignal) {
|
|
334528
334694
|
const promptId = getPromptIdWithFallback("llm-fixer");
|
|
334529
|
-
const cacheKey =
|
|
334695
|
+
const cacheKey = createHash9("sha256").update(JSON.stringify([
|
|
334530
334696
|
current_content,
|
|
334531
334697
|
old_string,
|
|
334532
334698
|
new_string,
|
|
@@ -337439,6 +337605,61 @@ var init_loggingContentGenerator = __esm({
|
|
|
337439
337605
|
}
|
|
337440
337606
|
});
|
|
337441
337607
|
|
|
337608
|
+
// packages/core/dist/src/core/modelMappingContentGenerator.js
|
|
337609
|
+
var ModelMappingContentGenerator;
|
|
337610
|
+
var init_modelMappingContentGenerator = __esm({
|
|
337611
|
+
"packages/core/dist/src/core/modelMappingContentGenerator.js"() {
|
|
337612
|
+
"use strict";
|
|
337613
|
+
init_node();
|
|
337614
|
+
init_contentGenerator();
|
|
337615
|
+
init_modelUtils();
|
|
337616
|
+
ModelMappingContentGenerator = class {
|
|
337617
|
+
wrapped;
|
|
337618
|
+
mappings;
|
|
337619
|
+
constructor(wrapped, mappings) {
|
|
337620
|
+
this.wrapped = wrapped;
|
|
337621
|
+
this.mappings = mappings;
|
|
337622
|
+
}
|
|
337623
|
+
getWrapped() {
|
|
337624
|
+
return this.wrapped;
|
|
337625
|
+
}
|
|
337626
|
+
get userTier() {
|
|
337627
|
+
return this.wrapped.userTier;
|
|
337628
|
+
}
|
|
337629
|
+
get userTierName() {
|
|
337630
|
+
return this.wrapped.userTierName;
|
|
337631
|
+
}
|
|
337632
|
+
get paidTier() {
|
|
337633
|
+
return this.wrapped.paidTier;
|
|
337634
|
+
}
|
|
337635
|
+
mapModel(req) {
|
|
337636
|
+
if (req.model) {
|
|
337637
|
+
const normalizedModel = normalizeModelId(req.model);
|
|
337638
|
+
if (this.mappings[normalizedModel]) {
|
|
337639
|
+
return {
|
|
337640
|
+
...req,
|
|
337641
|
+
model: req.model.startsWith("models/") ? `models/${this.mappings[normalizedModel]}` : this.mappings[normalizedModel]
|
|
337642
|
+
};
|
|
337643
|
+
}
|
|
337644
|
+
}
|
|
337645
|
+
return req;
|
|
337646
|
+
}
|
|
337647
|
+
generateContent(request, userPromptId, role) {
|
|
337648
|
+
return this.wrapped.generateContent(this.mapModel(request), userPromptId, role);
|
|
337649
|
+
}
|
|
337650
|
+
generateContentStream(request, userPromptId, role) {
|
|
337651
|
+
return this.wrapped.generateContentStream(this.mapModel(request), userPromptId, role);
|
|
337652
|
+
}
|
|
337653
|
+
countTokens(request) {
|
|
337654
|
+
return this.wrapped.countTokens(this.mapModel(request));
|
|
337655
|
+
}
|
|
337656
|
+
embedContent(request) {
|
|
337657
|
+
return this.wrapped.embedContent(this.mapModel(request));
|
|
337658
|
+
}
|
|
337659
|
+
};
|
|
337660
|
+
}
|
|
337661
|
+
});
|
|
337662
|
+
|
|
337442
337663
|
// packages/core/dist/src/code_assist/codeAssist.js
|
|
337443
337664
|
async function createCodeAssistContentGenerator(httpOptions, authType, config3, sessionId) {
|
|
337444
337665
|
if (authType === AuthType2.LOGIN_WITH_GOOGLE || authType === AuthType2.COMPUTE_ADC) {
|
|
@@ -337450,8 +337671,14 @@ async function createCodeAssistContentGenerator(httpOptions, authType, config3,
|
|
|
337450
337671
|
}
|
|
337451
337672
|
function getCodeAssistServer(config3) {
|
|
337452
337673
|
let server = config3.getContentGenerator();
|
|
337453
|
-
|
|
337454
|
-
server
|
|
337674
|
+
while (true) {
|
|
337675
|
+
if (server instanceof LoggingContentGenerator) {
|
|
337676
|
+
server = server.getWrapped();
|
|
337677
|
+
} else if (server instanceof ModelMappingContentGenerator) {
|
|
337678
|
+
server = server.getWrapped();
|
|
337679
|
+
} else {
|
|
337680
|
+
break;
|
|
337681
|
+
}
|
|
337455
337682
|
}
|
|
337456
337683
|
if (!(server instanceof CodeAssistServer)) {
|
|
337457
337684
|
return void 0;
|
|
@@ -337466,6 +337693,7 @@ var init_codeAssist = __esm({
|
|
|
337466
337693
|
init_setup();
|
|
337467
337694
|
init_server();
|
|
337468
337695
|
init_loggingContentGenerator();
|
|
337696
|
+
init_modelMappingContentGenerator();
|
|
337469
337697
|
}
|
|
337470
337698
|
});
|
|
337471
337699
|
|
|
@@ -337807,7 +338035,7 @@ async function createContentGenerator(config3, gcConfig, sessionId) {
|
|
|
337807
338035
|
}
|
|
337808
338036
|
if (config3.authType === AuthType2.LOGIN_WITH_GOOGLE || config3.authType === AuthType2.COMPUTE_ADC) {
|
|
337809
338037
|
const httpOptions = { headers: baseHeaders };
|
|
337810
|
-
return new LoggingContentGenerator(await createCodeAssistContentGenerator(httpOptions, config3.authType, gcConfig, sessionId), gcConfig);
|
|
338038
|
+
return new LoggingContentGenerator(new ModelMappingContentGenerator(await createCodeAssistContentGenerator(httpOptions, config3.authType, gcConfig, sessionId), CCPA_AI_MODEL_MAPPINGS), gcConfig);
|
|
337811
338039
|
}
|
|
337812
338040
|
if (config3.authType === AuthType2.USE_GEMINI || config3.authType === AuthType2.USE_VERTEX_AI || config3.authType === AuthType2.GATEWAY) {
|
|
337813
338041
|
let headers = { ...baseHeaders };
|
|
@@ -337888,6 +338116,8 @@ var init_contentGenerator = __esm({
|
|
|
337888
338116
|
init_surface();
|
|
337889
338117
|
init_recordingContentGenerator();
|
|
337890
338118
|
init_dist6();
|
|
338119
|
+
init_modelMappingContentGenerator();
|
|
338120
|
+
init_models();
|
|
337891
338121
|
(function(AuthType3) {
|
|
337892
338122
|
AuthType3["LOGIN_WITH_GOOGLE"] = "oauth-personal";
|
|
337893
338123
|
AuthType3["USE_GEMINI"] = "gemini-api-key";
|
|
@@ -361428,54 +361658,6 @@ var init_agent_loop_context = __esm({
|
|
|
361428
361658
|
}
|
|
361429
361659
|
});
|
|
361430
361660
|
|
|
361431
|
-
// packages/core/dist/src/core/agentChatHistory.js
|
|
361432
|
-
var AgentChatHistory;
|
|
361433
|
-
var init_agentChatHistory = __esm({
|
|
361434
|
-
"packages/core/dist/src/core/agentChatHistory.js"() {
|
|
361435
|
-
"use strict";
|
|
361436
|
-
AgentChatHistory = class {
|
|
361437
|
-
history = [];
|
|
361438
|
-
constructor(initialTurns = []) {
|
|
361439
|
-
this.history = [...initialTurns];
|
|
361440
|
-
}
|
|
361441
|
-
/**
|
|
361442
|
-
* Adds a new turn to the history.
|
|
361443
|
-
* Every turn must have a durable ID, usually provided by the ChatRecordingService.
|
|
361444
|
-
*/
|
|
361445
|
-
push(turn) {
|
|
361446
|
-
this.history.push(turn);
|
|
361447
|
-
}
|
|
361448
|
-
/**
|
|
361449
|
-
* Overwrites the entire history with a new list of turns.
|
|
361450
|
-
*/
|
|
361451
|
-
set(turns) {
|
|
361452
|
-
this.history = [...turns];
|
|
361453
|
-
}
|
|
361454
|
-
clear() {
|
|
361455
|
-
this.history = [];
|
|
361456
|
-
}
|
|
361457
|
-
get() {
|
|
361458
|
-
return this.history;
|
|
361459
|
-
}
|
|
361460
|
-
/**
|
|
361461
|
-
* Returns a copy of the raw Gemini Content[] for API consumption.
|
|
361462
|
-
*/
|
|
361463
|
-
getContents() {
|
|
361464
|
-
return this.history.map((h3) => h3.content);
|
|
361465
|
-
}
|
|
361466
|
-
map(callback) {
|
|
361467
|
-
return this.history.map(callback);
|
|
361468
|
-
}
|
|
361469
|
-
flatMap(callback) {
|
|
361470
|
-
return this.history.flatMap(callback);
|
|
361471
|
-
}
|
|
361472
|
-
get length() {
|
|
361473
|
-
return this.history.length;
|
|
361474
|
-
}
|
|
361475
|
-
};
|
|
361476
|
-
}
|
|
361477
|
-
});
|
|
361478
|
-
|
|
361479
361661
|
// packages/core/dist/src/utils/messageInspectors.js
|
|
361480
361662
|
function isFunctionResponse(content) {
|
|
361481
361663
|
return content.role === "user" && !!content.parts && content.parts.every((part) => !!part.functionResponse);
|
|
@@ -361489,18 +361671,6 @@ var init_messageInspectors = __esm({
|
|
|
361489
361671
|
}
|
|
361490
361672
|
});
|
|
361491
361673
|
|
|
361492
|
-
// packages/core/dist/src/utils/cryptoUtils.js
|
|
361493
|
-
import { createHash as createHash10 } from "node:crypto";
|
|
361494
|
-
function deriveStableId(sourceIds) {
|
|
361495
|
-
const sortedIds = [...sourceIds].sort();
|
|
361496
|
-
return createHash10("sha256").update(sortedIds.join("|")).digest("hex").slice(0, 32);
|
|
361497
|
-
}
|
|
361498
|
-
var init_cryptoUtils = __esm({
|
|
361499
|
-
"packages/core/dist/src/utils/cryptoUtils.js"() {
|
|
361500
|
-
"use strict";
|
|
361501
|
-
}
|
|
361502
|
-
});
|
|
361503
|
-
|
|
361504
361674
|
// packages/core/dist/src/utils/historyHardening.js
|
|
361505
361675
|
function hardenHistory(history, options = {}) {
|
|
361506
361676
|
if (history.length === 0)
|
|
@@ -361773,71 +361943,6 @@ var init_historyHardening = __esm({
|
|
|
361773
361943
|
}
|
|
361774
361944
|
});
|
|
361775
361945
|
|
|
361776
|
-
// packages/core/dist/src/core/geminiRequest.js
|
|
361777
|
-
function partListUnionToString(value) {
|
|
361778
|
-
return partToString(value, { verbose: true });
|
|
361779
|
-
}
|
|
361780
|
-
var init_geminiRequest = __esm({
|
|
361781
|
-
"packages/core/dist/src/core/geminiRequest.js"() {
|
|
361782
|
-
"use strict";
|
|
361783
|
-
init_node();
|
|
361784
|
-
init_partUtils();
|
|
361785
|
-
}
|
|
361786
|
-
});
|
|
361787
|
-
|
|
361788
|
-
// packages/core/dist/src/utils/sessionUtils.js
|
|
361789
|
-
function ensureStableToolIds(history) {
|
|
361790
|
-
for (let i4 = 0; i4 < history.length; i4++) {
|
|
361791
|
-
const turn = history[i4];
|
|
361792
|
-
const parts2 = turn.content.parts || [];
|
|
361793
|
-
for (let partIdx = 0; partIdx < parts2.length; partIdx++) {
|
|
361794
|
-
const part = parts2[partIdx];
|
|
361795
|
-
if (part.functionCall && !part.functionCall.id) {
|
|
361796
|
-
const name3 = part.functionCall.name;
|
|
361797
|
-
const nextTurn = history[i4 + 1];
|
|
361798
|
-
let pairedId;
|
|
361799
|
-
if (nextTurn?.content.role === "user") {
|
|
361800
|
-
const matchingResp = nextTurn.content.parts?.find((p3) => p3.functionResponse && p3.functionResponse.name === name3 && !p3.functionResponse.id);
|
|
361801
|
-
if (matchingResp) {
|
|
361802
|
-
pairedId = `synth_${name3}_${deriveStableId([turn.id, i4.toString(), partIdx.toString()])}`;
|
|
361803
|
-
part.functionCall.id = pairedId;
|
|
361804
|
-
matchingResp.functionResponse.id = pairedId;
|
|
361805
|
-
}
|
|
361806
|
-
}
|
|
361807
|
-
if (!part.functionCall.id) {
|
|
361808
|
-
part.functionCall.id = `synth_${name3}_${deriveStableId([turn.id, i4.toString(), partIdx.toString()])}`;
|
|
361809
|
-
}
|
|
361810
|
-
}
|
|
361811
|
-
if (part.functionResponse && !part.functionResponse.id) {
|
|
361812
|
-
const name3 = part.functionResponse.name;
|
|
361813
|
-
const prevTurn = history[i4 - 1];
|
|
361814
|
-
if (prevTurn?.content.role === "model") {
|
|
361815
|
-
const matchingCall = prevTurn.content.parts?.find((p3) => p3.functionCall && p3.functionCall.name === name3 && !p3.functionCall.id);
|
|
361816
|
-
if (matchingCall) {
|
|
361817
|
-
const pairedId = `synth_${name3}_${deriveStableId([prevTurn.id, (i4 - 1).toString(), partIdx.toString()])}`;
|
|
361818
|
-
matchingCall.functionCall.id = pairedId;
|
|
361819
|
-
part.functionResponse.id = pairedId;
|
|
361820
|
-
}
|
|
361821
|
-
}
|
|
361822
|
-
if (!part.functionResponse.id) {
|
|
361823
|
-
part.functionResponse.id = `synth_orph_${name3}_${deriveStableId([turn.id, i4.toString(), partIdx.toString()])}`;
|
|
361824
|
-
}
|
|
361825
|
-
}
|
|
361826
|
-
}
|
|
361827
|
-
}
|
|
361828
|
-
}
|
|
361829
|
-
var init_sessionUtils = __esm({
|
|
361830
|
-
"packages/core/dist/src/utils/sessionUtils.js"() {
|
|
361831
|
-
"use strict";
|
|
361832
|
-
init_node();
|
|
361833
|
-
init_chatRecordingService();
|
|
361834
|
-
init_geminiRequest();
|
|
361835
|
-
init_geminiRequest();
|
|
361836
|
-
init_agentChatHistory();
|
|
361837
|
-
init_cryptoUtils();
|
|
361838
|
-
}
|
|
361839
|
-
});
|
|
361840
|
-
|
|
361841
361946
|
// packages/core/dist/src/core/geminiChat.js
|
|
361842
361947
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
361843
361948
|
function isIndexedPart(part) {
|
|
@@ -403246,6 +403351,7 @@ async function discoverTools(mcpServerName, mcpServerConfig, mcpClient, cliConfi
|
|
|
403246
403351
|
} catch (error2) {
|
|
403247
403352
|
if (!isMcpMethodNotFoundError(error2)) {
|
|
403248
403353
|
cliConfig.emitMcpDiagnostic("error", `Error discovering tools from ${mcpServerName}: ${getErrorMessage(error2)}`, error2, mcpServerName);
|
|
403354
|
+
throw error2;
|
|
403249
403355
|
}
|
|
403250
403356
|
return [];
|
|
403251
403357
|
}
|
|
@@ -411533,7 +411639,7 @@ ${sections.join("\n")}
|
|
|
411533
411639
|
if (authType === AuthType2.USE_GEMINI) {
|
|
411534
411640
|
setFlashModels("gemini-3-flash-preview", "gemini-3.5-flash");
|
|
411535
411641
|
} else {
|
|
411536
|
-
setFlashModels("gemini-3-flash", "gemini-3-flash");
|
|
411642
|
+
setFlashModels("gemini-3.5-flash", "gemini-3.5-flash");
|
|
411537
411643
|
}
|
|
411538
411644
|
} else {
|
|
411539
411645
|
setFlashModels("gemini-3-flash-preview", "gemini-2.5-flash");
|