Sfoglia il codice sorgente

'upgrade'

localiazed
unknown 1 settimana fa
parent
commit
bf779f3068
2 ha cambiato i file con 234 aggiunte e 0 eliminazioni
  1. +2
    -0
      web/src/components/table/model-pricing/modal/ModelDetailSideSheet.jsx
  2. +232
    -0
      web/src/components/table/model-pricing/modal/components/ModelCodeSnippet.jsx

+ 2
- 0
web/src/components/table/model-pricing/modal/ModelDetailSideSheet.jsx Vedi File

@@ -26,6 +26,7 @@ import ModelHeader from './components/ModelHeader';
import ModelBasicInfo from './components/ModelBasicInfo';
import ModelEndpoints from './components/ModelEndpoints';
import ModelPricingTable from './components/ModelPricingTable';
import ModelCodeSnippet from './components/ModelCodeSnippet';

const { Text } = Typography;

@@ -99,6 +100,7 @@ const ModelDetailSideSheet = ({
autoGroups={autoGroups}
t={t}
/>
<ModelCodeSnippet modelData={modelData} t={t} />
</>
)}
</div>


+ 232
- 0
web/src/components/table/model-pricing/modal/components/ModelCodeSnippet.jsx Vedi File

@@ -0,0 +1,232 @@
/*
Copyright (C) 2025 QuantumNous

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

For commercial licensing, please contact support@quantumnous.com
*/

import React, { useState, useMemo, useContext } from 'react';
import {
Card,
Avatar,
Typography,
RadioGroup,
Radio,
TextArea,
Button,
} from '@douyinfe/semi-ui';
import { IconCode } from '@douyinfe/semi-icons';
import { copy, showSuccess, showInfo } from '../../../../../helpers';
import { StatusContext } from '../../../../../context/Status';

const { Text } = Typography;

const LANG_OPTIONS = [
{ value: 'python', label: 'Python' },
{ value: 'java', label: 'Java' },
{ value: 'go', label: 'Go' },
{ value: 'shell', label: 'Shell' },
];

// 四种语言的调用示例代码模板,使用 __MODEL_NAME__ 与 __BASE_URL__ 作为占位符
const getDefaultCodeByLang = () => ({
python: `
from openai import OpenAI

client = OpenAI(
api_key="<Your API Key>",
base_url="__BASE_URL__"
)

response = client.chat.completions.create(
model="__MODEL_NAME__",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello, how are you?"}
],
max_tokens=128000,
temperature=0.7
)

print(response.choices[0].message.content)
`,
java: `
import com.openai.OpenAI;
import com.openai.models.*;

OpenAI client = new OpenAI("<Your API Key>", "__BASE_URL__");

ChatCompletionRequest request = ChatCompletionRequest.builder()
.model("__MODEL_NAME__")
.messages(Arrays.asList(
new ChatMessage("system", "You are a helpful assistant."),
new ChatMessage("user", "Hello, how are you?")
))
.maxTokens(1000)
.temperature(0.7)
.build();

ChatCompletion response = client.chatCompletions().create(request);
System.out.println(response.getChoices().get(0).getMessage().getContent());
`,
go: `
package main

import (
"context"
"fmt"
"github.com/openai/openai-go"
)

func main() {
client := openai.NewClient("<Your API Key>", "__BASE_URL__")
messages := []openai.ChatMessage{
{Role: "system", Content: "You are a helpful assistant."},
{Role: "user", Content: "Hello, how are you?"},
}
response, err := client.ChatCompletions.Create(context.Background(), openai.ChatCompletionRequest{
Model: "__MODEL_NAME__",
Messages: messages,
MaxTokens: 128000,
Temperature: 0.7,
})
if err != nil {
panic(err)
}
fmt.Println(response.Choices[0].Message.Content)
}
`,
shell: `
#!/bin/bash

API_KEY="<Your API Key>"
MODEL_ID="__MODEL_NAME__"
BASE_URL="__BASE_URL__"

curl -X POST "$BASE_URL/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d '{
"model": "'$MODEL_ID'",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Hello, how are you?"
}
],
"max_tokens": 128000,
"temperature": 0.7
}'
`,
});

const PLACEHOLDER_MODEL = '__MODEL_NAME__';
const PLACEHOLDER_BASE_URL = '__BASE_URL__';

const ModelCodeSnippet = ({ modelData, t }) => {
const [statusState] = useContext(StatusContext);
const serverAddress =
statusState?.status?.server_address || (typeof window !== 'undefined' ? window.location.origin : '');
const [lang, setLang] = useState('python');
const codeByLang = useMemo(() => {
const templates = getDefaultCodeByLang();
const modelName = modelData?.model_name || '';
const baseUrl = serverAddress || '';
return Object.fromEntries(
Object.entries(templates).map(([key, code]) => {
let result = code.replaceAll(PLACEHOLDER_BASE_URL, baseUrl);
result = result.replaceAll(PLACEHOLDER_MODEL, modelName);
return [key, result];
}),
);
}, [modelData?.model_name, serverAddress]);

const currentCode = codeByLang[lang] || '';

const handleCopy = async () => {
if (!currentCode || currentCode.trim() === '') {
showInfo(t('当前语言暂无示例代码'));
return;
}
const ok = await copy(currentCode);
if (ok) {
showSuccess(t('已复制到剪切板'));
}
};

return (
<Card className='!rounded-2xl shadow-sm border-0 mb-6'>
<div className='flex items-center mb-4'>
<Avatar size='small' color='green' className='mr-2 shadow-md'>
<IconCode size={16} />
</Avatar>
<div>
<Text className='text-lg font-medium'>{t('调用示例')}</Text>
<div className='text-xs text-gray-600'>
{t('使用 OpenAI 兼容接口调用该模型的示例代码')}
</div>
</div>
</div>

<div className='mb-3'>
<Text className='text-sm text-semi-color-text-1 mb-2 block'>
{t('选择语言')}
</Text>
<RadioGroup
type='button'
value={lang}
onChange={(e) => setLang(e.target.value)}
direction='horizontal'
>
{LANG_OPTIONS.map((opt) => (
<Radio key={opt.value} value={opt.value}>
{opt.label}
</Radio>
))}
</RadioGroup>
</div>

<div className='mb-3'>
<TextArea
value={currentCode}
readOnly
placeholder={t('暂无该语言示例代码')}
autosize={{ minRows: 8, maxRows: 16 }}
className='font-mono text-sm'
style={{ backgroundColor: 'var(--semi-color-fill-0)' }}
/>
</div>

<Button
theme='solid'
type='primary'
onClick={handleCopy}
disabled={!currentCode || currentCode.trim() === ''}
>
{t('一键复制代码')}
</Button>
</Card>
);
};

export default ModelCodeSnippet;

Caricamento…
Annulla
Salva