import type { FileContentResponse } from "llama-stack-client/resources/vector-stores/files"; import type { LlamaStackClient } from "llama-stack-client"; export type VectorStoreContent = FileContentResponse.Content; export type VectorStoreContentsResponse = FileContentResponse; export interface VectorStoreContentItem { id: string; object: string; created_timestamp: number; vector_store_id: string; file_id: string; content: VectorStoreContent; metadata: Record; embedding?: number[]; } export interface VectorStoreContentDeleteResponse { id: string; object: string; deleted: boolean; } export interface VectorStoreListContentsResponse { object: string; data: VectorStoreContentItem[]; first_id?: string; last_id?: string; has_more: boolean; } export class ContentsAPI { constructor(private client: LlamaStackClient) {} async getFileContents(vectorStoreId: string, fileId: string): Promise { return this.client.vectorStores.files.content(vectorStoreId, fileId); } async getContent(vectorStoreId: string, fileId: string, contentId: string): Promise { const contentsResponse = await this.listContents(vectorStoreId, fileId); const targetContent = contentsResponse.data.find(c => c.id === contentId); if (!targetContent) { throw new Error(`Content ${contentId} not found`); } return targetContent; } async updateContent( vectorStoreId: string, fileId: string, contentId: string, updates: { content?: string; metadata?: Record } ): Promise { throw new Error("Individual content updates not yet implemented in API"); } async deleteContent(vectorStoreId: string, fileId: string, contentId: string): Promise { throw new Error("Individual content deletion not yet implemented in API"); } async listContents( vectorStoreId: string, fileId: string, options?: { limit?: number; order?: string; after?: string; before?: string; } ): Promise { const fileContents = await this.client.vectorStores.files.content(vectorStoreId, fileId); const contentItems: VectorStoreContentItem[] = []; fileContents.content.forEach((content, contentIndex) => { const rawContent = content as any; // Extract actual fields from the API response const embedding = rawContent.embedding || undefined; const created_timestamp = rawContent.created_timestamp || rawContent.created_at || Date.now() / 1000; const chunkMetadata = rawContent.chunk_metadata || {}; const contentId = rawContent.chunk_metadata?.chunk_id || rawContent.id || `content_${fileId}_${contentIndex}`; const objectType = rawContent.object || 'vector_store.file.content'; contentItems.push({ id: contentId, object: objectType, created_timestamp: created_timestamp, vector_store_id: vectorStoreId, file_id: fileId, content: content, embedding: embedding, metadata: { ...chunkMetadata, // chunk_metadata fields from API content_length: content.type === 'text' ? content.text.length : 0, }, }); }); // apply pagination if needed let filteredItems = contentItems; if (options?.limit) { filteredItems = filteredItems.slice(0, options.limit); } return { object: 'list', data: filteredItems, has_more: contentItems.length > (options?.limit || contentItems.length), }; } }