talemate/talemate_frontend/src/components/AppConfig.vue
veguAI 83027b3a0f
0.23.0 (#91)
* dockerfiles and docker-compose

* containerization fixes

* docker instructions

* readme

* readme

* dont mount src by default, readme

* hf template determine fixes

* auto determine prompt template

* script to start talemate listening only to 127.0.0.1

* prompt tweaks

* auto narrate round every 3 rounds

* tweaks

* Add return to startscreen button

* Only show return to start screen button if scene is active

* improvements to character creation

* dedicated property for scene title separate fromn the save directory name

* filter out negations into negative keywords

* increase auto narrate delay

* add character portrait keyword

* summarization should ignore most recent message, as it is often regenerated.

* cohere client

* specify python3

* improve viable runpod text gen detection

* fix formatting in template preview

* cohere command-r plus template that i am not sure if correct or not

* mistral client set to decensor

* fix issue with parsing json responses

* command-r prompts updated

* use official mistralai python client

* send max_tokens

* new input autocomplete functionality

* prompt tweeaks

* llama 3 templates

* add <|eot_id|> to stopping strings

* prompt tweak

* tooltip

* llama-3 identifier

* command-r and command-r plus prompt identifiers

* text-gen-webui client tweaks to make llama3 eos tokens work correctly

* better llama-3 detection

* better llama-3 finalizing of parameters

* streamline client prompt finalizers
reduce YY model smoothing factor from 0.3 to 0.1 for text-generation-webui client

* relock

* linting

* set 0.23.0

* add new gpt-4 models

* set 0.23.0

* add note about conecting to text-gen-webui from docker

* fix openai image generation no longer working

* default to concept_art
2024-04-20 01:01:06 +03:00

367 lines
No EOL
20 KiB
Vue

<template>
<v-dialog v-model="dialog" scrollable max-width="960px">
<v-card v-if="app_config !== null">
<v-card-title><v-icon class="mr-1">mdi-cog</v-icon>Settings</v-card-title>
<v-tabs color="primary" v-model="tab">
<v-tab value="game">
<v-icon start>mdi-gamepad-square</v-icon>
Game
</v-tab>
<v-tab value="application">
<v-icon start>mdi-application</v-icon>
Application
</v-tab>
<v-tab value="creator">
<v-icon start>mdi-palette-outline</v-icon>
Creator
</v-tab>
</v-tabs>
<v-divider></v-divider>
<v-window v-model="tab">
<!-- GAME -->
<v-window-item value="game">
<v-card flat>
<v-card-text>
<v-row>
<v-col cols="4">
<v-tabs v-model="gamePageSelected" color="primary" direction="vertical">
<v-tab v-for="(item, index) in navigation.game" :key="index" :value="item.value">
<v-icon class="mr-1">{{ item.icon }}</v-icon>
{{ item.title }}
</v-tab>
</v-tabs>
</v-col>
<v-col cols="8">
<div v-if="gamePageSelected === 'general'">
<v-alert color="white" variant="text" icon="mdi-cog" density="compact">
<v-alert-title>General</v-alert-title>
<div class="text-grey">
General game settings.
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="12">
<v-checkbox v-model="app_config.game.general.auto_save" label="Auto save" messages="Automatically save after each game-loop"></v-checkbox>
<v-checkbox v-model="app_config.game.general.auto_progress" label="Auto progress" messages="AI automatically progresses after player turn."></v-checkbox>
</v-col>
</v-row>
<v-row>
<v-col cols="6">
<v-text-field v-model="app_config.game.general.max_backscroll" type="number" label="Max backscroll" messages="Maximum number of messages to keep in the scene backscroll"></v-text-field>
</v-col>
</v-row>
</div>
<div v-else-if="gamePageSelected === 'character'">
<v-alert color="white" variant="text" icon="mdi-human-edit" density="compact">
<v-alert-title>Default player character</v-alert-title>
<div class="text-grey">
This will be default player character that will be added to a game if the game does not come with a defined player character. Essentially this is relevant for when you load character-cards that aren't in the talemate scene format.
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="6">
<v-text-field v-model="app_config.game.default_player_character.name"
label="Name"></v-text-field>
</v-col>
<v-col cols="6">
<v-text-field v-model="app_config.game.default_player_character.gender"
label="Gender"></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<v-textarea v-model="app_config.game.default_player_character.description"
auto-grow label="Description"></v-textarea>
</v-col>
</v-row>
</div>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-window-item>
<!-- APPLICATION -->
<v-window-item value="application">
<v-card flat>
<v-card-text>
<v-row>
<v-col cols="4">
<v-list>
<v-list-subheader>Third Party APIs</v-list-subheader>
<v-tabs v-model="applicationPageSelected" color="primary" direction="vertical" density="compact">
<v-tab v-for="(item, index) in navigation.application" :key="index" :value="item.value">
<v-icon class="mr-1">{{ item.icon }}</v-icon>
{{ item.title }}
</v-tab>
</v-tabs>
</v-list>
</v-col>
<v-col cols="8">
<!-- OPENAI API -->
<div v-if="applicationPageSelected === 'openai_api'">
<v-alert color="white" variant="text" icon="mdi-api" density="compact">
<v-alert-title>OpenAI</v-alert-title>
<div class="text-grey">
Configure your OpenAI API key here. You can get one from <a href="https://platform.openai.com/" target="_blank">https://platform.openai.com/</a>
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="12">
<v-text-field type="password" v-model="app_config.openai.api_key"
label="OpenAI API Key"></v-text-field>
</v-col>
</v-row>
</div>
<!-- MISTRAL.AI API -->
<div v-if="applicationPageSelected === 'mistralai_api'">
<v-alert color="white" variant="text" icon="mdi-api" density="compact">
<v-alert-title>mistral.ai</v-alert-title>
<div class="text-grey">
Configure your mistral.ai API key here. You can get one from <a href="https://console.mistral.ai/api-keys/" target="_blank">https://console.mistral.ai/api-keys/</a>
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="12">
<v-text-field type="password" v-model="app_config.mistralai.api_key"
label="mistral.ai API Key"></v-text-field>
</v-col>
</v-row>
</div>
<!-- ANTHROPIC API -->
<div v-if="applicationPageSelected === 'anthropic_api'">
<v-alert color="white" variant="text" icon="mdi-api" density="compact">
<v-alert-title>Anthropic</v-alert-title>
<div class="text-grey">
Configure your Anthropic API key here. You can get one from <a href="https://console.anthropic.com/settings/keys" target="_blank">https://console.anthropic.com/settings/keys</a>
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="12">
<v-text-field type="password" v-model="app_config.anthropic.api_key"
label="Anthropic API Key"></v-text-field>
</v-col>
</v-row>
</div>
<!-- COHERE API -->
<div v-if="applicationPageSelected === 'cohere_api'">
<v-alert color="white" variant="text" icon="mdi-api" density="compact">
<v-alert-title>Cohere</v-alert-title>
<div class="text-grey">
Configure your Cohere API key here. You can get one from <a href="https://dashboard.cohere.com/api-keys" target="_blank">https://dashboard.cohere.com/api-keys</a>
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="12">
<v-text-field type="password" v-model="app_config.cohere.api_key"
label="Cohere API Key"></v-text-field>
</v-col>
</v-row>
</div>
<!-- ELEVENLABS API -->
<div v-if="applicationPageSelected === 'elevenlabs_api'">
<v-alert color="white" variant="text" icon="mdi-api" density="compact">
<v-alert-title>ElevenLabs</v-alert-title>
<div class="text-grey">
<p class="mb-1">Generate realistic speech with the most advanced AI voice model ever.</p>
Configure your ElevenLabs API key here. You can get one from <a href="https://elevenlabs.io/?from=partnerewing2048" target="_blank">https://elevenlabs.io</a> <span class="text-caption">(affiliate link)</span>
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="12">
<v-text-field type="password" v-model="app_config.elevenlabs.api_key"
label="ElevenLabs API Key"></v-text-field>
</v-col>
</v-row>
</div>
<!-- RUNPOD API -->
<div v-if="applicationPageSelected === 'runpod_api'">
<v-alert color="white" variant="text" icon="mdi-api" density="compact">
<v-alert-title>RunPod</v-alert-title>
<div class="text-grey">
<p class="mb-1">Launch a GPU instance in seconds.</p>
Configure your RunPod API key here. You can get one from <a href="https://runpod.io?ref=gma8kdu0" target="_blank">https://runpod.io/</a> <span class="text-caption">(affiliate link)</span>
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="12">
<v-text-field type="password" v-model="app_config.runpod.api_key"
label="RunPod API Key"></v-text-field>
</v-col>
</v-row>
</div>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-window-item>
<!-- CREATOR -->
<v-window-item value="creator">
<v-card flat>
<v-card-text>
<v-row>
<v-col cols="4">
<v-tabs v-model="creatorPageSelected" color="primary" direction="vertical">
<v-tab v-for="(item, index) in navigation.creator" :key="index" :value="item.value">
<v-icon class="mr-1">{{ item.icon }}</v-icon>
{{ item.title }}
</v-tab>
</v-tabs>
</v-col>
<v-col cols="8">
<div v-if="creatorPageSelected === 'content_context'">
<!-- Content for Content context will go here -->
<v-alert color="white" variant="text" icon="mdi-cube-scan" density="compact">
<v-alert-title>Content context</v-alert-title>
<div class="text-grey">
Available content-context choices when generating characters or scenarios. This can strongly influence the content that is generated.
</div>
</v-alert>
<v-divider class="mb-2"></v-divider>
<v-row>
<v-col cols="12">
<v-list density="compact">
<v-list-item v-for="(value, index) in app_config.creator.content_context" :key="index">
<v-list-item-title><v-icon color="red-darken-1" class="mr-2" @click="contentContextRemove(index)">mdi-close-box-outline</v-icon>{{ value }}</v-list-item-title>
</v-list-item>
</v-list>
<v-divider></v-divider>
<v-text-field v-model="content_context_input" label="Add content context (Press enter to add)"
@keyup.enter="app_config.creator.content_context.push(content_context_input); content_context_input = ''"></v-text-field>
</v-col>
</v-row>
</div>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-window-item>
</v-window>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary" text @click="saveConfig" prepend-icon="mdi-check-circle-outline">Save</v-btn>
</v-card-actions>
</v-card>
<v-card v-else>
<v-card-title>
<span class="headline">Configuration</span>
</v-card-title>
<v-card-text>
<v-progress-circular indeterminate="disable-shrink" color="primary" size="20"></v-progress-circular>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: 'AppConfig',
data() {
return {
tab: 'game',
dialog: false,
app_config: null,
content_context_input: '',
navigation: {
game: [
{title: 'General', icon: 'mdi-cog', value: 'general'},
{title: 'Default Character', icon: 'mdi-human-edit', value: 'character'},
],
application: [
{title: 'OpenAI', icon: 'mdi-api', value: 'openai_api'},
{title: 'mistral.ai', icon: 'mdi-api', value: 'mistralai_api'},
{title: 'Anthropic', icon: 'mdi-api', value: 'anthropic_api'},
{title: 'Cohere', icon: 'mdi-api', value: 'cohere_api'},
{title: 'ElevenLabs', icon: 'mdi-api', value: 'elevenlabs_api'},
{title: 'RunPod', icon: 'mdi-api', value: 'runpod_api'},
],
creator: [
{title: 'Content Context', icon: 'mdi-cube-scan', value: 'content_context'},
]
},
gamePageSelected: 'general',
applicationPageSelected: 'openai_api',
creatorPageSelected: 'content_context',
}
},
inject: ['getWebsocket', 'registerMessageHandler', 'setWaitingForInput', 'requestSceneAssets', 'requestAppConfig'],
methods: {
show(tab, page) {
this.requestAppConfig();
this.dialog = true;
if(tab) {
this.tab = tab;
if(page) {
this[tab + 'PageSelected'] = page;
}
}
},
exit() {
this.dialog = false
},
contentContextRemove(index) {
this.app_config.creator.content_context.splice(index, 1);
},
handleMessage(message) {
if (message.type == "app_config") {
this.app_config = message.data;
return;
}
if (message.type == 'config') {
if (message.action == 'save_complete') {
this.exit();
}
}
},
sendRequest(data) {
data.type = 'config';
this.getWebsocket().send(JSON.stringify(data));
},
saveConfig() {
this.sendRequest({
action: 'save',
config: this.app_config,
})
},
},
created() {
this.registerMessageHandler(this.handleMessage);
},
}
</script>
<style scoped></style>