Skip to content

feat(ai): redesign administrator model management - #7663

Open
c121914yu wants to merge 13 commits into
labring:mainfrom
c121914yu:install-model
Open

feat(ai): redesign administrator model management#7663
c121914yu wants to merge 13 commits into
labring:mainfrom
c121914yu:install-model

Conversation

@c121914yu

Copy link
Copy Markdown
Collaborator

Summary

  • Treat plugin model definitions as dynamically fetched templates, with separate immutable create/update flows and inactive-by-default model creation.
  • Add transactional template creation and batch status operations, safe JSON import, legacy system-model migration, and channel cleanup when deleting models.
  • Aggregate complete channel data in administrator model list/detail APIs, and support channel binding, testing, status changes, duplicate-name checks, and newest-first ordering.
  • Redesign the administrator model and channel UI with shared v2 modals/forms, virtualized lists, batch actions, fixed table layout, loading/empty states, and consistent toast feedback.

Verification

  • pnpm --filter @fastgpt/app typecheck
  • Changed-file ESLint and Prettier through the pre-commit hook: passed
  • Targeted unit/integration coverage: 43 test files, 628 tests passed
  • git diff --check and locale JSON parsing: passed

Note

Repository-wide app lint still reports pre-existing errors outside this change; all files and lines changed by this PR pass the staged-file lint hook.

Copilot AI lite review requested due to automatic review settings September 4, 2026 16:25
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T16:31:28.662792Z e180812 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are confirmed runtime-safety issues in shared web hooks/components (unguarded ResizeObserver usage and SSR-unsafe useLayoutEffect) that should be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR redesigns administrator system model management in FastGPT by decoupling installed models from plugin templates, adding admin APIs for template-driven creation, channel binding, testing, batch status/delete operations, and updating the web UI to use shared v2 modals/forms with improved list ergonomics (virtualization, fixed headers, batch actions). It also aligns types/tests with the removal of isCustom and refines pricing tier normalization behavior.

Changes:

  • Backend: add/adjust admin model APIs (templates, create-from-templates, channel replace, batch status update, batch delete) and refactor model update flows to treat model as immutable once installed.
  • Frontend: redesign model/channel admin UI flows with new modals/components and shared hooks (fixed table header, static virtual list, row-multi-select).
  • Cleanup: remove isCustom from schemas/tests and update pricing tier resolution semantics (drop “single zero tier” as empty billing).
