Skip to content

Commit 57716f5

Browse files
authored
Merge pull request #46 from LlmLaraHub/assistant
Assistant
2 parents 885f402 + d819dc0 commit 57716f5

File tree

69 files changed

+3136
-106
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3136
-106
lines changed

Modules/LlmDriver/app/BaseClient.php

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use LlmLaraHub\LlmDriver\Functions\Chat;
88
use LlmLaraHub\LlmDriver\Functions\CreateDocument;
99
use LlmLaraHub\LlmDriver\Functions\CreateEventTool;
10+
use LlmLaraHub\LlmDriver\Functions\CreateTasksTool;
1011
use LlmLaraHub\LlmDriver\Functions\FunctionContract;
1112
use LlmLaraHub\LlmDriver\Functions\FunctionDto;
1213
use LlmLaraHub\LlmDriver\Functions\GatherInfoTool;
@@ -29,6 +30,8 @@ abstract class BaseClient
2930

3031
protected int $poolSize = 3;
3132

33+
protected ?string $system = null;
34+
3235
protected bool $limitByShowInUi = false;
3336

3437
protected ToolTypes $toolType = ToolTypes::NoFunction;
@@ -66,6 +69,7 @@ public function getFunctions(): array
6669
new CreateEventTool(),
6770
//new CreateDocument(),
6871
new SatisfyToolsRequired(),
72+
new CreateTasksTool(),
6973
//new Chat(),
7074
]
7175
);
@@ -117,6 +121,10 @@ public function modifyPayload(array $payload, bool $noTools = false): array
117121
$payload['tools'] = $this->getFunctions();
118122
}
119123

124+
if ($this->system) {
125+
$payload['system'] = $this->system;
126+
}
127+
120128
$payload = $this->addJsonFormat($payload);
121129

122130
return $payload;

Modules/LlmDriver/app/ClaudeClient.php

+23-12
Original file line numberDiff line numberDiff line change
@@ -346,15 +346,31 @@ public function remapMessages(array $messages, bool $userLast = false): array
346346
/**
347347
* Claude needs to not start with a system message
348348
*/
349-
$messages = collect($messages)->transform(function ($item) {
350-
if ($item->role === 'system') {
351-
$item->role = 'assistant';
352-
}
349+
$messages = collect($messages)
350+
->filter(function ($item) {
351+
if ($item->role === 'system') {
352+
$this->system = $item->content;
353353

354-
$item->content = str($item->content)->replaceEnd("\n", '')->trim()->toString();
354+
return false;
355+
}
355356

356-
return $item->toArray();
357-
});
357+
return true;
358+
})
359+
->transform(function (MessageInDto $item) {
360+
/**
361+
* @NOTE
362+
* Claude does not like to end a certain way
363+
*/
364+
$item->content = str(
365+
cleanString($item->content)
366+
)->replaceEnd("\n", '')->trim()->toString();
367+
368+
if (empty($item->content)) {
369+
$item->content = 'See content in thread.';
370+
}
371+
372+
return $item->toArray();
373+
});
358374

