From 1aac40bf0e173634aa7aafe5ce887813ff38fcc1 Mon Sep 17 00:00:00 2001 From: Ashley Johnson <61059402+PapaRascal2020@users.noreply.github.com> Date: Wed, 2 Oct 2024 19:48:44 +0100 Subject: [PATCH] Draft(SK): Livewire scaffolding - coming soon --- src/Drivers/OpenAi.php | 2 +- src/Utilities/Utilities.php | 2 +- .../app/Livewire/Sidekick/AudioGeneration.php | 43 +++++++++ stubs/livewire/app/Livewire/Sidekick/Chat.php | 47 +++++++++ .../app/Livewire/Sidekick/ChatRoom.php | 93 ++++++++++++++++++ .../app/Livewire/Sidekick/Completion.php | 36 +++++++ .../app/Livewire/Sidekick/Embeddding.php | 36 +++++++ .../app/Livewire/Sidekick/ImageGeneration.php | 47 +++++++++ .../livewire/app/Livewire/Sidekick/Index.php | 16 ++++ .../app/Livewire/Sidekick/Moderation.php | 28 ++++++ .../app/Livewire/Sidekick/Transcription.php | 33 +++++++ .../views/Components/layouts/app.blade.php | 57 +++++++++++ .../Components/sidekick-bot-message.blade.php | 17 ++++ .../sidekick-user-message.blade.php | 10 ++ .../views/livewire/audio-generation.blade.php | 53 ++++++++++ .../views/livewire/chat-room.blade.php | 96 +++++++++++++++++++ .../resources/views/livewire/chat.blade.php | 46 +++++++++ .../views/livewire/completion.blade.php | 46 +++++++++ .../views/livewire/embeddding.blade.php | 46 +++++++++ .../views/livewire/image-generation.blade.php | 55 +++++++++++ .../resources/views/livewire/index.blade.php | 13 +++ .../views/livewire/moderation.blade.php | 58 +++++++++++ .../views/livewire/transcription.blade.php | 47 +++++++++ stubs/livewire/routes/web.sidekick.php | 32 +++++++ 24 files changed, 957 insertions(+), 2 deletions(-) create mode 100644 stubs/livewire/app/Livewire/Sidekick/AudioGeneration.php create mode 100644 stubs/livewire/app/Livewire/Sidekick/Chat.php create mode 100644 stubs/livewire/app/Livewire/Sidekick/ChatRoom.php create mode 100644 stubs/livewire/app/Livewire/Sidekick/Completion.php create mode 100644 stubs/livewire/app/Livewire/Sidekick/Embeddding.php create mode 100644 stubs/livewire/app/Livewire/Sidekick/ImageGeneration.php create mode 100644 stubs/livewire/app/Livewire/Sidekick/Index.php create mode 100644 stubs/livewire/app/Livewire/Sidekick/Moderation.php create mode 100644 stubs/livewire/app/Livewire/Sidekick/Transcription.php create mode 100644 stubs/livewire/resources/views/Components/layouts/app.blade.php create mode 100644 stubs/livewire/resources/views/Components/sidekick-bot-message.blade.php create mode 100644 stubs/livewire/resources/views/Components/sidekick-user-message.blade.php create mode 100644 stubs/livewire/resources/views/livewire/audio-generation.blade.php create mode 100644 stubs/livewire/resources/views/livewire/chat-room.blade.php create mode 100644 stubs/livewire/resources/views/livewire/chat.blade.php create mode 100644 stubs/livewire/resources/views/livewire/completion.blade.php create mode 100644 stubs/livewire/resources/views/livewire/embeddding.blade.php create mode 100644 stubs/livewire/resources/views/livewire/image-generation.blade.php create mode 100644 stubs/livewire/resources/views/livewire/index.blade.php create mode 100644 stubs/livewire/resources/views/livewire/moderation.blade.php create mode 100644 stubs/livewire/resources/views/livewire/transcription.blade.php create mode 100644 stubs/livewire/routes/web.sidekick.php diff --git a/src/Drivers/OpenAi.php b/src/Drivers/OpenAi.php index a7b593e..c2fffcd 100644 --- a/src/Drivers/OpenAi.php +++ b/src/Drivers/OpenAi.php @@ -186,7 +186,7 @@ public function embedding(): Embedding public function moderate(): Moderate { return new Moderate( - url: "{$this->baseUrl}/moderation's", + url: "{$this->baseUrl}/moderations", headers: $this->headers ); } diff --git a/src/Utilities/Utilities.php b/src/Utilities/Utilities.php index 05fad64..caa8eb4 100644 --- a/src/Utilities/Utilities.php +++ b/src/Utilities/Utilities.php @@ -129,7 +129,7 @@ public function store(string $data, string $mimeType = null): string file_put_contents($filePath, $data); // Return the local path of the stored file - return $filePath; + return asset('uploads/' . $filename); } /** diff --git a/stubs/livewire/app/Livewire/Sidekick/AudioGeneration.php b/stubs/livewire/app/Livewire/Sidekick/AudioGeneration.php new file mode 100644 index 0000000..d8c3123 --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/AudioGeneration.php @@ -0,0 +1,43 @@ +audio()->fromText( + model: 'tts-1', + text: $this->prompt); + + $response_json = json_decode($response, true); + + if(isset($response_json['error'])) { + $this->errors = $response_json['error']['message']; + } else { + $this->audio = base64_encode($response); + $this->savedFile = sidekick(new OpenAi)->utilities()->store($response, 'audio/mpeg'); + } + } + + public function render() + { + return view('livewire.audio-generation') + ->layout('Components.layouts.app', [ + 'title' => 'Audio Generation', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ] + ); + } +} diff --git a/stubs/livewire/app/Livewire/Sidekick/Chat.php b/stubs/livewire/app/Livewire/Sidekick/Chat.php new file mode 100644 index 0000000..c17c34f --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/Chat.php @@ -0,0 +1,47 @@ +config, true); + + if(!$config) + { + $config = [ + "engine" => "\PapaRascalDev\Sidekick\Drivers\OpenAi", + "model" => "gpt-3.5-turbo" + ]; + } + + // This is the system prompt the user wants the AI to use + $systemPrompt = $this->prompt; + + + $conversation = sidekickConversation()->begin( + driver: new $config['engine'](), + model: $config['model'], + systemPrompt: $systemPrompt + ); + + return redirect()->to('/sidekick/chat/' . $conversation->id); + } + + public function render() + { + return view('livewire.chat')->layout('Components.layouts.app', [ + 'title' => 'Chat', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ]); + } +} diff --git a/stubs/livewire/app/Livewire/Sidekick/ChatRoom.php b/stubs/livewire/app/Livewire/Sidekick/ChatRoom.php new file mode 100644 index 0000000..44b2c65 --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/ChatRoom.php @@ -0,0 +1,93 @@ +messages = collect(); + if ($id) { + $this->loadConversation($id); + } + } + + public function loadConversation($id) + { + $conversation = sidekickConversation()->resume($id); + $this->conversationId = $conversation->model->id; + $this->config = [ + 'engine' => $conversation->model->class, + 'model' => $conversation->model->model, + ]; + $this->messages = collect($conversation->model->messages)->map(function ($message) { + return (object) $message; + }); + } + + public function sendMessage() + { + $this->messages->push((object) [ + 'role' => 'user', + 'content' => $this->newMessage + ]); + + if ($this->isStreaming) { + $this->streamingResponse = ''; + $this->dispatch('startStreaming'); + } else { + $response = sidekickConversation() + ->resume($this->conversationId) + ->sendMessage($this->newMessage, false); + + $this->messages->push((object) [ + 'role' => 'assistant', + 'content' => $response + ]); + } + + $this->newMessage = ''; + $this->dispatch('messageAdded'); + } + + #[On('streamChunk')] + public function handleStreamChunk($chunk) + { + $this->streamingResponse .= $chunk; + } + + #[On('endStreaming')] + public function endStreaming() + { + $this->messages->push((object) [ + 'role' => 'assistant', + 'content' => $this->streamingResponse + ]); + $this->streamingResponse = ''; + } + + public function delete($id) + { + sidekickConversation()->delete($id); + return redirect()->to('/sidekick/chat'); + } + + public function render() + { + return view('livewire.chat-room')->layout('Components.layouts.app', [ + 'title' => 'Chat', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ]); + } +} diff --git a/stubs/livewire/app/Livewire/Sidekick/Completion.php b/stubs/livewire/app/Livewire/Sidekick/Completion.php new file mode 100644 index 0000000..53e6aee --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/Completion.php @@ -0,0 +1,36 @@ +response = sidekick(new OpenAi)->complete( + model: 'gpt-3.5-turbo', + systemPrompt: 'You are a knowledge base, please answer there questions', + message: $this->prompt + ); + + + $this->prompt = ''; + + } + + public function render() + { + return view('livewire.completion')->layout('Components.layouts.app', [ + 'title' => 'Completion', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ]); + } +} diff --git a/stubs/livewire/app/Livewire/Sidekick/Embeddding.php b/stubs/livewire/app/Livewire/Sidekick/Embeddding.php new file mode 100644 index 0000000..9e1742d --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/Embeddding.php @@ -0,0 +1,36 @@ +response = sidekick(new OpenAi)->embedding()->make( + model:'text-embedding-3-large', + input: $this->prompt, + ); + + + $this->prompt = ''; + + } + + public function render() + { + return view('livewire.embeddding')->layout('Components.layouts.app', [ + 'title' => 'Embedding', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ]); + } +} diff --git a/stubs/livewire/app/Livewire/Sidekick/ImageGeneration.php b/stubs/livewire/app/Livewire/Sidekick/ImageGeneration.php new file mode 100644 index 0000000..fcdbf3b --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/ImageGeneration.php @@ -0,0 +1,47 @@ +image()->make( + model:$this->model, + prompt: $this->prompt, + width:'1024', + height:'1024' + ); + + $this->prompt = ''; + + if(isset($response['data'][0]['url'])) { + $this->image = $response['data'][0]['url']; + $this->savedFile = sidekick(new OpenAi)->utilities()->store($response['data'][0]['url'], 'image/png'); + } else { + $this->errors = $response['error']['message']; + } + } + + public function render() + { + return view('livewire.image-generation') + ->layout('Components.layouts.app', [ + 'title' => 'Image Generation', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ] + ); + } +} diff --git a/stubs/livewire/app/Livewire/Sidekick/Index.php b/stubs/livewire/app/Livewire/Sidekick/Index.php new file mode 100644 index 0000000..8a3374e --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/Index.php @@ -0,0 +1,16 @@ +layout('Components.layouts.app', [ + 'title' => '', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ]); + } +} diff --git a/stubs/livewire/app/Livewire/Sidekick/Moderation.php b/stubs/livewire/app/Livewire/Sidekick/Moderation.php new file mode 100644 index 0000000..ba98c18 --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/Moderation.php @@ -0,0 +1,28 @@ +response = sidekick(new OpenAi)->moderate()->text( + model:'text-moderation-latest', + content: $this->prompt + ); + } + + public function render() + { + return view('livewire.moderation')->layout('Components.layouts.app', [ + 'title' => 'Moderation', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ]); + } +} diff --git a/stubs/livewire/app/Livewire/Sidekick/Transcription.php b/stubs/livewire/app/Livewire/Sidekick/Transcription.php new file mode 100644 index 0000000..1d3907a --- /dev/null +++ b/stubs/livewire/app/Livewire/Sidekick/Transcription.php @@ -0,0 +1,33 @@ +response = sidekick(new OpenAi)->transcribe()->audioFile( + model:'whisper-1', + filePath:$this->prompt + ); + + } + + public function render() + { + return view('livewire.transcription')->layout('Components.layouts.app', [ + 'title' => 'Transcription', + 'conversations' => sidekickConversation()->database()->all('id', 'model') + ]); + } +} diff --git a/stubs/livewire/resources/views/Components/layouts/app.blade.php b/stubs/livewire/resources/views/Components/layouts/app.blade.php new file mode 100644 index 0000000..97332f4 --- /dev/null +++ b/stubs/livewire/resources/views/Components/layouts/app.blade.php @@ -0,0 +1,57 @@ + + + + + + + {{ $title ? "$title - Sidekick Playground" : "Sidekick Playground" }} + + + + + +
+ + + + + +
+ {{ $slot }} +
+
+ +@stack('page-scripts') + + + + diff --git a/stubs/livewire/resources/views/Components/sidekick-bot-message.blade.php b/stubs/livewire/resources/views/Components/sidekick-bot-message.blade.php new file mode 100644 index 0000000..4f1fc99 --- /dev/null +++ b/stubs/livewire/resources/views/Components/sidekick-bot-message.blade.php @@ -0,0 +1,17 @@ +
+
+