File summaries
File Description
test/setupModels.ts Update model fixtures to remove isCustom.
test/mocks/core/ai/embedding.ts Update embedding mock model to remove isCustom.
projects/app/test/web/core/ai/model/useUserModelStore.test.ts Update catalog test data to remove isCustom.
projects/app/test/service/core/app/workflow.test.ts Update workflow test model fixture to remove isCustom.
projects/app/test/pages/api/core/ai/model/updateWithJson.test.ts Expand JSON import behavior coverage (immutability, duplicates) and update mocks.
projects/app/test/pages/api/core/ai/model/updateStatus.test.ts Add tests for batch status update admin API.
projects/app/test/pages/api/core/ai/model/test.test.ts Add tests for admin model test routing (channel override + draft testing).
projects/app/test/pages/api/core/ai/model/delete.test.ts Update delete tests for batch deletion + AIProxy channel unbinding.
projects/app/test/pageComponents/account/model/submit.test.ts Add tests for create vs update submit controller behavior.
projects/app/test/migration/tasks/20260903_migrate_legacy_system_models/service.test.ts Extend migration service tests for inspection + transactional snapshot behavior.
projects/app/test/migration/tasks/20260903_migrate_legacy_system_models/index.test.ts Update migration task orchestration tests (skip plugin fetch when legacy empty, new flow).
projects/app/test/api/core/ai/skill/debugChat.test.ts Remove isCustom from test model fixtures.
projects/app/test/api/core/ai/model/updateDefault.test.ts Update default-model update tests for new reload semantics.
projects/app/test/api/core/ai/model/list.test.ts Remove isCustom from list response fixture.
projects/app/test/api/core/ai/model/getDefaultConfig.test.ts Remove tests for deprecated admin default-config endpoint.
projects/app/test/api/core/ai/model/detail.test.ts Update detail response shape and include channel association info.
projects/app/test/api/core/ai/model/catalog.test.ts Remove isCustom from catalog test fixture.
projects/app/test/api/admin/settings/model/list.test.ts Add tests for admin list aggregation with channels/providers.
projects/app/src/web/core/ai/config.ts Update admin model API client: templates, create-from-templates, channel replace, batch status, delete body support, draft testing.
projects/app/src/web/core/ai/channel.ts Change channel list sorting + add duplicate-name guard for channel creation.
projects/app/src/service/common/system/cron.ts Remove scheduled model refresh cron invocation.
projects/app/src/pages/config/system/migrations.tsx UI spacing tweak in failed records modal.
projects/app/src/pages/config/model/index.tsx Remove legacy “available model” tab; default routing now points to model config.
projects/app/src/pages/api/admin/settings/model/updateWithJson.ts Redesign JSON import to preserve installed model identifier immutability, dedupe checks, and simplified reload.
projects/app/src/pages/api/admin/settings/model/updateStatus.ts Add admin API route for batch status updates.
projects/app/src/pages/api/admin/settings/model/updateDefault.ts Simplify reload after default update (no template refresh dependency).
projects/app/src/pages/api/admin/settings/model/update.ts Route update through service-layer updateSystemModelConfig.
projects/app/src/pages/api/admin/settings/model/test.ts Support draft-model testing via POST and avoid mutating cached installed model data.
projects/app/src/pages/api/admin/settings/model/templates.ts Add admin API route to fetch plugin templates (no cache publication).
projects/app/src/pages/api/admin/settings/model/list.ts Enrich admin model list with channel snapshots and per-model channel associations.
projects/app/src/pages/api/admin/settings/model/getDefaultConfig.ts Remove deprecated admin default-config endpoint.
projects/app/src/pages/api/admin/settings/model/detail.ts Return { model, channels } including association flags for edit UX.
projects/app/src/pages/api/admin/settings/model/delete.ts Support batch delete; unbind AIProxy channels before DB deletion; reload cache once.
projects/app/src/pages/api/admin/settings/model/createFromTemplates.ts Add transactional batch creation from latest templates + channel binding.
projects/app/src/pages/api/admin/settings/model/create.ts Add optional channel binding at create time; default new models inactive when unset.
projects/app/src/pages/api/admin/settings/model/channel/replace.ts Add admin API route to replace a model’s channel bindings via stable modelId.
projects/app/src/pageComponents/dataset/detail/CollectionCard/index.tsx Adopt unified row-selection props (avoid conflicting row click vs multi-select).
projects/app/src/pageComponents/app/detail/Logs/LogTable.tsx Adopt unified row-selection props for logs table rows.
projects/app/src/pageComponents/app/detail/components/SandboxEntrypointEditor.tsx Disable code editor resize for sandbox entrypoint editor.
projects/app/src/pageComponents/account/model/submit.ts New submit helpers enforcing create-vs-update call patterns and model identifier immutability.
projects/app/src/pageComponents/account/model/ModelLinkedChannels.tsx New UI block for viewing/managing selected linked channels in model modals.
projects/app/src/pageComponents/account/model/ModelEditModal.tsx New v2 edit modal integrating detail fetch, channel association UX, and channel testing.
projects/app/src/pageComponents/account/model/ModelDashboard/index.tsx Dashboard spacing tweak.
projects/app/src/pageComponents/account/model/ModelDashboard/DataTableComponent.tsx Split fixed header/body tables + optional billing column sizing + fixed header hook.
projects/app/src/pageComponents/account/model/ModelChannelCount.tsx New channel-count badge with hover details + keyboard support.
projects/app/src/pageComponents/account/model/JsonModelConfigModal.tsx New modal for exporting/importing JSON config with confirmation and toast feedback.
projects/app/src/pageComponents/account/model/DefaultModelModal.tsx New modal for configuring default models with consolidated selection UX.
projects/app/src/pageComponents/account/model/Channel/ModelTest.tsx Switch to v2 modal and fixed-header table; use admin model config store instead of separate fetch.
projects/app/src/migration/tasks/20260903_migrate_legacy_system_models/service.ts Add migration inspection helper; clarify merge semantics and transactional behavior.
projects/app/src/migration/tasks/20260903_migrate_legacy_system_models/index.ts Skip plugin/template work when legacy source is empty; simplify reload to loadInstalledModels().
projects/app/src/components/Layout/index.tsx Avoid duplicate root model config prefetch on /config/model route; adjust effect deps.
projects/app/src/components/core/ai/ModelListFilters.tsx New shared filter bar (provider/type/search) for model lists.
projects/app/CLAUDE.md Add pointer to AGENTS.md.
projects/app/AGENTS.md Add Next.js agent rules file for this workspace.
packages/web/i18n/zh-Hant/dataset.json Rename website dataset label translation.
packages/web/i18n/zh-Hant/config_model.json Add admin model/channel UI strings and remove legacy “active_model” label.
packages/web/i18n/zh-CN/dataset.json Rename website dataset label translation.
packages/web/i18n/zh-CN/config_model.json Add admin model/channel UI strings and remove legacy “active_model” label.
packages/web/i18n/ko-KR/dataset.json Rename website dataset label translation.
packages/web/i18n/ko-KR/config_model.json Add admin model/channel UI strings and remove legacy “active_model” label.
packages/web/i18n/en/dataset.json Rename website dataset label translation.
packages/web/i18n/en/config_model.json Add admin model/channel UI strings and remove legacy “active_model” label.
packages/web/hooks/useVirtualList.tsx Add useStaticVirtualList for in-memory fixed-height virtualization.
packages/web/hooks/useToast.ts Add status-based default toast durations with explicit override priority.
packages/web/hooks/useTableMultipleSelect.tsx Add getRowSelectionProps to unify row click vs selection behavior and interactive hotzones.
packages/web/hooks/useFixedTableHeader.ts New hook to sync split table header/body widths and horizontal scrolling.
packages/web/components/v2/common/MyModal/index.tsx Adjust modal body layout to better support flexible-height content areas.
packages/web/components/core/plugin/tool/BatchUpdateDrawer.tsx Align list/detail view behavior and adopt row selection props.
packages/web/components/common/Textarea/CodeEditor/index.tsx Add resize prop passthrough and default it to true.
packages/web/components/common/TagFilter/SingleSelectFilter.tsx Add selected-option centering on open and configurable max list height; adjust typography.
packages/web/components/common/TagFilter/MultiSelectFilter.tsx Adjust typography sizing.
packages/web/components/common/TagFilter/FilterSearchInput.tsx Redesign filter search input styling and add clear button via MyIconButton.
packages/web/components/common/TagFilter/FilterButton.tsx Adjust typography sizing.
packages/web/components/common/MyPopover/PopoverConfirm.tsx Make closeOnBlur configurable (default true).
packages/web/components/common/MyPopover/index.tsx Add trigger-only hover mode (closeOnTriggerLeave) using PopoverAnchor.
packages/service/thirdProvider/aiproxy/channel.ts New service adapter for AIProxy channels: listing, admin summaries, bind/replace/remove operations.
packages/service/test/support/wallet/usage/utils.test.ts Remove isCustom from model fixtures.
packages/service/test/core/dataset/utils.test.ts Remove isCustom from model fixtures.
packages/service/test/core/dataset/search/index.test.ts Remove isCustom from model fixtures.
packages/service/test/core/dataset/search/defaultRecall.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/utils.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/rerank/index.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/model.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/llm/request/requestBody.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/llm/request/createLLMResponse.test.ts Update fixtures and remove unused custom-request test setup.
packages/service/test/core/ai/llm/compress/index.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/llm/agentLoop/piAgentModelBridge.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/llm/agentLoop/baseLoop.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/hooks/useTextCosine.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/functions/queryExtension.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/functions/createQuestionGuide.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/embedding/index.test.ts Remove isCustom from model fixtures.
packages/service/test/core/ai/config/utils.test.ts Update filtering tests for model response shape changes.
packages/service/test/core/ai/config/service.test.ts Add tests for new system-model update service behavior.
packages/service/test/core/ai/catalog.test.ts Remove isCustom from model fixtures.
packages/service/core/ai/config/utils.ts Remove template snapshot/preinstall logic; simplify load/reload to DB-installed models and newest-first ordering.
packages/service/core/ai/config/service.ts New service-layer helpers for atomic config/status updates with full-target matching.
packages/global/test/openapi/common/system.test.ts Update OpenAPI fixtures to remove isCustom.
packages/global/test/openapi/admin/core/model.test.ts Expand admin schema tests (unique IDs, immutable update payload, tag grouping).
packages/global/test/openapi/admin/common/system/migrations.test.ts Update admin tag grouping to include system model tag.
packages/global/test/core/dataset/training/utils.test.ts Remove isCustom from model fixtures.
packages/global/test/core/ai/pricing.test.ts Update/extend pricing tier normalization/resolution tests for “zero tier” semantics.
packages/global/openapi/tag.ts Add adminSystemModel OpenAPI tag.
packages/global/openapi/path.ts Add admin system model tag to admin tag group.
packages/global/openapi/core/ai/model/api.ts Remove isCustom from core model schema.
packages/global/openapi/admin/core/ai/model/index.ts Update admin model API definitions: new endpoints, tags, request/response shapes.
packages/global/core/ai/pricing.ts Adjust runtime pricing tier resolution to drop empty single-tier pricing.
packages/global/core/ai/model.schema.ts Remove isCustom from runtime model schema fields.
packages/global/core/ai/constants.ts Remove isCustom from default model constants.
.agents/design/core/ai/model-id-reference-migration.md Update design doc to remove isCustom and reflect template-decoupled model semantics.
Review details
  • Files reviewed: 125/125 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +22 to +37
