adachsoft/ai-model-list
Composer 安装命令:
composer require adachsoft/ai-model-list
包简介
Framework-agnostic library exposing a public API to list available AI models from multiple providers (SPI-enabled).
README 文档
README
Framework-agnostic PHP library that exposes a clean Public API (Facade) to list available AI models from multiple providers using a Domain Port for core providers and an SPI for external extensions.
Status: Work in Progress. Versioning is done via Git tags only.
Requirements
- PHP >= 8.3
- adachsoft/collection >= 2.1
- For real provider integrations: guzzlehttp/guzzle
- For .env support (CLI, tests): vlucas/phpdotenv
Installation
This library is currently under development and may not be published to Packagist yet.
- If available on Packagist:
- composer require adachsoft/ai-model-list
- If you use it from source, make sure your composer.json autoload maps the namespace:
- PSR-4: "AdachSoft\AIModelList\": "src/"
Optional dependencies if you want real OpenAI and Google Gemini API integration and .env support for CLI:
- composer require guzzlehttp/guzzle
- composer require vlucas/phpdotenv
Dev tools (optional but recommended):
- composer require --dev friendsofphp/php-cs-fixer phpstan/phpstan
Architecture Overview
- PublicApi
- Facade, DTOs, Enums, concrete Collections (immutable)
- Clean entrypoint that throws PublicApi exceptions only
- Application
- Use case(s), mapping Domain → PublicApi
- Adapter from SPI → Domain (wraps external SPI providers)
- Optional integration of SPI Enrichment (enricher chain + mapper)
- Domain
- Value Objects (e.g., ProviderId, ModelId), Enums, concrete Collections, ModelDefinition (readonly)
- Port: Domain\Port\AiModelProviderPortInterface used by core providers
- Optional ModelMetadata (enrichment) attached to ModelDefinition
- SPI
- Contract for external providers: Spi\AiModelProvider\AiModelProviderInterface
- Contract for enrichment: Spi\Enrichment (enrichers, chain, DTO/Enum/Collections)
- SPI types are mapped to Domain via the adapter/mapper in Application
- Infrastructure
- Core providers (OpenAI, Google Gemini) implement the Domain port and return Domain models
Key idea: Core providers implement the Domain port. External providers implement the SPI and are adapted at registration time via the Application adapter, ensuring strict isolation between layers. Enrichment is also SPI-only (no Domain/Public types in SPI).
Collections
All collections use adachsoft/collection. For immutable list collections (AbstractImmutableCollection), the item type is passed via parent constructor:
public function __construct(iterable $items = [])
{
parent::__construct($items, Foo::class);
}
Do not implement getItemType() methods in this project. For maps (AbstractImmutableMap), override getKeyType() and getValueType().
Configuration (SPI/Config)
Configuration in this library is source-agnostic and exposed via Spi\Config contracts and ready-to-use implementations:
- ConfigurationProviderInterface — has(string), get(string): ?string, getAll(): KeyValueMap
- KeyValueMap — immutable map of string→string (extends adachsoft/collection AbstractImmutableMap)
- InMemoryConfigurationProvider — wraps a KeyValueMap (useful for tests/overrides)
- EnvConfigurationProvider — reads from getenv()/$_ENV/$_SERVER and normalizes keys
- AggregatedConfigurationProvider — aggregates multiple providers, “first wins” policy
- NamespacedConfigurationProvider — exposes a namespaced view (e.g., "vendor/pkg." prefix or ENV variant "VENDORPKG…")
Examples:
use AdachSoft\AIModelList\Spi\Config\EnvConfigurationProvider;
use AdachSoft\AIModelList\Spi\Config\InMemoryConfigurationProvider;
use AdachSoft\AIModelList\Spi\Config\AggregatedConfigurationProvider;
use AdachSoft\AIModelList\Spi\Config\NamespacedConfigurationProvider;
use AdachSoft\AIModelList\Spi\Config\KeyValueMap;
// Global configuration built from ENV with optional in-memory overrides
$env = new EnvConfigurationProvider();
$overrides = new InMemoryConfigurationProvider(new KeyValueMap(['timeout' => '30']));
$global = new AggregatedConfigurationProvider([$overrides, $env]); // first wins
// Namespaced view for a package, exposes short keys like 'api_key'
$pkg = new NamespacedConfigurationProvider('vendor/pkg', $global);
$apiKey = $pkg->get('api_key'); // reads vendor/pkg.api_key or VENDOR_PKG_API_KEY
Quick Start (built-in providers)
Register providers with real API keys (e.g., from .env):
use AdachSoft\AIModelList\PublicApi\Builder\AiModelCatalogFacadeBuilder;
use AdachSoft\AIModelList\PublicApi\AiModelCatalogFacadeInterface;
use Dotenv\Dotenv;
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad();
$openAiKey = $_ENV['OPENAI_API_KEY'] ?? getenv('OPENAI_API_KEY');
$geminiKey = $_ENV['GEMINI_API_KEY'] ?? getenv('GEMINI_API_KEY');
$builder = new AiModelCatalogFacadeBuilder();
if (is_string($openAiKey) && $openAiKey !== '') {
$builder->withOpenAi($openAiKey);
}
if (is_string($geminiKey) && $geminiKey !== '') {
$builder->withGoogleGemini($geminiKey);
}
/** @var AiModelCatalogFacadeInterface $facade */
$facade = $builder->build();
$providers = $facade->listProviders(); // e.g. ["openai", "google_gemini"]
$models = $facade->listModels('google_gemini'); // PublicApi\Collection\ModelDefinitionCollection
SPI: External Providers
Implement AdachSoft\AIModelList\Spi\AiModelProvider\AiModelProviderInterface:
- getProviderId(): string – unique provider ID (e.g., openai, acme)
- listModels(ProviderId $providerId): ModelDefinitionCollection – returns SPI model definitions using SPI mirror types
- On provider failures throw Spi\AiModelProvider\Exception\ProviderSpiException
Register your provider via the builder; it will be wrapped by the SPI→Domain adapter automatically:
$facade = (new AiModelCatalogFacadeBuilder())
->withSpiProvider($yourSpiProvider)
->build();
$models = $facade->listModels($yourSpiProvider->getProviderId());
Bulk registration via typed collection
For multi-package integrations or autodiscovery tooling, provide a typed collection of SPI providers (the collection enforces the item type):
use AdachSoft\AIModelList\Spi\AiModelProvider\Collection\AiModelProviderCollection;
$providers = new AiModelProviderCollection([
$providerA, // implements AiModelProviderInterface
$providerB,
]);
$facade = (new AiModelCatalogFacadeBuilder())
->withProviders($providers)
->build();
Notes:
- The builder deduplicates providers by ID and throws PublicApi\Exception\DuplicateProviderIdException on conflicts.
- The collection guarantees all entries implement the SPI interface.
SPI Enrichment (optional)
To provide additional metadata (description, token limits, supportedGenerationMethods, etc.) implement:
- Spi\Enrichment\AiModelMetadataEnricherInterface – your enricher(s) producing SPI ModelMetadataDto
- Spi\Enrichment\AiModelMetadataEnricherChainInterface – orchestrates one or more enrichers
- Provide an Application-level mapper: Application\Mapper\SpiToDomain\SpiEnrichmentToDomainMetadataMapper to convert SPI DTOs to Domain ModelMetadata
Then register them in the builder:
$facade = (new AiModelCatalogFacadeBuilder())
->withSpiProvider($yourSpiProvider)
->withEnricherChain($yourEnricherChain)
->withEnrichmentMapper($yourSpiToDomainMetadataMapper)
->build();
$models = $facade->listModels($yourSpiProvider->getProviderId());
// Public DTOs will now contain enrichment fields (e.g., description) if provided by the chain.
Examples
Runnable examples are provided under the examples/ directory:
- examples/spi_provider_minimal.php – minimal external SPI provider registration and listing models
- examples/spi_enrichment_minimal.php – SPI provider + enrichment chain + mapper; shows enrichment in Public DTOs
- examples/config_providers_minimal.php – usage of Env, InMemory, Aggregated and Namespaced configuration providers
Run examples:
- php examples/spi_provider_minimal.php
- php examples/spi_enrichment_minimal.php
- php examples/config_providers_minimal.php
Providers implemented out of the box
- OpenAI (providerId: "openai")
- HTTP: GET https://api.openai.com/v1/models with Authorization: Bearer
- Model ID is taken from response "id"; displayName equals the model ID
- Capabilities are inferred heuristically from model ID (CHAT/IMAGE/AUDIO/EMBEDDING)
- On failures provider throws Domain\Exception\ProviderFailureException
- Google Gemini (providerId: "google_gemini")
- HTTP: GET https://generativelanguage.googleapis.com/v1beta/models?key=&pageToken=&pageSize=1000
- The provider fetches all pages using nextPageToken (pagination) and consolidates them into a single collection.
- A safety limit of 50 pages is applied; exceeding it throws Domain\Exception\ProviderFailureException.
- Model ID is the last segment of "name" (e.g., models/gemini-1.5-pro-001 → gemini-1.5-pro-001); displayName equals the model ID
- Capabilities inferred from supportedGenerationMethods and modelId (CHAT/EMBEDDING/IMAGE/AUDIO)
- On failures provider throws Domain\Exception\ProviderFailureException
Exceptions and layering
- Domain Port providers throw Domain\Exception\ProviderFailureException for network/HTTP/format errors.
- The Application ListModelsService wraps provider failures into Public API exceptions:
- PublicApi\AiModelCatalogFacade::listModels() throws PublicApi\Exception\AiModelCatalogException on provider failure.
.env configuration
Copy .env.example to .env and set your secrets:
OPENAI_API_KEY=sk-your-openai-key
GEMINI_API_KEY=AIza-your-gemini-key
CLI (bin/list-models)
The CLI script lists available models for a provider using .env configuration.
Usage:
- php bin/list-models
Examples:
- php bin/list-models openai (requires OPENAI_API_KEY)
- php bin/list-models google_gemini (requires GEMINI_API_KEY)
Behavior:
- Providers are registered conditionally based on available API keys
- Helpful error messages are printed when a required key is missing or the provider is not registered
- Output format (tab-separated):
- \t
Exit codes:
- 0: success
- 1: usage error or missing configuration (.env not found or API key missing) or provider not registered
- 2: runtime error
Testing
- PHPUnit >= 12 is used. A default phpunit.xml.dist is provided.
- Run tests: vendor/bin/phpunit
- Tests follow .docs/UNIT_TESTING_GUIDELINES.md (AAA, PHP attributes like #[CoversClass], avoid testing simple DTOs and exceptions).
- Functional tests include datasets conditionally for providers based on OPENAI_API_KEY and GEMINI_API_KEY.
Code Style & Static Analysis
- PHP CS Fixer: vendor/bin/php-cs-fixer fix src
- PHPStan (level 8 recommended): vendor/bin/phpstan analyse src --level=8
License
MIT
adachsoft/ai-model-list 适用场景与选型建议
adachsoft/ai-model-list 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 15 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 10 月 16 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「catalog」 「provider」 「models」 「ai」 「spi」 「framework-agnostic」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 adachsoft/ai-model-list 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 adachsoft/ai-model-list 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 adachsoft/ai-model-list 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Time provider, providing consistent current date, time, datetime and timezone across the request.
Wordpress Query Builder class library for custom models and data querying.
An Zend Expressive module for loading ZF2 or ZF3 modules.
A fast and intuitive dependency injection container.
A Laravel package for managing model drafts.
A package to better handle database operations via Eloquent Models.
统计信息
- 总下载量: 15
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 21
- 依赖项目数: 4
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-16