action_prompt 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aadef0f0c0b9de5ed1dcc33d550137a92b69fcd84b003dbc081d25f9e741e3f4
4
- data.tar.gz: 023eabdc185943d87c587f424b20b71cc425ca8d59b13688ffc54133ef19eca0
3
+ metadata.gz: de8ad6099ba3b0e8ff896d96e8ff8a543a9558d09c129d248b778bbf33ca5b36
4
+ data.tar.gz: b4473d1847ebf29e43c57461f8397281b6ccdb12132673517477a7a424c210da
5
5
  SHA512:
6
- metadata.gz: cfe7c7884e48024e04187aa8a92390994d84300c022fd0f4dc780aa79a01e083f2c79f703a964dcf22be7d81ae26de5d936a741773cc3267a019572d0db99834
7
- data.tar.gz: 7762444c108aaee485b964e90002ad2361db3fb46f38a5dcb08697af38068535f88126bb3d326157f1d87c0b2f41c0fa86499473c929d3d6780ddb4941f6ba11
6
+ metadata.gz: 56349f3e9365bee80336405ae7a04a3d8cee84fe83571c011f4f4fda49bc8048ac257853bd7d205fdbef72edad1275e4cd2960278a6bebd4534c3ffc9643b3d5
7
+ data.tar.gz: 385a20ef932cdf6d45e261b241333c886c1ab39e6feb6b10c265c207f05fe2e7ad350bd30e9c68bd7235d8eb7264ef26288d3cf2e8c501c7ef687b65f04f232d
data/README.md CHANGED
@@ -1,28 +1,61 @@
1
- # ActionPrompt
2
- Short description and motivation.
1
+ # Action Prompt
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ Action Prompt provides a dead simple way to way to organize, preview, and render prompts within a Ruby on Rails App. Because this leverages the `ApplicationController`, you're able to leverage all the bells an whistles
4
+
5
+ This draws heavy inspiration from `ActionMailer::Preview`.
6
+
7
+ > [!IMPORTANT]
8
+ > This gem is a work-in-progress. **It is not production ready** . That said, `ActionPrompt` is under active development. Any and all feedback would be very welcome. Or hey, feel free to open a PR.
9
+
10
+ ## Motivation & Usage
11
+
12
+ As LLMs have become ubiquitous in web applications, we've that prompts intended for Claude or GPT have become scattered throughout our codebase or buried within objects. Often, these prompts were built inline through string manipulation. Our thinking was two-fold, 1) Let's come up with a simple pattern for organizing and rendering these prompts, and 2) Let's make them easy to review.
6
13
 
7
14
  ## Installation
8
- Add this line to your application's Gemfile:
9
15
 
10
- ```ruby
11
- gem "action_prompt"
12
- ```
16
+ Install the gem with `gem "action_prompt"`.
17
+
18
+ ## Organizing & Previewing Prompts
19
+
20
+ 1. Create a template for organizing your prompts located at your `app/prompts`. For example, you might create `app/prompts/hello_world.text.erb` and give it the following content:
21
+
22
+ ```erb
23
+ You are a helpful assistant who replies with, "<%= @message >"
24
+ ```
25
+
26
+ 2. Create a preview class. These live in `test/prompts` and they inherit from `ActionPrompt::Preview`. For example, you might create `tests/prompts/hello_world_preview.rb` and give it the following context:
13
27
 
14
- And then execute:
15
- ```bash
16
- $ bundle
17
- ```
28
+ ```ruby
29
+ class HelloWorldPreview < ActionPrompt::Preview
30
+ def example_prompt
31
+ render "hello_world", locals: {message: "Hello, world!"}
32
+ end
33
+ end
34
+ ```
18
35
 
