Skip to content

Commit

Permalink
This will add the Events Tool the first multi object tool
Browse files Browse the repository at this point in the history
  • Loading branch information
alnutile committed Aug 17, 2024
1 parent aa8e06c commit 049b604
Show file tree
Hide file tree
Showing 13 changed files with 668 additions and 157 deletions.
33 changes: 19 additions & 14 deletions Modules/LlmDriver/app/ClaudeClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function chat(array $messages): CompletionResponse

$payload = $this->modifyPayload($payload);

put_fixture('claude_payload_with_tools.json', $payload);
put_fixture('error_claude_payload.json', $payload);

$results = $this->getClient()->post('/messages', $payload);

Expand Down Expand Up @@ -297,26 +297,31 @@ public function remapFunctions(array $functions): array
$required[] = $name;
}

$subType = data_get($property, 'type', 'string');
$properties[$name] = [
'description' => data_get($property, 'description', null),
'type' => data_get($property, 'type', 'string'),
'type' => $subType,
];

if ($subType === 'array') {
$subItems = $property['properties'][0]->properties; //stop at this for now
$subItemsMapped = [];
foreach ($subItems as $subItemKey => $subItemValue) {
$subItemsMapped[$subItemValue->name] = [
'type' => $subItemValue->type,
'description' => $subItemValue->description,
];
}

$properties[$name]['items'] = [
'type' => 'object',
'properties' => $subItemsMapped,
];
}
}

$itemsOrProperties = $properties;

if ($type === 'array') {
$itemsOrProperties = [
'results' => [
'type' => 'array',
'items' => [
'type' => 'object',
'properties' => $properties,
],
],
];
}

