chore: show llm code with common component

main
jialin 8 months ago
parent 61e506010c
commit ca99db5a97

@ -27,7 +27,7 @@ const TableRow: React.FC<
rowIndex,
expandable,
rowSelection,
expandedRowKeys,
expandedRowKeys = [],
rowKey,
childParentKey,
columns,
@ -80,6 +80,12 @@ const TableRow: React.FC<
return rowSelection?.selectedRowKeys?.includes(record[rowKey]);
}, [rowSelection?.selectedRowKeys, record, rowKey]);
useEffect(() => {
if (expandedRowKeys?.length === 0) {
setCurrentExpand(false);
}
}, [expandedRowKeys.length]);
const renderChildrenData = () => {
if (childrenData.length === 0) {
// return (

@ -9,11 +9,8 @@ import React, {
useRef,
useState
} from 'react';
import {
OpenAIViewCode,
Roles,
generateMessagesByListContent
} from '../config';
import { CHAT_API } from '../apis';
import { Roles, generateMessagesByListContent } from '../config';
import { ChatParamsConfig } from '../config/params-config';
import { MessageItem, MessageItemAction } from '../config/types';
import { LLM_METAKEYS, llmInitialValues } from '../hooks/config';
@ -21,12 +18,13 @@ import useChatCompletion from '../hooks/use-chat-completion';
import { useInitLLmMeta } from '../hooks/use-init-meta';
import '../style/ground-left.less';
import '../style/system-message-wrap.less';
import { generateLLMCode } from '../view-code/llm';
import DynamicParams from './dynamic-params';
import MessageInput from './message-input';
import MessageContent from './multiple-chat/message-content';
import SystemMessage from './multiple-chat/system-message';
import ReferenceParams from './reference-params';
import ViewCodeModal from './view-code-modal';
import ViewCommonCode from './view-common-code';
interface MessageProps {
modelList: Global.BaseOption<string>[];
@ -89,13 +87,19 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
};
});
const viewCodeMessage = useMemo(() => {
const viewCodeContent = useMemo(() => {
const resultList = systemMessage
? [{ role: Roles.System, content: systemMessage }]
: [];
const list = generateMessagesByListContent([...messageList]);
return [...resultList, ...list];
}, [messageList, systemMessage]);
return generateLLMCode({
api: CHAT_API,
parameters: {
...parameters,
messages: [...resultList, ...list]
}
});
}, [messageList, systemMessage, parameters]);
const handleSendMessage = (message: Omit<MessageItem, 'uid'>) => {
const currentMessage =
@ -189,17 +193,11 @@ const GroundLeft: React.FC<MessageProps> = forwardRef((props, ref) => {
/>
</div>
</div>
<ViewCodeModal
{...OpenAIViewCode.chat}
<ViewCommonCode
open={show}
payload={{
messages: viewCodeMessage
}}
parameters={parameters}
viewCodeContent={viewCodeContent}
onCancel={handleCloseViewCode}
title={intl.formatMessage({ id: 'playground.viewcode' })}
></ViewCodeModal>
></ViewCommonCode>
</div>
);
});

