(options: ChatOptions)
| 98 | } |
| 99 | |
| 100 | async chat(options: ChatOptions) { |
| 101 | const visionModel = isVisionModel(options.config.model); |
| 102 | const messages = options.messages.map((v, index) => ({ |
| 103 | // "Messages 中 system 角色必须位于列表的最开始" |
| 104 | role: index !== 0 && v.role === "system" ? "user" : v.role, |
| 105 | content: visionModel ? v.content : getMessageTextContent(v), |
| 106 | })); |
| 107 | |
| 108 | const modelConfig = { |
| 109 | ...useAppConfig.getState().modelConfig, |
| 110 | ...useChatStore.getState().currentSession().mask.modelConfig, |
| 111 | ...{ |
| 112 | model: options.config.model, |
| 113 | }, |
| 114 | }; |
| 115 | |
| 116 | const requestPayload: RequestPayload = capitalizeKeys({ |
| 117 | model: modelConfig.model, |
| 118 | messages, |
| 119 | temperature: modelConfig.temperature, |
| 120 | top_p: modelConfig.top_p, |
| 121 | stream: options.config.stream, |
| 122 | }); |
| 123 | |
| 124 | console.log("[Request] Tencent payload: ", requestPayload); |
| 125 | |
| 126 | const shouldStream = !!options.config.stream; |
| 127 | const controller = new AbortController(); |
| 128 | options.onController?.(controller); |
| 129 | |
| 130 | try { |
| 131 | const chatPath = this.path(); |
| 132 | const chatPayload = { |
| 133 | method: "POST", |
| 134 | body: JSON.stringify(requestPayload), |
| 135 | signal: controller.signal, |
| 136 | headers: getHeaders(), |
| 137 | }; |
| 138 | |
| 139 | // make a fetch request |
| 140 | const requestTimeoutId = setTimeout( |
| 141 | () => controller.abort(), |
| 142 | getTimeoutMSByModel(options.config.model), |
| 143 | ); |
| 144 | |
| 145 | if (shouldStream) { |
| 146 | let responseText = ""; |
| 147 | let remainText = ""; |
| 148 | let finished = false; |
| 149 | let responseRes: Response; |
| 150 | |
| 151 | // animate response to make it looks smooth |
| 152 | function animateResponseText() { |
| 153 | if (finished || controller.signal.aborted) { |
| 154 | responseText += remainText; |
| 155 | console.log("[Response Animation] finished"); |
| 156 | if (responseText?.length === 0) { |
| 157 | options.onError?.(new Error("empty response from server")); |
nothing calls this directly
no test coverage detected