Skip to content

Feature/improve db studio #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

Commons Clause Restriction:
Without limiting the foregoing, the permission granted above does not include
the right to Sell the Software. For the purposes of this license, "Sell" means
providing the Software, or any product or service substantially derived from it,
to third parties for a fee or other consideration, including but not limited to
offering it as a hosted or managed service that competes with the original
functionality of the Software. This restriction does not apply to the use of the
Software for internal purposes or within an organization.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down
131 changes: 76 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,84 +19,96 @@ Managing prompts across multiple applications, models, and use cases can quickly

## ✨ Key Features

### 🎯 Dynamic Prompt Generation
Create versatile prompts with Promptix's templating system, allowing for context-aware adjustments:
### 🔄 Static Prompt Retrieval and Version Control
Fetch your static prompts and manage different versions without dynamic templating:

```python
support_prompt = Promptix.get_prompt(
prompt_template="CustomerSupport",
# These variables dynamically modify the prompt
department="Billing",
customer_tier="Premium",
issue_type="refund request",
agent_name="Alex"
)
```

### 🔄 Version Control Built-in
Keep track of prompt iterations and test new versions without breaking production:

```python
# Get the latest live version (for production)
live_prompt = Promptix.get_prompt("CustomerSupport")
# Get the latest live version of a static prompt
live_prompt = Promptix.get_prompt("CustomerSupportStatic")

# Test a new draft version in development
draft_prompt = Promptix.get_prompt(
prompt_template="CustomerSupport",
prompt_template="CustomerSupportStatic",
version="v2"
)
```

### 🎨 Promptix Studio
Manage prompts through a clean web interface by simply running:

```bash
promptix studio
```

### 🛠️ Fluent Builder API
Create sophisticated prompt configurations with an intuitive builder pattern:
### 🎯 Dynamic Templating with Builder Pattern
Create sophisticated, context-aware system instructions using the fluent builder API:

```python
config = (
# Generate a dynamic system instruction
system_instruction = (
Promptix.builder("CustomerSupport")
.with_customer_name("Jane Doe")
.with_department("Technical Support")
.with_priority("high")
.with_tool("ticket_history") # Enable specific tools
.with_tool("ticket_history")
.with_tool_parameter("ticket_history", "max_tickets", 5)
.with_memory(conversation_history)
.build()
.system_instruction() # Returns the system instruction string
)
```

### 🤖 Multi-Provider Support
Send your prompts to any LLM provider while maintaining a consistent interface:
### 🤖 Model Configuration for API Calls
Prepare complete configurations for different LLM providers:

```python
# OpenAI integration
openai_config = Promptix.builder("AgentPrompt").build()
openai_config = (
Promptix.builder("AgentPrompt")
.with_customer_context(customer_data)
.with_issue_details(issue)
.for_client("openai")
.build()
)
openai_response = openai_client.chat.completions.create(**openai_config)

# Anthropic integration
anthropic_config = (
Promptix.builder("AgentPrompt")
.with_customer_context(customer_data)
.with_issue_details(issue)
.for_client("anthropic")
.build()
)
anthropic_response = anthropic_client.messages.create(**anthropic_config)
```

### 🎨 Promptix Studio
Manage prompts through a clean web interface by simply running:

```bash
promptix studio
```

When you run this command, you'll get access to the Promptix Studio dashboard:

