openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
116 lines (115 loc) • 4.04 kB
JavaScript
import { i as assertOkOrThrowProviderError } from "../../provider-http-errors-DqaqQLLZ.js";
import { r as describeImagesWithModel, t as describeImageWithModel } from "../../image-runtime-CmS6zMcE.js";
import "../../media-understanding-1KBZ_bnJ.js";
import { c as postJsonRequest } from "../../shared-IuCmx8oC.js";
import "../../provider-http-BXCBCi4E.js";
import { n as normalizeGoogleModelId } from "../../model-id-BCw7D6_O.js";
import { t as DEFAULT_GOOGLE_API_BASE_URL } from "../../provider-policy-CT7vRcoH.js";
import { t as resolveGoogleGenerativeAiHttpRequestConfig } from "../../api-Cysqpi9q.js";
import "../../runtime-api-BPKjuU0j.js";
//#region extensions/google/media-understanding-provider.ts
const DEFAULT_GOOGLE_AUDIO_BASE_URL = DEFAULT_GOOGLE_API_BASE_URL;
const DEFAULT_GOOGLE_VIDEO_BASE_URL = DEFAULT_GOOGLE_API_BASE_URL;
const DEFAULT_GOOGLE_AUDIO_MODEL = "gemini-3-flash-preview";
const DEFAULT_GOOGLE_VIDEO_MODEL = "gemini-3-flash-preview";
const DEFAULT_GOOGLE_AUDIO_PROMPT = "Transcribe the audio.";
const DEFAULT_GOOGLE_VIDEO_PROMPT = "Describe the video.";
async function generateGeminiInlineDataText(params) {
const fetchFn = params.fetchFn ?? fetch;
const model = (() => {
const trimmed = params.model?.trim();
if (!trimmed) return params.defaultModel;
return normalizeGoogleModelId(trimmed);
})();
const { baseUrl, allowPrivateNetwork, headers, dispatcherPolicy } = resolveGoogleGenerativeAiHttpRequestConfig({
apiKey: params.apiKey,
baseUrl: params.baseUrl,
headers: params.headers,
request: params.request,
capability: params.defaultMime.startsWith("audio/") ? "audio" : "video",
transport: "media-understanding"
});
const { response: res, release } = await postJsonRequest({
url: `${baseUrl ?? params.defaultBaseUrl}/models/${model}:generateContent`,
headers,
body: { contents: [{
role: "user",
parts: [{ text: (() => {
return params.prompt?.trim() || params.defaultPrompt;
})() }, { inline_data: {
mime_type: params.mime ?? params.defaultMime,
data: params.buffer.toString("base64")
} }]
}] },
timeoutMs: params.timeoutMs,
fetchFn,
allowPrivateNetwork,
dispatcherPolicy
});
try {
await assertOkOrThrowProviderError(res, params.httpErrorLabel);
const text = ((await res.json()).candidates?.[0]?.content?.parts ?? []).map((part) => part?.text?.trim()).filter(Boolean).join("\n");
if (!text) throw new Error(params.missingTextError);
return {
text,
model
};
} finally {
await release();
}
}
async function transcribeGeminiAudio(params) {
const { text, model } = await generateGeminiInlineDataText({
...params,
defaultBaseUrl: DEFAULT_GOOGLE_AUDIO_BASE_URL,
defaultModel: DEFAULT_GOOGLE_AUDIO_MODEL,
defaultPrompt: DEFAULT_GOOGLE_AUDIO_PROMPT,
defaultMime: "audio/wav",
httpErrorLabel: "Audio transcription failed",
missingTextError: "Audio transcription response missing text"
});
return {
text,
model
};
}
async function describeGeminiVideo(params) {
const { text, model } = await generateGeminiInlineDataText({
...params,
defaultBaseUrl: DEFAULT_GOOGLE_VIDEO_BASE_URL,
defaultModel: DEFAULT_GOOGLE_VIDEO_MODEL,
defaultPrompt: DEFAULT_GOOGLE_VIDEO_PROMPT,
defaultMime: "video/mp4",
httpErrorLabel: "Video description failed",
missingTextError: "Video description response missing text"
});
return {
text,
model
};
}
const googleMediaUnderstandingProvider = {
id: "google",
capabilities: [
"image",
"audio",
"video"
],
defaultModels: {
image: DEFAULT_GOOGLE_VIDEO_MODEL,
audio: DEFAULT_GOOGLE_AUDIO_MODEL,
video: DEFAULT_GOOGLE_VIDEO_MODEL
},
autoPriority: {
image: 30,
audio: 40,
video: 10
},
nativeDocumentInputs: ["pdf"],
describeImage: describeImageWithModel,
describeImages: describeImagesWithModel,
transcribeAudio: transcribeGeminiAudio,
describeVideo: describeGeminiVideo
};
//#endregion
export { DEFAULT_GOOGLE_AUDIO_BASE_URL, DEFAULT_GOOGLE_VIDEO_BASE_URL, describeGeminiVideo, googleMediaUnderstandingProvider, transcribeGeminiAudio };