From 670bb42b86c4b27994366aef2ea00fbfb139a002 Mon Sep 17 00:00:00 2001 From: kladafox Date: Fri, 11 Oct 2024 16:45:40 +0200 Subject: [PATCH] Dynamic Project Root Detection for Prompts --- CHANGELOG.md | 15 ++++++++++++++- Gemfile.lock | 2 +- lib/spectre/prompt.rb | 29 ++++++++++++++++++++++++++++- lib/spectre/version.rb | 2 +- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ca2276..7cfcd94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,7 +70,7 @@ This version enhances the flexibility and robustness of the Completions class, e # Changelog for Version 1.1.1 -**Release Date:** [11th Oct 2024] +**Release Date:** [10th Oct 2024] **New Features:** @@ -81,3 +81,16 @@ This version enhances the flexibility and robustness of the Completions class, e Spectre::Prompt.render(template: 'classification/intent/user', locals: { query: 'What is AI?' }) ``` * This feature allows for better organization and scalability when dealing with multiple prompt categories and complex scenarios. + + +# Changelog for Version 1.1.2 + +**Release Date:** [11th Oct 2024] + +**New Features:** + +* **Dynamic Project Root Detection for Prompts** + * The `Spectre::Prompt.render` method now dynamically detects the project root based on the presence of project-specific markers, such as `Gemfile`, `.git`, or `config/application.rb`. + * This change allows for greater flexibility when using spectre in different environments and projects, ensuring the prompt templates are found regardless of where spectre is used. + * **Example**: If you're using `spectre` inside a gem, the `detect_prompts_path` method will now correctly resolve the prompts path within the gem project root. + * If no markers are found, the system falls back to the current working directory (`Dir.pwd`). \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 0fbae53..7bbcc2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - spectre_ai (1.1.1) + spectre_ai (1.1.2) GEM remote: https://rubygems.org/ diff --git a/lib/spectre/prompt.rb b/lib/spectre/prompt.rb index 41c84f1..3cad922 100644 --- a/lib/spectre/prompt.rb +++ b/lib/spectre/prompt.rb @@ -50,7 +50,34 @@ def render(template:, locals: {}) # Detects the appropriate path for prompt templates def detect_prompts_path - File.join(Dir.pwd, 'app', 'spectre', 'prompts') + # Find the first non-spectre, non-ruby core file in the call stack + calling_file = caller.find do |path| + !path.include?('/spectre/') && !path.include?(RbConfig::CONFIG['rubylibdir']) + end + + # Determine the directory from where spectre was invoked + start_dir = calling_file ? File.dirname(calling_file) : Dir.pwd + + # Traverse up until we find a Gemfile (or another marker of the project root) + project_root = find_project_root(start_dir) + + # Return the prompts path based on the detected project root + File.join(project_root, 'app', 'spectre', 'prompts') + end + + def find_project_root(dir) + while dir != '/' do + # Check for Gemfile, .git directory, or config/application.rb (Rails) + return dir if File.exist?(File.join(dir, 'Gemfile')) || + File.directory?(File.join(dir, '.git')) || + File.exist?(File.join(dir, 'config', 'application.rb')) + + # Move up one directory + dir = File.expand_path('..', dir) + end + + # Default fallback if no root markers are found + Dir.pwd end # Split the template parameter into path and prompt diff --git a/lib/spectre/version.rb b/lib/spectre/version.rb index 1080f68..1fad201 100644 --- a/lib/spectre/version.rb +++ b/lib/spectre/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Spectre # :nodoc:all - VERSION = "1.1.1" + VERSION = "1.1.2" end