Files
talemate/talemate_frontend/src/components/CharacterMessage.vue
veguAI 39bd02722d 0.25.0 (#100)
* flip title and name in recent scenes

* fix issue where a message could not be regenerated after applying continuity error fixes

* prompt tweaks

* allow json parameters for commands

* autocomplete improvements

* dialogue cleanup fixes

* fix issue with narrate after dialogue and llama3 (and other models that don't have a line break after the user prompt in their prompt template.

* expose ability to auto generate dialogue instructions to wsm character ux

* use b64_json response type

* move tag checks up so they match first

* fix typo

* prompt tweak

* api key support

* prompt tweaks

* editable parameters in prompt debugger / tester

* allow reseting of prompt params

* codemirror for prompt editor

* prompt tweaks

* more prompt debug tool tweaks

* some extra control for `context_history`

* new analytical preset (testing)

* add `join` and `llm_can_be_coerced` to jinja env

* support factual list summaries

* prompt tweaks to continuity check and fix

* new summarization method `facts` exposed to ux

* clamp mistral ai temperature according to their new requirements

* prompt tweaks

* better parsing of fixed dialogue response

* prompt tweaks

* fix intermittent empty meta issue

* history regen status progression and small ux tweaks

* summary entries should always be condensed

* google gemini support

* relock to install google-cloud-aiplatform for vertex ai inference

* fix instruction link

* better error handling of google safety validation and allow disabling of safety validation

* docs

* clarify credentials path requirements

* tweak error line identification

* handle quota limit error

* autocomplete ux wired to assistant plugin instead of command

* autocomplete narrative editing and fixes to autocomplete during dialog edit

* main input autocomplete tweaks

* allow new lines in main input

* 0.25.0 and relock

* fix issue with autocomplete elsewhere locking out main input

* better way to determine remote service

* prompt tweak

* fix rubberbanding issue when editing character attributes

* add open mistral 8x22

* fix continuity error check summary inclusion of target entry

* docs

* default context length to 8192

* linting
2024-05-05 22:16:03 +03:00

180 lines
5.0 KiB
Vue

<template>
<v-alert variant="text" type="info" icon="mdi-chat-outline" elevation="0" density="compact" @mouseover="hovered=true" @mouseleave="hovered=false">
<template v-slot:close>
<v-btn size="x-small" icon @click="deleteMessage">
<v-icon>mdi-close</v-icon>
</v-btn>
</template>
<v-alert-title :style="{ color: color }" class="text-subtitle-1">
{{ character }}
</v-alert-title>
<div class="character-message">
<div class="character-avatar">
<!-- Placeholder for character avatar -->
</div>
<v-textarea
ref="textarea"
v-if="editing"
v-model="editing_text"
auto-grow
:hint="autocompleteInfoMessage(autocompleting) + ', Shift+Enter for newline'"
:loading="autocompleting"
:disabled="autocompleting"
@keydown.enter.prevent="handleEnter"
@blur="autocompleting ? null : cancelEdit()"
@keydown.escape.prevent="cancelEdit()"
>
</v-textarea>
<div v-else class="character-text" @dblclick="startEdit()">
<span v-for="(part, index) in parts" :key="index" :class="{ highlight: part.isNarrative }">
<span>{{ part.text }}</span>
</span>
</div>
</div>
<v-sheet v-if="hovered" rounded="sm" color="transparent">
<v-chip size="x-small" color="indigo-lighten-4" v-if="editing">
<v-icon class="mr-1">mdi-pencil</v-icon>
Editing - Press `enter` to submit. Click anywhere to cancel.</v-chip>
<v-chip size="x-small" color="grey-lighten-1" v-else-if="!editing && hovered" variant="text" class="mr-1">
<v-icon>mdi-pencil</v-icon>
Double-click to edit.</v-chip>
<v-chip size="x-small" label color="success" v-if="!editing && hovered" variant="outlined" @click="createPin(message_id)">
<v-icon class="mr-1">mdi-pin</v-icon>
Create Pin
</v-chip>
<v-chip size="x-small" class="ml-2" label color="primary" v-if="!editing && hovered" variant="outlined" @click="fixMessageContinuityErrors(message_id)">
<v-icon class="mr-1">mdi-call-split</v-icon>
Fix Continuity Errors
</v-chip>
</v-sheet>
<div v-else style="height:24px">
</div>
</v-alert>
</template>
<script>
export default {
props: ['character', 'text', 'color', 'message_id'],
inject: ['requestDeleteMessage', 'getWebsocket', 'createPin', 'fixMessageContinuityErrors', 'autocompleteRequest', 'autocompleteInfoMessage'],
computed: {
parts() {
const parts = [];
let start = 0;
let match;
const regex = /\*(.*?)\*/g;
while ((match = regex.exec(this.text)) !== null) {
if (match.index > start) {
parts.push({ text: this.text.slice(start, match.index), isNarrative: false });
}
parts.push({ text: match[1], isNarrative: true });
start = match.index + match[0].length;
}
if (start < this.text.length) {
parts.push({ text: this.text.slice(start), isNarrative: false });
}
return parts;
}
},
data() {
return {
editing: false,
autocompleting: false,
editing_text: "",
hovered: false,
}
},
methods: {
handleEnter(event) {
// if ctrl -> autocomplete
// else -> submit
// shift -> newline
if (event.ctrlKey) {
this.autocompleteEdit();
} else if (event.shiftKey) {
this.editing_text += "\n";
} else {
this.submitEdit();
}
},
autocompleteEdit() {
this.autocompleting = true;
this.autocompleteRequest(
{
partial: this.editing_text,
context: "dialogue:npc",
character: this.character,
},
(completion) => {
this.editing_text += completion;
this.autocompleting = false;
},
this.$refs.textarea
)
},
cancelEdit() {
console.log('cancelEdit', this.message_id);
this.editing = false;
},
startEdit() {
this.editing_text = this.text;
this.editing = true;
this.$nextTick(() => {
this.$refs.textarea.focus();
});
},
submitEdit() {
console.log('submitEdit', this.message_id, this.editing_text);
this.getWebsocket().send(JSON.stringify({ type: 'edit_message', id: this.message_id, text: this.character+": "+this.editing_text }));
this.editing = false;
},
deleteMessage() {
console.log('deleteMessage', this.message_id);
this.requestDeleteMessage(this.message_id);
},
}
}
</script>
<style scoped>
.highlight {
color: #9FA8DA;
font-style: italic;
margin-left: 2px;
margin-right: 2px;
}
.highlight:before {
--content: "*";
}
.highlight:after {
--content: "*";
}
.character-message {
display: flex;
flex-direction: row;
text-shadow: 2px 2px 4px #000000;
}
.character-name {
font-weight: bold;
margin-right: 10px;
white-space: nowrap;
}
.character-text {
color: #E0E0E0;
}
.character-avatar {
height: 50px;
margin-top: 10px;
}</style>