Skip to content

Commit

Permalink
more feature in ai chat
Browse files Browse the repository at this point in the history
  • Loading branch information
orzogc committed Nov 18, 2023
1 parent d4dd0b4 commit 1669282
Show file tree
Hide file tree
Showing 28 changed files with 414 additions and 273 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

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

8 changes: 4 additions & 4 deletions apps/ai_chat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
"@acfunlive-neotool/shared": "link:../../packages/shared",
"@tauri-apps/api": "^1.5.1",
"carbon-components-svelte": "^0.81.3",
"carbon-icons-svelte": "^12.3.1",
"svelte": "^4.2.3",
"carbon-icons-svelte": "^12.4.0",
"svelte": "^4.2.5",
"tauri-plugin-acfunlive-neotool-audio-api": "link:../../plugins/audio",
"tauri-plugin-acfunlive-neotool-base-api": "link:../../plugins/base",
"tauri-plugin-acfunlive-neotool-spark-api": "link:../../plugins/spark",
Expand All @@ -30,10 +30,10 @@
"devDependencies": {
"@rollup/plugin-json": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/node": "^20.9.0",
"@types/node": "^20.9.1",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"rollup": "^4.4.1",
"rollup": "^4.5.0",
"rollup-plugin-scss": "^4.0.0",
"rollup-plugin-svelte": "^7.1.6",
"rollup-plugin-typescript2": "^0.36.0",
Expand Down
100 changes: 76 additions & 24 deletions apps/ai_chat/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,24 @@
ttsKey
} from './scripts/chat';
import { Button, TextArea } from 'carbon-components-svelte';
import { Button, Slider, TextArea } from 'carbon-components-svelte';
import KeyDialog from './components/KeyDialog.svelte';
import Log from './components/Log.svelte';
import './app.css';
import appConfigJson from '../neotool.app.json';
let hasInit = false;
//let hasInit = false;
let openSparkKeyDialog = false;
let sparkKeyDialogKey = {};
let openTtsKeyDialog = false;
let ttsKeyDialogKey = {};
let openLogDialog = false;
let logDialogKey = {};
let cleanups: UnlistenFn[] = [];
Expand All @@ -39,7 +45,8 @@
let liveID: string | undefined;
let danmakuList: ChatContent[] = [];
let contents: ChatContent[] = [];
let danmakuList: string[] = [];
let reply = '';
let replyList: string[] = [];
Expand All @@ -50,26 +57,27 @@
$chatState = ChatState.Idle;
} else {
$chatState = ChatState.Disable;
contents = [];
danmakuList = [];
reply = '';
replyList = [];
audioSourceList = [];
stopAudio().catch((e) => emitError(`failed to stop audio: ${e}`));
}
$: console.log('liveID', liveID);
$: console.log('chatState', $chatState);
$: if (enable && liveID && $chatState === ChatState.Idle && danmakuList.length > 0) {
$: if (enable && liveID && $chatState === ChatState.Idle && contents.length > 0) {
danmakuList = contents.map((content) => content.toContent());
let isChatting = false;
chat(
[...danmakuList],
danmakuList,
(content) => {
if (isChatting) {
reply = reply + content;
} else {
reply = content;
isChatting = true;
if (enable) {
if (isChatting) {
reply = reply + content;
} else {
reply = content;
isChatting = true;
}
}
},
liveID
Expand All @@ -81,7 +89,7 @@
}
})
.catch((e) => emitError(`AI chat error: ${e}`));
danmakuList = [];
contents = [];
}
let isTts = false;
Expand Down Expand Up @@ -135,10 +143,10 @@
'danmaku',
(danmaku) => {
if (enable && danmaku.liverUID === liverUID) {
danmakuList.push(
contents.push(
new ChatContent(danmaku.data.danmuInfo.userInfo.nickname, danmaku.data.content)
);
danmakuList = danmakuList;
contents = contents;
}
},
undefined
Expand All @@ -148,7 +156,7 @@
await request('appData', appConfigJson.id);
await request('liverUID', undefined);
hasInit = true;
//hasInit = true;
} catch (e) {
await emitError(`${appConfigJson.id} init error: ${e}`);
}
Expand All @@ -173,19 +181,57 @@
<div class="text-red-600">请设置讯飞语音</div>
{/if}
<div>
<Button on:click={() => (openSparkKeyDialog = true)}>设置讯飞星火</Button>
<Button on:click={() => (openTtsKeyDialog = true)}>设置讯飞语音</Button>
<Button
on:click={() => {
openSparkKeyDialog = true;
sparkKeyDialogKey = {};
}}>设置讯飞星火</Button
>
<Button
on:click={() => {
openTtsKeyDialog = true;
ttsKeyDialogKey = {};
}}>设置讯飞语音</Button
>
</div>
</div>
<div class="pt-4">
<TextArea labelText="AI人设" bind:value={$chatConfig.characterSet}></TextArea>
<TextArea
labelText="AI人设(越详细越好,但最好不要超过一千字)"
bind:value={$chatConfig.characterSet}
></TextArea>
</div>
<div class="pt-4">
<TextArea readonly labelText="AI回复" bind:value={reply}></TextArea>
<div class="flex flex-col space-y-4 pt-4">
<TextArea readonly labelText="弹幕" rows={2} value={danmakuList.join('\n')}></TextArea>
<TextArea readonly labelText="AI回复" value={reply}></TextArea>
<div class="flex flex-row">
<Slider
hideTextInput
labelText="音量"
value={$chatConfig.volumn * 50}
on:change={(e) => {
const volumn = e.detail;
if (typeof volumn === 'number') {
$chatConfig.volumn = volumn / 50;
}
}}
></Slider>
<!-- <Button on:click={() => (enable = !enable)}>{enable ? '停止AI聊天' : '开始AI聊天'}</Button> -->
<Button
disabled={$chatState !== ChatState.Chatting}
on:click={() => ($chatState = ChatState.Ignore)}>忽略本次生成</Button
>
<Button
on:click={() => {
openLogDialog = true;
logDialogKey = {};
}}>记录</Button
>
</div>
</div>
</div>

