Skip to content

Commit

Permalink
Several examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed May 6, 2024
1 parent 29ac43c commit 0c2917a
Show file tree
Hide file tree
Showing 35 changed files with 1,693 additions and 214 deletions.
6 changes: 5 additions & 1 deletion bin/lively
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#!/usr/bin/env ruby

require 'async/service'
require_relative '../lib/application'
require_relative '../lib/lively/environment/application'

ARGV.each do |path|
require(path)
end

configuration = Async::Service::Configuration.build do
service "lively" do
Expand Down
94 changes: 94 additions & 0 deletions example/chatbot/application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env lively
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2024, by Samuel Williams.

require 'async/ollama'

require_relative 'conversation'

class ChatbotView < Live::View
def initialize(...)
super

# Defaults:
@data[:prompt] ||= ""
@data[:conversation_id] ||= nil
end

def conversation
@conversation ||= Conversation.create!(model: 'llama3').tap do |conversation|
@data[:conversation_id] = conversation.id
end
end

def update_conversation(prompt)
Console.info(self, "update_conversation", prompt: prompt)

Async::Ollama::Client.open do |client|
conversation_message = conversation.conversation_messages.build(prompt: prompt, response: String.new)

generate = client.generate(prompt) do |response|
response.body.each do |token|
conversation_message.response += token
sleep 0.1
self.update!
end
end

conversation_message.response = generate.response
conversation_message.context = generate.context
conversation_message.save!

self.update!
end
end

def handle(event)
Console.info(self, event)
case event[:type]
when "keypress"
detail = event[:detail]
@data[:prompt] = detail[:value]

if detail[:key] == "Enter"
prompt = @data[:prompt]
@data[:prompt] = ""
self.update!

Async do
update_conversation(prompt)
end

# self.eval('this.getElementBySelector("input.prompt").focus()')
end
end
end

def forward_keypress
"live.forwardEvent(#{JSON.dump(@id)}, event, {value: event.target.value, key: event.key})"
end

def render_message(builder, message)
builder.tag(:p, class: "message") do
builder.text(message.prompt)
end

builder.tag(:p, class: "response") do
builder.text(message.response)
end
end

def render(builder)
builder.tag(:div, class: "conversation") do
conversation.conversation_messages.each do |message|
render_message(builder, message)
end

builder.tag(:input, type: "text", class: "prompt", value: @data[:prompt], onkeypress: forward_keypress, autofocus: true, placeholder: "Type here...")
end
end
end

Application = Lively::Application[ChatbotView]
34 changes: 34 additions & 0 deletions example/chatbot/conversation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env lively
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2024, by Samuel Williams.

require "active_record"
require "console/compatible/logger"

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: "conversation.sqlite3")
ActiveRecord::Base.logger = Console::Compatible::Logger.new(Console)

ActiveRecord::Schema.define do
create_table :conversations, if_not_exists: true do |table|
table.string "model", null: false
table.timestamps
end

create_table :conversation_messages, if_not_exists: true do |table|
table.belongs_to :conversation, null: false, foreign_key: true

table.json :context
table.text :prompt
table.text :response
table.timestamps
end
end

class ConversationMessage < ActiveRecord::Base
end

class Conversation < ActiveRecord::Base
has_many :conversation_messages
end
Binary file added example/chatbot/conversation.sqlite3
Binary file not shown.
141 changes: 141 additions & 0 deletions example/chatbot/gems.locked
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
PATH
remote: ../..
specs:
lively (0.5.0)
falcon (~> 0.47)
live (~> 0.8)
xrb

GEM
remote: https://rubygems.org/
specs:
activemodel (7.1.3.2)
activesupport (= 7.1.3.2)
activerecord (7.1.3.2)
activemodel (= 7.1.3.2)
activesupport (= 7.1.3.2)
timeout (>= 0.4.0)
activesupport (7.1.3.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
async (2.11.0)
console (~> 1.25, >= 1.25.2)
fiber-annotation
io-event (~> 1.5, >= 1.5.1)
timers (~> 4.1)
async-container (0.18.2)
async (~> 2.10)
async-http (0.66.2)
async (>= 2.10.2)
async-pool (>= 0.6.1)
io-endpoint (~> 0.10)
io-stream (~> 0.4)
protocol-http (~> 0.26.0)
protocol-http1 (~> 0.19.0)
protocol-http2 (~> 0.17.0)
traces (>= 0.10.0)
async-http-cache (0.4.3)
async-http (~> 0.56)
async-ollama (0.1.0)
async
async-rest (~> 0.13.0)
async-pool (0.6.1)
async (>= 1.25)
async-rest (0.13.0)
async-http (~> 0.42)
protocol-http (~> 0.7)
async-service (0.12.0)
async
async-container (~> 0.16)
async-websocket (0.26.1)
async-http (~> 0.54)
protocol-rack (~> 0.5)
protocol-websocket (~> 0.11)
base64 (0.2.0)
bigdecimal (3.1.7)
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
console (1.25.2)
fiber-annotation
fiber-local (~> 1.1)
json
drb (2.2.1)
falcon (0.47.1)
async
async-container (~> 0.18)
async-http (~> 0.66, >= 0.66.2)
async-http-cache (~> 0.4.0)
async-service (~> 0.10)
bundler
localhost (~> 1.1)
openssl (~> 3.0)
process-metrics (~> 0.2.0)
protocol-rack (~> 0.5)
samovar (~> 2.3)
fiber-annotation (0.2.0)
fiber-local (1.1.0)
fiber-storage
fiber-storage (0.1.0)
i18n (1.14.4)
concurrent-ruby (~> 1.0)
io-endpoint (0.10.2)
io-event (1.5.1)
io-stream (0.4.0)
json (2.7.2)
live (0.8.0)
async-websocket (~> 0.23)
xrb
localhost (1.3.1)
mapping (1.1.1)
mini_portile2 (2.8.6)
minitest (5.22.3)
mutex_m (0.2.0)
openssl (3.2.0)
process-metrics (0.2.1)
console (~> 1.8)
samovar (~> 2.1)
protocol-hpack (1.4.3)
protocol-http (0.26.5)
protocol-http1 (0.19.1)
protocol-http (~> 0.22)
protocol-http2 (0.17.0)
protocol-hpack (~> 1.4)
protocol-http (~> 0.18)
protocol-rack (0.5.1)
protocol-http (~> 0.23)
rack (>= 1.0)
protocol-websocket (0.12.1)
protocol-http (~> 0.2)
rack (3.0.10)
samovar (2.3.0)
console (~> 1.0)
mapping (~> 1.0)
sqlite3 (1.7.3)
mini_portile2 (~> 2.8.0)
sqlite3 (1.7.3-x86_64-linux)
timeout (0.4.1)
timers (4.3.5)
traces (0.11.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
xrb (0.6.0)

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES
activerecord (~> 7.1)
async-ollama
lively!
sqlite3 (~> 1.4)

BUNDLED WITH
2.5.9
8 changes: 8 additions & 0 deletions example/chatbot/gems.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
source "https://rubygems.org"

gem "lively", path: "../../"

gem "activerecord", "~> 7.1"
gem "sqlite3", "~> 1.4"

gem "async-ollama"
8 changes: 8 additions & 0 deletions example/chatbot/public/_static/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.conversation {
margin: 1rem;
}

.conversation input[type="text"] {
width: 100%;
box-sizing: border-box;
}
Loading

0 comments on commit 0c2917a

Please sign in to comment.