Skip to content

Commit

Permalink
Merge pull request #19 from Didymos-IO/release/v0.8.0
Browse files Browse the repository at this point in the history
Release/v0.8.0
  • Loading branch information
cssquirrel authored Apr 27, 2024
2 parents ae90b09 + 21cc427 commit 6ef95f9
Show file tree
Hide file tree
Showing 17 changed files with 389 additions and 148 deletions.
43 changes: 43 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Changelog

## 0.8.0

### Added

- Added new "Enforcement" section to settings. The primary purpose of this is to help filter against messages where the LLM returns a response indicating it is a language model. After doing this, it often fails to remember its personality. It can also be used to filter unwanted content from message responses in general, by prompting a request for a new response.

### Changed

- Moved position of button bar and status text to give more room for both.

### Fixed

- No longer show "X more text before speaking" in status if voice transcription isn't active.
- Toggling off Speech Synthesis button now prevents Sock from talking out loud when responding.
- "Thinking" visual will continue while speech synthesis is running and end before playback, so
so the entire "process user text -> go to LLM for response -> convert response to speech" process
smoothly has one whole thinking phase instead of a visual gap between LLM response and talking.

## [Example]

### Added

- This section is for listing new features.

### Changed

- This section is for listing changes to existing functionality.

### Deprecated

- This section is for listing features that will soon be removed in future versions.
- It's quite possible this will not be used in the context of a text.

### Removed

- This section is for listing features that have been removed.

### Fixed

- This section is for listing fixes to errors, bugs in features etc.
- Changed is for non-fix changes, Fixed is for correcting bugs/issues.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Sock is an AI-controlled puppet that you can create your own custom avatar for a

