Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Prompto #173

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
.godot/
script-instances
log
.DS_Store
build/
51 changes: 51 additions & 0 deletions addons/prompto/auth/redirect_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Nunito+Sans:400,400i,700,900&display=swap" rel="stylesheet">
<meta charset="UTF-8">
</head>
<style>
@charset "utf-8";
body {
text-align: center;
padding: 40px 0;
background: #EBF0F5;
}
h1 {
color: #88B04B;
font-family: "Nunito Sans", "Helvetica Neue", sans-serif;
font-weight: 900;
font-size: 40px;
margin-bottom: 10px;
}
p {
color: #404F5E;
font-family: "Nunito Sans", "Helvetica Neue", sans-serif;
font-size:20px;
margin: 0;
}
i {
color: #9ABC66;
font-size: 100px;
line-height: 200px;
margin-left:-15px;
}
.card {
background: white;
padding: 60px;
border-radius: 4px;
box-shadow: 0 2px 3px #C8D0D8;
display: inline-block;
margin: 0 auto;
}
</style>
<body>
<div class="card">
<div style="border-radius:200px; height:200px; width:200px; background: #F8FAF5; margin:0 auto;">
<i class="checkmark">✓</i>
</div>
<h1>Prompto is ready!</h1>
<p>Return to Godot now.</p>
</div>
</body>
</html>
46 changes: 46 additions & 0 deletions addons/prompto/chat/InputField.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@tool
extends TextEdit

# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.

func _gui_input(event):
if self.has_focus() and event is InputEventKey and event.pressed:

# If the user presses shift + enter, we insert a new line
if Input.is_key_pressed(KEY_SHIFT) and event.keycode == KEY_ENTER:
self.insert_text_at_caret("\n")
return

# If the user presses enter, we send the message to the server
if event.keycode == KEY_ENTER:
var prompto_manager = get_node("/root/PromptoManager")
var prompt = self.text.strip_edges()
print("PROMPTO: Sending request to server...")

# We add the sent message to the chat window directly
var rq_message_entry = MessageEntry.new("", "", MessageEntry.MessageRole.USER, prompt)
var request_message_box = await self.owner.add_message(rq_message_entry)
self.text = ""
self.accept_event()

var response = await prompto_manager.create_chat(prompt)
print("PROMPTO: Server respondet")

# Hide the loading animation after the response was received
request_message_box.hide_loading()

# Check if response was successful. If it wasn't, we display the Warning next to the sent message
if (response.status != 200):
request_message_box.display_warning("Error: Server responded with status code \"" +
str(response.status) +"\". See Output for more details")
printerr("PROMPTO: Chat Error! Got ressponse with status " +
str(response.status) + " and body: " + str(response.body))
return

# If the response was successful, we add the response to the chat window
var body = response.body
var res_msg = body['messages'][-1]
var response_message = MessageEntry.new(res_msg['id'], body['history_id'], MessageEntry.MessageRole.ASSISTANT, res_msg['content'])
self.owner.add_message(response_message)
74 changes: 74 additions & 0 deletions addons/prompto/chat/MessageBox.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
@tool
extends MarginContainer

var MESSAGE_REF = preload("res://addons/prompto/chat/message.gd")

var message_entry: MessageEntry:
set(value):
message_entry = value
%Content.text = message_entry.content

# Hide Feedback buttons for own messages
match (message_entry.role):
MessageEntry.MessageRole.ASSISTANT:
set("theme_override_constants/margin_right", get_message_margin())
%Content.get("theme_override_styles/normal").bg_color = get_prompto_manager().get_settings().get_setting("interface/theme/base_color").darkened(.3)
# Add tooltip to response
%Content.tooltip_text = "This is the response generated by Prompto"
MessageEntry.MessageRole.USER:
set("theme_override_constants/margin_left", get_message_margin())
%Content.get("theme_override_styles/normal").bg_color = get_prompto_manager().get_settings().get_setting("interface/theme/accent_color").darkened(.5)
# Hide Feedback buttons for own messages
self.find_child("FeedbackButtons").visible = false
# Display the loading icon for own messages
%Loading.visible = true
# Add tooltip to your own message
%Content.tooltip_text = "This is your message"
_:
assert(false, "Unhandled message role. :-(")

func get_prompto_manager():
return get_node("/root/PromptoManager")

func get_message_margin():
return get_prompto_manager().get_message_margin()

func _ready():
get_prompto_manager().get_settings().settings_changed.connect(_on_settings_changed)
%LikeButton.button_down.connect(_like_message)
%DislikeButton.button_down.connect(_dislike_message)

