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

Commit fc04a65

Browse files
committed
refactor: Clean up Albert API implementation
- Replace empty() with isset() checks in examples - Remove unnecessary comments ending with 'OpenAI-compatible' - Remove redundant doc comments - Add HTTPS validation for Albert URL - Make /v1 path handling more flexible - Use data provider for URL tests - Add test for HTTPS validation
1 parent e4ba76b commit fc04a65

File tree

5 files changed

+39
-27
lines changed

5 files changed

+39
-27
lines changed

examples/albert/chat.php

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,24 @@
1010

1111
require_once dirname(__DIR__).'/../vendor/autoload.php';
1212

13-
$albertApiKey = $_ENV['ALBERT_API_KEY'] ?? null;
14-
$albertApiUrl = $_ENV['ALBERT_API_URL'] ?? null;
15-
16-
if (empty($albertApiKey)) {
13+
if (!isset($_ENV['ALBERT_API_KEY'])) {
1714
echo 'Please set the ALBERT_API_KEY environment variable.'.\PHP_EOL;
1815
exit(1);
1916
}
2017

21-
if (empty($albertApiUrl)) {
18+
if (!isset($_ENV['ALBERT_API_URL'])) {
2219
echo 'Please set the ALBERT_API_URL environment variable (e.g., https://your-albert-instance.com).'.\PHP_EOL;
2320
exit(1);
2421
}
2522

26-
// Create platform instance for Albert API
2723
$platform = PlatformFactory::create(
28-
apiKey: $albertApiKey,
29-
albertUrl: $albertApiUrl,
24+
apiKey: $_ENV['ALBERT_API_KEY'],
25+
albertUrl: $_ENV['ALBERT_API_URL'],
3026
);
3127

3228
$model = new GPT('gpt-4o');
3329
$chain = new Chain($platform, $model);
3430

35-
// Albert API supports RAG out of the box
36-
// You can pass document context as part of your messages
3731
$documentContext = <<<'CONTEXT'
3832
Document: AI Strategy of France
3933

src/Platform/Bridge/Albert/EmbeddingsModelClient.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
use Symfony\Contracts\HttpClient\ResponseInterface;
1212
use Webmozart\Assert\Assert;
1313

14-
/**
15-
* Embeddings Model Client for Albert API (OpenAI-compatible).
16-
*/
1714
final readonly class EmbeddingsModelClient implements ModelClientInterface
1815
{
1916
public function __construct(

src/Platform/Bridge/Albert/GPTModelClient.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
use Symfony\Contracts\HttpClient\ResponseInterface;
1313
use Webmozart\Assert\Assert;
1414

15-
/**
16-
* GPT Model Client for Albert API (OpenAI-compatible).
17-
*/
1815
final readonly class GPTModelClient implements ModelClientInterface
1916
{
2017
private EventSourceHttpClient $httpClient;

src/Platform/Bridge/Albert/PlatformFactory.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,26 @@
1010
use PhpLlm\LlmChain\Platform\Platform;
1111
use Symfony\Component\HttpClient\EventSourceHttpClient;
1212
use Symfony\Contracts\HttpClient\HttpClientInterface;
13+
use Webmozart\Assert\Assert;
1314

1415
final class PlatformFactory
1516
{
16-
/**
17-
* Creates a Platform instance for Albert API (OpenAI-compatible).
18-
*/
1917
public static function create(
2018
string $apiKey,
2119
string $albertUrl,
2220
?HttpClientInterface $httpClient = null,
2321
): Platform {
22+
Assert::startsWith($albertUrl, 'https://', 'The Albert URL must start with "https://".');
23+
2424
$httpClient = $httpClient instanceof EventSourceHttpClient ? $httpClient : new EventSourceHttpClient($httpClient);
2525

26-
// Configure base URL for Albert API
27-
$baseUrl = rtrim($albertUrl, '/').'/v1/';
26+
// The base URL should include the full path to the API endpoint
27+
// Albert API expects the URL to end with /v1/
28+
$baseUrl = rtrim($albertUrl, '/');
29+
if (!str_ends_with($baseUrl, '/v1')) {
30+
$baseUrl .= '/v1';
31+
}
32+
$baseUrl .= '/';
2833

2934
// Create Albert-specific model clients with custom base URL
3035
$gptClient = new GPTModelClient($httpClient, $apiKey, $baseUrl);

tests/Platform/Bridge/Albert/PlatformFactoryTest.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
use PhpLlm\LlmChain\Platform\Bridge\Albert\PlatformFactory;
88
use PhpLlm\LlmChain\Platform\Platform;
99
use PHPUnit\Framework\Attributes\CoversClass;
10+
use PHPUnit\Framework\Attributes\DataProvider;
1011
use PHPUnit\Framework\Attributes\Small;
1112
use PHPUnit\Framework\Attributes\Test;
1213
use PHPUnit\Framework\TestCase;
14+
use Webmozart\Assert\InvalidArgumentException;
1315

1416
#[CoversClass(PlatformFactory::class)]
1517
#[Small]
@@ -24,13 +26,30 @@ public function createsPlatformWithCorrectBaseUrl(): void
2426
}
2527

2628
#[Test]
27-
public function trimsTrailingSlashFromUrl(): void
29+
#[DataProvider('urlProvider')]
30+
public function handlesUrlsCorrectly(string $url): void
2831
{
29-
$platform1 = PlatformFactory::create('test-key', 'https://albert.example.com/');
30-
$platform2 = PlatformFactory::create('test-key', 'https://albert.example.com');
32+
$platform = PlatformFactory::create('test-key', $url);
3133

32-
// Both should create the same platform configuration
33-
self::assertInstanceOf(Platform::class, $platform1);
34-
self::assertInstanceOf(Platform::class, $platform2);
34+
self::assertInstanceOf(Platform::class, $platform);
35+
}
36+
37+
public static function urlProvider(): array
38+
{
39+
return [
40+
'with trailing slash' => ['https://albert.example.com/'],
41+
'without trailing slash' => ['https://albert.example.com'],
42+
'with v1 path' => ['https://albert.example.com/v1'],
43+
'with v1 path and trailing slash' => ['https://albert.example.com/v1/'],
44+
];
45+
}
46+
47+
#[Test]
48+
public function throwsExceptionForNonHttpsUrl(): void
49+
{
50+
$this->expectException(InvalidArgumentException::class);
51+
$this->expectExceptionMessage('The Albert URL must start with "https://".');
52+
53+
PlatformFactory::create('test-key', 'http://albert.example.com');
3554
}
3655
}

0 commit comments

Comments
 (0)