改进 聊天

This commit is contained in:
Twilight 2024-08-04 22:48:36 +08:00
parent 2e6aa54154
commit faa846abdc
3 changed files with 462 additions and 68 deletions

View File

@ -181,6 +181,50 @@ definitions:
- name - name
- url - url
type: object type: object
rag-new_internal_schema.ToolDiscoveryInput:
properties:
callback_url:
type: string
description:
type: string
functions:
items:
properties:
description:
type: string
name:
type: string
parameters:
properties:
properties:
properties:
location:
properties:
description:
type: string
type:
type: string
type: object
type: object
type:
type: string
type: object
required:
items:
type: string
type: array
required:
- required
type: object
type: array
homepage_url:
type: string
name:
type: string
required:
- description
- name
type: object
rag-new_internal_schema.ToolDiscoveryOutput: rag-new_internal_schema.ToolDiscoveryOutput:
properties: properties:
callback_url: callback_url:
@ -846,6 +890,70 @@ paths:
summary: Get Tool summary: Get Tool
tags: tags:
- tool - tool
/api/v1/tools/{id}/update:
post:
consumes:
- application/json
description: 如果你的 Tool Discovery 内容改变了,你需要调用此接口更新数据
parameters:
- description: Tool ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/rag-new_internal_schema.ResponseBody'
- properties:
data:
$ref: '#/definitions/rag-new_internal_entity.Tool'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/rag-new_internal_schema.ResponseBody'
"404":
description: Not Found
schema:
$ref: '#/definitions/rag-new_internal_schema.ResponseBody'
security:
- ApiKeyAuth: []
summary: 更新 Tool 的数据
tags:
- tool
/api/v1/tools/syntax:
post:
consumes:
- application/json
description: 如果你的 Tool Discovery 内容改变了,你需要调用此接口更新数据
parameters:
- description: ToolDiscoveryInput
in: body
name: toolDiscoveryInput
required: true
schema:
$ref: '#/definitions/rag-new_internal_schema.ToolDiscoveryInput'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/rag-new_internal_schema.ResponseBody'
"400":
description: Bad Request
schema:
$ref: '#/definitions/rag-new_internal_schema.ResponseBody'
security:
- ApiKeyAuth: []
summary: 校验 Discovery 语法
tags:
- tool
securityDefinitions: securityDefinitions:
ApiKeyAuth: ApiKeyAuth:
in: header in: header

View File