func _on_settings_changed():
message_entry = message_entry # trigger setter

# Give positive feedback for the given response
func _like_message():
var response = await _send_feedback("positive")
if not response.status == 200: return
%DislikeButton.visible = false
%LikeButton.disabled = true

# Give negative feedback for the given response
func _dislike_message():
var response = await _send_feedback("negative")
if not response.status == 200: return
%LikeButton.visible = false
%DislikeButton.disabled = true

# Send feedback to the server for the given response
func _send_feedback(feedback_type: String):
var prompto_manager = get_node("/root/PromptoManager")
var history_id = message_entry.history_id
var uuid = message_entry.uuid

var response = await prompto_manager.send_feedback(history_id, uuid, feedback_type)
return response

## Display a warning message below the message
func display_warning(message):
%Warning.visible = true
%Warning.tooltip_text = message

## Hide the loading icon
func hide_loading():
%Loading.visible = false
74 changes: 74 additions & 0 deletions addons/prompto/chat/MessageBox.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
[gd_scene load_steps=8 format=3 uid="uid://bqejq4kiap3ey"]

[ext_resource type="Script" path="res://addons/prompto/chat/MessageBox.gd" id="2_0kjv6"]
[ext_resource type="Texture2D" uid="uid://cnayo6p8r03ws" path="res://addons/prompto/icons/warning.svg" id="3_h1fs0"]
[ext_resource type="Texture2D" uid="uid://c0284nril2oac" path="res://addons/prompto/icons/like.svg" id="3_uv5l2"]
[ext_resource type="Texture2D" uid="uid://ceh5ko0t436tl" path="res://addons/prompto/icons/loading.svg" id="4_235sh"]
[ext_resource type="Texture2D" uid="uid://cq2shwvaidqhg" path="res://addons/prompto/icons/dislike.svg" id="4_besp7"]

[sub_resource type="Theme" id="Theme_djkh7"]

[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_js3c0"]
resource_local_to_scene = true
content_margin_left = 12.0
content_margin_top = 12.0
content_margin_right = 12.0
content_margin_bottom = 12.0
bg_color = Color(0.219608, 0.219608, 0.219608, 1)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10

[node name="MarginContainer" type="MarginContainer"]
offset_right = 401.0
offset_bottom = 39.0
script = ExtResource("2_0kjv6")

[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
alignment = 2

[node name="Content" type="RichTextLabel" parent="VBoxContainer"]
unique_name_in_owner = true
clip_contents = false
custom_minimum_size = Vector2(2.08165e-12, 2.08165e-12)
layout_mode = 2
theme = SubResource("Theme_djkh7")
theme_override_styles/normal = SubResource("StyleBoxFlat_js3c0")
text = "This is an example content"
fit_content = true
scroll_following = true
autowrap_mode = 2

[node name="Warning" type="TextureRect" parent="VBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 8
texture = ExtResource("3_h1fs0")
stretch_mode = 2

[node name="Loading" type="TextureRect" parent="VBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 8
texture = ExtResource("4_235sh")
stretch_mode = 2

[node name="FeedbackButtons" type="HBoxContainer" parent="VBoxContainer"]
layout_mode = 2
alignment = 2

[node name="LikeButton" type="Button" parent="VBoxContainer/FeedbackButtons"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "This answer was helpful"
icon = ExtResource("3_uv5l2")

[node name="DislikeButton" type="Button" parent="VBoxContainer/FeedbackButtons"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "This answer was not helpful"
icon = ExtResource("4_besp7")
35 changes: 35 additions & 0 deletions addons/prompto/chat/chat.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@tool
extends MarginContainer

const MESSAGE_ENTRY = preload("res://addons/prompto/chat/message.gd")
const MessageBox = preload("res://addons/prompto/chat/MessageBox.tscn")

# Called when the node enters the scene tree for the first time.
func get_messages():
return %MessageContainer.get_children()

## Add the given message to the chat. Returns the message box.
func add_message(message: MessageEntry):
%PromptoLabel.hide()
var message_box = MessageBox.instantiate()
%MessageContainer.add_child(message_box)
message_box.message_entry = message

# Scroll to end
await get_tree().process_frame
%ScrollableMessageContainer.scroll_vertical = %ScrollableMessageContainer.get_v_scroll_bar().max_value
return message_box

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass

## Reset the chat to its initial state by removing all messages.
func reset():
%PromptoLabel.show()

for n in %MessageContainer.get_children():
%MessageContainer.remove_child(n)
n.queue_free()


Loading