+ + + + + + + + + + Assistant

+

{{ $slot }}

+
+
diff --git a/stubs/livewire/resources/views/Components/sidekick-user-message.blade.php b/stubs/livewire/resources/views/Components/sidekick-user-message.blade.php new file mode 100644 index 0000000..10dc6cd --- /dev/null +++ b/stubs/livewire/resources/views/Components/sidekick-user-message.blade.php @@ -0,0 +1,10 @@ +
+
+

+ + + User

+

{{ $slot }}

+
+
diff --git a/stubs/livewire/resources/views/livewire/audio-generation.blade.php b/stubs/livewire/resources/views/livewire/audio-generation.blade.php new file mode 100644 index 0000000..c3024d7 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/audio-generation.blade.php @@ -0,0 +1,53 @@ +
+
+
+
+
+

🤖 Audio Generation Sample

+

Enter text below and click Generate to create an audio file.

+ + @if($errors) + + @endif + + @if($audio) +
+ +
+ + + @endif +
+
+
+
+ + +
+ diff --git a/stubs/livewire/resources/views/livewire/chat-room.blade.php b/stubs/livewire/resources/views/livewire/chat-room.blade.php new file mode 100644 index 0000000..a600e86 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/chat-room.blade.php @@ -0,0 +1,96 @@ +
+ +
+

