@squidcloud/client
Version:
A typescript implementation of the Squid client
572 lines (571 loc) • 24 kB
TypeScript
import { AgentContextRequest, AiChatModelSelection, UpsertContextStatusError } from './ai-agent.public-types';
import { AiEmbeddingsModelSelection, AiRerankProvider } from './ai-common.public-types';
import { AiContextId, AiKnowledgeBaseId, AppId } from './communication.public-types';
import { DocumentExtractionMethod } from './extraction.public-types';
import { MetadataAndFilter, MetadataFieldFilter, MetadataFilter, MetadataOrFilter, MetadataSimpleFilter, MetadataValue, MetadataValueArray } from './metadata-filter.public-types';
/**
* The set of supported vector store backends for a knowledge base. The authoritative backend for a
* given KB is persisted on its record; reads/writes route through the matching vector provider.
* @category AI
*/
export declare const VECTOR_DB_TYPES: readonly ["postgres", "mongoAtlas"];
/**
* A vector store backend identifier. See {@link VECTOR_DB_TYPES}.
* @category AI
*/
export type VectorDbType = (typeof VECTOR_DB_TYPES)[number];
/**
* Represents an AI knowledge base that can be attached to an AI agent.
* @category AI
*/
export interface AiKnowledgeBase {
/** The unique identifier of the knowledge base.*/
id: AiKnowledgeBaseId;
/** The app id that the knowledge base belongs to. */
appId: AppId;
/** The user's description of the knowledge base */
description: string;
/** A set of predefined metadata fields for the knowledge base that can be used for filtering.*/
metadataFields: Array<AiKnowledgeBaseMetadataField>;
/** The embedding model that should be used for this knowledge base.*/
embeddingModel: AiEmbeddingsModelSelection;
/** The model name that should be used when asking questions of this knowledge base. */
chatModel: AiChatModelSelection;
/**
* The vector store backend this knowledge base reads/writes from. Set at creation (defaulting to
* the server's `SQUID_DEFAULT_VECTOR_DB_TYPE`, otherwise `'postgres'`) and immutable thereafter.
* Optional on the read type for backwards compatibility with older records.
*/
vectorDbType?: VectorDbType;
/** The timestamp the knowledge base was last updated */
updatedAt: Date;
}
/**
* Represents a field in an AI knowledge base metadata.
*/
export interface AiKnowledgeBaseMetadataField {
/** The name of field.*/
name: string;
/**
* The field data type - used for validation and filtering. `date` values are normalized to integer
* epoch milliseconds at write time so range filters (`$gt`/`$lt`) work across vector store backends.
* `array` is not yet supported and is rejected at knowledge-base upsert time.
*/
dataType: 'string' | 'number' | 'boolean' | 'date' | 'array';
/** Indicates if the field is required for knowledge base entries.*/
required: boolean;
/**
* In case that the field is required and not provided when uploaded to the knowledge base,
* this description will be used for extracting the value from the document.
* Also, it will be used for auto filtering when a prompt is sent to an AI agent.
*/
description?: string;
/**
* True when {@link description} was AI-generated (via `generateMetadataFieldDescriptions`). Undefined or
* false means the description was authored by a human or has not been generated yet; it clears back to
* false once a human edits the description.
*/
descriptionGeneratedByAi?: boolean;
}
/**
* A record of metadata key-value pairs for AI context, where values are primitive types or undefined.
* @category AI
*/
export type AiContextMetadata = Record<string, AiContextMetadataValue>;
/**
* @category AI
* @deprecated Use {@link MetadataValue} from `metadata-filter.public-types` instead.
*/
export type AiContextMetadataValue = MetadataValue;
/**
* @category AI
* @deprecated Use {@link MetadataValueArray} from `metadata-filter.public-types` instead.
*/
export type AiContextMetadataValueArray = MetadataValueArray;
/**
* @category AI
* @deprecated Use {@link MetadataSimpleFilter} from `metadata-filter.public-types` instead.
*/
export type AiContextMetadataSimpleFilter = MetadataSimpleFilter;
/**
* A filter for AI context metadata based on field-specific conditions or values.
* @category AI
* @deprecated Use {@link MetadataFieldFilter} from `metadata-filter.public-types` instead.
*/
export type AiContextMetadataFieldFilter = MetadataFieldFilter;
/**
* A filter combining multiple AI context metadata filters with a logical AND operation.
* @category AI
* @deprecated Use {@link MetadataAndFilter} from `metadata-filter.public-types` instead.
*/
export type AiContextMetadataAndFilter = MetadataAndFilter;
/**
* A filter combining multiple AI context metadata filters with a logical OR operation.
* @category AI
* @deprecated Use {@link MetadataOrFilter} from `metadata-filter.public-types` instead.
*/
export type AiContextMetadataOrFilter = MetadataOrFilter;
/**
* Retrieval mode for a knowledge-base search.
* - `'vector'`: dense-only similarity.
* - `'hybrid'`: native fusion of dense + lexical (only distinct on backends with native fusion, e.g.
* Mongo Atlas; on pgvector it degrades to dense + a legacy app-side keyword fallback).
* - `'keyword'`: embedding-free lexical retrieval; the mechanism is backend-specific — native Lucene BM25
* on Mongo Atlas (ranked, term-optional: a partial-term query still matches), and a boolean substring
* filter on pgvector (every term must appear literally; unranked).
* @category AI
*/
export type AiKnowledgeBaseSearchMode = 'vector' | 'hybrid' | 'keyword';
/**
* The options for the AI knowledgebase search method.
* @category AI
*/
export interface AiKnowledgeBaseChatOptions {
/** A set of filters that will limit the context the AI can access. */
contextMetadataFilter?: AiContextMetadataFilter;
/** Whether to include references from the source context in the response. Default to false. */
includeReference?: boolean;
/** Include metadata in the context */
includeMetadata?: boolean;
/** Which provider's reranker to use for reranking the context. Defaults to 'cohere'. */
rerankProvider?: AiRerankProvider;
/** The maximum number of results to return. Defaults to 30 */
limit?: number;
/** How many chunks to look over. Defaults to 100 */
chunkLimit?: number;
/** Which chat model to use when asking the question */
chatModel?: AiChatModelSelection;
/**
* Selects how the underlying vector store generates candidates:
* - `'hybrid'` (default): fuses dense vector and keyword candidates when the backend supports it
* (Mongo Atlas uses `$rankFusion`; backends without native fusion fall back to dense-only with
* the legacy app-side keyword fallback).
* - `'vector'`: dense-only — skips native fusion even on backends that support it.
* - `'keyword'`: embedding-free lexical retrieval; the mechanism is backend-specific. On Mongo Atlas it
* is native Lucene BM25 (`$search`): results are ranked by relevance and term-optional — a partial-term
* query still returns its best matches. On Postgres it is a boolean substring filter (`ILIKE ALL`):
* every whitespace-separated term must appear in a chunk as a literal, case-insensitive substring,
* matched independently (order, adjacency and relevance are NOT considered), so results are unranked and
* for broad terms the returned top-k is arbitrary. Both skip embedding, dense, reranking and the
* app-side keyword fallback. Lets an agent (or an eval) target exact tokens — identifiers, names, codes
* — that dense retrieval tends to miss.
*
* Intended to let A/B evaluations compare dense-only, hybrid and boolean-keyword candidate generation
* on the same backend.
*/
searchMode?: AiKnowledgeBaseSearchMode;
/**
* Per-pipeline weights for native hybrid fusion (Mongo `$rankFusion.combination.weights`). Only
* applies when `searchMode` is `'hybrid'` on a backend with native fusion; ignored otherwise.
* Each value must be a finite non-negative number; an omitted key defaults to `1` (the MongoDB
* default). Useful for A/B evaluating dense-vs-keyword weighting on the same backend.
*/
hybridWeights?: AiHybridSearchWeights;
}
/**
* Per-pipeline weights for native hybrid fusion. Sub-keys mirror the `$rankFusion` pipeline names.
* @category AI
*/
export interface AiHybridSearchWeights {
/** Weight for the dense vector sub-pipeline. Defaults to `1`. */
vector?: number;
/** Weight for the BM25 keyword sub-pipeline. Defaults to `1`. */
keyword?: number;
}
/**
* @category AI
* @deprecated Use {@link MetadataFilter} from `metadata-filter.public-types` instead.
*/
export type AiContextMetadataFilter = MetadataFilter;
/**
* Represents an AI knowledge base's context entry with metadata and content.
* @category AI
*/
export interface AiKnowledgeBaseContext {
/** The unique identifier of the context entry. */
id: string;
/** The application id of the context entry */
appId: AppId;
/** The knowledge base id of the context entry */
knowledgeBaseId: AiKnowledgeBaseId;
/** The date and time the context was created. */
createdAt: Date;
/** The date and time the context was last updated. */
updatedAt: Date;
/** The type of context (e.g., 'text' or 'file'). */
type: AiKnowledgeBaseContextType;
/** A title describing the context content. */
title: string;
/** The text content of the context. */
text: string;
/** Indicates whether the context is a preview; defaults to false. */
preview: boolean;
/** The size of the context content in bytes. */
sizeBytes: number;
/** Metadata associated with the context. */
metadata: AiContextMetadata;
/**
* Names of metadata fields whose stored values were machine-extracted from the content
* (driven by the knowledge base's `metadataFields` schema) rather than user-supplied.
* On re-upsert/replay, extracted values count as not-supplied (re-extracted fresh) while
* user-supplied values are preserved; consumers can also use this to caveat extracted values.
*/
autoExtractedMetadataFields?: string[];
/** Original request configuration for how the context content was processed. */
requestConfig?: AgentContextRequest;
}
/**
* @category AI
*/
export type AiKnowledgeBaseContextType = 'text' | 'file';
/**
* @category AI
*/
export type AiKnowledgeBaseContextRequest = AiKnowledgeBaseTextContextRequest | AiKnowledgeBaseFileContextRequest;
interface BaseAiKnowledgeBaseContextRequest {
contextId: string;
type: AiKnowledgeBaseContextType;
metadata?: AiContextMetadata;
}
/**
* Base options for upserting text content into the AI agent's context.
* @category AI
*/
export interface AiKnowledgeBaseContextTextOptions extends BaseAiKnowledgeBaseContextOptions {
}
/**
* Base options for upserting file content into the AI agent's context.
* @category AI
*/
export interface AiKnowledgeBaseContextFileOptions extends BaseAiKnowledgeBaseContextOptions {
}
/**
* Hint about the format of a text context payload.
*
* - `auto`: detect the format from the content (default).
* - `markdown`: treat the text as Markdown — image references will be extracted if `extractImages` is true.
* - `html`: treat the text as HTML — `<img>` tags will be extracted if `extractImages` is true.
* - `plain`: treat the text as plain text — no image extraction is performed even if `extractImages` is true.
*
* @category AI
*/
export type AiKnowledgeBaseTextFormat = 'auto' | 'markdown' | 'html' | 'plain';
/**
* Request structure for adding text-based context to an AI agent.
* @category AI
*/
export interface AiKnowledgeBaseTextContextRequest extends BaseAiKnowledgeBaseContextRequest {
/** The id of the context */
contextId: AiContextId;
/** Specifies the context type as 'text'. */
type: 'text';
/** A title for the text context. */
title: string;
/** The text content to add to the context. */
text: string;
/**
* Hint about the format of the text. If omitted (or `'auto'`), the format is sniffed from the content.
* Only `'markdown'` and `'html'` (or `'auto'` with content that looks like markdown/HTML) participate in
* image extraction when `extractImages` is true.
*/
format?: AiKnowledgeBaseTextFormat;
/**
* Whether to extract images embedded in markdown/HTML text. Defaults to false.
*
* When true and the text is detected as (or declared to be) markdown/HTML, image references inside the
* text (`` or `<img src="...">`) are fetched, stored, and have descriptions generated
* just like images extracted from a PDF.
*
* Has no effect for plain text.
*/
extractImages?: boolean;
/** Minimum width/height (in pixels) for an image to be kept. Smaller images are skipped. */
imageMinSizePixels?: number;
/** The AI model to use for generating image descriptions, if specified. */
imageExtractionModel?: AiChatModelSelection;
/** General options for how to process the text. */
options?: AiKnowledgeBaseContextTextOptions;
}
/**
* Request structure for adding file-based context to an AI agent.
* @category AI
*/
export interface AiKnowledgeBaseFileContextRequest extends BaseAiKnowledgeBaseContextRequest {
/** The id of the context */
contextId: AiContextId;
/** Specifies the context type as 'file'. */
type: 'file';
/** Whether to extract images from the file; defaults to false. */
extractImages?: boolean;
/** The minimum size for extracted images, if applicable. */
imageMinSizePixels?: number;
/** The AI model to use for extraction, if specified. */
imageExtractionModel?: AiChatModelSelection;
/** General options for how to process the file. */
options?: AiKnowledgeBaseContextFileOptions;
/** The preferred method for extracting data from the document. */
preferredExtractionMethod?: DocumentExtractionMethod;
/**
* Whether Squid keeps or discards the original file.
*
* Keeping the original file allows reprocessing and the ability for the user to download it later.
*
* Defaults to false.
*/
discardOriginalFile?: boolean;
}
/**
* @category AI
*/
export declare const RAG_TYPES: readonly ["contextual", "basic"];
/**
* @category AI
*/
export type AiRagType = (typeof RAG_TYPES)[number];
/**
* Base options for how to deal with the content being upserted.
* @category AI
*/
export type BaseAiKnowledgeBaseContextOptions = {
/** The type of RAG to use for the content. */
ragType?: AiRagType;
/** Amount of chunk overlap, in characters. */
chunkOverlap?: number;
};
/**
* Specific options for the AI knowledgebase search method.
* @category AI
*/
export interface AiKnowledgeBaseSearchOptions {
/** The prompt to search for */
prompt: string;
/** The maximum number of results to return */
limit?: number;
/** Which provider's reranker to use for reranking the context. Defaults to 'cohere'. */
rerankProvider?: AiRerankProvider;
/** How many chunks to look over. Defaults to 100 */
chunkLimit?: number;
/** Which chat model to use when asking the question */
chatModel?: AiChatModelSelection;
/**
* Selects how the underlying vector store generates candidates:
* - `'hybrid'` (default): fuses dense vector and keyword candidates when the backend supports it
* (Mongo Atlas uses `$rankFusion`; backends without native fusion fall back to dense-only with
* the legacy app-side keyword fallback).
* - `'vector'`: dense-only — skips native fusion even on backends that support it.
* - `'keyword'`: embedding-free lexical retrieval; the mechanism is backend-specific. On Mongo Atlas it
* is native Lucene BM25 (`$search`): results are ranked by relevance and term-optional — a partial-term
* query still returns its best matches. On Postgres it is a boolean substring filter (`ILIKE ALL`):
* every whitespace-separated term must appear in a chunk as a literal, case-insensitive substring,
* matched independently (order, adjacency and relevance are NOT considered), so results are unranked and
* for broad terms the returned top-k is arbitrary. Both skip embedding, dense, reranking and the
* app-side keyword fallback. Lets an agent (or an eval) target exact tokens — identifiers, names, codes
* — that dense retrieval tends to miss.
*
* Intended to let A/B evaluations compare dense-only, hybrid and boolean-keyword candidate generation
* on the same backend.
*/
searchMode?: AiKnowledgeBaseSearchMode;
/**
* Per-pipeline weights for native hybrid fusion (Mongo `$rankFusion.combination.weights`). Only
* applies when `searchMode` is `'hybrid'` on a backend with native fusion; ignored otherwise.
* Each value must be a finite non-negative number; an omitted key defaults to `1` (the MongoDB
* default). Useful for A/B evaluating dense-vs-keyword weighting on the same backend.
*/
hybridWeights?: AiHybridSearchWeights;
}
/**
* A single chunk of data returned from an AI search operation.
* @category AI
*/
export interface AiKnowledgeBaseSearchResultChunk {
/** The unique identifier of the context. */
contextId: string;
/** The data content of the search result chunk. */
data: string;
/** Optional metadata associated with the chunk. */
metadata?: AiContextMetadata;
/** The relevance score of the chunk, indicating match quality. */
score: number;
}
/**
* Response structure for upserting context for an AiKnowledgeBase
* @category AI
*/
export interface UpsertKnowledgeBaseContextResponse {
/** List of the upsert status of each item sent in the request. */
failure?: UpsertContextStatusError;
}
/**
* Response structure for upserting contexts for an AiKnowledgeBase
* @category AI
*/
export interface UpsertKnowledgeBaseContextsResponse {
/** List of the upsert status of each item sent in the request. */
failures: Array<UpsertContextStatusError>;
}
/**
* Request structure for searching an AiKnowledgeBase
* @category AI
*/
export interface AiKnowledgeBaseSearchRequest {
/** The id of the AiKnowledgeBase */
knowledgeBaseId: string;
/** The user prompt to search on */
prompt: string;
/** The search options for this search */
options: AiKnowledgeBaseSearchOptions;
}
/**
* Request structure for searching AI contexts in the AiKnowledgeBase.
* @category AI
*/
export interface BaseAiKnowledgeBaseSearchContextsRequest {
/** The id of the AiKnowledgeBase */
knowledgeBaseId: AiKnowledgeBaseId;
/** The maximum number of results to return */
limit?: number;
/** A set of filters that will limit the context the AI can access. */
contextMetadataFilter?: AiContextMetadataFilter;
/** Whether to rerank the results with AI and provide reasoning - defaults to true */
rerank?: boolean;
/** Which chat model to use when doing reranking */
chatModel?: AiChatModelSelection;
}
/**
* Request structure for searching AI contexts in the AiKnowledgeBase with prompt.
* @category AI
*/
export interface AiKnowledgeBaseSearchContextsWithPromptRequest extends BaseAiKnowledgeBaseSearchContextsRequest {
/** The user prompt to search on */
prompt: string;
}
/**
* Request structure for searching AI contexts in the AiKnowledgeBase with an existing context.
* @category AI
*/
export interface AiKnowledgeBaseSearchContextsWithContextIdRequest extends BaseAiKnowledgeBaseSearchContextsRequest {
/** The contextId to search with */
contextId: string;
}
/**
* A context with reasoning and matching score.
* @category AI
*/
export interface AiKnowledgeBaseContextWithReasoning {
/** The actual context */
context: AiKnowledgeBaseContext;
/** The reasoning behind why this context was matched - can be undefined if no reasoning was requested */
reasoning?: string;
/** The score of the match, ranging from 0 to 100, where 100 is the best match. */
score: number;
}
/**
* Response structure for searching contexts in an AiKnowledgeBase.
* @category AI
*/
export interface AiKnowledgeBaseSearchContextsResponse {
/** The resulting contexts, with reasoning if it was requested */
results: Array<AiKnowledgeBaseContextWithReasoning>;
}
/**
* Request structure for requesting a download link to the context file that you previously provided.
* @category AI
*/
export interface AiKnowledgeBaseDownloadContextRequest {
/** The id of the AiKnowledgeBase */
knowledgeBaseId: string;
/** The id of the particular AiKnowledgeBaseContext */
contextId: string;
}
/**
* Response structure with the URL to download the specified context.
*
* Can be undefined if the file is not available in Squid.
* @category AI
*/
export interface AiKnowledgeBaseDownloadContextResponse {
/** The URL to download the file, if available. */
url?: string;
}
/**
* KnowledgeBase with optional fields, used during upsert
* @category AI
*/
export type AiEmbeddingsModelWithOptionalFields = Omit<AiKnowledgeBase, 'chatModel' | 'embeddingModel'> & {
chatModel?: AiKnowledgeBase['chatModel'];
name?: string;
embeddingModel?: AiEmbeddingsModelSelection;
};
/**
* API request for deleting an AiKnowledgeBase
* @category AI
*/
export interface DeleteAiKnowledgeBaseRequest {
/** The id of the AiKnowledgeBase */
id: string;
}
/**
* API request for upserting an AiKnowledgeBase
* @category AI
*/
export interface UpsertAiKnowledgeBaseRequest {
/** The AiKnowledgeBase to upsert */
knowledgeBase: Omit<AiEmbeddingsModelWithOptionalFields, 'appId' | 'updatedAt'>;
}
/**
* API request for deleting AiKnowledgeBaseContexts
* @category AI
*/
export interface DeleteAiKnowledgeBaseContextsRequest {
/** The id of the AiKnowledgeBase */
knowledgeBaseId: string;
/** An array of AiKnowledgeBaseContext ids */
contextIds: Array<string>;
}
/**
* API response to list AiKnowledgeBaseContexts
* @category AI
*/
export interface ListAiKnowledgeBaseContextsResponse {
/** The list of AiKnowledgeBaseContexts */
contexts: Array<AiKnowledgeBaseContext>;
}
/**
* API response for searching an AiKnowledgeBase
* @category AI
*/
export interface AiKnowledgeBaseSearchResponse {
/** Array of result chunks from the search */
chunks: Array<AiKnowledgeBaseSearchResultChunk>;
}
/**
* Response containing the list of AI knowledge bases in an application.
* @category AI
*/
export interface ListAiKnowledgeBasesResponse {
/** All AI knowledge bases defined for the application. */
knowledgeBases: Array<AiKnowledgeBase>;
}
/** Request to AI-generate descriptions for a KB's metadata fields and return them (the caller persists). */
export interface GenerateMetadataFieldDescriptionsRequest {
/** The id of the AiKnowledgeBase. */
knowledgeBaseId: AiKnowledgeBaseId;
/** Limit generation to these fields; omitted ⇒ all declared fields. */
fieldNames?: string[];
/** When true, regenerate fields that already have a description; default false (fill empties only). */
overwriteExisting?: boolean;
}
/** Response for the AI-generated metadata field descriptions. */
export interface GenerateMetadataFieldDescriptionsResponse {
/** The (re)generated fields with their new descriptions; not persisted — the caller saves them. */
fields: Array<GeneratedMetadataFieldDescription>;
}
/** A generated description for a single metadata field. */
export interface GeneratedMetadataFieldDescription {
/** The name of the metadata field. */
name: string;
/** The AI-generated description for the field. */
description: string;
}
export {};