Skip to content

Commit

Permalink
this GoogleSheet and allows LaraLlama to import and sync the sheet
Browse files Browse the repository at this point in the history
  • Loading branch information
alnutile committed Jul 9, 2024
1 parent 2822dec commit 31ef6ab
Show file tree
Hide file tree
Showing 17 changed files with 777 additions and 12 deletions.
30 changes: 30 additions & 0 deletions app/Domains/Prompts/GoogleSheetSource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace App\Domains\Prompts;

use Illuminate\Support\Facades\Log;

class GoogleSheetSource
{
public static function prompt(string $context): string
{
Log::info('[LaraChain] - GoogleSheetSource Prompt');

return <<<PROMPT
**Role**
You are an assistant that can take data from a Google Sheet and return it in a markdown format.
**Task**
Pull the url from the Google Sheet and add to documents.
**Format**
Column Name: Row Data
Column Name: Row Data
Column Name: Row Data
** CONTEXT IS BELOW THIS LINE **
$context
PROMPT;
}
}
61 changes: 61 additions & 0 deletions app/Domains/Sources/GoogleSheetSource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace App\Domains\Sources;

use App\Domains\Documents\TypesEnum;
use App\Jobs\ProcessCSVJob;
use App\Models\Document;
use App\Models\Source;
use Facades\App\Domains\Sources\GoogleSheetSource\GoogleSheetWrapper;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class GoogleSheetSource extends BaseSource
{
public SourceTypeEnum $sourceTypeEnum = SourceTypeEnum::GoogleSheetSource;

public static string $description = 'Add an URL that is Public Viewable and the system will keep an eye on it';

/**
* Here you can add content coming in from an API,
* Email etc to documents. or you can React to the data coming in and for example
* reply to it from the collection of data in the system eg
* API hits source with article added to CMS
* Source triggers Reaction via Output that sends the results of the LLM
* looking in the collection of data for related content
*/
public function handle(Source $source): void
{

Log::info('[LaraChain] - GoogleSheetSource Doing something');

$content = GoogleSheetWrapper::handle($source->meta_data['sheet_id'], $source->meta_data['sheet_name']);

$collection = $source->collection;

$name = sprintf('%s_%s.csv',
$source->meta_data['sheet_name'],
str($source->meta_data['sheet_id'])->limit(15, '')->toString()
);

Storage::disk('collections')
->put($collection->id.'/'.$name, $content);

$document = Document::updateOrCreate([
'collection_id' => $collection->id,
'file_path' => $name,
'type' => TypesEnum::CSV,
]);

Bus::batch([
new ProcessCSVJob($document),
])
->name('Process Google Sheet CSV Document - '.$document->id)
->allowFailures()
->dispatch();

Log::info('[LaraChain] - GoogleSheetSource sent work to ProcessCSVJob');

}
}
28 changes: 28 additions & 0 deletions app/Domains/Sources/GoogleSheetSource/GoogleSheetWrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Domains\Sources\GoogleSheetSource;

use Illuminate\Support\Facades\Http;

class GoogleSheetWrapper
{
public function handle(string $sheetId, string $sheetName, string $range = ''): string
{

$url = "https://docs.google.com/spreadsheets/d/{$sheetId}/gviz/tq?tqx=out:csv&sheet={$sheetName}";

if ($range) {
$url .= "&range={$range}";
}

$response = Http::get($url);

if ($response->successful()) {
$csvData = $response->body();

return $csvData;
}

return '';
}
}
1 change: 1 addition & 0 deletions app/Domains/Sources/SourceTypeEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum SourceTypeEnum: string
case FeedSource = 'feed_source';
case WebPageSource = 'web_page_source';
case SiteMapSource = 'site_map_source';
case GoogleSheetSource = 'google_sheet_source';
//leave for scripting

