You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.1 KiB
132 lines
3.1 KiB
<script setup lang="ts">
|
|
import type { AgentMessage } from "~/composables/useAgentChat";
|
|
|
|
interface ModelOption {
|
|
id: number;
|
|
name: string;
|
|
modelId: string;
|
|
providerName: string;
|
|
}
|
|
|
|
const props = defineProps<{
|
|
messages: AgentMessage[];
|
|
isLoading: boolean;
|
|
loggedIn: boolean;
|
|
modelId: number | null;
|
|
models: ModelOption[];
|
|
enableThinking: boolean;
|
|
enableTools: boolean;
|
|
rateLimitInfo?: {
|
|
sessionRemaining: number | null;
|
|
ipRemaining: number | null;
|
|
};
|
|
sidebarCollapsed: boolean;
|
|
errorMessage: string;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
send: [content: string];
|
|
stop: [];
|
|
"update:modelId": [modelId: number | null];
|
|
"update:enableThinking": [val: boolean];
|
|
"update:enableTools": [val: boolean];
|
|
approve: [toolCallId: string, approved: boolean];
|
|
feedback: [messageId: string, feedback: "like" | "dislike"];
|
|
edit: [messageId: string, content: string];
|
|
regenerate: [];
|
|
toggleSidebar: [];
|
|
showPrompt: [];
|
|
example: [content: string];
|
|
}>();
|
|
|
|
const inputRef = ref<{ setText: (text: string) => void; focus: () => void } | null>(null);
|
|
const showPromptModal = ref(false);
|
|
|
|
function handleExample(content: string) {
|
|
emit("example", content);
|
|
}
|
|
|
|
function handleEdit(messageId: string, content: string) {
|
|
inputRef.value?.setText(content);
|
|
emit("edit", messageId, content);
|
|
}
|
|
|
|
watch(
|
|
() => props.errorMessage,
|
|
(val) => {
|
|
if (val) {
|
|
const { $toast } = useNuxtApp();
|
|
$toast?.error?.(val);
|
|
}
|
|
},
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<div class="agent-chat-area">
|
|
<AgentToolbar
|
|
:model-id="modelId"
|
|
:models="models"
|
|
:enable-thinking="enableThinking"
|
|
:enable-tools="enableTools"
|
|
:logged-in="loggedIn"
|
|
:rate-limit-info="rateLimitInfo"
|
|
@update:model-id="emit('update:modelId', $event)"
|
|
@update:enable-thinking="emit('update:enableThinking', $event)"
|
|
@update:enable-tools="emit('update:enableTools', $event)"
|
|
@show-prompt="showPromptModal = true"
|
|
@toggle-sidebar="emit('toggleSidebar')"
|
|
/>
|
|
|
|
<div class="chat-content">
|
|
<AgentWelcome
|
|
v-if="messages.length === 0"
|
|
:logged-in="loggedIn"
|
|
@example="handleExample"
|
|
/>
|
|
|
|
<AgentMessageList
|
|
v-else
|
|
:messages="messages"
|
|
:is-loading="isLoading"
|
|
:logged-in="loggedIn"
|
|
@approve="(id, approved) => emit('approve', id, approved)"
|
|
@feedback="(id, fb) => emit('feedback', id, fb)"
|
|
@edit="handleEdit"
|
|
@regenerate="emit('regenerate')"
|
|
/>
|
|
</div>
|
|
|
|
<AgentInput
|
|
ref="inputRef"
|
|
:is-loading="isLoading"
|
|
:disabled="rateLimitInfo?.sessionRemaining === 0"
|
|
@send="emit('send', $event)"
|
|
@stop="emit('stop')"
|
|
/>
|
|
|
|
<AgentSystemPromptModal
|
|
:show="showPromptModal"
|
|
system-prompt=""
|
|
@close="showPromptModal = false"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.agent-chat-area {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 0;
|
|
background: var(--color-canvas);
|
|
}
|
|
|
|
.chat-content {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
min-height: 0;
|
|
}
|
|
</style>
|
|
|