359375
/**
360376
* Claude needs me to not use the role tool
@@ -369,11 +385,6 @@ public function remapMessages(array $messages, bool $userLast = false): array
369385
$toolId = data_get($item, 'tool_id', 'toolu_'.Str::random(32));
370386
$tool = data_get($item, 'tool', 'unknown_tool');
371387
$args = data_get($item, 'args', '{}');
372-
Log::info('Claude Tool Found', [
373-
'tool' => $tool,
374-
'tool_id' => $toolId,
375-
'args' => $args,
376-
]);
377388

378389
$content = $item['content'];
379390

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
namespace LlmLaraHub\LlmDriver\Functions;
4+
5+
use App\Models\Message;
6+
use App\Models\Task;
7+
use App\Models\User;
8+
use Illuminate\Support\Facades\Log;
9+
use LlmLaraHub\LlmDriver\Responses\FunctionResponse;
10+
11+
class CreateTasksTool extends FunctionContract
12+
{
13+
protected string $name = 'create_tasks_tool';
14+
15+
protected string $description = 'If the Campaign needs to have tasks created or the users prompt requires it you can use this tool to make multiple tasks';
16+
17+
public bool $showInUi = true;
18+
19+
public array $toolTypes = [
20+
ToolTypes::Source,
21+
ToolTypes::Output,
22+
ToolTypes::Chat,
23+
ToolTypes::ChatCompletion,
24+
];
25+
26+
public function handle(
27+
Message $message): FunctionResponse
28+
{
29+
Log::info('TaskTool called');
30+
31+
$args = $message->args;
32+
foreach (data_get($args, 'tasks', []) as $taskArg) {
33+
$name = data_get($taskArg, 'name', null);
34+
$details = data_get($taskArg, 'details', null);
35+
$due_date = data_get($taskArg, 'due_date', null);
36+
$assistant = data_get($taskArg, 'assistant', false);
37+
$user_id = data_get($taskArg, 'user_id', null);
38+
39+
$project = $message->chat->getChatable();
40+
41+
Task::updateOrCreate([
42+
'name' => $name,
43+
'project_id' => $project->id,
44+
],
45+
[
46+
'details' => $details,
47+
'due_date' => $due_date,
48+
'assistant' => $assistant,
49+
'user_id' => ($user_id !== '' && User::whereId($user_id)->exists()) ? $user_id : null,
50+
]);
51+
}
52+
53+
return FunctionResponse::from([
54+
'content' => json_encode($args),
55+
]);
56+
}
57+
58+
/**
59+
* @return PropertyDto[]
60+
*/
61+
protected function getProperties(): array
62+
{
63+
return [
64+
new PropertyDto(
65+
name: 'tasks',
66+
description: 'Array of task objects',
67+
type: 'array',
68+
required: true,
69+
properties: [
70+
new PropertyDto(
71+
name: 'items',
72+
description: 'Task object',
73+
type: 'object',
74+
required: true,
75+
properties: [
76+
new PropertyDto(
77+
name: 'name',
78+
description: 'Name of the task',
79+
type: 'string',
80+
required: true
81+
),
82+
new PropertyDto(
83+
name: 'details',
84+
description: 'Detailed info of the task',
85+
type: 'string',
86+
required: true
87+
),
88+
new PropertyDto(
89+
name: 'due_date',
90+
description: 'Due date if any format "Y-m-d"',
91+
type: 'string',
92+
required: true
93+
),
94+
new PropertyDto(
95+
name: 'assistant',
96+
description: 'Should the assistant be assigned this true or false',
97+
type: 'string',
98+
),
99+
new PropertyDto(
100+
name: 'user_id',
101+
description: 'User id if assigned to a user',
102+
type: 'string',
103+
),
104+
]
105+
),
106+
]
107+
),
108+
];
109+
}
110+
}

Modules/LlmDriver/app/Functions/SearchAndSummarize.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public function handle(
8585
* @TODO @WHY
8686
* Why do I do this system prompt thing?
8787
*/
88-
$assistantMessage = $message->getChat()->addInput(
88+
$message->getChat()->addInput(
8989
message: $contentFlattened,
9090
role: RoleEnum::Assistant,
9191
systemPrompt: $message->getChat()->getChatable()->systemPrompt(),
@@ -116,7 +116,8 @@ public function handle(
116116
/** @var CompletionResponse $response */
117117
$response = LlmDriverFacade::driver(
118118
$message->getChatable()->getDriver()
119-
)->chat($messages);
119+
)->setToolType(ToolTypes::NoFunction)
120+
->chat($messages);
120121

121122
$this->response = $response->content;
122123

Modules/LlmDriver/app/LlmDriverClient.php

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace LlmLaraHub\LlmDriver;
44

5+
use LlmLaraHub\LlmDriver\Functions\CreateTasksTool;
56
use LlmLaraHub\LlmDriver\Functions\GatherInfoTool;
67
use LlmLaraHub\LlmDriver\Functions\ReportingTool;
78
use LlmLaraHub\LlmDriver\Functions\SearchAndSummarize;
@@ -63,6 +64,7 @@ public function getFunctions(): array
6364
(new StandardsChecker())->getFunction(),
6465
(new ReportingTool())->getFunction(),
6566
(new GatherInfoTool())->getFunction(),
67+
(new CreateTasksTool())->getFunction(),
6668
];
6769
}
6870

Modules/LlmDriver/app/LlmServiceProvider.php

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Support\ServiceProvider;
88
use LlmLaraHub\LlmDriver\DistanceQuery\DistanceQueryClient;
99
use LlmLaraHub\LlmDriver\Functions\CreateEventTool;
10+
use LlmLaraHub\LlmDriver\Functions\CreateTasksTool;
1011
use LlmLaraHub\LlmDriver\Functions\GatherInfoTool;
1112
use LlmLaraHub\LlmDriver\Functions\GetWebSiteFromUrlTool;
1213
use LlmLaraHub\LlmDriver\Functions\ReportingTool;
@@ -98,6 +99,10 @@ public function boot(): void
9899
return new CreateEventTool();
99100
});
100101

