PHP code example of assistant-engine / filament-assistant

1. Go to this page and download the library: Download assistant-engine/filament-assistant library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

assistant-engine / filament-assistant example snippets


use AssistantEngine\Filament\FilamentAssistantPlugin;

class YourPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->plugin(FilamentAssistantPlugin::make());

    }
}

return [
    'api-url' => env('ASSISTANT_ENGINE_API', 'https://api.assistant-engine.com/v1/'),
    'api-key' => env('ASSISTANT_ENGINE_TOKEN'),
    'llm-provider-key' => env('OPENAI_API_KEY'),

    "chat" => [
        "render-assistant-message-as-markdown" => true,

        "disable-assistant-icon" => false,
        "disable-user-input" => false,

        "open-ai-recorder" => [
            "activate" => true,
            "open-ai-key" => env('OPENAI_API_KEY'),
            "language" => "en"
        ]
    ],
    'filament-assistant' => [
        'button' => [
            'show' => true,
            'options' => [
                'label' => 'Assistant',
                'size' => \Filament\Support\Enums\ActionSize::ExtraLarge,
                'color' => \Filament\Support\Colors\Color::Sky,
                'icon' => 'heroicon-o-chat-bubble-bottom-center-text'
            ]
        ],

        'conversation-option' => [
            'assistant-key' => env('ASSISTANT_ENGINE_ASSISTANT_KEY'),
            'conversation-resolver' => \AssistantEngine\Filament\Resolvers\ConversationOptionResolver::class,
            'context-resolver' => \AssistantEngine\Filament\Resolvers\ContextResolver::class
        ],

        'sidebar' => [
            'render' => true,
            'width' => 500,
            'show-without-trigger' => false
        ],
    ]
];



namespace AssistantEngine\Filament\Resolvers;

use AssistantEngine\Filament\Contracts\ConversationOptionResolverInterface;
use AssistantEngine\SDK\Models\Options\ConversationOption;
use Filament\Pages\Page;

class ConversationOptionResolver implements ConversationOptionResolverInterface
{
    public function resolve(Page $page): ?ConversationOption
    {
        $assistantKey = config('assistant-engine.filament-assistant.conversation-option.assistant-key');

        if (!$assistantKey) {
            throw new \Exception('assistant-key must be set');
        }

        $option = new ConversationOption($assistantKey, [
            'user_id' => auth()->check() ? auth()->user()->id : null
        ]);

        return $option;
    }
}

use AssistantEngine\SDK\Models\Options\ConversationOption;

// Create a new ConversationOption
$options = new ConversationOption('assistant_key', [
    'user_id' => 'user123',
    'subject_id' => 'subject456',
    'title' => 'New Conversation',
    'context' => ['topic' => 'tech support'],
    'additional_data' => ['foo' => 'bar'],
    'recreate' => true,
]);



namespace AssistantEngine\Filament\Resolvers;

use AssistantEngine\Filament\Contracts\ContextResolverInterface;
use Filament\Pages\Page;
use Filament\Resources\Pages\ListRecords;
use Filament\Resources\Pages\ManageRelatedRecords;
use Filament\Resources\RelationManagers\RelationManager;

class ContextResolver implements ContextResolverInterface
{
    public function resolve(Page $page): array
    {
        $result = [];

        // Collect models directly related to the page's record
        if (isset($page->record)) {
            $this->collectFromRecord($result, $page->record);
        }

        // Collect models for ListRecords page
        if ($page instanceof ListRecords) {
            $this->collectFromListRecordsPage($result, $page);
        }

        // Collect models for ManageRelatedRecords page
        if ($page instanceof ManageRelatedRecords) {
            $this->collectFromManageRelatedRecordsPage($result, $page);
        }

        // Collect models from relation managers
        if (method_exists($page, "getRelationManagers") && !empty($page->getRelationManagers())) {
            $this->collectFromRelationManagers($result, $page);
        }

        return $this->resolveCollectedModels($result);
    }
}



namespace App\Modules\Assistant\Resolvers;

