#!/usr/bin/env node /** * SAP AI Provider - Embeddings Example * * This example demonstrates text embedding generation using the SAP AI Provider * with the Vercel AI SDK's embed and embedMany functions. * * Use cases: * - RAG (Retrieval-Augmented Generation) * - Semantic search * - Document similarity * - Clustering * * Authentication: * - On SAP BTP: Automatically uses service binding (VCAP_SERVICES) * - Locally: Set AICORE_SERVICE_KEY environment variable with your service key JSON */ // Load environment variables import "dotenv/config"; import { APICallError, LoadAPIKeyError, NoSuchModelError } from "@ai-sdk/provider"; import { embed, embedMany } from "ai"; // This example uses relative imports for local development within this repo. // In YOUR production project, use the published package instead: // import { createSAPAIProvider } from "@jerome-benoit/sap-ai-provider"; import { createSAPAIProvider } from "../src/index"; /** * Demonstrates single and batch embedding generation */ async function embeddingsExample() { console.log("šŸ“Š SAP AI Embeddings Example\n"); // Verify AICORE_SERVICE_KEY is set for local development if (!process.env.AICORE_SERVICE_KEY && !process.env.VCAP_SERVICES) { console.warn("āš ļø Warning: AICORE_SERVICE_KEY environment variable not set."); console.warn(" Set it in your .env file or environment for local development.\n"); } try { const provider = createSAPAIProvider(); console.log("šŸ”¢ Generating single embedding...\n"); const { embedding } = await embed({ model: provider.embedding("text-embedding-3-small"), value: "What is machine learning and how does it work?", }); console.log("āœ… Single embedding generated:"); console.log(` Dimensions: ${String(embedding.length)}`); console.log( ` First 5 values: [${embedding .slice(0, 5) .map((v) => v.toFixed(6)) .join(", ")}...]`, ); console.log("\nšŸ”¢ Generating batch embeddings...\n"); const documents = [ "Machine learning is a subset of artificial intelligence.", "Deep learning uses neural networks with many layers.", "Natural language processing helps computers understand text.", "Computer vision enables machines to interpret images.", ]; const { embeddings } = await embedMany({ model: provider.embedding("text-embedding-3-small"), values: documents, }); console.log(`āœ… Generated ${String(embeddings.length)} embeddings:`); embeddings.forEach((emb, idx) => { const doc = documents[idx] ?? ""; console.log( ` [${String(idx)}] "${doc.slice(0, 40)}..." → ${String(emb.length)} dimensions`, ); }); console.log("\nšŸ“ Calculating cosine similarities...\n"); // Calculate cosine similarity between embeddings const cosineSimilarity = (a: number[], b: number[]): number => { const dotProduct = a.reduce((sum, val, i) => sum + val * (b[i] ?? 0), 0); const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0)); const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0)); return dotProduct / (magnitudeA * magnitudeB); }; // Compare each document to the first one const referenceDoc = documents[0] ?? ""; const referenceEmb = embeddings[0] ?? []; console.log(` Reference: "${referenceDoc.slice(0, 40)}..."`); for (let i = 1; i < embeddings.length; i++) { const currentEmb = embeddings[i] ?? []; const currentDoc = documents[i] ?? ""; const similarity = cosineSimilarity(referenceEmb, currentEmb); console.log(` → "${currentDoc.slice(0, 35)}..." similarity: ${similarity.toFixed(4)}`); } console.log("\nšŸ·ļø Testing embedding types...\n"); // Document embedding (for storage/indexing) const { embedding: docEmbedding } = await embed({ model: provider.embedding("text-embedding-3-small", { type: "document", }), value: "This is a document to be indexed for later retrieval.", }); console.log(` Document embedding: ${String(docEmbedding.length)} dimensions`); // Query embedding (for search queries) const { embedding: queryEmbedding } = await embed({ model: provider.embedding("text-embedding-3-small", { type: "query", }), value: "How do I retrieve documents?", }); console.log(` Query embedding: ${String(queryEmbedding.length)} dimensions`); console.log("\nāœ… All embedding tests completed!"); } catch (error: unknown) { if (error instanceof LoadAPIKeyError) { console.error("āŒ Authentication Error:", error.message); } else if (error instanceof NoSuchModelError) { console.error("āŒ Model Not Found:", error.modelId); } else if (error instanceof APICallError) { console.error("āŒ API Call Error:", error.statusCode, error.message); // Parse SAP-specific metadata const sapError = JSON.parse(error.responseBody ?? "{}") as { error?: { code?: string; request_id?: string }; }; if (sapError.error?.request_id) { console.error(" SAP Request ID:", sapError.error.request_id); console.error(" SAP Error Code:", sapError.error.code); } } else { const errorMessage = error instanceof Error ? error.message : String(error); console.error("āŒ Example failed:", errorMessage); } console.error("\nšŸ’” Troubleshooting tips:"); console.error(" - Ensure AICORE_SERVICE_KEY is set with valid credentials"); console.error(" - Check that your SAP AI Core instance is accessible"); console.error(" - Verify the embedding model is available in your deployment"); } } embeddingsExample().catch(console.error); export { embeddingsExample };