@ -827,6 +827,125 @@ export interface RagNewInternalSchemaToolCreateRequest {
*/ */
'url': string; 'url': string;
} }
/**
*
* @export
* @interface RagNewInternalSchemaToolDiscoveryInput
*/
export interface RagNewInternalSchemaToolDiscoveryInput {
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInput
*/
'callback_url'?: string;
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInput
*/
'description': string;
/**
*
* @type {Array<RagNewInternalSchemaToolDiscoveryInputFunctionsInner>}
* @memberof RagNewInternalSchemaToolDiscoveryInput
*/
'functions'?: Array<RagNewInternalSchemaToolDiscoveryInputFunctionsInner>;
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInput
*/
'homepage_url'?: string;
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInput
*/
'name': string;
}
/**
*
* @export
* @interface RagNewInternalSchemaToolDiscoveryInputFunctionsInner
*/
export interface RagNewInternalSchemaToolDiscoveryInputFunctionsInner {
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInner
*/
'description'?: string;
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInner
*/
'name'?: string;
/**
*
* @type {RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParameters}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInner
*/
'parameters'?: RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParameters;
/**
*
* @type {Array<string>}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInner
*/
'required': Array<string>;
}
/**
*
* @export
* @interface RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParameters
*/
export interface RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParameters {
/**
*
* @type {RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersProperties}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParameters
*/
'properties'?: RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersProperties;
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParameters
*/
'type'?: string;
}
/**
*
* @export
* @interface RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersProperties
*/
export interface RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersProperties {
/**
*
* @type {RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersPropertiesLocation}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersProperties
*/
'location'?: RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersPropertiesLocation;
}
/**
*
* @export
* @interface RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersPropertiesLocation
*/
export interface RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersPropertiesLocation {
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersPropertiesLocation
*/
'description'?: string;
/**
*
* @type {string}
* @memberof RagNewInternalSchemaToolDiscoveryInputFunctionsInnerParametersPropertiesLocation
*/
'type'?: string;
}
/** /**
* *
* @export * @export
@ -2201,6 +2320,43 @@ export const ToolApiAxiosParamCreator = function (configuration?: Configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
* Tool Discovery
* @summary Tool
* @param {number} id Tool ID
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiV1ToolsIdUpdatePost: async (id: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('apiV1ToolsIdUpdatePost', 'id', id)
const localVarPath = `/api/v1/tools/{id}/update`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication ApiKeyAuth required
await setApiKeyToObject(localVarHeaderParameter, "Authorization", configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter); setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
@ -2244,6 +2400,45 @@ export const ToolApiAxiosParamCreator = function (configuration?: Configuration)
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(tool, localVarRequestOptions, configuration) localVarRequestOptions.data = serializeDataIfNeeded(tool, localVarRequestOptions, configuration)
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
* Tool Discovery
* @summary Discovery
* @param {RagNewInternalSchemaToolDiscoveryInput} toolDiscoveryInput ToolDiscoveryInput
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiV1ToolsSyntaxPost: async (toolDiscoveryInput: RagNewInternalSchemaToolDiscoveryInput, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'toolDiscoveryInput' is not null or undefined
assertParamExists('apiV1ToolsSyntaxPost', 'toolDiscoveryInput', toolDiscoveryInput)
const localVarPath = `/api/v1/tools/syntax`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
// authentication ApiKeyAuth required
await setApiKeyToObject(localVarHeaderParameter, "Authorization", configuration)
localVarHeaderParameter['Content-Type'] = 'application/json';
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(toolDiscoveryInput, localVarRequestOptions, configuration)
return { return {
url: toPathString(localVarUrlObj), url: toPathString(localVarUrlObj),
options: localVarRequestOptions, options: localVarRequestOptions,
@ -2297,6 +2492,19 @@ export const ToolApiFp = function(configuration?: Configuration) {
const localVarOperationServerBasePath = operationServerMap['ToolApi.apiV1ToolsIdGet']?.[localVarOperationServerIndex]?.url; const localVarOperationServerBasePath = operationServerMap['ToolApi.apiV1ToolsIdGet']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/**
* Tool Discovery
* @summary Tool
* @param {number} id Tool ID
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiV1ToolsIdUpdatePost(id: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ApiV1ToolsPost200Response>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.apiV1ToolsIdUpdatePost(id, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['ToolApi.apiV1ToolsIdUpdatePost']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
/** /**
* Create tool * Create tool
* @summary Create Tool * @summary Create Tool
@ -2310,6 +2518,19 @@ export const ToolApiFp = function(configuration?: Configuration) {
const localVarOperationServerBasePath = operationServerMap['ToolApi.apiV1ToolsPost']?.[localVarOperationServerIndex]?.url; const localVarOperationServerBasePath = operationServerMap['ToolApi.apiV1ToolsPost']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
}, },
/**
* Tool Discovery
* @summary Discovery
* @param {RagNewInternalSchemaToolDiscoveryInput} toolDiscoveryInput ToolDiscoveryInput
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async apiV1ToolsSyntaxPost(toolDiscoveryInput: RagNewInternalSchemaToolDiscoveryInput, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RagNewInternalSchemaResponseBody>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.apiV1ToolsSyntaxPost(toolDiscoveryInput, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['ToolApi.apiV1ToolsSyntaxPost']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
} }
}; };
@ -2349,6 +2570,16 @@ export const ToolApiFactory = function (configuration?: Configuration, basePath?
apiV1ToolsIdGet(id: number, options?: any): AxiosPromise<ApiV1ToolsPost200Response> { apiV1ToolsIdGet(id: number, options?: any): AxiosPromise<ApiV1ToolsPost200Response> {
return localVarFp.apiV1ToolsIdGet(id, options).then((request) => request(axios, basePath)); return localVarFp.apiV1ToolsIdGet(id, options).then((request) => request(axios, basePath));
}, },
/**
* Tool Discovery
* @summary Tool
* @param {number} id Tool ID
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiV1ToolsIdUpdatePost(id: number, options?: any): AxiosPromise<ApiV1ToolsPost200Response> {
return localVarFp.apiV1ToolsIdUpdatePost(id, options).then((request) => request(axios, basePath));
},
/** /**
* Create tool * Create tool
* @summary Create Tool * @summary Create Tool
@ -2359,6 +2590,16 @@ export const ToolApiFactory = function (configuration?: Configuration, basePath?
apiV1ToolsPost(tool: RagNewInternalSchemaToolCreateRequest, options?: any): AxiosPromise<ApiV1ToolsPost200Response> { apiV1ToolsPost(tool: RagNewInternalSchemaToolCreateRequest, options?: any): AxiosPromise<ApiV1ToolsPost200Response> {
return localVarFp.apiV1ToolsPost(tool, options).then((request) => request(axios, basePath)); return localVarFp.apiV1ToolsPost(tool, options).then((request) => request(axios, basePath));
}, },
/**
* Tool Discovery
* @summary Discovery
* @param {RagNewInternalSchemaToolDiscoveryInput} toolDiscoveryInput ToolDiscoveryInput
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
apiV1ToolsSyntaxPost(toolDiscoveryInput: RagNewInternalSchemaToolDiscoveryInput, options?: any): AxiosPromise<RagNewInternalSchemaResponseBody> {
return localVarFp.apiV1ToolsSyntaxPost(toolDiscoveryInput, options).then((request) => request(axios, basePath));
},
}; };
}; };
@ -2404,6 +2645,18 @@ export class ToolApi extends BaseAPI {
return ToolApiFp(this.configuration).apiV1ToolsIdGet(id, options).then((request) => request(this.axios, this.basePath)); return ToolApiFp(this.configuration).apiV1ToolsIdGet(id, options).then((request) => request(this.axios, this.basePath));
} }
/**
* Tool Discovery
* @summary Tool
* @param {number} id Tool ID
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ToolApi
*/
public apiV1ToolsIdUpdatePost(id: number, options?: RawAxiosRequestConfig) {
return ToolApiFp(this.configuration).apiV1ToolsIdUpdatePost(id, options).then((request) => request(this.axios, this.basePath));
}
/** /**
* Create tool * Create tool
* @summary Create Tool * @summary Create Tool
@ -2415,6 +2668,18 @@ export class ToolApi extends BaseAPI {
public apiV1ToolsPost(tool: RagNewInternalSchemaToolCreateRequest, options?: RawAxiosRequestConfig) { public apiV1ToolsPost(tool: RagNewInternalSchemaToolCreateRequest, options?: RawAxiosRequestConfig) {
return ToolApiFp(this.configuration).apiV1ToolsPost(tool, options).then((request) => request(this.axios, this.basePath)); return ToolApiFp(this.configuration).apiV1ToolsPost(tool, options).then((request) => request(this.axios, this.basePath));
} }
/**
* Tool Discovery
* @summary Discovery
* @param {RagNewInternalSchemaToolDiscoveryInput} toolDiscoveryInput ToolDiscoveryInput
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ToolApi
*/
public apiV1ToolsSyntaxPost(toolDiscoveryInput: RagNewInternalSchemaToolDiscoveryInput, options?: RawAxiosRequestConfig) {
return ToolApiFp(this.configuration).apiV1ToolsSyntaxPost(toolDiscoveryInput, options).then((request) => request(this.axios, this.basePath));
}
} }

