Skip to content

Commit 7b8b61f

Browse files
feat: implement CustomerSupport agent and add SendMessageRequest for chat handling
1 parent 9044b40 commit 7b8b61f

3 files changed

Lines changed: 111 additions & 0 deletions

File tree

app/Ai/Agents/CustomerSupport.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace App\Ai\Agents;
4+
5+
use Laravel\Ai\Attributes\Provider;
6+
use Laravel\Ai\Concerns\RemembersConversations;
7+
use Laravel\Ai\Contracts\Agent;
8+
use Laravel\Ai\Contracts\Conversational;
9+
use Laravel\Ai\Promptable;
10+
use Stringable;
11+
12+
#[Provider('gemini')]
13+
class CustomerSupport implements Agent, Conversational
14+
{
15+
use Promptable, RemembersConversations;
16+
17+
/**
18+
* Get the instructions that the agent should follow.
19+
*/
20+
public function instructions(): Stringable|string
21+
{
22+
return <<<'PROMPT'
23+
You are a friendly and professional customer support agent. Your role is to:
24+
25+
- Answer customer questions clearly and concisely.
26+
- Help resolve issues with empathy and patience.
27+
- Escalate complex problems when you cannot resolve them directly.
28+
- Always maintain a polite and helpful tone.
29+
30+
If you don't know the answer, be honest and suggest the customer contact a human agent for further assistance.
31+
PROMPT;
32+
}
33+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Ai\Agents\CustomerSupport;
6+
use App\Http\Requests\Chat\SendMessageRequest;
7+
use Generator;
8+
use Illuminate\Support\Facades\DB;
9+
use Laravel\Ai\Streaming\Events\TextDelta;
10+
use Symfony\Component\HttpFoundation\StreamedResponse;
11+
12+
class ChatController extends Controller
13+
{
14+
/**
15+
* Stream a chat response from the CustomerSupport agent.
16+
*/
17+
public function stream(SendMessageRequest $request): StreamedResponse
18+
{
19+
$user = $request->user();
20+
$message = $request->validated('message');
21+
$conversationId = $request->validated('conversation_id');
22+
23+
$agent = new CustomerSupport;
24+
25+
if ($conversationId) {
26+
$conversationRecord = DB::table('agent_conversations')
27+
->where('id', $conversationId)
28+
->where('user_id', $user->id)
29+
->first();
30+
31+
abort_unless($conversationRecord, 403);
32+
33+
$stream = $agent->continue($conversationId, as: $user)->stream($message);
34+
} else {
35+
$stream = $agent->forUser($user)->stream($message);
36+
}
37+
38+
return response()->stream(function () use ($stream): Generator {
39+
foreach ($stream as $event) {
40+
if ($event instanceof TextDelta) {
41+
yield $event->delta;
42+
}
43+
}
44+
45+
yield "\n<<conversation:{$stream->conversationId}>>";
46+
});
47+
}
48+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace App\Http\Requests\Chat;
4+
5+
use Illuminate\Contracts\Validation\ValidationRule;
6+
use Illuminate\Foundation\Http\FormRequest;
7+
8+
class SendMessageRequest extends FormRequest
9+
{
10+
/**
11+
* Determine if the user is authorized to make this request.
12+
*/
13+
public function authorize(): bool
14+
{
15+
return true;
16+
}
17+
18+
/**
19+
* Get the validation rules that apply to the request.
20+
*
21+
* @return array<string, ValidationRule|array<mixed>|string>
22+
*/
23+
public function rules(): array
24+
{
25+
return [
26+
'message' => ['required', 'string', 'max:5000'],
27+
'conversation_id' => ['nullable', 'string', 'uuid'],
28+
];
29+
}
30+
}

0 commit comments

Comments
 (0)