mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
feat(llm,datasource): gate model/provider/oauth/datasource endpoints to admin
This commit is contained in:
parent
41f3408209
commit
bba9975749
@ -10,6 +10,7 @@ import vip.mate.datasource.service.DatasourceService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import vip.mate.workspace.core.annotation.RequireWorkspaceRole;
|
||||
|
||||
/**
|
||||
* 数据源管理接口
|
||||
@ -26,24 +27,28 @@ public class DatasourceController {
|
||||
|
||||
@Operation(summary = "获取数据源列表")
|
||||
@GetMapping
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<List<DatasourceEntity>> list() {
|
||||
return R.ok(datasourceService.listAll());
|
||||
}
|
||||
|
||||
@Operation(summary = "获取数据源详情")
|
||||
@GetMapping("/{id}")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<DatasourceEntity> get(@PathVariable Long id) {
|
||||
return R.ok(datasourceService.getByIdMasked(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "创建数据源")
|
||||
@PostMapping
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<DatasourceEntity> create(@RequestBody DatasourceEntity entity) {
|
||||
return R.ok(datasourceService.create(entity));
|
||||
}
|
||||
|
||||
@Operation(summary = "更新数据源")
|
||||
@PutMapping("/{id}")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<DatasourceEntity> update(@PathVariable Long id, @RequestBody DatasourceEntity entity) {
|
||||
entity.setId(id);
|
||||
return R.ok(datasourceService.update(entity));
|
||||
@ -51,6 +56,7 @@ public class DatasourceController {
|
||||
|
||||
@Operation(summary = "删除数据源")
|
||||
@DeleteMapping("/{id}")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> delete(@PathVariable Long id) {
|
||||
datasourceService.delete(id);
|
||||
return R.ok();
|
||||
@ -58,6 +64,7 @@ public class DatasourceController {
|
||||
|
||||
@Operation(summary = "测试数据源连接")
|
||||
@PostMapping("/{id}/test")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Map<String, Object>> testConnection(@PathVariable Long id) {
|
||||
boolean ok = datasourceService.testConnection(id);
|
||||
return R.ok(Map.of("success", ok, "message", ok ? "连接成功" : "连接失败"));
|
||||
@ -65,6 +72,7 @@ public class DatasourceController {
|
||||
|
||||
@Operation(summary = "启用/禁用数据源")
|
||||
@PutMapping("/{id}/toggle")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<DatasourceEntity> toggle(@PathVariable Long id, @RequestParam boolean enabled) {
|
||||
return R.ok(datasourceService.toggle(id, enabled));
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import vip.mate.common.result.R;
|
||||
import vip.mate.llm.anthropic.oauth.ClaudeCodeOAuthService;
|
||||
import vip.mate.llm.anthropic.oauth.ClaudeCodeOAuthService.OAuthStatus;
|
||||
import vip.mate.workspace.core.annotation.RequireWorkspaceRole;
|
||||
|
||||
/**
|
||||
* RFC-062 PR-3: management-UI surface for the Claude Code OAuth provider.
|
||||
@ -45,6 +46,7 @@ public class ClaudeCodeOAuthController {
|
||||
|
||||
@Operation(summary = "Read current Claude Code OAuth credential status from local disk")
|
||||
@GetMapping("/status")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<OAuthStatus> status() {
|
||||
return R.ok(oauthService.getStatus());
|
||||
}
|
||||
@ -60,6 +62,7 @@ public class ClaudeCodeOAuthController {
|
||||
*/
|
||||
@Operation(summary = "Force re-detect credentials and refresh if near expiry")
|
||||
@PostMapping("/reload")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<OAuthStatus> reload() {
|
||||
try {
|
||||
oauthService.getValidToken();
|
||||
|
||||
@ -20,6 +20,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import vip.mate.workspace.core.annotation.RequireWorkspaceRole;
|
||||
|
||||
@Tag(name = "模型配置管理")
|
||||
@RestController
|
||||
@ -37,42 +38,49 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "获取 Provider 列表(仅 enabled)")
|
||||
@GetMapping
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<List<ProviderInfoDTO>> list() {
|
||||
return R.ok(modelProviderService.listProviders());
|
||||
}
|
||||
|
||||
@Operation(summary = "RFC-074: 获取 Provider 全量目录(含未启用),供 Add Provider 抽屉使用")
|
||||
@GetMapping("/catalog")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<List<ProviderInfoDTO>> catalog() {
|
||||
return R.ok(modelProviderService.listCatalog());
|
||||
}
|
||||
|
||||
@Operation(summary = "RFC-074: 启用 Provider")
|
||||
@PostMapping("/{providerId}/enable")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<EnableResult> enableProvider(@PathVariable String providerId) {
|
||||
return R.ok(modelProviderService.setEnabled(providerId, true));
|
||||
}
|
||||
|
||||
@Operation(summary = "RFC-074: 禁用 Provider(如其下模型为当前默认会自动切换)")
|
||||
@PostMapping("/{providerId}/disable")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<EnableResult> disableProvider(@PathVariable String providerId) {
|
||||
return R.ok(modelProviderService.setEnabled(providerId, false));
|
||||
}
|
||||
|
||||
@Operation(summary = "获取启用模型列表")
|
||||
@GetMapping("/enabled")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<List<ModelConfigEntity>> listEnabled() {
|
||||
return R.ok(modelConfigService.listEnabledModels());
|
||||
}
|
||||
|
||||
@Operation(summary = "获取默认模型")
|
||||
@GetMapping("/default")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ModelConfigEntity> getDefaultModel() {
|
||||
return R.ok(modelConfigService.getDefaultModel());
|
||||
}
|
||||
|
||||
@Operation(summary = "获取当前激活模型")
|
||||
@GetMapping("/active")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ActiveModelsInfo> getActiveModel() {
|
||||
ModelConfigEntity model = modelConfigService.getDefaultModel();
|
||||
ActiveModelsInfo info = new ActiveModelsInfo();
|
||||
@ -82,6 +90,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "设置当前激活模型")
|
||||
@PutMapping("/active")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ActiveModelsInfo> setActiveModel(@RequestBody ModelSlotRequest request) {
|
||||
ModelConfigEntity model = modelConfigService.setDefaultModel(request.getProviderId(), request.getModel());
|
||||
ActiveModelsInfo info = new ActiveModelsInfo();
|
||||
@ -91,6 +100,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "更新 Provider 配置")
|
||||
@PutMapping("/{providerId}/config")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ProviderInfoDTO> updateProviderConfig(@PathVariable String providerId,
|
||||
@RequestBody ProviderConfigRequest request) {
|
||||
ProviderInfoDTO updated = modelProviderService.updateProviderConfig(providerId, request);
|
||||
@ -101,12 +111,14 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "创建自定义 Provider")
|
||||
@PostMapping("/custom-providers")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ProviderInfoDTO> createCustomProvider(@RequestBody CreateCustomProviderRequest request) {
|
||||
return R.ok(modelProviderService.createCustomProvider(request));
|
||||
}
|
||||
|
||||
@Operation(summary = "删除自定义 Provider")
|
||||
@DeleteMapping("/custom-providers/{providerId}")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> deleteCustomProvider(@PathVariable String providerId) {
|
||||
modelProviderService.deleteCustomProvider(providerId);
|
||||
return R.ok();
|
||||
@ -122,6 +134,7 @@ public class ModelConfigController {
|
||||
*/
|
||||
@Operation(summary = "删除自定义 Provider(查询参数变体,兼容含特殊字符的旧 ID)")
|
||||
@DeleteMapping("/custom-providers")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> deleteCustomProviderByQuery(@RequestParam("providerId") String providerId) {
|
||||
modelProviderService.deleteCustomProvider(providerId);
|
||||
return R.ok();
|
||||
@ -129,6 +142,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "向 Provider 添加模型")
|
||||
@PostMapping("/{providerId}/models")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ProviderInfoDTO> addProviderModel(@PathVariable String providerId,
|
||||
@RequestBody AddProviderModelRequest request) {
|
||||
return R.ok(modelProviderService.addModel(providerId, request));
|
||||
@ -136,6 +150,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "从 Provider 删除模型")
|
||||
@DeleteMapping("/{providerId}/models/{modelId}")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ProviderInfoDTO> removeProviderModel(@PathVariable String providerId,
|
||||
@PathVariable String modelId) {
|
||||
return R.ok(modelProviderService.removeModel(providerId, modelId));
|
||||
@ -143,18 +158,21 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "获取模型详情")
|
||||
@GetMapping("/{id}")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ModelConfigEntity> get(@PathVariable Long id) {
|
||||
return R.ok(modelConfigService.getModel(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "创建模型")
|
||||
@PostMapping
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ModelConfigEntity> create(@RequestBody ModelConfigEntity entity) {
|
||||
return R.ok(modelConfigService.createModel(entity));
|
||||
}
|
||||
|
||||
@Operation(summary = "更新模型")
|
||||
@PutMapping("/{id}")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ModelConfigEntity> update(@PathVariable Long id, @RequestBody ModelConfigEntity entity) {
|
||||
entity.setId(id);
|
||||
return R.ok(modelConfigService.updateModel(entity));
|
||||
@ -162,6 +180,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "删除模型")
|
||||
@DeleteMapping("/{id}")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> delete(@PathVariable Long id) {
|
||||
modelConfigService.deleteModel(id);
|
||||
return R.ok();
|
||||
@ -169,6 +188,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "设置默认模型")
|
||||
@PostMapping("/{id}/default")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ModelConfigEntity> setDefault(@PathVariable Long id) {
|
||||
return R.ok(modelConfigService.setDefaultModel(id));
|
||||
}
|
||||
@ -177,12 +197,14 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "发现远端模型")
|
||||
@PostMapping("/{providerId}/discover")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<DiscoverResult> discoverModels(@PathVariable String providerId) {
|
||||
return R.ok(modelDiscoveryService.discoverModels(providerId));
|
||||
}
|
||||
|
||||
@Operation(summary = "批量添加发现的模型")
|
||||
@PostMapping("/{providerId}/discover/apply")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Map<String, Integer>> applyDiscoveredModels(@PathVariable String providerId,
|
||||
@RequestBody ApplyDiscoveredModelsRequest request) {
|
||||
int added = modelDiscoveryService.batchAddModels(providerId, request.getModelIds());
|
||||
@ -191,12 +213,14 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "测试供应商连接")
|
||||
@PostMapping("/{providerId}/test-connection")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<TestResult> testConnection(@PathVariable String providerId) {
|
||||
return R.ok(modelDiscoveryService.testConnection(providerId));
|
||||
}
|
||||
|
||||
@Operation(summary = "测试单个模型可用性")
|
||||
@PostMapping("/{providerId}/models/{modelId}/test")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<TestResult> testModel(@PathVariable String providerId,
|
||||
@PathVariable String modelId) {
|
||||
return R.ok(modelDiscoveryService.testModel(providerId, modelId));
|
||||
@ -206,6 +230,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "按类型筛选模型(chat / embedding),可选 modality 过滤")
|
||||
@GetMapping("/by-type")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<List<ModelConfigEntity>> listByType(
|
||||
@RequestParam(defaultValue = "chat") String modelType,
|
||||
@RequestParam(required = false) String modality) {
|
||||
@ -214,6 +239,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "测试 Embedding 模型连通性(嵌入一个短文本验证 API key)")
|
||||
@PostMapping("/embedding/{modelId}/test")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Map<String, Object>> testEmbedding(@PathVariable Long modelId) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
@ -241,6 +267,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "获取系统默认 Embedding 模型 ID")
|
||||
@GetMapping("/embedding/default")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Map<String, Object>> getDefaultEmbedding() {
|
||||
SystemSettingEntity entity = systemSettingMapper.selectOne(
|
||||
new LambdaQueryWrapper<SystemSettingEntity>()
|
||||
@ -254,6 +281,7 @@ public class ModelConfigController {
|
||||
|
||||
@Operation(summary = "设置系统默认 Embedding 模型")
|
||||
@PostMapping("/embedding/default")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> setDefaultEmbedding(@RequestBody Map<String, Object> body) {
|
||||
Object v = body.get("modelId");
|
||||
String value = v == null ? "" : v.toString();
|
||||
|
||||
@ -12,6 +12,7 @@ import vip.mate.llm.oauth.OpenAIDeviceCodeService.DeviceCodeStartResult;
|
||||
import vip.mate.llm.oauth.OpenAIOAuthService;
|
||||
import vip.mate.llm.oauth.OpenAIOAuthService.OAuthAuthorizeResult;
|
||||
import vip.mate.llm.oauth.OpenAIOAuthService.OAuthStatusResult;
|
||||
import vip.mate.workspace.core.annotation.RequireWorkspaceRole;
|
||||
|
||||
@Tag(name = "OpenAI OAuth")
|
||||
@RestController
|
||||
@ -24,6 +25,7 @@ public class OAuthController {
|
||||
|
||||
@Operation(summary = "获取 OAuth 授权 URL(自动选 LOCAL / MANUAL_PASTE 模式)")
|
||||
@GetMapping("/authorize")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<OAuthAuthorizeResult> authorize(HttpServletRequest request) {
|
||||
// 用 Host header 判断是否远程部署 — 远程则不启 localhost server,进 MANUAL_PASTE 流。
|
||||
// 优先 X-Forwarded-Host(反向代理后的实际入口),fallback 到 Host。
|
||||
@ -42,6 +44,7 @@ public class OAuthController {
|
||||
*/
|
||||
@Operation(summary = "MANUAL_PASTE 模式:用户粘贴浏览器回调 URL 完成 OAuth")
|
||||
@PostMapping("/callback-paste")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> callbackPaste(@RequestBody PasteRequest request) {
|
||||
oauthService.completeFromPastedUrl(request.callbackUrl());
|
||||
return R.ok();
|
||||
@ -52,18 +55,21 @@ public class OAuthController {
|
||||
|
||||
@Operation(summary = "Device flow: start — request user_code")
|
||||
@PostMapping("/device/start")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<DeviceCodeStartResult> deviceStart() {
|
||||
return R.ok(deviceCodeService.start());
|
||||
}
|
||||
|
||||
@Operation(summary = "Device flow: poll for completion")
|
||||
@PostMapping("/device/poll")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<DeviceCodePollResult> devicePoll(@RequestBody DeviceRequest request) {
|
||||
return R.ok(deviceCodeService.poll(request.deviceAuthId()));
|
||||
}
|
||||
|
||||
@Operation(summary = "Device flow: cancel a pending session")
|
||||
@PostMapping("/device/cancel")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> deviceCancel(@RequestBody DeviceRequest request) {
|
||||
deviceCodeService.cancel(request.deviceAuthId());
|
||||
return R.ok();
|
||||
@ -74,6 +80,7 @@ public class OAuthController {
|
||||
|
||||
@Operation(summary = "手动刷新 Token")
|
||||
@PostMapping("/refresh")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> refresh() {
|
||||
oauthService.refreshToken();
|
||||
return R.ok();
|
||||
@ -81,6 +88,7 @@ public class OAuthController {
|
||||
|
||||
@Operation(summary = "清除 OAuth 凭证")
|
||||
@DeleteMapping("/revoke")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<Void> revoke() {
|
||||
oauthService.revokeToken();
|
||||
return R.ok();
|
||||
@ -88,6 +96,7 @@ public class OAuthController {
|
||||
|
||||
@Operation(summary = "获取 OAuth 连接状态")
|
||||
@GetMapping("/status")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<OAuthStatusResult> status() {
|
||||
return R.ok(oauthService.getStatus());
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import vip.mate.llm.service.ModelProviderService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import vip.mate.workspace.core.annotation.RequireWorkspaceRole;
|
||||
|
||||
/**
|
||||
* RFC-009 Phase 4 — read-only diagnostic endpoint for the provider pool.
|
||||
@ -49,6 +50,7 @@ public class ProviderPoolController {
|
||||
|
||||
@Operation(summary = "查询所有 provider 的池状态 + 冷却信息")
|
||||
@GetMapping
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<List<ProviderPoolEntryDTO>> snapshot() {
|
||||
Map<String, RemovalReason> poolView = providerPool.snapshot();
|
||||
Map<String, ProviderHealthSnapshot> healthView = healthTracker.snapshot();
|
||||
@ -81,6 +83,7 @@ public class ProviderPoolController {
|
||||
|
||||
@Operation(summary = "手动重新探测某个 provider,立即更新池状态")
|
||||
@PostMapping("/{providerId}/reprobe")
|
||||
@RequireWorkspaceRole("admin")
|
||||
public R<ReprobeResultDTO> reprobe(@PathVariable String providerId) {
|
||||
ProbeResult result = initProbe.probeOne(providerId);
|
||||
return R.ok(new ReprobeResultDTO(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user