Skip to content

Commit

Permalink
Update dependencies and tidy up examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed May 6, 2024
1 parent 0c2917a commit e9e6a59
Show file tree
Hide file tree
Showing 20 changed files with 194 additions and 65 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
/external

/.github/workflows/test-external.yaml
/example/*/*.sqlite3*
90 changes: 55 additions & 35 deletions example/chatbot/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,90 +5,110 @@
# Copyright, 2024, by Samuel Williams.

require 'async/ollama'
require 'markly'
require 'xrb/reference'

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
@conversation ||= Conversation.find_by(id: @data[:conversation_id])
end

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

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

generate = client.generate(prompt) do |response|
self.append(".conversation .messages") do |builder|
self.render_message(builder, conversation_message)
end

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

self.replace(".message.id#{conversation_message.id}") do |builder|
self.render_message(builder, conversation_message)
end
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!
prompt = detail[:value]

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})"
"live.forwardEvent(#{JSON.dump(@id)}, event, {value: event.target.value, key: event.key}); if (event.key == 'Enter') event.target.value = '';"
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)
builder.tag(:div, class: "message id#{message.id}") do
builder.inline_tag(:p, class: "prompt") do
builder.text(message.prompt)
end

builder.inline_tag(:div, class: "response") do
builder.raw(Markly.render_html(message.response))
end
end
end

def render(builder)
builder.tag(:div, class: "conversation") do
conversation.conversation_messages.each do |message|
render_message(builder, message)
builder.tag(:div, class: "messages") do
conversation.conversation_messages.each do |message|
render_message(builder, message)
end
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]
class Application < Lively::Application
def self.resolver
Live::Resolver.allow(ChatbotView)
end

def body(...)
ChatbotView.new(...)
end

def handle(request)
reference = ::XRB::Reference(request.path)

if value = reference.query[:conversation_id]
conversation_id = Integer(value)
else
conversation_id = nil
end

unless conversation_id
reference.query[:conversation_id] = Conversation.create!(model: 'llama3').id

return ::Protocol::HTTP::Response[302, {'location' => reference.to_s}]
else
return super(request, conversation_id: conversation_id)
end
end
end
5 changes: 5 additions & 0 deletions example/chatbot/conversation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Copyright, 2024, by Samuel Williams.

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

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: "conversation.sqlite3")
Expand All @@ -31,4 +32,8 @@ class ConversationMessage < ActiveRecord::Base

class Conversation < ActiveRecord::Base
has_many :conversation_messages

def context
self.conversation_messages.order(created_at: :desc).first&.context
end
end
Binary file removed example/chatbot/conversation.sqlite3
Binary file not shown.
17 changes: 12 additions & 5 deletions example/chatbot/gems.locked
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
PATH
remote: ../../../live
specs:
live (0.8.1)
async-websocket (~> 0.23)
xrb

PATH
remote: ../..
specs:
Expand Down Expand Up @@ -89,11 +96,9 @@ GEM
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)
markly (0.10.0)
mini_portile2 (2.8.6)
minitest (5.22.3)
mutex_m (0.2.0)
Expand Down Expand Up @@ -125,7 +130,7 @@ GEM
traces (0.11.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
xrb (0.6.0)
xrb (0.6.1)

PLATFORMS
ruby
Expand All @@ -134,8 +139,10 @@ PLATFORMS
DEPENDENCIES
activerecord (~> 7.1)
async-ollama
live!
lively!
markly
sqlite3 (~> 1.4)

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

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

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

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
Expand Up @@ -6,3 +6,11 @@
width: 100%;
box-sizing: border-box;
}

.conversation .prompt {
font-weight: bold;
}

.conversation .response {
margin-left: 2rem;
}
Binary file removed example/flappy-bird/highscores.sqlite3
Binary file not shown.
14 changes: 9 additions & 5 deletions lib/lively/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,23 @@ def title
self.class.name
end

def body
HelloWorld.new
def body(...)
HelloWorld.new(...)
end

def index
Pages::Index.new(title: self.title, body: self.body)
def index(...)
Pages::Index.new(title: self.title, body: self.body(...))
end

def handle(request, ...)
return Protocol::HTTP::Response[200, [], [self.index(...).call]]
end

def call(request)
if request.path == '/live'
return Async::WebSocket::Adapters::HTTP.open(request, &self.method(:live)) || Protocol::HTTP::Response[400]
else
return Protocol::HTTP::Response[200, [], [self.index.call]]
return handle(request)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lively.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = ">= 3.1"

spec.add_dependency "falcon", "~> 0.47"
spec.add_dependency "live", "~> 0.8"
spec.add_dependency "live", "~> 0.9"
spec.add_dependency "xrb"
end
6 changes: 3 additions & 3 deletions node_modules/.package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 16 additions & 4 deletions node_modules/@socketry/live/Live.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion node_modules/@socketry/live/package.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions node_modules/@socketry/live/test/Live.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"dependencies": {
"@socketry/live": "^0.12"
"@socketry/live": "^0.13"
},
"scripts": {
"postinstall": "bundle exec bake utopia:node:update"
Expand Down
Loading

0 comments on commit e9e6a59

Please sign in to comment.