use App\Filament\Resources\ProductResource\Pages\Ideas\IdeaPlanner;
use App\Modules\Product\Models\ProductGoal;
use App\Modules\Product\Models\ProductIdea;
use Filament\Pages\Page;

class ContextResolver extends \AssistantEngine\Filament\Resolvers\ContextResolver
{
    public function resolve(Page $page): array
    {
        $context = parent::resolve($page);

        return match (get_class($page)) {
            IdeaPlanner::class => $this->handleIdeaPlannerPage($page, $context),
            default => $context
        };
    }

    protected function handleIdeaPlannerPage(IdeaPlanner $page, array $context): array
    {
        $context['pageDescription'] = "This page shows a matrix where product goals are the rows and the roadmap phases (now, next, later)"
        . " are the columns. The user can drag and drop the product ideas between different phases and product goals"
        . " The Ideas you find in the context which don't belong to a goal are unassigned";

        $context = array_merge_recursive($context, $this->resolveModels(ProductGoal::class, $page->goals->all()));

        return array_merge_recursive($context, $this->resolveModels(ProductIdea::class, $page->ideas->all()));
    }
}



namespace AssistantEngine\Filament\Contracts;

use Filament\Pages\Page;

interface ContextModelInterface
{
    public static function resolveModels(array $models): array;
}



namespace AssistantEngine\Filament\Traits;

use AssistantEngine\Filament\Resolvers\ContextModelResolver;

trait ContextModel
{
    public static function getContextMetaData(): array
    {
        return [
            'schema' => self::class
        ];
    }

    public static function getContextExcludes(): array
    {
        return [];
    }

    public static function resolveModels(array $models): array
    {
        $result = [];
        $result['data'] = null;

        if (count($models) > 0) {
            $result['data'] = ContextModelResolver::collection($models)->resolve();
        }

        $result['meta'] = self::getContextMetaData();

        return $result;
    }
}

namespace AssistantEngine\Filament\Contracts\ContextModelInterface;

#[Schema(
    schema: "Product",
    properties: [
        new Property(property: "id", type: "integer"),
        new Property(property: "title", type: "string"),
        new Property(property: "description", type: "string"),
        new Property(property: "created_at", type: "string", format: "date-time"),
        new Property(property: "updated_at", type: "string", format: "date-time"),
    ]
)]
class Product extends Model implements ContextModelInterface
{
    use ContextModel;

    protected $fillable = ['title', 'description', 'integration_settings', 'assistant_overwrites'];

    public static function getContextExcludes(): array
    {
        return ['integration_settings'];
    }

    public static function getContextMetaData(): array
    {
        return ['schema' => 'Product'];
    }
}

#[On(ChatComponent::EVENT_RUN_FINISHED)]
public function onRunFinished()
{
    // Handle run finished event
}

MarkdownEditor::make('description')
    ->hintActions([
        Action::make('suggestion')
            ->button()
            ->action(function (AssistantEngine $engine, Set $set, Get $get) use ($goals) {
                $title = $get('title');

                if (!$title) {
                    Notification::make()
                        ->title('At least a title must be set')
                        ->danger()
                        ->send();

                    return;
                }

                $taskOptions = new TaskRunOption([
                    'title' => $title,
                    'object' => 'Product Goal',
                    'existing_goals' => $goals->toArray()
                ]);

                $output = $engine->initiateTaskRunAndPoll(env("ASSISTANT_ENGINE_TASK_SUGGESTION_TEXT"), $taskOptions);

                $set('description', $output->output);
            })
            ->icon('heroicon-o-bolt')
            ->color(Color::Sky),
    ])
    ->maxLength(65535)
    ->columnSpanFull();
bash
php artisan filament-assistant:publish-config
typescript
// resources/css/filament/admin(theme name)/tailwind.config.js
export default {
    content: [
        './vendor/assistant-engine/filament-assistant/resources/**/*.blade.php',
        './vendor/assistant-engine/laravel-assistant/resources/**/*.blade.php',
    ]
};