UNPKG

@admesh/weave-node

Version:

AdMesh Backend SDK for Node.js - Subscribe to and weave recommendations into LLM responses

588 lines (464 loc) 17.3 kB
# @admesh/weave-node Lightweight backend SDK for Node.js that fetches recommendations from the AdMesh Protocol service. This SDK enables AI platforms to integrate AdMesh's **Weave Ad Format** into their LLM responses. ## Overview The `@admesh/weave-node` SDK is a thin client wrapper that: - **Fetches recommendations** directly from admesh-protocol's `/agent/recommend` endpoint via HTTP POST - **Uses database-backed caching** for instant retrieval of previously generated recommendations - **Formats recommendations** for seamless integration into LLM prompts - **Falls back gracefully** if no recommendations are available ### Architecture (v0.2.4+) ``` Your Application ↓ (calls SDK) @admesh/weave-node SDK ↓ (HTTP POST) admesh-protocol /agent/recommend ↓ (checks database cache) Database Cache Hit? → Return Cached Recommendations ↓ (cache miss) Generate New Recommendations → Save to Database → Return ``` The SDK uses a **simplified database-backed architecture** (as of v0.2.4): - **No Pub/Sub**: Direct HTTP calls to `/agent/recommend` endpoint - **No SSE**: Synchronous request/response pattern - **Database caching**: Recommendations are cached in Firestore with 60-second TTL - **Fast cache hits**: Second call returns instantly from database (< 100ms) - **Simple integration**: Single HTTP POST, no complex subscription management ## Installation ```bash npm install @admesh/weave-node ``` ## Quick Start ```typescript import { AdMeshClient } from '@admesh/weave-node'; // Initialize the SDK with your API key const client = new AdMeshClient({ apiKey: process.env.ADMESH_API_KEY }); // Get recommendations for Weave const result = await client.getRecommendationsForWeave({ sessionId: 'sess_123', messageId: 'msg_1', query: 'best laptops for programming', timeoutMs: 30000 }); if (result.found) { console.log('Recommendations:', result.recommendations); console.log('Query:', result.query); } else { console.log('No recommendations found:', result.error); } ``` ## API Reference ### AdMeshClient Main client for consuming recommendations from the AdMesh Protocol service. #### Constructor ```typescript const client = new AdMeshClient({ apiKey: string; // Required: Your AdMesh API key }); ``` All other settings (API endpoint, debug mode, timeouts) are configured internally for optimal performance. #### Methods ##### `getRecommendationsForWeave(options)` Get recommendations for Weave format from admesh-protocol. This method makes a direct HTTP POST to `/agent/recommend` which either returns cached recommendations from the database or generates new ones. ```typescript const result = await client.getRecommendationsForWeave({ sessionId: string; // Required: Session ID messageId: string; // Required: Message ID for this conversation message query: string; // Required: User query for contextual recommendations timeoutMs?: number; // Optional: Max wait time (default: 12000ms) }); // Returns: { found: boolean; // Whether recommendations were found recommendations?: WeaveRecommendation[]; // Array of recommendations query?: string; // Original query requestId?: string; // Request ID error?: string; // Error message if not found } ``` **Example:** ```typescript const result = await client.getRecommendationsForWeave({ sessionId: 'sess_123', messageId: 'msg_1', query: 'best project management tools', timeoutMs: 30000 }); if (result.found) { console.log('Recommendations found:', result.recommendations); console.log('Original query:', result.query); // Use recommendations in your application for (const rec of result.recommendations) { console.log(`- ${rec.product_title}`); console.log(` ${rec.weave_summary}`); console.log(` Click: ${rec.click_url}`); console.log(` Exposure: ${rec.exposure_url}`); } } else { console.log('No recommendations available:', result.error); } ``` ## Configuration ### Environment Variables ```bash # Required ADMESH_API_KEY=your_api_key_here # Optional - Enable debug logging in development NODE_ENV=development ``` ### Initialization The AdMeshClient requires only your API key: ```typescript const client = new AdMeshClient({ apiKey: process.env.ADMESH_API_KEY }); ``` ### How It Works - **API Endpoint:** Automatically configured to `https://api.useadmesh.com` - **Debug Mode:** Automatically enabled when `NODE_ENV === 'development'` - **Timeouts & Retries:** Configured internally with sensible defaults ## Integration Guide ### Step 1: Initialize the SDK ```typescript import { AdMeshClient } from '@admesh/weave-node'; const client = new AdMeshClient({ apiKey: process.env.ADMESH_API_KEY }); ``` ### Step 2: Get Recommendations for Weave ```typescript async function handleUserQuery(sessionId, messageId, userQuery) { // Get recommendations for Weave (direct HTTP call to /agent/recommend) const result = await client.getRecommendationsForWeave({ sessionId, messageId, query: userQuery, timeoutMs: 30000 // 30 second timeout for generation }); if (result.found) { // Recommendations available (either from cache or freshly generated) console.log('Found', result.recommendations.length, 'recommendations'); return result.recommendations; } // No recommendations available console.log('No recommendations:', result.error); return null; } ``` ### Step 3: Use Recommendations ```typescript const recommendations = await handleUserQuery(sessionId, messageId, query); if (recommendations) { // Use recommendations in your application for (const rec of recommendations) { console.log(`Product: ${rec.product_title}`); console.log(`Summary: ${rec.weave_summary}`); console.log(`Click URL: ${rec.click_url}`); console.log(`Exposure URL: ${rec.exposure_url}`); console.log(`Trust Score: ${rec.trust_score}`); } } else { // Fallback behavior console.log('No recommendations available'); } ``` ## Performance - **Cache Hit Latency**: < 100ms when recommendations are cached in database - **Cache Miss Latency**: 1-3 seconds for fresh recommendation generation - **Timeout**: Default 30 seconds, configurable per request - **Database TTL**: Recommendations cached for 60 seconds - **Fallback**: Graceful degradation if recommendations unavailable - **Lightweight**: SDK is a thin HTTP client with minimal overhead ## Migration Guide (v0.2.7 → v0.3.0) ### What Changed Version 0.3.0 introduces **finalized minimal schema** with updated field names and structure: **Breaking Changes:** - Response structure: `data.response.recommendations``data.recommendations` - Field names: `product_description``weave_summary`, `intent_match_score``contextual_relevance_score` - Removed fields: `admesh_link`, `product_description`, `product_url`, `cpx_value`, `meta` - New fields: `recommendation_id`, `citation_summary`, `product_logo` (object), `categories`, `trust_score`, `model_used` ### Migration Steps 1. **Update the SDK:** ```bash npm install @admesh/weave-node@^0.3.0 ``` 2. **Update your code:** ```typescript // OLD (v0.2.7) for (const rec of result.recommendations) { console.log(rec.product_description); // ❌ No longer available console.log(rec.admesh_link); // ❌ No longer available } // NEW (v0.3.0) for (const rec of result.recommendations) { console.log(rec.weave_summary); // ✅ Use this instead console.log(rec.click_url); // ✅ Use this instead } ``` 3. **Update field access:** - `product_description``weave_summary` - `intent_match_score``contextual_relevance_score` - `admesh_link``click_url` (for click tracking) - `image_url``product_logo.url` (now an object) ### Backward Compatibility The SDK maintains backward compatibility: - `WeaveClient` is still exported as an alias to `AdMeshClient` - Old code using `WeaveClient` will continue to work - Type definitions have been updated to match the new schema --- ## Migration Guide (v0.2.3 → v0.2.4+) ### What Changed Version 0.2.4 introduced a **simplified database-backed architecture** that removes Google Cloud Pub/Sub and SSE subscriptions: **Before (v0.2.3):** - Used Pub/Sub for real-time message delivery - Required SSE subscription endpoint (`/weave/subscribe`) - Complex race condition handling with delays and polling - Required GCP credentials and Pub/Sub configuration **After (v0.2.4+):** - Direct HTTP POST to `/agent/recommend` endpoint - Database-backed caching with 60-second TTL - Simple request/response pattern - No GCP Pub/Sub dependencies ### Breaking Changes The following options have been **removed** from `getRecommendationsForWeave()`: - `pollIntervalMs` - No longer needed (direct HTTP call, not polling) - `delayMs` - No longer needed (no race condition with database-backed approach) ### Migration Steps 1. **Update the SDK:** ```bash npm install @admesh/weave-node@^0.2.4 ``` 2. **Update your code:** ```typescript // OLD (v0.2.3) const result = await client.getRecommendationsForWeave({ sessionId, messageId, query, timeoutMs: 10000, pollIntervalMs: 100, // ❌ Remove this delayMs: 500 // ❌ Remove this }); // NEW (v0.2.4+) const result = await client.getRecommendationsForWeave({ sessionId, messageId, query, timeoutMs: 30000 // Increased default timeout }); ``` 3. **Remove Pub/Sub environment variables** (no longer needed): ```bash # ❌ Remove these from your .env file GCP_PROJECT_ID=... PUBSUB_TOPIC_RECOMMENDATIONS=... PUBSUB_TOPIC_ACK=... PUBSUB_SUBSCRIPTION_ID=... ``` 4. **Keep these environment variables:** ```bash # ✅ Still required ADMESH_API_KEY=your_api_key_here ADMESH_API_BASE_URL=http://localhost:8000 ``` ### Backward Compatibility The SDK maintains backward compatibility: - `WeaveClient` is still exported as an alias to `AdMeshClient` - Old code using `WeaveClient` will continue to work - The removed options (`pollIntervalMs`, `delayMs`) are simply ignored if provided ### Benefits of the New Architecture**Simpler**: No Pub/Sub setup, no SSE subscriptions, no race conditions ✅ **Faster**: Database cache hits return in < 100ms ✅ **More Reliable**: No message delivery issues, no subscription timeouts ✅ **Easier to Debug**: Simple HTTP request/response, standard error handling ✅ **Lower Latency**: Direct database lookup instead of Pub/Sub message routing ## Error Handling ```typescript const result = await weave.getRecommendationsForWeave({ sessionId, messageId, timeoutMs: 10000 }); if (!result.found) { console.error('Failed to retrieve recommendations:', result.error); // Fallback behavior return { success: false, recommendations: [], error: result.error }; } // Use recommendations return { success: true, recommendations: result.recommendations, query: result.query }; ``` ## Troubleshooting ### No recommendations found **Possible causes:** 1. admesh-protocol is not running or not accessible 2. Query doesn't match any products in the database 3. Session ID or Message ID mismatch 4. Timeout too short for fresh generation 5. Invalid API key **Solution:** ```typescript // Debug mode is automatically enabled in development (NODE_ENV=development) // Try with longer timeout const result = await client.getRecommendationsForWeave({ sessionId, messageId, query: 'specific product query', // Provide a clear query timeoutMs: 45000 // Increase timeout for generation }); console.log('Found:', result.found); console.log('Error:', result.error); ``` ### Connection errors **Possible causes:** 1. Network connectivity issues 2. Invalid API key 3. AdMesh API service is down **Solution:** ```typescript // Check API key format console.log('API key starts with:', process.env.ADMESH_API_KEY?.substring(0, 10)); // Test the connection try { const result = await client.getRecommendationsForWeave({ sessionId: 'test', messageId: 'test', query: 'test query', timeoutMs: 5000 }); console.log('Connection successful:', result.found); } catch (error) { console.error('Connection failed:', error.message); } ``` ### Slow response times **Possible causes:** 1. First call (cache miss) - recommendations are being generated 2. Complex query requiring more processing 3. Database connection issues **Solution:** ```typescript // First call will be slower (1-3 seconds) - this is normal const result1 = await client.getRecommendationsForWeave({ sessionId, messageId, query, timeoutMs: 30000 }); console.log('First call (generation):', result1.found); // Second call with same session_id + message_id should be fast (< 100ms) const result2 = await client.getRecommendationsForWeave({ sessionId, messageId, query, timeoutMs: 5000 // Can use shorter timeout for cached results }); console.log('Second call (cache hit):', result2.found); ``` ## Types ### AdMeshRecommendation Individual recommendation object returned by the API. ```typescript interface AdMeshRecommendation { ad_id: string; // Unique ad identifier product_id: string; // Product ID recommendation_id: string; // Recommendation identifier product_title: string; // Product name citation_summary: string; // Citation text (moved from top-level) weave_summary: string; // Weave format summary exposure_url: string; // Exposure tracking URL click_url: string; // Click tracking URL product_logo: { url: string }; // Product logo object categories: string[]; // Product categories contextual_relevance_score: number; // Contextual relevance score (0-100) trust_score: number; // Trust score model_used: string; // Model used for generation } ``` ### AdMeshIntegrationResult Result from `integrateRecommendations()` method. ```typescript interface AdMeshIntegrationResult { success: boolean; // Whether recommendations were found recommendations: AdMeshRecommendation[]; // Array of recommendations query: string; // Original query weaveText: string; // Formatted recommendations for LLM error?: string; // Error message if unsuccessful } ``` ### AdMeshWaitResult Result from `getRecommendationsForWeave()` method. ```typescript interface AdMeshWaitResult { found: boolean; // Whether recommendations were found recommendations?: AdMeshRecommendation[]; // Array of recommendations query?: string; // Original query requestId?: string; // Request ID error?: string; // Error message if not found } ``` ### AdMeshClientConfig Configuration for initializing the AdMeshClient. ```typescript interface AdMeshClientConfig { apiKey: string; // Required: Your AdMesh API key } ``` **Note:** All other configuration (API endpoint, debug mode, timeouts) is handled internally. ## Architecture Details ### How It Works (v0.2.4+) 1. **@admesh/weave-node SDK** makes HTTP POST to `/agent/recommend` endpoint 2. **admesh-protocol** checks database cache for existing recommendations 3. **Cache Hit**: Returns cached recommendations immediately (< 100ms) 4. **Cache Miss**: Generates new recommendations, saves to database, returns (1-3s) 5. SDK returns recommendations in a format ready for LLM integration ### Data Flow ``` Your Application ↓ @admesh/weave-node SDK ↓ (HTTP POST) admesh-protocol /agent/recommend ↓ Check Database Cache (session_id + message_id) ↓ Cache Hit? → Return Cached (< 100ms) ↓ (cache miss) Generate Recommendations ↓ Save to Database (60s TTL) ↓ Return Recommendations ↓ SDK Formats for LLM ↓ Integrate into Prompt ↓ LLM Response with Weave Ads ``` ### Database Caching - **Collection**: `recommendations` in Firestore (reuses existing collection) - **Query**: By `session_id` and `message_id` fields - **Freshness Window**: 60 seconds (validated using `created_at` timestamp) - **Cache Hit**: < 100ms response time (reconstructs response from individual documents) - **Cache Miss**: 1-3 seconds for fresh generation - **No TTL Required**: Application-level freshness validation, documents persist for billing/analytics ### Key Design Principles - **Lightweight**: SDK is a thin HTTP client with minimal dependencies - **Fast**: Database cache hits return in < 100ms - **Simple**: Direct request/response pattern, no complex subscriptions - **Reliable**: No message delivery issues, no race conditions - **Graceful Fallback**: Works seamlessly even if recommendations aren't available - **Configurable**: Timeout is customizable per request - **Debug-friendly**: Optional debug logging for troubleshooting ## License MIT