Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.

Commit 871deab

Browse files
committed
fix: Create Albert-specific model clients for OpenAI-compatible API
- Add GPTModelClient and EmbeddingsModelClient for Albert with configurable base URL - Update PlatformFactory to use Albert-specific clients instead of OpenAI's - Fix PHPStan errors by using correct Platform class - Apply code style fixes
1 parent 7dbc39e commit 871deab

File tree

4 files changed

+110
-8
lines changed

4 files changed

+110
-8
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpLlm\LlmChain\Platform\Bridge\Albert;
6+
7+
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Embeddings;
8+
use PhpLlm\LlmChain\Platform\Model;
9+
use PhpLlm\LlmChain\Platform\ModelClientInterface;
10+
use Symfony\Contracts\HttpClient\HttpClientInterface;
11+
use Symfony\Contracts\HttpClient\ResponseInterface;
12+
use Webmozart\Assert\Assert;
13+
14+
/**
15+
* Embeddings Model Client for Albert API (OpenAI-compatible).
16+
*/
17+
final readonly class EmbeddingsModelClient implements ModelClientInterface
18+
{
19+
public function __construct(
20+
private HttpClientInterface $httpClient,
21+
#[\SensitiveParameter]
22+
private string $apiKey,
23+
private string $baseUrl,
24+
) {
25+
Assert::stringNotEmpty($apiKey, 'The API key must not be empty.');
26+
Assert::stringNotEmpty($baseUrl, 'The base URL must not be empty.');
27+
}
28+
29+
public function supports(Model $model): bool
30+
{
31+
return $model instanceof Embeddings;
32+
}
33+
34+
public function request(Model $model, array|string $payload, array $options = []): ResponseInterface
35+
{
36+
return $this->httpClient->request('POST', $this->baseUrl.'embeddings', [
37+
'auth_bearer' => $this->apiKey,
38+
'json' => array_merge($options, $payload),
39+
]);
40+
}
41+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpLlm\LlmChain\Platform\Bridge\Albert;
6+
7+
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\GPT;
8+
use PhpLlm\LlmChain\Platform\Model;
9+
use PhpLlm\LlmChain\Platform\ModelClientInterface;
10+
use Symfony\Component\HttpClient\EventSourceHttpClient;
11+
use Symfony\Contracts\HttpClient\HttpClientInterface;
12+
use Symfony\Contracts\HttpClient\ResponseInterface;
13+
use Webmozart\Assert\Assert;
14+
15+
/**
16+
* GPT Model Client for Albert API (OpenAI-compatible).
17+
*/
18+
final readonly class GPTModelClient implements ModelClientInterface
19+
{
20+
private EventSourceHttpClient $httpClient;
21+
22+
public function __construct(
23+
HttpClientInterface $httpClient,
24+
#[\SensitiveParameter]
25+
private string $apiKey,
26+
private string $baseUrl,
27+
) {
28+
$this->httpClient = $httpClient instanceof EventSourceHttpClient ? $httpClient : new EventSourceHttpClient($httpClient);
29+
Assert::stringNotEmpty($apiKey, 'The API key must not be empty.');
30+
Assert::stringNotEmpty($baseUrl, 'The base URL must not be empty.');
31+
}
32+
33+
public function supports(Model $model): bool
34+
{
35+
return $model instanceof GPT;
36+
}
37+
38+
public function request(Model $model, array|string $payload, array $options = []): ResponseInterface
39+
{
40+
return $this->httpClient->request('POST', $this->baseUrl.'chat/completions', [
41+
'auth_bearer' => $this->apiKey,
42+
'json' => array_merge($options, $payload),
43+
]);
44+
}
45+
}

src/Platform/Bridge/Albert/PlatformFactory.php

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,42 @@
44

55
namespace PhpLlm\LlmChain\Platform\Bridge\Albert;
66

7-
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Platform;
8-
use Symfony\Component\HttpClient\HttpClient;
7+
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Embeddings\ResponseConverter as EmbeddingsResponseConverter;
8+
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\GPT\ResponseConverter as GPTResponseConverter;
9+
use PhpLlm\LlmChain\Platform\Contract;
10+
use PhpLlm\LlmChain\Platform\Platform;
11+
use Symfony\Component\HttpClient\EventSourceHttpClient;
912
use Symfony\Contracts\HttpClient\HttpClientInterface;
1013

1114
final class PlatformFactory
1215
{
1316
/**
14-
* Creates a Platform instance for Albert API.
17+
* Creates a Platform instance for Albert API (OpenAI-compatible).
1518
*/
1619
public static function create(
1720
string $apiKey,
1821
string $albertUrl,
1922
?HttpClientInterface $httpClient = null,
2023
): Platform {
21-
$httpClient ??= HttpClient::create();
24+
$httpClient = $httpClient instanceof EventSourceHttpClient ? $httpClient : new EventSourceHttpClient($httpClient);
25+
26+
// Configure base URL for Albert API
27+
$baseUrl = rtrim($albertUrl, '/').'/v1/';
28+
29+
// Create Albert-specific model clients with custom base URL
30+
$gptClient = new GPTModelClient($httpClient, $apiKey, $baseUrl);
31+
$embeddingsClient = new EmbeddingsModelClient($httpClient, $apiKey, $baseUrl);
2232

2333
return new Platform(
24-
$httpClient,
25-
$apiKey,
26-
rtrim($albertUrl, '/').'/v1/',
34+
[
35+
$gptClient,
36+
$embeddingsClient,
37+
],
38+
[
39+
new GPTResponseConverter(),
40+
new EmbeddingsResponseConverter(),
41+
],
42+
Contract::create(),
2743
);
2844
}
2945
}

tests/Platform/Bridge/Albert/PlatformFactoryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace PhpLlm\LlmChain\Tests\Platform\Bridge\Albert;
66

77
use PhpLlm\LlmChain\Platform\Bridge\Albert\PlatformFactory;
8-
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Platform;
8+
use PhpLlm\LlmChain\Platform\Platform;
99
use PHPUnit\Framework\Attributes\CoversClass;
1010
use PHPUnit\Framework\Attributes\Small;
1111
use PHPUnit\Framework\Attributes\Test;

0 commit comments

Comments
 (0)