@ -22,11 +22,8 @@ import React, {
useState
} from 'react';
import 'simplebar-react/dist/simplebar.min.css';
import {
OpenAIViewCode,
Roles,
generateMessagesByListContent
} from '../../config';
import { CHAT_API } from '../../apis';
import { Roles, generateMessagesByListContent } from '../../config';
import CompareContext from '../../config/compare-context';
import { ChatParamsConfig } from '../../config/params-config';
import { MessageItem, ModelSelectionItem } from '../../config/types';
@ -34,9 +31,10 @@ import { LLM_METAKEYS, llmInitialValues } from '../../hooks/config';
import useChatCompletion from '../../hooks/use-chat-completion';
import { useInitLLmMeta } from '../../hooks/use-init-meta';
import '../../style/model-item.less';
import { generateLLMCode } from '../../view-code/llm';
import DynamicParams from '../dynamic-params';
import ReferenceParams from '../reference-params';
import ViewCodeModal from '../view-code-modal';
import ViewCommonCode from '../view-common-code';
import MessageContent from './message-content';
import SystemMessage from './system-message';
@ -92,13 +90,20 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
loading
} = useChatCompletion(scroller);
const viewCodeMessage = useMemo(() => {
const viewCodeContent = useMemo(() => {
const resultList = systemMessage
? [{ role: Roles.System, content: systemMessage }]
: [];
const list = generateMessagesByListContent([...messageList]);
return [...resultList, ...list];
}, [messageList, systemMessage]);
return generateLLMCode({
api: CHAT_API,
parameters: {
...parameters,
messages: [...resultList, ...list]
}
});
}, [messageList, systemMessage, parameters]);
const abortFetch = () => {
handleStopConversation();
@ -338,16 +343,11 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef((props, ref) => {
<Spin spinning={loading} size="small" style={{ width: '100%' }} />
</div>
</div>
<ViewCodeModal
{...OpenAIViewCode.chat}
<ViewCommonCode
open={show}
payload={{
messages: viewCodeMessage
}}
parameters={parameters}
viewCodeContent={viewCodeContent}
onCancel={handleCloseViewCode}
title={intl.formatMessage({ id: 'playground.viewcode' })}
></ViewCodeModal>
></ViewCommonCode>
</div>
);
});

@ -1,197 +0,0 @@
import EditorWrap from '@/components/editor-wrap';
import HighlightCode from '@/components/highlight-code';
import { BulbOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Modal } from 'antd';
import _ from 'lodash';
import React, { useMemo, useState } from 'react';
import { GPUSTACK_API } from '../apis';
type ViewModalProps = {
systemMessage?: string;
messageList?: any[];
payload: Record<string, any>;
parameters: any;
title: string;
api: string;
clientType: string;
logcommand?: string;
open: boolean;
onCancel: () => void;
};
const langMap = {
shell: 'bash',
python: 'python',
javascript: 'javascript'
};
const langOptions = [
{ label: 'Curl', value: langMap.shell },
{ label: 'Python', value: langMap.python },
{ label: 'Nodejs', value: langMap.javascript }
];
const ViewCodeModal: React.FC<ViewModalProps> = (props) => {
const {
title,
open,
api,
clientType,
logcommand,
onCancel,
payload,
parameters = {}
} = props || {};
const intl = useIntl();
const [lang, setLang] = useState(langMap.shell);
const BaseURL = `${window.location.origin}/${GPUSTACK_API}`;
const formatPyParams = (params: any) => {
return _.keys(params).reduce((acc: string, key: string) => {
if (params[key] === null) {
return acc;
}
const value =
typeof params[key] === 'object'
? JSON.stringify(params[key], null, 2)
: `"${params[key]}"`;
return acc + ` ${key}=${value},\n`;
}, '');
};
const codeValue = useMemo(() => {
const consoleLog = logcommand
? `console.log(response.${logcommand});\n`
: '';
const printLog = logcommand ? `print(response.${logcommand})` : '';
if (lang === langMap.shell) {
const code = `curl ${window.location.origin}/${GPUSTACK_API}/${api} \\\n-H "Content-Type: application/json" \\\n-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\\n-d '${JSON.stringify(
{
...parameters,
...payload
},
null,
2
)}'`;
return code;
}
if (lang === langMap.javascript) {
const code = `const OpenAI = require("openai");\n\nconst openai = new OpenAI({\n "apiKey": "YOUR_GPUSTACK_API_KEY",\n "baseURL": "${BaseURL}"\n});\n\nasync function main(){\n const params = ${JSON.stringify(
{
...parameters,
...payload
},
null,
4
)};\nconst response = await openai.${clientType}(params);\n ${consoleLog}}\nmain();`;
return code;
}
if (lang === langMap.python) {
const formattedParams = _.keys(parameters).reduce(
(acc: string, key: string) => {
if (parameters[key] === null) {
return acc;
}
const value =
typeof parameters[key] === 'string'
? `"${parameters[key]}"`
: parameters[key];
return acc + ` ${key}=${value},\n`;
},
''
);
const params = formatPyParams(payload);
const code = `from openai import OpenAI\n\nclient = OpenAI(\n base_url="${BaseURL}", \n api_key="YOUR_GPUSTACK_API_KEY"\n)\n\nresponse = client.${clientType}(\n${formattedParams}${params})\n${printLog}`;
return code;
}
return '';
}, [lang, payload, parameters, api, clientType, logcommand]);
const handleOnChangeLang = (value: string | number) => {
setLang(value as string);
};
const handleClose = () => {
setLang(langMap.shell);
onCancel();
};
return (
<>
<Modal
title={title}
open={open}
centered={true}
onCancel={handleClose}
destroyOnClose={true}
closeIcon={true}
maskClosable={false}
keyboard={false}
width={600}
footer={null}
>
<div style={{ marginBottom: '10px' }}>
{intl.formatMessage({ id: 'playground.viewcode.info' })}
</div>
<div>
<EditorWrap
copyText={codeValue}
langOptions={langOptions}
defaultValue={langMap.shell}
showHeader={true}
onChangeLang={handleOnChangeLang}
styles={{
wrapper: {
backgroundColor: 'var(--color-editor-dark)'
}
}}
>
<HighlightCode
height={380}
theme="dark"
code={codeValue}
lang={lang}
copyable={false}
></HighlightCode>
</EditorWrap>
<div
style={{ marginTop: 10, display: 'flex', alignItems: 'baseline' }}
>
<BulbOutlined className="m-r-8" />
<span>
{intl.formatMessage(
{ id: 'playground.viewcode.tips' },
{
here: (
<Button
type="link"
size="small"
href="#/api-keys"
target="_blank"
style={{ paddingInline: 2 }}
>
<span>
{' '}
{intl.formatMessage({
id: 'playground.viewcode.here'
})}
</span>
</Button>
)
}
)}
</span>
</div>
</div>
</Modal>
</>
);
};
export default React.memo(ViewCodeModal);

