Skip to content

Commit 4e3918b

Browse files
committed
chore: update to llm-chain 0.24
1 parent 77af4db commit 4e3918b

File tree

10 files changed

+415
-271
lines changed

10 files changed

+415
-271
lines changed

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
"ext-iconv": "*",
1010
"codewithkyrian/chromadb-php": "^0.4.0",
1111
"league/commonmark": "^2.7",
12-
"php-llm/llm-chain-bundle": "^0.22",
12+
"mrmysql/youtube-transcript": "^0.0.5",
13+
"php-http/discovery": "^1.20",
14+
"php-llm/llm-chain-bundle": "^0.24",
1315
"runtime/frankenphp-symfony": "^0.2.0",
1416
"symfony/asset": "7.3.*",
1517
"symfony/asset-mapper": "7.3.*",

composer.lock

Lines changed: 373 additions & 212 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/packages/http_discovery.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory'
3+
Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory'
4+
Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory'
5+
Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory'
6+
Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory'
7+
Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory'
8+
9+
http_discovery.psr17_factory:
10+
class: Http\Discovery\Psr17Factory

config/packages/llm_chain.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ llm_chain:
4444
chroma_db:
4545
symfonycon:
4646
collection: 'symfony_blog'
47-
embedder:
47+
indexer:
4848
default:
4949
model:
5050
name: 'Embeddings'
@@ -61,5 +61,5 @@ services:
6161
# $apiKey: '%env(SERP_API_KEY)%'
6262
PhpLlm\LlmChain\Chain\Toolbox\Tool\Wikipedia: ~
6363
PhpLlm\LlmChain\Chain\Toolbox\Tool\SimilaritySearch:
64-
$model: '@llm_chain.embedder.default.model'
64+
$model: '@llm_chain.indexer.default.model'
6565

src/Audio/Chat.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use PhpLlm\LlmChain\Platform\Message\Message;
1111
use PhpLlm\LlmChain\Platform\Message\MessageBag;
1212
use PhpLlm\LlmChain\Platform\PlatformInterface;
13-
use PhpLlm\LlmChain\Platform\Response\AsyncResponse;
1413
use PhpLlm\LlmChain\Platform\Response\TextResponse;
1514
use Symfony\Component\DependencyInjection\Attribute\Autowire;
1615
use Symfony\Component\HttpFoundation\RequestStack;
@@ -34,11 +33,8 @@ public function say(string $base64audio): void
3433
file_put_contents($path, base64_decode($base64audio));
3534

3635
$response = $this->platform->request(new Whisper(), Audio::fromFile($path));
37-
assert($response instanceof AsyncResponse);
38-
$response = $response->unwrap();
39-
assert($response instanceof TextResponse);
4036

41-
$this->submitMessage($response->getContent());
37+
$this->submitMessage($response->asText());
4238
}
4339

4440
public function loadMessages(): MessageBag

src/Blog/Command/QueryCommand.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
use Codewithkyrian\ChromaDB\Client;
88
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Embeddings;
99
use PhpLlm\LlmChain\Platform\PlatformInterface;
10-
use PhpLlm\LlmChain\Platform\Response\AsyncResponse;
11-
use PhpLlm\LlmChain\Platform\Response\VectorResponse;
1210
use Symfony\Component\Console\Attribute\AsCommand;
1311
use Symfony\Component\Console\Command\Command;
1412
use Symfony\Component\Console\Input\InputInterface;
@@ -44,11 +42,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
4442
$io->comment('Results are limited to 4 most similar documents.');
4543

4644
$platformResponse = $this->platform->request(new Embeddings(), $search);
47-
assert($platformResponse instanceof AsyncResponse);
48-
$platformResponse = $platformResponse->unwrap();
49-
assert($platformResponse instanceof VectorResponse);
5045
$queryResponse = $collection->query(
51-
queryEmbeddings: [$platformResponse->getContent()[0]->getData()],
46+
queryEmbeddings: [$platformResponse->asVectors()[0]->getData()],
5247
nResults: 4,
5348
);
5449

src/Blog/Embedder.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66

77
use PhpLlm\LlmChain\Store\Document\Metadata;
88
use PhpLlm\LlmChain\Store\Document\TextDocument;
9-
use PhpLlm\LlmChain\Store\Embedder as LlmChainEmbedder;
9+
use PhpLlm\LlmChain\Store\Indexer;
1010

1111
final readonly class Embedder
1212
{
1313
public function __construct(
1414
private FeedLoader $loader,
15-
private LlmChainEmbedder $embedder,
15+
private Indexer $indexer,
1616
) {
1717
}
1818

@@ -23,6 +23,6 @@ public function embedBlog(): void
2323
$documents[] = new TextDocument($post->id, $post->toString(), new Metadata($post->toArray()));
2424
}
2525

