feat(platform): 插件协议系统 - 支持声明式渠道、工作流与参考媒体映射

This commit is contained in:
ddCat
2026-08-26 13:11:10 +08:00
parent 054e3bbbff
commit 2f3a813ccb
58 changed files with 2074 additions and 706 deletions

View File

@@ -0,0 +1,46 @@
import { apiClient, request } from "@/services/api/request";
import type { ModelProtocolDefinition, ProtocolCapability } from "@/lib/model-protocols";
type PluginProviderCatalogItem = {
id: string;
version: string;
name: string;
vendor: string;
categories: string[];
scopes: string[];
create?: string;
poll?: string;
contentType?: string;
enabled: boolean;
unavailableReason?: string;
baseUrl?: string;
workflows?: Array<{
id: string;
label: string;
providerId: string;
capability: ProtocolCapability;
parameters: Array<{ name: string; type: string; required?: boolean; description?: string; values?: string[]; mapping?: string }>;
defaults?: Record<string, string | number | boolean>;
}>;
};
export async function fetchPluginProviderCatalog(scope: string, capability?: ProtocolCapability) {
const result = await request<{ providers: PluginProviderCatalogItem[] }>(apiClient.get("/plugins/catalog", { params: { scope, capability } }));
return result.providers.filter((item) => item.enabled && !item.unavailableReason).map(toProviderDefinition);
}
function toProviderDefinition(item: PluginProviderCatalogItem): ModelProtocolDefinition {
return {
value: item.id,
label: item.name,
vendor: item.vendor,
capability: (item.categories[0] || "text") as ProtocolCapability,
create: item.create || "",
poll: item.poll,
contentType: item.contentType || "application/json",
media: `${item.vendor} · ${item.version}`,
enabled: item.enabled && !item.unavailableReason,
baseUrl: item.baseUrl,
workflows: item.workflows || [],
};
}

View File

@@ -1,32 +1,11 @@
import { apiClient, request } from "@/services/api/request";
import type { PluginManifest, ProtocolCapability, ProtocolScope } from "@/lib/plugins/plugin-types";
import type { PluginManifest } from "@/lib/plugins/plugin-types";
export type BackendPlugin = {
manifest: {
id: string;
name: string;
version: string;
apiVersion: string;
category: "protocol";
description?: string;
author?: string;
surfaces: string[];
permissions: string[];
trusted: boolean;
kind: "protocol";
protocol: {
categories: ProtocolCapability[];
scopes: ProtocolScope[];
create?: string;
poll?: string;
cancel?: string;
contentType?: string;
documentation?: string;
parameters?: NonNullable<PluginManifest["protocol"]>["parameters"];
};
};
manifest: PluginManifest;
source: "bundled" | "uploaded" | string;
fileName: string;
package: string;
sha256: string;
installedAt: string;
updatedAt: string;

View File

@@ -1,35 +0,0 @@
import { apiClient, request } from "@/services/api/request";
import type { ModelProtocolDefinition, ProtocolCapability } from "@/lib/model-protocols";
type ProtocolCatalogItem = {
id: string;
version: string;
name: string;
vendor: string;
categories: string[];
scopes: string[];
create?: string;
poll?: string;
contentType?: string;
enabled: boolean;
unavailableReason?: string;
};
export async function fetchProtocolCatalog(scope: string, capability?: ProtocolCapability) {
const result = await request<{ protocols: ProtocolCatalogItem[] }>(apiClient.get("/protocols", { params: { scope, capability } }));
return result.protocols.filter((item) => item.enabled && !item.unavailableReason).map(toProtocolDefinition);
}
function toProtocolDefinition(item: ProtocolCatalogItem): ModelProtocolDefinition {
return {
value: item.id,
label: item.name,
vendor: item.vendor,
capability: (item.categories[0] || "text") as ProtocolCapability,
create: item.create || "",
poll: item.poll,
contentType: item.contentType || "application/json",
media: `${item.vendor} · ${item.version}`,
enabled: item.enabled && !item.unavailableReason,
};
}