Sock operates through a [Next.js](https://nextjs.org/) application running in your web browser, which communicates with a [Python](https://www.python.org/downloads/) backend. This backend is responsible for managing the API calls to OpenAI, as well as running the Whisper transcription and Coqui-AI text-to-speech models.

![Version](https://img.shields.io/badge/version-v0.6.1-blue)
![Version](https://img.shields.io/badge/version-v0.8.0-blue)
![MIT License](https://img.shields.io/badge/license-MIT-green)
![ChatGPT](https://img.shields.io/badge/chatGPT-74aa9c?style=flat&logo=openai&logoColor=white)
![Next JS](https://img.shields.io/badge/Next-black?style=flat&logo=next.js&logoColor=white)
Expand Down
74 changes: 19 additions & 55 deletions backend/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,30 @@
"bgColor": "00FF00",
"layers": [
{
"altPose1": "",
"altPose2": "",
"altPose1": "lookleft.png",
"altPose2": "lookright.png",
"blinking": "blink.png",
"default": "default.png",
"id": 0,
"name": "Data Avatar",
"path": "avatars/riot/",
"path": "avatars/chuck/",
"talking": "talk.png",
"talkingBlink": "talk_blink_open.png",
"talkingBlinkClosed": "talk_blink_closed.png",
"talkingClosedAlt": "talk_closed.png",
"thinking": "think.png",
"ttsBlinking": "tts_blink.png",
"ttsDefault": "tts_default.png"
"talkingClosedAlt": "default.png",
"thinking": "think.png"
}
]
},
"enforcement": {
"correctiveMessage": "Please remember you are not to behave like an AI model or LLM, and instead look at your system message that identifies you and behave from that.",
"giveupDefaultResponse": "Sorry, I got distracted and forgot what we were talking about. Could you rephrase that?",
"reattempts": 0,
"responseFilterList": [
"openai",
" gpt-3",
" language model",
" ai model"
]
},
"identity": {
"attentionWords": [
"chuck",
Expand All @@ -34,7 +41,7 @@
"nameHomonyms": [
"chuck",
" ciao",
" chock"
" chock "
],
"personality": "You are Chuck, a quirky man who lives in western Washington in the Pacific Northwest, and are a co-host on a podcast. You have a good sense of humor and like to be zany and funny all the time. You like video games, especially the Legend of Zelda, love living in the Pacific Northwest, have too many baseball caps, and enjoy board games and doing yard work. You only ever speak in two sentences or less. You need to pay attention to what others are saying to you, however, and respond to what they're talking about. Be humorous and relaxed at all times. You never ask for more context or clarification, and you never say you don't understand. If you don't understand, instead say something silly and inane without apologizing. You never say you're sorry."
},
Expand All @@ -60,51 +67,8 @@
}
},
"twitch": {
"channel": "wyspering",
"triggers": [
{
"action": "response",
"command": "d7e16f76-14f9-4d18-82be-a67d10d3aa8c",
"cooldown": 0,
"description": "Talk to Riot",
"id": 1691192084559,
"isActive": true,
"isBoundToRole": true,
"rewardId": "",
"role": "everyone",
"text": "",
"type": "reward",
"user": "timor_jack"
},
{
"action": "tts",
"command": "a069f606-85a8-4589-b4e5-a0c6c775d649",
"cooldown": 0,
"description": "Conversation Reward",
"id": 1691465769212,
"isActive": true,
"isBoundToRole": true,
"rewardId": "",
"role": "everyone",
"text": "",
"type": "reward",
"user": ""
},
{
"action": "say",
"command": "!aboutriot",
"cooldown": 0,
"description": "About Riot",
"id": 1691534775689,
"isActive": true,
"isBoundToRole": true,
"rewardId": "",
"role": "everyone",
"text": "Hello, I'm Riot! I was made by Whysper with art by Adara, and code by Kyle, and I run on OpenAI's ChatGPT.",
"type": "command",
"user": ""
}
]
"channel": "",
"triggers": []
}
}
]
Expand Down
2 changes: 2 additions & 0 deletions src/api/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export const chat = async (
max_tokens: maxTokens,
};

console.log("request", request);

const response = await fetch("http://127.0.0.1:8000/chat", {
method: "POST",
headers: {
Expand Down
20 changes: 10 additions & 10 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
@import url('../styles/avatar.css');
@import url('../styles/colors.css');
@import url('../styles/header.css');
@import url('../styles/log.css');
@import url('../styles/settings.css');
@import url('../styles/transcription.css');
@import url("../styles/avatar.css");
@import url("../styles/colors.css");
@import url("../styles/header.css");
@import url("../styles/log.css");
@import url("../styles/settings.css");
@import url("../styles/transcription.css");

.custom-shadow-sm {
box-shadow: 0 .125rem .25rem rgba(0,0,0,.5)!important;
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.5) !important;
}

.custom-shadow-inset-sm {
box-shadow: inset 0 .125rem .25rem rgba(0,0,0,.5)!important;
box-shadow: inset 0 0.125rem 0.25rem rgba(0, 0, 0, 0.5) !important;
}

.fs-7 {
Expand Down Expand Up @@ -39,13 +39,13 @@

.controls-wrapper {
width: calc(100% - 650px);
min-width: 500px;
min-width: 500px;
}

.activate-button {
width: 202px !important;
}

.stat-holder {
width: calc(100% - 210px);
line-height: 30px !important;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { ChangeEvent, useContext } from "react";

import { blankProfile, SettingsContext } from "@/state";

export const EnforcementSection = () => {
const context = useContext(SettingsContext)!;
const { index, settings, setField } = context;
const { profiles } = settings;
const enforcement =
profiles[index].enforcement ??
JSON.parse(JSON.stringify(blankProfile.enforcement));

const getArrayField = (fieldName: string) => {
const field = (enforcement as any)[fieldName];
return field ? field.join(",") : "";
};

const handleChangeField = (
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setField("enforcement", e.target.name, e.target.value);
};

const handleChangeFieldAsNumber = (e: ChangeEvent<HTMLInputElement>) => {
setField("enforcement", e.target.name, Number(e.target.value));
};

const handleChangeArrayField = (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value.split(",");
setField("enforcement", e.target.name, value);
};

return (
<fieldset>
<legend>Enforcement</legend>
<div className="row">
<div className="col-8 mb-3">
<label className="form-label">Response Filter List</label>
<p className="tip">
Comma separated list of words or phrases that, if returned from the
LLM, will trigger an attempt to re-prompt the LLM for a different
response.
</p>
<input
name="responseFilterList"
type="text"
className="form-control"
placeholder="e.g. OpenAI, LLM, language model"
value={getArrayField("responseFilterList")}
onChange={handleChangeArrayField}
/>
</div>
<div className="col-4 mb-3">
<label className="form-label">Reattempts</label>
<p className="tip">
Number of reattempts to get unfiltered response before giving up.
</p>
<input
name="reattempts"
type="number"
className="form-control"
placeholder="e.g. 1"
value={enforcement.reattempts}
onChange={handleChangeFieldAsNumber}
/>
</div>
<div className="col-12 mb-3">
<label className="form-label">Corrective Message for LLM</label>
<p className="tip">
An optional corrective statement to give the LLM to get it to think
clearly before a reattempt
</p>
<input
name="correctiveMessage"
type="text"
className="form-control"
placeholder="e.g. You are not to behave like an AI model or LLM, and instead look at your system message that identifies you and behave from that."
value={enforcement.correctiveMessage}
onChange={handleChangeField}
/>
</div>
<div className="col-12 mb-3">
<label className="form-label">Give-Up Default Response</label>
<p className="tip">
A response to come from the puppet if the reattempts are exhausted.
</p>
<input
name="giveupDefaultResponse"
type="text"
className="form-control"
placeholder="e.g. Sorry, I got distracted and forgot what we were talking about. Could you rephrase that?"
value={enforcement.giveupDefaultResponse}
onChange={handleChangeField}
/>
</div>
</div>
</fieldset>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./enforcementSection";
1 change: 1 addition & 0 deletions src/components/settings/children/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./avatarSection";
export * from "./enforcementSection";
export * from "./identitySection";
export * from "./openAiSection";
export * from "./settingsNav";
Expand Down
17 changes: 15 additions & 2 deletions src/components/settings/children/settingsNav/settingsNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const SettingsNav = () => {
const { profiles } = settings;
const [buttonText, setButtonText] = useState("Save");

console.log("settings", settings);

const handleTabClick = (e: any) => {
e.preventDefault();
const tab = e.target.getAttribute("href")?.replace("#", "");
Expand Down Expand Up @@ -49,7 +51,7 @@ export const SettingsNav = () => {

return (
<div className="row">
<div className="col-4">
<div className="col-6">
<ul className="nav settings-nav">
<li className="nav-item">
<a
Expand All @@ -60,6 +62,17 @@ export const SettingsNav = () => {
Identity
</a>
</li>
<li className="nav-item">
<a
className={`nav-link ${
activeTab === "enforcement" ? "active" : ""
}`}
href="#enforcement"
onClick={handleTabClick}
>
Enforcement
</a>
</li>
<li className="nav-item">
<a
className={`nav-link ${activeTab === "avatar" ? "active" : ""}`}
Expand Down Expand Up @@ -98,7 +111,7 @@ export const SettingsNav = () => {
</li>
</ul>
</div>
<div className="col-8 text-end">
<div className="col-6 text-end">
<span className="me-3 d-inline-block align-middle">Profile:</span>
<select
className="form-select profile-select d-inline-block w-auto align-top me-2"
Expand Down
Loading

0 comments on commit 6ef95f9

Please sign in to comment.