View File

@ -2,12 +2,7 @@
<div> <div>
<h3 class="mb-3">聊天记录</h3> <h3 class="mb-3">聊天记录</h3>
<v-card <v-card v-for="message in messages.data" :key="message.id" class="mx-auto mt-3" width="100%">
v-for="message in messages.data"
:key="message.id"
class="mx-auto mt-3"
width="100%"
>
<template #title> <template #title>
<div class="font-weight-black"> <div class="font-weight-black">
<div v-if="message.role == 'assistant'"> AI </div> <div v-if="message.role == 'assistant'"> AI </div>
@ -28,41 +23,41 @@
</v-card> </v-card>
<div class="mt-3"> <div class="mt-3">
<div v-show="toolName != ''"> <div v-if="toolError" class="mb-3">
<v-progress-circular <v-alert density="compact" text="这个工具出现了异常,这应该不是我们的问题,如果你是此工具的开发者,请打开开发者控制台查看具体错误。"
color="primary" :title="'工具 ' + toolName + ' 出现异常'" type="warning"></v-alert>
indeterminate
:size="16"
></v-progress-circular>
{{ toolName }}
</div> </div>
<v-text-field
v-model="input" <div v-show="toolCalling">
label="输入消息" <v-progress-circular color="primary" indeterminate :size="16"></v-progress-circular>
@keyup.enter="sendMessage" 正在执行 {{ toolName }}
></v-text-field> </div>
<v-text-field v-model="input" label="输入消息" @keyup.enter="sendMessage"></v-text-field>
<v-btn color="primary" @click="sendMessage">发送</v-btn> <v-btn color="primary" @click="sendMessage">发送</v-btn>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ApiV1ChatsIdMessagesGet200Response } from "@/api"; import { ApiV1ChatsIdMessagesGet200Response } from "@/api"
import { ref } from "vue"; import { ref } from "vue"
import { api, conf } from "@/plugins/api"; import { api, conf } from "@/plugins/api"
import VueMarkdown from "vue-markdown-render"; import VueMarkdown from "vue-markdown-render"
// @ts-ignore // @ts-ignore
const chatId = parseInt(useRoute().params.id as string); const chatId = parseInt(useRoute().params.id as string)
const messages: Ref<ApiV1ChatsIdMessagesGet200Response> = ref({ const messages: Ref<ApiV1ChatsIdMessagesGet200Response> = ref({
data: [], data: [],
}); })
const input = ref(""); const input = ref("")
const toolName = ref(""); const toolName = ref("")
const toolError = ref(false)
const toolCalling = ref(false)
function sendMessage() { function sendMessage() {
if (input.value !== "") { if (input.value !== "") {
toolError.value = false
api.ChatMessage.apiV1ChatsIdMessagesPost(chatId, { api.ChatMessage.apiV1ChatsIdMessagesPost(chatId, {
message: input.value, message: input.value,
}) })
@ -70,83 +65,109 @@ function sendMessage() {
const newMessage = { const newMessage = {
content: input.value, content: input.value,
role: "user", role: "user",
};
if (messages.value.data == null) {
messages.value.data = [newMessage];
} else {
messages.value.data?.push(newMessage);
} }
const streamId = res.data.data?.stream_id; if (messages.value.data == null) {
messages.value.data = [newMessage]
} else {
messages.value.data?.push(newMessage)
}
const streamId = res.data.data?.stream_id
if (streamId) { if (streamId) {
streamChat(streamId); streamChat(streamId)
} }
}) })
.catch((err) => { .catch((err) => {
// if 409 // if 409
if (err.response.status === 409) { if (err.response.status === 409) {
const streamId = err.response.data.data?.stream_id; const streamId = err.response.data.data?.stream_id
if (streamId) { if (streamId) {
streamChat(streamId); streamChat(streamId)
} }
} }
}); })
} }
} }
function streamChat(streamId: String) { function streamChat(streamId: String) {
const url = conf.basePath + "/api/v1/stream/" + streamId; const url = conf.basePath + "/api/v1/stream/" + streamId
const evtSource = new EventSource(url); const evtSource = new EventSource(url)
let messageAdded = false
//
window.scrollTo(0, document.body.scrollHeight)
// set index
const i = (messages.value.data?.length ?? 1) - 1
evtSource.addEventListener("data", (e) => {
const data = JSON.parse(e.data)
console.log(data.state)
let append = true
switch (data.state) {
case "tool_calling":
toolCalling.value = true
toolName.value = data.tool_call_message.tool_name + " 中的 " + data.tool_call_message.function_name
break
case "tool_response":
setTimeout(() => {
toolName.value = ""
toolCalling.value = false
}, 300)
break
case "tool_failed":
toolName.value = data.tool_response_message.tool_name + " 中的 " + data.tool_response_message.function_name
toolError.value = true
append = false
setTimeout(() => {
toolCalling.value = false
}, 300)
break
case "chunk":
if (!messageAdded) {
const newMessage = { const newMessage = {
content: "", content: "",
role: "assistant", role: "assistant",
}; }
if (messages.value.data == null) { if (messages.value.data == null) {
messages.value.data = [newMessage]; messages.value.data = [newMessage]
} else { } else {
// add to messages // add to messages
messages.value.data?.push(newMessage); messages.value.data?.push(newMessage)
} }
// messageAdded = true
window.scrollTo(0, document.body.scrollHeight); append = true
}
// set index
const i = (messages.value.data?.length ?? 1) - 1;
console.log(i);
evtSource.addEventListener("data", (e) => {
const data = JSON.parse(e.data);
if (data.state === "tool_calling") {
toolName.value = data.tool_call_message.name;
} else if (data.state === "tool_response") {
setTimeout(() => {
toolName.value = "";
}, 300);
} }
if (append && messageAdded) {
// @ts-ignore // @ts-ignore
messages.value.data[i].content += data.content; messages.value.data[i].content += data.content
}); }
})
// close // close
evtSource.addEventListener("close", () => { evtSource.addEventListener("close", () => {
evtSource.close(); evtSource.close()
}); })
} }
const getMessages = () => { const getMessages = () => {
api.ChatMessage.apiV1ChatsIdMessagesGet(chatId).then((res) => { api.ChatMessage.apiV1ChatsIdMessagesGet(chatId).then((res) => {
messages.value = res.data; messages.value = res.data
}); })
}; }
getMessages(); getMessages()
</script> </script>