102+
$this->app->bind('create_tasks_tool', function () {
103+
return new CreateTasksTool();
104+
});
105+
101106
}
102107

103108
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace LlmLaraHub\LlmDriver\Tests\Feature;
4+
5+
use App\Models\Chat;
6+
use App\Models\Message;
7+
use App\Models\Project;
8+
use LlmLaraHub\LlmDriver\Functions\CreateTasksTool;
9+
use Tests\TestCase;
10+
11+
class CreateTasksToolTest extends TestCase
12+
{
13+
/**
14+
* A basic feature test example.
15+
*/
16+
public function test_generates_tasks(): void
17+
{
18+
$project = Project::factory()->create();
19+
$chat = Chat::factory()->create([
20+
'chatable_id' => $project->id,
21+
'chatable_type' => Project::class,
22+
]);
23+
24+
$data = get_fixture('claude_chat_response.json');
25+
26+
$data = data_get($data, 'tool_calls.1.arguments.tasks');
27+
28+
$message = Message::factory()->create([
29+
'chat_id' => $chat->id,
30+
'args' => [
31+
'tasks' => $data,
32+
],
33+
]);
34+
35+
$this->assertDatabaseCount('tasks', 0);
36+
37+
(new CreateTasksTool())->handle($message);
38+
39+
$this->assertDatabaseCount('tasks', 5);
40+
41+
$this->assertCount(5, $project->refresh()->tasks);
42+
43+
}
44+
}

app/Domains/Chat/UiStatusEnum.php

+2
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55
enum UiStatusEnum: string
66
{
77
case Complete = 'complete';
8+
case InProgress = 'in_progress';
9+
case NotStarted = 'not_started';
810
}

app/Domains/Messages/SearchAndSummarizeChatRepo.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ public function search(
3535

3636
$input = $message->body;
3737

38+
Log::info('[LaraChain] Search and Summarize Default Function', [
39+
'note' => 'Showing input since some system grab the last on the array',
40+
'input' => $input,
41+
]);
42+
3843
$filter = $message->getFilter();
3944

4045
$functionDto = FunctionCallDto::from([
@@ -47,11 +52,6 @@ public function search(
4752

4853
$message = $this->addToolsToMessage($message, $functionDto);
4954

50-
Log::info('[LaraChain] Search and Summarize Default Function', [
51-
'note' => 'Showing input since some system grab the last on the array',
52-
'input' => $input,
53-
]);
54-
5555
$originalPrompt = $input;
5656

5757
/** @var EmbeddingsResponseDto $embedding */
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace App\Domains\Projects;
4+
5+
use App\Domains\Chat\UiStatusEnum;
6+
use App\Models\Project;
7+
use Facades\App\Domains\Projects\Orchestrate;
8+
9+
class KickOffProject
10+
{
11+
public function handle(Project $project)
12+
{
13+
$chat = $project->chats()->first();
14+
15+
$chat->updateQuietly([
16+
'chat_status' => UiStatusEnum::InProgress,
17+
]);
18+
19+
$chat->messages()->delete();
20+
21+
$project->tasks()->delete();
22+
23+
Orchestrate::handle($chat, $project->content, $project->system_prompt);
24+
25+
$chat->updateQuietly([
26+
'chat_status' => UiStatusEnum::Complete,
27+
]);
28+
}
29+
}

0 commit comments

Comments
 (0)