const updateScrollbarWidth = () => {
setScrollbarWidth(body.offsetWidth - body.clientWidth);
};
const syncHorizontalScroll = () => {
header.scrollLeft = body.scrollLeft;
};
updateScrollbarWidth();
syncHorizontalScroll();

const resizeObserver = new ResizeObserver(updateScrollbarWidth);
resizeObserver.observe(body);
body.addEventListener('scroll', syncHorizontalScroll, { passive: true });
return () => {
resizeObserver.disconnect();
body.removeEventListener('scroll', syncHorizontalScroll);
};
Comment on lines +74 to +86
const { triggerRef, triggerWidth } = useFilterTriggerWidth(selected?.label);
const listScrollable = showSearch || visibleOptions.length > FILTER_SEARCH_THRESHOLD;

useLayoutEffect(() => {
const list = listRef.current;
const selectedOption = selectedOptionRef.current;
if (!list || !selectedOption) return;

const centeredScrollTop =
selectedOption.offsetTop - (list.clientHeight - selectedOption.offsetHeight) / 2;
const maxScrollTop = Math.max(0, list.scrollHeight - list.clientHeight);
list.scrollTop = Math.min(Math.max(0, centeredScrollTop), maxScrollTop);
}, [openRevision, value, visibleOptions]);

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e18081296d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +92 to +94
});
setTestModelList(list);
}, [getModelProvider, i18n.language, models, systemModelList, t]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid resetting test state on every loading render