19
- Or install it yourself as:
20
- ```bash
21
- $ gem install action_prompt
22
- ```
36
+ 3. Next, start up your rails server (`rails s`) and navigate to [http://localhost:3000/action_prompt/previews](http://localhost:3000/action_prompt/previews). You'll see a list of your prompts that resembles the following:
23
37
 
24
- ## Contributing
25
- Contribution directions go here.
38
+ ![Screenshot](docs/assets/images/screenshot.png)
39
+
40
+ You can now preview your prompts.
41
+
42
+ ## Rendering prompts within your app
43
+
44
+ 1. Assume you've followed step one above, and you have a prompt located at `app/prompts/hello_world.text.erb`.
45
+ 2. You can now render this anywhere in your codebase with the following:
46
+
47
+ ```ruby
48
+ ActionPrompt::Renderer.new.render("hello_world", locals: {message: "Now we're cooking"})
49
+ # You are a helpful assistant who replies with, "Now we're cooking"
50
+ ```
51
+
52
+ Under the hood, `ActionPrompt` is leveraging the app's `ApplicationController`. That means you can use the full magic of `ActionView` which includes
53
+
54
+ - Rendering partials.
55
+ - Rendering json with `Jbuilder`
56
+ - Using route helpers, i.e. `posts_url`
57
+ - ...and more!
26
58
 
27
59
  ## License
60
+
28
61
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -13,9 +13,9 @@ class ActionPrompt::PreviewsController < ActionController::Base
13
13
  end
14
14
 
15
15
  def show
16
- preview_class_name = params[:preview_name].camelize + "Preview"
16
+ preview_class_name = params[:preview_slug].camelize + "Preview"
17
17
  @preview_class = ActionPrompt::Preview.find(preview_class_name)
18
- slug = "#{params[:preview_name]}/#{params[:prompt_name]}"
18
+ slug = "#{params[:preview_slug]}/#{params[:prompt_name]}"
19
19
  @prompt = @preview_class.find_prompt(slug)
20
20
  @prompt_output = @preview_class.new.send(params[:prompt_name].to_sym)
21
21
  end
@@ -7,10 +7,10 @@
7
7
  <div class="space-y-4">
8
8
  <% @previews.each do |preview| %>
9
9
  <div>
10
- <h2 class="text-lg font-semibold"><%= preview.preview_name.titleize %></h2>
10
+ <h2 class="text-lg font-semibold"><%= preview.display_name %></h2>
11
11
  <ul>
12
12
  <% preview.prompts.each do |prompt| %>
13
- <li><%= link_to prompt.name, "/action_prompt/previews/#{prompt.slug}", class: "cursor-pointer text-blue-500 underline hover:text-blue-600" %></li>
13
+ <li><%= link_to prompt.name, "/action_prompt/previews/#{prompt.slug}", class: "cursor-pointer underline text-blue-600 hover:text-blue-800" %></li>
14
14
  <% end %>
15
15
  </ul>
16
16
  </div>
@@ -1,8 +1,8 @@
1
1
  <h1 class="text-xl font-semibold">
2
- <%= @preview_class.name %>: <%= @prompt.name %>
2
+ <%= @preview_class.display_name %>: <%= @prompt.name %>
3
3
  </h1>
4
4
  <div class="pb-2">
5
- <%= link_to "<< Back to prompts", "/action_prompt/previews", class: "cursor-pointer text-blue-500 underline hover:text-blue-600 text-sm" %>
5
+ <%= link_to "<< Back to prompts", "/action_prompt/previews", class: "cursor-pointer underline text-blue-600 hover:text-blue-800 text-sm" %>
6
6
  </div>
7
7
  <div class="py-2">
8
8
  <div>
@@ -6,9 +6,9 @@
6
6
  <title><%= @page_title %></title>
7
7
  <script src="https://cdn.tailwindcss.com"></script>
8
8
  </head>
9
- <body class="min-h-screen bg-yellow-100 pt-2">
9
+ <body class="min-h-screen bg-gray-100 pt-4">
10
10
 
11
- <div class="mx-auto w-2/3 bg-white rounded-lg p-8 shadow-lg">
11
+ <div class="mx-auto w-2/3 bg-white rounded-lg p-8 shadow-lg border-2">
12
12
  <%= yield %>
13
13
  </div>
14
14
 
@@ -21,7 +21,11 @@ module ActionPrompt
21
21
  end
22
22
  end
23
23
 
24
- def preview_name
24
+ def display_name
25
+ name.titleize
26
+ end
27
+
28
+ def slug
25
29
  name.delete_suffix("Preview").underscore
26
30
  end
27
31
 
@@ -31,7 +35,7 @@ module ActionPrompt
31
35
 
32
36
  prompt_methods.map do |method_name|
33
37
  Prompt.new(name: method_name.humanize,
34
- slug: "#{preview_name}/#{method_name}")
38
+ slug: "#{slug}/#{method_name}")
35
39
  end