Conversation (id: {{$conversationId}}) - Model: {{ $config['model'] ?? 'Auto-Select'}}

+ +
+ New Chat + +
+
+ + +
+
+ @if($messages->isEmpty()) +
+

To start the conversation send a message

+
+ @else + @foreach($messages as $message) + @if(strtolower($message->role) === 'user') + + {!! $message->content !!} + + @else + + {!! nl2br($message->content) !!} + + @endif + @endforeach + @endif + + @if($streamingResponse) +
+

{{ $streamingResponse }}

+
+ @endif +
+
+ + +
diff --git a/stubs/livewire/resources/views/livewire/chat.blade.php b/stubs/livewire/resources/views/livewire/chat.blade.php new file mode 100644 index 0000000..b692816 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/chat.blade.php @@ -0,0 +1,46 @@ +
+
+
+
+
+

🤖 Assistant

+

To begin a conversation select a model and type a system prompt to start.

+
+
+
+
+ + +
diff --git a/stubs/livewire/resources/views/livewire/completion.blade.php b/stubs/livewire/resources/views/livewire/completion.blade.php new file mode 100644 index 0000000..e04fec2 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/completion.blade.php @@ -0,0 +1,46 @@ +
+
+
+
+
+

🤖 Completion Sample

+

Type some text into the box below and click to see the AI's response.

