Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
30 changes: 30 additions & 0 deletions config/cortex.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,36 @@
],
],

/*
|--------------------------------------------------------------------------
| Prompt Factories
|--------------------------------------------------------------------------
|
| Here you may define the prompt factories.
|
| Supported drivers: "langfuse", "mcp"
|
*/
'prompt_factory' => [
'default' => env('CORTEX_DEFAULT_PROMPT_FACTORY', 'langfuse'),

'langfuse' => [
'username' => env('LANGFUSE_USERNAME', ''),
'password' => env('LANGFUSE_PASSWORD', ''),
'base_uri' => env('LANGFUSE_BASE_URI', 'https://cloud.langfuse.com'),

'cache' => [
'enabled' => env('CORTEX_PROMPT_CACHE_ENABLED', false),
'store' => env('CORTEX_PROMPT_CACHE_STORE', null),
'ttl' => env('CORTEX_PROMPT_CACHE_TTL', 3600),
],
Comment thread
tymondesigns marked this conversation as resolved.
],

// 'mcp' => [
// 'base_uri' => env('MCP_BASE_URI', 'http://localhost:3000'),
// ],
],

/*
|--------------------------------------------------------------------------
| Embedding Providers
Expand Down
37 changes: 36 additions & 1 deletion scratchpad.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use Cortex\Cortex;
use Cortex\Prompts\Prompt;
use Cortex\JsonSchema\SchemaFactory;
use Cortex\LLM\Data\Messages\UserMessage;
use Cortex\LLM\Data\Messages\SystemMessage;
Expand All @@ -18,11 +19,45 @@

// Or more simply
$result = Cortex::prompt('What is the capital of {country}?')
->llm('anthropic', 'claude-3-5-sonnet-20240620')
->metadata(
provider: 'anthropic',
model: 'claude-3-5-sonnet-20240620',
structuredOutput: SchemaFactory::object()->properties(
SchemaFactory::string('capital'),
),
)
->llm()
->invoke([
'country' => 'France',
]);

// Get a text prompt builder
$prompt = Cortex::prompt('What is the capital of {country}?');

// Get a chat prompt builder
$prompt = Cortex::prompt([
new SystemMessage('You are an expert at geography.'),
new UserMessage('What is the capital of {country}?'),
]);

// Get a prompt from the given factory
$prompt = Cortex::prompt()->factory('langfuse')->make('test-prompt');

// Get a chat prompt builder
$prompt = Cortex::prompt()->builder('chat')->messages([
new SystemMessage('You are an expert at geography.'),
new UserMessage('What is the capital of {country}?'),
]);

// Get a text prompt builder
$prompt = Cortex::prompt()->builder('text');

$prompt = Prompt::factory()->make('test-prompt');
$prompt = Prompt::builder()->messages([
new SystemMessage('You are an expert at geography.'),
new UserMessage('What is the capital of {country}?'),
]);

// Uses default llm driver
$result = Cortex::llm()->invoke([
new SystemMessage('You are a helpful assistant'),
Expand Down
33 changes: 21 additions & 12 deletions src/Cortex.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,35 @@
namespace Cortex;

use Cortex\Facades\LLM;
use Cortex\Prompts\Prompt;
use Cortex\Facades\Embeddings;
use Cortex\Tasks\Enums\TaskType;
use Cortex\Tasks\Builders\TextTaskBuilder;
use Cortex\Prompts\Contracts\PromptBuilder;
use Cortex\LLM\Contracts\LLM as LLMContract;
use Cortex\Prompts\Builders\ChatPromptBuilder;
use Cortex\LLM\Data\Messages\MessageCollection;
use Cortex\Tasks\Builders\StructuredTaskBuilder;
use Cortex\Embeddings\Contracts\Embeddings as EmbeddingsContract;

class Cortex
{
/**
* Create a chat prompt builder.
* Create a prompt builder or factory.
*
* @param \Cortex\LLM\Data\Messages\MessageCollection|array<int, \Cortex\LLM\Contracts\Message>|string $messages
* @param \Cortex\LLM\Data\Messages\MessageCollection|array<int, \Cortex\LLM\Contracts\Message|\Cortex\LLM\Data\Messages\MessagePlaceholder>|string|null $messages
*
* @return ($messages is null ? \Cortex\Prompts\Prompt : ($messages is string ? \Cortex\Prompts\Builders\TextPromptBuilder : \Cortex\Prompts\Builders\ChatPromptBuilder))
*/
public static function prompt(
MessageCollection|array|string|null $messages,
): ChatPromptBuilder {
$builder = new ChatPromptBuilder();

if ($messages !== null) {
$builder->messages($messages);
MessageCollection|array|string|null $messages = null,
): Prompt|PromptBuilder {
if (func_num_args() === 0) {
return new Prompt();
}

return $builder;
return is_string($messages)
? Prompt::builder('text')->text($messages)
: Prompt::builder('chat')->messages($messages);
}

/**
Expand All @@ -47,9 +50,15 @@ public static function llm(?string $provider = null, ?string $model = null): LLM
return $llm;
}

public static function embeddings(?string $driver = null): EmbeddingsContract
public static function embeddings(?string $driver = null, ?string $model = null): EmbeddingsContract
{
return Embeddings::driver($driver);
$embeddings = Embeddings::driver($driver);

if ($model !== null) {
$embeddings->withModel($model);
}

return $embeddings;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/CortexServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
use Cortex\ModelInfo\ModelInfoFactory;
use Spatie\LaravelPackageTools\Package;
use Cortex\Embeddings\EmbeddingsManager;
use Cortex\Prompts\PromptFactoryManager;
use Cortex\Embeddings\Contracts\Embeddings;
use Cortex\Prompts\Contracts\PromptFactory;
use Illuminate\Contracts\Container\Container;
use Spatie\LaravelPackageTools\PackageServiceProvider;

Expand All @@ -30,6 +32,10 @@ public function packageRegistered(): void
$this->app->alias('cortex.embeddings', EmbeddingsManager::class);
$this->app->bind(Embeddings::class, fn(Container $app) => $app->make('cortex.embeddings')->driver());

$this->app->singleton('cortex.prompt_factory', fn(Container $app): PromptFactoryManager => new PromptFactoryManager($app));
$this->app->alias('cortex.prompt_factory', PromptFactoryManager::class);
$this->app->bind(PromptFactory::class, fn(Container $app) => $app->make('cortex.prompt_factory')->driver());

$this->app->singleton('cortex.model_info_factory', function (Container $app): ModelInfoFactory {
$providers = [];
foreach ($app->make('config')->get('cortex.model_info_providers', []) as $provider => $config) {
Expand Down
22 changes: 22 additions & 0 deletions src/Facades/PromptFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Cortex\Facades;

use Illuminate\Support\Facades\Facade;

/**
* @method static \Cortex\Prompts\Contracts\PromptFactory driver(string $driver = null)
* @method static \Cortex\Prompts\Contracts\PromptFactory make(string $name, array<string, mixed> $options = [])
* @method static string getDefaultDriver()
*
* @see \Cortex\Prompts\PromptFactoryManager
*/
class PromptFactory extends Facade
{
protected static function getFacadeAccessor(): string
{
return 'cortex.prompt_factory';
}
}
4 changes: 2 additions & 2 deletions src/LLM/LLMManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ protected function createDriver($driver): LLM // @pest-ignore-type
/**
* Create an OpenAI LLM driver instance.
*
* @param array<string, mixed> $config
* @param array{default_model?: string, model_provider?: string, default_parameters: array<string, mixed>, options: array{api_key?: string, organization?: string, base_uri?: string, headers?: array<string, string>, query_params?: array<string, string>}} $config
*/
public function createOpenAIDriver(array $config, string $name): OpenAIChat|CacheDecorator
{
Expand Down Expand Up @@ -142,7 +142,7 @@ public function createAnthropicDriver(array $config, string $name): AnthropicCha
}

/**
* @param array<string, mixed> $config
* @param array{model_provider?: string} $config
*
* @throws \InvalidArgumentException
*/
Expand Down
4 changes: 2 additions & 2 deletions src/Prompts/Builders/ChatPromptBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ChatPromptBuilder implements PromptBuilder
use BuildsPrompts;

/**
* @var \Cortex\LLM\Data\Messages\MessageCollection|array<int, \Cortex\LLM\Contracts\Message>|string
* @var \Cortex\LLM\Data\Messages\MessageCollection|array<int, \Cortex\LLM\Contracts\Message|\Cortex\LLM\Data\Messages\MessagePlaceholder>|string
*/
protected MessageCollection|array|string $messages = [];

Expand All @@ -32,7 +32,7 @@ public function build(): PromptTemplate&Pipeable
}

