$git clone https://github.com/Mirascope/lilypad---
| 1 | <p align="center"> |
| 2 | <a href="https://mirascope.com/#lilypad"> |
| 3 | <img src="https://github.com/user-attachments/assets/b3ccb489-792d-4f13-8184-1eeae94e3451" /> |
| 4 | </a> |
| 5 | </p> |
| 6 | |
| 7 | |
| 8 | <p align="center"> |
| 9 | <a href="https://github.com/Mirascope/lilypad/actions/workflows/tests.yml" target="_blank"><img src="https://github.com/Mirascope/lilypad/actions/workflows/tests.yml/badge.svg?branch=main" alt="Tests"/></a> |
| 10 | <a href="https://codecov.io/github/Mirascope/lilypad" target="_blank"><img src="https://codecov.io/github/Mirascope/lilypad/graph/badge.svg?token=n9hOWO3hlx" alt="Coverage"/></a> |
| 11 | <a href="https://mirascope.com/docs/lilypad" target="_blank"><img src="https://img.shields.io/badge/docs-available-brightgreen" alt="Docs"/></a> |
| 12 | <a href="https://github.com/Mirascope/lilypad/stargazers" target="_blank"><img src="https://img.shields.io/github/stars/Mirascope/lilypad.svg" alt="Stars"/></a> |
| 13 | </p> |
| 14 | |
| 15 | --- |
| 16 | |
| 17 | > [!CAUTION] |
| 18 | > Lilypad is now deprecated after the GA release of Mirascope `v2` and Mirascope Cloud + Router. |
| 19 | > |
| 20 | > The new `mirascope.ops` module supports a significantly improved OTEL compliant Python SDK for instrumentation, and Mirascope Cloud offers a backend solution for that OTEL data. |
| 21 | > If you're looking for such tooling, we recommend checking out what we've build over in [`Mirascope/mirascope`](https://github.com/Mirascope/mirascope). |
| 22 | > You can find the full documentation here: https://mirascope.com/docs |
| 23 | > |
| 24 | > Lilypad will remain open-source and available for use, but we will no longer be spending cycles maintaining it as our core focus will be on all things Mirascope. |
| 25 | > |
| 26 | > If you have any questions, reach out in [our discord](https://mirascope.com/discord-invite)! |
| 27 | |
| 28 | An open-source LLM engineering platform built on these principles: |
| 29 | |
| 30 | - Building with LLMs introduces non-determinisim to your code, which requires... |
| 31 | - Tracking all input/output pairs and the exact version of the code that produced them so you can... |
| 32 | - Continuously evaluate and optimize your code. |
| 33 | |
| 34 | > [!IMPORTANT] |
| 35 | > __Lilypad is still in beta__ |
| 36 | > |
| 37 | > If you're interested in participating in the closed beta of Lilypad Pro+, [join our community](https://join.slack.com/t/mirascope-community/shared_invite/zt-2ilqhvmki-FB6LWluInUCkkjYD3oSjNA) and DM William Bakst :) |
| 38 | > |
| 39 | > We also welcome contributions with open arms! If you're interested in [contributing](https://github.com/Mirascope/lilypad/tree/main/CONTRIBUTING.md), just do it! We're here to help. |
| 40 | |
| 41 | ## Quickstart |
| 42 | |
| 43 | To get started with Lilypad: |
| 44 | |
| 45 | 1. Create an account at <https://lilypad.mirascope.com>. You can also [run Lilypad locally](https://lilypad.so/self-hosting) if you'd prefer. |
| 46 | 2. Navigate to [your organization settings](https://lilypad.mirascope.com/settings/org) |
| 47 | 3. Create a project, and then create an API key for that project. |
| 48 | a. Save your `LILYPAD_PROJECT_ID` and `LILYPAD_API_KEY` (e.g. in a `.env` file). |
| 49 | 4. Install Lilypad: `uv add "lilypad-sdk[openai]" # specify your provider of choice` |
| 50 | 5. Run and trace your first versioned function: |
| 51 | |
| 52 | ```python |
| 53 | import os |
| 54 | |
| 55 | import lilypad |
| 56 | from openai import OpenAI # use your provider of choice |
| 57 | |
| 58 | lilypad.configure( |
| 59 | project_id=os.environ["LILYPAD_PROJECT_ID"], |
| 60 | api_key=os.environ["LILYPAD_API_KEY"], |
| 61 | auto_llm=True, |
| 62 | ) |
| 63 | client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]) |
| 64 | |
| 65 | |
| 66 | @lilypad.trace(versioning="automatic") # Automatically version (non-deterministic) functions |
| 67 | def answer_question(question: str) -> str | None: |
| 68 | completion = client.chat.completions.create( |
| 69 | model="gpt-4o", |
| 70 | messages=[ |
| 71 | {"role": "system", "content": "You are a helpful assistant."}, |
| 72 | {"role": "user", "content": f"Answer this question: {question}"}, |
| 73 | ], |
| 74 | ) |
| 75 | return completion.choices[0].message.content |
| 76 | |
| 77 | |
| 78 | answer = answer_question("What is the capital of France?") |
| 79 | print(answer) |
| 80 | # > The capital of France is Paris. |
| 81 | ``` |
| 82 | |
| 83 | And that's it! Now you've versioned and traced your first non-deterministic function with Lilypad. |
| 84 | |
| 85 | ## Usage |
| 86 | |
| 87 | We are actively working |