When the administrator-model request is pending or fails, useAdminModelConfig() returns newly allocated fallback arrays and rebuilds getModelProvider on every render. This effect depends on both values and always calls setTestModelList with a new array, creating a render/effect loop that can make the channel-test modal consume CPU or hit React's maximum update-depth warning. Guard until model data is loaded, stabilize the hook's empty fallbacks, or derive this list with memoization.

Useful? React with 👍 / 👎.

bodySchema: CreateSystemModelBodySchema
}).body;

await appendModelsToAIProxyChannels({ channelIds, models: [modelData.model] });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Check duplicate model names before modifying channels

When an administrator enters an already-installed model and selects a channel that does not yet contain it, this call successfully adds the existing identifier to that channel before MongoAIModel.create fails on the unique {scope, model} index. The request therefore reports creation failure while persisting an unexpected channel association; query and reject duplicate system models before performing the external write.

Useful? React with 👍 / 👎.

Comment on lines +47 to +50
const { data: response } = await axiosWithoutSSRF.get(`${baseUrl}/api/channels/all`, {
headers,
params: { page: 1, perPage: 1000 }
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fetch all channel pages before applying model changes

For installations with more than 1,000 AI Proxy channels, this fetch returns only the first requested page even though callers treat it as the complete snapshot. Consequently model listing omits later associations, replacement never updates those channels, and deletion can leave the removed model attached to channels after the first 1,000; iterate through pages (or use a verified unbounded endpoint) before returning the snapshot.

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 33.61% 3379 / 10052
🔵 Statements 33.51% 3568 / 10645
🔵 Functions 28.01% 671 / 2395
🔵 Branches 28.34% 1699 / 5993
File CoverageNo changed files found.
Generated in workflow #3029 for commit b099703 by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Admin Preview Image Ready!

ghcr.io/labring/fastgpt-pr:admin_b099703a70e2a86fbfd92ca9cff0b2bbd1d1f9fb

🕒 Time: 2026-09-06 02:21:05 (UTC+8)

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Build and publish successful - Preview fastgpt Image:

ghcr.io/labring/fastgpt-pr:fastgpt_b099703a70e2a86fbfd92ca9cff0b2bbd1d1f9fb

🕒 Time: 2026-09-06 02:21:25 (UTC+8)

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Docs preview deployed

🔗 👀 Click here to visit preview

ghcr.io/labring/fastgpt-docs-pr:b099703a70e2a86fbfd92ca9cff0b2bbd1d1f9fb

🕒 Time: 2026-09-06 02:18:23 (UTC+8)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants