Skip to content

GeminiFileSearchStores

GeminiFileSearchStores provides CRUD operations for Gemini File Search Stores and executes semantic search queries using the model's built-in fileSearch tool. It combines direct REST API calls for store and document management with SDK-based content generation for search.

File Search Stores are Gemini's managed vector store solution -- you upload documents and the API automatically chunks, indexes, and enables semantic retrieval without external infrastructure.

Import

import { GeminiClient } from "@modernpath/agent-framework";

const client = new GeminiClient({ apiKey: process.env.GEMINI_API_KEY! });
const stores = client.fileSearchStores();

GeminiFileSearchStores is accessed via GeminiClient.fileSearchStores() rather than imported directly.

Methods

Store Management

create()

Create a new File Search Store.

async create(displayName: string): Promise<FileSearchStoreSummary>

Example

const store = await stores.create("hvac-knowledge-base");
console.log(store.name); // "fileSearchStores/abc123"

list()

List all File Search Stores. Returns an empty array on failure (graceful degradation).

async list(): Promise<FileSearchStoreSummary[]>

get()

Get a single store by name.

async get(name: string): Promise<FileSearchStoreSummary>

Accepts both short names ("abc123") and fully-qualified names ("fileSearchStores/abc123").


delete()

Delete a File Search Store.

async delete(name: string, force?: boolean): Promise<void>
Parameter Type Default Description
name string required Store name (short or fully-qualified).
force boolean false When true, deletes the store even if it contains documents.

Document Management

uploadToStore()

Upload a document to a File Search Store. Supports both SDK and REST multipart upload paths.

async uploadToStore(
  file: Buffer | string,
  fileSearchStoreName: string,
  config?: {
    displayName?: string;
    mimeType?: string;
    customMetadata?: Array<{ key: string; string_value?: string; numeric_value?: number }>;
  },
): Promise<FileSearchUploadResult>
Parameter Type Description
file Buffer \| string File content as a Buffer, or a file path string.
fileSearchStoreName string Target store name (short or fully-qualified).
config.displayName string Document display name in the store.
config.mimeType string MIME type (auto-detected from file extension if omitted).
config.customMetadata Array<{...}> Key-value metadata for filtering and canonical document resolution.

Uploading with metadata

const result = await stores.uploadToStore(
  readFileSync("./sop-cold-complaint.pdf"),
  "fileSearchStores/abc123",
  {
    displayName: "cold-complaint-sop.pdf",
    mimeType: "application/pdf",
    customMetadata: [
      { key: "source_type", string_value: "s3" },
      { key: "s3_bucket", string_value: "my-bucket" },
      { key: "s3_key", string_value: "sops/cold-complaint.pdf" },
    ],
  },
);
console.log(result.name); // document resource name
console.log(result.done); // true if processing complete

Upload operations

Large document uploads return with done: false. Use waitForUpload() to poll until the document is indexed and searchable.


waitForUpload()

Poll an upload operation until it completes.

async waitForUpload(
  operationName: string | any,
  options?: {
    timeoutMs?: number;       // default: 120000 (2 min)
    initialIntervalMs?: number; // default: 2000
    maxIntervalMs?: number;     // default: 15000
  },
): Promise<{ done: boolean; response?: any; error?: any }>

listDocuments()

List documents in a store with pagination support.

async listDocuments(
  storeName: string,
  options?: { pageSize?: number; pageToken?: string },
): Promise<FileSearchDocumentListResult>

Note

The Gemini API limits pageSize to 20. For stores with more documents, iterate using nextPageToken.


getDocument()

Get metadata for a single document, including customMetadata.

async getDocument(
  storeName: string,
  documentNameOrId: string,
): Promise<FileSearchDocument>

Accepts document identifiers in several forms:

  • Full path: "fileSearchStores/.../documents/..."
  • Store-relative: "documents/xyz"
  • Raw ID: "xyz"

deleteDocument()

Delete a document from a store.

async deleteDocument(
  storeName: string,
  documentName: string,
  force?: boolean,
): Promise<void>

search()

Execute a semantic search query against one or more File Search Stores using Gemini's built-in fileSearch tool.

async search(
  query: string,
  fileSearchStoreNames: string[],
  options?: {
    metadataFilter?: string;
    topK?: number;
    systemInstruction?: string;
    maxOutputTokens?: number;
  },
): Promise<FileSearchQueryResult>
Parameter Type Default Description
query string required Natural language search query.
fileSearchStoreNames string[] required One or more store names to search across.
options.metadataFilter string -- Metadata filter expression for scoping results.
options.topK number -- Maximum number of retrieval chunks.
options.systemInstruction string -- System instruction for the search LLM call.
options.maxOutputTokens number 2048 Max tokens for the synthesized answer.

Returns: FileSearchQueryResult with a synthesized text answer and raw groundingMetadata containing source chunks, document names, and relevance scores.

Semantic search

const result = await stores.search(
  "How should I handle a cold complaint in winter?",
  ["fileSearchStores/hvac-kb"],
  { topK: 5 },
);

console.log(result.text); // Synthesized answer
console.log(result.groundingMetadata?.groundingChunks); // Source chunks

RECITATION errors

If the model's response too closely matches copyrighted source material, the API returns a RECITATION error. The client wraps this with a user-friendly message suggesting the query be rephrased to ask for summaries rather than verbatim quotes.

Types

FileSearchStoreSummary

interface FileSearchStoreSummary {
  name: string;                  // e.g. "fileSearchStores/abc123"
  displayName?: string;          // Human-readable name
  activeDocumentsCount?: number; // Number of indexed documents
  sizeBytes?: number;            // Total store size
  createTime?: string;           // ISO timestamp
  updateTime?: string;           // ISO timestamp
}

FileSearchUploadResult

interface FileSearchUploadResult {
  name: string;      // Document resource name
  done: boolean;     // Whether processing is complete
  operation?: any;   // Raw operation object for polling
}

FileSearchQueryResult

interface FileSearchQueryResult {
  text: string;              // Synthesized answer text
  groundingMetadata?: any;   // Raw grounding metadata with source chunks
}

FileSearchDocument

interface FileSearchDocument {
  name: string;
  displayName?: string;
  mimeType?: string;
  sizeBytes?: number;
  state?: string;           // e.g. "ACTIVE", "PROCESSING"
  createTime?: string;
  updateTime?: string;
  customMetadata?: Array<{
    key: string;
    stringValue?: string;
    numericValue?: number;
  }>;
}

Debug Logging

Enable with:

DEBUG=file-search-stores node app.js