@ -6,7 +6,7 @@ import { Button, Modal } from 'antd';
import React, { useMemo, useState } from 'react';
type ViewModalProps = {
title: string;
title?: string;
open: boolean;
viewCodeContent: {
curlCode: string;
@ -59,7 +59,7 @@ const ViewCodeModal: React.FC<ViewModalProps> = (props) => {
return (
<>
<Modal
title={title}
title={title || intl.formatMessage({ id: 'playground.viewcode' })}
open={open}
centered={true}
onCancel={handleClose}

@ -0,0 +1,54 @@
import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis';
import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils';
export const generateLLMCode = ({
api: url,
parameters
}: Record<string, any>) => {
const host = window.location.origin;
const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
// ========================= Curl =========================
const curlCode = `
curl ${host}${api} \\
-H "Content-Type: application/json" \\
-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\
${formatCurlArgs(parameters, false)}`.trim();
// ========================= Python =========================
const pythonCode = `
from openai import OpenAI\n
client = OpenAI(
base_url="${host}/${GPUSTACK_API}",
api_key="YOUR_GPUSTACK_API_KEY"
)
response = client.chat.completions.create((\n${formatPyParams({ ...parameters })})\n
print(response.choices[0].message.content)`.trim();
// ========================= Node.js =========================
const params = fomatNodeJsParams({
...parameters
});
const nodeJsCode = `
const OpenAI = require("openai");
const openai = new OpenAI({
"apiKey": "YOUR_GPUSTACK_API_KEY",
"baseURL": "${host}/${GPUSTACK_API}"
});
async function main() {
const params = ${params};
const response = await openai.chat.completions.create(params);
console.log(response.choices[0].message.content);
}
main();`.trim();
return {
curlCode,
pythonCode,
nodeJsCode
};
};

@ -22,10 +22,14 @@ export const formatPyParams = (parameters: Record<string, any>) => {
if (parameters[key] === null || parameters[key] === undefined) {
return acc;
}
const vauleType = typeof parameters[key];
const value =
typeof parameters[key] === 'object'
vauleType === 'object'
? JSON.stringify(parameters[key], null, 2)
: `"${parameters[key]}"`;
: vauleType === 'string'
? `"${parameters[key]}"`
: parameters[key];
return acc + ` ${key}=${value},\n`;
}, '');
};

Loading…
Cancel
Save