+
+
+ +
+
+
+ + + + +
Generating Response...
+
+
+ @if($response) +
+

Response

+

{{ $response }}

+
+ @endif +
+
+
+ + +
diff --git a/stubs/livewire/resources/views/livewire/embeddding.blade.php b/stubs/livewire/resources/views/livewire/embeddding.blade.php new file mode 100644 index 0000000..bc71ae0 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/embeddding.blade.php @@ -0,0 +1,46 @@ +
+
+
+
+
+

🤖 Embedding Generation Sample

+

Type some text into the box below and click to see it's vector representation response.

+
+
+ +
+
+
+ + + + +
Generating Text...
+
+
+ @if(isset($response)) +
+

Response

+ +
+ @endif +
+
+
+ + +
diff --git a/stubs/livewire/resources/views/livewire/image-generation.blade.php b/stubs/livewire/resources/views/livewire/image-generation.blade.php new file mode 100644 index 0000000..adfc0f4 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/image-generation.blade.php @@ -0,0 +1,55 @@ +
+
+
+
+
+

🤖 Image Generation Sample

+

Describe the image you want in the text box below and click to generate an image.

+ @if(isset($image)) + generated image + + + @endif + @if($errors) + + @endif +
+
+ + + + +
Generating Image...
+
+
+
+
+
+
+ + +
diff --git a/stubs/livewire/resources/views/livewire/index.blade.php b/stubs/livewire/resources/views/livewire/index.blade.php new file mode 100644 index 0000000..33c8aa2 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/index.blade.php @@ -0,0 +1,13 @@ +
+
+
+
+

