69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
/**
|
||
* 能力目录(架构设计 2 / 4:registry 模块)。
|
||
*
|
||
* 保存已注册 Provider 与它们声明的能力;上层按身份取「能力清单」(A4 起按策略过滤,
|
||
* 当前只做注册与查找)。能力目录是唯一来源——引擎的工具列表是它的投影。
|
||
*/
|
||
import type { Capability, Provider, ProviderManifest } from '@aps/provider-sdk';
|
||
|
||
export interface RegisteredProvider {
|
||
manifest: ProviderManifest;
|
||
provider: Provider;
|
||
}
|
||
|
||
export interface ResolvedCapability {
|
||
capability: Capability;
|
||
provider: Provider;
|
||
providerId: string;
|
||
/** 该系统是否需要平台用户绑定账号(A4.1);缺省 true */
|
||
requiresIdentity: boolean;
|
||
}
|
||
|
||
export class CapabilityRegistry {
|
||
private readonly providers = new Map<string, RegisteredProvider>();
|
||
|
||
async register(provider: Provider): Promise<ProviderManifest> {
|
||
const manifest = await provider.describe();
|
||
if (manifest.platformVersion !== 1) {
|
||
throw new Error(`Provider ${manifest.id} 声明兼容平台版本 ${manifest.platformVersion},当前平台只支持 1`);
|
||
}
|
||
this.providers.set(manifest.id, { manifest, provider });
|
||
return manifest;
|
||
}
|
||
|
||
list(): Capability[] {
|
||
return [...this.providers.values()].flatMap((entry) => entry.manifest.capabilities);
|
||
}
|
||
|
||
resolve(capabilityId: string): ResolvedCapability | undefined {
|
||
for (const entry of this.providers.values()) {
|
||
const capability = entry.manifest.capabilities.find((item) => item.id === capabilityId);
|
||
if (capability) {
|
||
return {
|
||
capability,
|
||
provider: entry.provider,
|
||
providerId: entry.manifest.id,
|
||
requiresIdentity: entry.manifest.requiresIdentity !== false,
|
||
};
|
||
}
|
||
}
|
||
return undefined;
|
||
}
|
||
|
||
providerIds(): string[] {
|
||
return [...this.providers.keys()];
|
||
}
|
||
|
||
async health(): Promise<Array<{ providerId: string; status: string; detail?: string }>> {
|
||
const results: Array<{ providerId: string; status: string; detail?: string }> = [];
|
||
for (const [providerId, entry] of this.providers) {
|
||
try {
|
||
const health = await entry.provider.health();
|
||
results.push(health.detail === undefined ? { providerId, status: health.status } : { providerId, status: health.status, detail: health.detail });
|
||
} catch (error) {
|
||
results.push({ providerId, status: 'down', detail: error instanceof Error ? error.message : '健康探测失败' });
|
||
}
|
||
}
|
||
return results;
|
||
}
|
||
} |