Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds embeddings #10

Merged
merged 15 commits into from
Sep 7, 2024
50 changes: 12 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ class SiteStatusCheckerAgent extends AgentAggregate
Now, let's implement the tool used by this agent:

```php
use LLM\Agents\Tool\Tool;
use LLM\Agents\Tool\PhpTool;
use LLM\Agents\Tool\ToolLanguage;

class CheckSiteAvailabilityTool extends Tool
class CheckSiteAvailabilityTool extends PhpTool
{
public const NAME = 'check_site_availability';

Expand Down Expand Up @@ -217,7 +217,7 @@ execution.
Here's an example of how you might call the linked agent:

```php
use LLM\Agents\Tool\Tool;
use LLM\Agents\Tool\PhpTool;
use LLM\Agents\Agent\AgentExecutor;
use LLM\Agents\LLM\Prompt\Chat\ToolCallResultMessage;
use LLM\Agents\LLM\Response\ToolCalledResponse;
Expand All @@ -227,7 +227,7 @@ use LLM\Agents\Tool\ToolLanguage;
/**
* @extends PhpTool<AskAgentInput>
*/
final class AskAgentTool extends Tool
final class AskAgentTool extends PhpTool
{
public const NAME = 'ask_agent';

Expand Down Expand Up @@ -735,44 +735,18 @@ class PromptGeneratorBootloader extends Bootloader

This class is responsible for handling conversions between JSON schemas and PHP objects.

Here's an example implementation of the `LLM\Agents\Tool\SchemaMapperInterface`:
We provide a schema mapper package that you can use to implement the `SchemaMapperInterface` in your project. This
package is a super handy JSON Schema Mapper for the LLM Agents project.

```php
use CuyZ\Valinor\Mapper\TreeMapper;
use LLM\Agents\Tool\SchemaMapperInterface;
use Spiral\JsonSchemaGenerator\Generator as JsonSchemaGenerator;

final readonly class SchemaMapper implements SchemaMapperInterface
{
public function __construct(
private JsonSchemaGenerator $generator,
private TreeMapper $mapper,
) {}

public function toJsonSchema(string $class): array
{
if (json_validate($class)) {
return json_decode($class, associative: true);
}

if (class_exists($class)) {
return $this->generator->generate($class)->jsonSerialize();
}
**To install the package:**

throw new \InvalidArgumentException("Invalid class or JSON schema provided: $class");
}

public function toObject(string $json, ?string $class = null): object
{
if ($class === null) {
return json_decode($json, associative: false);
}

return $this->mapper->map($class, json_decode($json, associative: true));
}
}
```bash
composer require llm-agents/json-schema-mapper
```

> **Note:** Read full documentation of the `llm-agents/json-schema-mapper`
> package [here](https://github.com/llm-agents-php/schema-mapper)

### → ContextFactoryInterface

It provides a clean way to pass execution-specific data through the system without tightly coupling components or overly
Expand Down
7 changes: 7 additions & 0 deletions src/Agent/Agent.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@

final class Agent extends Solution
{
/**
* @param string $key The unique key of the agent that is used to retrieve it
* @param string $name The name of the agent
* @param string $description The short description
* @param string $instruction The initial instruction for the agent to interact with the user
* @param bool $isActive
*/
public function __construct(
public readonly string $key,
string $name,
Expand Down
15 changes: 14 additions & 1 deletion src/Agent/AgentAggregate.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

use LLM\Agents\Agent\Exception\AgentModelException;
use LLM\Agents\Agent\Exception\MissingModelException;
use LLM\Agents\Embeddings\HasLinkedContextSourcesInterface;
use LLM\Agents\Solution\AgentLink;
use LLM\Agents\Solution\ContextSourceLink;
use LLM\Agents\Solution\MetadataType;
use LLM\Agents\Solution\Model;
use LLM\Agents\Solution\Solution;
Expand All @@ -17,7 +19,10 @@
/**
* @psalm-type TAssociation = Solution|Model|ToolLink|AgentLink
*/
class AgentAggregate implements AgentInterface
class AgentAggregate implements AgentInterface,
HasLinkedAgentsInterface,
HasLinkedToolsInterface,
HasLinkedContextSourcesInterface
{
/**
* @var array<TAssociation>
Expand Down Expand Up @@ -56,6 +61,14 @@ public function getTools(): array
);
}

public function getContextSources(): array
{
return \array_filter(
$this->associations,
static fn(Solution $association): bool => $association instanceof ContextSourceLink,
);
}

public function getAgents(): array
{
return \array_filter(
Expand Down
18 changes: 18 additions & 0 deletions src/Agent/AgentFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,25 @@

namespace LLM\Agents\Agent;

namespace LLM\Agents\Agent;

/**
* It defines a contract for creating instances of agents. It encapsulates the complex process of agent
* initialization, configuration, and setup.
*
* Purpose:
* 1. Abstraction: It provides a level of abstraction between the agent creation
* process and the rest of the application, allowing for different implementation
* strategies without affecting the client code.
*
* 2. Flexibility: By using a factory interface, the framework can support multiple
* types of agents or different initialization strategies for agents without
* changing the core logic.
*/
interface AgentFactoryInterface
{
/**
* Create and return a fully initialized agent instance.
*/
public function create(): AgentInterface;
}
39 changes: 32 additions & 7 deletions src/Agent/AgentInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,67 @@
use LLM\Agents\Solution\ToolLink;

/**
* Represents an AI agent capable of performing tasks, making decisions,
* and interacting with various tools and other agents.
* @psalm-type TAssociation = Solution|Model|ToolLink|AgentLink
*/
interface AgentInterface
{
/**
* Get the unique key identifier for the agent.
*/
public function getKey(): string;

/**
* Get the human-readable name of the agent.
*/
public function getName(): string;

/**
* Get the description of the agent's purpose and capabilities.
*/
public function getDescription(): ?string;

public function getInstruction(): string;

/**
* @return array<ToolLink>
* Get the primary instruction set for the agent.
*/
public function getTools(): array;
public function getInstruction(): string;

/**
* @return array<AgentLink>
* Get the language model associated with this agent.
*/
public function getAgents(): array;

public function getModel(): Model;

/**
* Get the agent's memory, containing learned information and experiences.
*
* @return array<SolutionMetadata>
*/
public function getMemory(): array;

/**
* Get the list of predefined prompts for the agent.
*
* @return array<SolutionMetadata>
*/
public function getPrompts(): array;

/**
* Get the agent's configuration settings.
*
* This method returns an array of configuration settings for the agent,
* which can include parameters for the LLM (Language Model) client configuration.
* These settings may affect how the agent interacts with the language model,
* including parameters like temperature, max tokens, and other model-specific options.
*
* @return array<SolutionMetadata>
*
* @example
* [
* new SolutionMetadata(MetadataType::Configuration, 'temperature', 0.7),
* new SolutionMetadata(MetadataType::Configuration, 'max_tokens', 150),
* new SolutionMetadata(MetadataType::Configuration, 'top_p', 1),
* ]
*/
public function getConfiguration(): array;
}
11 changes: 11 additions & 0 deletions src/Agent/AgentRegistryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,25 @@

use LLM\Agents\Agent\Exception\AgentAlreadyRegisteredException;

/**
* It defines the contract for a registry that manages the registration of agents.
*
* Purpose:
* - Provide a centralized mechanism for registering new agents in the system.
* - Allow for dynamic addition of agents at runtime.
*/
interface AgentRegistryInterface
{
/**
* Register a new agent in the system.
*
* @throws AgentAlreadyRegisteredException
*/
public function register(AgentInterface $agent): void;

/**
* Retrieve all registered agents.
*
* @return AgentInterface[]
*/
public function all(): iterable;
Expand Down
20 changes: 20 additions & 0 deletions src/Agent/AgentRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,32 @@

use LLM\Agents\Agent\Exception\AgentNotFoundException;

/**
* It defines the contract for a repository that provides access to registered agents.
*
* Purpose:
* - Provide a standardized way to retrieve specific agents by their unique keys.
* - Allow checking for the existence of agents in the system.
*
* This interface is essential for components that need to work with specific
* agents. It abstracts the storage and retrieval mechanisms, allowing for
* different implementations (e.g., in-memory, database-backed) without
* affecting the consumers of the interface.
*/
interface AgentRepositoryInterface
{
/**
* Retrieve an agent by its unique key.
*
* @param non-empty-string $key The unique key of the agent to retrieve.
* @throws AgentNotFoundException
*/
public function get(string $key): AgentInterface;

/**
* Check if an agent with the given key exists in the repository.
*
* @param non-empty-string $key The key to check for existence.
*/
public function has(string $key): bool;
}
7 changes: 7 additions & 0 deletions src/Agent/Execution.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@
use LLM\Agents\LLM\Prompt\Chat\PromptInterface;
use LLM\Agents\LLM\Response\Response;

/**
* Represents the result of an agent's execution, including the response and the prompt used.
*/
final readonly class Execution
{
/**
* @param Response $result The response from the agent's execution.
* @param PromptInterface $prompt The prompt used for the execution.
*/
public function __construct(
public Response $result,
public PromptInterface $prompt,
Expand Down
17 changes: 17 additions & 0 deletions src/Agent/HasLinkedAgentsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace LLM\Agents\Agent;

use LLM\Agents\Solution\AgentLink;

interface HasLinkedAgentsInterface
{
/**
* Get the list of other agents this agent can interact with.
*
* @return array<AgentLink>
*/
public function getAgents(): array;
}
17 changes: 17 additions & 0 deletions src/Agent/HasLinkedToolsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace LLM\Agents\Agent;

use LLM\Agents\Solution\ToolLink;

interface HasLinkedToolsInterface
{
/**
* Get the list of tools available to the agent.
*
* @return array<ToolLink>
*/
public function getTools(): array;
}
Loading