|
| 1 | +import * as traceloop from "@traceloop/node-server-sdk"; |
| 2 | +import OpenAI from "openai"; |
| 3 | + |
| 4 | +// Initialize Traceloop |
| 5 | +traceloop.initialize({ |
| 6 | + appName: "associations_demo", |
| 7 | + apiKey: process.env.TRACELOOP_API_KEY, |
| 8 | + disableBatch: true, |
| 9 | +}); |
| 10 | + |
| 11 | +const openai = new OpenAI(); |
| 12 | + |
| 13 | +/** |
| 14 | + * Sample chatbot that demonstrates the Associations API. |
| 15 | + * This example shows how to track conversations, users, and sessions |
| 16 | + * across multiple LLM interactions. |
| 17 | + */ |
| 18 | +class ChatbotWithAssociations { |
| 19 | + constructor( |
| 20 | + private conversationId: string, |
| 21 | + private userId: string, |
| 22 | + private sessionId: string, |
| 23 | + ) {} |
| 24 | + |
| 25 | + /** |
| 26 | + * Process a multi-turn conversation with associations |
| 27 | + */ |
| 28 | + @traceloop.workflow({ name: "chatbot_conversation" }) |
| 29 | + async handleConversation() { |
| 30 | + console.log("\n=== Starting Chatbot Conversation ==="); |
| 31 | + console.log(`Conversation ID: ${this.conversationId}`); |
| 32 | + console.log(`User ID: ${this.userId}`); |
| 33 | + console.log(`Session ID: ${this.sessionId}\n`); |
| 34 | + |
| 35 | + // Set associations at the beginning of the conversation |
| 36 | + // These will be automatically attached to all spans within this context |
| 37 | + traceloop.Associations.set([ |
| 38 | + [traceloop.AssociationProperty.CONVERSATION_ID, this.conversationId], |
| 39 | + [traceloop.AssociationProperty.USER_ID, this.userId], |
| 40 | + [traceloop.AssociationProperty.SESSION_ID, this.sessionId], |
| 41 | + ]); |
| 42 | + |
| 43 | + // First message |
| 44 | + const greeting = await this.sendMessage( |
| 45 | + "Hello! What's the weather like today?", |
| 46 | + ); |
| 47 | + console.log(`Bot: ${greeting}\n`); |
| 48 | + |
| 49 | + // Second message in the same conversation |
| 50 | + const followup = await this.sendMessage( |
| 51 | + "What should I wear for that weather?", |
| 52 | + ); |
| 53 | + console.log(`Bot: ${followup}\n`); |
| 54 | + |
| 55 | + // Third message |
| 56 | + const final = await this.sendMessage("Thanks for the advice!"); |
| 57 | + console.log(`Bot: ${final}\n`); |
| 58 | + |
| 59 | + return { |
| 60 | + greeting, |
| 61 | + followup, |
| 62 | + final, |
| 63 | + }; |
| 64 | + } |
| 65 | + |
| 66 | + /** |
| 67 | + * Send a single message - this is a task within the workflow |
| 68 | + */ |
| 69 | + @traceloop.task({ name: "send_message" }) |
| 70 | + private async sendMessage(userMessage: string): Promise<string> { |
| 71 | + console.log(`User: ${userMessage}`); |
| 72 | + |
| 73 | + const completion = await openai.chat.completions.create({ |
| 74 | + messages: [{ role: "user", content: userMessage }], |
| 75 | + model: "gpt-3.5-turbo", |
| 76 | + }); |
| 77 | + |
| 78 | + return completion.choices[0].message.content || "No response"; |
| 79 | + } |
| 80 | +} |
| 81 | + |
| 82 | +/** |
| 83 | + * Simulate a customer service scenario with multiple customers |
| 84 | + */ |
| 85 | +async function customerServiceDemo() { |
| 86 | + return traceloop.withWorkflow( |
| 87 | + { name: "customer_service_scenario" }, |
| 88 | + async () => { |
| 89 | + console.log("\n=== Customer Service Scenario ===\n"); |
| 90 | + |
| 91 | + // Customer 1 |
| 92 | + traceloop.Associations.set([ |
| 93 | + [traceloop.AssociationProperty.CUSTOMER_ID, "cust-001"], |
| 94 | + [traceloop.AssociationProperty.USER_ID, "agent-alice"], |
| 95 | + ]); |
| 96 | + |
| 97 | + const customer1Response = await openai.chat.completions.create({ |
| 98 | + messages: [ |
| 99 | + { |
| 100 | + role: "user", |
| 101 | + content: "I need help with my order #12345", |
| 102 | + }, |
| 103 | + ], |
| 104 | + model: "gpt-3.5-turbo", |
| 105 | + }); |
| 106 | + |
| 107 | + console.log("Customer 1 (cust-001):"); |
| 108 | + console.log(`Response: ${customer1Response.choices[0].message.content}\n`); |
| 109 | + |
| 110 | + // Customer 2 - Update associations for new customer |
| 111 | + traceloop.Associations.set([ |
| 112 | + [traceloop.AssociationProperty.CUSTOMER_ID, "cust-002"], |
| 113 | + [traceloop.AssociationProperty.USER_ID, "agent-bob"], |
| 114 | + ]); |
| 115 | + |
| 116 | + const customer2Response = await openai.chat.completions.create({ |
| 117 | + messages: [ |
| 118 | + { |
| 119 | + role: "user", |
| 120 | + content: "How do I return an item?", |
| 121 | + }, |
| 122 | + ], |
| 123 | + model: "gpt-3.5-turbo", |
| 124 | + }); |
| 125 | + |
| 126 | + console.log("Customer 2 (cust-002):"); |
| 127 | + console.log(`Response: ${customer2Response.choices[0].message.content}\n`); |
| 128 | + }, |
| 129 | + ); |
| 130 | +} |
| 131 | + |
| 132 | +/** |
| 133 | + * Main execution |
| 134 | + */ |
| 135 | +async function main() { |
| 136 | + console.log("============================================"); |
| 137 | + console.log("Traceloop Associations API Demo"); |
| 138 | + console.log("============================================"); |
| 139 | + |
| 140 | + try { |
| 141 | + // Example 1: Multi-turn chatbot conversation |
| 142 | + const chatbot = new ChatbotWithAssociations( |
| 143 | + "conv-abc-123", // conversation_id |
| 144 | + "user-alice-456", // user_id |
| 145 | + "session-xyz-789", // session_id |
| 146 | + ); |
| 147 | + |
| 148 | + await chatbot.handleConversation(); |
| 149 | + |
| 150 | + // Example 2: Customer service with multiple customers |
| 151 | + await customerServiceDemo(); |
| 152 | + |
| 153 | + console.log("\n=== Demo Complete ==="); |
| 154 | + console.log( |
| 155 | + "Check your Traceloop dashboard to see the associations attached to traces!", |
| 156 | + ); |
| 157 | + console.log( |
| 158 | + "You can filter and search by conversation_id, user_id, session_id, or customer_id.", |
| 159 | + ); |
| 160 | + } catch (error) { |
| 161 | + console.error("Error running demo:", error); |
| 162 | + process.exit(1); |
| 163 | + } |
| 164 | +} |
| 165 | + |
| 166 | +// Run the demo |
| 167 | +main(); |
0 commit comments