wpmind/includes/Providers/AbstractOpenAiCompatibleProvider.php
LinuxJoy dcfa6f5cbe feat(v1.3.1): 提升为一级菜单 + 统一 API Key 管理 + UI 优化
## 新功能
- 提升为一级菜单"心思",使用心形图标
- 统一 API Key 管理界面,所有服务在同一页面管理
- 优化服务显示名称(ChatGPT、Claude、Gemini 等)

## Bug 修复
- 修复高级设置按钮无响应问题
- 修复 HTML 验证错误(label for 属性)
- 修复样式丢失问题(hook suffix 更新)

## 技术改进
- 移除调试用 console.log 语句
- 为每个服务添加 display_name 字段
- 更新 hook suffix 从 settings_page_wpmind 到 toplevel_page_wpmind

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:15:58 +08:00

117 lines
3.3 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* OpenAI 兼容 Provider 抽象基类
*
* @package WPMind
* @since 1.3.0
*/
declare(strict_types=1);
namespace WPMind\Providers;
use WordPress\AiClient\Common\Exception\RuntimeException;
use WordPress\AiClient\Providers\ApiBasedImplementation\AbstractApiProvider;
use WordPress\AiClient\Providers\Contracts\ModelMetadataDirectoryInterface;
use WordPress\AiClient\Providers\Contracts\ProviderAvailabilityInterface;
use WordPress\AiClient\Providers\DTO\ProviderMetadata;
use WordPress\AiClient\Providers\Enums\ProviderTypeEnum;
use WordPress\AiClient\Providers\Models\Contracts\ModelInterface;
use WordPress\AiClient\Providers\Models\DTO\ModelMetadata;
/**
* OpenAI 兼容 API Provider 抽象基类
*
* 为所有使用 OpenAI 兼容 API 的国内 AI 服务提供基础实现。
*
* @since 1.3.0
*/
abstract class AbstractOpenAiCompatibleProvider extends AbstractApiProvider
{
/**
* 获取 Provider ID
*
* @return string
*/
abstract protected static function providerId(): string;
/**
* 获取 Provider 显示名称
*
* @return string
*/
abstract protected static function providerName(): string;
/**
* 获取 API 凭据获取 URL
*
* @return string|null
*/
abstract protected static function credentialsUrl(): ?string;
/**
* {@inheritDoc}
*/
protected static function createModel(
ModelMetadata $modelMetadata,
ProviderMetadata $providerMetadata
): ModelInterface {
$capabilities = $modelMetadata->getSupportedCapabilities();
foreach ($capabilities as $capability) {
if ($capability->isTextGeneration()) {
$modelClass = static::textGenerationModelClass();
return new $modelClass($modelMetadata, $providerMetadata);
}
}
throw new RuntimeException(
sprintf(
'Unsupported model capabilities for %s: %s',
$providerMetadata->getName(),
implode(', ', $capabilities)
)
);
}
/**
* 获取文本生成模型类名
*
* @return class-string<ModelInterface>
*/
abstract protected static function textGenerationModelClass(): string;
/**
* {@inheritDoc}
*/
protected static function createProviderMetadata(): ProviderMetadata
{
return new ProviderMetadata(
static::providerId(),
static::providerName(),
ProviderTypeEnum::cloud(),
static::credentialsUrl()
);
}
/**
* {@inheritDoc}
*/
protected static function createProviderAvailability(): ProviderAvailabilityInterface
{
// 从模型目录获取第一个模型用于可用性检查
$directory = static::modelMetadataDirectory();
$models = $directory->listModelMetadata();
$firstModelId = $models[0]->getId();
// 使用自定义的 AuthenticatedProviderAvailability
// 它实现了 WithRequestAuthenticationInterface可以接收 API Key 认证
return new AuthenticatedProviderAvailability(
static::model($firstModelId)
);
}
/**
* {@inheritDoc}
*/
abstract protected static function createModelMetadataDirectory(): ModelMetadataDirectoryInterface;
}