zidane 9.1.9 → 9.1.13
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/{acp-Bha_yCgU.js → acp-Cz5mFUjB.js} +3 -3
- package/dist/{acp-Bha_yCgU.js.map → acp-Cz5mFUjB.js.map} +1 -1
- package/dist/acp-cli.js +4 -4
- package/dist/acp.js +1 -1
- package/dist/{auth-store-port-BvxVXx9g.js → auth-store-port-CDJa8Q8U.js} +2 -2
- package/dist/{auth-store-port-BvxVXx9g.js.map → auth-store-port-CDJa8Q8U.js.map} +1 -1
- package/dist/{auto-update-restart-CF3uPnr4.js → auto-update-restart-B4pU7Qgf.js} +10 -10
- package/dist/{auto-update-restart-CF3uPnr4.js.map → auto-update-restart-B4pU7Qgf.js.map} +1 -1
- package/dist/chat.js +9 -9
- package/dist/{cli-shared-C17TUz6H.js → cli-shared-BVtiiICW.js} +3 -3
- package/dist/{cli-shared-C17TUz6H.js.map → cli-shared-BVtiiICW.js.map} +1 -1
- package/dist/{credentials-BZP-MgtZ.js → credentials-axv5VvMR.js} +2 -2
- package/dist/{credentials-BZP-MgtZ.js.map → credentials-axv5VvMR.js.map} +1 -1
- package/dist/daemon-cli.js +2 -2
- package/dist/{discovery-Czp7bZZP.js → discovery-D7qVZWzq.js} +4 -4
- package/dist/{discovery-Czp7bZZP.js.map → discovery-D7qVZWzq.js.map} +1 -1
- package/dist/{engine-CDuOhwbt.js → engine-DjM5NPIf.js} +3 -3
- package/dist/{engine-CDuOhwbt.js.map → engine-DjM5NPIf.js.map} +1 -1
- package/dist/{executor-CoHqHsCp.js → executor-DlW7qAeN.js} +2 -2
- package/dist/{executor-CoHqHsCp.js.map → executor-DlW7qAeN.js.map} +1 -1
- package/dist/extensions/testing.js +2 -2
- package/dist/{extensions-BEaWxX4e.js → extensions-D7DeZNpn.js} +6 -6
- package/dist/{extensions-BEaWxX4e.js.map → extensions-D7DeZNpn.js.map} +1 -1
- package/dist/extensions.js +5 -5
- package/dist/{google-Bzt7uvy9.js → google-D1zjAViO.js} +2 -2
- package/dist/{google-Bzt7uvy9.js.map → google-D1zjAViO.js.map} +1 -1
- package/dist/{host-DkqB2P7L.js → host-Ds3RDlG5.js} +9 -9
- package/dist/{host-DkqB2P7L.js.map → host-Ds3RDlG5.js.map} +1 -1
- package/dist/{host-signals-Ca_oUeYl.js → host-signals-C8x5Yso0.js} +5 -5
- package/dist/{host-signals-Ca_oUeYl.js.map → host-signals-C8x5Yso0.js.map} +1 -1
- package/dist/{host-version-BwON7XSr.js → host-version-BGZumnpZ.js} +2 -2
- package/dist/{host-version-BwON7XSr.js.map → host-version-BGZumnpZ.js.map} +1 -1
- package/dist/index.js +5 -5
- package/dist/ipc/remote.js +3 -3
- package/dist/{ipc-Dlqz_xIe.js → ipc-DGfuNEfR.js} +4 -4
- package/dist/{ipc-Dlqz_xIe.js.map → ipc-DGfuNEfR.js.map} +1 -1
- package/dist/ipc.js +4 -4
- package/dist/{links-B5Dz7jku.js → links-D_1RhPh5.js} +8 -8
- package/dist/{links-B5Dz7jku.js.map → links-D_1RhPh5.js.map} +1 -1
- package/dist/{loaded-entry-BGN69Fns.js → loaded-entry-CLva6GQT.js} +2 -2
- package/dist/{loaded-entry-BGN69Fns.js.map → loaded-entry-CLva6GQT.js.map} +1 -1
- package/dist/{memory-ZWFqa7di.js → memory-CaFXUvQs.js} +15 -15
- package/dist/{memory-ZWFqa7di.js.map → memory-CaFXUvQs.js.map} +1 -1
- package/dist/{path-display-B3Jeqx9E.js → path-display-ZIWdFaTI.js} +3 -3
- package/dist/{path-display-B3Jeqx9E.js.map → path-display-ZIWdFaTI.js.map} +1 -1
- package/dist/providers/google.js +1 -1
- package/dist/{providers-ChifjOYS.js → providers-CsYrxuX1.js} +2 -2
- package/dist/{providers-ChifjOYS.js.map → providers-CsYrxuX1.js.map} +1 -1
- package/dist/providers.js +1 -1
- package/dist/{registry-mmAX5qBS.js → registry-BY45AOA-.js} +2 -2
- package/dist/{registry-mmAX5qBS.js.map → registry-BY45AOA-.js.map} +1 -1
- package/dist/{registry-TW3C94iD.js → registry-DTotchq6.js} +2 -2
- package/dist/{registry-TW3C94iD.js.map → registry-DTotchq6.js.map} +1 -1
- package/dist/{registry-CYEN4C4M.js → registry-Dl6261Xh.js} +2 -2
- package/dist/{registry-CYEN4C4M.js.map → registry-Dl6261Xh.js.map} +1 -1
- package/dist/{remote-hosts-Ctg9fwQY.js → remote-hosts-usqMiMbs.js} +4 -4
- package/dist/{remote-hosts-Ctg9fwQY.js.map → remote-hosts-usqMiMbs.js.map} +1 -1
- package/dist/{setting-DPim5iCP.js → setting-DzTMJIV3.js} +2 -2
- package/dist/{setting-DPim5iCP.js.map → setting-DzTMJIV3.js.map} +1 -1
- package/dist/{settings-keys-BIWy4T_0.js → settings-keys-DDrfnBHi.js} +2 -2
- package/dist/{settings-keys-BIWy4T_0.js.map → settings-keys-DDrfnBHi.js.map} +1 -1
- package/dist/{system-freeze-CEuTQzNu.js → system-freeze-CY4Hc9WX.js} +2 -2
- package/dist/{system-freeze-CEuTQzNu.js.map → system-freeze-CY4Hc9WX.js.map} +1 -1
- package/dist/tui.js +15 -15
- package/dist/{version-CU8ppdCQ.js → version-Bu3Nc8-U.js} +2 -2
- package/dist/{version-CU8ppdCQ.js.map → version-Bu3Nc8-U.js.map} +1 -1
- package/dist/{wire-GwOPpxJg.js → wire-BKcREhuL.js} +2 -2
- package/dist/{wire-GwOPpxJg.js.map → wire-BKcREhuL.js.map} +1 -1
- package/dist/{ws-CqlZkB4w.js → ws-DriNRyP-.js} +4 -4
- package/dist/{ws-CqlZkB4w.js.map → ws-DriNRyP-.js.map} +1 -1
- package/dist/{ws-client-Bn_asPwE.js → ws-client-PZdbO0fj.js} +2 -2
- package/dist/{ws-client-Bn_asPwE.js.map → ws-client-PZdbO0fj.js.map} +1 -1
- package/docs/RELEASE.md +1 -1
- package/package.json +1 -1
package/dist/extensions.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { n as composeExtensionPreset, t as buildExtensionPreset } from "./compose-preset-1td8qO5b.js";
|
|
2
2
|
import { r as isJson } from "./json-BjClr43H.js";
|
|
3
|
-
import { $ as SidebarDecoration, $t as DisposedError, A as projectStorageFolder, C as createFileStoragePort, F as createFacetRegistry, G as LinkHandler, H as BadgeAction, I as MAX_SLOT_BADGES, J as Panel, K as Menu, L as UI_TOKEN_NAMES, M as MAX_FACETS_PER_EXTENSION, N as MAX_FACET_BYTES, P as SESSION_FACET_TRIGGERS, Q as SettingsPage, St as builtinKeymapEntries, U as ContextSection, V as wireWithSettingsPages, W as DialogTimeoutError, X as Renderer, Y as Reference, Z as Screen, _ as createMemorySettingsPort, _t as mergeWireSettings, at as Space, b as createScriptedDialogPort, c as extensionSettingsWire, d as touchesSettingsPages, et as SidebarFilter, f as EMPTY_MCP_PORT, g as NO_UI_CLIENT_PORT, gt as createWorkspaceSurface, h as NO_INTEGRATION_FLOWS, it as Slot, j as FACET_COMPUTE_TIMEOUT_MS, l as onSettingsPagesChanged, m as NO_CLIENT_DIALOG_PORT, mt as createExtensionHostRuntimeBridge, n as MAX_SIDEBAR_ROWS, nt as SidebarRow, o as LINK_SOURCES, ot as ThemeToken, p as MEMORY_CLIENT_ID, pt as createArtifactsSurface, q as NoUiError, rt as SidebarSort, s as MAX_LINK_URL_LENGTH, st as Webview, t as MAX_COMPOSER_BADGES, tt as SidebarGroup, u as runtimeSettingsWire, v as createMemoryStoragePort, xt as withSettingsPages, y as createRecordingUiClientPort } from "./registry-
|
|
3
|
+
import { $ as SidebarDecoration, $t as DisposedError, A as projectStorageFolder, C as createFileStoragePort, F as createFacetRegistry, G as LinkHandler, H as BadgeAction, I as MAX_SLOT_BADGES, J as Panel, K as Menu, L as UI_TOKEN_NAMES, M as MAX_FACETS_PER_EXTENSION, N as MAX_FACET_BYTES, P as SESSION_FACET_TRIGGERS, Q as SettingsPage, St as builtinKeymapEntries, U as ContextSection, V as wireWithSettingsPages, W as DialogTimeoutError, X as Renderer, Y as Reference, Z as Screen, _ as createMemorySettingsPort, _t as mergeWireSettings, at as Space, b as createScriptedDialogPort, c as extensionSettingsWire, d as touchesSettingsPages, et as SidebarFilter, f as EMPTY_MCP_PORT, g as NO_UI_CLIENT_PORT, gt as createWorkspaceSurface, h as NO_INTEGRATION_FLOWS, it as Slot, j as FACET_COMPUTE_TIMEOUT_MS, l as onSettingsPagesChanged, m as NO_CLIENT_DIALOG_PORT, mt as createExtensionHostRuntimeBridge, n as MAX_SIDEBAR_ROWS, nt as SidebarRow, o as LINK_SOURCES, ot as ThemeToken, p as MEMORY_CLIENT_ID, pt as createArtifactsSurface, q as NoUiError, rt as SidebarSort, s as MAX_LINK_URL_LENGTH, st as Webview, t as MAX_COMPOSER_BADGES, tt as SidebarGroup, u as runtimeSettingsWire, v as createMemoryStoragePort, xt as withSettingsPages, y as createRecordingUiClientPort } from "./registry-DTotchq6.js";
|
|
4
4
|
import { t as createArtifactDetectHook } from "./artifact-detect-BkDNUhfB.js";
|
|
5
5
|
import { B as githubTokenSource, C as viewForIssueRead, P as clockTime, S as pullStateLook, _ as isPullFresh, a as BUILTIN_REFERENCE_PROVIDERS, b as pullFromMeta, c as GITHUB_PULL_PROVIDER_ID, d as githubIssueView, f as githubPullReferenceProvider, g as githubRefKey, h as githubRateLimitText, i as isBadgeColor, l as fetchGithubPullRequest, m as githubPullView, n as ARTIFACT_BADGES_MAX, o as GITHUB_ISSUE_PROVIDER_ID, p as githubPullUrl, r as EMPTY_EXTENSION_REGISTRY, s as GITHUB_PULL_COLORS, u as githubIssueReferenceProvider, v as parseGithubRefKey, w as viewForRead, x as pullMeta, y as pullChecks } from "./row-fields-CAYcZogp.js";
|
|
6
6
|
import { a as commitKind, c as pullRequestKind, d as resolveArtifactKind, f as sessionBadges, i as branchKind, l as refreshArtifact, n as BUILTIN_ARTIFACT_KINDS, o as fileKind, p as sessionsBadges, r as artifactKindLabel, s as parseShortstat, u as renderArtifactRow } from "./builtin-artifact-kinds-DsqaAQjX.js";
|
|
7
7
|
import { A as panelShowsIn, B as badgeMenu, C as isExtensionPanelScope, D as normalizePanelLoadContext, E as normalizePanelHomeLayout, G as mergeBadgeMenu, H as builtinBadgeActions, J as runBadgeAction, K as normalizeBadgeEffect, M as panelViewValue, N as panelViewValues, O as panelBadgeText, P as resolvePanelLoadContext, S as PANEL_CONTENT_LIMITS, T as normalizePanelContent, U as builtinBadgeEffect, V as badgePromptText, W as extensionBadgeActions, Y as sessionBadgeTarget, a as referenceProviders, d as querySessions, i as referenceProviderWires, j as panelSurfaces, k as panelOnSurface, n as createReferenceResolver, q as normalizeBadgeTarget, r as findReferences, s as escapeTemplate, t as compileReferencePattern, w as isPanelSurface, x as SessionQueryError, y as compileQuery, z as artifactBadgeTarget } from "./references-BEKthBnn.js";
|
|
8
|
-
import { _ as precompileExtension, b as defineExtension, c as inlineLoadedExtension, d as parseExtensionScanPathEnv, g as COMPILE_CACHE_MAX_AGE_MS, i as discoverExtensions, l as loadExtensionFolder, m as scanExtensionDirectories, n as defaultExtensionScanPaths, t as ENTRY_CANDIDATES, u as loadableExtensionDirs, v as pruneExtensionCompileCache, y as EXTENSION_API_VERSION } from "./discovery-
|
|
8
|
+
import { _ as precompileExtension, b as defineExtension, c as inlineLoadedExtension, d as parseExtensionScanPathEnv, g as COMPILE_CACHE_MAX_AGE_MS, i as discoverExtensions, l as loadExtensionFolder, m as scanExtensionDirectories, n as defaultExtensionScanPaths, t as ENTRY_CANDIDATES, u as loadableExtensionDirs, v as pruneExtensionCompileCache, y as EXTENSION_API_VERSION } from "./discovery-D7qVZWzq.js";
|
|
9
9
|
import { a as registerExtensionApiHostModules, i as missingHostModuleSpecifiers, n as coreExtensionHostModules, o as registerExtensionHostModules, r as hostModuleSpecifiers, t as HOST_MODULE_SPECIFIERS } from "./host-modules-C2GGiSjg.js";
|
|
10
|
-
import { a as runtimeLoadedExtension, i as runtimeEntryOf, n as isRuntimeLoadedExtension } from "./loaded-entry-
|
|
11
|
-
import { $ as toWireConfigSchema, A as removeInstalledExtension, B as createRegistryViewSource, C as extensionSourceLabel, D as parseExtensionInstallSource, E as listExtensionCandidates, F as extensionRuntimeOf, G as runExtensionAction, I as filterExtensionRegistry, J as isValidExtensionConfigItem, K as clampExtensionConfigNumber, L as filterRegistryPlugins, M as reloadChangedExtensions, N as buildExtensionRegistry, O as readExtensionInstallOrigin, P as disposeExtensionRegistry, Q as sanitizeExtensionConfigActionPatch, R as partitionExtensionCatalog, S as changeExtensionOrigin, T as installExtensionFromSpec, U as listActionSummaries, V as extensionConfigSettingsPort, W as probeActionStatuses, X as resolveExtensionConfig, Y as isValidExtensionConfigValue, Z as resolveExtensionConfigValue, _ as configSyncFailures, a as listExtensionPaletteItems, at as suggestCompletionItems, b as loadExtensionsConfig, c as panelSummaries, ct as UI_HOST_MODULES, d as subscribeExtensionPalette, et as COMPLETION_TIMEOUT_MS, f as subscribeExtensionPanel, g as applyExtensionsConfigReport, h as createConfigSettingsLayer, i as createExtensionPromptBridge, it as resolveExtensionCompletionSubmit, j as updateInstalledExtension, k as readExtensionInstallProvenance, l as runExtensionPaletteItem, lt as classifyUiImport, m as discoverAndBuildExtensionRegistry, n as Contract, nt as completionProviderSummaries, o as loadExtensionPanel, ot as usableCompletionProviders, p as integrationMethodFromOAuthProvider, q as coerceExtensionConfigInput, r as Registry, rt as createCompletionRunner, s as panelHostRuntime, st as resolveUiEntries, t as createSharedWatches, tt as MAX_COMPLETION_ITEMS, u as runExtensionPanelAction, ut as isUiHostModule, v as configuredExtensions, w as fetchExtensionSource, x as ExtensionInstallError, y as createExtensionsConfigSync, z as createRegistryView } from "./extensions-
|
|
10
|
+
import { a as runtimeLoadedExtension, i as runtimeEntryOf, n as isRuntimeLoadedExtension } from "./loaded-entry-CLva6GQT.js";
|
|
11
|
+
import { $ as toWireConfigSchema, A as removeInstalledExtension, B as createRegistryViewSource, C as extensionSourceLabel, D as parseExtensionInstallSource, E as listExtensionCandidates, F as extensionRuntimeOf, G as runExtensionAction, I as filterExtensionRegistry, J as isValidExtensionConfigItem, K as clampExtensionConfigNumber, L as filterRegistryPlugins, M as reloadChangedExtensions, N as buildExtensionRegistry, O as readExtensionInstallOrigin, P as disposeExtensionRegistry, Q as sanitizeExtensionConfigActionPatch, R as partitionExtensionCatalog, S as changeExtensionOrigin, T as installExtensionFromSpec, U as listActionSummaries, V as extensionConfigSettingsPort, W as probeActionStatuses, X as resolveExtensionConfig, Y as isValidExtensionConfigValue, Z as resolveExtensionConfigValue, _ as configSyncFailures, a as listExtensionPaletteItems, at as suggestCompletionItems, b as loadExtensionsConfig, c as panelSummaries, ct as UI_HOST_MODULES, d as subscribeExtensionPalette, et as COMPLETION_TIMEOUT_MS, f as subscribeExtensionPanel, g as applyExtensionsConfigReport, h as createConfigSettingsLayer, i as createExtensionPromptBridge, it as resolveExtensionCompletionSubmit, j as updateInstalledExtension, k as readExtensionInstallProvenance, l as runExtensionPaletteItem, lt as classifyUiImport, m as discoverAndBuildExtensionRegistry, n as Contract, nt as completionProviderSummaries, o as loadExtensionPanel, ot as usableCompletionProviders, p as integrationMethodFromOAuthProvider, q as coerceExtensionConfigInput, r as Registry, rt as createCompletionRunner, s as panelHostRuntime, st as resolveUiEntries, t as createSharedWatches, tt as MAX_COMPLETION_ITEMS, u as runExtensionPanelAction, ut as isUiHostModule, v as configuredExtensions, w as fetchExtensionSource, x as ExtensionInstallError, y as createExtensionsConfigSync, z as createRegistryView } from "./extensions-D7DeZNpn.js";
|
|
12
12
|
import { m as settingsSidebar, p as settingsSearchIndex } from "./palette-DhfYhvnx.js";
|
|
13
|
-
import { n as createCredentialsAuthStore } from "./auth-store-port-
|
|
13
|
+
import { n as createCredentialsAuthStore } from "./auth-store-port-CDJa8Q8U.js";
|
|
14
14
|
import { n as RpcCallError, t as Rpc } from "./rpc-Daec0xVh.js";
|
|
15
15
|
export { ARTIFACT_BADGES_MAX, BUILTIN_ARTIFACT_KINDS, BUILTIN_REFERENCE_PROVIDERS, BadgeAction, COMPILE_CACHE_MAX_AGE_MS, COMPLETION_TIMEOUT_MS, ContextSection, Contract, DialogTimeoutError, DisposedError, EMPTY_EXTENSION_REGISTRY, EMPTY_MCP_PORT, ENTRY_CANDIDATES, EXTENSION_API_VERSION, ExtensionInstallError, FACET_COMPUTE_TIMEOUT_MS, GITHUB_ISSUE_PROVIDER_ID, GITHUB_PULL_COLORS, GITHUB_PULL_PROVIDER_ID, HOST_MODULE_SPECIFIERS, LINK_SOURCES, LinkHandler, MAX_COMPLETION_ITEMS, MAX_COMPOSER_BADGES, MAX_FACETS_PER_EXTENSION, MAX_FACET_BYTES, MAX_LINK_URL_LENGTH, MAX_SIDEBAR_ROWS, MAX_SLOT_BADGES, MEMORY_CLIENT_ID, Menu, NO_CLIENT_DIALOG_PORT, NO_INTEGRATION_FLOWS, NO_UI_CLIENT_PORT, NoUiError, PANEL_CONTENT_LIMITS, Panel, Reference, Registry, Renderer, Rpc, RpcCallError, SESSION_FACET_TRIGGERS, Screen, SessionQueryError, SettingsPage, SidebarDecoration, SidebarFilter, SidebarGroup, SidebarRow, SidebarSort, Slot, Space, ThemeToken, UI_HOST_MODULES, UI_TOKEN_NAMES, Webview, applyExtensionsConfigReport, artifactBadgeTarget, artifactKindLabel, badgeMenu, badgePromptText, branchKind, buildExtensionPreset, buildExtensionRegistry, builtinBadgeActions, builtinBadgeEffect, builtinKeymapEntries, changeExtensionOrigin, clampExtensionConfigNumber, classifyUiImport, clockTime, coerceExtensionConfigInput, commitKind, compileQuery, compileReferencePattern, completionProviderSummaries, composeExtensionPreset, configSyncFailures, configuredExtensions, coreExtensionHostModules, createArtifactDetectHook, createArtifactsSurface, createCompletionRunner, createConfigSettingsLayer, createCredentialsAuthStore, createExtensionHostRuntimeBridge, createExtensionPromptBridge, createExtensionsConfigSync, createFacetRegistry, createFileStoragePort, createMemorySettingsPort, createMemoryStoragePort, createRecordingUiClientPort, createReferenceResolver, createRegistryView, createRegistryViewSource, createScriptedDialogPort, createSharedWatches, createWorkspaceSurface, defaultExtensionScanPaths, defineExtension, discoverAndBuildExtensionRegistry, discoverExtensions, disposeExtensionRegistry, escapeTemplate, extensionBadgeActions, extensionConfigSettingsPort, extensionRuntimeOf, extensionSettingsWire, extensionSourceLabel, fetchExtensionSource, fetchGithubPullRequest, fileKind, filterExtensionRegistry, filterRegistryPlugins, findReferences, githubIssueReferenceProvider, githubIssueView, githubPullReferenceProvider, githubPullUrl, githubPullView, githubRateLimitText, githubRefKey, githubTokenSource, hostModuleSpecifiers, inlineLoadedExtension, installExtensionFromSpec, integrationMethodFromOAuthProvider, isBadgeColor, isExtensionPanelScope, isJson, isPanelSurface, isPullFresh, isRuntimeLoadedExtension, isUiHostModule, isValidExtensionConfigItem, isValidExtensionConfigValue, listActionSummaries, listExtensionCandidates, listExtensionPaletteItems, loadExtensionFolder, loadExtensionPanel, loadExtensionsConfig, loadableExtensionDirs, mergeBadgeMenu, mergeWireSettings, missingHostModuleSpecifiers, normalizeBadgeEffect, normalizeBadgeTarget, normalizePanelContent, normalizePanelHomeLayout, normalizePanelLoadContext, onSettingsPagesChanged, panelBadgeText, panelHostRuntime, panelOnSurface, panelShowsIn, panelSummaries, panelSurfaces, panelViewValue, panelViewValues, parseExtensionInstallSource, parseExtensionScanPathEnv, parseGithubRefKey, parseShortstat, partitionExtensionCatalog, precompileExtension, probeActionStatuses, projectStorageFolder, pruneExtensionCompileCache, pullChecks, pullFromMeta, pullMeta, pullRequestKind, pullStateLook, querySessions, readExtensionInstallOrigin, readExtensionInstallProvenance, referenceProviderWires, referenceProviders, refreshArtifact, registerExtensionApiHostModules, registerExtensionHostModules, reloadChangedExtensions, removeInstalledExtension, renderArtifactRow, resolveArtifactKind, resolveExtensionCompletionSubmit, resolveExtensionConfig, resolveExtensionConfigValue, resolvePanelLoadContext, resolveUiEntries, runBadgeAction, runExtensionAction, runExtensionPaletteItem, runExtensionPanelAction, runtimeEntryOf, runtimeLoadedExtension, runtimeSettingsWire, sanitizeExtensionConfigActionPatch, scanExtensionDirectories, sessionBadgeTarget, sessionBadges, sessionsBadges, settingsSearchIndex, settingsSidebar, subscribeExtensionPalette, subscribeExtensionPanel, suggestCompletionItems, toWireConfigSchema, touchesSettingsPages, updateInstalledExtension, usableCompletionProviders, viewForIssueRead, viewForRead, wireWithSettingsPages, withSettingsPages };
|
|
@@ -3,7 +3,7 @@ import { n as assertResolvedMediaBlock } from "./types-myxheQkw.js";
|
|
|
3
3
|
import { B as lookupModel, F as fillEstimatedCost, T as sanitizeToolSpecs, V as mergeCatalogEntry, W as systemNotesAsText, X as unsupportedMediaError, g as createToolNameBoundary, h as userMessage, m as toolResultsMessage, o as assistantMessage } from "./openai-compat-Odgmd5bB.js";
|
|
4
4
|
import { renderSystemForWire } from "./prompt.js";
|
|
5
5
|
import { c as reasoningWireAction } from "./messages-kX7YJXHU.js";
|
|
6
|
-
import { t as ZIDANE_VERSION } from "./version-
|
|
6
|
+
import { t as ZIDANE_VERSION } from "./version-Bu3Nc8-U.js";
|
|
7
7
|
import { r as googleTokenRequest, t as GOOGLE_VERTEX_OAUTH_ID } from "./google-oauth-g3JmRoJ-.js";
|
|
8
8
|
import { a as pinnedAccountMissingError, l as resolveOAuthApiKey, o as readAccountOAuthCredential, s as readOAuthCredentials } from "./oauth-HKL8zPcd.js";
|
|
9
9
|
import { a as imageHttpError, o as repeatRequest, r as imageCount } from "./wire-DH77Z-rr.js";
|
|
@@ -1333,4 +1333,4 @@ function googleVertex(params) {
|
|
|
1333
1333
|
//#endregion
|
|
1334
1334
|
export { googleCompatible as a, resolveVertexAuth as c, google as i, GOOGLE_IMAGE_MODELS as l, GOOGLE_EXTRA_MODELS as n, googleVertex as o, classifyGoogleError as r, resolveGoogleModel as s, GOOGLE_DEFAULT_MODEL as t, toGeminiContents as u };
|
|
1335
1335
|
|
|
1336
|
-
//# sourceMappingURL=google-
|
|
1336
|
+
//# sourceMappingURL=google-D1zjAViO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-Bzt7uvy9.js","names":["catalogLookup"],"sources":["../src/providers/gemini/errors.ts","../src/providers/gemini/request.ts","../src/providers/gemini/stream.ts","../src/providers/gemini/vertex-auth.ts","../src/providers/images/google.ts","../src/providers/google.ts"],"sourcesContent":["/**\n * Google's HTTP errors, as the Google providers throw them: the innermost\n * message, prefixed with its HTTP and RPC status, with `status` and the\n * raw `body` on the error.\n */\n\ninterface GoogleErrorBody { error?: { code?: unknown, message?: unknown, status?: unknown } }\n\n/** A Google error object in `text`: `{ \"error\": … }`, or the first of an array of them (Vertex streams). */\nfunction parseGoogleErrorBody(text: string): GoogleErrorBody['error'] | undefined {\n try {\n let parsed = JSON.parse(text) as GoogleErrorBody | GoogleErrorBody[] | null\n if (Array.isArray(parsed))\n parsed = parsed[0] ?? null\n return parsed && typeof parsed.error === 'object' && parsed.error ? parsed.error : undefined\n }\n catch {\n return undefined\n }\n}\n\n/** The HTTP status a message starts with (`429: …`). */\nexport function leadingStatus(message: string): number | undefined {\n const match = /^(\\d{3})\\b/.exec(message)\n return match ? Number(match[1]) : undefined\n}\n\n/**\n * The message, status and body of a Google error text. A proxy's non-JSON\n * body arrives wrapped as `{\"error\":{\"message\":\"<body>\"}}`, so Google's own\n * `{\"error\":{…}}` can sit JSON-encoded inside another one.\n *\n * @param raw - `<status>: <body>`, or a JSON error body.\n * @returns The innermost message prefixed with its HTTP and RPC status, the\n * status, and the innermost body (it carries details such as `retryDelay`).\n */\nexport function unwrapGoogleError(raw: string): { message: string, status?: number, body?: string } {\n let status = leadingStatus(raw)\n let rpcStatus: string | undefined\n let text = status === undefined ? raw : raw.replace(/^\\d{3}:\\s*/, '')\n let message: string | undefined\n let body = raw\n for (let error = parseGoogleErrorBody(text); error; error = parseGoogleErrorBody(text)) {\n body = text\n if (typeof error.code === 'number')\n status = error.code\n if (typeof error.status === 'string' && /^[A-Z_]+$/.test(error.status))\n rpcStatus = error.status\n if (typeof error.message !== 'string')\n break\n message = text = error.message.trim()\n }\n if (!message)\n return { message: raw, ...(status !== undefined ? { status } : {}) }\n const prefix = [status, rpcStatus].filter(part => part !== undefined).join(' ')\n return { message: prefix ? `${prefix}: ${message}` : message, ...(status !== undefined ? { status } : {}), body }\n}\n\n/** An error carrying Google's message, HTTP status and body. */\nexport function googleError(raw: string): Error & { status?: number, body?: string } {\n const { message, ...details } = unwrapGoogleError(raw)\n return Object.assign(new Error(message), details)\n}\n\n/**\n * The error for a non-2xx answer. A JSON body is read as Google's; any\n * other body (a proxy's HTML page) is wrapped with the status, the way\n * Google's SDK reports it.\n *\n * @param response - The failed response.\n */\nexport async function googleHttpError(response: Response): Promise<Error> {\n const text = await response.text().catch(() => '')\n const json = response.headers.get('content-type')?.includes('application/json')\n let body = text\n if (json) {\n try {\n body = JSON.stringify(JSON.parse(text))\n }\n catch {\n body = JSON.stringify({ error: { message: text, code: response.status, status: response.statusText } })\n }\n }\n else {\n body = JSON.stringify({ error: { message: text, code: response.status, status: response.statusText } })\n }\n const error = googleError(body)\n if (error.status === undefined)\n error.status = response.status\n return error\n}\n\n/** An error named `AbortError`, so it classifies as an abort. */\nexport function abortError(message = 'Request was aborted'): Error {\n return Object.assign(new Error(message), { name: 'AbortError' })\n}\n","/**\n * Session messages, tools and settings to a Gemini `GenerateContentRequest`.\n *\n * Thought signatures replay only to the scope that issued them: an\n * assistant turn holding this scope's signatures is sent as the target\n * model's own (its signed thoughts, text and calls as received, model\n * switches included: Google accepts them across its models), and every other\n * turn goes unsigned, its reasoning dropped and, for models that pair calls\n * by id, its call ids normalized.\n */\nimport type { StreamOptions } from '..'\nimport type { GeminiSignatureScope, SessionContentBlock, SessionMessage } from '../../types'\nimport type { GeminiBlob, GeminiContent, GeminiFunctionDeclaration, GeminiPart, GeminiRequest, GeminiThinkingConfig, GoogleWireModel } from './types'\nimport { unsupportedMediaError } from '../../prompt'\nimport { reasoningWireAction, SYNTHETIC_TOOL_RESULT_PLACEHOLDER } from '../../session/messages'\nimport { systemNotesAsText } from '../../system-notes'\nimport { assertResolvedMediaBlock } from '../../types'\n\n/** A tool as `formatTools` hands it to the request: name, description, JSON Schema. */\nexport interface GeminiTool {\n /** Function name on the wire. */\n name: string\n /** What it does. */\n description: string\n /** JSON Schema of its arguments. */\n parameters: Record<string, unknown>\n}\n\n/** Which thinking-budget table a route uses for Gemini 2.5 levels. */\nexport type GeminiBudgetTable = 'gemini-api' | 'vertex'\n\n/** Inputs of {@link buildGeminiRequest}. */\nexport interface GeminiRequestInput {\n /** Session messages, tool names already on the wire. */\n messages: SessionMessage[]\n /** Target model. */\n model: GoogleWireModel\n /** Signature scope of the target: the only scope whose signatures replay. */\n scope: GeminiSignatureScope\n /** Provider named in unsupported-media errors. */\n provider: string\n /** System prompt, rendered for the wire. */\n system: string\n /** Tools, names on the wire. */\n tools: readonly GeminiTool[]\n /** Requested thinking level. */\n thinking?: StreamOptions['thinking']\n /** Exact thinking budget (Gemini 2.5 models). */\n thinkingBudget?: number\n /** Requested output ceiling; the model's when unset. */\n maxTokens?: number\n /** Forced tool choice. */\n toolChoice?: StreamOptions['toolChoice']\n /** Canonical tool name to its wire name. */\n toWire?: (name: string) => string\n /** Budget table for Gemini 2.5 levels. */\n budgets: GeminiBudgetTable\n}\n\n/** Unpaired surrogates make Google reject the JSON. */\nexport function sanitizeSurrogates(text: string): string {\n return text.replace(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g, '')\n}\n\nfunction geminiMajorVersion(modelId: string): number | undefined {\n const match = /^gemini(?:-live)?-(\\d+)/.exec(modelId.toLowerCase())\n return match ? Number.parseInt(match[1]!, 10) : undefined\n}\n\n/**\n * Whether the model needs ids on function calls and responses: Gemini 3+,\n * and Claude / GPT-OSS behind Gemini-wire backends.\n *\n * @param modelId - Model id on the wire.\n */\nexport function requiresToolCallId(modelId: string): boolean {\n const major = geminiMajorVersion(modelId)\n return modelId.startsWith('claude-') || modelId.startsWith('gpt-oss-') || (major !== undefined && major >= 3)\n}\n\n/** Gemini before 3 takes no media inside a function response; other families do. */\nfunction supportsMultimodalFunctionResponse(modelId: string): boolean {\n const major = geminiMajorVersion(modelId)\n return major === undefined || major >= 3\n}\n\nconst BASE64_SIGNATURE_RE = /^[A-Z0-9+/]+={0,2}$/i\n\n/** Google types signatures as bytes: anything that isn't base64 would 400. */\nfunction validSignature(signature: string | undefined): string | undefined {\n return signature && signature.length % 4 === 0 && BASE64_SIGNATURE_RE.test(signature) ? signature : undefined\n}\n\nconst USER_IMAGE_PLACEHOLDER = '(image omitted: model does not support images)'\nconst TOOL_IMAGE_PLACEHOLDER = '(tool image omitted: model does not support images)'\n\n/** Builds parts, folding a run of images into one placeholder when the model has no vision. */\nfunction mediaParts(vision: boolean, placeholder: string) {\n const parts: GeminiPart[] = []\n let lastWasPlaceholder = false\n return {\n parts,\n text(text: string) {\n parts.push({ text })\n lastWasPlaceholder = text === placeholder\n },\n image(blob: GeminiBlob) {\n if (vision) {\n parts.push({ inlineData: blob })\n lastWasPlaceholder = false\n }\n else if (!lastWasPlaceholder) {\n parts.push({ text: placeholder })\n lastWasPlaceholder = true\n }\n },\n }\n}\n\nfunction userParts(content: SessionContentBlock[], model: GoogleWireModel, provider: string): GeminiPart[] {\n for (const block of content) {\n if (block.type === 'audio')\n throw unsupportedMediaError('audio', provider)\n if (block.type === 'video')\n throw unsupportedMediaError('video', provider)\n }\n const out = mediaParts(model.input.includes('image'), USER_IMAGE_PLACEHOLDER)\n for (const block of content) {\n if (block.type === 'text') {\n out.text(sanitizeSurrogates(block.text))\n }\n else if (block.type === 'image') {\n assertResolvedMediaBlock(block, 'Google wire messages')\n out.image({ mimeType: block.mediaType, data: block.data })\n }\n else if (block.type === 'document') {\n assertResolvedMediaBlock(block, 'Google wire messages')\n // A file part: PDFs and other files go as inline bytes, text as text.\n if (block.encoding === 'base64')\n out.parts.push({ inlineData: { mimeType: block.mediaType, data: block.data } })\n else out.text(sanitizeSurrogates(block.data))\n }\n }\n return out.parts\n}\n\ntype ToolResultBlock = Extract<SessionContentBlock, { type: 'tool_result' }>\n\n/** A tool result's text (joined by newlines), and its media: images and files. */\nfunction toolResultParts(result: ToolResultBlock, model: GoogleWireModel, provider: string): { text: string, media: GeminiBlob[], images: boolean } {\n if (typeof result.output === 'string')\n return { text: result.output, media: [], images: false }\n const vision = model.input.includes('image')\n const texts: string[] = []\n const media: GeminiBlob[] = []\n let images = false\n let lastWasPlaceholder = false\n for (const block of result.output) {\n if (block.type === 'audio')\n throw unsupportedMediaError('audio', provider)\n if (block.type === 'video')\n throw unsupportedMediaError('video', provider)\n if (block.type === 'image') {\n assertResolvedMediaBlock(block, 'Google wire messages')\n if (vision) {\n media.push({ mimeType: block.mediaType, data: block.data })\n images = true\n }\n else if (!lastWasPlaceholder) {\n texts.push(TOOL_IMAGE_PLACEHOLDER)\n lastWasPlaceholder = true\n }\n continue\n }\n if (block.type === 'document') {\n assertResolvedMediaBlock(block, 'Google wire messages')\n if (block.encoding === 'base64')\n media.push({ mimeType: block.mediaType, data: block.data })\n else texts.push(block.data)\n lastWasPlaceholder = false\n continue\n }\n texts.push(block.text)\n lastWasPlaceholder = block.text === TOOL_IMAGE_PLACEHOLDER\n }\n return { text: texts.join('\\n'), media, images }\n}\n\n/**\n * Converts session messages to Gemini `contents`.\n *\n * An assistant turn stays whole: Gemini signs only the FIRST function call\n * of a parallel step, so splitting the calls into separate model turns would\n * leave the others unsigned. Its results follow in call order, in one user\n * turn, with the synthetic placeholder for any the history lost.\n *\n * @param messages - Session messages, tool names already on the wire.\n * @param model - Target model.\n * @param scope - Signature scope of the target.\n * @param provider - Provider named in unsupported-media errors. Defaults to `scope`.\n */\nexport function toGeminiContents(messages: SessionMessage[], model: GoogleWireModel, scope: GeminiSignatureScope, provider: string = scope): GeminiContent[] {\n // System notes have no native slot on this wire: send them as `<system-reminder>` text.\n messages = systemNotesAsText(messages)\n const withIds = requiresToolCallId(model.id)\n const multimodal = supportsMultimodalFunctionResponse(model.id)\n /** Call ids rewritten in foreign turns, so their results still pair. */\n const ids = new Map<string, string>()\n const contents: GeminiContent[] = []\n\n const pushResult = (result: ToolResultBlock, name: string): void => {\n const { text, media, images } = toolResultParts(result, model, provider)\n const id = ids.get(result.callId) ?? result.callId\n const value = text.length > 0 ? sanitizeSurrogates(text) : media.length > 0 ? (images ? '(see attached image)' : '(see attached file)') : ''\n const part: GeminiPart = {\n functionResponse: {\n name,\n response: result.isError ? { error: value } : { output: value },\n ...(media.length > 0 && multimodal ? { parts: media.map(blob => ({ inlineData: blob })) } : {}),\n ...(withIds ? { id } : {}),\n },\n }\n // All of a step's function responses go in one user turn.\n const last = contents.at(-1)\n if (last?.role === 'user' && last.parts.some(p => p.functionResponse))\n last.parts.push(part)\n else contents.push({ role: 'user', parts: [part] })\n if (media.length > 0 && !multimodal)\n contents.push({ role: 'user', parts: [{ text: 'Tool result image:' }, ...media.map(blob => ({ inlineData: blob }))] })\n }\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]!\n if (msg.role !== 'assistant') {\n const parts = userParts(msg.content.filter(b => b.type !== 'tool_result'), model, provider)\n if (parts.length > 0)\n contents.push({ role: 'user', parts })\n continue\n }\n\n const parts = assistantParts(msg.content, scope, withIds, ids)\n if (parts.length > 0)\n contents.push({ role: 'model', parts })\n const calls = msg.content.filter((b): b is Extract<SessionContentBlock, { type: 'tool_call' }> => b.type === 'tool_call')\n if (calls.length === 0)\n continue\n const next = messages[i + 1]\n const results = new Map(\n (next?.role === 'user' ? next.content : [])\n .filter((b): b is ToolResultBlock => b.type === 'tool_result')\n .map(r => [r.callId, r]),\n )\n for (const call of calls)\n pushResult(results.get(call.id) ?? { type: 'tool_result', callId: call.id, output: SYNTHETIC_TOOL_RESULT_PLACEHOLDER, isError: true }, call.name)\n if (next?.role === 'user') {\n // Results whose call isn't in the turn above were removed by the\n // canonical pairing repair; never send one unpaired.\n const rest = userParts(next.content.filter(b => b.type !== 'tool_result'), model, provider)\n if (rest.length > 0)\n contents.push({ role: 'user', parts: rest })\n i++\n }\n }\n return contents\n}\n\nfunction assistantParts(content: SessionContentBlock[], scope: GeminiSignatureScope, withIds: boolean, ids: Map<string, string>): GeminiPart[] {\n const native = content.some(block =>\n (block.type === 'text' || block.type === 'tool_call' || block.type === 'thinking')\n && block.signature !== undefined\n && block.signatureProducer === scope)\n const own = (block: { signature?: string, signatureProducer?: string }): string | undefined =>\n native && block.signatureProducer === scope ? validSignature(block.signature) : undefined\n\n const parts: GeminiPart[] = []\n for (const block of content) {\n if (block.type === 'text') {\n const signature = own(block)\n // An empty part that carries a signature must still be echoed back.\n if (!block.text.trim() && !signature)\n continue\n parts.push({ text: sanitizeSurrogates(block.text), ...(signature ? { thoughtSignature: signature } : {}) })\n }\n else if (block.type === 'thinking') {\n // Reasoning from any other producer or model is dropped: sent as text,\n // the model would take it for part of its visible reply.\n if (!native)\n continue\n const action = reasoningWireAction(block, scope)\n if (action === 'drop')\n continue\n const signature = action === 'keep' ? own(block) : undefined\n if (!block.text.trim() && !signature)\n continue\n parts.push({ thought: true, text: sanitizeSurrogates(block.text), ...(signature ? { thoughtSignature: signature } : {}) })\n }\n else if (block.type === 'tool_call') {\n const signature = own(block)\n let id = block.id\n if (!native && withIds) {\n id = block.id.replace(/[^\\w-]/g, '_').slice(0, 64)\n if (id !== block.id)\n ids.set(block.id, id)\n }\n parts.push({\n functionCall: { name: block.name, args: block.input ?? {}, ...(withIds ? { id } : {}) },\n ...(signature ? { thoughtSignature: signature } : {}),\n })\n }\n // `redacted_thinking`, `provider_reasoning` and server-tool blocks belong\n // to other providers' wires.\n }\n return parts\n}\n\n/** Function declarations for the request (full JSON Schema). */\nexport function toFunctionDeclarations(tools: readonly GeminiTool[]): GeminiFunctionDeclaration[] {\n return tools.map(tool => ({ name: tool.name, description: tool.description, parametersJsonSchema: tool.parameters }))\n}\n\n// ---------------------------------------------------------------------------\n// Thinking\n// ---------------------------------------------------------------------------\n\nconst LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const\ntype Level = (typeof LEVELS)[number]\ntype GeminiLevel = 'minimal' | 'low' | 'medium' | 'high'\n\nfunction supportedLevels(model: GoogleWireModel): Level[] {\n if (!model.reasoning)\n return ['off']\n return LEVELS.filter((level) => {\n const mapped = model.thinkingLevelMap?.[level]\n if (mapped === null)\n return false\n return level === 'xhigh' || level === 'max' ? mapped !== undefined : true\n })\n}\n\n/** The level if the model has it, else the next higher one it has, else the next lower. */\nfunction clampLevel(model: GoogleWireModel, level: Level): Level {\n const available = supportedLevels(model)\n if (available.includes(level))\n return level\n const index = LEVELS.indexOf(level)\n for (let i = index; i < LEVELS.length; i++) {\n if (available.includes(LEVELS[i]!))\n return LEVELS[i]!\n }\n for (let i = index - 1; i >= 0; i--) {\n if (available.includes(LEVELS[i]!))\n return LEVELS[i]!\n }\n return available[0] ?? 'off'\n}\n\nfunction geminiLevel(model: GoogleWireModel, level: Level): GeminiLevel {\n const mapped = model.thinkingLevelMap?.[level]\n const resolved = typeof mapped === 'string' ? mapped.toLowerCase() : level\n if (resolved === 'minimal' || resolved === 'low' || resolved === 'medium' || resolved === 'high')\n return resolved\n throw new Error(`Unsupported Google thinking level mapping for ${model.provider}/${model.id}: ${level} -> ${String(mapped)}`)\n}\n\n/** Whether the model takes Gemini 3's discrete `thinkingLevel` rather than a token budget. */\nfunction usesThinkingLevel(model: GoogleWireModel): boolean {\n const id = model.id.toLowerCase()\n return /gemini-3(?:\\.\\d+)?-(?:pro|flash)/.test(id)\n || /gemini-(?:[4-9]|[1-3]\\d)/.test(id)\n || id === 'gemini-flash-latest'\n || id === 'gemini-flash-lite-latest'\n || /gemma-?4/.test(id)\n}\n\nconst BUDGETS: Record<GeminiBudgetTable, readonly [string, Record<GeminiLevel, number>][]> = {\n 'gemini-api': [\n ['2.5-pro', { minimal: 128, low: 2048, medium: 8192, high: 32768 }],\n ['2.5-flash-lite', { minimal: 512, low: 2048, medium: 8192, high: 24576 }],\n ['2.5-flash', { minimal: 128, low: 2048, medium: 8192, high: 24576 }],\n ],\n 'vertex': [\n ['2.5-pro', { minimal: 128, low: 2048, medium: 8192, high: 32768 }],\n ['2.5-flash', { minimal: 128, low: 2048, medium: 8192, high: 24576 }],\n ],\n}\n\n/** Thinking turned off: budget 0, or the lowest level on a model that can't stop thinking. */\nfunction disabledThinking(model: GoogleWireModel): GeminiThinkingConfig {\n if (!usesThinkingLevel(model))\n return { thinkingBudget: 0 }\n const fallback = clampLevel(model, 'off')\n if (fallback === 'off')\n return { thinkingBudget: 0 }\n return { thinkingLevel: geminiLevel(model, fallback).toUpperCase() as GeminiThinkingConfig['thinkingLevel'] }\n}\n\n/**\n * The `thinkingConfig` for a requested level, or `undefined` for a model\n * that doesn't think. `adaptive` turns thinking on with no level or budget:\n * the model thinks as much as it decides, with thought summaries. A level\n * clamps to what the model supports; Gemini 3+ takes it as `thinkingLevel`,\n * Gemini 2.5 as a token budget (`thinkingBudget` when set, else the route's\n * table, else `-1`, the model's own choice).\n *\n * @param model - Target model.\n * @param thinking - Requested level.\n * @param thinkingBudget - Exact budget.\n * @param budgets - The route's budget table.\n */\nexport function geminiThinkingConfig(model: GoogleWireModel, thinking: StreamOptions['thinking'], thinkingBudget: number | undefined, budgets: GeminiBudgetTable): GeminiThinkingConfig | undefined {\n if (!model.reasoning)\n return undefined\n if (thinking === 'adaptive')\n return { includeThoughts: true }\n if (!thinking || thinking === 'off')\n return disabledThinking(model)\n const clamped = clampLevel(model, thinking as Level)\n if (clamped === 'off')\n return disabledThinking(model)\n const level = geminiLevel(model, clamped)\n if (usesThinkingLevel(model))\n return { includeThoughts: true, thinkingLevel: level.toUpperCase() as GeminiThinkingConfig['thinkingLevel'] }\n const table = BUDGETS[budgets].find(([marker]) => model.id.includes(marker))?.[1]\n return { includeThoughts: true, thinkingBudget: thinkingBudget ?? table?.[level] ?? -1 }\n}\n\n// ---------------------------------------------------------------------------\n// Output ceiling\n// ---------------------------------------------------------------------------\n\nconst CHARS_PER_TOKEN = 3.5\nconst IMAGE_CHARS = 4800\nconst CONTEXT_SAFETY_TOKENS = 4096\n\n/** A rough size of the request: 3.5 characters a token, 4800 characters an image or file. */\nfunction estimateTokens(request: GeminiRequest): number {\n let tokens = 0\n const system = request.systemInstruction?.parts.map(p => p.text).join('') ?? ''\n tokens += Math.ceil(system.length / CHARS_PER_TOKEN)\n if (request.tools)\n tokens += Math.ceil(JSON.stringify(request.tools).length / CHARS_PER_TOKEN)\n for (const content of request.contents) {\n let chars = 0\n for (const part of content.parts) {\n if (part.text !== undefined)\n chars += part.text.length\n if (part.inlineData)\n chars += IMAGE_CHARS\n if (part.functionCall)\n chars += (part.functionCall.name ?? '').length + JSON.stringify(part.functionCall.args ?? {}).length\n if (part.functionResponse) {\n const response = part.functionResponse.response\n chars += ('output' in response ? response.output : response.error).length + IMAGE_CHARS * (part.functionResponse.parts?.length ?? 0)\n }\n }\n tokens += Math.ceil(chars / CHARS_PER_TOKEN)\n }\n return tokens\n}\n\n/** The requested ceiling, kept inside what the context window has left. */\nfunction maxOutputTokens(model: GoogleWireModel, request: GeminiRequest, requested: number): number {\n if (model.contextWindow <= 0)\n return Math.max(1, requested)\n const available = model.contextWindow - estimateTokens(request) - CONTEXT_SAFETY_TOKENS\n return Math.min(requested, Math.max(1, available))\n}\n\n// ---------------------------------------------------------------------------\n// Request\n// ---------------------------------------------------------------------------\n\n/**\n * Builds the `GenerateContentRequest` for one turn.\n *\n * @param input - Messages, model, scope, tools and settings.\n */\nexport function buildGeminiRequest(input: GeminiRequestInput): GeminiRequest {\n const { model } = input\n const request: GeminiRequest = { contents: toGeminiContents(input.messages, model, input.scope, input.provider) }\n if (input.system)\n request.systemInstruction = { role: 'user', parts: [{ text: sanitizeSurrogates(input.system) }] }\n if (input.tools.length > 0) {\n request.tools = [{ functionDeclarations: toFunctionDeclarations(input.tools) }]\n const choice = input.toolChoice\n if (choice && choice.type !== 'auto') {\n request.toolConfig = {\n functionCallingConfig: choice.type === 'tool' && choice.name\n ? { mode: 'ANY', allowedFunctionNames: [(input.toWire ?? (n => n))(choice.name)] }\n : { mode: 'ANY' },\n }\n }\n }\n const thinkingConfig = geminiThinkingConfig(model, input.thinking, input.thinkingBudget, input.budgets)\n request.generationConfig = {\n maxOutputTokens: maxOutputTokens(model, request, input.maxTokens ?? model.maxTokens),\n ...(thinkingConfig ? { thinkingConfig } : {}),\n }\n return request\n}\n","/**\n * Reading a `streamGenerateContent?alt=sse` answer: SSE events to response\n * chunks, chunks to one assistant turn.\n */\nimport type { StreamCallbacks } from '..'\nimport type { GeminiModelCost, GeminiResponseChunk, GeminiUsageMetadata } from './types'\nimport { abortError, googleError } from './errors'\n\n/**\n * The `data:` payloads of an SSE body, parsed as JSON. Events end at a\n * blank line (`\\n`, `\\r\\n` or `\\r` line ends); `[DONE]` is skipped.\n *\n * @param body - The response body.\n * @param signal - Aborts the read.\n */\nexport async function* readSseJson(body: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncGenerator<unknown> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n const onAbort = (): void => {\n void reader.cancel().catch(() => {})\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n let buffer = ''\n let data: string[] = []\n const flush = function* (): Generator<unknown> {\n if (data.length === 0)\n return\n const payload = data.join('\\n').trim()\n data = []\n if (!payload || payload === '[DONE]')\n return\n try {\n yield JSON.parse(payload) as unknown\n }\n catch {\n throw new Error(`Google sent a stream event that isn't JSON: ${payload.slice(0, 200)}`)\n }\n }\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (signal?.aborted)\n throw abortError()\n buffer += done ? decoder.decode() : decoder.decode(value, { stream: true })\n for (let end = buffer.search(/\\r\\n|\\r|\\n/); end >= 0; end = buffer.search(/\\r\\n|\\r|\\n/)) {\n // A lone `\\r` at the end may be the first half of `\\r\\n`: wait for more.\n if (!done && end === buffer.length - 1 && buffer[end] === '\\r')\n break\n const line = buffer.slice(0, end)\n buffer = buffer.slice(end + (buffer.startsWith('\\r\\n', end) ? 2 : 1))\n if (line === '')\n yield* flush()\n else if (line.startsWith('data:'))\n data.push(line.slice(5).replace(/^ /, ''))\n }\n if (done)\n break\n }\n if (buffer.startsWith('data:'))\n data.push(buffer.slice(5).replace(/^ /, ''))\n yield* flush()\n }\n finally {\n signal?.removeEventListener('abort', onAbort)\n reader.releaseLock()\n }\n}\n\n/**\n * A Gemini API / Vertex AI event as a response chunk. An in-stream\n * `{ \"error\": … }` throws with its status.\n *\n * @param payload - One parsed `data:` payload.\n */\nexport function parseGoogleChunk(payload: unknown): GeminiResponseChunk {\n const error = (payload as { error?: unknown } | null)?.error\n if (error && typeof error === 'object')\n throw googleError(JSON.stringify({ error }))\n return payload as GeminiResponseChunk\n}\n\n/** A block of the turn being streamed. */\nexport type GeminiTurnBlock\n = | { type: 'text', text: string, signature?: string }\n | { type: 'thinking', text: string, signature?: string }\n | { type: 'call', id: string, name: string, args: Record<string, unknown>, signature?: string }\n\n/** Token counts and cost of a turn, Gemini's counts mapped to zidane's. */\nexport interface GeminiTurnUsage {\n /** Uncached prompt tokens. */\n input: number\n /** Answer and thought tokens. */\n output: number\n /** Cached prompt tokens. */\n cacheRead: number\n /** Thought tokens. */\n reasoning: number\n /** Cost at the model's rates, in USD. */\n cost: number\n}\n\n/** What a streamed turn came to. */\nexport interface GeminiTurn {\n /** Blocks in arrival order. */\n blocks: GeminiTurnBlock[]\n /** Text as streamed. */\n text: string\n /** The finish reason as Gemini sent it. */\n finishReason: string\n /** Token counts and cost. */\n usage: GeminiTurnUsage\n}\n\n/**\n * Cost of a turn at the model's rates (long-context tiers included).\n *\n * @param cost - Rates per million tokens.\n * @param usage - Token counts.\n */\nexport function turnCost(cost: GeminiModelCost, usage: Pick<GeminiTurnUsage, 'input' | 'output' | 'cacheRead'>): number {\n const inputTokens = usage.input + usage.cacheRead\n let rates: Omit<GeminiModelCost, 'tiers'> = cost\n let threshold = -1\n for (const tier of cost.tiers ?? []) {\n if (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > threshold) {\n rates = tier\n threshold = tier.inputTokensAbove\n }\n }\n return (rates.input * usage.input + rates.output * usage.output + rates.cacheRead * usage.cacheRead) / 1_000_000\n}\n\nfunction usageOf(metadata: GeminiUsageMetadata, cost: GeminiModelCost): GeminiTurnUsage {\n const cached = metadata.cachedContentTokenCount ?? 0\n const usage = {\n input: (metadata.promptTokenCount ?? 0) - cached,\n output: (metadata.candidatesTokenCount ?? 0) + (metadata.thoughtsTokenCount ?? 0),\n cacheRead: cached,\n reasoning: metadata.thoughtsTokenCount ?? 0,\n }\n return { ...usage, cost: turnCost(cost, usage) }\n}\n\ntype TextBlock = Extract<GeminiTurnBlock, { type: 'text' | 'thinking' }>\n\nlet generatedIds = 0\n\n/**\n * Streams the chunks into one turn, calling back text, thoughts and call\n * progress as they arrive. Consecutive text (or thought) parts merge into\n * one block, keeping the last signature any of them carried; each function\n * call is its own block. Throws when the turn stopped for anything but\n * `STOP` or `MAX_TOKENS` (safety, recitation, a malformed call, …), when\n * it ended without a finish reason, and when it was aborted.\n *\n * @param chunks - Response chunks.\n * @param cost - The model's rates.\n * @param callbacks - Stream callbacks.\n * @param signal - The request's abort signal.\n */\nexport async function collectGeminiTurn(\n chunks: AsyncIterable<GeminiResponseChunk>,\n cost: GeminiModelCost,\n callbacks: Pick<StreamCallbacks, 'onText' | 'onThinking' | 'onToolCallDelta'>,\n signal?: AbortSignal,\n): Promise<GeminiTurn> {\n const blocks: GeminiTurnBlock[] = []\n let current: TextBlock | undefined\n let text = ''\n let finishReason: string | undefined\n let usage: GeminiTurnUsage = { input: 0, output: 0, cacheRead: 0, reasoning: 0, cost: 0 }\n\n for await (const chunk of chunks) {\n const candidate = chunk.candidates?.[0]\n for (const part of candidate?.content?.parts ?? []) {\n if (part.text !== undefined) {\n const kind = part.thought === true ? 'thinking' : 'text'\n let block = current?.type === kind ? current : undefined\n if (!block) {\n const fresh: TextBlock = kind === 'thinking' ? { type: 'thinking', text: '' } : { type: 'text', text: '' }\n blocks.push(fresh)\n current = block = fresh\n }\n block.text += part.text\n if (part.thoughtSignature)\n block.signature = part.thoughtSignature\n if (kind === 'thinking') {\n callbacks.onThinking?.(part.text)\n }\n else {\n text += part.text\n callbacks.onText(part.text)\n }\n }\n if (part.functionCall) {\n current = undefined\n const name = part.functionCall.name ?? ''\n const provided = part.functionCall.id\n const id = provided && !blocks.some(b => b.type === 'call' && b.id === provided)\n ? provided\n : `${name}_${Date.now()}_${++generatedIds}`\n blocks.push({ type: 'call', id, name, args: part.functionCall.args ?? {}, ...(part.thoughtSignature ? { signature: part.thoughtSignature } : {}) })\n // Liveness: the call started, and its arguments arrived.\n callbacks.onToolCallDelta?.()\n callbacks.onToolCallDelta?.()\n }\n }\n if (candidate?.finishReason)\n finishReason = candidate.finishReason\n if (chunk.usageMetadata)\n usage = usageOf(chunk.usageMetadata, cost)\n }\n\n if (signal?.aborted)\n throw abortError()\n if (!finishReason)\n throw new Error('Google stream ended without a finish reason')\n if (finishReason !== 'STOP' && finishReason !== 'MAX_TOKENS')\n throw new Error(`Provider stopped with: ${finishReason}`)\n return { blocks, text, finishReason, usage }\n}\n","/**\n * Google Cloud credentials for Vertex AI, without google-auth-library: the\n * Application Default Credentials chain zidane's users rely on.\n *\n * 1. A credentials file: `GOOGLE_APPLICATION_CREDENTIALS` (or the\n * provider's `credentialsFile`), else gcloud's\n * `application_default_credentials.json`. `authorized_user` files\n * refresh their token at Google's token endpoint; `service_account` files\n * sign a JWT (RS256) and exchange it.\n * 2. Without a file, the metadata server of the machine (Compute Engine,\n * Cloud Run, GKE).\n *\n * A token is minted per request, as before. Other credential types\n * (`external_account`, `impersonated_service_account`) are refused with a\n * clear error.\n */\nimport { Buffer } from 'node:buffer'\nimport { createSign } from 'node:crypto'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { googleTokenRequest } from '../google-oauth'\n\nconst CLOUD_PLATFORM_SCOPE = 'https://www.googleapis.com/auth/cloud-platform'\nconst DEFAULT_TOKEN_URI = 'https://oauth2.googleapis.com/token'\n/** The metadata server answers at once on Google Cloud; elsewhere the address doesn't route. */\nconst METADATA_TIMEOUT_MS = 3_000\nconst TOKEN_TIMEOUT_MS = 30_000\n\n/** A bearer token and the project its requests bill, when the credentials name one. */\nexport interface GoogleCloudToken {\n /** OAuth access token. */\n token: string\n /** `quota_project_id` of the credentials: sent as `x-goog-user-project`. */\n quotaProject?: string\n}\n\ninterface CredentialsFile {\n type?: string\n client_id?: string\n client_secret?: string\n refresh_token?: string\n quota_project_id?: string\n client_email?: string\n private_key?: string\n private_key_id?: string\n token_uri?: string\n}\n\n/** Where gcloud keeps the Application Default Credentials. */\nfunction wellKnownCredentialsFile(): string {\n const config = process.env.CLOUDSDK_CONFIG\n || (process.platform === 'win32' && process.env.APPDATA ? join(process.env.APPDATA, 'gcloud') : join(homedir(), '.config', 'gcloud'))\n return join(config, 'application_default_credentials.json')\n}\n\nfunction readCredentials(file: string): CredentialsFile {\n let text: string\n try {\n text = readFileSync(file, 'utf8')\n }\n catch (err) {\n throw new Error(`Can't read the Google Cloud credentials file ${file}: ${(err as Error).message}`, { cause: err })\n }\n try {\n return JSON.parse(text) as CredentialsFile\n }\n catch (err) {\n throw new Error(`The Google Cloud credentials file ${file} isn't JSON.`, { cause: err })\n }\n}\n\nfunction base64url(value: string | Buffer): string {\n return Buffer.from(value).toString('base64url')\n}\n\nasync function serviceAccountToken(creds: CredentialsFile, file: string, signal?: AbortSignal): Promise<string> {\n if (!creds.client_email || !creds.private_key)\n throw new Error(`The service account file ${file} has no client_email or private_key.`)\n const tokenUri = creds.token_uri || DEFAULT_TOKEN_URI\n const now = Math.floor(Date.now() / 1000)\n const unsigned = `${base64url(JSON.stringify({ alg: 'RS256' }))}.${base64url(JSON.stringify({ iss: creds.client_email, scope: CLOUD_PLATFORM_SCOPE, aud: tokenUri, exp: now + 3600, iat: now }))}`\n const signature = createSign('RSA-SHA256').update(unsigned).sign(creds.private_key)\n const timeout = AbortSignal.timeout(TOKEN_TIMEOUT_MS)\n const response = await fetch(tokenUri, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', assertion: `${unsigned}.${base64url(signature)}` }).toString(),\n signal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n })\n const text = await response.text()\n if (!response.ok) {\n let reason = text.slice(0, 300)\n try {\n const parsed = JSON.parse(text) as { error?: string, error_description?: string }\n reason = [parsed.error, parsed.error_description].filter(Boolean).join(': ') || reason\n }\n catch { /* not JSON */ }\n throw new Error(`Google service account token request failed (${response.status}): ${reason}`)\n }\n return (JSON.parse(text) as { access_token: string }).access_token\n}\n\nasync function metadataToken(signal?: AbortSignal): Promise<string> {\n const host = process.env.GCE_METADATA_HOST || '169.254.169.254'\n const timeout = AbortSignal.timeout(METADATA_TIMEOUT_MS)\n let response: Response\n try {\n response = await fetch(`http://${host}/computeMetadata/v1/instance/service-accounts/default/token`, {\n headers: { 'Metadata-Flavor': 'Google' },\n signal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n })\n }\n catch (err) {\n if (signal?.aborted)\n throw err\n throw new Error('Could not load the default Google Cloud credentials. Run `gcloud auth application-default login`, or set GOOGLE_APPLICATION_CREDENTIALS to a credentials file.', { cause: err })\n }\n if (!response.ok)\n throw new Error(`The Google Cloud metadata server refused a token (${response.status}): ${(await response.text()).slice(0, 300)}`)\n return (await response.json() as { access_token: string }).access_token\n}\n\n/**\n * A fresh access token from Google Cloud credentials.\n *\n * @param credentialsFile - An explicit credentials file; else the\n * well-known gcloud file, else the metadata server.\n * @param signal - Aborts the token request.\n */\nexport async function googleCloudToken(credentialsFile?: string, signal?: AbortSignal): Promise<GoogleCloudToken> {\n const file = credentialsFile || (existsSync(wellKnownCredentialsFile()) ? wellKnownCredentialsFile() : undefined)\n if (!file)\n return { token: await metadataToken(signal) }\n const creds = readCredentials(file)\n const quota = creds.quota_project_id ? { quotaProject: creds.quota_project_id } : {}\n if (creds.type === 'authorized_user') {\n if (!creds.client_id || !creds.client_secret || !creds.refresh_token)\n throw new Error(`The credentials file ${file} has no client_id, client_secret or refresh_token.`)\n const tokens = await googleTokenRequest({\n refresh_token: creds.refresh_token,\n client_id: creds.client_id,\n client_secret: creds.client_secret,\n grant_type: 'refresh_token',\n }, signal)\n return { token: tokens.access_token, ...quota }\n }\n if (creds.type === 'service_account')\n return { token: await serviceAccountToken(creds, file, signal), ...quota }\n throw new Error(`Google Cloud credentials of type \"${creds.type ?? 'unknown'}\" (${file}) aren't supported. Use a service account key, or \\`gcloud auth application-default login\\`.`)\n}\n","/**\n * Gemini image generation on the Gemini API (Google AI Studio):\n * `generateContent` with `responseModalities: ['TEXT', 'IMAGE']`. Reference\n * images go in as `inlineData` parts. One image per request, so a request for\n * several sends several in parallel.\n */\n\nimport type { ImageModelInfo, ProviderImageResponse, ProviderImages } from './types'\nimport type { ImageFetch } from './wire'\nimport { imageCount, imageHttpError, repeatRequest } from './wire'\n\nconst BASE_URL = 'https://generativelanguage.googleapis.com/v1beta'\n\n/** Gemini image models on the Gemini API. */\nexport const GOOGLE_IMAGE_MODELS: readonly ImageModelInfo[] = [\n { id: 'gemini-3.1-flash-image', name: 'Gemini 3.1 Flash Image', input: ['text', 'image'] },\n { id: 'gemini-3-pro-image', name: 'Gemini 3 Pro Image', input: ['text', 'image'] },\n { id: 'gemini-3.1-flash-lite-image', name: 'Gemini 3.1 Flash Lite Image', input: ['text', 'image'] },\n { id: 'gemini-2.5-flash-image', name: 'Gemini 2.5 Flash Image', input: ['text', 'image'] },\n]\n\ninterface GenerateContentResponse {\n candidates?: Array<{\n finishReason?: string\n content?: { parts?: Array<{ text?: string, inlineData?: { mimeType?: string, data?: string } }> }\n }>\n promptFeedback?: { blockReason?: string }\n}\n\n/**\n * Gemini image generation as a {@link ProviderImages}. Unavailable while `resolveKey` returns `undefined`.\n *\n * @param options - Key resolver and test overrides.\n * @param options.resolveKey - Returns the Gemini API key, or `undefined` when none is set. Called on every request.\n * @param options.fetch - Fetch override, for tests.\n */\nexport function googleImages(options: { resolveKey: () => string | undefined, fetch?: ImageFetch }): ProviderImages {\n const doFetch = options.fetch ?? fetch\n return {\n defaultModel: GOOGLE_IMAGE_MODELS[0]!.id,\n models: GOOGLE_IMAGE_MODELS,\n availability: () => options.resolveKey()\n ? { available: true }\n : { available: false, reason: 'Gemini image generation needs a Gemini API key (GEMINI_API_KEY).' },\n async generate(request, signal) {\n const key = options.resolveKey()\n if (!key)\n throw new Error('Gemini image generation needs a Gemini API key. Set GEMINI_API_KEY, or add a key in the Google Gemini provider settings.')\n const body = {\n contents: [{\n role: 'user',\n parts: [\n { text: request.prompt },\n ...(request.references ?? []).map(ref => ({ inlineData: { mimeType: ref.mediaType, data: ref.data } })),\n ],\n }],\n generationConfig: {\n responseModalities: ['TEXT', 'IMAGE'],\n ...(request.aspectRatio ? { imageConfig: { aspectRatio: request.aspectRatio } } : {}),\n },\n }\n const once = async (): Promise<ProviderImageResponse> => {\n const res = await doFetch(`${BASE_URL}/models/${encodeURIComponent(request.model)}:generateContent`, {\n method: 'POST',\n headers: { 'x-goog-api-key': key, 'content-type': 'application/json' },\n body: JSON.stringify(body),\n signal,\n })\n if (!res.ok)\n throw await imageHttpError('Gemini', res)\n const json = await res.json() as GenerateContentResponse\n if (json.promptFeedback?.blockReason)\n throw new Error(`Gemini refused the prompt (${json.promptFeedback.blockReason}).`)\n const candidate = json.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n const images = parts.flatMap(part => part.inlineData?.data\n ? [{ mediaType: part.inlineData.mimeType ?? 'image/png', data: part.inlineData.data }]\n : [])\n const text = parts.flatMap(part => part.text ? [part.text] : []).join('\\n').trim()\n if (images.length === 0) {\n const reason = candidate?.finishReason && candidate.finishReason !== 'STOP' ? ` (${candidate.finishReason})` : ''\n throw new Error(`Gemini returned no image${reason}${text ? `: ${text}` : '.'}`)\n }\n return { images, model: request.model, ...(text ? { text } : {}) }\n }\n return repeatRequest(imageCount(request.count), once)\n },\n }\n}\n","/**\n * Google Gemini providers, on zidane's own Gemini REST client\n * (`streamGenerateContent` over SSE, see `./gemini`).\n *\n * - {@link google}: the Gemini API (Google AI Studio), authenticated by an\n * API key.\n * - {@link googleVertex}: Vertex AI, authenticated by Google Cloud\n * credentials (gcloud Application Default Credentials, a credentials file\n * or the metadata server), a \"Sign in with Google\" grant, or a Vertex API\n * key.\n * - {@link googleCompatible}: the same plumbing over another Gemini-wire\n * backend (an extension's transport, models and auth).\n *\n * Every request goes through the provider's `fetch`, so `http.request` /\n * `http.response` interceptors apply.\n *\n * Gemini signs its reasoning: thought signatures ride on text parts, thought\n * parts and function calls, and Gemini 3 rejects a tool-use step whose\n * function calls come back without theirs. These providers persist them on\n * the blocks that carried them (`signature`, `signatureProducer`) and\n * replay them only to the route that issued them, whatever the model:\n * Google's guidance is to resend a session's thought blocks as received,\n * model switches included.\n */\nimport type { Provider, ProviderCapabilities, StreamCallbacks, StreamOptions, ToolSpec, TurnResult } from '.'\nimport type { ClassifiedError } from '../errors'\nimport type { GeminiSignatureScope, SessionContentBlock, SessionMessage, TurnFinishReason, TurnUsage } from '../types'\nimport type { ModelCostRates } from './cost'\nimport type { GeminiBudgetTable, GeminiTool } from './gemini/request'\nimport type { GeminiRequest, GeminiResponseChunk, GoogleWireModel } from './gemini/types'\nimport type { ModelCatalog } from './model-catalog'\nimport type { OAuthParams } from './oauth'\nimport { getBuiltinModel } from '@earendil-works/pi-ai/providers/all'\nimport { classifyErrorPrelude, classifyProviderLimit, isRetryableHttpStatus, matchesContextExceeded, matchesToolPairingError, providerLimitReason } from '../errors'\nimport { renderSystemForWire } from '../system-prompt'\nimport { ZIDANE_VERSION } from '../version'\nimport { fillEstimatedCost } from './cost'\nimport { googleHttpError, leadingStatus } from './gemini/errors'\nimport { buildGeminiRequest } from './gemini/request'\nimport { collectGeminiTurn, parseGoogleChunk, readSseJson } from './gemini/stream'\nimport { googleCloudToken } from './gemini/vertex-auth'\nimport { GOOGLE_VERTEX_OAUTH_ID } from './google-oauth'\nimport { googleImages } from './images/google'\nimport { lookupModel as catalogLookup, mergeCatalogEntry } from './model-catalog'\nimport { pinnedAccountMissingError, readAccountOAuthCredential, readOAuthCredentials, resolveOAuthApiKey } from './oauth'\nimport { assistantMessage, toolResultsMessage, userMessage } from './openai-compat'\nimport { sanitizeToolSpecs } from './schema-sanitize'\nimport { createToolNameBoundary } from './tool-name-boundary'\n\nexport type { GeminiTool } from './gemini/request'\nexport { toGeminiContents } from './gemini/request'\nexport type { GeminiContent, GeminiFunctionDeclaration, GeminiGenerationConfig, GeminiPart, GeminiRequest, GeminiResponseChunk, GeminiThinkingConfig, GeminiToolConfig, GoogleWireModel } from './gemini/types'\n\n/** Zidane provider (and signature route) names of the two Google backends. */\nexport type GoogleRouteName = 'google' | 'google-vertex'\n\n/** Model used when a request names none. Served on free-tier Gemini API keys. */\nexport const GOOGLE_DEFAULT_MODEL = 'gemini-3.8-flash'\n\n/** A Google model pi-ai's registry hasn't bundled yet: a bundled `template` with the same thinking shape, under its own id. */\nexport interface GoogleExtraModel {\n /** Model id sent to the API. */\n id: string\n /** Display name. */\n name: string\n /** A bundled model with the same thinking levels and budgets. */\n template: string\n /** Context window in tokens. */\n contextWindow: number\n /** Largest output in tokens. */\n maxTokens: number\n /** A function, so a dated price change applies to long-running hosts. */\n rates: () => Required<ModelCostRates>\n}\n\n/**\n * Models pi-ai's registry hasn't bundled yet, served on both routes. A\n * pi-ai release that bundles one supersedes its entry (bundled metadata\n * always wins), so delete the entry then.\n */\nexport const GOOGLE_EXTRA_MODELS: readonly GoogleExtraModel[] = []\n\nconst GEMINI_API_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta'\nconst USER_AGENT = `zidane/${ZIDANE_VERSION}`\n\nconst lookupBuiltin = getBuiltinModel as (provider: string, modelId: string) => GoogleWireModel | undefined\n\nfunction builtinModel(route: GoogleRouteName, modelId: string): GoogleWireModel | undefined {\n try {\n return lookupBuiltin(route, modelId)\n }\n catch {\n return undefined\n }\n}\n\n/**\n * Model record for `modelId` on `route`: the registry's entry, else a\n * {@link GOOGLE_EXTRA_MODELS} overlay, else the default model's shape under\n * the requested id. A catalog entry overlays whichever applies.\n *\n * @param route - Backend the request goes to.\n * @param modelId - Requested model id.\n * @param catalog - Per-run catalog override.\n */\nexport function resolveGoogleModel(route: GoogleRouteName, modelId: string, catalog?: ModelCatalog): GoogleWireModel {\n const entry = catalogLookup(route, modelId, catalog)\n const bundled = builtinModel(route, modelId)\n if (bundled)\n return mergeCatalogEntry(bundled, entry)\n\n const extra = GOOGLE_EXTRA_MODELS.find(m => m.id === modelId)\n const template = builtinModel(route, extra?.template ?? GOOGLE_DEFAULT_MODEL)\n if (!template)\n throw new Error(`Google model registry (${route}) is missing ${extra?.template ?? GOOGLE_DEFAULT_MODEL}`)\n if (extra) {\n return mergeCatalogEntry({\n ...template,\n id: extra.id,\n name: extra.name,\n contextWindow: extra.contextWindow,\n maxTokens: extra.maxTokens,\n cost: extra.rates(),\n }, entry)\n }\n return mergeCatalogEntry({ ...template, id: modelId, name: modelId }, entry)\n}\n\nfunction formatTools(tools: ToolSpec[]): GeminiTool[] {\n // Sent as `parametersJsonSchema` (full JSON Schema); the OpenAI pass still\n // fixes the root shapes (`$ref`, `anyOf`, nullable roots) MCP servers\n // publish and Gemini rejects as well.\n return sanitizeToolSpecs(tools, { profile: 'openai' }).map(t => ({\n name: t.name,\n description: t.description ?? '',\n parameters: t.inputSchema,\n }))\n}\n\n/**\n * Transient Gemini failures worth a loop-level retry. The client itself\n * never retries.\n */\nconst TRANSIENT_GOOGLE_MESSAGE_RE = /RESOURCE_EXHAUSTED|UNAVAILABLE|DEADLINE_EXCEEDED|overloaded|high demand|rate.?limit|try again later/i\n\n/** Gemini's `RetryInfo` detail in a 429 body: `\"retryDelay\": \"34s\"`. */\nconst RETRY_DELAY_RE = /\"retryDelay\"\\s*:\\s*\"(\\d+(?:\\.\\d+)?)s\"/\n\n/**\n * Classify a Gemini API / Vertex AI error.\n *\n * @param err - Error a Google provider threw.\n * @param label - Product a limit's message names; routes over other services (Antigravity) pass their own.\n */\nexport function classifyGoogleError(err: unknown, label = 'Gemini'): ClassifiedError | null {\n const prelude = classifyErrorPrelude(err)\n if (prelude === 'not-object')\n return null\n if (prelude === 'aborted')\n return { kind: 'aborted' }\n const anyErr = err as { message?: unknown, status?: unknown, body?: unknown }\n const message = typeof anyErr.message === 'string' ? anyErr.message : ''\n if (matchesContextExceeded(message))\n return { kind: 'context_exceeded', providerCode: 'context_length_exceeded', message }\n if (matchesToolPairingError(message))\n return { kind: 'tool_pairing_corruption', message }\n if (!message)\n return null\n const status = typeof anyErr.status === 'number' ? anyErr.status : leadingStatus(message)\n const retryable = (status !== undefined && isRetryableHttpStatus(status)) || TRANSIENT_GOOGLE_MESSAGE_RE.test(message)\n const reason = providerLimitReason({ status, message })\n if (reason) {\n const delay = RETRY_DELAY_RE.exec(typeof anyErr.body === 'string' ? anyErr.body : message)\n return classifyProviderLimit(\n { reason, provider: label, ...(delay ? { retryAfterMs: Number(delay[1]) * 1000 } : {}) },\n { ...(status !== undefined ? { providerCode: String(status) } : {}), retryable },\n )\n }\n return {\n kind: 'provider_error',\n ...(status !== undefined ? { providerCode: String(status) } : {}),\n message,\n ...(retryable ? { retryable: true } : {}),\n }\n}\n\n/** One turn's request, handed to a {@link GoogleCompatibleRoute}'s `send`. */\nexport interface GoogleTurnRequest {\n /** The model record the route resolved. */\n model: GoogleWireModel\n /**\n * The standard `GenerateContentRequest`: contents with this route's\n * signatures, tools, forced tool choice, and `generationConfig` with the\n * output ceiling and the thinking config Gemini models take. A route may\n * edit it, or wrap it in its backend's envelope.\n */\n body: GeminiRequest\n /** Thinking level as requested, for a backend that maps it its own way. */\n thinking?: StreamOptions['thinking']\n /** Output ceiling as requested (the body's is already resolved). */\n maxTokens?: number\n /** Aborts the request. */\n signal?: AbortSignal\n /** The provider's extra headers (`extraHeaders`), to send on top of the route's. */\n headers: Record<string, string>\n /** Stream callbacks, for OAuth refresh hooks. */\n callbacks: StreamCallbacks\n}\n\n/**\n * A Gemini-wire backend for {@link googleCompatible}: where requests go and\n * how they authenticate (`send`), how its stream events read\n * (`parseChunk`) and which models it serves (`resolveModel`). Message\n * conversion, thought-signature bookkeeping, tool names, thinking levels,\n * SSE parsing, usage and cost stay in the shared plumbing.\n */\nexport interface GoogleCompatibleRoute {\n /**\n * Provider name (`Provider.name`, error copy) and the default signature\n * scope. Must not be a built-in provider name (`google`,\n * `google-vertex`, `anthropic`, `openai`).\n */\n name: string\n /**\n * Sends one turn and returns the streaming response\n * (`streamGenerateContent?alt=sse` or the backend's equivalent). Send it\n * with `fetch`: it is the provider's, carrying the `http.request` /\n * `http.response` interceptors. A non-2xx response is read as a Google\n * error; throw instead to report the backend's own (with a numeric\n * `status` so it classifies by HTTP status).\n *\n * @param request - The turn: model, standard body, settings, signal.\n * @param fetch - The provider's fetch.\n */\n send: (request: GoogleTurnRequest, fetch: typeof globalThis.fetch) => Promise<Response>\n /**\n * One SSE event's JSON to a `GenerateContentResponse`, for a backend that\n * wraps it (Cloud Code Assist's `{ response }`). Throw for an in-stream\n * error. Defaults to the event as is, an `{ error }` event thrown as a\n * Google error.\n */\n parseChunk?: (payload: unknown) => GeminiResponseChunk\n /** Whether the provider runs on an OAuth credential. */\n isOAuth: boolean\n /**\n * Model record for a requested model id. Its `cost` rates price each\n * turn: zero rates report no cost (quota-backed access).\n *\n * @param modelId - Requested model id.\n * @param catalog - Per-run catalog override.\n */\n resolveModel: (modelId: string, catalog?: ModelCatalog) => GoogleWireModel\n /**\n * Signature scope of a model: the tag its thought signatures carry, and\n * the only scope they replay to. Defaults to `name`, right when every model\n * behind the backend accepts the others' signatures (Gemini does). A\n * backend fronting several model families returns one scope per family,\n * so switching families mid-session sends earlier reasoning unsigned.\n *\n * @param modelId - Model id of the turn.\n */\n signatureScope?: (modelId: string) => string\n /** Error classification. Defaults to {@link classifyGoogleError}. */\n classifyError?: (err: unknown) => ClassifiedError | null\n}\n\n/** A route plus the budget table only the built-in Vertex route changes. */\ninterface GoogleRoute extends GoogleCompatibleRoute {\n budgets: GeminiBudgetTable\n}\n\n/** Names a {@link googleCompatible} route can't take: built-in providers and signature producers. */\nconst RESERVED_ROUTE_NAMES: ReadonlySet<string> = new Set(['google', 'google-vertex', 'anthropic', 'openai', 'zidane'])\n\n/** Settings shared by the Google providers. */\nexport interface GoogleSharedParams {\n /**\n * Model used when a request does not set one.\n * @default 'gemini-3.8-flash'\n */\n defaultModel?: string\n /**\n * Provider capability flags. Gemini takes images and files (PDFs and\n * others) in prompts and in tool results; audio and video are refused.\n */\n capabilities?: ProviderCapabilities\n /** Extra HTTP headers sent on every request. */\n extraHeaders?: Record<string, string>\n}\n\n/** JSON request headers: the route's, then the provider's extra headers on top (case-insensitively). */\nfunction requestHeaders(route: Record<string, string>, extra: Record<string, string>): Headers {\n const headers = new Headers({ 'Content-Type': 'application/json', 'User-Agent': USER_AGENT, ...route })\n for (const [key, value] of Object.entries(extra))\n headers.set(key, value)\n return headers\n}\n\n/** POSTs a turn's body as JSON with the route's auth headers. */\nfunction postTurn(fetch: typeof globalThis.fetch, url: string, request: GoogleTurnRequest, headers: Record<string, string>): Promise<Response> {\n return fetch(url, {\n method: 'POST',\n headers: requestHeaders(headers, request.headers),\n body: JSON.stringify(request.body),\n ...(request.signal ? { signal: request.signal } : {}),\n })\n}\n\nfunction finishReasonOf(raw: string, hasToolCalls: boolean): TurnFinishReason {\n if (raw === 'MAX_TOKENS')\n return 'length'\n return hasToolCalls ? 'tool-calls' : 'stop'\n}\n\nfunction createGoogleProvider(route: GoogleRoute, params: GoogleSharedParams | undefined): Provider {\n const defaultModel = params?.defaultModel || GOOGLE_DEFAULT_MODEL\n const capabilities: ProviderCapabilities = params?.capabilities ?? {\n vision: true,\n imageInToolResult: true,\n audio: false,\n video: false,\n documents: true,\n }\n\n return {\n name: route.name,\n meta: { defaultModel, isOAuth: route.isOAuth, capabilities },\n formatTools,\n userMessage,\n assistantMessage,\n toolResultsMessage,\n classifyError: route.classifyError ?? classifyGoogleError,\n\n async stream(options: StreamOptions, callbacks: StreamCallbacks): Promise<TurnResult> {\n const modelId = options.model || defaultModel\n const model = route.resolveModel(modelId, options.modelCatalog)\n const scope = signatureScopeOf(route, model.id)\n const tools = options.tools as GeminiTool[]\n const nameBoundary = createToolNameBoundary(options.messages, tools.map(tool => tool.name))\n const body = buildGeminiRequest({\n messages: nameBoundary.messages,\n model,\n scope,\n provider: route.name,\n system: renderSystemForWire(options.system),\n tools: tools.map(tool => ({ ...tool, name: nameBoundary.toWire(tool.name) })),\n ...(options.thinking !== undefined ? { thinking: options.thinking } : {}),\n ...(options.thinkingBudget !== undefined ? { thinkingBudget: options.thinkingBudget } : {}),\n ...(options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n ...(options.toolChoice ? { toolChoice: options.toolChoice } : {}),\n toWire: nameBoundary.toWire,\n budgets: route.budgets,\n })\n const fetchImpl = options.wrapFetch ? options.wrapFetch(globalThis.fetch) : globalThis.fetch\n const response = await route.send({\n model,\n body,\n ...(options.thinking !== undefined ? { thinking: options.thinking } : {}),\n ...(options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n headers: params?.extraHeaders ?? {},\n callbacks,\n }, fetchImpl)\n if (!response.ok)\n throw await googleHttpError(response)\n if (!response.body)\n throw new Error(`${route.name} answered without a body.`)\n\n const parse = route.parseChunk ?? parseGoogleChunk\n const events = readSseJson(response.body, options.signal)\n const chunks = (async function* () {\n for await (const event of events)\n yield parse(event)\n })()\n const turn = await collectGeminiTurn(chunks, model.cost, callbacks, options.signal)\n\n const signed = (signature: string | undefined) => signature ? { signature, signatureProducer: scope } : {}\n const content: SessionContentBlock[] = []\n const toolCalls: TurnResult['toolCalls'] = []\n for (const block of turn.blocks) {\n if (block.type === 'call') {\n const name = nameBoundary.fromWire(block.name)\n toolCalls.push({ id: block.id, name, input: block.args })\n content.push({ type: 'tool_call', id: block.id, name, input: block.args, ...signed(block.signature) })\n }\n else {\n content.push({ type: block.type, text: block.text, ...signed(block.signature) })\n }\n }\n const finishReason = finishReasonOf(turn.finishReason, toolCalls.length > 0)\n const usage: TurnUsage = await fillEstimatedCost({\n input: turn.usage.input,\n output: turn.usage.output,\n cacheRead: turn.usage.cacheRead || undefined,\n ...(turn.usage.reasoning ? { thinking: turn.usage.reasoning } : {}),\n cost: turn.usage.cost || undefined,\n finishReason,\n modelId,\n }, route.name, undefined, options.modelCatalog)\n\n const assistantTurn: SessionMessage = { role: 'assistant', content }\n return {\n assistantMessage: assistantTurn,\n text: turn.text || turn.blocks.flatMap(block => block.type === 'text' ? [block.text] : []).join(''),\n toolCalls,\n done: toolCalls.length === 0,\n usage,\n }\n },\n }\n}\n\n/**\n * The scope a model's thought signatures carry. A custom route's scope can't\n * impersonate a built-in producer, whose signatures it would then replay.\n */\nfunction signatureScopeOf(route: GoogleCompatibleRoute, modelId: string): GeminiSignatureScope {\n const scope = route.signatureScope?.(modelId) ?? route.name\n if (scope !== route.name && RESERVED_ROUTE_NAMES.has(scope))\n throw new Error(`${route.name}: signature scope \"${scope}\" is reserved for a built-in provider`)\n return scope\n}\n\n/**\n * Creates a provider over another Gemini-wire backend: an extension supplies\n * the transport (`send`, `parseChunk`) and model records; message\n * conversion, thought signatures (tagged with the route's scope, never\n * replayed elsewhere), tool names, thinking levels, SSE parsing, usage and\n * cost come from the same plumbing as {@link google} and\n * {@link googleVertex}.\n *\n * @param route - The backend: name, transport and models.\n * @param params - Default model, capabilities and extra headers.\n *\n * @example\n * ```ts\n * import { googleCompatible } from 'zidane/providers'\n *\n * const provider = googleCompatible({\n * name: 'my-gateway',\n * isOAuth: false,\n * send: (turn, fetch) => fetch(`https://gateway.example/v1beta/models/${turn.model.id}:streamGenerateContent?alt=sse`, {\n * method: 'POST',\n * headers: { 'content-type': 'application/json', 'authorization': `Bearer ${process.env.MY_GATEWAY_KEY}` },\n * body: JSON.stringify(turn.body),\n * signal: turn.signal,\n * }),\n * resolveModel: id => myModels[id],\n * }, { defaultModel: 'gemini-3.8-flash' })\n * ```\n */\nexport function googleCompatible(route: GoogleCompatibleRoute, params?: GoogleSharedParams): Provider {\n if (!route.name || RESERVED_ROUTE_NAMES.has(route.name))\n throw new Error(`googleCompatible: route name \"${route.name}\" is reserved for a built-in provider`)\n return createGoogleProvider({ ...route, budgets: 'gemini-api' }, params)\n}\n\n/** Options for {@link google}. */\nexport interface GoogleParams extends GoogleSharedParams {\n /** Gemini API key. Defaults to `GEMINI_API_KEY`, then `GOOGLE_API_KEY`. */\n apiKey?: string\n}\n\n/**\n * Creates the Google Gemini provider on the Gemini API (Google AI Studio).\n * Authenticates with `apiKey`, else `GEMINI_API_KEY`, else `GOOGLE_API_KEY`.\n *\n * @param params - API key, default model, capabilities and extra headers.\n *\n * @example\n * ```ts\n * import { createAgent } from 'zidane'\n * import { google } from 'zidane/providers/google'\n *\n * const agent = createAgent({\n * provider: google({ apiKey: process.env.GEMINI_API_KEY }),\n * })\n * await agent.run({ prompt: 'Say hello.' })\n * ```\n */\nexport function google(params?: GoogleParams): Provider {\n const resolveKey = (): string | undefined => params?.apiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY\n const provider = createGoogleProvider({\n name: 'google',\n isOAuth: false,\n budgets: 'gemini-api',\n resolveModel: (modelId, catalog) => resolveGoogleModel('google', modelId, catalog),\n send: async (request, fetch) => {\n const apiKey = resolveKey()\n if (!apiKey)\n throw new Error('No Gemini API key found. Set GEMINI_API_KEY, or add a key in the Google Gemini provider settings.')\n const base = request.model.baseUrl || GEMINI_API_BASE_URL\n return postTurn(fetch, `${base}/models/${request.model.id}:streamGenerateContent?alt=sse`, request, { 'x-goog-api-key': apiKey })\n },\n }, params)\n return { ...provider, images: googleImages({ resolveKey }) }\n}\n\n/** Options for {@link googleVertex}. */\nexport interface GoogleVertexParams extends GoogleSharedParams {\n /**\n * Vertex AI API key (express mode). Defaults to `GOOGLE_CLOUD_API_KEY`.\n * Without one, requests authenticate with Google Cloud credentials.\n */\n apiKey?: string\n /** Google Cloud project. Defaults to `GOOGLE_CLOUD_PROJECT`, then `GCLOUD_PROJECT`. */\n project?: string\n /** Vertex AI location. Defaults to `GOOGLE_CLOUD_LOCATION`, then `global`. */\n location?: string\n /**\n * Service-account or authorized-user credentials file. Defaults to\n * `GOOGLE_APPLICATION_CREDENTIALS`, then gcloud's Application Default\n * Credentials (`gcloud auth application-default login`), then the\n * metadata server on Google Cloud.\n */\n credentialsFile?: string\n /**\n * Run on one stored \"Sign in with Google\" account (its stable id) rather\n * than the active one. See {@link OAuthParams.account}.\n */\n account?: OAuthParams['account']\n}\n\n/** Where a Vertex AI request goes and how it authenticates. */\nexport interface VertexRequestAuth {\n /** The `streamGenerateContent` URL of a model. */\n url: (modelId: string) => string\n /** Auth headers: `x-goog-api-key`, or a bearer token and the billed project. */\n headers: Record<string, string>\n}\n\n/** Multi-region locations, served from their own regional endpoint. */\nconst MULTI_REGIONAL_LOCATIONS: ReadonlySet<string> = new Set(['us', 'eu'])\n\nfunction vertexProjectUrl(project: string, location: string): (modelId: string) => string {\n const host = location === 'global'\n ? 'https://aiplatform.googleapis.com'\n : MULTI_REGIONAL_LOCATIONS.has(location)\n ? `https://aiplatform.${location}.rep.googleapis.com`\n : `https://${location}-aiplatform.googleapis.com`\n return modelId => `${host}/v1/projects/${project}/locations/${location}/publishers/google/models/${modelId}:streamGenerateContent?alt=sse`\n}\n\n/** The fields a \"Sign in with Google\" grant carries beyond the token triple. */\ninterface VertexGrant {\n refresh: string\n projectId: string\n clientId: string\n clientSecret: string\n}\n\n/**\n * Request auth from the stored \"Sign in with Google\" grant (the pinned\n * account's, else the active one), or `undefined` when none is stored. The\n * access token rotates through zidane's OAuth path (cross-process locks,\n * persistence, refresh hooks, a clear \"sign in again\" for a revoked grant)\n * and goes out as the bearer token, the grant's project billed.\n */\nasync function signedInAuth(\n params: GoogleVertexParams | undefined,\n callbacks: StreamCallbacks | undefined,\n): Promise<VertexRequestAuth | undefined> {\n const account = params?.account\n const read = () => account\n ? readAccountOAuthCredential(GOOGLE_VERTEX_OAUTH_ID, account)\n : readOAuthCredentials()[GOOGLE_VERTEX_OAUTH_ID]\n if (!read()) {\n if (account)\n throw new Error(pinnedAccountMissingError('google-vertex'))\n return undefined\n }\n const token = await resolveOAuthApiKey({\n provider: 'google-vertex',\n providerId: GOOGLE_VERTEX_OAUTH_ID,\n ...(account ? { params: { account } } : {}),\n missingError: 'No Google sign-in found for Vertex AI. Sign in with Google again.',\n refreshError: reason => `Google sign-in refresh failed. Sign in with Google again. ${reason}`,\n }, callbacks)\n const grant = read() as Partial<VertexGrant> | undefined\n if (!grant?.refresh || !grant.clientId || !grant.clientSecret || !grant.projectId)\n throw new Error('This Google sign-in is missing its OAuth client or project. Sign in with Google again.')\n const project = params?.project || grant.projectId\n return {\n url: vertexProjectUrl(project, params?.location || process.env.GOOGLE_CLOUD_LOCATION || 'global'),\n headers: { 'Authorization': `Bearer ${token}`, 'x-goog-user-project': project },\n }\n}\n\n/**\n * Where a Vertex AI request goes and its credentials, read per turn so a\n * credential configured after the provider was built still applies. In\n * order: a pinned account's sign-in, a Vertex API key, the active \"Sign in\n * with Google\" grant, then Google Cloud credentials for the project (a\n * credentials file, gcloud's Application Default Credentials, the metadata\n * server), a fresh token minted per request.\n *\n * @param params - Explicit settings; environment variables fill the rest.\n * @param callbacks - Stream callbacks, for the OAuth refresh hook.\n * @param signal - Aborts a token request.\n */\nexport async function resolveVertexAuth(params?: GoogleVertexParams, callbacks?: StreamCallbacks, signal?: AbortSignal): Promise<VertexRequestAuth> {\n if (params?.account)\n return (await signedInAuth(params, callbacks))!\n const apiKey = params?.apiKey || process.env.GOOGLE_CLOUD_API_KEY\n if (apiKey) {\n return {\n url: modelId => `https://aiplatform.googleapis.com/v1/publishers/google/models/${modelId}:streamGenerateContent?alt=sse`,\n headers: { 'x-goog-api-key': apiKey },\n }\n }\n const signedIn = await signedInAuth(params, callbacks)\n if (signedIn)\n return signedIn\n const project = params?.project || process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT\n if (!project)\n throw new Error('Vertex AI needs a Google Cloud project. Set GOOGLE_CLOUD_PROJECT, or configure it in the Google Vertex AI provider settings.')\n const location = params?.location || process.env.GOOGLE_CLOUD_LOCATION || 'global'\n const { token, quotaProject } = await googleCloudToken(params?.credentialsFile || process.env.GOOGLE_APPLICATION_CREDENTIALS, signal)\n return {\n url: vertexProjectUrl(project, location),\n headers: { Authorization: `Bearer ${token}`, ...(quotaProject ? { 'x-goog-user-project': quotaProject } : {}) },\n }\n}\n\n/**\n * Creates the Google Vertex AI provider. Authenticates with a pinned\n * `account`'s Google sign-in, else a Vertex API key (`apiKey` or\n * `GOOGLE_CLOUD_API_KEY`), else the active \"Sign in with Google\" grant, else\n * Google Cloud credentials for `project` in `location`. See\n * {@link resolveVertexAuth}.\n *\n * @param params - Credentials, project, location, default model, capabilities and extra headers.\n *\n * @example\n * ```ts\n * import { createAgent } from 'zidane'\n * import { googleVertex } from 'zidane/providers/google'\n *\n * // After `gcloud auth application-default login`:\n * const agent = createAgent({\n * provider: googleVertex({ project: 'my-project' }),\n * })\n * await agent.run({ prompt: 'Say hello.' })\n * ```\n */\nexport function googleVertex(params?: GoogleVertexParams): Provider {\n return createGoogleProvider({\n name: 'google-vertex',\n isOAuth: !!params?.account || !(params?.apiKey || process.env.GOOGLE_CLOUD_API_KEY),\n budgets: 'vertex',\n resolveModel: (modelId, catalog) => resolveGoogleModel('google-vertex', modelId, catalog),\n send: async (request, fetch) => {\n const auth = await resolveVertexAuth(params, request.callbacks, request.signal)\n return postTurn(fetch, auth.url(request.model.id), request, auth.headers)\n },\n }, params)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"google-D1zjAViO.js","names":["catalogLookup"],"sources":["../src/providers/gemini/errors.ts","../src/providers/gemini/request.ts","../src/providers/gemini/stream.ts","../src/providers/gemini/vertex-auth.ts","../src/providers/images/google.ts","../src/providers/google.ts"],"sourcesContent":["/**\n * Google's HTTP errors, as the Google providers throw them: the innermost\n * message, prefixed with its HTTP and RPC status, with `status` and the\n * raw `body` on the error.\n */\n\ninterface GoogleErrorBody { error?: { code?: unknown, message?: unknown, status?: unknown } }\n\n/** A Google error object in `text`: `{ \"error\": … }`, or the first of an array of them (Vertex streams). */\nfunction parseGoogleErrorBody(text: string): GoogleErrorBody['error'] | undefined {\n try {\n let parsed = JSON.parse(text) as GoogleErrorBody | GoogleErrorBody[] | null\n if (Array.isArray(parsed))\n parsed = parsed[0] ?? null\n return parsed && typeof parsed.error === 'object' && parsed.error ? parsed.error : undefined\n }\n catch {\n return undefined\n }\n}\n\n/** The HTTP status a message starts with (`429: …`). */\nexport function leadingStatus(message: string): number | undefined {\n const match = /^(\\d{3})\\b/.exec(message)\n return match ? Number(match[1]) : undefined\n}\n\n/**\n * The message, status and body of a Google error text. A proxy's non-JSON\n * body arrives wrapped as `{\"error\":{\"message\":\"<body>\"}}`, so Google's own\n * `{\"error\":{…}}` can sit JSON-encoded inside another one.\n *\n * @param raw - `<status>: <body>`, or a JSON error body.\n * @returns The innermost message prefixed with its HTTP and RPC status, the\n * status, and the innermost body (it carries details such as `retryDelay`).\n */\nexport function unwrapGoogleError(raw: string): { message: string, status?: number, body?: string } {\n let status = leadingStatus(raw)\n let rpcStatus: string | undefined\n let text = status === undefined ? raw : raw.replace(/^\\d{3}:\\s*/, '')\n let message: string | undefined\n let body = raw\n for (let error = parseGoogleErrorBody(text); error; error = parseGoogleErrorBody(text)) {\n body = text\n if (typeof error.code === 'number')\n status = error.code\n if (typeof error.status === 'string' && /^[A-Z_]+$/.test(error.status))\n rpcStatus = error.status\n if (typeof error.message !== 'string')\n break\n message = text = error.message.trim()\n }\n if (!message)\n return { message: raw, ...(status !== undefined ? { status } : {}) }\n const prefix = [status, rpcStatus].filter(part => part !== undefined).join(' ')\n return { message: prefix ? `${prefix}: ${message}` : message, ...(status !== undefined ? { status } : {}), body }\n}\n\n/** An error carrying Google's message, HTTP status and body. */\nexport function googleError(raw: string): Error & { status?: number, body?: string } {\n const { message, ...details } = unwrapGoogleError(raw)\n return Object.assign(new Error(message), details)\n}\n\n/**\n * The error for a non-2xx answer. A JSON body is read as Google's; any\n * other body (a proxy's HTML page) is wrapped with the status, the way\n * Google's SDK reports it.\n *\n * @param response - The failed response.\n */\nexport async function googleHttpError(response: Response): Promise<Error> {\n const text = await response.text().catch(() => '')\n const json = response.headers.get('content-type')?.includes('application/json')\n let body = text\n if (json) {\n try {\n body = JSON.stringify(JSON.parse(text))\n }\n catch {\n body = JSON.stringify({ error: { message: text, code: response.status, status: response.statusText } })\n }\n }\n else {\n body = JSON.stringify({ error: { message: text, code: response.status, status: response.statusText } })\n }\n const error = googleError(body)\n if (error.status === undefined)\n error.status = response.status\n return error\n}\n\n/** An error named `AbortError`, so it classifies as an abort. */\nexport function abortError(message = 'Request was aborted'): Error {\n return Object.assign(new Error(message), { name: 'AbortError' })\n}\n","/**\n * Session messages, tools and settings to a Gemini `GenerateContentRequest`.\n *\n * Thought signatures replay only to the scope that issued them: an\n * assistant turn holding this scope's signatures is sent as the target\n * model's own (its signed thoughts, text and calls as received, model\n * switches included: Google accepts them across its models), and every other\n * turn goes unsigned, its reasoning dropped and, for models that pair calls\n * by id, its call ids normalized.\n */\nimport type { StreamOptions } from '..'\nimport type { GeminiSignatureScope, SessionContentBlock, SessionMessage } from '../../types'\nimport type { GeminiBlob, GeminiContent, GeminiFunctionDeclaration, GeminiPart, GeminiRequest, GeminiThinkingConfig, GoogleWireModel } from './types'\nimport { unsupportedMediaError } from '../../prompt'\nimport { reasoningWireAction, SYNTHETIC_TOOL_RESULT_PLACEHOLDER } from '../../session/messages'\nimport { systemNotesAsText } from '../../system-notes'\nimport { assertResolvedMediaBlock } from '../../types'\n\n/** A tool as `formatTools` hands it to the request: name, description, JSON Schema. */\nexport interface GeminiTool {\n /** Function name on the wire. */\n name: string\n /** What it does. */\n description: string\n /** JSON Schema of its arguments. */\n parameters: Record<string, unknown>\n}\n\n/** Which thinking-budget table a route uses for Gemini 2.5 levels. */\nexport type GeminiBudgetTable = 'gemini-api' | 'vertex'\n\n/** Inputs of {@link buildGeminiRequest}. */\nexport interface GeminiRequestInput {\n /** Session messages, tool names already on the wire. */\n messages: SessionMessage[]\n /** Target model. */\n model: GoogleWireModel\n /** Signature scope of the target: the only scope whose signatures replay. */\n scope: GeminiSignatureScope\n /** Provider named in unsupported-media errors. */\n provider: string\n /** System prompt, rendered for the wire. */\n system: string\n /** Tools, names on the wire. */\n tools: readonly GeminiTool[]\n /** Requested thinking level. */\n thinking?: StreamOptions['thinking']\n /** Exact thinking budget (Gemini 2.5 models). */\n thinkingBudget?: number\n /** Requested output ceiling; the model's when unset. */\n maxTokens?: number\n /** Forced tool choice. */\n toolChoice?: StreamOptions['toolChoice']\n /** Canonical tool name to its wire name. */\n toWire?: (name: string) => string\n /** Budget table for Gemini 2.5 levels. */\n budgets: GeminiBudgetTable\n}\n\n/** Unpaired surrogates make Google reject the JSON. */\nexport function sanitizeSurrogates(text: string): string {\n return text.replace(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g, '')\n}\n\nfunction geminiMajorVersion(modelId: string): number | undefined {\n const match = /^gemini(?:-live)?-(\\d+)/.exec(modelId.toLowerCase())\n return match ? Number.parseInt(match[1]!, 10) : undefined\n}\n\n/**\n * Whether the model needs ids on function calls and responses: Gemini 3+,\n * and Claude / GPT-OSS behind Gemini-wire backends.\n *\n * @param modelId - Model id on the wire.\n */\nexport function requiresToolCallId(modelId: string): boolean {\n const major = geminiMajorVersion(modelId)\n return modelId.startsWith('claude-') || modelId.startsWith('gpt-oss-') || (major !== undefined && major >= 3)\n}\n\n/** Gemini before 3 takes no media inside a function response; other families do. */\nfunction supportsMultimodalFunctionResponse(modelId: string): boolean {\n const major = geminiMajorVersion(modelId)\n return major === undefined || major >= 3\n}\n\nconst BASE64_SIGNATURE_RE = /^[A-Z0-9+/]+={0,2}$/i\n\n/** Google types signatures as bytes: anything that isn't base64 would 400. */\nfunction validSignature(signature: string | undefined): string | undefined {\n return signature && signature.length % 4 === 0 && BASE64_SIGNATURE_RE.test(signature) ? signature : undefined\n}\n\nconst USER_IMAGE_PLACEHOLDER = '(image omitted: model does not support images)'\nconst TOOL_IMAGE_PLACEHOLDER = '(tool image omitted: model does not support images)'\n\n/** Builds parts, folding a run of images into one placeholder when the model has no vision. */\nfunction mediaParts(vision: boolean, placeholder: string) {\n const parts: GeminiPart[] = []\n let lastWasPlaceholder = false\n return {\n parts,\n text(text: string) {\n parts.push({ text })\n lastWasPlaceholder = text === placeholder\n },\n image(blob: GeminiBlob) {\n if (vision) {\n parts.push({ inlineData: blob })\n lastWasPlaceholder = false\n }\n else if (!lastWasPlaceholder) {\n parts.push({ text: placeholder })\n lastWasPlaceholder = true\n }\n },\n }\n}\n\nfunction userParts(content: SessionContentBlock[], model: GoogleWireModel, provider: string): GeminiPart[] {\n for (const block of content) {\n if (block.type === 'audio')\n throw unsupportedMediaError('audio', provider)\n if (block.type === 'video')\n throw unsupportedMediaError('video', provider)\n }\n const out = mediaParts(model.input.includes('image'), USER_IMAGE_PLACEHOLDER)\n for (const block of content) {\n if (block.type === 'text') {\n out.text(sanitizeSurrogates(block.text))\n }\n else if (block.type === 'image') {\n assertResolvedMediaBlock(block, 'Google wire messages')\n out.image({ mimeType: block.mediaType, data: block.data })\n }\n else if (block.type === 'document') {\n assertResolvedMediaBlock(block, 'Google wire messages')\n // A file part: PDFs and other files go as inline bytes, text as text.\n if (block.encoding === 'base64')\n out.parts.push({ inlineData: { mimeType: block.mediaType, data: block.data } })\n else out.text(sanitizeSurrogates(block.data))\n }\n }\n return out.parts\n}\n\ntype ToolResultBlock = Extract<SessionContentBlock, { type: 'tool_result' }>\n\n/** A tool result's text (joined by newlines), and its media: images and files. */\nfunction toolResultParts(result: ToolResultBlock, model: GoogleWireModel, provider: string): { text: string, media: GeminiBlob[], images: boolean } {\n if (typeof result.output === 'string')\n return { text: result.output, media: [], images: false }\n const vision = model.input.includes('image')\n const texts: string[] = []\n const media: GeminiBlob[] = []\n let images = false\n let lastWasPlaceholder = false\n for (const block of result.output) {\n if (block.type === 'audio')\n throw unsupportedMediaError('audio', provider)\n if (block.type === 'video')\n throw unsupportedMediaError('video', provider)\n if (block.type === 'image') {\n assertResolvedMediaBlock(block, 'Google wire messages')\n if (vision) {\n media.push({ mimeType: block.mediaType, data: block.data })\n images = true\n }\n else if (!lastWasPlaceholder) {\n texts.push(TOOL_IMAGE_PLACEHOLDER)\n lastWasPlaceholder = true\n }\n continue\n }\n if (block.type === 'document') {\n assertResolvedMediaBlock(block, 'Google wire messages')\n if (block.encoding === 'base64')\n media.push({ mimeType: block.mediaType, data: block.data })\n else texts.push(block.data)\n lastWasPlaceholder = false\n continue\n }\n texts.push(block.text)\n lastWasPlaceholder = block.text === TOOL_IMAGE_PLACEHOLDER\n }\n return { text: texts.join('\\n'), media, images }\n}\n\n/**\n * Converts session messages to Gemini `contents`.\n *\n * An assistant turn stays whole: Gemini signs only the FIRST function call\n * of a parallel step, so splitting the calls into separate model turns would\n * leave the others unsigned. Its results follow in call order, in one user\n * turn, with the synthetic placeholder for any the history lost.\n *\n * @param messages - Session messages, tool names already on the wire.\n * @param model - Target model.\n * @param scope - Signature scope of the target.\n * @param provider - Provider named in unsupported-media errors. Defaults to `scope`.\n */\nexport function toGeminiContents(messages: SessionMessage[], model: GoogleWireModel, scope: GeminiSignatureScope, provider: string = scope): GeminiContent[] {\n // System notes have no native slot on this wire: send them as `<system-reminder>` text.\n messages = systemNotesAsText(messages)\n const withIds = requiresToolCallId(model.id)\n const multimodal = supportsMultimodalFunctionResponse(model.id)\n /** Call ids rewritten in foreign turns, so their results still pair. */\n const ids = new Map<string, string>()\n const contents: GeminiContent[] = []\n\n const pushResult = (result: ToolResultBlock, name: string): void => {\n const { text, media, images } = toolResultParts(result, model, provider)\n const id = ids.get(result.callId) ?? result.callId\n const value = text.length > 0 ? sanitizeSurrogates(text) : media.length > 0 ? (images ? '(see attached image)' : '(see attached file)') : ''\n const part: GeminiPart = {\n functionResponse: {\n name,\n response: result.isError ? { error: value } : { output: value },\n ...(media.length > 0 && multimodal ? { parts: media.map(blob => ({ inlineData: blob })) } : {}),\n ...(withIds ? { id } : {}),\n },\n }\n // All of a step's function responses go in one user turn.\n const last = contents.at(-1)\n if (last?.role === 'user' && last.parts.some(p => p.functionResponse))\n last.parts.push(part)\n else contents.push({ role: 'user', parts: [part] })\n if (media.length > 0 && !multimodal)\n contents.push({ role: 'user', parts: [{ text: 'Tool result image:' }, ...media.map(blob => ({ inlineData: blob }))] })\n }\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]!\n if (msg.role !== 'assistant') {\n const parts = userParts(msg.content.filter(b => b.type !== 'tool_result'), model, provider)\n if (parts.length > 0)\n contents.push({ role: 'user', parts })\n continue\n }\n\n const parts = assistantParts(msg.content, scope, withIds, ids)\n if (parts.length > 0)\n contents.push({ role: 'model', parts })\n const calls = msg.content.filter((b): b is Extract<SessionContentBlock, { type: 'tool_call' }> => b.type === 'tool_call')\n if (calls.length === 0)\n continue\n const next = messages[i + 1]\n const results = new Map(\n (next?.role === 'user' ? next.content : [])\n .filter((b): b is ToolResultBlock => b.type === 'tool_result')\n .map(r => [r.callId, r]),\n )\n for (const call of calls)\n pushResult(results.get(call.id) ?? { type: 'tool_result', callId: call.id, output: SYNTHETIC_TOOL_RESULT_PLACEHOLDER, isError: true }, call.name)\n if (next?.role === 'user') {\n // Results whose call isn't in the turn above were removed by the\n // canonical pairing repair; never send one unpaired.\n const rest = userParts(next.content.filter(b => b.type !== 'tool_result'), model, provider)\n if (rest.length > 0)\n contents.push({ role: 'user', parts: rest })\n i++\n }\n }\n return contents\n}\n\nfunction assistantParts(content: SessionContentBlock[], scope: GeminiSignatureScope, withIds: boolean, ids: Map<string, string>): GeminiPart[] {\n const native = content.some(block =>\n (block.type === 'text' || block.type === 'tool_call' || block.type === 'thinking')\n && block.signature !== undefined\n && block.signatureProducer === scope)\n const own = (block: { signature?: string, signatureProducer?: string }): string | undefined =>\n native && block.signatureProducer === scope ? validSignature(block.signature) : undefined\n\n const parts: GeminiPart[] = []\n for (const block of content) {\n if (block.type === 'text') {\n const signature = own(block)\n // An empty part that carries a signature must still be echoed back.\n if (!block.text.trim() && !signature)\n continue\n parts.push({ text: sanitizeSurrogates(block.text), ...(signature ? { thoughtSignature: signature } : {}) })\n }\n else if (block.type === 'thinking') {\n // Reasoning from any other producer or model is dropped: sent as text,\n // the model would take it for part of its visible reply.\n if (!native)\n continue\n const action = reasoningWireAction(block, scope)\n if (action === 'drop')\n continue\n const signature = action === 'keep' ? own(block) : undefined\n if (!block.text.trim() && !signature)\n continue\n parts.push({ thought: true, text: sanitizeSurrogates(block.text), ...(signature ? { thoughtSignature: signature } : {}) })\n }\n else if (block.type === 'tool_call') {\n const signature = own(block)\n let id = block.id\n if (!native && withIds) {\n id = block.id.replace(/[^\\w-]/g, '_').slice(0, 64)\n if (id !== block.id)\n ids.set(block.id, id)\n }\n parts.push({\n functionCall: { name: block.name, args: block.input ?? {}, ...(withIds ? { id } : {}) },\n ...(signature ? { thoughtSignature: signature } : {}),\n })\n }\n // `redacted_thinking`, `provider_reasoning` and server-tool blocks belong\n // to other providers' wires.\n }\n return parts\n}\n\n/** Function declarations for the request (full JSON Schema). */\nexport function toFunctionDeclarations(tools: readonly GeminiTool[]): GeminiFunctionDeclaration[] {\n return tools.map(tool => ({ name: tool.name, description: tool.description, parametersJsonSchema: tool.parameters }))\n}\n\n// ---------------------------------------------------------------------------\n// Thinking\n// ---------------------------------------------------------------------------\n\nconst LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const\ntype Level = (typeof LEVELS)[number]\ntype GeminiLevel = 'minimal' | 'low' | 'medium' | 'high'\n\nfunction supportedLevels(model: GoogleWireModel): Level[] {\n if (!model.reasoning)\n return ['off']\n return LEVELS.filter((level) => {\n const mapped = model.thinkingLevelMap?.[level]\n if (mapped === null)\n return false\n return level === 'xhigh' || level === 'max' ? mapped !== undefined : true\n })\n}\n\n/** The level if the model has it, else the next higher one it has, else the next lower. */\nfunction clampLevel(model: GoogleWireModel, level: Level): Level {\n const available = supportedLevels(model)\n if (available.includes(level))\n return level\n const index = LEVELS.indexOf(level)\n for (let i = index; i < LEVELS.length; i++) {\n if (available.includes(LEVELS[i]!))\n return LEVELS[i]!\n }\n for (let i = index - 1; i >= 0; i--) {\n if (available.includes(LEVELS[i]!))\n return LEVELS[i]!\n }\n return available[0] ?? 'off'\n}\n\nfunction geminiLevel(model: GoogleWireModel, level: Level): GeminiLevel {\n const mapped = model.thinkingLevelMap?.[level]\n const resolved = typeof mapped === 'string' ? mapped.toLowerCase() : level\n if (resolved === 'minimal' || resolved === 'low' || resolved === 'medium' || resolved === 'high')\n return resolved\n throw new Error(`Unsupported Google thinking level mapping for ${model.provider}/${model.id}: ${level} -> ${String(mapped)}`)\n}\n\n/** Whether the model takes Gemini 3's discrete `thinkingLevel` rather than a token budget. */\nfunction usesThinkingLevel(model: GoogleWireModel): boolean {\n const id = model.id.toLowerCase()\n return /gemini-3(?:\\.\\d+)?-(?:pro|flash)/.test(id)\n || /gemini-(?:[4-9]|[1-3]\\d)/.test(id)\n || id === 'gemini-flash-latest'\n || id === 'gemini-flash-lite-latest'\n || /gemma-?4/.test(id)\n}\n\nconst BUDGETS: Record<GeminiBudgetTable, readonly [string, Record<GeminiLevel, number>][]> = {\n 'gemini-api': [\n ['2.5-pro', { minimal: 128, low: 2048, medium: 8192, high: 32768 }],\n ['2.5-flash-lite', { minimal: 512, low: 2048, medium: 8192, high: 24576 }],\n ['2.5-flash', { minimal: 128, low: 2048, medium: 8192, high: 24576 }],\n ],\n 'vertex': [\n ['2.5-pro', { minimal: 128, low: 2048, medium: 8192, high: 32768 }],\n ['2.5-flash', { minimal: 128, low: 2048, medium: 8192, high: 24576 }],\n ],\n}\n\n/** Thinking turned off: budget 0, or the lowest level on a model that can't stop thinking. */\nfunction disabledThinking(model: GoogleWireModel): GeminiThinkingConfig {\n if (!usesThinkingLevel(model))\n return { thinkingBudget: 0 }\n const fallback = clampLevel(model, 'off')\n if (fallback === 'off')\n return { thinkingBudget: 0 }\n return { thinkingLevel: geminiLevel(model, fallback).toUpperCase() as GeminiThinkingConfig['thinkingLevel'] }\n}\n\n/**\n * The `thinkingConfig` for a requested level, or `undefined` for a model\n * that doesn't think. `adaptive` turns thinking on with no level or budget:\n * the model thinks as much as it decides, with thought summaries. A level\n * clamps to what the model supports; Gemini 3+ takes it as `thinkingLevel`,\n * Gemini 2.5 as a token budget (`thinkingBudget` when set, else the route's\n * table, else `-1`, the model's own choice).\n *\n * @param model - Target model.\n * @param thinking - Requested level.\n * @param thinkingBudget - Exact budget.\n * @param budgets - The route's budget table.\n */\nexport function geminiThinkingConfig(model: GoogleWireModel, thinking: StreamOptions['thinking'], thinkingBudget: number | undefined, budgets: GeminiBudgetTable): GeminiThinkingConfig | undefined {\n if (!model.reasoning)\n return undefined\n if (thinking === 'adaptive')\n return { includeThoughts: true }\n if (!thinking || thinking === 'off')\n return disabledThinking(model)\n const clamped = clampLevel(model, thinking as Level)\n if (clamped === 'off')\n return disabledThinking(model)\n const level = geminiLevel(model, clamped)\n if (usesThinkingLevel(model))\n return { includeThoughts: true, thinkingLevel: level.toUpperCase() as GeminiThinkingConfig['thinkingLevel'] }\n const table = BUDGETS[budgets].find(([marker]) => model.id.includes(marker))?.[1]\n return { includeThoughts: true, thinkingBudget: thinkingBudget ?? table?.[level] ?? -1 }\n}\n\n// ---------------------------------------------------------------------------\n// Output ceiling\n// ---------------------------------------------------------------------------\n\nconst CHARS_PER_TOKEN = 3.5\nconst IMAGE_CHARS = 4800\nconst CONTEXT_SAFETY_TOKENS = 4096\n\n/** A rough size of the request: 3.5 characters a token, 4800 characters an image or file. */\nfunction estimateTokens(request: GeminiRequest): number {\n let tokens = 0\n const system = request.systemInstruction?.parts.map(p => p.text).join('') ?? ''\n tokens += Math.ceil(system.length / CHARS_PER_TOKEN)\n if (request.tools)\n tokens += Math.ceil(JSON.stringify(request.tools).length / CHARS_PER_TOKEN)\n for (const content of request.contents) {\n let chars = 0\n for (const part of content.parts) {\n if (part.text !== undefined)\n chars += part.text.length\n if (part.inlineData)\n chars += IMAGE_CHARS\n if (part.functionCall)\n chars += (part.functionCall.name ?? '').length + JSON.stringify(part.functionCall.args ?? {}).length\n if (part.functionResponse) {\n const response = part.functionResponse.response\n chars += ('output' in response ? response.output : response.error).length + IMAGE_CHARS * (part.functionResponse.parts?.length ?? 0)\n }\n }\n tokens += Math.ceil(chars / CHARS_PER_TOKEN)\n }\n return tokens\n}\n\n/** The requested ceiling, kept inside what the context window has left. */\nfunction maxOutputTokens(model: GoogleWireModel, request: GeminiRequest, requested: number): number {\n if (model.contextWindow <= 0)\n return Math.max(1, requested)\n const available = model.contextWindow - estimateTokens(request) - CONTEXT_SAFETY_TOKENS\n return Math.min(requested, Math.max(1, available))\n}\n\n// ---------------------------------------------------------------------------\n// Request\n// ---------------------------------------------------------------------------\n\n/**\n * Builds the `GenerateContentRequest` for one turn.\n *\n * @param input - Messages, model, scope, tools and settings.\n */\nexport function buildGeminiRequest(input: GeminiRequestInput): GeminiRequest {\n const { model } = input\n const request: GeminiRequest = { contents: toGeminiContents(input.messages, model, input.scope, input.provider) }\n if (input.system)\n request.systemInstruction = { role: 'user', parts: [{ text: sanitizeSurrogates(input.system) }] }\n if (input.tools.length > 0) {\n request.tools = [{ functionDeclarations: toFunctionDeclarations(input.tools) }]\n const choice = input.toolChoice\n if (choice && choice.type !== 'auto') {\n request.toolConfig = {\n functionCallingConfig: choice.type === 'tool' && choice.name\n ? { mode: 'ANY', allowedFunctionNames: [(input.toWire ?? (n => n))(choice.name)] }\n : { mode: 'ANY' },\n }\n }\n }\n const thinkingConfig = geminiThinkingConfig(model, input.thinking, input.thinkingBudget, input.budgets)\n request.generationConfig = {\n maxOutputTokens: maxOutputTokens(model, request, input.maxTokens ?? model.maxTokens),\n ...(thinkingConfig ? { thinkingConfig } : {}),\n }\n return request\n}\n","/**\n * Reading a `streamGenerateContent?alt=sse` answer: SSE events to response\n * chunks, chunks to one assistant turn.\n */\nimport type { StreamCallbacks } from '..'\nimport type { GeminiModelCost, GeminiResponseChunk, GeminiUsageMetadata } from './types'\nimport { abortError, googleError } from './errors'\n\n/**\n * The `data:` payloads of an SSE body, parsed as JSON. Events end at a\n * blank line (`\\n`, `\\r\\n` or `\\r` line ends); `[DONE]` is skipped.\n *\n * @param body - The response body.\n * @param signal - Aborts the read.\n */\nexport async function* readSseJson(body: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncGenerator<unknown> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n const onAbort = (): void => {\n void reader.cancel().catch(() => {})\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n let buffer = ''\n let data: string[] = []\n const flush = function* (): Generator<unknown> {\n if (data.length === 0)\n return\n const payload = data.join('\\n').trim()\n data = []\n if (!payload || payload === '[DONE]')\n return\n try {\n yield JSON.parse(payload) as unknown\n }\n catch {\n throw new Error(`Google sent a stream event that isn't JSON: ${payload.slice(0, 200)}`)\n }\n }\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (signal?.aborted)\n throw abortError()\n buffer += done ? decoder.decode() : decoder.decode(value, { stream: true })\n for (let end = buffer.search(/\\r\\n|\\r|\\n/); end >= 0; end = buffer.search(/\\r\\n|\\r|\\n/)) {\n // A lone `\\r` at the end may be the first half of `\\r\\n`: wait for more.\n if (!done && end === buffer.length - 1 && buffer[end] === '\\r')\n break\n const line = buffer.slice(0, end)\n buffer = buffer.slice(end + (buffer.startsWith('\\r\\n', end) ? 2 : 1))\n if (line === '')\n yield* flush()\n else if (line.startsWith('data:'))\n data.push(line.slice(5).replace(/^ /, ''))\n }\n if (done)\n break\n }\n if (buffer.startsWith('data:'))\n data.push(buffer.slice(5).replace(/^ /, ''))\n yield* flush()\n }\n finally {\n signal?.removeEventListener('abort', onAbort)\n reader.releaseLock()\n }\n}\n\n/**\n * A Gemini API / Vertex AI event as a response chunk. An in-stream\n * `{ \"error\": … }` throws with its status.\n *\n * @param payload - One parsed `data:` payload.\n */\nexport function parseGoogleChunk(payload: unknown): GeminiResponseChunk {\n const error = (payload as { error?: unknown } | null)?.error\n if (error && typeof error === 'object')\n throw googleError(JSON.stringify({ error }))\n return payload as GeminiResponseChunk\n}\n\n/** A block of the turn being streamed. */\nexport type GeminiTurnBlock\n = | { type: 'text', text: string, signature?: string }\n | { type: 'thinking', text: string, signature?: string }\n | { type: 'call', id: string, name: string, args: Record<string, unknown>, signature?: string }\n\n/** Token counts and cost of a turn, Gemini's counts mapped to zidane's. */\nexport interface GeminiTurnUsage {\n /** Uncached prompt tokens. */\n input: number\n /** Answer and thought tokens. */\n output: number\n /** Cached prompt tokens. */\n cacheRead: number\n /** Thought tokens. */\n reasoning: number\n /** Cost at the model's rates, in USD. */\n cost: number\n}\n\n/** What a streamed turn came to. */\nexport interface GeminiTurn {\n /** Blocks in arrival order. */\n blocks: GeminiTurnBlock[]\n /** Text as streamed. */\n text: string\n /** The finish reason as Gemini sent it. */\n finishReason: string\n /** Token counts and cost. */\n usage: GeminiTurnUsage\n}\n\n/**\n * Cost of a turn at the model's rates (long-context tiers included).\n *\n * @param cost - Rates per million tokens.\n * @param usage - Token counts.\n */\nexport function turnCost(cost: GeminiModelCost, usage: Pick<GeminiTurnUsage, 'input' | 'output' | 'cacheRead'>): number {\n const inputTokens = usage.input + usage.cacheRead\n let rates: Omit<GeminiModelCost, 'tiers'> = cost\n let threshold = -1\n for (const tier of cost.tiers ?? []) {\n if (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > threshold) {\n rates = tier\n threshold = tier.inputTokensAbove\n }\n }\n return (rates.input * usage.input + rates.output * usage.output + rates.cacheRead * usage.cacheRead) / 1_000_000\n}\n\nfunction usageOf(metadata: GeminiUsageMetadata, cost: GeminiModelCost): GeminiTurnUsage {\n const cached = metadata.cachedContentTokenCount ?? 0\n const usage = {\n input: (metadata.promptTokenCount ?? 0) - cached,\n output: (metadata.candidatesTokenCount ?? 0) + (metadata.thoughtsTokenCount ?? 0),\n cacheRead: cached,\n reasoning: metadata.thoughtsTokenCount ?? 0,\n }\n return { ...usage, cost: turnCost(cost, usage) }\n}\n\ntype TextBlock = Extract<GeminiTurnBlock, { type: 'text' | 'thinking' }>\n\nlet generatedIds = 0\n\n/**\n * Streams the chunks into one turn, calling back text, thoughts and call\n * progress as they arrive. Consecutive text (or thought) parts merge into\n * one block, keeping the last signature any of them carried; each function\n * call is its own block. Throws when the turn stopped for anything but\n * `STOP` or `MAX_TOKENS` (safety, recitation, a malformed call, …), when\n * it ended without a finish reason, and when it was aborted.\n *\n * @param chunks - Response chunks.\n * @param cost - The model's rates.\n * @param callbacks - Stream callbacks.\n * @param signal - The request's abort signal.\n */\nexport async function collectGeminiTurn(\n chunks: AsyncIterable<GeminiResponseChunk>,\n cost: GeminiModelCost,\n callbacks: Pick<StreamCallbacks, 'onText' | 'onThinking' | 'onToolCallDelta'>,\n signal?: AbortSignal,\n): Promise<GeminiTurn> {\n const blocks: GeminiTurnBlock[] = []\n let current: TextBlock | undefined\n let text = ''\n let finishReason: string | undefined\n let usage: GeminiTurnUsage = { input: 0, output: 0, cacheRead: 0, reasoning: 0, cost: 0 }\n\n for await (const chunk of chunks) {\n const candidate = chunk.candidates?.[0]\n for (const part of candidate?.content?.parts ?? []) {\n if (part.text !== undefined) {\n const kind = part.thought === true ? 'thinking' : 'text'\n let block = current?.type === kind ? current : undefined\n if (!block) {\n const fresh: TextBlock = kind === 'thinking' ? { type: 'thinking', text: '' } : { type: 'text', text: '' }\n blocks.push(fresh)\n current = block = fresh\n }\n block.text += part.text\n if (part.thoughtSignature)\n block.signature = part.thoughtSignature\n if (kind === 'thinking') {\n callbacks.onThinking?.(part.text)\n }\n else {\n text += part.text\n callbacks.onText(part.text)\n }\n }\n if (part.functionCall) {\n current = undefined\n const name = part.functionCall.name ?? ''\n const provided = part.functionCall.id\n const id = provided && !blocks.some(b => b.type === 'call' && b.id === provided)\n ? provided\n : `${name}_${Date.now()}_${++generatedIds}`\n blocks.push({ type: 'call', id, name, args: part.functionCall.args ?? {}, ...(part.thoughtSignature ? { signature: part.thoughtSignature } : {}) })\n // Liveness: the call started, and its arguments arrived.\n callbacks.onToolCallDelta?.()\n callbacks.onToolCallDelta?.()\n }\n }\n if (candidate?.finishReason)\n finishReason = candidate.finishReason\n if (chunk.usageMetadata)\n usage = usageOf(chunk.usageMetadata, cost)\n }\n\n if (signal?.aborted)\n throw abortError()\n if (!finishReason)\n throw new Error('Google stream ended without a finish reason')\n if (finishReason !== 'STOP' && finishReason !== 'MAX_TOKENS')\n throw new Error(`Provider stopped with: ${finishReason}`)\n return { blocks, text, finishReason, usage }\n}\n","/**\n * Google Cloud credentials for Vertex AI, without google-auth-library: the\n * Application Default Credentials chain zidane's users rely on.\n *\n * 1. A credentials file: `GOOGLE_APPLICATION_CREDENTIALS` (or the\n * provider's `credentialsFile`), else gcloud's\n * `application_default_credentials.json`. `authorized_user` files\n * refresh their token at Google's token endpoint; `service_account` files\n * sign a JWT (RS256) and exchange it.\n * 2. Without a file, the metadata server of the machine (Compute Engine,\n * Cloud Run, GKE).\n *\n * A token is minted per request, as before. Other credential types\n * (`external_account`, `impersonated_service_account`) are refused with a\n * clear error.\n */\nimport { Buffer } from 'node:buffer'\nimport { createSign } from 'node:crypto'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { googleTokenRequest } from '../google-oauth'\n\nconst CLOUD_PLATFORM_SCOPE = 'https://www.googleapis.com/auth/cloud-platform'\nconst DEFAULT_TOKEN_URI = 'https://oauth2.googleapis.com/token'\n/** The metadata server answers at once on Google Cloud; elsewhere the address doesn't route. */\nconst METADATA_TIMEOUT_MS = 3_000\nconst TOKEN_TIMEOUT_MS = 30_000\n\n/** A bearer token and the project its requests bill, when the credentials name one. */\nexport interface GoogleCloudToken {\n /** OAuth access token. */\n token: string\n /** `quota_project_id` of the credentials: sent as `x-goog-user-project`. */\n quotaProject?: string\n}\n\ninterface CredentialsFile {\n type?: string\n client_id?: string\n client_secret?: string\n refresh_token?: string\n quota_project_id?: string\n client_email?: string\n private_key?: string\n private_key_id?: string\n token_uri?: string\n}\n\n/** Where gcloud keeps the Application Default Credentials. */\nfunction wellKnownCredentialsFile(): string {\n const config = process.env.CLOUDSDK_CONFIG\n || (process.platform === 'win32' && process.env.APPDATA ? join(process.env.APPDATA, 'gcloud') : join(homedir(), '.config', 'gcloud'))\n return join(config, 'application_default_credentials.json')\n}\n\nfunction readCredentials(file: string): CredentialsFile {\n let text: string\n try {\n text = readFileSync(file, 'utf8')\n }\n catch (err) {\n throw new Error(`Can't read the Google Cloud credentials file ${file}: ${(err as Error).message}`, { cause: err })\n }\n try {\n return JSON.parse(text) as CredentialsFile\n }\n catch (err) {\n throw new Error(`The Google Cloud credentials file ${file} isn't JSON.`, { cause: err })\n }\n}\n\nfunction base64url(value: string | Buffer): string {\n return Buffer.from(value).toString('base64url')\n}\n\nasync function serviceAccountToken(creds: CredentialsFile, file: string, signal?: AbortSignal): Promise<string> {\n if (!creds.client_email || !creds.private_key)\n throw new Error(`The service account file ${file} has no client_email or private_key.`)\n const tokenUri = creds.token_uri || DEFAULT_TOKEN_URI\n const now = Math.floor(Date.now() / 1000)\n const unsigned = `${base64url(JSON.stringify({ alg: 'RS256' }))}.${base64url(JSON.stringify({ iss: creds.client_email, scope: CLOUD_PLATFORM_SCOPE, aud: tokenUri, exp: now + 3600, iat: now }))}`\n const signature = createSign('RSA-SHA256').update(unsigned).sign(creds.private_key)\n const timeout = AbortSignal.timeout(TOKEN_TIMEOUT_MS)\n const response = await fetch(tokenUri, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', assertion: `${unsigned}.${base64url(signature)}` }).toString(),\n signal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n })\n const text = await response.text()\n if (!response.ok) {\n let reason = text.slice(0, 300)\n try {\n const parsed = JSON.parse(text) as { error?: string, error_description?: string }\n reason = [parsed.error, parsed.error_description].filter(Boolean).join(': ') || reason\n }\n catch { /* not JSON */ }\n throw new Error(`Google service account token request failed (${response.status}): ${reason}`)\n }\n return (JSON.parse(text) as { access_token: string }).access_token\n}\n\nasync function metadataToken(signal?: AbortSignal): Promise<string> {\n const host = process.env.GCE_METADATA_HOST || '169.254.169.254'\n const timeout = AbortSignal.timeout(METADATA_TIMEOUT_MS)\n let response: Response\n try {\n response = await fetch(`http://${host}/computeMetadata/v1/instance/service-accounts/default/token`, {\n headers: { 'Metadata-Flavor': 'Google' },\n signal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n })\n }\n catch (err) {\n if (signal?.aborted)\n throw err\n throw new Error('Could not load the default Google Cloud credentials. Run `gcloud auth application-default login`, or set GOOGLE_APPLICATION_CREDENTIALS to a credentials file.', { cause: err })\n }\n if (!response.ok)\n throw new Error(`The Google Cloud metadata server refused a token (${response.status}): ${(await response.text()).slice(0, 300)}`)\n return (await response.json() as { access_token: string }).access_token\n}\n\n/**\n * A fresh access token from Google Cloud credentials.\n *\n * @param credentialsFile - An explicit credentials file; else the\n * well-known gcloud file, else the metadata server.\n * @param signal - Aborts the token request.\n */\nexport async function googleCloudToken(credentialsFile?: string, signal?: AbortSignal): Promise<GoogleCloudToken> {\n const file = credentialsFile || (existsSync(wellKnownCredentialsFile()) ? wellKnownCredentialsFile() : undefined)\n if (!file)\n return { token: await metadataToken(signal) }\n const creds = readCredentials(file)\n const quota = creds.quota_project_id ? { quotaProject: creds.quota_project_id } : {}\n if (creds.type === 'authorized_user') {\n if (!creds.client_id || !creds.client_secret || !creds.refresh_token)\n throw new Error(`The credentials file ${file} has no client_id, client_secret or refresh_token.`)\n const tokens = await googleTokenRequest({\n refresh_token: creds.refresh_token,\n client_id: creds.client_id,\n client_secret: creds.client_secret,\n grant_type: 'refresh_token',\n }, signal)\n return { token: tokens.access_token, ...quota }\n }\n if (creds.type === 'service_account')\n return { token: await serviceAccountToken(creds, file, signal), ...quota }\n throw new Error(`Google Cloud credentials of type \"${creds.type ?? 'unknown'}\" (${file}) aren't supported. Use a service account key, or \\`gcloud auth application-default login\\`.`)\n}\n","/**\n * Gemini image generation on the Gemini API (Google AI Studio):\n * `generateContent` with `responseModalities: ['TEXT', 'IMAGE']`. Reference\n * images go in as `inlineData` parts. One image per request, so a request for\n * several sends several in parallel.\n */\n\nimport type { ImageModelInfo, ProviderImageResponse, ProviderImages } from './types'\nimport type { ImageFetch } from './wire'\nimport { imageCount, imageHttpError, repeatRequest } from './wire'\n\nconst BASE_URL = 'https://generativelanguage.googleapis.com/v1beta'\n\n/** Gemini image models on the Gemini API. */\nexport const GOOGLE_IMAGE_MODELS: readonly ImageModelInfo[] = [\n { id: 'gemini-3.1-flash-image', name: 'Gemini 3.1 Flash Image', input: ['text', 'image'] },\n { id: 'gemini-3-pro-image', name: 'Gemini 3 Pro Image', input: ['text', 'image'] },\n { id: 'gemini-3.1-flash-lite-image', name: 'Gemini 3.1 Flash Lite Image', input: ['text', 'image'] },\n { id: 'gemini-2.5-flash-image', name: 'Gemini 2.5 Flash Image', input: ['text', 'image'] },\n]\n\ninterface GenerateContentResponse {\n candidates?: Array<{\n finishReason?: string\n content?: { parts?: Array<{ text?: string, inlineData?: { mimeType?: string, data?: string } }> }\n }>\n promptFeedback?: { blockReason?: string }\n}\n\n/**\n * Gemini image generation as a {@link ProviderImages}. Unavailable while `resolveKey` returns `undefined`.\n *\n * @param options - Key resolver and test overrides.\n * @param options.resolveKey - Returns the Gemini API key, or `undefined` when none is set. Called on every request.\n * @param options.fetch - Fetch override, for tests.\n */\nexport function googleImages(options: { resolveKey: () => string | undefined, fetch?: ImageFetch }): ProviderImages {\n const doFetch = options.fetch ?? fetch\n return {\n defaultModel: GOOGLE_IMAGE_MODELS[0]!.id,\n models: GOOGLE_IMAGE_MODELS,\n availability: () => options.resolveKey()\n ? { available: true }\n : { available: false, reason: 'Gemini image generation needs a Gemini API key (GEMINI_API_KEY).' },\n async generate(request, signal) {\n const key = options.resolveKey()\n if (!key)\n throw new Error('Gemini image generation needs a Gemini API key. Set GEMINI_API_KEY, or add a key in the Google Gemini provider settings.')\n const body = {\n contents: [{\n role: 'user',\n parts: [\n { text: request.prompt },\n ...(request.references ?? []).map(ref => ({ inlineData: { mimeType: ref.mediaType, data: ref.data } })),\n ],\n }],\n generationConfig: {\n responseModalities: ['TEXT', 'IMAGE'],\n ...(request.aspectRatio ? { imageConfig: { aspectRatio: request.aspectRatio } } : {}),\n },\n }\n const once = async (): Promise<ProviderImageResponse> => {\n const res = await doFetch(`${BASE_URL}/models/${encodeURIComponent(request.model)}:generateContent`, {\n method: 'POST',\n headers: { 'x-goog-api-key': key, 'content-type': 'application/json' },\n body: JSON.stringify(body),\n signal,\n })\n if (!res.ok)\n throw await imageHttpError('Gemini', res)\n const json = await res.json() as GenerateContentResponse\n if (json.promptFeedback?.blockReason)\n throw new Error(`Gemini refused the prompt (${json.promptFeedback.blockReason}).`)\n const candidate = json.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n const images = parts.flatMap(part => part.inlineData?.data\n ? [{ mediaType: part.inlineData.mimeType ?? 'image/png', data: part.inlineData.data }]\n : [])\n const text = parts.flatMap(part => part.text ? [part.text] : []).join('\\n').trim()\n if (images.length === 0) {\n const reason = candidate?.finishReason && candidate.finishReason !== 'STOP' ? ` (${candidate.finishReason})` : ''\n throw new Error(`Gemini returned no image${reason}${text ? `: ${text}` : '.'}`)\n }\n return { images, model: request.model, ...(text ? { text } : {}) }\n }\n return repeatRequest(imageCount(request.count), once)\n },\n }\n}\n","/**\n * Google Gemini providers, on zidane's own Gemini REST client\n * (`streamGenerateContent` over SSE, see `./gemini`).\n *\n * - {@link google}: the Gemini API (Google AI Studio), authenticated by an\n * API key.\n * - {@link googleVertex}: Vertex AI, authenticated by Google Cloud\n * credentials (gcloud Application Default Credentials, a credentials file\n * or the metadata server), a \"Sign in with Google\" grant, or a Vertex API\n * key.\n * - {@link googleCompatible}: the same plumbing over another Gemini-wire\n * backend (an extension's transport, models and auth).\n *\n * Every request goes through the provider's `fetch`, so `http.request` /\n * `http.response` interceptors apply.\n *\n * Gemini signs its reasoning: thought signatures ride on text parts, thought\n * parts and function calls, and Gemini 3 rejects a tool-use step whose\n * function calls come back without theirs. These providers persist them on\n * the blocks that carried them (`signature`, `signatureProducer`) and\n * replay them only to the route that issued them, whatever the model:\n * Google's guidance is to resend a session's thought blocks as received,\n * model switches included.\n */\nimport type { Provider, ProviderCapabilities, StreamCallbacks, StreamOptions, ToolSpec, TurnResult } from '.'\nimport type { ClassifiedError } from '../errors'\nimport type { GeminiSignatureScope, SessionContentBlock, SessionMessage, TurnFinishReason, TurnUsage } from '../types'\nimport type { ModelCostRates } from './cost'\nimport type { GeminiBudgetTable, GeminiTool } from './gemini/request'\nimport type { GeminiRequest, GeminiResponseChunk, GoogleWireModel } from './gemini/types'\nimport type { ModelCatalog } from './model-catalog'\nimport type { OAuthParams } from './oauth'\nimport { getBuiltinModel } from '@earendil-works/pi-ai/providers/all'\nimport { classifyErrorPrelude, classifyProviderLimit, isRetryableHttpStatus, matchesContextExceeded, matchesToolPairingError, providerLimitReason } from '../errors'\nimport { renderSystemForWire } from '../system-prompt'\nimport { ZIDANE_VERSION } from '../version'\nimport { fillEstimatedCost } from './cost'\nimport { googleHttpError, leadingStatus } from './gemini/errors'\nimport { buildGeminiRequest } from './gemini/request'\nimport { collectGeminiTurn, parseGoogleChunk, readSseJson } from './gemini/stream'\nimport { googleCloudToken } from './gemini/vertex-auth'\nimport { GOOGLE_VERTEX_OAUTH_ID } from './google-oauth'\nimport { googleImages } from './images/google'\nimport { lookupModel as catalogLookup, mergeCatalogEntry } from './model-catalog'\nimport { pinnedAccountMissingError, readAccountOAuthCredential, readOAuthCredentials, resolveOAuthApiKey } from './oauth'\nimport { assistantMessage, toolResultsMessage, userMessage } from './openai-compat'\nimport { sanitizeToolSpecs } from './schema-sanitize'\nimport { createToolNameBoundary } from './tool-name-boundary'\n\nexport type { GeminiTool } from './gemini/request'\nexport { toGeminiContents } from './gemini/request'\nexport type { GeminiContent, GeminiFunctionDeclaration, GeminiGenerationConfig, GeminiPart, GeminiRequest, GeminiResponseChunk, GeminiThinkingConfig, GeminiToolConfig, GoogleWireModel } from './gemini/types'\n\n/** Zidane provider (and signature route) names of the two Google backends. */\nexport type GoogleRouteName = 'google' | 'google-vertex'\n\n/** Model used when a request names none. Served on free-tier Gemini API keys. */\nexport const GOOGLE_DEFAULT_MODEL = 'gemini-3.8-flash'\n\n/** A Google model pi-ai's registry hasn't bundled yet: a bundled `template` with the same thinking shape, under its own id. */\nexport interface GoogleExtraModel {\n /** Model id sent to the API. */\n id: string\n /** Display name. */\n name: string\n /** A bundled model with the same thinking levels and budgets. */\n template: string\n /** Context window in tokens. */\n contextWindow: number\n /** Largest output in tokens. */\n maxTokens: number\n /** A function, so a dated price change applies to long-running hosts. */\n rates: () => Required<ModelCostRates>\n}\n\n/**\n * Models pi-ai's registry hasn't bundled yet, served on both routes. A\n * pi-ai release that bundles one supersedes its entry (bundled metadata\n * always wins), so delete the entry then.\n */\nexport const GOOGLE_EXTRA_MODELS: readonly GoogleExtraModel[] = []\n\nconst GEMINI_API_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta'\nconst USER_AGENT = `zidane/${ZIDANE_VERSION}`\n\nconst lookupBuiltin = getBuiltinModel as (provider: string, modelId: string) => GoogleWireModel | undefined\n\nfunction builtinModel(route: GoogleRouteName, modelId: string): GoogleWireModel | undefined {\n try {\n return lookupBuiltin(route, modelId)\n }\n catch {\n return undefined\n }\n}\n\n/**\n * Model record for `modelId` on `route`: the registry's entry, else a\n * {@link GOOGLE_EXTRA_MODELS} overlay, else the default model's shape under\n * the requested id. A catalog entry overlays whichever applies.\n *\n * @param route - Backend the request goes to.\n * @param modelId - Requested model id.\n * @param catalog - Per-run catalog override.\n */\nexport function resolveGoogleModel(route: GoogleRouteName, modelId: string, catalog?: ModelCatalog): GoogleWireModel {\n const entry = catalogLookup(route, modelId, catalog)\n const bundled = builtinModel(route, modelId)\n if (bundled)\n return mergeCatalogEntry(bundled, entry)\n\n const extra = GOOGLE_EXTRA_MODELS.find(m => m.id === modelId)\n const template = builtinModel(route, extra?.template ?? GOOGLE_DEFAULT_MODEL)\n if (!template)\n throw new Error(`Google model registry (${route}) is missing ${extra?.template ?? GOOGLE_DEFAULT_MODEL}`)\n if (extra) {\n return mergeCatalogEntry({\n ...template,\n id: extra.id,\n name: extra.name,\n contextWindow: extra.contextWindow,\n maxTokens: extra.maxTokens,\n cost: extra.rates(),\n }, entry)\n }\n return mergeCatalogEntry({ ...template, id: modelId, name: modelId }, entry)\n}\n\nfunction formatTools(tools: ToolSpec[]): GeminiTool[] {\n // Sent as `parametersJsonSchema` (full JSON Schema); the OpenAI pass still\n // fixes the root shapes (`$ref`, `anyOf`, nullable roots) MCP servers\n // publish and Gemini rejects as well.\n return sanitizeToolSpecs(tools, { profile: 'openai' }).map(t => ({\n name: t.name,\n description: t.description ?? '',\n parameters: t.inputSchema,\n }))\n}\n\n/**\n * Transient Gemini failures worth a loop-level retry. The client itself\n * never retries.\n */\nconst TRANSIENT_GOOGLE_MESSAGE_RE = /RESOURCE_EXHAUSTED|UNAVAILABLE|DEADLINE_EXCEEDED|overloaded|high demand|rate.?limit|try again later/i\n\n/** Gemini's `RetryInfo` detail in a 429 body: `\"retryDelay\": \"34s\"`. */\nconst RETRY_DELAY_RE = /\"retryDelay\"\\s*:\\s*\"(\\d+(?:\\.\\d+)?)s\"/\n\n/**\n * Classify a Gemini API / Vertex AI error.\n *\n * @param err - Error a Google provider threw.\n * @param label - Product a limit's message names; routes over other services (Antigravity) pass their own.\n */\nexport function classifyGoogleError(err: unknown, label = 'Gemini'): ClassifiedError | null {\n const prelude = classifyErrorPrelude(err)\n if (prelude === 'not-object')\n return null\n if (prelude === 'aborted')\n return { kind: 'aborted' }\n const anyErr = err as { message?: unknown, status?: unknown, body?: unknown }\n const message = typeof anyErr.message === 'string' ? anyErr.message : ''\n if (matchesContextExceeded(message))\n return { kind: 'context_exceeded', providerCode: 'context_length_exceeded', message }\n if (matchesToolPairingError(message))\n return { kind: 'tool_pairing_corruption', message }\n if (!message)\n return null\n const status = typeof anyErr.status === 'number' ? anyErr.status : leadingStatus(message)\n const retryable = (status !== undefined && isRetryableHttpStatus(status)) || TRANSIENT_GOOGLE_MESSAGE_RE.test(message)\n const reason = providerLimitReason({ status, message })\n if (reason) {\n const delay = RETRY_DELAY_RE.exec(typeof anyErr.body === 'string' ? anyErr.body : message)\n return classifyProviderLimit(\n { reason, provider: label, ...(delay ? { retryAfterMs: Number(delay[1]) * 1000 } : {}) },\n { ...(status !== undefined ? { providerCode: String(status) } : {}), retryable },\n )\n }\n return {\n kind: 'provider_error',\n ...(status !== undefined ? { providerCode: String(status) } : {}),\n message,\n ...(retryable ? { retryable: true } : {}),\n }\n}\n\n/** One turn's request, handed to a {@link GoogleCompatibleRoute}'s `send`. */\nexport interface GoogleTurnRequest {\n /** The model record the route resolved. */\n model: GoogleWireModel\n /**\n * The standard `GenerateContentRequest`: contents with this route's\n * signatures, tools, forced tool choice, and `generationConfig` with the\n * output ceiling and the thinking config Gemini models take. A route may\n * edit it, or wrap it in its backend's envelope.\n */\n body: GeminiRequest\n /** Thinking level as requested, for a backend that maps it its own way. */\n thinking?: StreamOptions['thinking']\n /** Output ceiling as requested (the body's is already resolved). */\n maxTokens?: number\n /** Aborts the request. */\n signal?: AbortSignal\n /** The provider's extra headers (`extraHeaders`), to send on top of the route's. */\n headers: Record<string, string>\n /** Stream callbacks, for OAuth refresh hooks. */\n callbacks: StreamCallbacks\n}\n\n/**\n * A Gemini-wire backend for {@link googleCompatible}: where requests go and\n * how they authenticate (`send`), how its stream events read\n * (`parseChunk`) and which models it serves (`resolveModel`). Message\n * conversion, thought-signature bookkeeping, tool names, thinking levels,\n * SSE parsing, usage and cost stay in the shared plumbing.\n */\nexport interface GoogleCompatibleRoute {\n /**\n * Provider name (`Provider.name`, error copy) and the default signature\n * scope. Must not be a built-in provider name (`google`,\n * `google-vertex`, `anthropic`, `openai`).\n */\n name: string\n /**\n * Sends one turn and returns the streaming response\n * (`streamGenerateContent?alt=sse` or the backend's equivalent). Send it\n * with `fetch`: it is the provider's, carrying the `http.request` /\n * `http.response` interceptors. A non-2xx response is read as a Google\n * error; throw instead to report the backend's own (with a numeric\n * `status` so it classifies by HTTP status).\n *\n * @param request - The turn: model, standard body, settings, signal.\n * @param fetch - The provider's fetch.\n */\n send: (request: GoogleTurnRequest, fetch: typeof globalThis.fetch) => Promise<Response>\n /**\n * One SSE event's JSON to a `GenerateContentResponse`, for a backend that\n * wraps it (Cloud Code Assist's `{ response }`). Throw for an in-stream\n * error. Defaults to the event as is, an `{ error }` event thrown as a\n * Google error.\n */\n parseChunk?: (payload: unknown) => GeminiResponseChunk\n /** Whether the provider runs on an OAuth credential. */\n isOAuth: boolean\n /**\n * Model record for a requested model id. Its `cost` rates price each\n * turn: zero rates report no cost (quota-backed access).\n *\n * @param modelId - Requested model id.\n * @param catalog - Per-run catalog override.\n */\n resolveModel: (modelId: string, catalog?: ModelCatalog) => GoogleWireModel\n /**\n * Signature scope of a model: the tag its thought signatures carry, and\n * the only scope they replay to. Defaults to `name`, right when every model\n * behind the backend accepts the others' signatures (Gemini does). A\n * backend fronting several model families returns one scope per family,\n * so switching families mid-session sends earlier reasoning unsigned.\n *\n * @param modelId - Model id of the turn.\n */\n signatureScope?: (modelId: string) => string\n /** Error classification. Defaults to {@link classifyGoogleError}. */\n classifyError?: (err: unknown) => ClassifiedError | null\n}\n\n/** A route plus the budget table only the built-in Vertex route changes. */\ninterface GoogleRoute extends GoogleCompatibleRoute {\n budgets: GeminiBudgetTable\n}\n\n/** Names a {@link googleCompatible} route can't take: built-in providers and signature producers. */\nconst RESERVED_ROUTE_NAMES: ReadonlySet<string> = new Set(['google', 'google-vertex', 'anthropic', 'openai', 'zidane'])\n\n/** Settings shared by the Google providers. */\nexport interface GoogleSharedParams {\n /**\n * Model used when a request does not set one.\n * @default 'gemini-3.8-flash'\n */\n defaultModel?: string\n /**\n * Provider capability flags. Gemini takes images and files (PDFs and\n * others) in prompts and in tool results; audio and video are refused.\n */\n capabilities?: ProviderCapabilities\n /** Extra HTTP headers sent on every request. */\n extraHeaders?: Record<string, string>\n}\n\n/** JSON request headers: the route's, then the provider's extra headers on top (case-insensitively). */\nfunction requestHeaders(route: Record<string, string>, extra: Record<string, string>): Headers {\n const headers = new Headers({ 'Content-Type': 'application/json', 'User-Agent': USER_AGENT, ...route })\n for (const [key, value] of Object.entries(extra))\n headers.set(key, value)\n return headers\n}\n\n/** POSTs a turn's body as JSON with the route's auth headers. */\nfunction postTurn(fetch: typeof globalThis.fetch, url: string, request: GoogleTurnRequest, headers: Record<string, string>): Promise<Response> {\n return fetch(url, {\n method: 'POST',\n headers: requestHeaders(headers, request.headers),\n body: JSON.stringify(request.body),\n ...(request.signal ? { signal: request.signal } : {}),\n })\n}\n\nfunction finishReasonOf(raw: string, hasToolCalls: boolean): TurnFinishReason {\n if (raw === 'MAX_TOKENS')\n return 'length'\n return hasToolCalls ? 'tool-calls' : 'stop'\n}\n\nfunction createGoogleProvider(route: GoogleRoute, params: GoogleSharedParams | undefined): Provider {\n const defaultModel = params?.defaultModel || GOOGLE_DEFAULT_MODEL\n const capabilities: ProviderCapabilities = params?.capabilities ?? {\n vision: true,\n imageInToolResult: true,\n audio: false,\n video: false,\n documents: true,\n }\n\n return {\n name: route.name,\n meta: { defaultModel, isOAuth: route.isOAuth, capabilities },\n formatTools,\n userMessage,\n assistantMessage,\n toolResultsMessage,\n classifyError: route.classifyError ?? classifyGoogleError,\n\n async stream(options: StreamOptions, callbacks: StreamCallbacks): Promise<TurnResult> {\n const modelId = options.model || defaultModel\n const model = route.resolveModel(modelId, options.modelCatalog)\n const scope = signatureScopeOf(route, model.id)\n const tools = options.tools as GeminiTool[]\n const nameBoundary = createToolNameBoundary(options.messages, tools.map(tool => tool.name))\n const body = buildGeminiRequest({\n messages: nameBoundary.messages,\n model,\n scope,\n provider: route.name,\n system: renderSystemForWire(options.system),\n tools: tools.map(tool => ({ ...tool, name: nameBoundary.toWire(tool.name) })),\n ...(options.thinking !== undefined ? { thinking: options.thinking } : {}),\n ...(options.thinkingBudget !== undefined ? { thinkingBudget: options.thinkingBudget } : {}),\n ...(options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n ...(options.toolChoice ? { toolChoice: options.toolChoice } : {}),\n toWire: nameBoundary.toWire,\n budgets: route.budgets,\n })\n const fetchImpl = options.wrapFetch ? options.wrapFetch(globalThis.fetch) : globalThis.fetch\n const response = await route.send({\n model,\n body,\n ...(options.thinking !== undefined ? { thinking: options.thinking } : {}),\n ...(options.maxTokens !== undefined ? { maxTokens: options.maxTokens } : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n headers: params?.extraHeaders ?? {},\n callbacks,\n }, fetchImpl)\n if (!response.ok)\n throw await googleHttpError(response)\n if (!response.body)\n throw new Error(`${route.name} answered without a body.`)\n\n const parse = route.parseChunk ?? parseGoogleChunk\n const events = readSseJson(response.body, options.signal)\n const chunks = (async function* () {\n for await (const event of events)\n yield parse(event)\n })()\n const turn = await collectGeminiTurn(chunks, model.cost, callbacks, options.signal)\n\n const signed = (signature: string | undefined) => signature ? { signature, signatureProducer: scope } : {}\n const content: SessionContentBlock[] = []\n const toolCalls: TurnResult['toolCalls'] = []\n for (const block of turn.blocks) {\n if (block.type === 'call') {\n const name = nameBoundary.fromWire(block.name)\n toolCalls.push({ id: block.id, name, input: block.args })\n content.push({ type: 'tool_call', id: block.id, name, input: block.args, ...signed(block.signature) })\n }\n else {\n content.push({ type: block.type, text: block.text, ...signed(block.signature) })\n }\n }\n const finishReason = finishReasonOf(turn.finishReason, toolCalls.length > 0)\n const usage: TurnUsage = await fillEstimatedCost({\n input: turn.usage.input,\n output: turn.usage.output,\n cacheRead: turn.usage.cacheRead || undefined,\n ...(turn.usage.reasoning ? { thinking: turn.usage.reasoning } : {}),\n cost: turn.usage.cost || undefined,\n finishReason,\n modelId,\n }, route.name, undefined, options.modelCatalog)\n\n const assistantTurn: SessionMessage = { role: 'assistant', content }\n return {\n assistantMessage: assistantTurn,\n text: turn.text || turn.blocks.flatMap(block => block.type === 'text' ? [block.text] : []).join(''),\n toolCalls,\n done: toolCalls.length === 0,\n usage,\n }\n },\n }\n}\n\n/**\n * The scope a model's thought signatures carry. A custom route's scope can't\n * impersonate a built-in producer, whose signatures it would then replay.\n */\nfunction signatureScopeOf(route: GoogleCompatibleRoute, modelId: string): GeminiSignatureScope {\n const scope = route.signatureScope?.(modelId) ?? route.name\n if (scope !== route.name && RESERVED_ROUTE_NAMES.has(scope))\n throw new Error(`${route.name}: signature scope \"${scope}\" is reserved for a built-in provider`)\n return scope\n}\n\n/**\n * Creates a provider over another Gemini-wire backend: an extension supplies\n * the transport (`send`, `parseChunk`) and model records; message\n * conversion, thought signatures (tagged with the route's scope, never\n * replayed elsewhere), tool names, thinking levels, SSE parsing, usage and\n * cost come from the same plumbing as {@link google} and\n * {@link googleVertex}.\n *\n * @param route - The backend: name, transport and models.\n * @param params - Default model, capabilities and extra headers.\n *\n * @example\n * ```ts\n * import { googleCompatible } from 'zidane/providers'\n *\n * const provider = googleCompatible({\n * name: 'my-gateway',\n * isOAuth: false,\n * send: (turn, fetch) => fetch(`https://gateway.example/v1beta/models/${turn.model.id}:streamGenerateContent?alt=sse`, {\n * method: 'POST',\n * headers: { 'content-type': 'application/json', 'authorization': `Bearer ${process.env.MY_GATEWAY_KEY}` },\n * body: JSON.stringify(turn.body),\n * signal: turn.signal,\n * }),\n * resolveModel: id => myModels[id],\n * }, { defaultModel: 'gemini-3.8-flash' })\n * ```\n */\nexport function googleCompatible(route: GoogleCompatibleRoute, params?: GoogleSharedParams): Provider {\n if (!route.name || RESERVED_ROUTE_NAMES.has(route.name))\n throw new Error(`googleCompatible: route name \"${route.name}\" is reserved for a built-in provider`)\n return createGoogleProvider({ ...route, budgets: 'gemini-api' }, params)\n}\n\n/** Options for {@link google}. */\nexport interface GoogleParams extends GoogleSharedParams {\n /** Gemini API key. Defaults to `GEMINI_API_KEY`, then `GOOGLE_API_KEY`. */\n apiKey?: string\n}\n\n/**\n * Creates the Google Gemini provider on the Gemini API (Google AI Studio).\n * Authenticates with `apiKey`, else `GEMINI_API_KEY`, else `GOOGLE_API_KEY`.\n *\n * @param params - API key, default model, capabilities and extra headers.\n *\n * @example\n * ```ts\n * import { createAgent } from 'zidane'\n * import { google } from 'zidane/providers/google'\n *\n * const agent = createAgent({\n * provider: google({ apiKey: process.env.GEMINI_API_KEY }),\n * })\n * await agent.run({ prompt: 'Say hello.' })\n * ```\n */\nexport function google(params?: GoogleParams): Provider {\n const resolveKey = (): string | undefined => params?.apiKey || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY\n const provider = createGoogleProvider({\n name: 'google',\n isOAuth: false,\n budgets: 'gemini-api',\n resolveModel: (modelId, catalog) => resolveGoogleModel('google', modelId, catalog),\n send: async (request, fetch) => {\n const apiKey = resolveKey()\n if (!apiKey)\n throw new Error('No Gemini API key found. Set GEMINI_API_KEY, or add a key in the Google Gemini provider settings.')\n const base = request.model.baseUrl || GEMINI_API_BASE_URL\n return postTurn(fetch, `${base}/models/${request.model.id}:streamGenerateContent?alt=sse`, request, { 'x-goog-api-key': apiKey })\n },\n }, params)\n return { ...provider, images: googleImages({ resolveKey }) }\n}\n\n/** Options for {@link googleVertex}. */\nexport interface GoogleVertexParams extends GoogleSharedParams {\n /**\n * Vertex AI API key (express mode). Defaults to `GOOGLE_CLOUD_API_KEY`.\n * Without one, requests authenticate with Google Cloud credentials.\n */\n apiKey?: string\n /** Google Cloud project. Defaults to `GOOGLE_CLOUD_PROJECT`, then `GCLOUD_PROJECT`. */\n project?: string\n /** Vertex AI location. Defaults to `GOOGLE_CLOUD_LOCATION`, then `global`. */\n location?: string\n /**\n * Service-account or authorized-user credentials file. Defaults to\n * `GOOGLE_APPLICATION_CREDENTIALS`, then gcloud's Application Default\n * Credentials (`gcloud auth application-default login`), then the\n * metadata server on Google Cloud.\n */\n credentialsFile?: string\n /**\n * Run on one stored \"Sign in with Google\" account (its stable id) rather\n * than the active one. See {@link OAuthParams.account}.\n */\n account?: OAuthParams['account']\n}\n\n/** Where a Vertex AI request goes and how it authenticates. */\nexport interface VertexRequestAuth {\n /** The `streamGenerateContent` URL of a model. */\n url: (modelId: string) => string\n /** Auth headers: `x-goog-api-key`, or a bearer token and the billed project. */\n headers: Record<string, string>\n}\n\n/** Multi-region locations, served from their own regional endpoint. */\nconst MULTI_REGIONAL_LOCATIONS: ReadonlySet<string> = new Set(['us', 'eu'])\n\nfunction vertexProjectUrl(project: string, location: string): (modelId: string) => string {\n const host = location === 'global'\n ? 'https://aiplatform.googleapis.com'\n : MULTI_REGIONAL_LOCATIONS.has(location)\n ? `https://aiplatform.${location}.rep.googleapis.com`\n : `https://${location}-aiplatform.googleapis.com`\n return modelId => `${host}/v1/projects/${project}/locations/${location}/publishers/google/models/${modelId}:streamGenerateContent?alt=sse`\n}\n\n/** The fields a \"Sign in with Google\" grant carries beyond the token triple. */\ninterface VertexGrant {\n refresh: string\n projectId: string\n clientId: string\n clientSecret: string\n}\n\n/**\n * Request auth from the stored \"Sign in with Google\" grant (the pinned\n * account's, else the active one), or `undefined` when none is stored. The\n * access token rotates through zidane's OAuth path (cross-process locks,\n * persistence, refresh hooks, a clear \"sign in again\" for a revoked grant)\n * and goes out as the bearer token, the grant's project billed.\n */\nasync function signedInAuth(\n params: GoogleVertexParams | undefined,\n callbacks: StreamCallbacks | undefined,\n): Promise<VertexRequestAuth | undefined> {\n const account = params?.account\n const read = () => account\n ? readAccountOAuthCredential(GOOGLE_VERTEX_OAUTH_ID, account)\n : readOAuthCredentials()[GOOGLE_VERTEX_OAUTH_ID]\n if (!read()) {\n if (account)\n throw new Error(pinnedAccountMissingError('google-vertex'))\n return undefined\n }\n const token = await resolveOAuthApiKey({\n provider: 'google-vertex',\n providerId: GOOGLE_VERTEX_OAUTH_ID,\n ...(account ? { params: { account } } : {}),\n missingError: 'No Google sign-in found for Vertex AI. Sign in with Google again.',\n refreshError: reason => `Google sign-in refresh failed. Sign in with Google again. ${reason}`,\n }, callbacks)\n const grant = read() as Partial<VertexGrant> | undefined\n if (!grant?.refresh || !grant.clientId || !grant.clientSecret || !grant.projectId)\n throw new Error('This Google sign-in is missing its OAuth client or project. Sign in with Google again.')\n const project = params?.project || grant.projectId\n return {\n url: vertexProjectUrl(project, params?.location || process.env.GOOGLE_CLOUD_LOCATION || 'global'),\n headers: { 'Authorization': `Bearer ${token}`, 'x-goog-user-project': project },\n }\n}\n\n/**\n * Where a Vertex AI request goes and its credentials, read per turn so a\n * credential configured after the provider was built still applies. In\n * order: a pinned account's sign-in, a Vertex API key, the active \"Sign in\n * with Google\" grant, then Google Cloud credentials for the project (a\n * credentials file, gcloud's Application Default Credentials, the metadata\n * server), a fresh token minted per request.\n *\n * @param params - Explicit settings; environment variables fill the rest.\n * @param callbacks - Stream callbacks, for the OAuth refresh hook.\n * @param signal - Aborts a token request.\n */\nexport async function resolveVertexAuth(params?: GoogleVertexParams, callbacks?: StreamCallbacks, signal?: AbortSignal): Promise<VertexRequestAuth> {\n if (params?.account)\n return (await signedInAuth(params, callbacks))!\n const apiKey = params?.apiKey || process.env.GOOGLE_CLOUD_API_KEY\n if (apiKey) {\n return {\n url: modelId => `https://aiplatform.googleapis.com/v1/publishers/google/models/${modelId}:streamGenerateContent?alt=sse`,\n headers: { 'x-goog-api-key': apiKey },\n }\n }\n const signedIn = await signedInAuth(params, callbacks)\n if (signedIn)\n return signedIn\n const project = params?.project || process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT\n if (!project)\n throw new Error('Vertex AI needs a Google Cloud project. Set GOOGLE_CLOUD_PROJECT, or configure it in the Google Vertex AI provider settings.')\n const location = params?.location || process.env.GOOGLE_CLOUD_LOCATION || 'global'\n const { token, quotaProject } = await googleCloudToken(params?.credentialsFile || process.env.GOOGLE_APPLICATION_CREDENTIALS, signal)\n return {\n url: vertexProjectUrl(project, location),\n headers: { Authorization: `Bearer ${token}`, ...(quotaProject ? { 'x-goog-user-project': quotaProject } : {}) },\n }\n}\n\n/**\n * Creates the Google Vertex AI provider. Authenticates with a pinned\n * `account`'s Google sign-in, else a Vertex API key (`apiKey` or\n * `GOOGLE_CLOUD_API_KEY`), else the active \"Sign in with Google\" grant, else\n * Google Cloud credentials for `project` in `location`. See\n * {@link resolveVertexAuth}.\n *\n * @param params - Credentials, project, location, default model, capabilities and extra headers.\n *\n * @example\n * ```ts\n * import { createAgent } from 'zidane'\n * import { googleVertex } from 'zidane/providers/google'\n *\n * // After `gcloud auth application-default login`:\n * const agent = createAgent({\n * provider: googleVertex({ project: 'my-project' }),\n * })\n * await agent.run({ prompt: 'Say hello.' })\n * ```\n */\nexport function googleVertex(params?: GoogleVertexParams): Provider {\n return createGoogleProvider({\n name: 'google-vertex',\n isOAuth: !!params?.account || !(params?.apiKey || process.env.GOOGLE_CLOUD_API_KEY),\n budgets: 'vertex',\n resolveModel: (modelId, catalog) => resolveGoogleModel('google-vertex', modelId, catalog),\n send: async (request, fetch) => {\n const auth = await resolveVertexAuth(params, request.callbacks, request.signal)\n return postTurn(fetch, auth.url(request.model.id), request, auth.headers)\n },\n }, params)\n}\n"],"mappings":"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"}
|