diff --git a/payloads/cases/models.ts b/payloads/cases/models.ts index 94623c59..4a935960 100644 --- a/payloads/cases/models.ts +++ b/payloads/cases/models.ts @@ -14,3 +14,5 @@ export const BEDROCK_ANTHROPIC_MODEL = "us.anthropic.claude-haiku-4-5-20251001-v1:0"; export const VERTEX_ANTHROPIC_MODEL = "publishers/anthropic/models/claude-haiku-4-5"; +export const VERTEX_GOOGLE_MODEL = + "publishers/google/models/gemini-2.5-flash-lite"; diff --git a/payloads/cases/params.ts b/payloads/cases/params.ts index 059162c9..4d5fcff3 100644 --- a/payloads/cases/params.ts +++ b/payloads/cases/params.ts @@ -14,6 +14,7 @@ import { ANTHROPIC_OPUS_MODEL, GOOGLE_GEMINI_3_MODEL, GOOGLE_IMAGE_MODEL, + VERTEX_GOOGLE_MODEL, } from "./models"; // OpenAI Responses API and Chat Completions API parameter test cases @@ -108,6 +109,15 @@ export const paramsCases: TestCaseCollection = { responseMimeType: "application/json", }, }, + "vertex-google": { + model: VERTEX_GOOGLE_MODEL, + contents: [ + { role: "user", parts: [{ text: 'Return {"status": "ok"} as JSON.' }] }, + ], + generationConfig: { + responseMimeType: "application/json", + }, + }, bedrock: null, }, @@ -190,6 +200,21 @@ export const paramsCases: TestCaseCollection = { }, }, }, + "vertex-google": { + model: VERTEX_GOOGLE_MODEL, + contents: [{ role: "user", parts: [{ text: "Extract: John is 25." }] }], + generationConfig: { + responseMimeType: "application/json", + responseJsonSchema: { + type: "object", + properties: { + name: { type: "string" }, + age: { type: "number" }, + }, + required: ["name", "age"], + }, + }, + }, bedrock: null, }, @@ -274,6 +299,21 @@ export const paramsCases: TestCaseCollection = { }, }, }, + "vertex-google": { + model: VERTEX_GOOGLE_MODEL, + contents: [{ role: "user", parts: [{ text: "Extract: John is 25." }] }], + generationConfig: { + responseMimeType: "application/json", + responseJsonSchema: { + type: "object", + properties: { + name: { type: "string" }, + age: { type: "number" }, + }, + required: ["name", "age"], + }, + }, + }, bedrock: null, }, diff --git a/payloads/cases/simple.ts b/payloads/cases/simple.ts index 11c152c2..d78b2781 100644 --- a/payloads/cases/simple.ts +++ b/payloads/cases/simple.ts @@ -7,6 +7,7 @@ import { BEDROCK_MODEL, BEDROCK_ANTHROPIC_MODEL, VERTEX_ANTHROPIC_MODEL, + VERTEX_GOOGLE_MODEL, } from "./models"; // Simple test cases - basic functionality testing @@ -86,6 +87,16 @@ export const simpleCases: TestCaseCollection = { }, ], }, + + "vertex-google": { + model: VERTEX_GOOGLE_MODEL, + contents: [ + { + role: "user", + parts: [{ text: "What is the capital of France?" }], + }, + ], + }, }, reasoningRequest: { @@ -173,6 +184,20 @@ export const simpleCases: TestCaseCollection = { }, ], }, + + "vertex-google": { + model: VERTEX_GOOGLE_MODEL, + contents: [ + { + role: "user", + parts: [ + { + text: "Solve this step by step: If a train travels 60 mph for 2 hours, then 80 mph for 1 hour, what's the average speed?", + }, + ], + }, + ], + }, }, reasoningRequestTruncated: { @@ -268,6 +293,23 @@ export const simpleCases: TestCaseCollection = { }, ], }, + + "vertex-google": { + model: VERTEX_GOOGLE_MODEL, + contents: [ + { + role: "user", + parts: [ + { + text: "Solve this step by step: If a train travels 60 mph for 2 hours, then 80 mph for 1 hour, what's the average speed?", + }, + ], + }, + ], + generationConfig: { + maxOutputTokens: 100, + }, + }, }, toolCallRequest: { @@ -469,5 +511,35 @@ export const simpleCases: TestCaseCollection = { }, ], }, + + "vertex-google": { + model: VERTEX_GOOGLE_MODEL, + contents: [ + { + role: "user", + parts: [{ text: "What's the weather like in San Francisco?" }], + }, + ], + tools: [ + { + functionDeclarations: [ + { + name: "get_weather", + description: "Get the current weather for a location", + parameters: { + type: Type.OBJECT, + properties: { + location: { + type: Type.STRING, + description: "The city and state, e.g. San Francisco, CA", + }, + }, + required: ["location"], + }, + }, + ], + }, + ], + }, }, }; diff --git a/payloads/cases/types.ts b/payloads/cases/types.ts index d716dd0f..a2786212 100644 --- a/payloads/cases/types.ts +++ b/payloads/cases/types.ts @@ -47,6 +47,7 @@ export interface TestCase { bedrock: BedrockConverseRequest | null; "bedrock-anthropic"?: AnthropicMessageCreateParams | null; "vertex-anthropic"?: AnthropicMessageCreateParams | null; + "vertex-google"?: GoogleGenerateContentRequest | null; // Optional expectations for proxy compatibility tests expect?: TestExpectation; } @@ -67,4 +68,5 @@ export const PROVIDER_TYPES = [ "bedrock", "bedrock-anthropic", "vertex-anthropic", + "vertex-google", ] as const; diff --git a/payloads/scripts/capture.ts b/payloads/scripts/capture.ts index 3fd52f8b..fe5f56f9 100644 --- a/payloads/scripts/capture.ts +++ b/payloads/scripts/capture.ts @@ -14,6 +14,7 @@ import { googleExecutor } from "./providers/google"; import { bedrockExecutor } from "./providers/bedrock"; import { bedrockAnthropicExecutor } from "./providers/bedrock-anthropic"; import { vertexAnthropicExecutor } from "./providers/vertex-anthropic"; +import { vertexGoogleExecutor } from "./providers/vertex-google"; import { type ProviderExecutor } from "./types"; // Update provider names to be more descriptive @@ -25,6 +26,7 @@ const allProviders = [ bedrockExecutor, bedrockAnthropicExecutor, vertexAnthropicExecutor, + vertexGoogleExecutor, ] as const; interface CaptureOptions { diff --git a/payloads/scripts/providers/vertex-google.ts b/payloads/scripts/providers/vertex-google.ts new file mode 100644 index 00000000..a72fa145 --- /dev/null +++ b/payloads/scripts/providers/vertex-google.ts @@ -0,0 +1,413 @@ +import { readFileSync } from "fs"; +import { resolve, isAbsolute } from "path"; +import { createSign } from "crypto"; +import { CaptureResult, ExecuteOptions, ProviderExecutor } from "../types"; +import { + allTestCases, + getCaseNames, + getCaseForProvider, + hasExpectation, + type GoogleGenerateContentRequest, + VERTEX_GOOGLE_MODEL, +} from "../../cases"; + +export const vertexGoogleCases: Record = + {}; + +getCaseNames(allTestCases).forEach((caseName) => { + if (hasExpectation(allTestCases, caseName)) { + return; + } + const caseData = getCaseForProvider(allTestCases, caseName, "vertex-google"); + if (caseData) { + vertexGoogleCases[caseName] = caseData; + } +}); + +interface ServiceAccountKey { + client_email: string; + private_key: string; + token_uri: string; +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null; +} + +function parseAccessTokenResponse(value: unknown): { + access_token: string; + expires_in: number; +} { + if (!isRecord(value)) { + throw new Error("Invalid access token response: expected object"); + } + const accessToken = value.access_token; + const expiresIn = value.expires_in; + if (typeof accessToken !== "string") { + throw new Error( + "Invalid access token response: access_token must be string" + ); + } + if (typeof expiresIn !== "number") { + throw new Error("Invalid access token response: expires_in must be number"); + } + return { access_token: accessToken, expires_in: expiresIn }; +} + +function loadServiceAccountKey(): ServiceAccountKey { + const credPath = process.env.GOOGLE_APPLICATION_CREDENTIALS; + if (!credPath) { + throw new Error( + "GOOGLE_APPLICATION_CREDENTIALS environment variable is required" + ); + } + const resolvedPath = isAbsolute(credPath) + ? credPath + : resolve(process.cwd(), credPath); + const raw = readFileSync(resolvedPath, "utf-8"); + return JSON.parse(raw); +} + +function createSignedJwt(key: ServiceAccountKey): string { + const now = Math.floor(Date.now() / 1000); + const header = Buffer.from( + JSON.stringify({ alg: "RS256", typ: "JWT" }) + ).toString("base64url"); + const payload = Buffer.from( + JSON.stringify({ + iss: key.client_email, + sub: key.client_email, + aud: key.token_uri, + iat: now, + exp: now + 3600, + scope: "https://www.googleapis.com/auth/cloud-platform", + }) + ).toString("base64url"); + + const signInput = `${header}.${payload}`; + const signer = createSign("RSA-SHA256"); + signer.update(signInput); + const signature = signer.sign(key.private_key, "base64url"); + + return `${signInput}.${signature}`; +} + +let cachedToken: { token: string; expiresAt: number } | null = null; + +async function getAccessToken(): Promise { + if (cachedToken && Date.now() < cachedToken.expiresAt - 60_000) { + return cachedToken.token; + } + + const key = loadServiceAccountKey(); + const jwt = createSignedJwt(key); + + const response = await fetch(key.token_uri, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: new URLSearchParams({ + grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", + assertion: jwt, + }), + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`Failed to get access token: ${response.status} ${text}`); + } + + const json: unknown = await response.json(); + const data = parseAccessTokenResponse(json); + cachedToken = { + token: data.access_token, + expiresAt: Date.now() + data.expires_in * 1000, + }; + return cachedToken.token; +} + +function buildUrl(model: string, stream: boolean): string { + const project = process.env.VERTEX_PROJECT; + if (!project) { + throw new Error("VERTEX_PROJECT environment variable is required"); + } + const location = process.env.VERTEX_LOCATION ?? "us-central1"; + const method = stream ? "streamGenerateContent?alt=sse" : "generateContent"; + return `https://${location}-aiplatform.googleapis.com/v1/projects/${project}/locations/${location}/${model}:${method}`; +} + +// Response type matching Google's GenerateContent response +type GenerateContentResponse = { + candidates?: Array<{ + content?: { + role?: string; + parts?: Array<{ + text?: string; + functionCall?: { name: string; args?: Record }; + [key: string]: unknown; + }>; + }; + [key: string]: unknown; + }>; + [key: string]: unknown; +}; + +type Content = { + role: string; + parts: Array>; +}; + +async function parseJsonResponse( + response: Response +): Promise { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- response.json() returns unknown + return (await response.json()) as GenerateContentResponse; +} + +async function parseSSEStream( + response: Response +): Promise { + const chunks: GenerateContentResponse[] = []; + const text = await response.text(); + const lines = text.split("\n"); + for (const line of lines) { + if (line.startsWith("data: ")) { + const jsonStr = line.slice(6); + if (jsonStr.trim()) { + try { + chunks.push(JSON.parse(jsonStr)); + } catch { + // skip malformed JSON + } + } + } + } + return chunks; +} + +function toContent(content: { role?: string; parts?: unknown[] }): Content { + const parts: Array> = []; + for (const part of content.parts ?? []) { + if (part && typeof part === "object") { + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- validated above + parts.push(part as Record); + } + } + return { role: content.role ?? "user", parts }; +} + +async function vertexGoogleRequest( + model: string, + payload: GoogleGenerateContentRequest, + token: string, + stream: boolean +): Promise { + const url = buildUrl(model, stream); + const { model: _model, ...body } = payload; + + return fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify(body), + }); +} + +type ParallelResult = + | { type: "response"; data: GenerateContentResponse } + | { type: "streamingResponse"; data: GenerateContentResponse[] }; + +export async function executeVertexGoogle( + _caseName: string, + payload: GoogleGenerateContentRequest, + options?: ExecuteOptions +): Promise< + CaptureResult< + GoogleGenerateContentRequest, + GenerateContentResponse, + GenerateContentResponse + > +> { + const { stream } = options ?? {}; + const token = await getAccessToken(); + const model = payload.model ?? VERTEX_GOOGLE_MODEL; + + const result: CaptureResult< + GoogleGenerateContentRequest, + GenerateContentResponse, + GenerateContentResponse + > = { request: payload }; + + try { + const promises: Promise[] = []; + + if (stream !== true) { + promises.push( + (async () => { + const response = await vertexGoogleRequest( + model, + payload, + token, + false + ); + if (!response.ok) { + const text = await response.text(); + throw new Error(`ApiError: ${text}`); + } + const data = await parseJsonResponse(response); + return { type: "response" as const, data }; + })() + ); + } + + if (stream !== false) { + promises.push( + (async () => { + const response = await vertexGoogleRequest( + model, + payload, + token, + true + ); + if (!response.ok) { + const text = await response.text(); + throw new Error(`ApiError: ${text}`); + } + const chunks = await parseSSEStream(response); + return { type: "streamingResponse" as const, data: chunks }; + })() + ); + } + + const initialResults = await Promise.all(promises); + + for (const r of initialResults) { + if (r.type === "response") { + result.response = r.data; + } else if (r.type === "streamingResponse") { + result.streamingResponse = r.data; + } + } + + if (result.response) { + const assistantContent = result.response.candidates?.[0]?.content; + + if (assistantContent) { + const followUpContents: Content[] = [ + ...payload.contents.map(toContent), + toContent(assistantContent), + ]; + + const assistantParts = assistantContent.parts ?? []; + let hasToolCalls = false; + + for (const part of assistantParts) { + if ("functionCall" in part && part.functionCall) { + hasToolCalls = true; + followUpContents.push({ + role: "user", + parts: [ + { + functionResponse: { + name: part.functionCall.name, + response: { temperature: "71 degrees" }, + }, + }, + ], + }); + } + } + + if (!hasToolCalls) { + followUpContents.push({ + role: "user", + parts: [{ text: "What should I do next?" }], + }); + } + + const followUpPayload: GoogleGenerateContentRequest = { + ...payload, + contents: followUpContents, + }; + + result.followupRequest = followUpPayload; + + type FollowupResult = + | { type: "followupResponse"; data: GenerateContentResponse } + | { + type: "followupStreamingResponse"; + data: GenerateContentResponse[]; + }; + + const followupPromises: Promise[] = []; + + if (stream !== true) { + followupPromises.push( + (async () => { + const response = await vertexGoogleRequest( + model, + followUpPayload, + token, + false + ); + if (!response.ok) { + const text = await response.text(); + throw new Error(`ApiError: ${text}`); + } + const data = await parseJsonResponse(response); + return { type: "followupResponse" as const, data }; + })() + ); + } + + if (stream !== false) { + followupPromises.push( + (async () => { + const response = await vertexGoogleRequest( + model, + followUpPayload, + token, + true + ); + if (!response.ok) { + const text = await response.text(); + throw new Error(`ApiError: ${text}`); + } + const chunks = await parseSSEStream(response); + return { + type: "followupStreamingResponse" as const, + data: chunks, + }; + })() + ); + } + + if (followupPromises.length > 0) { + const followupResults = await Promise.all(followupPromises); + for (const r of followupResults) { + if (r.type === "followupResponse") { + result.followupResponse = r.data; + } else if (r.type === "followupStreamingResponse") { + result.followupStreamingResponse = r.data; + } + } + } + } + } + } catch (error) { + result.error = String(error); + } + + return result; +} + +export const vertexGoogleExecutor: ProviderExecutor< + GoogleGenerateContentRequest, + GenerateContentResponse, + GenerateContentResponse +> = { + name: "vertex-google", + cases: vertexGoogleCases, + execute: executeVertexGoogle, +}; diff --git a/payloads/scripts/transforms/__snapshots__/transforms.test.ts.snap b/payloads/scripts/transforms/__snapshots__/transforms.test.ts.snap index 7381585f..568d2338 100644 --- a/payloads/scripts/transforms/__snapshots__/transforms.test.ts.snap +++ b/payloads/scripts/transforms/__snapshots__/transforms.test.ts.snap @@ -4674,6 +4674,2103 @@ exports[`chat-completions → google > topPParam > response 1`] = ` } `; +exports[`chat-completions → vertex-google > complexReasoningRequest > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "There is a digital clock, with minutes and hours in the form of 00:00. The clock shows all times from 00:00 to 23:59 and repeating. Imagine you had a list of all these times. Which digit(s) is the most common and which is the rarest? Can you find their percentage?", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "maxOutputTokens": 20000, + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > complexReasoningRequest > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Let's break this down to figure out the most common and rarest digits and their percentages. + +**1. Total Number of Digits** + +* **Hours:** There are 24 hours in a day (00 to 23). +* **Minutes:** There are 60 minutes in an hour (00 to 59). +* **Total Time Combinations:** 24 hours * 60 minutes = 1440 unique time combinations. + +Now, let's consider how many digits are displayed for each time: + +* Each time is displayed as HH:MM, which is 5 characters. +* However, the colon is not a digit. We have 4 digits for each time: 2 for hours and 2 for minutes. + +Therefore, the total number of digits displayed across all times is: +1440 time combinations * 4 digits/time = **5760 digits**. + +**2. Counting the Occurrences of Each Digit (0-9)** + +We need to systematically count how many times each digit appears in all the possible hour and minute combinations. + +* **Hours (00 to 23):** + * **Tens digit of hours:** + * '0' appears 10 times (00-09) + * '1' appears 10 times (10-19) + * '2' appears 4 times (20-23) + * **Units digit of hours:** + * '0' appears 3 times (00, 10, 20) + * '1' appears 3 times (01, 11, 21) + * '2' appears 3 times (02, 12, 22) + * '3' appears 3 times (03, 13, 23) + * '4' appears 2 times (04, 14) + * '5' appears 2 times (05, 15) + * '6' appears 2 times (06, 16) + * '7' appears 2 times (07, 17) + * '8' appears 2 times (08, 18) + * '9' appears 2 times (09, 19) + + Let's sum these up for hours: + * **0:** (10 + 3) = 13 + * **1:** (10 + 3) = 13 + * **2:** (4 + 3) = 7 + * **3:** (0 + 3) = 3 + * **4:** (0 + 2) = 2 + * **5:** (0 + 2) = 2 + * **6:** (0 + 2) = 2 + * **7:** (0 + 2) = 2 + * **8:** (0 + 2) = 2 + * **9:** (0 + 2) = 2 + +* **Minutes (00 to 59):** This is easier because the pattern repeats for every 10-minute interval. + * **Tens digit of minutes:** + * '0' appears 10 times (00-09) + * '1' appears 10 times (10-19) + * '2' appears 10 times (20-29) + * '3' appears 10 times (30-39) + * '4' appears 10 times (40-49) + * '5' appears 10 times (50-59) + * **Units digit of minutes:** In every block of 10 minutes, each digit from 0 to 9 appears once. Since there are 6 such blocks (0-9, 10-19, ..., 50-59), each unit digit appears 6 times. + * '0' appears 6 times + * '1' appears 6 times + * '2' appears 6 times + * '3' appears 6 times + * '4' appears 6 times + * '5' appears 6 times + * '6' appears 6 times + * '7' appears 6 times + * '8' appears 6 times + * '9' appears 6 times + + Let's sum these up for minutes: + * **0:** (10 * 6) + 6 = 60 + 6 = 66 + * **1:** (10 * 6) + 6 = 60 + 6 = 66 + * **2:** (10 * 6) + 6 = 60 + 6 = 66 + * **3:** (10 * 6) + 6 = 60 + 6 = 66 + * **4:** (10 * 6) + 6 = 60 + 6 = 66 + * **5:** (10 * 6) + 6 = 60 + 6 = 66 + * **6:** (0 * 6) + 6 = 0 + 6 = 6 + * **7:** (0 * 6) + 6 = 0 + 6 = 6 + * **8:** (0 * 6) + 6 = 0 + 6 = 6 + * **9:** (0 * 6) + 6 = 0 + 6 = 6 + +* **Total Count for Each Digit (Hours + Minutes):** + * **0:** 13 (hours) + 66 (minutes) = **79** + * **1:** 13 (hours) + 66 (minutes) = **79** + * **2:** 7 (hours) + 66 (minutes) = **73** + * **3:** 3 (hours) + 66 (minutes) = **69** + * **4:** 2 (hours) + 66 (minutes) = **68** + * **5:** 2 (hours) + 66 (minutes) = **68** + * **6:** 2 (hours) + 6 (minutes) = **8** + * **7:** 2 (hours) + 6 (minutes) = **8** + * **8:** 2 (hours) + 6 (minutes) = **8** + * **9:** 2 (hours) + 6 (minutes) = **8** + +**Let's double check our count of minutes digits:** +Total minutes digits displayed: 1440 times * 2 digits/minute = 2880 minute digits. +Sum of our minute digit counts: 6 * 66 (for 0-5) + 4 * 6 (for 6-9) = 396 + 24 = 420. This is incorrect. + +Let's re-evaluate the minute digits. +For each of the 60 minutes (00-59): +* The tens digit cycles through 0 (10 times), 1 (10 times), 2 (10 times), 3 (10 times), 4 (10 times), 5 (10 times). +* The units digit cycles through 0-9 six times. + +So, for the minutes portion (MM): +* **Digit 0:** Tens digit appears 10 times (00-09). Units digit appears 6 times (00, 10, 20, 30, 40, 50). Total for minutes: 10 + 6 = 16. +* **Digit 1:** Tens digit appears 10 times (10-19). Units digit appears 6 times (01, 11, 21, 31, 41, 51). Total for minutes: 10 + 6 = 16. +* **Digit 2:** Tens digit appears 10 times (20-29). Units digit appears 6 times (02, 12, 22, 32, 42, 52). Total for minutes: 10 + 6 = 16. +* **Digit 3:** Tens digit appears 10 times (30-39). Units digit appears 6 times (03, 13, 23, 33, 43, 53). Total for minutes: 10 + 6 = 16. +* **Digit 4:** Tens digit appears 10 times (40-49). Units digit appears 6 times (04, 14, 24, 34, 44, 54). Total for minutes: 10 + 6 = 16. +* **Digit 5:** Tens digit appears 10 times (50-59). Units digit appears 6 times (05, 15, 25, 35, 45, 55). Total for minutes: 10 + 6 = 16. +* **Digit 6:** Tens digit appears 0 times in the 00-59 range. Units digit appears 6 times (06, 16, 26, 36, 46, 56). Total for minutes: 0 + 6 = 6. +* **Digit 7:** Tens digit appears 0 times. Units digit appears 6 times (07, 17, 27, 37, 47, 57). Total for minutes: 0 + 6 = 6. +* **Digit 8:** Tens digit appears 0 times. Units digit appears 6 times (08, 18, 28, 38, 48, 58). Total for minutes: 0 + 6 = 6. +* **Digit 9:** Tens digit appears 0 times. Units digit appears 6 times (09, 19, 29, 39, 49, 59). Total for minutes: 0 + 6 = 6. + +Let's verify the total minute digits: 6 * 16 (for 0-5) + 4 * 6 (for 6-9) = 96 + 24 = 120. +This is still not right. The issue is that there are 60 minutes, and each minute has 2 digits. Total minute digits = 60 * 2 = 120. +The previous calculation method was counting the occurrences across all 1440 times. + +Let's re-do the minute counts across all 1440 times: +For each hour (00 to 23), the minutes run from 00 to 59. +So, the distribution of digits in the minutes part is the same for every hour. + +Total occurrences of a digit in the minutes across all 24 hours: +* **Digit 0:** Tens digit appears 10 times per hour (00-09). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384** +* **Digit 1:** Tens digit appears 10 times per hour (10-19). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384** +* **Digit 2:** Tens digit appears 10 times per hour (20-29). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384** +* **Digit 3:** Tens digit appears 10 times per hour (30-39). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384** +* **Digit 4:** Tens digit appears 10 times per hour (40-49). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384** +* **Digit 5:** Tens digit appears 10 times per hour (50-59). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384** +* **Digit 6:** Tens digit appears 0 times per hour. Units digit appears 6 times per hour. Total per hour = 6. Across 24 hours: 6 * 24 = **144** +* **Digit 7:** Tens digit appears 0 times per hour. Units digit appears 6 times per hour. Total per hour = 6. Across 24 hours: 6 * 24 = **144** +* **Digit 8:** Tens digit appears 0 times per hour. Units digit appears 6 times per hour. Total per hour = 6. Across 24 hours: 6 * 24 = **144** +* **Digit 9:** Tens digit appears 0 times per hour. Units digit appears 6 times per hour. Total per hour = 6. Across 24 hours: 6 * 24 = **144** + +Let's sum these minute digits: 6 * 384 + 4 * 144 = 2304 + 576 = 2880. This matches the total number of minute digits. + +Now, let's combine hour and minute digit counts: +* **Digit 0:** 13 (hours) + 384 (minutes) = **397** +* **Digit 1:** 13 (hours) + 384 (minutes) = **397** +* **Digit 2:** 7 (hours) + 384 (minutes) = **391** +* **Digit 3:** 3 (hours) + 384 (minutes) = **387** +* **Digit 4:** 2 (hours) + 384 (minutes) = **386** +* **Digit 5:** 2 (hours) + 384 (minutes) = **386** +* **Digit 6:** 2 (hours) + 144 (minutes) = **146** +* **Digit 7:** 2 (hours) + 144 (minutes) = **146** +* **Digit 8:** 2 (hours) + 144 (minutes) = **146** +* **Digit 9:** 2 (hours) + 144 (minutes) = **146** + +Let's sum these total digit counts: 2 * 397 + 391 + 387 + 2 * 386 + 4 * 146 = 794 + 391 + 387 + 772 + 584 = 2928. +This is still not 5760. The issue is in how we are summing. We need to count the total occurrences of each digit. + +Let's restart the counting from scratch, systematically. + +**Total number of digits: 5760** + +We can analyze the digits based on their position: +* **Hour Tens Digit (H1):** Ranges from 0 to 2. + * 0 appears 10 times (00-09) + * 1 appears 10 times (10-19) + * 2 appears 4 times (20-23) + * Total times H1 is displayed: 10 + 10 + 4 = 24 times *per minute*. This is not how we should count. + +Let's count the occurrences across all 1440 times: + +**Hour Digits:** +* **Tens Digit of Hour:** + * '0': Appears in 00:00 through 09:59. That's 10 hours. So, 10 * 60 minutes = 600 times. + * '1': Appears in 10:00 through 19:59. That's 10 hours. So, 10 * 60 minutes = 600 times. + * '2': Appears in 20:00 through 23:59. That's 4 hours. So, 4 * 60 minutes = 240 times. +* **Units Digit of Hour:** + * '0': Appears in 00, 10, 20. For each of these hour patterns (e.g., 00), it appears for 60 minutes. So, 3 * 60 = 180 times. + * '1': Appears in 01, 11, 21. So, 3 * 60 = 180 times. + * '2': Appears in 02, 12, 22. So, 3 * 60 = 180 times. + * '3': Appears in 03, 13, 23. So, 3 * 60 = 180 times. + * '4': Appears in 04, 14. So, 2 * 60 = 120 times. + * '5': Appears in 05, 15. So, 2 * 60 = 120 times. + * '6': Appears in 06, 16. So, 2 * 60 = 120 times. + * '7': Appears in 07, 17. So, 2 * 60 = 120 times. + * '8': Appears in 08, 18. So, 2 * 60 = 120 times. + * '9': Appears in 09, 19. So, 2 * 60 = 120 times. + +**Total Hour Digit Counts:** +* '0': 600 + 180 = **780** +* '1': 600 + 180 = **780** +* '2': 240 + 180 = **420** +* '3': 0 + 180 = **180** +* '4': 0 + 120 = **120** +* '5': 0 + 120 = **120** +* '6': 0 + 120 = **120** +* '7': 0 + 120 = **120** +* '8': 0 + 120 = **120** +* '9': 0 + 120 = **120** + +Sum of hour digits: 2*780 + 420 + 180 + 6*120 = 1560 + 420 + 180 + 720 = 2880. This is correct for the hour digits (24 hours * 60 minutes * 2 digits/hour = 2880 digits). + +**Minute Digits:** +For every hour, the minutes run from 00 to 59. This means the distribution of digits in the minutes is the same for each of the 24 hours. +* **Tens Digit of Minute:** + * '0': Appears in 00-09. That's 10 minutes. For each hour, this occurs 10 times. Over 24 hours: 10 * 24 = 240 times. + * '1': Appears in 10-19. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times. + * '2': Appears in 20-29. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times. + * '3': Appears in 30-39. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times. + * '4': Appears in 40-49. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times. + * '5': Appears in 50-59. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times. +* **Units Digit of Minute:** + * '0': Appears in 00, 10, 20, 30, 40, 50. That's 6 times for every hour. Over 24 hours: 6 * 24 = 144 times. + * '1': Appears in 01, 11, 21, 31, 41, 51. So, 6 * 24 = 144 times. + * '2': Appears in 02, 12, 22, 32, 42, 52. So, 6 * 24 = 144 times. + * '3': Appears in 03, 13, 23, 33, 43, 53. So, 6 * 24 = 144 times. + * '4': Appears in 04, 14, 24, 34, 44, 54. So, 6 * 24 = 144 times. + * '5': Appears in 05, 15, 25, 35, 45, 55. So, 6 * 24 = 144 times. + * '6': Appears in 06, 16, 26, 36, 46, 56. So, 6 * 24 = 144 times. + * '7': Appears in 07, 17, 27, 37, 47, 57. So, 6 * 24 = 144 times. + * '8': Appears in 08, 18, 28, 38, 48, 58. So, 6 * 24 = 144 times. + * '9': Appears in 09, 19, 29, 39, 49, 59. So, 6 * 24 = 144 times. + +**Total Minute Digit Counts:** +* '0': 240 (tens) + 144 (units) = **384** +* '1': 240 (tens) + 144 (units) = **384** +* '2': 240 (tens) + 144 (units) = **384** +* '3': 240 (tens) + 144 (units) = **384** +* '4': 240 (tens) + 144 (units) = **384** +* '5': 240 (tens) + 144 (units) = **384** +* '6': 0 (tens) + 144 (units) = **144** +* '7': 0 (tens) + 144 (units) = **144** +* '8': 0 (tens) + 144 (units) = **144** +* '9': 0 (tens) + 144 (units) = **144** + +Sum of minute digits: 6 * 384 + 4 * 144 = 2304 + 576 = 2880. This is correct for the minute digits. + +**Grand Total for Each Digit (Hour + Minute):** +* **0:** 780 (hours) + 384 (minutes) = **1164** +* **1:** 780 (hours) + 384 (minutes) = **1164** +* **2:** 420 (hours) + 384 (minutes) = **804** +* **3:** 180 (hours) + 384 (minutes) = **564** +* **4:** 120 (hours) + 384 (minutes) = **504** +* **5:** 120 (hours) + 384 (minutes) = **504** +* **6:** 120 (hours) + 144 (minutes) = **264** +* **7:** 120 (hours) + 144 (minutes) = **264** +* **8:** 120 (hours) + 144 (minutes) = **264** +* **9:** 120 (hours) + 144 (minutes) = **264** + +Let's check the sum of all digits: 2 * 1164 + 804 + 564 + 2 * 504 + 4 * 264 = 2328 + 804 + 564 + 1008 + 1056 = 5760. This matches the total number of digits. + +**Results:** + +* **Most Common Digit(s):** The digits **0** and **1** are the most common. + * Count: **1164** each + * Percentage: (1164 / 5760) * 100% = **20.21%** + +* **Rarest Digit(s):** The digits **6**, **7**, **8**, and **9** are the rarest. + * Count: **264** each + * Percentage: (264 / 5760) * 100% = **4.58%** + +**Summary:** + +* **Most Common Digits:** **0 and 1** (1164 occurrences each, 20.21% each) +* **Rarest Digits:** **6, 7, 8, and 9** (264 occurrences each, 4.58% each)", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 6344, + "prompt_tokens": 74, + "total_tokens": 6418, + }, +} +`; + +exports[`chat-completions → vertex-google > frequencyPenaltyParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say ok.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > frequencyPenaltyParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Ok.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > instructionsParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Hi", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", + "systemInstruction": { + "parts": [ + { + "text": "Always say ok.", + }, + ], + }, +} +`; + +exports[`chat-completions → vertex-google > instructionsParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "ok", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 1, + "prompt_tokens": 5, + "total_tokens": 6, + }, +} +`; + +exports[`chat-completions → vertex-google > logitBiasParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say hello.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > logitBiasParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Hello! How can I help you today?", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 9, + "prompt_tokens": 3, + "total_tokens": 12, + }, +} +`; + +exports[`chat-completions → vertex-google > logprobsParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "What is 2 + 2?", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > logprobsParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "2 + 2 = 4", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 7, + "prompt_tokens": 8, + "total_tokens": 15, + }, +} +`; + +exports[`chat-completions → vertex-google > maxCompletionTokensParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say ok.", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "maxOutputTokens": 500, + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > maxCompletionTokensParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Ok.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > metadataParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say ok.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > metadataParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Ok.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > multimodalRequest > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "What do you see in this image?", + }, + { + "fileData": { + "fileUri": "https://t3.ftcdn.net/jpg/02/36/99/22/360_F_236992283_sNOxCVQeFLd5pdqaKGh8DRGMZy7P4XKm.jpg", + }, + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "maxOutputTokens": 300, + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > nMultipleCompletionsParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say a word.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > nMultipleCompletionsParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Hello.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 4, + "total_tokens": 6, + }, +} +`; + +exports[`chat-completions → vertex-google > parallelToolCallsDisabledParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Weather in NYC and LA?", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", + "tools": [ + { + "functionDeclarations": [ + { + "description": "Get weather", + "name": "get_weather", + "parameters": null, + "parametersJsonSchema": { + "additionalProperties": false, + "properties": { + "location": { + "type": "string", + }, + }, + "required": [ + "location", + ], + "type": "object", + }, + "response": null, + }, + ], + }, + ], +} +`; + +exports[`chat-completions → vertex-google > parallelToolCallsDisabledParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "tool_calls", + "index": 0, + "message": { + "annotations": [], + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{"location":"NYC"}", + "name": "get_weather", + }, + "id": "", + "type": "function", + }, + { + "function": { + "arguments": "{"location":"LA"}", + "name": "get_weather", + }, + "id": "", + "type": "function", + }, + ], + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 10, + "prompt_tokens": 11, + "total_tokens": 21, + }, +} +`; + +exports[`chat-completions → vertex-google > predictionParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Update this function to add error handling: + +function divide(a, b) { + return a / b; +}", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > predictionParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "\`\`\`javascript +/** + * Divides two numbers and handles potential errors. + * + * @param {number} a The dividend. + * @param {number} b The divisor. + * @returns {number | string} The result of the division, or an error message string if an error occurs. + */ +function divide(a, b) { + // 1. Check if inputs are valid numbers + if (typeof a !== 'number' || typeof b !== 'number') { + return "Error: Both inputs must be numbers."; + } + + // 2. Check for division by zero + if (b === 0) { + return "Error: Division by zero is not allowed."; + } + + // 3. Perform the division + return a / b; +} + +// --- Examples of usage --- + +console.log(divide(10, 2)); // Output: 5 +console.log(divide(15, 3)); // Output: 5 +console.log(divide(7, 0)); // Output: Error: Division by zero is not allowed. +console.log(divide(10, 'abc')); // Output: Error: Both inputs must be numbers. +console.log(divide('xyz', 5)); // Output: Error: Both inputs must be numbers. +console.log(divide(10, undefined)); // Output: Error: Both inputs must be numbers. +console.log(divide(null, 5)); // Output: Error: Both inputs must be numbers. +console.log(divide(20, 4)); // Output: 5 +\`\`\` + +**Explanation of Error Handling:** + +1. **Type Checking:** + * \`if (typeof a !== 'number' || typeof b !== 'number')\`: This checks if either \`a\` or \`b\` is not of the \`number\` data type. If they are not, it returns a specific error message. This prevents issues like trying to divide a string by a number or vice-versa, which would result in \`NaN\` or other unexpected behavior. + +2. **Division by Zero:** + * \`if (b === 0)\`: This is the most crucial error to handle in division. Dividing by zero is mathematically undefined and would result in \`Infinity\` or \`-Infinity\` in JavaScript, which might not be the desired outcome. This check ensures that we explicitly catch this case and return a clear error message. + +3. **Returning Error Messages:** + * Instead of throwing actual JavaScript \`Error\` objects (which is also a valid approach for more complex applications), this updated function returns descriptive **string messages** when an error occurs. This makes it easy to check the return value and display the appropriate message to the user. + +**Alternative (Throwing Errors):** + +For more robust error handling in larger applications, you might prefer to \`throw\` actual \`Error\` objects. This allows for more structured error management using \`try...catch\` blocks. + +\`\`\`javascript +function divideWithErrorThrow(a, b) { + if (typeof a !== 'number' || typeof b !== 'number') { + throw new Error("Both inputs must be numbers."); + } + + if (b === 0) { + throw new Error("Division by zero is not allowed."); + } + + return a / b; +} + +// Example of using try...catch +try { + console.log(divideWithErrorThrow(10, 2)); // Output: 5 + console.log(divideWithErrorThrow(7, 0)); // This line will throw an error +} catch (error) { + console.error(error.message); // Output: Division by zero is not allowed. +} + +try { + console.log(divideWithErrorThrow(10, 'abc')); // This line will throw an error +} catch (error) { + console.error(error.message); // Output: Both inputs must be numbers. +} +\`\`\` + +The choice between returning error strings or throwing errors depends on the context and how you intend to handle errors in your application. For a simple function, returning strings is often sufficient and easier to read.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 912, + "prompt_tokens": 26, + "total_tokens": 938, + }, +} +`; + +exports[`chat-completions → vertex-google > presencePenaltyParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say ok.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > presencePenaltyParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Ok.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > promptCacheKeyParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say ok.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > promptCacheKeyParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Ok.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > reasoningEffortLowParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "What is 2+2?", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseSchema": null, + "thinkingConfig": { + "includeThoughts": true, + "thinkingBudget": 1024, + }, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > reasoningEffortLowParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "2 + 2 = 4", + "reasoning": "Ah, so the core of this inquiry, as I perceive it, is a straightforward request for the summation of two numerical entities. My immediate mental process is to identify this as a fundamental arithmetic operation, specifically addition. With that recognized, I then execute the calculation: two plus two. The result, unequivocally, is four. Therefore, my conclusion is to present this numerical outcome with the utmost clarity and conciseness.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 79, + "completion_tokens_details": { + "reasoning_tokens": 72, + }, + "prompt_tokens": 7, + "total_tokens": 86, + }, +} +`; + +exports[`chat-completions → vertex-google > reasoningRequest > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Solve this step by step: If a train travels 60 mph for 2 hours, then 80 mph for 1 hour, what's the average speed?", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > reasoningRequest > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Here's how to solve this problem step-by-step: + +**1. Understand the Goal:** +We need to find the *average speed* of the train. Average speed is calculated as: + +Average Speed = Total Distance / Total Time + +**2. Calculate the Distance for the First Part of the Journey:** +* **Formula:** Distance = Speed × Time +* **Speed:** 60 mph +* **Time:** 2 hours +* **Calculation:** 60 mph × 2 hours = 120 miles + +**3. Calculate the Distance for the Second Part of the Journey:** +* **Formula:** Distance = Speed × Time +* **Speed:** 80 mph +* **Time:** 1 hour +* **Calculation:** 80 mph × 1 hour = 80 miles + +**4. Calculate the Total Distance Traveled:** +* **Add the distances from both parts of the journey:** +* **Calculation:** 120 miles + 80 miles = 200 miles + +**5. Calculate the Total Time of the Journey:** +* **Add the times from both parts of the journey:** +* **Calculation:** 2 hours + 1 hour = 3 hours + +**6. Calculate the Average Speed:** +* **Use the average speed formula:** Average Speed = Total Distance / Total Time +* **Total Distance:** 200 miles +* **Total Time:** 3 hours +* **Calculation:** 200 miles / 3 hours = 66.67 mph (approximately) + +**Answer:** The average speed of the train is approximately **66.67 mph**.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 349, + "prompt_tokens": 36, + "total_tokens": 385, + }, +} +`; + +exports[`chat-completions → vertex-google > reasoningRequestTruncated > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Solve this step by step: If a train travels 60 mph for 2 hours, then 80 mph for 1 hour, what's the average speed?", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "maxOutputTokens": 100, + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > reasoningRequestTruncated > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "length", + "index": 0, + "message": { + "annotations": [], + "content": "Here's how to solve this problem step-by-step: + +**1. Calculate the distance traveled in the first part of the journey:** + +* **Formula:** Distance = Speed × Time +* **Speed:** 60 mph +* **Time:** 2 hours +* **Calculation:** Distance1 = 60 mph × 2 hours = 120 miles + +**2. Calculate the distance traveled in the second part of the journey:** + +* **Formula:**", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 100, + "prompt_tokens": 36, + "total_tokens": 136, + }, +} +`; + +exports[`chat-completions → vertex-google > reasoningSummaryParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "What is 2+2?", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseSchema": null, + "thinkingConfig": { + "includeThoughts": true, + "thinkingBudget": 2048, + }, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > reasoningSummaryParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "2 + 2 = 4.", + "reasoning": "My immediate thought process, upon encountering the user's request, was to pinpoint the essential task at hand. It was quite straightforward: to ascertain the outcome of the arithmetic expression "2 + 2." + +Having identified this core objective, the next logical step was to execute the calculation itself. This is a fundamental operation, and the result is immediately apparent: 2 plus 2 unequivocally equals 4. + +Finally, the last stage involved synthesizing this outcome into a clear and direct response, ensuring the answer is presented without ambiguity.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 66, + "completion_tokens_details": { + "reasoning_tokens": 58, + }, + "prompt_tokens": 7, + "total_tokens": 73, + }, +} +`; + +exports[`chat-completions → vertex-google > reasoningWithOutput > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "What color is the sky?", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > reasoningWithOutput > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "The sky is **blue** on a clear day. + +However, its color can change depending on several factors: + +* **Time of day:** During sunrise and sunset, the sky can appear red, orange, pink, and purple due to the way sunlight scatters through the atmosphere. +* **Weather conditions:** Clouds can make the sky appear white, gray, or even dark and stormy. +* **Atmospheric particles:** Smoke, dust, or pollution can tint the sky with different hues. + +But in its most common and iconic appearance, it's blue!", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 119, + "prompt_tokens": 6, + "total_tokens": 125, + }, +} +`; + +exports[`chat-completions → vertex-google > safetyIdentifierParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say ok.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > safetyIdentifierParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Ok.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > seedParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Pick a number.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > seedParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "I'll pick **7**.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 7, + "prompt_tokens": 4, + "total_tokens": 11, + }, +} +`; + +exports[`chat-completions → vertex-google > serviceTierParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say ok.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > serviceTierParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Ok.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > simpleRequest > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "What is the capital of France?", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseSchema": null, + "thinkingConfig": { + "includeThoughts": true, + "thinkingBudget": 1024, + }, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > simpleRequest > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "The capital of France is **Paris**.", + "reasoning": "Okay, so I'm presented with a query. My primary objective, as I see it, is to immediately isolate the fundamental question being posed. In this instance, it's quite straightforward: "What is the capital of France?" + +Once I've clearly identified this core inquiry, my next step is to access my internal knowledge base. I need to retrieve the relevant piece of information that directly answers this question. Fortunately, this is a well-established and readily available datum: Paris is indeed the capital of France. + +With the factual answer in hand, my task then shifts to constructing a response. This response needs to be unambiguous and directly address the user's prompt. Therefore, a clear and direct statement of the fact is the most efficient and effective approach. + +Finally, before presenting the answer, I perform a quick internal review. I ask myself: Is the information I'm about to provide accurate? In this case, unequivocally yes. And is the answer concise and to the point, avoiding any unnecessary verbosity? Again, yes. This ensures I've met the user's need with precision and efficiency.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 79, + "completion_tokens_details": { + "reasoning_tokens": 71, + }, + "prompt_tokens": 7, + "total_tokens": 86, + }, +} +`; + +exports[`chat-completions → vertex-google > stopSequencesParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Count from 1 to 20.", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseSchema": null, + "stopSequences": [ + "10", + "ten", + ], + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > stopSequencesParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Here's the count from 1 to 20: + +1 +2 +3 +4 +5 +6 +7 +8 +9 +", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 32, + "prompt_tokens": 9, + "total_tokens": 41, + }, +} +`; + +exports[`chat-completions → vertex-google > storeDisabledParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say ok.", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > storeDisabledParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Ok.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > systemMessageArrayContent > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "What errors occurred recently?", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "maxOutputTokens": 300, + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", + "systemInstruction": { + "parts": [ + { + "text": "You are a helpful data analyst. The default data source is project_logs with id abc-123.", + }, + ], + }, +} +`; + +exports[`chat-completions → vertex-google > systemMessageArrayContent > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "I can't provide specific error details without knowing what constitutes "recently." Please specify a time frame (e.g., "in the last hour," "yesterday," "this morning") for me to query the project logs.", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 47, + "prompt_tokens": 28, + "total_tokens": 75, + }, +} +`; + +exports[`chat-completions → vertex-google > temperatureParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say hi.", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseSchema": null, + "temperature": 0.7, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > temperatureParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Hi!", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 3, + "total_tokens": 5, + }, +} +`; + +exports[`chat-completions → vertex-google > textFormatJsonObjectParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Return {"status": "ok"} as JSON.", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseMimeType": "application/json", + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > textFormatJsonObjectParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "{"status": "ok"}", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 6, + "prompt_tokens": 10, + "total_tokens": 16, + }, +} +`; + +exports[`chat-completions → vertex-google > textFormatJsonSchemaParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Extract: John is 25.", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseJsonSchema": { + "additionalProperties": false, + "properties": { + "age": { + "type": "number", + }, + "name": { + "type": "string", + }, + }, + "required": [ + "name", + "age", + ], + "title": "person_info", + "type": "object", + }, + "responseMimeType": "application/json", + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > textFormatJsonSchemaParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "{ + "name": "John", + "age": 25 +}", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 19, + "prompt_tokens": 8, + "total_tokens": 27, + }, +} +`; + +exports[`chat-completions → vertex-google > textFormatJsonSchemaWithDescriptionParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Extract: John is 25.", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseJsonSchema": { + "additionalProperties": false, + "description": "Extract person information from text", + "properties": { + "age": { + "type": "number", + }, + "name": { + "type": "string", + }, + }, + "required": [ + "name", + "age", + ], + "title": "person_info", + "type": "object", + }, + "responseMimeType": "application/json", + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > textFormatJsonSchemaWithDescriptionParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "{ + "name": "John", + "age": 25 +}", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 19, + "prompt_tokens": 8, + "total_tokens": 27, + }, +} +`; + +exports[`chat-completions → vertex-google > textFormatTextParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say hello.", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseMimeType": "text/plain", + "responseSchema": null, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > textFormatTextParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Hello! How can I help you today?", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 9, + "prompt_tokens": 3, + "total_tokens": 12, + }, +} +`; + +exports[`chat-completions → vertex-google > toolCallRequest > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "What's the weather like in San Francisco?", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", + "toolConfig": { + "functionCallingConfig": { + "mode": "AUTO", + }, + }, + "tools": [ + { + "functionDeclarations": [ + { + "description": "Get the current weather for a location", + "name": "get_weather", + "parameters": null, + "parametersJsonSchema": { + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "type": "string", + }, + }, + "required": [ + "location", + ], + "type": "object", + }, + "response": null, + }, + ], + }, + ], +} +`; + +exports[`chat-completions → vertex-google > toolCallRequest > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "tool_calls", + "index": 0, + "message": { + "annotations": [], + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{"location":"San Francisco, CA"}", + "name": "get_weather", + }, + "id": "", + "type": "function", + }, + ], + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 8, + "prompt_tokens": 20, + "total_tokens": 28, + }, +} +`; + +exports[`chat-completions → vertex-google > toolChoiceRequiredParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Tokyo weather", + }, + ], + "role": "user", + }, + ], + "model": "publishers/google/models/gemini-2.5-flash-lite", + "toolConfig": { + "functionCallingConfig": { + "allowedFunctionNames": [ + "get_weather", + ], + "mode": "ANY", + }, + }, + "tools": [ + { + "functionDeclarations": [ + { + "description": "Get weather", + "name": "get_weather", + "parameters": null, + "parametersJsonSchema": { + "additionalProperties": false, + "properties": { + "location": { + "type": "string", + }, + }, + "required": [ + "location", + ], + "type": "object", + }, + "response": null, + }, + ], + }, + ], +} +`; + +exports[`chat-completions → vertex-google > toolChoiceRequiredParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "tool_calls", + "index": 0, + "message": { + "annotations": [], + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{"location":"Tokyo"}", + "name": "get_weather", + }, + "id": "", + "type": "function", + }, + ], + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 5, + "prompt_tokens": 7, + "total_tokens": 12, + }, +} +`; + +exports[`chat-completions → vertex-google > toolChoiceRequiredWithReasoningParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Tokyo weather", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseSchema": null, + "thinkingConfig": { + "includeThoughts": true, + "thinkingBudget": 2048, + }, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", + "toolConfig": { + "functionCallingConfig": { + "allowedFunctionNames": [ + "get_weather", + ], + "mode": "ANY", + }, + }, + "tools": [ + { + "functionDeclarations": [ + { + "description": "Get weather", + "name": "get_weather", + "parameters": null, + "parametersJsonSchema": { + "additionalProperties": false, + "properties": { + "location": { + "type": "string", + }, + }, + "required": [ + "location", + ], + "type": "object", + }, + "response": null, + }, + ], + }, + ], +} +`; + +exports[`chat-completions → vertex-google > toolChoiceRequiredWithReasoningParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "tool_calls", + "index": 0, + "message": { + "annotations": [], + "reasoning": "Ah, I see the user's request. They're looking for weather information, specifically for Tokyo. My internal knowledge base immediately points me to the \`get_weather\` tool – that's precisely what it's designed for. Now, I just need to provide it with the necessary details. The \`get_weather\` tool has a clear \`location\` parameter, and in this case, the location is unequivocally "Tokyo." So, the logical next step is to construct the tool call as \`get_weather(location="Tokyo")\`. This should effectively retrieve the weather data the user is asking for.", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{"location":"Tokyo"}", + "name": "get_weather", + }, + "id": "", + "type": "function", + }, + ], + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 63, + "completion_tokens_details": { + "reasoning_tokens": 58, + }, + "prompt_tokens": 7, + "total_tokens": 70, + }, +} +`; + +exports[`chat-completions → vertex-google > topPParam > request 1`] = ` +{ + "contents": [ + { + "parts": [ + { + "text": "Say hi.", + }, + ], + "role": "user", + }, + ], + "generationConfig": { + "responseSchema": null, + "topP": 0.9, + }, + "model": "publishers/google/models/gemini-2.5-flash-lite", +} +`; + +exports[`chat-completions → vertex-google > topPParam > response 1`] = ` +{ + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "annotations": [], + "content": "Hi there!", + "role": "assistant", + }, + }, + ], + "created": 0, + "id": "chatcmpl-transformed", + "model": "gemini-2.5-flash-lite", + "object": "chat.completion", + "usage": { + "completion_tokens": 3, + "prompt_tokens": 3, + "total_tokens": 6, + }, +} +`; + exports[`responses → anthropic > complexReasoningRequest > request 1`] = ` { "max_tokens": 20000, diff --git a/payloads/scripts/transforms/capture-transforms.ts b/payloads/scripts/transforms/capture-transforms.ts index d65282ea..abf1a351 100644 --- a/payloads/scripts/transforms/capture-transforms.ts +++ b/payloads/scripts/transforms/capture-transforms.ts @@ -1,10 +1,16 @@ #!/usr/bin/env tsx -import { existsSync, mkdirSync, writeFileSync } from "fs"; -import { dirname } from "path"; +import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs"; +import { dirname, resolve, isAbsolute } from "path"; +import { createSign } from "crypto"; import Anthropic from "@anthropic-ai/sdk"; import OpenAI from "openai"; -import { allTestCases, getCaseForProvider, GOOGLE_MODEL } from "../../cases"; +import { + allTestCases, + getCaseForProvider, + GOOGLE_MODEL, + VERTEX_GOOGLE_MODEL, +} from "../../cases"; import { TRANSFORM_PAIRS, STREAMING_PAIRS, @@ -21,6 +27,124 @@ import { const GOOGLE_API_BASE = "https://generativelanguage.googleapis.com/v1beta"; +interface ServiceAccountKey { + client_email: string; + private_key: string; + token_uri: string; +} + +function loadServiceAccountKey(): ServiceAccountKey { + const credPath = process.env.GOOGLE_APPLICATION_CREDENTIALS; + if (!credPath) { + throw new Error( + "GOOGLE_APPLICATION_CREDENTIALS environment variable is required" + ); + } + const resolvedPath = isAbsolute(credPath) + ? credPath + : resolve(process.cwd(), credPath); + const raw = readFileSync(resolvedPath, "utf-8"); + return JSON.parse(raw); +} + +function createSignedJwt(key: ServiceAccountKey): string { + const now = Math.floor(Date.now() / 1000); + const header = Buffer.from( + JSON.stringify({ alg: "RS256", typ: "JWT" }) + ).toString("base64url"); + const payload = Buffer.from( + JSON.stringify({ + iss: key.client_email, + sub: key.client_email, + aud: key.token_uri, + iat: now, + exp: now + 3600, + scope: "https://www.googleapis.com/auth/cloud-platform", + }) + ).toString("base64url"); + const signInput = `${header}.${payload}`; + const signer = createSign("RSA-SHA256"); + signer.update(signInput); + const signature = signer.sign(key.private_key, "base64url"); + return `${signInput}.${signature}`; +} + +let _cachedVertexToken: { token: string; expiresAt: number } | null = null; + +async function getVertexAccessToken(): Promise { + if ( + _cachedVertexToken && + Date.now() < _cachedVertexToken.expiresAt - 60_000 + ) { + return _cachedVertexToken.token; + } + const key = loadServiceAccountKey(); + const jwt = createSignedJwt(key); + const response = await fetch(key.token_uri, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: new URLSearchParams({ + grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", + assertion: jwt, + }), + }); + if (!response.ok) { + const text = await response.text(); + throw new Error(`Failed to get access token: ${response.status} ${text}`); + } + const json: unknown = await response.json(); + if ( + typeof json !== "object" || + json === null || + !("access_token" in json) || + !("expires_in" in json) + ) { + throw new Error("Invalid access token response"); + } + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- keys confirmed present via `in` checks above + const { access_token, expires_in } = json as Record; + if (typeof access_token !== "string" || typeof expires_in !== "number") { + throw new Error("Invalid access token response"); + } + _cachedVertexToken = { + token: access_token, + expiresAt: Date.now() + expires_in * 1000, + }; + return _cachedVertexToken.token; +} + +async function callVertexGoogleProvider( + request: Record +): Promise { + const project = process.env.VERTEX_PROJECT; + if (!project) { + throw new Error("VERTEX_PROJECT environment variable is required"); + } + const location = process.env.VERTEX_LOCATION ?? "us-central1"; + const rawModel = request.model ?? VERTEX_GOOGLE_MODEL; + const model = typeof rawModel === "string" ? rawModel : String(rawModel); + const { model: _model, ...body } = request; + + const token = await getVertexAccessToken(); + const url = `https://${location}-aiplatform.googleapis.com/v1/projects/${project}/locations/${location}/${model}:generateContent`; + + const response = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`Vertex Google API error (${response.status}): ${text}`); + } + + return response.json(); +} + let _anthropic: Anthropic | undefined; let _openai: OpenAI | undefined; @@ -85,6 +209,8 @@ async function callProvider( ); case "google": return callGoogleProvider(request); + case "vertex-google": + return callVertexGoogleProvider(request); } } /* eslint-enable @typescript-eslint/consistent-type-assertions */ diff --git a/payloads/scripts/transforms/helpers.ts b/payloads/scripts/transforms/helpers.ts index fab6653e..4b7f9fd7 100644 --- a/payloads/scripts/transforms/helpers.ts +++ b/payloads/scripts/transforms/helpers.ts @@ -18,13 +18,15 @@ import { GOOGLE_MODEL, OPENAI_CHAT_COMPLETIONS_MODEL, OPENAI_RESPONSES_MODEL, + VERTEX_GOOGLE_MODEL, } from "../../cases/models"; export type SourceFormat = | "chat-completions" | "responses" | "anthropic" - | "google"; + | "google" + | "vertex-google"; export type WasmFormat = "OpenAI" | "Responses" | "Anthropic" | "Google"; export interface TransformPair { @@ -65,6 +67,12 @@ export const TRANSFORM_PAIRS: TransformPair[] = [ wasmSource: "OpenAI", wasmTarget: "Google", }, + { + source: "chat-completions", + target: "vertex-google", + wasmSource: "OpenAI", + wasmTarget: "Google", + }, ]; // Validation functions by format @@ -73,6 +81,7 @@ const REQUEST_VALIDATORS: Record unknown> = { responses: validate_responses_request, anthropic: validate_anthropic_request, google: validate_google_request, + "vertex-google": validate_google_request, }; const RESPONSE_VALIDATORS: Record unknown> = { @@ -80,6 +89,7 @@ const RESPONSE_VALIDATORS: Record unknown> = { responses: validate_responses_response, anthropic: validate_anthropic_response, google: validate_google_response, + "vertex-google": validate_google_response, }; interface TransformResultData { @@ -183,6 +193,7 @@ export const TARGET_MODELS: Record = { "chat-completions": OPENAI_CHAT_COMPLETIONS_MODEL, responses: OPENAI_RESPONSES_MODEL, google: GOOGLE_MODEL, + "vertex-google": VERTEX_GOOGLE_MODEL, }; export function getTransformableCases( @@ -194,7 +205,9 @@ export function getTransformableCases( if ( caseName.endsWith("Param") && (pair.source !== "chat-completions" || - (pair.target !== "anthropic" && pair.target !== "google")) + (pair.target !== "anthropic" && + pair.target !== "google" && + pair.target !== "vertex-google")) ) return false; if (filter && !caseName.includes(filter)) return false; diff --git a/payloads/snapshots/reasoningRequest/vertex-google/followup-request.json b/payloads/snapshots/reasoningRequest/vertex-google/followup-request.json new file mode 100644 index 00000000..93483e1a --- /dev/null +++ b/payloads/snapshots/reasoningRequest/vertex-google/followup-request.json @@ -0,0 +1,29 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Solve this step by step: If a train travels 60 mph for 2 hours, then 80 mph for 1 hour, what's the average speed?" + } + ] + }, + { + "role": "model", + "parts": [ + { + "text": "Here's how to solve this problem step-by-step:\n\n**1. Understand the Concept of Average Speed**\n\nAverage speed is not simply the average of the individual speeds. It's calculated as:\n\nAverage Speed = Total Distance / Total Time\n\n**2. Calculate the Distance for Each Leg of the Journey**\n\nWe need to find out how far the train traveled at each speed. The formula for distance is:\n\nDistance = Speed × Time\n\n* **Leg 1:**\n * Speed = 60 mph\n * Time = 2 hours\n * Distance 1 = 60 mph × 2 hours = 120 miles\n\n* **Leg 2:**\n * Speed = 80 mph\n * Time = 1 hour\n * Distance 2 = 80 mph × 1 hour = 80 miles\n\n**3. Calculate the Total Distance**\n\nAdd the distances from each leg of the journey.\n\n* Total Distance = Distance 1 + Distance 2\n* Total Distance = 120 miles + 80 miles = 200 miles\n\n**4. Calculate the Total Time**\n\nAdd the time spent on each leg of the journey.\n\n* Total Time = Time 1 + Time 2\n* Total Time = 2 hours + 1 hour = 3 hours\n\n**5. Calculate the Average Speed**\n\nNow, use the formula for average speed with the total distance and total time.\n\n* Average Speed = Total Distance / Total Time\n* Average Speed = 200 miles / 3 hours\n* Average Speed = 66.67 mph (approximately)\n\n**Answer:** The average speed of the train is approximately **66.67 mph**." + } + ] + }, + { + "role": "user", + "parts": [ + { + "text": "What should I do next?" + } + ] + } + ] +} \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequest/vertex-google/followup-response-streaming.json b/payloads/snapshots/reasoningRequest/vertex-google/followup-response-streaming.json new file mode 100644 index 00000000..46644dca --- /dev/null +++ b/payloads/snapshots/reasoningRequest/vertex-google/followup-response-streaming.json @@ -0,0 +1,238 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "That" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "'s a great question! What you should do next depends entirely on your goals" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " and what you're trying to achieve. To give you the best advice, I need a" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " little more information about your situation.\n\nThink about these questions and tell me what comes to mind:\n\n**1. What was the purpose of asking me to" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " solve that math problem?**\n\n* Were you learning about **average speed** and want to practice more problems?\n* Were you testing my **problem" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "-solving abilities**?\n* Did you have a **specific project or task** in mind that this was a part of?\n* Are you **curious about train travel** or physics?\n* Something else entirely" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "?\n\n**2. What are you generally interested in or working on right now?**\n\n* Are you a **student**? If so, what subject and grade level?\n* Are you working on a **personal project**?\n" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "* Are you trying to **learn a new skill**?\n* Are you **researching something**?\n* Are you just **exploring possibilities**?\n\n**3. What kind of \"next steps\" are you looking for?**\n\n* More **math problems**?\n* " + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "**Explanations** of related concepts?\n* **Information** on a specific topic?\n* **Ideas** for what to do next?\n* **Assistance** with a task?\n\n**Once you tell me more about what you're thinking, I can provide much more targeted and helpful" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " suggestions!**\n\nFor example, if you say:\n\n* \"I'm a student learning about average speed and want more practice,\" I can give you more average speed problems.\n* \"I'm curious about how trains work,\" I can give you information about train engineering or history.\n* " + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "\"I was testing your ability to break down problems,\" I can acknowledge that and ask if you have other types of problems you'd like me to tackle.\n\nLooking forward to hearing what's on your mind!" + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 427, + "candidatesTokenCount": 439, + "totalTokenCount": 866, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 427 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 439 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.235739Z", + "responseId": "4ZbKaduxDomdheMP8OzF6Qk" + } +] \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequest/vertex-google/followup-response.json b/payloads/snapshots/reasoningRequest/vertex-google/followup-response.json new file mode 100644 index 00000000..c137c239 --- /dev/null +++ b/payloads/snapshots/reasoningRequest/vertex-google/followup-response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "That's a great question! What you should do next depends entirely on your goals and what you want to achieve. Here are a few possibilities, depending on what you were doing before asking:\n\n**If you were studying or learning something:**\n\n* **Review and Summarize:** Go over what you just learned. Can you explain it in your own words? Try writing a brief summary.\n* **Practice Problems:** If you're working through a textbook or online course, try another practice problem related to average speed or distance/rate/time calculations. This will solidify your understanding.\n* **Explore Related Concepts:** Average speed is a fundamental concept. You might want to explore related topics like:\n * **Relative Speed:** How speeds combine when objects are moving towards or away from each other.\n * **Acceleration:** How speed changes over time.\n * **Velocity vs. Speed:** The difference between speed (how fast) and velocity (how fast and in what direction).\n* **Ask More Questions:** If anything is still unclear, don't hesitate to ask! \"What if the train stopped for half an hour?\" or \"What if the speeds were decimals?\"\n* **Apply it to a Real-World Scenario:** Think about your own travel. How far do you go on a typical car ride? How long does it take? You can calculate your own average speed.\n\n**If you were asking for help with a specific task or project:**\n\n* **Implement the Solution:** If the problem you solved was part of a larger task (like coding, planning an event, etc.), now you can incorporate the solution into your project.\n* **Move to the Next Step:** What's the next logical step in your task or project after solving this specific problem?\n* **Verify the Solution:** Does the answer you got make sense in the context of your larger task?\n\n**If you were just curious or exploring:**\n\n* **Ask a New Question:** You can ask me anything! It could be another math problem, a question about science, history, literature, or even a creative prompt.\n* **Explore a New Topic:** Tell me what you're interested in, and I can suggest things to learn or discuss.\n* **Play a Game:** We could try a word game, a trivia challenge, or a creative writing exercise.\n* **Just Chat:** We can have a casual conversation about anything you like.\n\n**To give you a more specific recommendation, tell me:**\n\n* **What were you doing right before you asked about the train problem?**\n* **What are you hoping to achieve by interacting with me?**\n\nOnce I have a little more context, I can give you much better suggestions for what to do next!" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.3539034590761886 + } + ], + "usageMetadata": { + "promptTokenCount": 427, + "candidatesTokenCount": 585, + "totalTokenCount": 1012, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 427 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 585 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:37.237671Z", + "responseId": "4ZbKaefADv3-29sPnaKJqQY" +} \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequest/vertex-google/request.json b/payloads/snapshots/reasoningRequest/vertex-google/request.json new file mode 100644 index 00000000..df834bbe --- /dev/null +++ b/payloads/snapshots/reasoningRequest/vertex-google/request.json @@ -0,0 +1,13 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Solve this step by step: If a train travels 60 mph for 2 hours, then 80 mph for 1 hour, what's the average speed?" + } + ] + } + ] +} \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequest/vertex-google/response-streaming.json b/payloads/snapshots/reasoningRequest/vertex-google/response-streaming.json new file mode 100644 index 00000000..476bb32b --- /dev/null +++ b/payloads/snapshots/reasoningRequest/vertex-google/response-streaming.json @@ -0,0 +1,238 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Here" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "'s how to solve" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " this problem step-by-step:\n\n**Understanding Average Speed**\n\nAverage" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " speed isn't simply the average of the two speeds. It's the" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " *total distance traveled divided by the total time taken*.\n\n**Step 1: Calculate the distance traveled in the first part of the journey.**\n\n* " + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "**Formula:** Distance = Speed × Time\n* **Speed:** 60 mph\n* **Time:** 2 hours\n* **Distance" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " 1:** 60 mph × 2 hours = 120 miles\n\n**Step 2: Calculate the distance traveled in the second part of the journey.**\n\n* **Formula:** Distance = Speed × Time\n*" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " **Speed:** 80 mph\n* **Time:** 1 hour\n* **Distance 2:** 80 mph × 1 hour = 80 miles\n\n**Step 3: Calculate the total distance" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " traveled.**\n\n* **Total Distance:** Distance 1 + Distance 2\n* **Total Distance:** 120 miles + 80 miles = 200 miles\n\n**Step 4: Calculate the total time taken for the journey.**\n\n* **Total Time:** Time 1 + Time 2\n" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "* **Total Time:** 2 hours + 1 hour = 3 hours\n\n**Step 5: Calculate the average speed.**\n\n* **Formula:** Average Speed = Total Distance / Total Time\n* **Total Distance:** 200 miles\n* **Total Time:** 3 hours\n" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "* **Average Speed:** 200 miles / 3 hours = 66.67 mph (approximately)\n\n**Answer:** The average speed of the train is approximately **66.67 mph**." + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 36, + "candidatesTokenCount": 378, + "totalTokenCount": 414, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 36 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 378 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.156775Z", + "responseId": "35bKaefICfaAheMPg4_z6Ac" + } +] \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequest/vertex-google/response.json b/payloads/snapshots/reasoningRequest/vertex-google/response.json new file mode 100644 index 00000000..c94f0d32 --- /dev/null +++ b/payloads/snapshots/reasoningRequest/vertex-google/response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Here's how to solve this problem step-by-step:\n\n**1. Understand the Concept of Average Speed**\n\nAverage speed is not simply the average of the individual speeds. It's calculated as:\n\nAverage Speed = Total Distance / Total Time\n\n**2. Calculate the Distance for Each Leg of the Journey**\n\nWe need to find out how far the train traveled at each speed. The formula for distance is:\n\nDistance = Speed × Time\n\n* **Leg 1:**\n * Speed = 60 mph\n * Time = 2 hours\n * Distance 1 = 60 mph × 2 hours = 120 miles\n\n* **Leg 2:**\n * Speed = 80 mph\n * Time = 1 hour\n * Distance 2 = 80 mph × 1 hour = 80 miles\n\n**3. Calculate the Total Distance**\n\nAdd the distances from each leg of the journey.\n\n* Total Distance = Distance 1 + Distance 2\n* Total Distance = 120 miles + 80 miles = 200 miles\n\n**4. Calculate the Total Time**\n\nAdd the time spent on each leg of the journey.\n\n* Total Time = Time 1 + Time 2\n* Total Time = 2 hours + 1 hour = 3 hours\n\n**5. Calculate the Average Speed**\n\nNow, use the formula for average speed with the total distance and total time.\n\n* Average Speed = Total Distance / Total Time\n* Average Speed = 200 miles / 3 hours\n* Average Speed = 66.67 mph (approximately)\n\n**Answer:** The average speed of the train is approximately **66.67 mph**." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.060274347082361 + } + ], + "usageMetadata": { + "promptTokenCount": 36, + "candidatesTokenCount": 385, + "totalTokenCount": 421, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 36 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 385 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.148755Z", + "responseId": "35bKaZOKCb6yheMPoIWq0Qs" +} \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-request.json b/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-request.json new file mode 100644 index 00000000..a15ab931 --- /dev/null +++ b/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-request.json @@ -0,0 +1,32 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Solve this step by step: If a train travels 60 mph for 2 hours, then 80 mph for 1 hour, what's the average speed?" + } + ] + }, + { + "role": "model", + "parts": [ + { + "text": "Here's how to solve this problem step-by-step:\n\n**1. Understand the Goal:**\nWe need to find the *average speed* of the train over its entire journey. Average speed is calculated as:\n\nAverage Speed = Total Distance / Total Time\n\n**2. Break Down the Journey:**\nThe train's journey has two distinct parts:\n\n* **Part 1:** Travels at 60 mph for 2 hours.\n* **Part " + } + ] + }, + { + "role": "user", + "parts": [ + { + "text": "What should I do next?" + } + ] + } + ], + "generationConfig": { + "maxOutputTokens": 100 + } +} \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-response-streaming.json b/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-response-streaming.json new file mode 100644 index 00000000..3a809c75 --- /dev/null +++ b/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-response-streaming.json @@ -0,0 +1,118 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "You" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.961762Z", + "responseId": "35bKaeLZOuTZ29sP5fjDsAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "'re right to ask! We've just finished breaking down the journey into its" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.961762Z", + "responseId": "35bKaeLZOuTZ29sP5fjDsAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " two parts.\n\n**What you should do next is to calculate the distance traveled in each part of the" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.961762Z", + "responseId": "35bKaeLZOuTZ29sP5fjDsAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " journey.**\n\nRemember the relationship between distance, speed, and time:\n\n**Distance = Speed × Time**\n\nSo, for each part of the train's trip" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.961762Z", + "responseId": "35bKaeLZOuTZ29sP5fjDsAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": ", you'll use this formula." + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 142, + "candidatesTokenCount": 81, + "totalTokenCount": 223, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 142 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 81 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.961762Z", + "responseId": "35bKaeLZOuTZ29sP5fjDsAY" + } +] \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-response.json b/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-response.json new file mode 100644 index 00000000..8759bd27 --- /dev/null +++ b/payloads/snapshots/reasoningRequestTruncated/vertex-google/followup-response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "You're right to ask! We've just finished calculating the *total distance* and *total time*.\n\n**The next step is to use these two values to calculate the average speed.**\n\nRemember our formula for average speed:\n\n**Average Speed = Total Distance / Total Time**" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.28805037676277806 + } + ], + "usageMetadata": { + "promptTokenCount": 142, + "candidatesTokenCount": 59, + "totalTokenCount": 201, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 142 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 59 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:36.007967Z", + "responseId": "4JbKaZ8-mu3b2w_gx-_JCQ" +} \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequestTruncated/vertex-google/request.json b/payloads/snapshots/reasoningRequestTruncated/vertex-google/request.json new file mode 100644 index 00000000..8088aeca --- /dev/null +++ b/payloads/snapshots/reasoningRequestTruncated/vertex-google/request.json @@ -0,0 +1,16 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Solve this step by step: If a train travels 60 mph for 2 hours, then 80 mph for 1 hour, what's the average speed?" + } + ] + } + ], + "generationConfig": { + "maxOutputTokens": 100 + } +} \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequestTruncated/vertex-google/response-streaming.json b/payloads/snapshots/reasoningRequestTruncated/vertex-google/response-streaming.json new file mode 100644 index 00000000..ddda7b95 --- /dev/null +++ b/payloads/snapshots/reasoningRequestTruncated/vertex-google/response-streaming.json @@ -0,0 +1,138 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Here" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.157775Z", + "responseId": "35bKac_QCf3-29sPnaKJqQY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "'s how to solve" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.157775Z", + "responseId": "35bKac_QCf3-29sPnaKJqQY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " this problem step-by-step:\n\n**1. Calculate the distance traveled in the first" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.157775Z", + "responseId": "35bKac_QCf3-29sPnaKJqQY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " part of the journey.**\n\n* **Formula:** Distance = Speed × Time\n* **Given:**" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.157775Z", + "responseId": "35bKac_QCf3-29sPnaKJqQY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " Speed = 60 mph, Time = 2 hours\n* **Calculation:** Distance1 = 60 mph × 2 hours = 120 miles" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.157775Z", + "responseId": "35bKac_QCf3-29sPnaKJqQY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "\n\n**2. Calculate the distance traveled in the second part of the journey.**\n\n* **Formula:**" + } + ] + }, + "finishReason": "MAX_TOKENS" + } + ], + "usageMetadata": { + "promptTokenCount": 36, + "candidatesTokenCount": 100, + "totalTokenCount": 136, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 36 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 100 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.157775Z", + "responseId": "35bKac_QCf3-29sPnaKJqQY" + } +] \ No newline at end of file diff --git a/payloads/snapshots/reasoningRequestTruncated/vertex-google/response.json b/payloads/snapshots/reasoningRequestTruncated/vertex-google/response.json new file mode 100644 index 00000000..3acefc92 --- /dev/null +++ b/payloads/snapshots/reasoningRequestTruncated/vertex-google/response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Here's how to solve this problem step-by-step:\n\n**1. Understand the Goal:**\nWe need to find the *average speed* of the train over its entire journey. Average speed is calculated as:\n\nAverage Speed = Total Distance / Total Time\n\n**2. Break Down the Journey:**\nThe train's journey has two distinct parts:\n\n* **Part 1:** Travels at 60 mph for 2 hours.\n* **Part " + } + ] + }, + "finishReason": "MAX_TOKENS", + "avgLogprobs": -0.06584382057189941 + } + ], + "usageMetadata": { + "promptTokenCount": 36, + "candidatesTokenCount": 100, + "totalTokenCount": 136, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 36 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 100 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.284552Z", + "responseId": "35bKaYivEeTZ29sP5fjDsAY" +} \ No newline at end of file diff --git a/payloads/snapshots/simpleRequest/vertex-google/followup-request.json b/payloads/snapshots/simpleRequest/vertex-google/followup-request.json new file mode 100644 index 00000000..cdb62ddb --- /dev/null +++ b/payloads/snapshots/simpleRequest/vertex-google/followup-request.json @@ -0,0 +1,29 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "What is the capital of France?" + } + ] + }, + { + "role": "model", + "parts": [ + { + "text": "The capital of France is **Paris**." + } + ] + }, + { + "role": "user", + "parts": [ + { + "text": "What should I do next?" + } + ] + } + ] +} \ No newline at end of file diff --git a/payloads/snapshots/simpleRequest/vertex-google/followup-response-streaming.json b/payloads/snapshots/simpleRequest/vertex-google/followup-response-streaming.json new file mode 100644 index 00000000..2a20b426 --- /dev/null +++ b/payloads/snapshots/simpleRequest/vertex-google/followup-response-streaming.json @@ -0,0 +1,318 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "That" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "'s a great" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " question, and the answer depends entirely on what you want to do! To give you the best" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " advice, I need a little more information.\n\nTell me:\n\n* **What were" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " you doing before you asked this question?** (Were you just browsing? Reading something specific? Working on a task?)\n* **What are your current interests or goals?" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "** (Are you looking for entertainment, information, to learn something new, to be productive, to relax?)\n* **What kind of things do you usually" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " enjoy?** (Are you into history, science, art, cooking, gaming, sports, music, writing, travel, etc.?)\n* **Do you have any specific constraints?** (Like limited time, budget, or" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " resources?)\n\n**In the meantime, here are some general ideas to get you thinking, categorized by what you might be looking for:**\n\n**If you're looking for entertainment/distraction:**\n\n* **Ask me a fun" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " question!** Like \"Tell me a joke,\" \"Give me a weird fact,\" or \"Invent a new animal.\"\n* **Play a game.** We can try a trivia game, a word association game, or I can even tell you a story.\n* **Explore a new topic.** Ask me about something" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " you're curious about, even if it's something random.\n* **Get a creative prompt.** I can suggest a writing prompt, a drawing idea, or a story scenario.\n* **Listen to music or a podcast.** I can suggest some based on your preferences.\n\n**If you're looking" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " to learn something new:**\n\n* **Ask me to explain a complex concept.** Like quantum physics, artificial intelligence, or how the internet works.\n* **Learn about a historical event or person.**\n* **Discover a new skill.** I can provide information or steps on how to do things like knitting, basic" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " coding, or cooking a simple recipe.\n* **Explore a different culture.** Ask me about traditions, food, or geography of a country.\n\n**If you're looking to be productive/get things done:**\n\n* **Ask me to help you plan something.** A trip, a meal, a project" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": ".\n* **Get help with writing.** I can help you brainstorm, outline, or even draft text for emails, essays, or creative pieces.\n* **Solve a problem.** Describe a problem you're facing, and I'll try to offer solutions.\n* **Organize your thoughts" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": ".** You can tell me what's on your mind, and I can help you structure it.\n\n**If you're feeling creative:**\n\n* **Write a story together.** You start, and I continue, or vice-versa.\n* **Brainstorm ideas for a project.** A business, a hobby, an" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " event.\n* **Create a poem or song lyrics.**\n\n**Once you give me a little more direction, I can give you a much more tailored and helpful suggestion!**" + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 21, + "candidatesTokenCount": 640, + "totalTokenCount": 661, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 21 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 640 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.880059Z", + "responseId": "35bKabvbNff-29sPhZmkwQM" + } +] \ No newline at end of file diff --git a/payloads/snapshots/simpleRequest/vertex-google/followup-response.json b/payloads/snapshots/simpleRequest/vertex-google/followup-response.json new file mode 100644 index 00000000..e662d077 --- /dev/null +++ b/payloads/snapshots/simpleRequest/vertex-google/followup-response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "That's a great question, but it's a bit like asking \"What should I eat next?\" without telling me what you like or what you have available! To give you good advice, I need a little more information.\n\nTell me:\n\n**1. What are you interested in?**\n* Are you looking for something to do **right now**?\n* Are you planning something for the **future**?\n* Are you interested in **learning** something new?\n* Are you looking for **entertainment**?\n* Are you trying to **solve a problem**?\n* Are you looking for **personal growth** or **self-improvement**?\n* Are you thinking about **travel**?\n* Are you looking for **creative inspiration**?\n\n**2. What's your current situation?**\n* Are you at home, at work, or somewhere else?\n* What resources do you have available (e.g., computer, phone, books, materials)?\n* How much time do you have?\n* Who are you with (if anyone)?\n\n**3. What have you been doing recently?**\n* This can help me suggest something different or a continuation of something you've enjoyed.\n\n**Once I have a better understanding of what you're looking for, I can give you some much more specific and helpful suggestions!**\n\nFor example, if you just asked \"What is the capital of France?\", I could suggest:\n\n* **Learning more about Paris:** Its history, landmarks, culture, etc.\n* **Planning a trip to Paris:** Researching flights, accommodation, and things to do.\n* **Trying French cuisine:** Looking up recipes or finding a French restaurant.\n* **Learning some French phrases:** To prepare for a potential trip or just for fun.\n\nSo, tell me, **what's on your mind?**" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.25043986250714556 + } + ], + "usageMetadata": { + "promptTokenCount": 21, + "candidatesTokenCount": 410, + "totalTokenCount": 431, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 21 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 410 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.860496Z", + "responseId": "35bKadDCNOTZ29sP5fjDsAY" +} \ No newline at end of file diff --git a/payloads/snapshots/simpleRequest/vertex-google/request.json b/payloads/snapshots/simpleRequest/vertex-google/request.json new file mode 100644 index 00000000..eb36dbc9 --- /dev/null +++ b/payloads/snapshots/simpleRequest/vertex-google/request.json @@ -0,0 +1,13 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "What is the capital of France?" + } + ] + } + ] +} \ No newline at end of file diff --git a/payloads/snapshots/simpleRequest/vertex-google/response-streaming.json b/payloads/snapshots/simpleRequest/vertex-google/response-streaming.json new file mode 100644 index 00000000..8905b268 --- /dev/null +++ b/payloads/snapshots/simpleRequest/vertex-google/response-streaming.json @@ -0,0 +1,78 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "The" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.153877Z", + "responseId": "35bKaZWyCamzheMPiLOJ0Qo" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " capital of France" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.153877Z", + "responseId": "35bKaZWyCamzheMPiLOJ0Qo" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " is **Paris**." + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 7, + "candidatesTokenCount": 8, + "totalTokenCount": 15, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.153877Z", + "responseId": "35bKaZWyCamzheMPiLOJ0Qo" + } +] \ No newline at end of file diff --git a/payloads/snapshots/simpleRequest/vertex-google/response.json b/payloads/snapshots/simpleRequest/vertex-google/response.json new file mode 100644 index 00000000..510805ec --- /dev/null +++ b/payloads/snapshots/simpleRequest/vertex-google/response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "The capital of France is **Paris**." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.004186893813312054 + } + ], + "usageMetadata": { + "promptTokenCount": 7, + "candidatesTokenCount": 8, + "totalTokenCount": 15, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:29:35.251951Z", + "responseId": "35bKaa-wD6mzheMPiLOJ0Qo" +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-request.json b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-request.json new file mode 100644 index 00000000..5249e3a3 --- /dev/null +++ b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-request.json @@ -0,0 +1,32 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Return {\"status\": \"ok\"} as JSON." + } + ] + }, + { + "role": "model", + "parts": [ + { + "text": "{\"status\": \"ok\"}" + } + ] + }, + { + "role": "user", + "parts": [ + { + "text": "What should I do next?" + } + ] + } + ], + "generationConfig": { + "responseMimeType": "application/json" + } +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-response-streaming.json b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-response-streaming.json new file mode 100644 index 00000000..d4371eeb --- /dev/null +++ b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-response-streaming.json @@ -0,0 +1,78 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\"" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.210891Z", + "responseId": "LJzKacvvDOTZ29sP5fjDsAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "status\": \"" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.210891Z", + "responseId": "LJzKacvvDOTZ29sP5fjDsAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "ok\"}" + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 22, + "candidatesTokenCount": 6, + "totalTokenCount": 28, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 22 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 6 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.210891Z", + "responseId": "LJzKacvvDOTZ29sP5fjDsAY" + } +] \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-response.json b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-response.json new file mode 100644 index 00000000..7bbac274 --- /dev/null +++ b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/followup-response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\"status\": \"ok\"}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.02323950578769048 + } + ], + "usageMetadata": { + "promptTokenCount": 22, + "candidatesTokenCount": 6, + "totalTokenCount": 28, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 22 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 6 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.135106Z", + "responseId": "LJzKacKfCJro88APvMH1sAw" +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonObjectParam/vertex-google/request.json b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/request.json new file mode 100644 index 00000000..c454bc1c --- /dev/null +++ b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/request.json @@ -0,0 +1,16 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Return {\"status\": \"ok\"} as JSON." + } + ] + } + ], + "generationConfig": { + "responseMimeType": "application/json" + } +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonObjectParam/vertex-google/response-streaming.json b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/response-streaming.json new file mode 100644 index 00000000..b65738c4 --- /dev/null +++ b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/response-streaming.json @@ -0,0 +1,78 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\"" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.794973Z", + "responseId": "K5zKad3CMI7b88APmL2zyQg" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "status\": \"ok\"}" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.794973Z", + "responseId": "K5zKad3CMI7b88APmL2zyQg" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "" + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 10, + "candidatesTokenCount": 6, + "totalTokenCount": 16, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 10 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 6 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.794973Z", + "responseId": "K5zKad3CMI7b88APmL2zyQg" + } +] \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonObjectParam/vertex-google/response.json b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/response.json new file mode 100644 index 00000000..40f14048 --- /dev/null +++ b/payloads/snapshots/textFormatJsonObjectParam/vertex-google/response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\"status\": \"ok\"}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.00005933811674670627 + } + ], + "usageMetadata": { + "promptTokenCount": 10, + "candidatesTokenCount": 6, + "totalTokenCount": 16, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 10 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 6 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.703412Z", + "responseId": "K5zKabT3Kpjm88AP6uPG8As" +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-request.json b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-request.json new file mode 100644 index 00000000..fd6f8844 --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-request.json @@ -0,0 +1,47 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Extract: John is 25." + } + ] + }, + { + "role": "model", + "parts": [ + { + "text": "{\n \"name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + { + "role": "user", + "parts": [ + { + "text": "What should I do next?" + } + ] + } + ], + "generationConfig": { + "responseMimeType": "application/json", + "responseJsonSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "number" + } + }, + "required": [ + "name", + "age" + ] + } + } +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-response-streaming.json b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-response-streaming.json new file mode 100644 index 00000000..0ec9fefd --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-response-streaming.json @@ -0,0 +1,78 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.091992Z", + "responseId": "LJzKadjOBcfp88APsqiOmAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "\n \"" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.091992Z", + "responseId": "LJzKadjOBcfp88APsqiOmAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 33, + "candidatesTokenCount": 19, + "totalTokenCount": 52, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 33 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.091992Z", + "responseId": "LJzKadjOBcfp88APsqiOmAY" + } +] \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-response.json b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-response.json new file mode 100644 index 00000000..a289be31 --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/followup-response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\n \"name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.003994755446910858 + } + ], + "usageMetadata": { + "promptTokenCount": 33, + "candidatesTokenCount": 19, + "totalTokenCount": 52, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 33 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.128204Z", + "responseId": "LJzKaczpB4GX7rcP8amI8A4" +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/request.json b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/request.json new file mode 100644 index 00000000..de611a5d --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/request.json @@ -0,0 +1,31 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Extract: John is 25." + } + ] + } + ], + "generationConfig": { + "responseMimeType": "application/json", + "responseJsonSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "number" + } + }, + "required": [ + "name", + "age" + ] + } + } +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/response-streaming.json b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/response-streaming.json new file mode 100644 index 00000000..39d9b41a --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/response-streaming.json @@ -0,0 +1,78 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.707091Z", + "responseId": "K5zKaZOUK8fp88APsqiOmAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "\n \"name\":" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.707091Z", + "responseId": "K5zKaZOUK8fp88APsqiOmAY" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 8, + "candidatesTokenCount": 19, + "totalTokenCount": 27, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.707091Z", + "responseId": "K5zKaZOUK8fp88APsqiOmAY" + } +] \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/response.json b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/response.json new file mode 100644 index 00000000..daf88b68 --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaParam/vertex-google/response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\n \"name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.0010230096155091335 + } + ], + "usageMetadata": { + "promptTokenCount": 8, + "candidatesTokenCount": 19, + "totalTokenCount": 27, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.704524Z", + "responseId": "K5zKaYyAK8qAzvgP_vC8mAk" +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-request.json b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-request.json new file mode 100644 index 00000000..fd6f8844 --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-request.json @@ -0,0 +1,47 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Extract: John is 25." + } + ] + }, + { + "role": "model", + "parts": [ + { + "text": "{\n \"name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + { + "role": "user", + "parts": [ + { + "text": "What should I do next?" + } + ] + } + ], + "generationConfig": { + "responseMimeType": "application/json", + "responseJsonSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "number" + } + }, + "required": [ + "name", + "age" + ] + } + } +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-response-streaming.json b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-response-streaming.json new file mode 100644 index 00000000..87a81439 --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-response-streaming.json @@ -0,0 +1,78 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.368536Z", + "responseId": "LJzKaZi_FomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "\n \"" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.368536Z", + "responseId": "LJzKaZi_FomdheMP8OzF6Qk" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 33, + "candidatesTokenCount": 19, + "totalTokenCount": 52, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 33 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.368536Z", + "responseId": "LJzKaZi_FomdheMP8OzF6Qk" + } +] \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-response.json b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-response.json new file mode 100644 index 00000000..164ddf22 --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/followup-response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\n \"name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.007324193653307463 + } + ], + "usageMetadata": { + "promptTokenCount": 33, + "candidatesTokenCount": 19, + "totalTokenCount": 52, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 33 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:12.373751Z", + "responseId": "LJzKaffnFvaS7rcPpPevyQs" +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/request.json b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/request.json new file mode 100644 index 00000000..de611a5d --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/request.json @@ -0,0 +1,31 @@ +{ + "model": "publishers/google/models/gemini-2.5-flash-lite", + "contents": [ + { + "role": "user", + "parts": [ + { + "text": "Extract: John is 25." + } + ] + } + ], + "generationConfig": { + "responseMimeType": "application/json", + "responseJsonSchema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "age": { + "type": "number" + } + }, + "required": [ + "name", + "age" + ] + } + } +} \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/response-streaming.json b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/response-streaming.json new file mode 100644 index 00000000..dd8566e7 --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/response-streaming.json @@ -0,0 +1,78 @@ +[ + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.799252Z", + "responseId": "K5zKaZTkMNXn88APtcbT2A0" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "\n \"name\":" + } + ] + } + } + ], + "usageMetadata": { + "trafficType": "ON_DEMAND_PRIORITY" + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.799252Z", + "responseId": "K5zKaZTkMNXn88APtcbT2A0" + }, + { + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": " \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP" + } + ], + "usageMetadata": { + "promptTokenCount": 8, + "candidatesTokenCount": 19, + "totalTokenCount": 27, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.799252Z", + "responseId": "K5zKaZTkMNXn88APtcbT2A0" + } +] \ No newline at end of file diff --git a/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/response.json b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/response.json new file mode 100644 index 00000000..1dc1905b --- /dev/null +++ b/payloads/snapshots/textFormatJsonSchemaWithDescriptionParam/vertex-google/response.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\n \"name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.0010230096155091335 + } + ], + "usageMetadata": { + "promptTokenCount": 8, + "candidatesTokenCount": 19, + "totalTokenCount": 27, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:11.800821Z", + "responseId": "K5zKabXwML6yheMPoIWq0Qs" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/complexReasoningRequest.json b/payloads/transforms/chat-completions_to_vertex-google/complexReasoningRequest.json new file mode 100644 index 00000000..056bf996 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/complexReasoningRequest.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Let's break this down to figure out the most common and rarest digits and their percentages.\n\n**1. Total Number of Digits**\n\n* **Hours:** There are 24 hours in a day (00 to 23).\n* **Minutes:** There are 60 minutes in an hour (00 to 59).\n* **Total Time Combinations:** 24 hours * 60 minutes = 1440 unique time combinations.\n\nNow, let's consider how many digits are displayed for each time:\n\n* Each time is displayed as HH:MM, which is 5 characters.\n* However, the colon is not a digit. We have 4 digits for each time: 2 for hours and 2 for minutes.\n\nTherefore, the total number of digits displayed across all times is:\n1440 time combinations * 4 digits/time = **5760 digits**.\n\n**2. Counting the Occurrences of Each Digit (0-9)**\n\nWe need to systematically count how many times each digit appears in all the possible hour and minute combinations.\n\n* **Hours (00 to 23):**\n * **Tens digit of hours:**\n * '0' appears 10 times (00-09)\n * '1' appears 10 times (10-19)\n * '2' appears 4 times (20-23)\n * **Units digit of hours:**\n * '0' appears 3 times (00, 10, 20)\n * '1' appears 3 times (01, 11, 21)\n * '2' appears 3 times (02, 12, 22)\n * '3' appears 3 times (03, 13, 23)\n * '4' appears 2 times (04, 14)\n * '5' appears 2 times (05, 15)\n * '6' appears 2 times (06, 16)\n * '7' appears 2 times (07, 17)\n * '8' appears 2 times (08, 18)\n * '9' appears 2 times (09, 19)\n\n Let's sum these up for hours:\n * **0:** (10 + 3) = 13\n * **1:** (10 + 3) = 13\n * **2:** (4 + 3) = 7\n * **3:** (0 + 3) = 3\n * **4:** (0 + 2) = 2\n * **5:** (0 + 2) = 2\n * **6:** (0 + 2) = 2\n * **7:** (0 + 2) = 2\n * **8:** (0 + 2) = 2\n * **9:** (0 + 2) = 2\n\n* **Minutes (00 to 59):** This is easier because the pattern repeats for every 10-minute interval.\n * **Tens digit of minutes:**\n * '0' appears 10 times (00-09)\n * '1' appears 10 times (10-19)\n * '2' appears 10 times (20-29)\n * '3' appears 10 times (30-39)\n * '4' appears 10 times (40-49)\n * '5' appears 10 times (50-59)\n * **Units digit of minutes:** In every block of 10 minutes, each digit from 0 to 9 appears once. Since there are 6 such blocks (0-9, 10-19, ..., 50-59), each unit digit appears 6 times.\n * '0' appears 6 times\n * '1' appears 6 times\n * '2' appears 6 times\n * '3' appears 6 times\n * '4' appears 6 times\n * '5' appears 6 times\n * '6' appears 6 times\n * '7' appears 6 times\n * '8' appears 6 times\n * '9' appears 6 times\n\n Let's sum these up for minutes:\n * **0:** (10 * 6) + 6 = 60 + 6 = 66\n * **1:** (10 * 6) + 6 = 60 + 6 = 66\n * **2:** (10 * 6) + 6 = 60 + 6 = 66\n * **3:** (10 * 6) + 6 = 60 + 6 = 66\n * **4:** (10 * 6) + 6 = 60 + 6 = 66\n * **5:** (10 * 6) + 6 = 60 + 6 = 66\n * **6:** (0 * 6) + 6 = 0 + 6 = 6\n * **7:** (0 * 6) + 6 = 0 + 6 = 6\n * **8:** (0 * 6) + 6 = 0 + 6 = 6\n * **9:** (0 * 6) + 6 = 0 + 6 = 6\n\n* **Total Count for Each Digit (Hours + Minutes):**\n * **0:** 13 (hours) + 66 (minutes) = **79**\n * **1:** 13 (hours) + 66 (minutes) = **79**\n * **2:** 7 (hours) + 66 (minutes) = **73**\n * **3:** 3 (hours) + 66 (minutes) = **69**\n * **4:** 2 (hours) + 66 (minutes) = **68**\n * **5:** 2 (hours) + 66 (minutes) = **68**\n * **6:** 2 (hours) + 6 (minutes) = **8**\n * **7:** 2 (hours) + 6 (minutes) = **8**\n * **8:** 2 (hours) + 6 (minutes) = **8**\n * **9:** 2 (hours) + 6 (minutes) = **8**\n\n**Let's double check our count of minutes digits:**\nTotal minutes digits displayed: 1440 times * 2 digits/minute = 2880 minute digits.\nSum of our minute digit counts: 6 * 66 (for 0-5) + 4 * 6 (for 6-9) = 396 + 24 = 420. This is incorrect.\n\nLet's re-evaluate the minute digits.\nFor each of the 60 minutes (00-59):\n* The tens digit cycles through 0 (10 times), 1 (10 times), 2 (10 times), 3 (10 times), 4 (10 times), 5 (10 times).\n* The units digit cycles through 0-9 six times.\n\nSo, for the minutes portion (MM):\n* **Digit 0:** Tens digit appears 10 times (00-09). Units digit appears 6 times (00, 10, 20, 30, 40, 50). Total for minutes: 10 + 6 = 16.\n* **Digit 1:** Tens digit appears 10 times (10-19). Units digit appears 6 times (01, 11, 21, 31, 41, 51). Total for minutes: 10 + 6 = 16.\n* **Digit 2:** Tens digit appears 10 times (20-29). Units digit appears 6 times (02, 12, 22, 32, 42, 52). Total for minutes: 10 + 6 = 16.\n* **Digit 3:** Tens digit appears 10 times (30-39). Units digit appears 6 times (03, 13, 23, 33, 43, 53). Total for minutes: 10 + 6 = 16.\n* **Digit 4:** Tens digit appears 10 times (40-49). Units digit appears 6 times (04, 14, 24, 34, 44, 54). Total for minutes: 10 + 6 = 16.\n* **Digit 5:** Tens digit appears 10 times (50-59). Units digit appears 6 times (05, 15, 25, 35, 45, 55). Total for minutes: 10 + 6 = 16.\n* **Digit 6:** Tens digit appears 0 times in the 00-59 range. Units digit appears 6 times (06, 16, 26, 36, 46, 56). Total for minutes: 0 + 6 = 6.\n* **Digit 7:** Tens digit appears 0 times. Units digit appears 6 times (07, 17, 27, 37, 47, 57). Total for minutes: 0 + 6 = 6.\n* **Digit 8:** Tens digit appears 0 times. Units digit appears 6 times (08, 18, 28, 38, 48, 58). Total for minutes: 0 + 6 = 6.\n* **Digit 9:** Tens digit appears 0 times. Units digit appears 6 times (09, 19, 29, 39, 49, 59). Total for minutes: 0 + 6 = 6.\n\nLet's verify the total minute digits: 6 * 16 (for 0-5) + 4 * 6 (for 6-9) = 96 + 24 = 120.\nThis is still not right. The issue is that there are 60 minutes, and each minute has 2 digits. Total minute digits = 60 * 2 = 120.\nThe previous calculation method was counting the occurrences across all 1440 times.\n\nLet's re-do the minute counts across all 1440 times:\nFor each hour (00 to 23), the minutes run from 00 to 59.\nSo, the distribution of digits in the minutes part is the same for every hour.\n\nTotal occurrences of a digit in the minutes across all 24 hours:\n* **Digit 0:** Tens digit appears 10 times per hour (00-09). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384**\n* **Digit 1:** Tens digit appears 10 times per hour (10-19). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384**\n* **Digit 2:** Tens digit appears 10 times per hour (20-29). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384**\n* **Digit 3:** Tens digit appears 10 times per hour (30-39). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384**\n* **Digit 4:** Tens digit appears 10 times per hour (40-49). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384**\n* **Digit 5:** Tens digit appears 10 times per hour (50-59). Units digit appears 6 times per hour. Total per hour = 16. Across 24 hours: 16 * 24 = **384**\n* **Digit 6:** Tens digit appears 0 times per hour. Units digit appears 6 times per hour. Total per hour = 6. Across 24 hours: 6 * 24 = **144**\n* **Digit 7:** Tens digit appears 0 times per hour. Units digit appears 6 times per hour. Total per hour = 6. Across 24 hours: 6 * 24 = **144**\n* **Digit 8:** Tens digit appears 0 times per hour. Units digit appears 6 times per hour. Total per hour = 6. Across 24 hours: 6 * 24 = **144**\n* **Digit 9:** Tens digit appears 0 times per hour. Units digit appears 6 times per hour. Total per hour = 6. Across 24 hours: 6 * 24 = **144**\n\nLet's sum these minute digits: 6 * 384 + 4 * 144 = 2304 + 576 = 2880. This matches the total number of minute digits.\n\nNow, let's combine hour and minute digit counts:\n* **Digit 0:** 13 (hours) + 384 (minutes) = **397**\n* **Digit 1:** 13 (hours) + 384 (minutes) = **397**\n* **Digit 2:** 7 (hours) + 384 (minutes) = **391**\n* **Digit 3:** 3 (hours) + 384 (minutes) = **387**\n* **Digit 4:** 2 (hours) + 384 (minutes) = **386**\n* **Digit 5:** 2 (hours) + 384 (minutes) = **386**\n* **Digit 6:** 2 (hours) + 144 (minutes) = **146**\n* **Digit 7:** 2 (hours) + 144 (minutes) = **146**\n* **Digit 8:** 2 (hours) + 144 (minutes) = **146**\n* **Digit 9:** 2 (hours) + 144 (minutes) = **146**\n\nLet's sum these total digit counts: 2 * 397 + 391 + 387 + 2 * 386 + 4 * 146 = 794 + 391 + 387 + 772 + 584 = 2928.\nThis is still not 5760. The issue is in how we are summing. We need to count the total occurrences of each digit.\n\nLet's restart the counting from scratch, systematically.\n\n**Total number of digits: 5760**\n\nWe can analyze the digits based on their position:\n* **Hour Tens Digit (H1):** Ranges from 0 to 2.\n * 0 appears 10 times (00-09)\n * 1 appears 10 times (10-19)\n * 2 appears 4 times (20-23)\n * Total times H1 is displayed: 10 + 10 + 4 = 24 times *per minute*. This is not how we should count.\n\nLet's count the occurrences across all 1440 times:\n\n**Hour Digits:**\n* **Tens Digit of Hour:**\n * '0': Appears in 00:00 through 09:59. That's 10 hours. So, 10 * 60 minutes = 600 times.\n * '1': Appears in 10:00 through 19:59. That's 10 hours. So, 10 * 60 minutes = 600 times.\n * '2': Appears in 20:00 through 23:59. That's 4 hours. So, 4 * 60 minutes = 240 times.\n* **Units Digit of Hour:**\n * '0': Appears in 00, 10, 20. For each of these hour patterns (e.g., 00), it appears for 60 minutes. So, 3 * 60 = 180 times.\n * '1': Appears in 01, 11, 21. So, 3 * 60 = 180 times.\n * '2': Appears in 02, 12, 22. So, 3 * 60 = 180 times.\n * '3': Appears in 03, 13, 23. So, 3 * 60 = 180 times.\n * '4': Appears in 04, 14. So, 2 * 60 = 120 times.\n * '5': Appears in 05, 15. So, 2 * 60 = 120 times.\n * '6': Appears in 06, 16. So, 2 * 60 = 120 times.\n * '7': Appears in 07, 17. So, 2 * 60 = 120 times.\n * '8': Appears in 08, 18. So, 2 * 60 = 120 times.\n * '9': Appears in 09, 19. So, 2 * 60 = 120 times.\n\n**Total Hour Digit Counts:**\n* '0': 600 + 180 = **780**\n* '1': 600 + 180 = **780**\n* '2': 240 + 180 = **420**\n* '3': 0 + 180 = **180**\n* '4': 0 + 120 = **120**\n* '5': 0 + 120 = **120**\n* '6': 0 + 120 = **120**\n* '7': 0 + 120 = **120**\n* '8': 0 + 120 = **120**\n* '9': 0 + 120 = **120**\n\nSum of hour digits: 2*780 + 420 + 180 + 6*120 = 1560 + 420 + 180 + 720 = 2880. This is correct for the hour digits (24 hours * 60 minutes * 2 digits/hour = 2880 digits).\n\n**Minute Digits:**\nFor every hour, the minutes run from 00 to 59. This means the distribution of digits in the minutes is the same for each of the 24 hours.\n* **Tens Digit of Minute:**\n * '0': Appears in 00-09. That's 10 minutes. For each hour, this occurs 10 times. Over 24 hours: 10 * 24 = 240 times.\n * '1': Appears in 10-19. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times.\n * '2': Appears in 20-29. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times.\n * '3': Appears in 30-39. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times.\n * '4': Appears in 40-49. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times.\n * '5': Appears in 50-59. That's 10 minutes. Over 24 hours: 10 * 24 = 240 times.\n* **Units Digit of Minute:**\n * '0': Appears in 00, 10, 20, 30, 40, 50. That's 6 times for every hour. Over 24 hours: 6 * 24 = 144 times.\n * '1': Appears in 01, 11, 21, 31, 41, 51. So, 6 * 24 = 144 times.\n * '2': Appears in 02, 12, 22, 32, 42, 52. So, 6 * 24 = 144 times.\n * '3': Appears in 03, 13, 23, 33, 43, 53. So, 6 * 24 = 144 times.\n * '4': Appears in 04, 14, 24, 34, 44, 54. So, 6 * 24 = 144 times.\n * '5': Appears in 05, 15, 25, 35, 45, 55. So, 6 * 24 = 144 times.\n * '6': Appears in 06, 16, 26, 36, 46, 56. So, 6 * 24 = 144 times.\n * '7': Appears in 07, 17, 27, 37, 47, 57. So, 6 * 24 = 144 times.\n * '8': Appears in 08, 18, 28, 38, 48, 58. So, 6 * 24 = 144 times.\n * '9': Appears in 09, 19, 29, 39, 49, 59. So, 6 * 24 = 144 times.\n\n**Total Minute Digit Counts:**\n* '0': 240 (tens) + 144 (units) = **384**\n* '1': 240 (tens) + 144 (units) = **384**\n* '2': 240 (tens) + 144 (units) = **384**\n* '3': 240 (tens) + 144 (units) = **384**\n* '4': 240 (tens) + 144 (units) = **384**\n* '5': 240 (tens) + 144 (units) = **384**\n* '6': 0 (tens) + 144 (units) = **144**\n* '7': 0 (tens) + 144 (units) = **144**\n* '8': 0 (tens) + 144 (units) = **144**\n* '9': 0 (tens) + 144 (units) = **144**\n\nSum of minute digits: 6 * 384 + 4 * 144 = 2304 + 576 = 2880. This is correct for the minute digits.\n\n**Grand Total for Each Digit (Hour + Minute):**\n* **0:** 780 (hours) + 384 (minutes) = **1164**\n* **1:** 780 (hours) + 384 (minutes) = **1164**\n* **2:** 420 (hours) + 384 (minutes) = **804**\n* **3:** 180 (hours) + 384 (minutes) = **564**\n* **4:** 120 (hours) + 384 (minutes) = **504**\n* **5:** 120 (hours) + 384 (minutes) = **504**\n* **6:** 120 (hours) + 144 (minutes) = **264**\n* **7:** 120 (hours) + 144 (minutes) = **264**\n* **8:** 120 (hours) + 144 (minutes) = **264**\n* **9:** 120 (hours) + 144 (minutes) = **264**\n\nLet's check the sum of all digits: 2 * 1164 + 804 + 564 + 2 * 504 + 4 * 264 = 2328 + 804 + 564 + 1008 + 1056 = 5760. This matches the total number of digits.\n\n**Results:**\n\n* **Most Common Digit(s):** The digits **0** and **1** are the most common.\n * Count: **1164** each\n * Percentage: (1164 / 5760) * 100% = **20.21%**\n\n* **Rarest Digit(s):** The digits **6**, **7**, **8**, and **9** are the rarest.\n * Count: **264** each\n * Percentage: (264 / 5760) * 100% = **4.58%**\n\n**Summary:**\n\n* **Most Common Digits:** **0 and 1** (1164 occurrences each, 20.21% each)\n* **Rarest Digits:** **6, 7, 8, and 9** (264 occurrences each, 4.58% each)" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.06834504463032245 + } + ], + "usageMetadata": { + "promptTokenCount": 74, + "candidatesTokenCount": 6344, + "totalTokenCount": 6418, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 74 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 6344 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:32:39.914820Z", + "responseId": "l5fKaYTrN-WDheMPz5ifqQ0" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/frequencyPenaltyParam.json b/payloads/transforms/chat-completions_to_vertex-google/frequencyPenaltyParam.json new file mode 100644 index 00000000..03c0b579 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/frequencyPenaltyParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ok." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.046509161591529846 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:22.290406Z", + "responseId": "NpzKaebcEZrt29sP4MfvyQk" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/instructionsParam.json b/payloads/transforms/chat-completions_to_vertex-google/instructionsParam.json new file mode 100644 index 00000000..486a1272 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/instructionsParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "ok" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.06907737255096436 + } + ], + "usageMetadata": { + "promptTokenCount": 5, + "candidatesTokenCount": 1, + "totalTokenCount": 6, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 5 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 1 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:19.740336Z", + "responseId": "M5zKafCXLfaAheMPg4_z6Ac" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/logitBiasParam.json b/payloads/transforms/chat-completions_to_vertex-google/logitBiasParam.json new file mode 100644 index 00000000..62735d28 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/logitBiasParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Hello! How can I help you today?" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.05748928917778863 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 9, + "totalTokenCount": 12, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 9 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:27.511609Z", + "responseId": "O5zKafmcH5rt29sP4MfvyQk" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/logprobsParam.json b/payloads/transforms/chat-completions_to_vertex-google/logprobsParam.json new file mode 100644 index 00000000..d5576615 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/logprobsParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "2 + 2 = 4" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.07273911578314644 + } + ], + "usageMetadata": { + "promptTokenCount": 8, + "candidatesTokenCount": 7, + "totalTokenCount": 15, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:23.007344Z", + "responseId": "N5zKabA55YOF4w_PmJ-pDQ" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/maxCompletionTokensParam.json b/payloads/transforms/chat-completions_to_vertex-google/maxCompletionTokensParam.json new file mode 100644 index 00000000..5e6988b5 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/maxCompletionTokensParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ok." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.11952361464500427 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:24.177054Z", + "responseId": "OJzKaZ7nCr6yheMPoIWq0Qs" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/metadataParam.json b/payloads/transforms/chat-completions_to_vertex-google/metadataParam.json new file mode 100644 index 00000000..3faa430c --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/metadataParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ok." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.046509161591529846 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:21.061799Z", + "responseId": "NZzKaefiA8P_29sPi8C2yAk" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/nMultipleCompletionsParam.json b/payloads/transforms/chat-completions_to_vertex-google/nMultipleCompletionsParam.json new file mode 100644 index 00000000..a132b7b1 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/nMultipleCompletionsParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Hello." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.7975924015045166 + } + ], + "usageMetadata": { + "promptTokenCount": 4, + "candidatesTokenCount": 2, + "totalTokenCount": 6, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 4 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:23.492080Z", + "responseId": "N5zKabCEHvf-29sPhZmkwQM" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/parallelToolCallsDisabledParam.json b/payloads/transforms/chat-completions_to_vertex-google/parallelToolCallsDisabledParam.json new file mode 100644 index 00000000..e9d2782d --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/parallelToolCallsDisabledParam.json @@ -0,0 +1,50 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "functionCall": { + "name": "get_weather", + "args": { + "location": "NYC" + } + } + }, + { + "functionCall": { + "name": "get_weather", + "args": { + "location": "LA" + } + } + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.0014866354875266552 + } + ], + "usageMetadata": { + "promptTokenCount": 11, + "candidatesTokenCount": 10, + "totalTokenCount": 21, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 11 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 10 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:19.331572Z", + "responseId": "M5zKabSeFJrt29sP4MfvyQk" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/predictionParam.json b/payloads/transforms/chat-completions_to_vertex-google/predictionParam.json new file mode 100644 index 00000000..05ebcd8b --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/predictionParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "```javascript\n/**\n * Divides two numbers and handles potential errors.\n *\n * @param {number} a The dividend.\n * @param {number} b The divisor.\n * @returns {number | string} The result of the division, or an error message string if an error occurs.\n */\nfunction divide(a, b) {\n // 1. Check if inputs are valid numbers\n if (typeof a !== 'number' || typeof b !== 'number') {\n return \"Error: Both inputs must be numbers.\";\n }\n\n // 2. Check for division by zero\n if (b === 0) {\n return \"Error: Division by zero is not allowed.\";\n }\n\n // 3. Perform the division\n return a / b;\n}\n\n// --- Examples of usage ---\n\nconsole.log(divide(10, 2)); // Output: 5\nconsole.log(divide(15, 3)); // Output: 5\nconsole.log(divide(7, 0)); // Output: Error: Division by zero is not allowed.\nconsole.log(divide(10, 'abc')); // Output: Error: Both inputs must be numbers.\nconsole.log(divide('xyz', 5)); // Output: Error: Both inputs must be numbers.\nconsole.log(divide(10, undefined)); // Output: Error: Both inputs must be numbers.\nconsole.log(divide(null, 5)); // Output: Error: Both inputs must be numbers.\nconsole.log(divide(20, 4)); // Output: 5\n```\n\n**Explanation of Error Handling:**\n\n1. **Type Checking:**\n * `if (typeof a !== 'number' || typeof b !== 'number')`: This checks if either `a` or `b` is not of the `number` data type. If they are not, it returns a specific error message. This prevents issues like trying to divide a string by a number or vice-versa, which would result in `NaN` or other unexpected behavior.\n\n2. **Division by Zero:**\n * `if (b === 0)`: This is the most crucial error to handle in division. Dividing by zero is mathematically undefined and would result in `Infinity` or `-Infinity` in JavaScript, which might not be the desired outcome. This check ensures that we explicitly catch this case and return a clear error message.\n\n3. **Returning Error Messages:**\n * Instead of throwing actual JavaScript `Error` objects (which is also a valid approach for more complex applications), this updated function returns descriptive **string messages** when an error occurs. This makes it easy to check the return value and display the appropriate message to the user.\n\n**Alternative (Throwing Errors):**\n\nFor more robust error handling in larger applications, you might prefer to `throw` actual `Error` objects. This allows for more structured error management using `try...catch` blocks.\n\n```javascript\nfunction divideWithErrorThrow(a, b) {\n if (typeof a !== 'number' || typeof b !== 'number') {\n throw new Error(\"Both inputs must be numbers.\");\n }\n\n if (b === 0) {\n throw new Error(\"Division by zero is not allowed.\");\n }\n\n return a / b;\n}\n\n// Example of using try...catch\ntry {\n console.log(divideWithErrorThrow(10, 2)); // Output: 5\n console.log(divideWithErrorThrow(7, 0)); // This line will throw an error\n} catch (error) {\n console.error(error.message); // Output: Division by zero is not allowed.\n}\n\ntry {\n console.log(divideWithErrorThrow(10, 'abc')); // This line will throw an error\n} catch (error) {\n console.error(error.message); // Output: Both inputs must be numbers.\n}\n```\n\nThe choice between returning error strings or throwing errors depends on the context and how you intend to handle errors in your application. For a simple function, returning strings is often sufficient and easier to read." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.11710622854400099 + } + ], + "usageMetadata": { + "promptTokenCount": 26, + "candidatesTokenCount": 912, + "totalTokenCount": 938, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 26 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 912 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:24.502569Z", + "responseId": "OJzKaanWHtWrheMPh_zuqQ0" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/presencePenaltyParam.json b/payloads/transforms/chat-completions_to_vertex-google/presencePenaltyParam.json new file mode 100644 index 00000000..1b5eee7d --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/presencePenaltyParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ok." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.11952361464500427 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:22.624379Z", + "responseId": "NpzKafuNJqmzheMPiLOJ0Qo" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/promptCacheKeyParam.json b/payloads/transforms/chat-completions_to_vertex-google/promptCacheKeyParam.json new file mode 100644 index 00000000..838c2ef2 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/promptCacheKeyParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ok." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.046509161591529846 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:20.747291Z", + "responseId": "NJzKaZvOLcKdheMP1cvT4QQ" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/reasoningEffortLowParam.json b/payloads/transforms/chat-completions_to_vertex-google/reasoningEffortLowParam.json new file mode 100644 index 00000000..cac39e05 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/reasoningEffortLowParam.json @@ -0,0 +1,42 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ah, so the core of this inquiry, as I perceive it, is a straightforward request for the summation of two numerical entities. My immediate mental process is to identify this as a fundamental arithmetic operation, specifically addition. With that recognized, I then execute the calculation: two plus two. The result, unequivocally, is four. Therefore, my conclusion is to present this numerical outcome with the utmost clarity and conciseness.", + "thought": true + }, + { + "text": "2 + 2 = 4" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.8170896938868931 + } + ], + "usageMetadata": { + "promptTokenCount": 7, + "candidatesTokenCount": 7, + "totalTokenCount": 86, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ], + "thoughtsTokenCount": 72 + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:14.312438Z", + "responseId": "LpzKafaIE9WrheMPh_zuqQ0" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/reasoningRequest.json b/payloads/transforms/chat-completions_to_vertex-google/reasoningRequest.json new file mode 100644 index 00000000..3bdd9849 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/reasoningRequest.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Here's how to solve this problem step-by-step:\n\n**1. Understand the Goal:**\nWe need to find the *average speed* of the train. Average speed is calculated as:\n\nAverage Speed = Total Distance / Total Time\n\n**2. Calculate the Distance for the First Part of the Journey:**\n* **Formula:** Distance = Speed × Time\n* **Speed:** 60 mph\n* **Time:** 2 hours\n* **Calculation:** 60 mph × 2 hours = 120 miles\n\n**3. Calculate the Distance for the Second Part of the Journey:**\n* **Formula:** Distance = Speed × Time\n* **Speed:** 80 mph\n* **Time:** 1 hour\n* **Calculation:** 80 mph × 1 hour = 80 miles\n\n**4. Calculate the Total Distance Traveled:**\n* **Add the distances from both parts of the journey:**\n* **Calculation:** 120 miles + 80 miles = 200 miles\n\n**5. Calculate the Total Time of the Journey:**\n* **Add the times from both parts of the journey:**\n* **Calculation:** 2 hours + 1 hour = 3 hours\n\n**6. Calculate the Average Speed:**\n* **Use the average speed formula:** Average Speed = Total Distance / Total Time\n* **Total Distance:** 200 miles\n* **Total Time:** 3 hours\n* **Calculation:** 200 miles / 3 hours = 66.67 mph (approximately)\n\n**Answer:** The average speed of the train is approximately **66.67 mph**." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.05087701092476831 + } + ], + "usageMetadata": { + "promptTokenCount": 36, + "candidatesTokenCount": 349, + "totalTokenCount": 385, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 36 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 349 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:32:37.224949Z", + "responseId": "lZfKabXdDYmdheMP8OzF6Qk" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/reasoningRequestTruncated.json b/payloads/transforms/chat-completions_to_vertex-google/reasoningRequestTruncated.json new file mode 100644 index 00000000..645d427f --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/reasoningRequestTruncated.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Here's how to solve this problem step-by-step:\n\n**1. Calculate the distance traveled in the first part of the journey:**\n\n* **Formula:** Distance = Speed × Time\n* **Speed:** 60 mph\n* **Time:** 2 hours\n* **Calculation:** Distance1 = 60 mph × 2 hours = 120 miles\n\n**2. Calculate the distance traveled in the second part of the journey:**\n\n* **Formula:**" + } + ] + }, + "finishReason": "MAX_TOKENS", + "avgLogprobs": -0.04633222103118897 + } + ], + "usageMetadata": { + "promptTokenCount": 36, + "candidatesTokenCount": 100, + "totalTokenCount": 136, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 36 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 100 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:32:38.533416Z", + "responseId": "lpfKaajHIOTZ29sP5fjDsAY" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/reasoningSummaryParam.json b/payloads/transforms/chat-completions_to_vertex-google/reasoningSummaryParam.json new file mode 100644 index 00000000..c436f9a3 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/reasoningSummaryParam.json @@ -0,0 +1,42 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "My immediate thought process, upon encountering the user's request, was to pinpoint the essential task at hand. It was quite straightforward: to ascertain the outcome of the arithmetic expression \"2 + 2.\"\n\nHaving identified this core objective, the next logical step was to execute the calculation itself. This is a fundamental operation, and the result is immediately apparent: 2 plus 2 unequivocally equals 4.\n\nFinally, the last stage involved synthesizing this outcome into a clear and direct response, ensuring the answer is presented without ambiguity.", + "thought": true + }, + { + "text": "2 + 2 = 4." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -1.5069457292556763 + } + ], + "usageMetadata": { + "promptTokenCount": 7, + "candidatesTokenCount": 8, + "totalTokenCount": 73, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "thoughtsTokenCount": 58 + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:13.175828Z", + "responseId": "LZzKadTdCr6yheMPoIWq0Qs" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/reasoningWithOutput.json b/payloads/transforms/chat-completions_to_vertex-google/reasoningWithOutput.json new file mode 100644 index 00000000..f7ac6f47 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/reasoningWithOutput.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "The sky is **blue** on a clear day.\n\nHowever, its color can change depending on several factors:\n\n* **Time of day:** During sunrise and sunset, the sky can appear red, orange, pink, and purple due to the way sunlight scatters through the atmosphere.\n* **Weather conditions:** Clouds can make the sky appear white, gray, or even dark and stormy.\n* **Atmospheric particles:** Smoke, dust, or pollution can tint the sky with different hues.\n\nBut in its most common and iconic appearance, it's blue!" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.2678120877562451 + } + ], + "usageMetadata": { + "promptTokenCount": 6, + "candidatesTokenCount": 119, + "totalTokenCount": 125, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 6 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 119 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:32:55.627525Z", + "responseId": "p5fKacWmJv3-29sPnaKJqQY" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/safetyIdentifierParam.json b/payloads/transforms/chat-completions_to_vertex-google/safetyIdentifierParam.json new file mode 100644 index 00000000..64d95f13 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/safetyIdentifierParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ok." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.046509161591529846 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:21.374558Z", + "responseId": "NZzKaZ7uFomdheMP8OzF6Qk" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/seedParam.json b/payloads/transforms/chat-completions_to_vertex-google/seedParam.json new file mode 100644 index 00000000..4f5cf244 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/seedParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "I'll pick **7**." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.7032333101545062 + } + ], + "usageMetadata": { + "promptTokenCount": 4, + "candidatesTokenCount": 7, + "totalTokenCount": 11, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 4 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:27.271306Z", + "responseId": "O5zKacrHEPaAheMPg4_z6Ac" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/serviceTierParam.json b/payloads/transforms/chat-completions_to_vertex-google/serviceTierParam.json new file mode 100644 index 00000000..3a6d0a1c --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/serviceTierParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ok." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.046509161591529846 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:20.345087Z", + "responseId": "NJzKaf-HFcCzheMP5Lq_kQk" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/simpleRequest.json b/payloads/transforms/chat-completions_to_vertex-google/simpleRequest.json new file mode 100644 index 00000000..ea8f4432 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/simpleRequest.json @@ -0,0 +1,42 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Okay, so I'm presented with a query. My primary objective, as I see it, is to immediately isolate the fundamental question being posed. In this instance, it's quite straightforward: \"What is the capital of France?\"\n\nOnce I've clearly identified this core inquiry, my next step is to access my internal knowledge base. I need to retrieve the relevant piece of information that directly answers this question. Fortunately, this is a well-established and readily available datum: Paris is indeed the capital of France.\n\nWith the factual answer in hand, my task then shifts to constructing a response. This response needs to be unambiguous and directly address the user's prompt. Therefore, a clear and direct statement of the fact is the most efficient and effective approach.\n\nFinally, before presenting the answer, I perform a quick internal review. I ask myself: Is the information I'm about to provide accurate? In this case, unequivocally yes. And is the answer concise and to the point, avoiding any unnecessary verbosity? Again, yes. This ensures I've met the user's need with precision and efficiency.", + "thought": true + }, + { + "text": "The capital of France is **Paris**." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -2.2697744369506836 + } + ], + "usageMetadata": { + "promptTokenCount": 7, + "candidatesTokenCount": 8, + "totalTokenCount": 86, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "thoughtsTokenCount": 71 + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:32:35.600403Z", + "responseId": "k5fKadPSJMP_29sPi8C2yAk" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/stopSequencesParam.json b/payloads/transforms/chat-completions_to_vertex-google/stopSequencesParam.json new file mode 100644 index 00000000..5e321eed --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/stopSequencesParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Here's the count from 1 to 20:\n\n1\n2\n3\n4\n5\n6\n7\n8\n9\n" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.042997512966394424 + } + ], + "usageMetadata": { + "promptTokenCount": 9, + "candidatesTokenCount": 32, + "totalTokenCount": 41, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 9 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 32 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:23.871567Z", + "responseId": "N5zKaY-ZNf3-29sPnaKJqQY" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/storeDisabledParam.json b/payloads/transforms/chat-completions_to_vertex-google/storeDisabledParam.json new file mode 100644 index 00000000..6ad30dfb --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/storeDisabledParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ok." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.046509161591529846 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:20.015845Z", + "responseId": "NJzKaeV7yLOF4w_Qj5zpAQ" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/systemMessageArrayContent.json b/payloads/transforms/chat-completions_to_vertex-google/systemMessageArrayContent.json new file mode 100644 index 00000000..5cc2a9e6 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/systemMessageArrayContent.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "I can't provide specific error details without knowing what constitutes \"recently.\" Please specify a time frame (e.g., \"in the last hour,\" \"yesterday,\" \"this morning\") for me to query the project logs." + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.4081573080509267 + } + ], + "usageMetadata": { + "promptTokenCount": 28, + "candidatesTokenCount": 47, + "totalTokenCount": 75, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 28 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 47 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:32:56.586903Z", + "responseId": "qJfKaZfpI67229sP-ICEiQY" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/temperatureParam.json b/payloads/transforms/chat-completions_to_vertex-google/temperatureParam.json new file mode 100644 index 00000000..b77774ef --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/temperatureParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Hi!" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.2152658998966217 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 2, + "totalTokenCount": 5, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 2 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:21.691323Z", + "responseId": "NZzKafuYKq7229sP-ICEiQY" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonObjectParam.json b/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonObjectParam.json new file mode 100644 index 00000000..9ee6998e --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonObjectParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\"status\": \"ok\"}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.00005933811674670627 + } + ], + "usageMetadata": { + "promptTokenCount": 10, + "candidatesTokenCount": 6, + "totalTokenCount": 16, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 10 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 6 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:15.757322Z", + "responseId": "L5zKacqcLqmzheMPiLOJ0Qo" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonSchemaParam.json b/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonSchemaParam.json new file mode 100644 index 00000000..a4f7b7dd --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonSchemaParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\n \"name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.0010230096155091335 + } + ], + "usageMetadata": { + "promptTokenCount": 8, + "candidatesTokenCount": 19, + "totalTokenCount": 27, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:16.107989Z", + "responseId": "MJzKadXLBvf-29sPhZmkwQM" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonSchemaWithDescriptionParam.json b/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonSchemaWithDescriptionParam.json new file mode 100644 index 00000000..4e2f9807 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/textFormatJsonSchemaWithDescriptionParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "{\n \"name\": \"John\",\n \"age\": 25\n}" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.0017420582865413866 + } + ], + "usageMetadata": { + "promptTokenCount": 8, + "candidatesTokenCount": 19, + "totalTokenCount": 27, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 19 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:16.560578Z", + "responseId": "MJzKacKbIuWDheMPz5ifqQ0" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/textFormatTextParam.json b/payloads/transforms/chat-completions_to_vertex-google/textFormatTextParam.json new file mode 100644 index 00000000..586fa3b4 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/textFormatTextParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Hello! How can I help you today?" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.05475230349434747 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 9, + "totalTokenCount": 12, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 9 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:16.922158Z", + "responseId": "MJzKaa6kOP3-29sPnaKJqQY" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/toolCallRequest.json b/payloads/transforms/chat-completions_to_vertex-google/toolCallRequest.json new file mode 100644 index 00000000..e2cb1470 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/toolCallRequest.json @@ -0,0 +1,42 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "functionCall": { + "name": "get_weather", + "args": { + "location": "San Francisco, CA" + } + } + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.021860778331756592 + } + ], + "usageMetadata": { + "promptTokenCount": 20, + "candidatesTokenCount": 8, + "totalTokenCount": 28, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 20 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 8 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:32:39.344114Z", + "responseId": "l5fKabKAFb6yheMPoIWq0Qs" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/toolChoiceRequiredParam.json b/payloads/transforms/chat-completions_to_vertex-google/toolChoiceRequiredParam.json new file mode 100644 index 00000000..96705df4 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/toolChoiceRequiredParam.json @@ -0,0 +1,42 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "functionCall": { + "name": "get_weather", + "args": { + "location": "Tokyo" + } + } + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.0011209084652364254 + } + ], + "usageMetadata": { + "promptTokenCount": 7, + "candidatesTokenCount": 5, + "totalTokenCount": 12, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 5 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:17.330296Z", + "responseId": "MZzKabiUFPaAheMPg4_z6Ac" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/toolChoiceRequiredWithReasoningParam.json b/payloads/transforms/chat-completions_to_vertex-google/toolChoiceRequiredWithReasoningParam.json new file mode 100644 index 00000000..e5a00170 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/toolChoiceRequiredWithReasoningParam.json @@ -0,0 +1,48 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Ah, I see the user's request. They're looking for weather information, specifically for Tokyo. My internal knowledge base immediately points me to the `get_weather` tool – that's precisely what it's designed for. Now, I just need to provide it with the necessary details. The `get_weather` tool has a clear `location` parameter, and in this case, the location is unequivocally \"Tokyo.\" So, the logical next step is to construct the tool call as `get_weather(location=\"Tokyo\")`. This should effectively retrieve the weather data the user is asking for.", + "thought": true + }, + { + "functionCall": { + "name": "get_weather", + "args": { + "location": "Tokyo" + } + }, + "thoughtSignature": "CowCAY89a1+8JoG3SS9WbPICZeypCySEKZQ5KQA0MqGKtrAGLr6i1swQz4PkeIhWM5edM9VsRpUroSVtcPFctI+msSPeVdzhF5egmaIhdyVtyQZ/Wf3lef+DmkdiXGDY6R0bPMozgbqeg4sx/gAj4TKzN/lAW9XVt6xVFfHRKrL978osWdgWqLKrPsV7q+6dwoLof/JRROr0K/Pt3qOfFYIzupoHNcbWoPXR6iCX8MTfQpf5h1osi2N/J5UM4AAN1byIjG/FtCsEjXKnEBgK2bFs/A2L6p+z410/4r0Use0R0TnTMIMzgAEss5tgT/x+ZtA9rVsyXbrlNjX/N/+nZd28mL6vJWAhr+bOZHULew==" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.9516056060791016 + } + ], + "usageMetadata": { + "promptTokenCount": 7, + "candidatesTokenCount": 5, + "totalTokenCount": 70, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 7 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 5 + } + ], + "thoughtsTokenCount": 58 + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:17.798281Z", + "responseId": "MZzKacncMMizheMP0I-c6QE" +} \ No newline at end of file diff --git a/payloads/transforms/chat-completions_to_vertex-google/topPParam.json b/payloads/transforms/chat-completions_to_vertex-google/topPParam.json new file mode 100644 index 00000000..a9ae0cf1 --- /dev/null +++ b/payloads/transforms/chat-completions_to_vertex-google/topPParam.json @@ -0,0 +1,37 @@ +{ + "candidates": [ + { + "content": { + "role": "model", + "parts": [ + { + "text": "Hi there!" + } + ] + }, + "finishReason": "STOP", + "avgLogprobs": -0.357339342435201 + } + ], + "usageMetadata": { + "promptTokenCount": 3, + "candidatesTokenCount": 3, + "totalTokenCount": 6, + "trafficType": "ON_DEMAND_PRIORITY", + "promptTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ], + "candidatesTokensDetails": [ + { + "modality": "TEXT", + "tokenCount": 3 + } + ] + }, + "modelVersion": "gemini-2.5-flash-lite", + "createTime": "2026-03-30T15:52:21.993886Z", + "responseId": "NZzKad7UPOTZ29sP5fjDsAY" +} \ No newline at end of file