Skip to content

Conversation

@kxzk
Copy link
Collaborator

@kxzk kxzk commented Dec 12, 2025

Summary

  • Add create_prompt and update_prompt methods to the Client API for programmatic prompt management
  • Enable creating new prompts (or versions) and updating labels without the Langfuse UI
  • Fix URL encoding for prompt names containing special characters (e.g., /, ?, spaces)

Key Changes

File Change
lib/langfuse/client.rb Add create_prompt and update_prompt with validation
lib/langfuse/api_client.rb Add HTTP methods + URL encoding fix
docs/PROMPTS.md Document new methods with examples
spec/ Add 30+ test cases for new functionality

API Example

# Create
prompt = client.create_prompt(
  name: "greeting",
  prompt: "Hello {{name}}!",
  type: :text,
  labels: ["staging"]
)

# Update labels
client.update_prompt(name: "greeting", version: 1, labels: ["production"])

- Enable programmatic prompt creation and version management without requiring UI access
- Support label updates for promoting prompts across environments (staging → production)
- Add comprehensive documentation with workflow examples for prompt lifecycle management
- Implement URL encoding for prompt names to handle special characters safely
- Extend retry logic to include PATCH requests for idempotent label updates
@kxzk kxzk added the enhancement New feature or request label Dec 12, 2025
@kxzk
Copy link
Collaborator Author

kxzk commented Dec 17, 2025

Validation

Platform output Screenshot 2025-12-16 at 15 22 36
Script used to validate
#!/usr/bin/env ruby
# frozen_string_literal: true

require "bundler/setup"
require "langfuse"
require "dotenv/load"
require "securerandom"

Langfuse.configure do |config|
  config.public_key = ENV.fetch("LANGFUSE_PUBLIC_KEY")
  config.secret_key = ENV.fetch("LANGFUSE_SECRET_KEY")
  config.base_url = ENV.fetch("LANGFUSE_HOST")
end

client = Langfuse.client
unique_id = SecureRandom.hex(4)

puts "=" * 60
puts "Validating Langfuse Prompt Create/Update API"
puts "=" * 60

puts "\n[1] Creating text prompt..."
text_prompt_name = "test-text-prompt-#{unique_id}"
text_prompt = client.create_prompt(
  name: text_prompt_name,
  prompt: "Hello {{name}}! Welcome to {{place}}.",
  type: :text,
  labels: ["staging"],
  config: { model: "gpt-4o", temperature: 0.7 }
)

puts "  ✓ Created: #{text_prompt.name} v#{text_prompt.version}"
puts "  ✓ Labels: #{text_prompt.labels.inspect}"
puts "  ✓ Compiled: #{text_prompt.compile(name: 'Alice', place: 'Wonderland')}"

puts "\n[2] Creating chat prompt..."
chat_prompt_name = "test-chat-prompt-#{unique_id}"
chat_prompt = client.create_prompt(
  name: chat_prompt_name,
  prompt: [
    { role: "system", content: "You are a helpful {{role}} assistant." },
    { role: "user", content: "{{question}}" }
  ],
  type: :chat,
  labels: ["staging"],
  tags: ["validation-test"]
)

puts "  ✓ Created: #{chat_prompt.name} v#{chat_prompt.version}"
puts "  ✓ Labels: #{chat_prompt.labels.inspect}"
compiled_chat = chat_prompt.compile(role: "coding", question: "How do I write Ruby?")
puts "  ✓ Compiled messages:"
compiled_chat.each { |msg| puts "      [#{msg[:role]}] #{msg[:content]}" }

puts "\n[3] Creating new version of text prompt..."
text_prompt_v2 = client.create_prompt(
  name: text_prompt_name,
  prompt: "Greetings {{name}}! Welcome aboard to {{place}}.",
  type: :text,
  labels: ["staging"]
)

puts "  ✓ Created: #{text_prompt_v2.name} v#{text_prompt_v2.version}"
raise "Expected version 2" unless text_prompt_v2.version == 2

puts "\n[4] Updating prompt labels (promote v2 to production)..."
updated_prompt = client.update_prompt(
  name: text_prompt_name,
  version: 2,
  labels: ["production"]
)

puts "  ✓ Updated: #{updated_prompt.name} v#{updated_prompt.version}"
puts "  ✓ New labels: #{updated_prompt.labels.inspect}"
raise "Expected production label" unless updated_prompt.labels.include?("production")

puts "\n[5] Fetching prompt by label..."
production_prompt = client.get_prompt(text_prompt_name, label: "production")
puts "  ✓ Fetched v#{production_prompt.version} with label 'production'"
raise "Expected version 2" unless production_prompt.version == 2

puts "\n[6] Using compile_prompt shorthand..."
compiled = client.compile_prompt(text_prompt_name, variables: { name: "Bob", place: "Earth" }, label: "production")
puts "  ✓ Result: #{compiled}"

puts "\n" + "=" * 60
puts "All validations passed!"
puts "=" * 60
puts "\nCreated prompts (clean up manually if needed):"
puts "  - #{text_prompt_name}"
puts "  - #{chat_prompt_name}"

@kxzk kxzk marked this pull request as ready for review December 17, 2025 09:17
@kxzk kxzk requested review from NoahFisher and Copilot December 17, 2025 09:17
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds programmatic prompt management capabilities to the Langfuse Ruby SDK by introducing create_prompt and update_prompt methods, enabling users to create and update prompts without using the Langfuse UI. Additionally, it fixes URL encoding for prompt names containing special characters.

Key Changes:

  • Added create_prompt method for creating new prompts or versions programmatically with full parameter support (config, labels, tags, commit messages)
  • Added update_prompt method for updating labels on existing prompt versions to support promotion workflows
  • Fixed URL encoding for prompt names with special characters (e.g., /, ?, spaces) using URI.encode_uri_component

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
lib/langfuse/client.rb Adds create_prompt and update_prompt methods with validation, type checking, and normalization of chat message keys
lib/langfuse/api_client.rb Implements HTTP methods for create/update operations, adds URL encoding fix, updates retry configuration to include PATCH, handles 201 status code
spec/langfuse/client_spec.rb Adds comprehensive test coverage for create/update methods including text/chat prompts, validation, and compilation
spec/langfuse/api_client_spec.rb Adds detailed API client tests for create/update operations, error handling, URL encoding, and edge cases
docs/PROMPTS.md Documents new methods with usage examples, quick reference table, and promotion workflow patterns

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Prevents crashes when message hashes use string or other key types
- Ensures robust key conversion with fallback for edge cases
- Maintains consistent string key output regardless of input format
@kxzk kxzk merged commit 7725cf7 into main Dec 18, 2025
10 checks passed
@kxzk kxzk deleted the feature/add-prompt-creation-and-update-methods-to-client-api branch December 18, 2025 21:05
drborges added a commit to drborges/langfuse-ruby that referenced this pull request Jan 14, 2026
…ture/stale-while-revalidate

* 'main' of github.com:simplepractice/langfuse-rb:
  Allow a wider range of faraday versions to increase gem compatibility with older projects (simplepractice#37)
  docs(contributing): update file paths and pr template guidance
  chore(pr-template): standardize heading format for consistency
  chore: add pull request template
  docs(changelog): consolidate unreleased changes into v0.2.0 release
  chore(release): bump version to 0.2.0
  chore: release v0.2.0
  docs(changelog): restructure to reflect incremental releases
  docs(readme): improve visual hierarchy and readability
  docs(readme): improve contribution guidelines presentation
  docs: remove redundant license section from readme
  docs(readme): update gem badge and fix formatting
  Add create and update methods to client API (simplepractice#36)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants