feat(M3-003): implement OpenAI provider adapter for Codex gpt-5.4
Adds OpenAIAdapter implementing IProviderAdapter, replacing the legacy
registerOpenAIProvider() inline registration in ProviderService.
- Creates apps/gateway/src/agent/adapters/openai.adapter.ts with:
- register(): initialises OpenAI client, registers codex-gpt-5-4 with
Pi ModelRegistry using openai-completions API; skips gracefully when
OPENAI_API_KEY is absent
- listModels(): returns Codex gpt-5.4 ModelInfo (128k context, tools+vision)
- healthCheck(): lightweight GET /v1/models to verify API key validity
- createCompletion(): streaming completions via openai SDK
chat.completions.create({ stream: true }); maps chunks to CompletionEvent
- Installs openai SDK (^6.32.0) as a dependency in apps/gateway
- Registers OpenAIAdapter in ProviderService alongside OllamaAdapter
- Removes legacy registerOpenAIProvider() private method from ProviderService
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,7 @@ import type {
|
||||
ProviderHealth,
|
||||
ProviderInfo,
|
||||
} from '@mosaic/types';
|
||||
import { OllamaAdapter } from './adapters/index.js';
|
||||
import { OllamaAdapter, OpenAIAdapter } from './adapters/index.js';
|
||||
import type { TestConnectionResultDto } from './provider.dto.js';
|
||||
|
||||
/** DI injection token for the provider adapter array. */
|
||||
@@ -31,15 +31,14 @@ export class ProviderService implements OnModuleInit {
|
||||
this.registry = new ModelRegistry(authStorage);
|
||||
|
||||
// Build the default set of adapters that rely on the registry
|
||||
this.adapters = [new OllamaAdapter(this.registry)];
|
||||
this.adapters = [new OllamaAdapter(this.registry), new OpenAIAdapter(this.registry)];
|
||||
|
||||
// Run all adapter registrations first (Ollama, and any future adapters)
|
||||
await this.registerAll();
|
||||
|
||||
// Register API-key providers directly (Anthropic, OpenAI, Z.ai, custom)
|
||||
// These do not yet have dedicated adapter classes (M3-002 through M3-005).
|
||||
// Register API-key providers directly (Anthropic, Z.ai, custom)
|
||||
// OpenAI now has a dedicated adapter class (M3-003).
|
||||
this.registerAnthropicProvider();
|
||||
this.registerOpenAIProvider();
|
||||
this.registerZaiProvider();
|
||||
this.registerCustomProviders();
|
||||
|
||||
@@ -234,7 +233,7 @@ export class ProviderService implements OnModuleInit {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Private helpers — direct registry registration for providers without adapters yet
|
||||
// (Anthropic, OpenAI, Z.ai will move to adapters in M3-002 through M3-005)
|
||||
// (Anthropic, Z.ai will move to adapters in M3-002, M3-005)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
private registerAnthropicProvider(): void {
|
||||
@@ -257,26 +256,6 @@ export class ProviderService implements OnModuleInit {
|
||||
this.logger.log('Anthropic provider registered with 3 models');
|
||||
}
|
||||
|
||||
private registerOpenAIProvider(): void {
|
||||
const apiKey = process.env['OPENAI_API_KEY'];
|
||||
if (!apiKey) {
|
||||
this.logger.debug('Skipping OpenAI provider registration: OPENAI_API_KEY not set');
|
||||
return;
|
||||
}
|
||||
|
||||
const models = ['gpt-4o', 'gpt-4o-mini', 'o3-mini'].map((id) =>
|
||||
this.cloneBuiltInModel('openai', id),
|
||||
);
|
||||
|
||||
this.registry.registerProvider('openai', {
|
||||
apiKey,
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
models,
|
||||
});
|
||||
|
||||
this.logger.log('OpenAI provider registered with 3 models');
|
||||
}
|
||||
|
||||
private registerZaiProvider(): void {
|
||||
const apiKey = process.env['ZAI_API_KEY'];
|
||||
if (!apiKey) {
|
||||
|
||||
Reference in New Issue
Block a user