public static function ignore(): array
Expand Down
18 changes: 9 additions & 9 deletions app/Http/Controllers/ChatController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ public function showCollectionChat(Collection $collection, Chat $chat)
'collection' => new CollectionResource($collection),
'reference_collections' => Collection::orderBy('name')
->get()
->transform(function ($item) {
return [
'id' => $item->id,
'name' => $item->name,
];
}),
->transform(
/** @phpstan-ignore-next-line */
function ($item) {
return [
'id' => $item->id,
'name' => $item->name,
];
}),
'date_ranges' => DateRangesEnum::selectOptions(),
'chat' => new ChatResource($chat),
'chats' => ChatResource::collection($collection->chats()->latest()->paginate(20)),
Expand All @@ -56,7 +58,7 @@ public function showCollectionChat(Collection $collection, Chat $chat)
'audiences' => AudienceResource::collection(Audience::all()),
'system_prompt' => $collection->systemPrompt(),
'settings' => [
'supports_functions' => LlmDriverFacade::driver($chat->getDriver())->hasFunctions(),
'supports_functions' => LlmDriverFacade::driver($chat->getDriver())->hasFunctions(),
],
'messages' => MessageResource::collection($chat->latest_messages),
]);
Expand Down Expand Up @@ -93,8 +95,6 @@ public function chat(Chat $chat)
$input = $persona->wrapPromptInPersona($input);
}

put_fixture('validated_chat_input.json', $validated);

$meta_data = MetaDataDto::from($validated);

$message = $chat->addInput(
Expand Down
77 changes: 77 additions & 0 deletions app/Http/Controllers/Sources/GoogleSheetSourceController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace App\Http\Controllers\Sources;

use App\Domains\Prompts\GoogleSheetSource;
use App\Domains\Sources\SourceTypeEnum;
use App\Http\Controllers\BaseSourceController;
use App\Models\Collection;
use App\Models\Source;
use Facades\App\Domains\Sources\GoogleSheetSource\GoogleSheetWrapper;

class GoogleSheetSourceController extends BaseSourceController
{
protected SourceTypeEnum $sourceTypeEnum = SourceTypeEnum::GoogleSheetSource;

protected string $edit_path = 'Sources/GoogleSheetSource/Edit';

protected string $show_path = 'Sources/GoogleSheetSource/Show';

protected string $create_path = 'Sources/GoogleSheetSource/Create';

protected string $info = 'Add an URL that is Public Viewable and the system will keep an eye on it';

protected string $type = 'Google Sheet Source';

public function getPrompts(): array
{
return [
'sheet_to_document' => GoogleSheetSource::prompt('[CONTEXT]'),
];
}

protected function getValidationRules(): array
{
return [
'title' => 'required|string',
'details' => 'required|string',
'active' => ['boolean', 'required'],
'recurring' => ['string', 'required'],
'meta_data' => ['required', 'array'],
'meta_data.sheet_id' => ['required', 'string'],
'meta_data.sheet_name' => ['required', 'string'],
'secrets' => ['nullable', 'array'],
];

}

protected function makeSource(array $validated, Collection $collection): void
{
Source::create([
'title' => $validated['title'],
'details' => $validated['details'],
'recurring' => $validated['recurring'],
'active' => $validated['active'],
'collection_id' => $collection->id,
'type' => $this->sourceTypeEnum,
'meta_data' => $validated['meta_data'],
]);
}

public function testFeed()
{
$validated = request()->validate([
'sheet_id' => ['required', 'string'],
'sheet_name' => ['required', 'string'],
]);

$items = GoogleSheetWrapper::handle($validated['sheet_id'], $validated['sheet_name'], 'A1:Z10');

$rows = array_map('str_getcsv', explode("\n", $items));

return response()->json([
'count' => count($rows),
'items' => $rows,
]);
}
}
51 changes: 51 additions & 0 deletions resources/js/Pages/Sources/GoogleSheetSource/Components/Card.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script setup>
import {Link, useForm} from "@inertiajs/vue3";
import {useToast} from "vue-toastification";
import Settings from "@/Pages/Sources/Cards/Settings.vue";
import Clipboard from "@/Components/Clipboard.vue";
import {computed} from "vue";
const toast = useToast();
const props = defineProps({
source: Object
})
const form = useForm({})
const run = (source) => {
form.post(route('collections.sources.run', {
source: source.id
}), {
onStart: params => {
toast("Running");
},
preserveScroll: true,
onSuccess: () => {
toast.success('Source is running');
}
});
}
</script>

<template>
<div class="card rounded-none w-96 shadow-xl border border-neutral" :key="source.id">
<div class="card-body">
<Settings :source="source"/>
<div class="card-actions justify-end">
<button @click="run(source)" type="button" class="btn btn-primary rounded-none">Run</button>
<Link :href="route('collections.sources.google_sheet_source.edit', {
collection: source.collection_id,
source: source.id
})" class="btn btn-primary rounded-none">Edit</Link>
</div>
</div>
</div>
</template>

<style scoped>
</style>
Loading

0 comments on commit 31ef6ab

Please sign in to comment.