feat: supports automatic model setup and fixes rendering issues

This commit is contained in:
Zhang Minghan 2024-03-11 23:35:12 +08:00
parent 82d0f3c4b1
commit 5366fb7307
4 changed files with 37 additions and 5 deletions

View File

@ -2,6 +2,8 @@ import axios from "axios";
import { Model, Plan } from "@/api/types.tsx"; import { Model, Plan } from "@/api/types.tsx";
import { ChargeProps, nonBilling } from "@/admin/charge.ts"; import { ChargeProps, nonBilling } from "@/admin/charge.ts";
import { getErrorMessage } from "@/utils/base.ts"; import { getErrorMessage } from "@/utils/base.ts";
import { getModelName } from "@/routes/admin/Market.tsx";
import { modelImages } from "@/admin/market.ts";
type v1Options = { type v1Options = {
endpoint?: string; endpoint?: string;
@ -88,8 +90,38 @@ export async function getApiMarket(options?: v1Options): Promise<Model[]> {
} }
} }
export async function getFilledApiMarket(
secret?: string,
options?: v1Options,
): Promise<Model[]> {
const data = await getApiMarket(options);
if (data.length > 0) return data;
const resp = await getApiModels(secret, options);
if (!resp.status) return [];
return resp.data.map((id) => ({
id,
default: true,
name: getModelName(id),
tag: [],
avatar: modelImages[0],
description: id,
free: false,
auth: true,
high_context: false,
price: {
type: nonBilling,
anonymous: false,
models: [id],
input: 0,
output: 0,
},
}));
}
export async function bindMarket(options?: v1Options): Promise<Model[]> { export async function bindMarket(options?: v1Options): Promise<Model[]> {
const market = await getApiMarket(options); const market = await getFilledApiMarket(undefined, options);
const charge = await getApiCharge(options); const charge = await getApiCharge(options);
market.forEach((item: Model) => { market.forEach((item: Model) => {

View File

@ -192,11 +192,11 @@ function MarkdownContent({
rehypePlugins={rehypePlugins} rehypePlugins={rehypePlugins}
className={cn("markdown-body", className)} className={cn("markdown-body", className)}
children={children} children={children}
skipHtml={!acceptHtml} skipHtml={acceptHtml}
components={{ components={{
p({ children }) { p({ children }) {
// if the format is `user quota is not enough error (model: gpt-3.5-turbo-1106, minimum quota: 0.01, your quota: -77.77)`, return special component // if the format is `user quota is not enough error (model: gpt-3.5-turbo-1106, minimum quota: 0.01, your quota: -77.77)`, return special component
const match = children const match = (children ?? "")
.toString() .toString()
.match( .match(
/user quota is not enough error \(model: (.*), minimum quota: (.*), your quota: (.*)\)/, /user quota is not enough error \(model: (.*), minimum quota: (.*), your quota: (.*)\)/,

View File

@ -271,7 +271,7 @@ function MessageContent({
</div> </div>
<div className={`message-content`}> <div className={`message-content`}>
{message.content.length ? ( {message.content.length ? (
<Markdown children={message.content} /> <Markdown children={message.content} acceptHtml={false} />
) : message.end === true ? ( ) : message.end === true ? (
<CircleSlash className={`h-5 w-5 m-1`} /> <CircleSlash className={`h-5 w-5 m-1`} />
) : ( ) : (

View File

@ -855,7 +855,7 @@ function MarketAlert({
); );
} }
function getModelName(id: string): string { export function getModelName(id: string): string {
// replace all `-` to ` ` except first `-` keep it // replace all `-` to ` ` except first `-` keep it
let begin = true; let begin = true;