![Promptix Studio Dashboard](https://raw.githubusercontent.com/username/promptix/main/docs/images/promptix-studio-dashboard.png)

The Studio interface provides:

- **Dashboard overview** with prompt usage statistics
- **Prompt Library** for browsing and managing all your prompts
- **Version management** to track prompt iterations and mark releases as live
- **Quick creation** of new prompts with a visual editor
- **Usage statistics** showing which models and providers are most used
- **Live editing** with immediate validation and preview

Studio makes it easy to collaborate on prompts, test variations, and manage your prompt library without touching code.

> **Note**: To include the screenshot in your README, save the image to your repository (e.g., in a `docs/images/` directory) and update the image path accordingly.

### 🧠 Context-Aware Prompting
Adapt prompts based on dynamic conditions to create truly intelligent interactions:

```python
# Prompt adapts based on user context
prompt = Promptix.get_prompt(
prompt_template="CustomerSupport",
customer_history_length="long" if customer.interactions > 5 else "short",
sentiment="frustrated" if sentiment_score < 0.3 else "neutral",
technical_level=customer.technical_proficiency
# Build system instruction with conditional logic
system_instruction = (
Promptix.builder("CustomerSupport")
.with_history_context("long" if customer.interactions > 5 else "short")
.with_sentiment("frustrated" if sentiment_score < 0.3 else "neutral")
.with_technical_level(customer.technical_proficiency)
.system_instruction()
)
```

Expand All @@ -117,27 +129,34 @@ promptix studio

2. **Create your first prompt template** in the Studio UI or in your YAML file.

3. **Use the prompt in your code**:
3. **Use prompts in your code**:
```python
from promptix import Promptix

# Basic usage
greeting = Promptix.get_prompt(
prompt_template="Greeting",
user_name="Alex"
# Static prompt retrieval
greeting = Promptix.get_prompt("SimpleGreeting")

# Dynamic system instruction
system_instruction = (
Promptix.builder("CustomerSupport")
.with_customer_name("Alex")
.with_issue_type("billing")
.system_instruction()
)

# With OpenAI
from openai import OpenAI
client = OpenAI()

model_config = Promptix.prepare_model_config(
prompt_template="CustomerSupport",
customer_name="Jordan Smith",
issue="billing question"
openai_config = (
Promptix.builder("CustomerSupport")
.with_customer_name("Jordan Smith")
.with_issue("billing question")
.for_client("openai")
.build()
)

response = client.chat.completions.create(**model_config)
response = client.chat.completions.create(**openai_config)
```

## 📊 Real-World Use Cases
Expand Down Expand Up @@ -174,6 +193,7 @@ security_review_config = (
.with_review_focus("security")
.with_tool("vulnerability_scanner")
.with_tool("dependency_checker")
.for_client("openai")
.build()
)
```
Expand All @@ -184,10 +204,11 @@ Promptix automatically validates your prompt variables against defined schemas:

```python
try:
# Will raise error if technical_level isn't one of the allowed values
prompt = Promptix.get_prompt(
prompt_template="TechnicalSupport",
technical_level="expert" # Must be in ["beginner", "intermediate", "advanced"]
# Dynamic system instruction with validation
system_instruction = (
Promptix.builder("TechnicalSupport")
.with_technical_level("expert") # Must be in ["beginner", "intermediate", "advanced", "expert"]
.system_instruction()
)
except ValueError as e:
print(f"Validation Error: {str(e)}")
Expand Down
Binary file added docs/images/promptix-studio-dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 11 additions & 11 deletions examples/03_builder_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@ def main():

# Example 1: Basic builder usage with SimpleChat
print("Example 1: Basic Builder (SimpleChat)")
config1 = (
SystemPrompt = (
Promptix.builder("SimpleChat")
.with_user_name("Alice")
.with_assistant_name("Helper")
.build()
.system_instruction()
)
print_config(config1)
print_config(SystemPrompt)

# Example 2: Builder with version specification
print("Example 2: Builder with Version (SimpleChat v2)")
config2 = (
config1 = (
Promptix.builder("SimpleChat")
.with_version("v2")
.with_user_name("Bob")
.with_assistant_name("Advisor")
.with_personality_type("professional")
.build()
)
print_config(config2)
print_config(config1)

# Example 3: Builder with memory (conversation history)
print("Example 3: Builder with Memory")
Expand All @@ -45,21 +45,21 @@ def main():
{"role": "assistant", "content": "I'd be happy to help! Could you share some code with me?"}
]

config3 = (
config2 = (
Promptix.builder("CodeReviewer")
.with_code_snippet("def add(a, b): return a + b")
.with_programming_language("Python")
.with_review_focus("Best practices")
.with_memory(memory)
.build()
)
print_config(config3)
print_config(config2)


# Example 4: Builder for specific client
print("Example 4: Builder for Specific Client (Anthropic)")
try:
config5 = (
config3 = (
Promptix.builder("CodeReviewer")
.with_version("v2") # Anthropic-compatible version
.with_code_snippet("def process(data): return [x for x in data if x > 0]")
Expand All @@ -69,13 +69,13 @@ def main():
.for_client("anthropic") # Specify client type
.build()
)
print_config(config5)
print_config(config3)
except ValueError as e:
print(f"Error: {str(e)}")

# Example 5: Complex tool configuration
print("Example 5: Complex Tool Configuration")
config5 = (
config4 = (
Promptix.builder("ComplexCodeReviewer")
.with_programming_language("Python")
.with_severity("high")
Expand All @@ -88,7 +88,7 @@ def main():
.disable_tools("style_checker")
.build()
)
print_config(config5)
print_config(config4)

if __name__ == "__main__":
main()
26 changes: 24 additions & 2 deletions src/promptix/core/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,16 @@ def _process_tools_template(self) -> List[Dict[str, Any]]:
self._logger.warning(f"Error processing tools: {str(e)}\nDetails: {error_details}")
return [] # Return empty list on error

def build(self) -> Dict[str, Any]:
"""Build the final configuration using the appropriate adapter."""
def build(self, system_only: bool = False) -> Union[Dict[str, Any], str]:
"""Build the final configuration using the appropriate adapter.

Args:
system_only: If True, returns only the system instruction string instead of the full model config.

Returns:
Either the full model configuration dictionary or just the system instruction string,
depending on the value of system_only.
"""
# Validate all required fields are present and have correct types
missing_fields = []
for field, props in self.properties.items():
Expand All @@ -324,6 +332,10 @@ def build(self) -> Dict[str, Any]:
# Provide a fallback basic message when template rendering fails
system_message = f"You are an AI assistant for {self.prompt_template}."

# If system_only is True, just return the system message
if system_only:
return system_message

# Initialize the base configuration
model_config = {}

Expand Down Expand Up @@ -358,6 +370,16 @@ def build(self) -> Dict[str, Any]:

return model_config

def system_instruction(self) -> str:
"""Get only the system instruction/prompt as a string.

This is a convenient shorthand for build(system_only=True).

Returns:
The rendered system instruction string
"""
return self.build(system_only=True)

def debug_tools(self) -> Dict[str, Any]:
"""Debug method to inspect the tools configuration.

Expand Down
Loading