|
| 1 | +import os |
| 2 | +import json |
| 3 | +import asyncio |
| 4 | +import ldclient |
| 5 | +from ldclient import Context |
| 6 | +from ldclient.config import Config |
| 7 | +from ldai import LDAIClient, AICompletionConfigDefault |
| 8 | + |
| 9 | +# Set sdk_key to your LaunchDarkly SDK key. |
| 10 | +sdk_key = os.getenv('LAUNCHDARKLY_SDK_KEY') |
| 11 | + |
| 12 | +# Set config_key to the AI Config key you want to evaluate. |
| 13 | +ai_config_key = os.getenv('LAUNCHDARKLY_AI_CONFIG_KEY', 'sample-ai-config') |
| 14 | + |
| 15 | + |
| 16 | +async def async_main(): |
| 17 | + if not sdk_key: |
| 18 | + print("*** Please set the LAUNCHDARKLY_SDK_KEY env first") |
| 19 | + exit() |
| 20 | + |
| 21 | + ldclient.set_config(Config(sdk_key)) |
| 22 | + |
| 23 | + if not ldclient.get().is_initialized(): |
| 24 | + print("*** SDK failed to initialize. Please check your internet connection and SDK credential for any typo.") |
| 25 | + exit() |
| 26 | + |
| 27 | + aiclient = LDAIClient(ldclient.get()) |
| 28 | + print("*** SDK successfully initialized") |
| 29 | + |
| 30 | + # Set up the evaluation context. This context should appear on your |
| 31 | + # LaunchDarkly contexts dashboard soon after you run the demo. |
| 32 | + context = ( |
| 33 | + Context |
| 34 | + .builder('example-user-key') |
| 35 | + .kind('user') |
| 36 | + .name('Sandy') |
| 37 | + .build() |
| 38 | + ) |
| 39 | + |
| 40 | + try: |
| 41 | + # Example using the chat functionality which automates the judge evaluation |
| 42 | + default_value = AICompletionConfigDefault( |
| 43 | + enabled=False, |
| 44 | + ) |
| 45 | + |
| 46 | + chat = await aiclient.create_chat(ai_config_key, context, default_value, { |
| 47 | + 'companyName': 'LaunchDarkly', |
| 48 | + }) |
| 49 | + |
| 50 | + if not chat: |
| 51 | + print(f"*** AI chat configuration is not enabled for key: {ai_config_key}") |
| 52 | + return |
| 53 | + |
| 54 | + print("\n*** Starting chat with automatic judge evaluation:") |
| 55 | + user_input = 'How can LaunchDarkly help me?' |
| 56 | + print("User Input:", user_input) |
| 57 | + |
| 58 | + # The invoke method will automatically evaluate the chat response with any judges defined in the AI config |
| 59 | + chat_response = await chat.invoke(user_input) |
| 60 | + print("Chat Response:", chat_response.message.content) |
| 61 | + |
| 62 | + # Log judge evaluation results with full detail |
| 63 | + if chat_response.evaluations is not None and len(chat_response.evaluations) > 0: |
| 64 | + # Note: Judge evaluations run asynchronously and do not block your application. |
| 65 | + # Results are automatically sent to LaunchDarkly for AI config metrics. |
| 66 | + # You only need to await if you want to access the evaluation results in your code. |
| 67 | + print("\nNote: Awaiting judge results (optional - done here for demonstration only).") |
| 68 | + eval_results = await asyncio.gather(*chat_response.evaluations) |
| 69 | + |
| 70 | + # Convert results, replacing None with a message |
| 71 | + results_to_display = [ |
| 72 | + result.to_dict() if result is not None else "not evaluated" |
| 73 | + for result in eval_results |
| 74 | + ] |
| 75 | + |
| 76 | + print("Judge results:") |
| 77 | + print(json.dumps(results_to_display, indent=2, default=str)) |
| 78 | + |
| 79 | + if None in eval_results: |
| 80 | + print("\nNote: Some judge evaluations were skipped.") |
| 81 | + print("This typically happens when the sample rate doesn't require this evaluation, or due to a configuration issue.") |
| 82 | + print("Check application logs for more details.") |
| 83 | + else: |
| 84 | + print("\nNo judge evaluations were performed.") |
| 85 | + print("This typically happens when the sample rate doesn't require this evaluation, or due to a configuration issue.") |
| 86 | + print("Check application logs for more details.") |
| 87 | + |
| 88 | + print("Success.") |
| 89 | + except Exception as err: |
| 90 | + print("Error:", err) |
| 91 | + finally: |
| 92 | + # Close the client to flush events and close the connection. |
| 93 | + ldclient.get().close() |
| 94 | + |
| 95 | + |
| 96 | +def main(): |
| 97 | + """Synchronous entry point for Poetry script.""" |
| 98 | + asyncio.run(async_main()) |
| 99 | + |
| 100 | + |
| 101 | +if __name__ == "__main__": |
| 102 | + main() |
0 commit comments