{#if hasInit}
{#key sparkKeyDialogKey}
<KeyDialog
bind:isOpen={openSparkKeyDialog}
header="讯飞星火模型"
Expand All @@ -194,7 +240,9 @@
apiKey={$sparkKey?.apiKey}
on:key={(e) => setSparkKey(e.detail)}
></KeyDialog>
{/key}

{#key ttsKeyDialogKey}
<KeyDialog
bind:isOpen={openTtsKeyDialog}
header="讯飞语音"
Expand All @@ -205,4 +253,8 @@
on:key={(e) => setTtsKey(e.detail)}
on:vcn={(e) => ($chatConfig.vcn = e.detail)}
></KeyDialog>
{/if}
{/key}

{#key logDialogKey}
<Log bind:isOpen={openLogDialog}></Log>
{/key}
2 changes: 0 additions & 2 deletions apps/ai_chat/src/components/KeyDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@

<Modal
bind:open={isOpen}
id="hideCloseButton"
preventCloseOnClickOutside
modalHeading={header}
primaryButtonText="确定"
selectorPrimaryFocus="#appIdInput"
Expand Down
27 changes: 27 additions & 0 deletions apps/ai_chat/src/components/Log.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script lang="ts">
import { history } from '../scripts/chat';
import { Modal, TextArea } from 'carbon-components-svelte';
export let isOpen: boolean;
</script>

<Modal
bind:open={isOpen}
modalHeading="记录"
primaryButtonText="关闭"
on:submit={() => (isOpen = false)}
>
<TextArea
rows={8}
value={history
.map((h) => {
if (h.role === 'assistant') {
return 'AI回复:' + h.content;
}

return h.content;
})
.join('\n')}
></TextArea>
</Modal>
23 changes: 16 additions & 7 deletions apps/ai_chat/src/scripts/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ async function saveConfig(config: ChatConfig): Promise<void> {
export async function initConfig(): Promise<Unsubscriber> {
await loadConfig();
let isSavingConfig = false;
const configUnsubscriber = chatConfig.subscribe(() => {
const configUnsubscriber = chatConfig.subscribe((config) => {
if (config.volumn >= 0.0) {
audio?.setVolume(config.volumn);
}

// 延迟2秒保存设置,减少IO
if (!isSavingConfig) {
isSavingConfig = true;
Expand Down Expand Up @@ -181,15 +185,15 @@ function prompt(contents: string[]): string {
const config = get(chatConfig);
const content = contents.join('\n');

return `现在你是一名主播,需要回复观众的弹幕,直接回复你想要说的话即可,不需要带上名字前缀
return `现在你是一名主播,需要回复观众的弹幕,直接回复你想要说的话即可,回复的前面不要带上你的名字
你需要遵循以下的设定:
${config.characterSet}
观众的弹幕:
${content}`;
}

export async function chat(
chatContents: ChatContent[],
contents: string[],
callback: (content: string) => void,
chatId?: string
): Promise<string | undefined> {
Expand All @@ -204,7 +208,6 @@ export async function chat(
historyList = history.slice(history.length - historyNum);
}

const contents = chatContents.map((content) => content.toContent());
let reply = '';

chatState.set(ChatState.Chatting);
Expand All @@ -216,14 +219,14 @@ export async function chat(
content: prompt(contents)
},
(content) => {
if (!(get(chatState) === ChatState.Ignore)) {
if (get(chatState) === ChatState.Chatting) {
reply = reply + content;
callback(content);
}
}
);

if (!(get(chatState) === ChatState.Ignore)) {
if (get(chatState) === ChatState.Chatting) {
history.push(
...contents.map((content): ChatText => {
return { role: 'user', content };
Expand All @@ -236,7 +239,13 @@ export async function chat(

return;
} finally {
chatState.set(ChatState.Idle);
chatState.update((state) => {
if (state === ChatState.Disable) {
return state;
} else {
return ChatState.Idle;
}
});
}
} else {
throw new Error('no spark key');
Expand Down
6 changes: 3 additions & 3 deletions apps/danmaku_keyboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@
"dependencies": {
"@acfunlive-neotool/shared": "link:../../packages/shared",
"@tauri-apps/api": "^1.5.1",
"svelte": "^4.2.3",
"svelte": "^4.2.5",
"tauri-plugin-acfunlive-neotool-keyboard-api": "link:../../plugins/keyboard"
},
"devDependencies": {
"@rollup/plugin-json": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@types/node": "^20.9.0",
"@types/node": "^20.9.1",
"autoprefixer": "^10.4.16",
"daisyui": "^3.9.4",
"postcss": "^8.4.31",
"rollup": "^4.4.1",
"rollup": "^4.5.0",
"rollup-plugin-scss": "^4.0.0",
"rollup-plugin-svelte": "^7.1.6",
"rollup-plugin-typescript2": "^0.36.0",
Expand Down
3 changes: 2 additions & 1 deletion apps/danmaku_keyboard/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
</script>

<div class="flex flex-col content-between p-5 space-y-5">
<div>说明:弹幕文字前面需要添加 @ 符号来触发</div>
<div>说明:弹幕文字前面需要添加对应的前缀来触发</div>

{#if config}
<div class="flex flex-row space-x-3">
Expand All @@ -102,6 +102,7 @@
<thead>
<tr>
<th></th>
<th class="text-base">触发弹幕前缀</th>
<th class="text-base">触发弹幕</th>
<th class="text-base">触发按键</th>
<th class="text-base">按键时长(毫秒)</th>
Expand Down
Loading

0 comments on commit 1669282

Please sign in to comment.