Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,12 @@ acseo_typesense:
from:
- title
- description
model_config:
model_name: ts/e5-small
model_config:
model_name: ts/e5-small # Typesense Cloud model (requires Typesense Cloud)
# For custom embedding services (Ollama, local models, etc.):
# model_name: 'openai/your-model-name'
# url: 'http://your-embedding-service:port'
# api_key: 'your-api-key' # Optional
default_sorting_field: sortable_id # Default sorting field. Must be int32 or float
symbols_to_index: ['+'] # Optional - You can add + to this list to make the word c++ indexable verbatim.
users:
Expand Down Expand Up @@ -327,7 +331,7 @@ $commonParams = new TypesenseQuery()->addParameter('query_by', 'name');
$response = $this->collectionClient->multisearch($searchRequests, $commonParams);
```

## Cookbook
## Cookbook
----------------

* [Use Typesense to make an autocomplete field](doc/cookbook/autocomplete.md)
Expand Down
6 changes: 1 addition & 5 deletions src/Client/CollectionClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function list()
return $this->client->collections->retrieve();
}

public function create($name, $fields, $defaultSortingField, array $tokenSeparators, array $symbolsToIndex, bool $enableNestedFields = false, ?array $embed = null)
public function create($name, $fields, $defaultSortingField, array $tokenSeparators, array $symbolsToIndex, bool $enableNestedFields = false)
{
if (!$this->client->isOperationnal()) {
return null;
Expand All @@ -72,10 +72,6 @@ public function create($name, $fields, $defaultSortingField, array $tokenSeparat
'symbols_to_index' => $symbolsToIndex,
'enable_nested_fields' => $enableNestedFields,
];

if ($embed) {
$options['embed'] = $embed;
}

$this->client->collections->create($options);
}
Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public function getConfigTreeBuilder(): TreeBuilder
->arrayNode('model_config')
->children()
->scalarNode('model_name')->isRequired()->end()
->scalarNode('api_key')->cannotBeEmpty()->end()
->scalarNode('url')->cannotBeEmpty()->end()
->end()
->end()
->end()
Expand Down
3 changes: 1 addition & 2 deletions src/Manager/CollectionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ public function createCollection($collectionDefinitionName)
$definition['default_sorting_field'],
$tokenSeparators,
$symbolsToIndex,
$definition['enable_nested_fields'] ?? false,
$definition['embed'] ?? null
$definition['enable_nested_fields'] ?? false
);
}
}
35 changes: 35 additions & 0 deletions tests/Unit/DependencyInjection/ACSEOTypesenseExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,39 @@ public function testFinderServiceDefinitionWithCollectionPrefix()
$this->assertSame('acseo_prefix_books', $arguments['typesense_name']);
$this->assertSame('books', $arguments['name']);
}

public function testEmbeddingConfigurationWithCustomService()
{
$containerBuilder = new ContainerBuilder();
$containerBuilder->registerExtension($extension = new ACSEOTypesenseExtension());
$containerBuilder->setParameter('kernel.debug', true);

$loader = new YamlFileLoader($containerBuilder, new FileLocator(__DIR__.'/fixtures'));
$loader->load('acseo_typesense.yml');

$extensionConfig = $containerBuilder->getExtensionConfig($extension->getAlias());
$extension->load($extensionConfig, $containerBuilder);

$this->assertTrue($containerBuilder->hasDefinition('typesense.client'));
$this->assertTrue($containerBuilder->hasDefinition('typesense.finder.books'));

// Verify that embed configuration is properly stored at field level
$managerDefinition = $containerBuilder->getDefinition('typesense.collection_manager');
$collections = $managerDefinition->getArgument(2);

$this->assertArrayHasKey('books', $collections);
$this->assertArrayHasKey('embeddings', $collections['books']['fields']);

$embeddingsField = $collections['books']['fields']['embeddings'];
$this->assertArrayHasKey('embed', $embeddingsField);
$this->assertArrayHasKey('from', $embeddingsField['embed']);
$this->assertArrayHasKey('model_config', $embeddingsField['embed']);
$this->assertEquals(['title'], $embeddingsField['embed']['from']);
$this->assertEquals('openai/test-model', $embeddingsField['embed']['model_config']['model_name']);
$this->assertEquals('test-api-key', $embeddingsField['embed']['model_config']['api_key']);
$this->assertEquals('http://test-url:8080', $embeddingsField['embed']['model_config']['url']);

// Verify that there is NO embed parameter at collection level
$this->assertArrayNotHasKey('embed', $collections['books']);
}
}
13 changes: 12 additions & 1 deletion tests/Unit/DependencyInjection/fixtures/acseo_typesense.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,21 @@ acseo_typesense:
genres:
name: genres
type: collection # Convert ArrayCollection to array of strings
publishedAt:
publishedAt:
name: publishedAt
type: datetime
optional: true # Declare field as optional
embeddings:
name: embeddings
type: float[]
optional: true
embed:
from:
- title
model_config:
model_name: 'openai/test-model'
api_key: 'test-api-key'
url: 'http://test-url:8080'
default_sorting_field: sortable_id # Default sorting field. Must be int32 or float
finders:
title_or_author:
Expand Down