feat: ionet integrate (#2105)

* wip ionet integrate

* wip ionet integrate

* wip ionet integrate

* ollama wip

* wip

* feat: ionet integration & ollama manage

* fix merge conflict

* wip

* fix: test conn cors

* wip

* fix ionet

* fix ionet

* wip

* fix model select

* refactor: Remove `pkg/ionet` test files and update related Go source and web UI model deployment components.

* feat: Enhance model deployment UI with styling improvements, updated text, and a new description component.

* Revert "feat: Enhance model deployment UI with styling improvements, updated text, and a new description component."

This reverts commit 8b75cb5bf0d1a534b339df8c033be9a6c7df7964.
This commit is contained in:
Seefs
2025-12-28 15:55:35 +08:00
committed by GitHub
parent 984ae32667
commit b10f1f7b85
51 changed files with 11895 additions and 369 deletions

View File

@@ -47,7 +47,8 @@ import {
import { FaRandom } from 'react-icons/fa';
// Render functions
const renderType = (type, channelInfo = undefined, t) => {
const renderType = (type, record = {}, t) => {
const channelInfo = record?.channel_info;
let type2label = new Map();
for (let i = 0; i < CHANNEL_OPTIONS.length; i++) {
type2label[CHANNEL_OPTIONS[i].value] = CHANNEL_OPTIONS[i];
@@ -71,11 +72,65 @@ const renderType = (type, channelInfo = undefined, t) => {
);
}
return (
const typeTag = (
<Tag color={type2label[type]?.color} shape='circle' prefixIcon={icon}>
{type2label[type]?.label}
</Tag>
);
let ionetMeta = null;
if (record?.other_info) {
try {
const parsed = JSON.parse(record.other_info);
if (parsed && typeof parsed === 'object' && parsed.source === 'ionet') {
ionetMeta = parsed;
}
} catch (error) {
// ignore invalid metadata
}
}
if (!ionetMeta) {
return typeTag;
}
const handleNavigate = (event) => {
event?.stopPropagation?.();
if (!ionetMeta?.deployment_id) {
return;
}
const targetUrl = `/console/deployment?deployment_id=${ionetMeta.deployment_id}`;
window.open(targetUrl, '_blank', 'noopener');
};
return (
<Space spacing={6}>
{typeTag}
<Tooltip
content={
<div className='max-w-xs'>
<div className='text-xs text-gray-600'>{t('来源于 IO.NET 部署')}</div>
{ionetMeta?.deployment_id && (
<div className='text-xs text-gray-500 mt-1'>
{t('部署 ID')}: {ionetMeta.deployment_id}
</div>
)}
</div>
}
>
<span>
<Tag
color='purple'
type='light'
className='cursor-pointer'
onClick={handleNavigate}
>
IO.NET
</Tag>
</span>
</Tooltip>
</Space>
);
};
const renderTagType = (t) => {
@@ -231,6 +286,7 @@ export const getChannelsColumns = ({
refresh,
activePage,
channels,
checkOllamaVersion,
setShowMultiKeyManageModal,
setCurrentMultiKeyChannel,
}) => {
@@ -330,12 +386,7 @@ export const getChannelsColumns = ({
dataIndex: 'type',
render: (text, record, index) => {
if (record.children === undefined) {
if (record.channel_info) {
if (record.channel_info.is_multi_key) {
return <>{renderType(text, record.channel_info, t)}</>;
}
}
return <>{renderType(text, undefined, t)}</>;
return <>{renderType(text, record, t)}</>;
} else {
return <>{renderTagType(t)}</>;
}
@@ -569,6 +620,15 @@ export const getChannelsColumns = ({
},
];
if (record.type === 4) {
moreMenuItems.unshift({
node: 'item',
name: t('测活'),
type: 'tertiary',
onClick: () => checkOllamaVersion(record),
});
}
return (
<Space wrap>
<SplitButtonGroup