Hello!

+ Sidekick Robot +

Note: To use this playground you must have configured the .env with your SIDEKICK_OPENAI_TOKEN.

+
+
+
+
diff --git a/stubs/livewire/resources/views/livewire/moderation.blade.php b/stubs/livewire/resources/views/livewire/moderation.blade.php new file mode 100644 index 0000000..601c693 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/moderation.blade.php @@ -0,0 +1,58 @@ +
+
+
+
+
+

🤖 Moderate Sample

+

Type a dummy comment or post into the text box below and hit . The AI will then review the content and send back a moderation response.

+
+
+ +
+
+
+ + + + +
Moderating Content...
+
+
+ @if(isset($response)) +
+ @if (isset($response['error'])) +

An error occurred: {{ $response['error']['message'] }}

+ @elseif (!$response['results'][0]['flagged']) +

The content is fine

+ @else +

This content has been flagged due to the following categories:

+
    + @foreach($response['results'][0]['categories'] as $category => $value) + @if($value) +
  • {{ $category }}
  • + @endif + @endforeach +
+ @endif +
+ @endif +
+
+
+ + +
diff --git a/stubs/livewire/resources/views/livewire/transcription.blade.php b/stubs/livewire/resources/views/livewire/transcription.blade.php new file mode 100644 index 0000000..d3964d5 --- /dev/null +++ b/stubs/livewire/resources/views/livewire/transcription.blade.php @@ -0,0 +1,47 @@ +
+
+
+
+
+

🤖 Transcription Generation Sample

+

Enter a URL to an audio file and click to generate the transcription (audio to text). + For convenience, Sidekick has added an example URL in case you don't know where to find one.

+
+
+ +
+
+
+ + + + +
Generating Text...
+
+
+ @if(isset($response)) +
+

Response

+

{!! $response['text'] !!}

+
+ @endif +
+
+
+ + +
diff --git a/stubs/livewire/routes/web.sidekick.php b/stubs/livewire/routes/web.sidekick.php new file mode 100644 index 0000000..c48ae44 --- /dev/null +++ b/stubs/livewire/routes/web.sidekick.php @@ -0,0 +1,32 @@ +resume($request->get('conversation_id')) + ->sendMessage($request->get('message'), $request->get('stream')); +}); + +Route::get('/sidekick/chat/{id}', ChatRoom::class); + +