return [
'name' => data_get($function, 'name'),
'description' => data_get($function, 'description'),
Expand Down
126 changes: 86 additions & 40 deletions Modules/LlmDriver/app/Functions/CreateEventTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\Event;
use App\Models\Message;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use LlmLaraHub\LlmDriver\Responses\FunctionResponse;
use LlmLaraHub\LlmDriver\ToolsHelper;
Expand All @@ -21,7 +22,7 @@ class CreateEventTool extends FunctionContract

protected string $name = 'create_event_tool';

protected string $description = 'If the user needs to create an event this tool help';
protected string $description = 'If the user needs to create one or more events this tool help';

public function handle(
Message $message): FunctionResponse
Expand All @@ -30,50 +31,48 @@ public function handle(

$args = $message->meta_data->args;

$assigned_to_assistant = data_get($args, 'assigned_to_assistant', false);
$description = data_get($args, 'description', null);
$start_date = data_get($args, 'start_date', null);
$start_time = data_get($args, 'start_time', null);
$end_date = data_get($args, 'end_date', null);
$end_time = data_get($args, 'end_time', null);
$location = data_get($args, 'location', null);
$type = data_get($args, 'type', 'event');
$title = data_get($args, 'title', null);
$all_day = data_get($args, 'all_day', false);

if (! $title || ! $start_date) {
throw new \Exception('No title found');
}
$eventArray = data_get($args, 'events', []);

if ($start_date == null && $start_date != '') {
$start_date = str($start_date)->remove('\\')->toString();
} else {
foreach ($eventArray as $event) {
$start_date = null;
}

if ($end_date && $end_date !== '') {
$end_date = str($end_date)->remove('\\')->toString();
} else {
$end_date = null;
$assigned_to_assistant = data_get($event, 'assigned_to_assistant', false);
$description = data_get($event, 'description', null);
$start_time = data_get($event, 'start_time', null);
$end_time = data_get($event, 'end_time', null);
$location = data_get($event, 'location', null);
$type = data_get($event, 'type', 'event');
$title = data_get($event, 'title', 'No Title Found');
$all_day = data_get($event, 'all_day', false);

if ($start_time != '' || $start_time != null) {
$start_date = Carbon::parse($start_time)->format('Y-m-d');
$start_time = Carbon::parse($start_time)->format('H:i:s');
}

if ($end_time != '' || $end_time != null) {
$end_date = Carbon::parse($end_time)->format('Y-m-d');
$end_time = Carbon::parse($end_time)->format('H:i:s');
}

Event::create([
'title' => $title,
'description' => $description,
'start_date' => $start_date,
'start_time' => $start_time,
'end_date' => $end_date,
'end_time' => $end_time,
'location' => $location,
'type' => $type,
'assigned_to_id' => null,
'assigned_to_assistant' => $assigned_to_assistant,
'all_day' => $all_day,
'collection_id' => $message->getChatable()->id,
]);
}

$event = Event::create([
'title' => $title,
'description' => $description,
'start_date' => $start_date,
'start_time' => $start_time,
'end_date' => $end_date,
'end_time' => $end_time,
'location' => $location,
'type' => $type,
'assigned_to_id' => null,
'assigned_to_assistant' => $assigned_to_assistant,
'all_day' => $all_day,
'collection_id' => $message->getChatable()->id,
]);

return FunctionResponse::from([
'content' => $event->title,
'content' => json_encode($eventArray),
'prompt' => $message->getContent(),
'requires_followup' => false,
'documentChunks' => collect([]),
Expand All @@ -86,7 +85,54 @@ public function handle(
*/
protected function getProperties(): array
{
return [];
return [
new PropertyDto(
name: 'events',
description: 'Array of event objects',
type: 'array',
required: true,
properties: [
new PropertyDto(
name: 'items',
description: 'Event object',
type: 'object',
required: true,
properties: [
new PropertyDto(
name: 'start_time',
description: 'Start time of the event',
type: 'string',
required: true
),
new PropertyDto(
name: 'end_time',
description: 'End time of the event',
type: 'string',
required: false
),
new PropertyDto(
name: 'title',
description: 'Title of the event',
type: 'string',
required: true
),
new PropertyDto(
name: 'location',
description: 'Location of the event',
type: 'string',
required: false
),
new PropertyDto(
name: 'description',
description: 'Description of the event',
type: 'string',
required: true
),
]
),
]
),
];
}

public function runAsBatch(): bool
Expand Down
5 changes: 5 additions & 0 deletions Modules/LlmDriver/app/Functions/FunctionContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ public function runAsBatch(): bool
return false;
}

public function getParameters(): array
{
return $this->getProperties();
}

/**
* @return PropertyDto[]
*/
Expand Down
29 changes: 4 additions & 25 deletions Modules/LlmDriver/tests/Feature/ClaudeClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use LlmLaraHub\LlmDriver\ClaudeClient;
use LlmLaraHub\LlmDriver\Functions\CreateEventTool;
use LlmLaraHub\LlmDriver\Functions\FunctionDto;
use LlmLaraHub\LlmDriver\Functions\ParametersDto;
use LlmLaraHub\LlmDriver\Functions\PropertyDto;
Expand Down Expand Up @@ -219,33 +220,11 @@ public function test_functions_prompt(): void
public function test_remap_array(): void
{

$payload = get_fixture('payload_modified.json');
$shouldBe = get_fixture('claude_remap_functions_results_v2.json');

$shouldBe = data_get($payload, 'tools');
$function = (new CreateEventTool)->getFunction();

$dto = FunctionDto::from([
'name' => 'reporting_json',
'description' => 'JSON Summary of the report',
'parameters' => ParametersDto::from([
'type' => 'array',
'properties' => [
PropertyDto::from([
'name' => 'title',
'description' => 'The title of the section',
'type' => 'string',
'required' => true,
]),
PropertyDto::from([
'name' => 'content',
'description' => 'The content of the section',
'type' => 'string',
'required' => true,
]),
],
]),
]);

$results = (new ClaudeClient)->remapFunctions([$dto]);
$results = (new ClaudeClient)->remapFunctions(collect([$function])->toArray());

$this->assertEquals(
$shouldBe,
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<env name="LARALAMMA_SEARCH_SOURCE" value="mock"/>
<env name="BRAVE_API_TOKEN" value="FOOBAR"/>
<!-- this is a fake token! -->
<env name="OPENAI_API_KEY" value="sk-m8ox9NVgboSLRCr5VA5RT3BXbkFJzP1QGUedbQxGmmuAQWRT"/>
<env name="OPENAI_API_KEY" value="sk-m8ox9NVgboSLRCr5TESTBXbkFJzP1QGUedbQxGmmuAQWRT"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="OPENAI_MOCK" value="true"/>
Expand Down
2 changes: 1 addition & 1 deletion tests/Feature/CreateEventToolTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function test_makes_event(): void
]);
$this->assertDatabaseCount('events', 0);
(new CreateEventTool())->handle($message);
$this->assertDatabaseCount('events', 1);
$this->assertDatabaseCount('events', 19);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function test_create_source()
$response = $this->actingAs($user)
->post(route('api.chrome_extension.collections.source.create', $collection), [
'url' => 'https://www.google.com',
'title' => 'Test Title',
'recurring' => 'not',
'force' => false,
'prompt' => 'Foo bar',
Expand Down
Loading

0 comments on commit 049b604

Please sign in to comment.