boxcars-station 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 270d11f4510c036858ac090b4c0423b745b3e329c60a3ff0cf7ec16801d1ef13
4
+ data.tar.gz: b4dd7b082a37430a234989cc7eeccdcabd5cb884195dddb8980c2642d295f80b
5
+ SHA512:
6
+ metadata.gz: 392ed337a1838787a246cbdd69c190fa85306677b067eafffd70e845e2c68b509e0cfae6cf99fa7e7f611054ac35abbf674e67e50949eb31ab4ff1804854b77f
7
+ data.tar.gz: 05fe0cdec3319dd01c1e944bd1c95758b655fe4b472179f28f55316a2ece17611f6f1fc833c4b3c60428d9f070a931e6ad31718c80dffa23a10b3f56ea9344d1
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2023 Francis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # Boxcars::Station
2
+ This gem provides an engine for the popular boxcars gem. Once installed to your Rails application, you can navigate to /boxcars/station/chat to do Q&A with ActiveRecord using an LLM for translation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "boxcars-station"
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install boxcars-station
22
+ ```
23
+ ### Configure Permissions and Route
24
+ Note - for security, you should probably mount this only for Admins for now since this is early days and we haven't hardened Boxcars to prevent malicious prompt injection. For example, if you use Adminstrate, you could do the following in the routes file:
25
+ ```ruby
26
+ authenticated :user, ->(u) { u.admin? } do
27
+ mount Boxcars::Station::Engine => "/boxcars/station"
28
+ end
29
+ ```
30
+ ### Initializer
31
+ by default, Boxcars-station is set to read-only, but will consider all models. To limit the scope, create an initializer to configure the settings with something like:
32
+ ```ruby
33
+ Boxcars::Station.configure do |config|
34
+ config.read_only = false # true by default
35
+ config.active_record_models = [Model1, Model2, ...] # limit to only these models instead of all models
36
+ end
37
+ ```
38
+ ## Contributing
39
+ Bug reports and pull requests are welcome on GitHub at https://github.com/BoxcarsAI/boxcars-station. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/BoxcarsAI/boxcars-station/blob/main/CODE_OF_CONDUCT.md).
40
+
41
+ ## License
42
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
43
+
44
+ ## Code of Conduct
45
+
46
+ Everyone interacting in the Boxcars project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/BoxcarsAI/boxcars-station/blob/main/CODE_OF_CONDUCT.md).
47
+
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
9
+
10
+ require "rubocop/rake_task"
11
+
12
+ RuboCop::RakeTask.new
13
+
14
+ task default: %i[test rubocop]
@@ -0,0 +1 @@
1
+ /*! tailwindcss v3.3.0 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:Inter var,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],select,textarea{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,select:focus,textarea:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple]{background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1rem}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E")}[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 16 16' fill='%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=checkbox]:indeterminate,[type=radio]:checked:focus,[type=radio]:checked:hover{background-color:currentColor;border-color:#0000}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}[type=file]{background:unset;border-color:inherit;border-radius:0;border-width:0;font-size:unset;line-height:inherit;padding:0}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.pointer-events-none{pointer-events:none}.absolute{position:absolute}.inset-0{inset:0}.mt-1{margin-top:.25rem}.mt-4{margin-top:1rem}.flex{display:flex}.h-full{height:100%}.w-3\/5{width:60%}.items-center{align-items:center}.justify-center{justify-content:center}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.whitespace-nowrap{white-space:nowrap}.rounded-md{border-radius:.375rem}.bg-indigo-500{--tw-bg-opacity:1;background-color:rgb(99 102 241/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.p-3{padding:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-2\.5{padding-bottom:.625rem;padding-top:.625rem}.py-4{padding-bottom:1rem;padding-top:1rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.pl-10{padding-left:2.5rem}.pl-3{padding-left:.75rem}.text-center{text-align:center}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.shadow{--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.hover\:bg-indigo-400:hover{--tw-bg-opacity:1;background-color:rgb(129 140 248/var(--tw-bg-opacity))}.focus-visible\:outline:focus-visible{outline-style:solid}.focus-visible\:outline-2:focus-visible{outline-width:2px}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\:outline-indigo-500:focus-visible{outline-color:#6366f1}@media (min-width:640px){.sm\:ml-3{margin-left:.75rem}.sm\:mt-0{margin-top:0}.sm\:flex{display:flex}.sm\:items-baseline{align-items:baseline}.sm\:justify-between{justify-content:space-between}.sm\:space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.sm\:rounded-lg{border-radius:.5rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/boxcars/station .css
@@ -0,0 +1,13 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ /*
6
+
7
+ @layer components {
8
+ .btn-primary {
9
+ @apply py-2 px-4 bg-blue-200;
10
+ }
11
+ }
12
+
13
+ */
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,6 @@
1
+ module Boxcars
2
+ module Station
3
+ class ApplicationController < ActionController::Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,28 @@
1
+ require 'boxcars'
2
+ module Boxcars
3
+ module Station
4
+ class ChatController < ApplicationController
5
+ def index
6
+ session[:qa] ||= []
7
+
8
+ if params[:textcommand]
9
+ boxcar_models = Boxcars::Station.configuration.active_record_models
10
+ read_only = Boxcars::Station.configuration.read_only
11
+ ar_boxcar = Boxcars::ActiveRecord.new models: boxcar_models, read_only: read_only
12
+ @question = params[:textcommand]
13
+ @answer = ar_boxcar.run @question
14
+
15
+ @qa = [@question, @answer, Time.now]
16
+ session[:qa] = [@qa] + session[:qa].first(4)
17
+ puts session[:qa]
18
+ end
19
+ @qalist = session[:qa]
20
+
21
+ respond_to do |format|
22
+ format.html
23
+ format.turbo_stream
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,6 @@
1
+ module Boxcars
2
+ module Station
3
+ module ApplicationHelper
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Boxcars
2
+ module Station
3
+ class ApplicationJob < ActiveJob::Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ module Boxcars
2
+ module Station
3
+ class ApplicationMailer < ActionMailer::Base
4
+ default from: "from@example.com"
5
+ layout "mailer"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ module Boxcars
2
+ module Station
3
+ class ApplicationRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+
2
+ <%= turbo_frame_tag "boxcars", target: "_top" do %>
3
+
4
+ <div id="qablock" class="flex items-center justify-center">
5
+ <ul role="list" class="space-y-2 py-4 sm:space-y-4 sm:px-6 lg:px-8 w-3/5">
6
+ <% @qalist.each do |qa| %>
7
+ <li class="bg-white px-4 py-6 shadow sm:rounded-lg sm:px-6">
8
+ <div class="sm:flex sm:items-baseline sm:justify-between">
9
+ <h3 class="text-base font-medium">
10
+
11
+ <span class="text-gray-900">Question:</span>
12
+ <span class="text-gray-600"><%=qa[0]%></span>
13
+
14
+
15
+ </h3>
16
+ <p class="mt-1 whitespace-nowrap text-sm text-gray-600 sm:mt-0 sm:ml-3">
17
+ <time datetime="2021-01-28T19:24"><%= distance_of_time_in_words(Time.now, qa[2])%></time>
18
+ </p>
19
+ </div>
20
+ <div class="mt-4 space-y-6 text-sm text-gray-800">
21
+
22
+ <p> <%= qa[1] %>
23
+
24
+ </p></div>
25
+ </li>
26
+
27
+ <% end %>
28
+ </ul>
29
+ </div>
30
+ <div class="justify-center w-3/5">
31
+
32
+ </div>
33
+ <% end %>
34
+
@@ -0,0 +1,20 @@
1
+ <div class="flex items-center justify-center h-full">
2
+ <%= form_with url: chat_path, data: { turbo_frame: "chat" }, class: "w-3/5 justify-center" do |f| %>
3
+ <div class="flex items-center justify-center h-full">
4
+ <div class="flex absolute inset-0 items-center pl-3 pointer-events-none">
5
+
6
+ </div>
7
+ <%= f.text_field :textcommand, class: "search-input p-3 pl-10 text-sm", placeholder: "Ask BoxCars ..." %>
8
+ </div>
9
+ <div class="flex items-center justify-center h-full">
10
+ <%=f.submit "Submit", :class => "rounded-md bg-indigo-500 px-3.5 py-2.5 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500" %>
11
+ </div>
12
+
13
+
14
+ <% end %>
15
+ </div>
16
+
17
+
18
+ <%= turbo_frame_tag "chat", target: "_top" do %>
19
+ <%= render "result", todo: @qa %>
20
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= turbo_stream.replace"chat" do %>
2
+ <%= render "result", todo: @qa %>
3
+ <% end %>
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Boxcars station</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "boxcars/station/application", media: "all" %>
9
+ <%= stylesheet_link_tag "boxcars/station", "data-turbo-track": "reload" %>
10
+ </head>
11
+ <body>
12
+
13
+ <%= yield %>
14
+
15
+ </body>
16
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Boxcars::Station::Engine.routes.draw do
2
+ match 'chat', to: 'chat#index', via: [:get, :post]
3
+ end
@@ -0,0 +1,23 @@
1
+ const defaultTheme = require('tailwindcss/defaultTheme')
2
+
3
+ module.exports = {
4
+ content: [
5
+ './public/*.html',
6
+ './app/helpers/**/*.rb',
7
+ './app/javascript/**/*.js',
8
+ './app/views/**/*.{erb,haml,html,slim}'
9
+ ],
10
+ theme: {
11
+ extend: {
12
+ fontFamily: {
13
+ sans: ['Inter var', ...defaultTheme.fontFamily.sans],
14
+ },
15
+ },
16
+ },
17
+ plugins: [
18
+ require('@tailwindcss/forms'),
19
+ require('@tailwindcss/aspect-ratio'),
20
+ require('@tailwindcss/typography'),
21
+ require('@tailwindcss/container-queries'),
22
+ ]
23
+ }
@@ -0,0 +1,12 @@
1
+ module Boxcars
2
+ module Station
3
+ class Engine < ::Rails::Engine
4
+ isolate_namespace Boxcars::Station
5
+
6
+ # NOTE: add engine manifest to precompile assets in production, if you don't have this yet.
7
+ initializer "boxcars_station.assets" do |app|
8
+ app.config.assets.precompile += %w[boxcars_station_manifest]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module Boxcars
2
+ module Station
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,30 @@
1
+ require "boxcars/station/version"
2
+ require "boxcars/station/engine"
3
+
4
+ module Boxcars
5
+ module Station
6
+ class Configuration
7
+ attr_accessor :active_record_models, :read_only
8
+
9
+ def initialize
10
+ @active_record_models = ENV.fetch("BOXCAR_ACTIVE_RECORD_MODELS", "").split(",").map(&:strip)
11
+ @active_record_models = nil if @boxcar_active_record_models.empty?
12
+ @read_only = ENV.fetch("BOXCAR_READ_ONLY", "true") == "true"
13
+ end
14
+ end
15
+
16
+ # @return [Boxcars::Station::Configuration] The configuration object.
17
+ class << self
18
+ attr_writer :configuration
19
+ end
20
+
21
+ def self.configuration
22
+ @configuration ||= Boxcars::Station::Configuration.new
23
+ end
24
+
25
+ # Configure the gem.
26
+ def self.configure
27
+ yield(configuration)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ # desc "Explaining what the task does"
2
+ # task :boxcars_station do
3
+ # # Task goes here
4
+ # end
5
+
6
+ # from https://stackoverflow.com/questions/71232601/how-to-use-tailwind-css-gem-in-a-rails-7-engine
7
+ desc "Tailwind build"
8
+ task :tailwind_engine_watch do
9
+ require "tailwindcss-rails"
10
+ # NOTE: tailwindcss-rails is an engine
11
+ system "#{Tailwindcss::Engine.root.join("exe/tailwindcss")} \
12
+ -i #{Boxcars::Station::Engine.root.join("app/assets/stylesheets/application.tailwind.css")} \
13
+ -o #{Boxcars::Station::Engine.root.join("app/assets/builds/station.css")} \
14
+ -c #{Boxcars::Station:Engine.root.join("config/tailwind.config.js")} \
15
+ --minify -w"
16
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: boxcars-station
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Francis Sullivan
8
+ - Tabrez Syed
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2023-04-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: debug
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.1'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: dotenv
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '2.8'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '2.8'
42
+ - !ruby/object:Gem::Dependency
43
+ name: boxcars
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rails
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 7.0.4.3
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 7.0.4.3
70
+ - !ruby/object:Gem::Dependency
71
+ name: tailwindcss-rails
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: turbo-rails
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '1.4'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.4'
98
+ description: You simply add and configure the engine, and you have a new powerful
99
+ tool to get things done.
100
+ email:
101
+ - hi@boxcars.ai
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - MIT-LICENSE
107
+ - README.md
108
+ - Rakefile
109
+ - app/assets/builds/boxcars/station.css
110
+ - app/assets/config/boxcars_station_manifest.js
111
+ - app/assets/stylesheets/application.tailwind.css
112
+ - app/assets/stylesheets/boxcars/station/application.css
113
+ - app/controllers/boxcars/station/application_controller.rb
114
+ - app/controllers/boxcars/station/chat_controller.rb
115
+ - app/helpers/boxcars/station/application_helper.rb
116
+ - app/jobs/boxcars/station/application_job.rb
117
+ - app/mailers/boxcars/station/application_mailer.rb
118
+ - app/models/boxcars/station/application_record.rb
119
+ - app/views/boxcars/station/chat/_result.html.erb
120
+ - app/views/boxcars/station/chat/index.html.erb
121
+ - app/views/boxcars/station/chat/index.turbo_stream.erb
122
+ - app/views/layouts/boxcars/station/application.html.erb
123
+ - config/routes.rb
124
+ - config/tailwind.config.js
125
+ - lib/boxcars/station.rb
126
+ - lib/boxcars/station/engine.rb
127
+ - lib/boxcars/station/version.rb
128
+ - lib/tasks/boxcars/station_tasks.rake
129
+ homepage: https://github.com/BoxcarsAI/boxcars-station
130
+ licenses:
131
+ - MIT
132
+ metadata:
133
+ homepage_uri: https://github.com/BoxcarsAI/boxcars-station
134
+ source_code_uri: https://github.com/BoxcarsAI/boxcars-station
135
+ changelog_uri: https://github.com/BoxcarsAI/boxcars-station/blob/main/CHANGELOG.md
136
+ rubygems_mfa_required: 'true'
137
+ post_install_message:
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: 2.6.0
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubygems_version: 3.2.32
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: Boxcars-station is a Rails engine that uses the boxcars gem for AI composability.
156
+ test_files: []