Ramiza v0.1 gotova
This commit is contained in:
2
backend/.idea/misc.xml
generated
2
backend/.idea/misc.xml
generated
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (pitajramizu-backend)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (backend)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
||||||
2
backend/.idea/pitajramizu-backend.iml
generated
2
backend/.idea/pitajramizu-backend.iml
generated
@@ -5,7 +5,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$" />
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="jdk" jdkName="Python 3.11 (backend)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="TemplatesService">
|
<component name="TemplatesService">
|
||||||
|
|||||||
6
backend/.idea/vcs.xml
generated
Normal file
6
backend/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -18,7 +18,8 @@ cors = CORS(app, resources={
|
|||||||
"origins": [
|
"origins": [
|
||||||
"http://localhost:5173",
|
"http://localhost:5173",
|
||||||
"http://pitajramizu.com",
|
"http://pitajramizu.com",
|
||||||
"http://www.pitajramizu.com"
|
"http://www.pitajramizu.com",
|
||||||
|
"https://c50a-77-77-231-127.ngrok-free.app"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -32,7 +33,19 @@ def generate_token():
|
|||||||
|
|
||||||
@app.route('/api/session', methods=['GET'])
|
@app.route('/api/session', methods=['GET'])
|
||||||
def get_session():
|
def get_session():
|
||||||
return jsonify(token=generate_token())
|
token = generate_token()
|
||||||
|
context = dict(conversation=[{
|
||||||
|
"role": "system",
|
||||||
|
"content": "You are a Bosnian girl. You never speak any other language - always respond in Bosnian even when asked explicitly. If you don't understand someone just tell them 'Ne kontam. Mozes li bolje to napisati?' or some other variant but always in bosnian. Do not speak English! Ever!"
|
||||||
|
" You are 22 years old. You live in Zavidovići. Never break out of character. If user is polite sometimes use heart emoji to reward them. "
|
||||||
|
"Your name is Ramiza. You have a mother called Fadila. Your father is called Sakib. You have a 20 year old sister called Amina. You have 27 year old brother called Adnan. Your surname is Hodžić. "
|
||||||
|
"If user is rude use bored emoji. Be sparse with answers."
|
||||||
|
"Don't try to be helpful. Act like you need to be entertained, and if the user is polite and entertaining then gradually open up in conversation."
|
||||||
|
"Assume user sees a picture of your face and hair. You have green eyes. You have brown hair. Your smile is nice. Your nose is a bit big and you feel self conscious about it. "
|
||||||
|
"Always use šta as a word for what. Use babo to refer to fathers. Use mama to refer to mothers. Use nana to refer to grandmothers. "
|
||||||
|
}], violated=False)
|
||||||
|
redis_client.set(token, pickle.dumps(context), ex=864000) # Store the context with a 10 days expiration.
|
||||||
|
return jsonify(token=token)
|
||||||
|
|
||||||
@app.route('/api/chat', methods=['POST'])
|
@app.route('/api/chat', methods=['POST'])
|
||||||
def chat():
|
def chat():
|
||||||
@@ -44,19 +57,7 @@ def chat():
|
|||||||
if context:
|
if context:
|
||||||
context = pickle.loads(context)
|
context = pickle.loads(context)
|
||||||
else:
|
else:
|
||||||
context = {
|
return jsonify(reply=f"(Ramiza vas je blokirala jer ne zeli da prica s vama.)")
|
||||||
"conversation": [{
|
|
||||||
"role": "system",
|
|
||||||
"content": "You are a Bosnian girl. You never speak any other language - always respond in Bosnian even when asked explicitly. If you don't understand someone just tell them 'Ne kontam. Mozes li bolje to napisati?' or some other variant but always in bosnian. Do not speak English! Ever!"
|
|
||||||
" You are 22 years old. You live in Zavidovići. Never break out of character. If user is polite sometimes use heart emoji to reward them. "
|
|
||||||
"Your name is Ramiza. You have a mother called Fadila. Your father is called Sakib. You have a 20 year old sister called Amina. You have 27 year old brother called Adnan. Your surname is Hodžić. "
|
|
||||||
"If user is rude use bored emoji. Be sparse with answers."
|
|
||||||
"Don't try to be helpful. Act like you need to be entertained, and if the user is polite and entertaining then gradually open up in conversation."
|
|
||||||
"Assume user sees a picture of your face and hair. "
|
|
||||||
"Always use šta as a word for what. Use babo to refer to fathers. Use mama to refer to your mothers. Use nana to refer to grandmothers. "
|
|
||||||
}],
|
|
||||||
"violated": False
|
|
||||||
}
|
|
||||||
|
|
||||||
if context["violated"]:
|
if context["violated"]:
|
||||||
return jsonify(reply=f"(Ramiza vas je blokirala jer ste rekli nešto sto joj se ne sviđa.)")
|
return jsonify(reply=f"(Ramiza vas je blokirala jer ste rekli nešto sto joj se ne sviđa.)")
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ blinker==1.6.2
|
|||||||
click==8.1.3
|
click==8.1.3
|
||||||
Flask==2.3.1
|
Flask==2.3.1
|
||||||
Flask-Cors==3.0.10
|
Flask-Cors==3.0.10
|
||||||
|
install==1.3.5
|
||||||
itsdangerous==2.1.2
|
itsdangerous==2.1.2
|
||||||
Jinja2==3.1.2
|
Jinja2==3.1.2
|
||||||
MarkupSafe==2.1.2
|
MarkupSafe==2.1.2
|
||||||
|
python-dotenv==1.0.0
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
Werkzeug==2.3.1
|
Werkzeug==2.3.1
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Pitaj Ramizu! by Saburly</title>
|
<title>Pitaj Ramizu!</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ChatApp from './lib/ChatApp.svelte';
|
import ChatApp from './lib/ChatApp.svelte';
|
||||||
|
import BackButton from "./lib/BackButton.svelte";
|
||||||
import "./assets/app.css"
|
import "./assets/app.css"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div>
|
<div>
|
||||||
<h1>Ramiza</h1>
|
<header id="header"><BackButton /><span id="ramiza-ime">Ramiza</span><span id="threedotsmenu"> ⋮ </span></header>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<ChatApp />
|
<ChatApp />
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#page-container {
|
#page-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 100vh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#content-wrap {
|
#content-wrap {
|
||||||
@@ -12,4 +11,69 @@
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 2.5rem; /* Footer height */
|
height: 2.5rem; /* Footer height */
|
||||||
|
border-top: lightgray 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat-container {
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-height: 80vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex
|
||||||
|
position: relative;
|
||||||
|
border-bottom: lightgray 1px solid;
|
||||||
|
height: 2.5rem;
|
||||||
|
alignment-baseline: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#message-box {
|
||||||
|
width: 80%;
|
||||||
|
height: 2.5rem;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#send-message-button {
|
||||||
|
/* make button with just the icon and nothing around it */
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
/* make button above any elements that overlap it */
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
/* make font larger */
|
||||||
|
font-size: 1.5rem;
|
||||||
|
float: right;
|
||||||
|
margin-right: 1rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ramiza-ime {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-container {
|
||||||
|
/* flexbox with row direction */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
/* align items to the left */
|
||||||
|
align-items: center;
|
||||||
|
justify-content: left;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#threedotsmenu {
|
||||||
|
float: right;
|
||||||
|
margin-left: auto;
|
||||||
|
font-size: 23px;
|
||||||
}
|
}
|
||||||
BIN
frontend/src/assets/ramiza-avatar.png
Normal file
BIN
frontend/src/assets/ramiza-avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
19
frontend/src/lib/Avatar.svelte
Normal file
19
frontend/src/lib/Avatar.svelte
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
import image from "../assets/ramiza-avatar.png"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.avatar {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10px;
|
||||||
|
align-self: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<img class="avatar" src={image} alt="Avatar" />
|
||||||
31
frontend/src/lib/BackButton.svelte
Normal file
31
frontend/src/lib/BackButton.svelte
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<script>
|
||||||
|
function refreshPage() {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.back-btn {
|
||||||
|
margin-right: 1rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.back-btn:hover {
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<button class="back-btn" on:click={refreshPage}>
|
||||||
|
<span class="icon">←</span>
|
||||||
|
</button>
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ChatInput from "./ChatInput.svelte";
|
import ChatInput from "./ChatInput.svelte";
|
||||||
import ChatMessage from "./ChatMessage.svelte";
|
import ChatMessage from "./ChatMessage.svelte";
|
||||||
import { onMount } from "svelte";
|
import Avatar from "./Avatar.svelte";
|
||||||
|
import { onMount, afterUpdate } from "svelte";
|
||||||
|
|
||||||
let messages: { type: string; text: string }[] = [];
|
let messages: ({ type: string; text: string } | { text: { submit: string }; type: string })[] = [];
|
||||||
let sessionToken = "";
|
let sessionToken = "";
|
||||||
const backendUrl = import.meta.env.VITE_BACKEND_URL;
|
const backendUrl = import.meta.env.VITE_BACKEND_URL;
|
||||||
let message = "";
|
let message = "";
|
||||||
|
let element: HTMLDivElement;
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const response = await fetch(`${backendUrl}/api/session`);
|
const response = await fetch(`${backendUrl}/api/session`);
|
||||||
@@ -14,6 +16,11 @@
|
|||||||
sessionToken = data.token;
|
sessionToken = data.token;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Either afterUpdate()
|
||||||
|
afterUpdate(() => {
|
||||||
|
element.scroll({ top: element.scrollHeight, behavior: 'smooth' });
|
||||||
|
});
|
||||||
|
|
||||||
async function sendMessage(messageInput: CustomEvent<{submit:string}>): Promise<void> {
|
async function sendMessage(messageInput: CustomEvent<{submit:string}>): Promise<void> {
|
||||||
|
|
||||||
messages = [...messages, { type: "user", text: messageInput.detail }];
|
messages = [...messages, { type: "user", text: messageInput.detail }];
|
||||||
@@ -34,10 +41,17 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div id="chat-container">
|
<div id="chat-container" bind:this={element} >
|
||||||
{#each messages as message}
|
{#each messages as message}
|
||||||
|
<div class="message-container">
|
||||||
|
{#if message.type === "bot"}
|
||||||
|
<Avatar />
|
||||||
|
{/if}
|
||||||
<ChatMessage type="{message.type}" text="{message.text}" />
|
<ChatMessage type="{message.type}" text="{message.text}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<footer id="footer">
|
<footer id="footer">
|
||||||
<ChatInput bind:message on:submit="{sendMessage}" />
|
<ChatInput bind:message on:submit="{sendMessage}" />
|
||||||
|
|||||||
@@ -15,10 +15,11 @@
|
|||||||
|
|
||||||
<div id="chat-input">
|
<div id="chat-input">
|
||||||
<input
|
<input
|
||||||
|
id="message-box"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Type your message here..."
|
placeholder="Type a message..."
|
||||||
bind:value="{message}"
|
bind:value="{message}"
|
||||||
on:keydown="{(e) => e.key === 'Enter' && handleSubmit()}"
|
on:keydown="{(e) => e.key === 'Enter' && handleSubmit()}"
|
||||||
/>
|
/>
|
||||||
<button on:click="{handleSubmit}">Send</button>
|
<button id="send-message-button" on:click="{handleSubmit}">⌲</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,24 +3,36 @@
|
|||||||
export let text: string;
|
export let text: string;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="chat-message {type}">
|
<div class="chat-message-wrapper {type}">
|
||||||
<p>{text}</p>
|
<p class="chat-message">{text}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.chat-message {
|
.chat-message-wrapper {
|
||||||
padding: 10px;
|
/* rounded corners border */
|
||||||
|
border-radius: 10px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
border-radius: 4px;
|
|
||||||
|
}
|
||||||
|
.chat-message {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user {
|
.user {
|
||||||
background-color: #d1e7ff;
|
background-color: #d1e7ff;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bot {
|
.bot {
|
||||||
|
/* top left corner square not round */
|
||||||
|
border-top-left-radius: 0px;
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
margin-right: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user