/**
* @param \Cortex\LLM\Data\Messages\MessageCollection|array<int, \Cortex\LLM\Contracts\Message>|string $messages
* @param \Cortex\LLM\Data\Messages\MessageCollection|non-empty-array<int, \Cortex\LLM\Contracts\Message|\Cortex\LLM\Data\Messages\MessagePlaceholder>|string $messages
*/
public function messages(MessageCollection|array|string $messages): self
{
Expand Down
12 changes: 10 additions & 2 deletions src/Prompts/Builders/Concerns/BuildsPrompts.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,22 @@ public function metadata(
StructuredOutputConfig|ObjectSchema|string|null $structuredOutput = null,
array $additional = [],
): self {
$this->metadata = new PromptMetadata(
return $this->setMetadata(new PromptMetadata(
$provider,
$model,
$parameters,
$tools,
$structuredOutput,
$additional,
);
));
}

/**
* Set the metadata for the prompt.
*/
public function setMetadata(PromptMetadata $metadata): self
{
$this->metadata = $metadata;

return $this;
}
Expand Down
25 changes: 25 additions & 0 deletions src/Prompts/Contracts/PromptBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,35 @@

namespace Cortex\Prompts\Contracts;

use Closure;
use Cortex\Pipeline;
use Cortex\LLM\Contracts\LLM;
use Cortex\JsonSchema\Types\ObjectSchema;
use Cortex\LLM\Data\StructuredOutputConfig;

interface PromptBuilder
{
/**
* Build the prompt template.
*/
public function build(): PromptTemplate;

/**
* Convenience method to build and pipe the prompt template to an LLM.
*/
public function llm(LLM|string|null $provider = null, Closure|string|null $model = null): Pipeline;

/**
* @param array<string, mixed> $parameters
* @param array<int, \Cortex\LLM\Contracts\Tool|\Closure|string> $tools
* @param array<string, mixed> $additional
*/
public function metadata(
?string $provider = null,
?string $model = null,
array $parameters = [],
array $tools = [],
StructuredOutputConfig|ObjectSchema|string|null $structuredOutput = null,
array $additional = [],
): self;
}
15 changes: 15 additions & 0 deletions src/Prompts/Contracts/PromptFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Cortex\Prompts\Contracts;

interface PromptFactory
{
/**
* Make a prompt template from the given name and options.
*
* @param array<string, mixed> $options
*/
public function make(string $name, array $options = []): PromptTemplate;
}
28 changes: 28 additions & 0 deletions src/Prompts/Enums/PromptType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Cortex\Prompts\Enums;

use Cortex\Prompts\Contracts\PromptBuilder;
use Cortex\Prompts\Builders\ChatPromptBuilder;
use Cortex\Prompts\Builders\TextPromptBuilder;

enum PromptType: string
{
case Chat = 'chat';
case Text = 'text';

/**
* Get the prompt builder for the given type.
*
* @return ($this is \Cortex\Prompts\Enums\PromptType::Chat ? \Cortex\Prompts\Builders\ChatPromptBuilder : \Cortex\Prompts\Builders\TextPromptBuilder)
*/
public function builder(): PromptBuilder
{
return match ($this) {
self::Chat => new ChatPromptBuilder(),
self::Text => new TextPromptBuilder(),
};
}
}
Loading
Loading