26-
$this->embedder->embed($documents);
26+
$this->indexer->index($documents);
2727
}
2828
}

src/Video/TwigComponent.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
use PhpLlm\LlmChain\Platform\Message\Message;
1010
use PhpLlm\LlmChain\Platform\Message\MessageBag;
1111
use PhpLlm\LlmChain\Platform\PlatformInterface;
12-
use PhpLlm\LlmChain\Platform\Response\AsyncResponse;
13-
use PhpLlm\LlmChain\Platform\Response\TextResponse;
1412
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
1513
use Symfony\UX\LiveComponent\Attribute\LiveAction;
1614
use Symfony\UX\LiveComponent\Attribute\LiveArg;
@@ -46,10 +44,6 @@ public function submit(#[LiveArg] string $instruction, #[LiveArg] string $image)
4644
'max_tokens' => 100,
4745
]);
4846

49-
assert($response instanceof AsyncResponse);
50-
$response = $response->unwrap();
51-
assert($response instanceof TextResponse);
52-
53-
$this->caption = $response->getContent();
47+
$this->caption = $response->asText();
5448
}
5549
}

src/YouTube/TranscriptFetcher.php

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
namespace App\YouTube;
66

7-
use Symfony\Component\DomCrawler\Crawler;
7+
use MrMySQL\YoutubeTranscript\TranscriptListFetcher;
8+
use Symfony\Component\HttpClient\Psr18Client;
89
use Symfony\Contracts\HttpClient\HttpClientInterface;
910

1011
final class TranscriptFetcher
@@ -16,41 +17,14 @@ public function __construct(
1617

1718
public function fetchTranscript(string $videoId): string
1819
{
19-
// Fetch the HTML content of the YouTube video page
20-
$htmlResponse = $this->client->request('GET', 'https://youtube.com/watch?v='.$videoId);
21-
$html = $htmlResponse->getContent();
20+
$psr18Client = new Psr18Client($this->client);
21+
$fetcher = new TranscriptListFetcher($psr18Client, $psr18Client, $psr18Client);
2222

23-
// Use DomCrawler to parse the HTML
24-
$crawler = new Crawler($html);
23+
$list = $fetcher->fetch($videoId);
24+
$transcript = $list->findTranscript($list->getAvailableLanguageCodes());
2525

26-
// Extract the script containing the ytInitialPlayerResponse
27-
$scriptContent = $crawler->filter('script')->reduce(function (Crawler $node) {
28-
return str_contains($node->text(), 'var ytInitialPlayerResponse = {');
29-
})->text();
30-
31-
// Extract and parse the JSON data from the script
32-
$start = strpos($scriptContent, 'var ytInitialPlayerResponse = ') + strlen('var ytInitialPlayerResponse = ');
33-
$dataString = substr($scriptContent, $start);
34-
$dataString = substr($dataString, 0, strrpos($dataString, ';') ?: null);
35-
$data = json_decode(trim($dataString), true);
36-
37-
// Extract the URL for the captions
38-
if (!isset($data['captions']['playerCaptionsTracklistRenderer']['captionTracks'][0]['baseUrl'])) {
39-
throw new \Exception('Captions are not available for this video.');
40-
}
41-
$captionsUrl = $data['captions']['playerCaptionsTracklistRenderer']['captionTracks'][0]['baseUrl'];
42-
43-
// Fetch and parse the captions XML
44-
$xmlResponse = $this->client->request('GET', $captionsUrl);
45-
$xmlContent = $xmlResponse->getContent();
46-
$xmlCrawler = new Crawler($xmlContent);
47-
48-
// Collect all text elements from the captions
49-
$transcript = $xmlCrawler->filter('text')->each(function (Crawler $node) {
50-
return $node->text().' ';
51-
});
52-
53-
// Combine all the text elements into one string
54-
return implode(PHP_EOL, $transcript);
26+
return array_reduce($transcript->fetch(), function (string $carry, array $item): string {
27+
return $carry.\PHP_EOL.$item['text'];
28+
}, '');
5529
}
5630
}

symfony.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@
2020
".php-cs-fixer.dist.php"
2121
]
2222
},
23+
"php-http/discovery": {
24+
"version": "1.20",
25+
"recipe": {
26+
"repo": "github.com/symfony/recipes",
27+
"branch": "main",
28+
"version": "1.18",
29+
"ref": "f45b5dd173a27873ab19f5e3180b2f661c21de02"
30+
},
31+
"files": [
32+
"config/packages/http_discovery.yaml"
33+
]
34+
},
2335
"php-llm/llm-chain-bundle": {
2436
"version": "dev-main"
2537
},

0 commit comments

Comments
 (0)