Journalism AI - v3.0.7
    Preparing search index...

    Function askGeminiPool

    • Processes multiple Gemini requests concurrently using a pool of workers. This function wraps askGemini and manages parallel execution, retries, progress logging, and error handling for batch operations.

      Each request in the array is processed by a worker from the pool. The pool size controls how many requests run simultaneously. Results and errors are returned separately, sorted by their original index, making it easy to match outputs back to inputs.

      Caching: model calls can be slow and costly, so original responses are cached in .journalism-cache by default. processResponse reruns on every call, including cache hits, and its output is never cached. Keep it lightweight and optimize heavier processing, especially for large workloads. Set options.cache: false on each request to disable its cache.

      Type Parameters

      • TResponse = unknown

      Parameters

      • requests: {
            id?: string;
            options?: Omit<
                {
                    apiKey?: string;
                    cache?: boolean;
                    files?: {
                        path: string;
                        type: "image"
                        | "video"
                        | "audio"
                        | "pdf"
                        | "text";
                    }[];
                    geminiParameters?: Partial<GenerateContentParameters>;
                    location?: string;
                    model?: string;
                    processResponse?: (response: unknown) => TResponse | Promise<TResponse>;
                    project?: string;
                    safetyEnabled?: boolean;
                    schemaJson?: unknown;
                    systemPrompt?: string;
                    temperature?: number;
                    thinkingBudget?: number;
                    thinkingLevel?: "minimal" | "low" | "medium" | "high";
                    vertex?: boolean;
                    webSearch?: boolean;
                },
                "processResponse",
            >;
            processResponse?: (response: unknown) => TResponse | Promise<TResponse>;
            prompt: string;
        }[]

        An array of request objects to process.

        • Optionalid?: string

          Optional identifier retained with the result.

        • Optionaloptions?: Omit<
              {
                  apiKey?: string;
                  cache?: boolean;
                  files?: {
                      path: string;
                      type: "image"
                      | "video"
                      | "audio"
                      | "pdf"
                      | "text";
                  }[];
                  geminiParameters?: Partial<GenerateContentParameters>;
                  location?: string;
                  model?: string;
                  processResponse?: (response: unknown) => TResponse | Promise<TResponse>;
                  project?: string;
                  safetyEnabled?: boolean;
                  schemaJson?: unknown;
                  systemPrompt?: string;
                  temperature?: number;
                  thinkingBudget?: number;
                  thinkingLevel?: "minimal" | "low" | "medium" | "high";
                  vertex?: boolean;
                  webSearch?: boolean;
              },
              "processResponse",
          >

          Provider options, with caching enabled by default.

        • OptionalprocessResponse?: (response: unknown) => TResponse | Promise<TResponse>

          Transform or validate inside the retry loop, including on cache hits. The output is never cached; failures follow the retry policy.

        • prompt: string

          Primary text input for Gemini.

      • poolSize: number

        The number of concurrent workers processing requests.

      • poolOptions: {
            logProgress?: boolean;
            minRequestDurationMs?: number;
            retry?: number;
            retryCheck?: (error: unknown) => boolean | Promise<boolean>;
        } = {}

        Configuration for the pool execution.

        • OptionallogProgress?: boolean

          If true, logs progress to the console after each completed or failed request. Defaults to false.

        • OptionalminRequestDurationMs?: number

          A minimum duration in milliseconds for each request. If a request completes faster, the worker will wait before picking up the next one. Useful for rate limiting.

        • Optionalretry?: number

          The maximum number of retry attempts for a failed request. Defaults to 0 (no retries).

        • OptionalretryCheck?: (error: unknown) => boolean | Promise<boolean>

          A function that receives the error and returns whether the request should be retried. If not provided, all failed requests are retried up to the retry limit.

      Returns Promise<
          {
              errors: {
                  error: unknown;
                  index: number;
                  request: {
                      id?: string;
                      options?: Omit<
                          {
                              apiKey?: string;
                              cache?: boolean;
                              files?: { path: ...; type: ... }[];
                              geminiParameters?: Partial<GenerateContentParameters>;
                              location?: string;
                              model?: string;
                              processResponse?: (response: unknown) => (...) | (...);
                              project?: string;
                              safetyEnabled?: boolean;
                              schemaJson?: unknown;
                              systemPrompt?: string;
                              temperature?: number;
                              thinkingBudget?: number;
                              thinkingLevel?: "minimal" | "low" | "medium" | "high";
                              vertex?: boolean;
                              webSearch?: boolean;
                          },
                          "processResponse",
                      >;
                      processResponse?: (response: unknown) => TResponse | Promise<TResponse>;
                      prompt: string;
                  };
              }[];
              results: {
                  index: number;
                  request: {
                      id?: string;
                      options?: Omit<
                          {
                              apiKey?: string;
                              cache?: boolean;
                              files?: { path: ...; type: ... }[];
                              geminiParameters?: Partial<GenerateContentParameters>;
                              location?: string;
                              model?: string;
                              processResponse?: (response: unknown) => (...) | (...);
                              project?: string;
                              safetyEnabled?: boolean;
                              schemaJson?: unknown;
                              systemPrompt?: string;
                              temperature?: number;
                              thinkingBudget?: number;
                              thinkingLevel?: "minimal" | "low" | "medium" | "high";
                              vertex?: boolean;
                              webSearch?: boolean;
                          },
                          "processResponse",
                      >;
                      processResponse?: (response: unknown) => TResponse | Promise<TResponse>;
                      prompt: string;
                  };
                  result: {
                      durationMs: number;
                      estimatedCost: number
                      | null;
                      files: {
                          path: string;
                          type: "image" | "video" | "audio" | "pdf" | "text";
                      }[];
                      fromCache: boolean;
                      model: string;
                      outputTokenCount: number;
                      prompt: string;
                      promptTokenCount: number;
                      response: TResponse;
                      safetyEnabled: boolean;
                      systemPrompt: string
                      | null;
                      thinkingLevel: "minimal" | "low" | "medium" | "high" | null;
                      thoughts: string | null;
                      thoughtsTokenCount: number;
                      tokensPerSecond: number | null;
                      totalTokens: number;
                      webSearch: boolean;
                  };
              }[];
          },
      >

      A Promise that resolves to an object with results (successful responses with their index and request) and errors (failed requests with their index, request, and error), both sorted by original index.

      // Basic usage: Process a batch of prompts with a pool of 5 concurrent workers.
      const { results, errors } = await askGeminiPool(
      [
      { prompt: "What is the capital of France?" },
      { prompt: "What is the capital of Germany?" },
      { prompt: "What is the capital of Italy?" },
      ],
      5,
      );
      for (const r of results) {
      console.log(r.result.response);
      }
      // Use an id to easily identify each request in the results.
      const { results, errors } = await askGeminiPool(
      [
      { id: "france", prompt: "What is the capital of France?" },
      { id: "germany", prompt: "What is the capital of Germany?" },
      ],
      2,
      );
      for (const r of results) {
      console.log(r.request.id, r.result.response);
      }
      // Enable progress logging and retries.
      const { results, errors } = await askGeminiPool(
      [
      { prompt: "Summarize this article.", options: { files: [{ path: "./article1.txt", type: "text" }], schemaJson: schema } },
      { prompt: "Summarize this article.", options: { files: [{ path: "./article2.txt", type: "text" }], schemaJson: schema } },
      ],
      3,
      {
      logProgress: true,
      retry: 2,
      },
      );
      console.log(`${results.length} succeeded, ${errors.length} failed`);
      // Use retryCheck to only retry on specific errors.
      const { results, errors } = await askGeminiPool(
      [
      { prompt: "Analyze this image.", options: { files: [{ path: "./photo.jpg", type: "image" }], schemaJson: schema } },
      ],
      1,
      {
      retry: 3,
      retryCheck: (error) => {
      // Only retry on rate limit errors
      return error instanceof Error && error.message.includes("429");
      },
      },
      );
      // Use schemaJson to enforce structured output with a specific schema.
      import * as z from "zod";

      const schema = z.toJSONSchema(
      z.object({
      people: z.array(z.object({
      name: z.string(),
      age: z.number(),
      gender: z.enum(["man", "woman"]),
      })),
      }),
      );

      const { results, errors } = await askGeminiPool(
      [
      { prompt: "Give me 5 characters from Harry Potter.", options: { schemaJson: schema } },
      { prompt: "Give me 5 characters from Lord of the Rings.", options: { schemaJson: schema } },
      ],
      2,
      );
      // Each result.response will conform to the specified schema
      for (const r of results) {
      console.log(r.result.response); // { people: [{ name: "...", age: ..., gender: "..." }, ...] }
      }