36
40
  end
37
41
 
@@ -44,17 +48,6 @@ module ActionPrompt
44
48
  end
45
49
  end
46
50
 
47
-
48
- class Prompt
49
- attr_reader :name, :slug
50
-
51
- # NOTE: this could probably be a Struct
52
- def initialize(name:, slug:)
53
- @name = name
54
- @slug = slug
55
- end
56
- end
57
-
58
51
  def render(template_name, locals: {})
59
52
  ActionPrompt::Renderer.new.render(template_name, locals: locals)
60
53
  end
@@ -0,0 +1,11 @@
1
+ module ActionPrompt
2
+ class Prompt
3
+ attr_reader :name, :slug
4
+
5
+ # NOTE: this could probably be a Struct
6
+ def initialize(name:, slug:)
7
+ @name = name
8
+ @slug = slug
9
+ end
10
+ end
11
+ end
@@ -2,13 +2,15 @@ require "rails/application_controller"
2
2
 
3
3
  module ActionPrompt
4
4
  class Railtie < Rails::Railtie
5
- config.autoload_paths << Rails.root.join("tests/prompts")
5
+ config.before_configuration do |app|
6
+ app.config.autoload_paths << Rails.root.join("tests/prompts")
7
+ end
6
8
 
7
9
  config.after_initialize do |app|
8
10
  if Rails.env.development? || Rails.env.test?
9
11
  app.routes.prepend do
10
12
  get "/action_prompt/previews", to: "action_prompt/previews#index" # , internal: true
11
- get "/action_prompt/previews/:preview_name/:prompt_name", to: "action_prompt/previews#show" # , internal: true
13
+ get "/action_prompt/previews/:preview_slug/:prompt_name", to: "action_prompt/previews#show" # , internal: true
12
14
  end
13
15
  end
14
16
  end
@@ -1,3 +1,3 @@
1
1
  module ActionPrompt
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/action_prompt.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "action_prompt/version"
2
2
  require "action_prompt/engine"
3
3
  require "action_prompt/railtie"
4
+ require "action_prompt/prompt"
4
5
  require "action_prompt/preview"
5
6
  require "action_prompt/renderer"
6
7
  module ActionPrompt
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_prompt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Arnold
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-13 00:00:00.000000000 Z
11
+ date: 2024-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -43,6 +43,7 @@ files:
43
43
  - lib/action_prompt.rb
44
44
  - lib/action_prompt/engine.rb
45
45
  - lib/action_prompt/preview.rb
46
+ - lib/action_prompt/prompt.rb
46
47
  - lib/action_prompt/railtie.rb
47
48
  - lib/action_prompt/renderer.rb
48
49
  - lib/action_prompt/version.rb
@@ -66,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
67
  - !ruby/object:Gem::Version
67
68
  version: '0'
68
69
  requirements: []
69
- rubygems_version: 3.5.16
70
+ rubygems_version: 3.5.19
70
71
  signing_key:
71
72
  specification_version: 4
72
73
  summary: ActionPrompt is a Rails plugin for managing templated LLM prompts