-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
916 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
apps/console/src/lib/components/magic-spell-textarea/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Magic Spell | ||
|
||
Based on nextjs [magic-spell](https://github.com/ai-ng/magic-spell/tree/main) |
2 changes: 2 additions & 0 deletions
2
apps/console/src/lib/components/magic-spell-textarea/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Reexport your entry components here | ||
export { default as MagicSpellTextarea } from './magic-spell-textarea.svelte'; |
15 changes: 15 additions & 0 deletions
15
apps/console/src/lib/components/magic-spell-textarea/loader-icon.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<svg | ||
xmlns="http://www.w3.org/2000/svg" | ||
width="24" | ||
height="24" | ||
viewBox="0 0 24 24" | ||
fill="none" | ||
stroke="currentColor" | ||
strokeWidth="2" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
class="animate-spin" | ||
> | ||
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> | ||
<path d="M12 3a9 9 0 1 0 9 9" /> | ||
</svg> |
65 changes: 65 additions & 0 deletions
65
apps/console/src/lib/components/magic-spell-textarea/magic-spell-textarea.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<script lang="ts"> | ||
import { AutoResizeTextarea } from '@spectacular/skeleton/components/auto-resize-textarea'; | ||
import { useCompletion } from 'ai/svelte'; | ||
import type { HTMLTextareaAttributes } from 'svelte/elements'; | ||
import { Sparkles } from 'lucide-svelte'; | ||
import { Logger } from '@spectacular/utils'; | ||
import { default as LoaderIcon } from './loader-icon.svelte'; | ||
const log = new Logger('experiments:ai:ms:browser'); | ||
const api = '/api/completion'; | ||
/* FIXME */ | ||
/* eslint-disable @typescript-eslint/no-unused-vars,no-unused-vars */ | ||
interface $$Props extends HTMLTextareaAttributes { | ||
value?: any; | ||
} | ||
export let value = ''; | ||
/* eslint-disable @typescript-eslint/no-unused-vars,no-unused-vars */ | ||
const { complete, completion, input, isLoading, handleSubmit, stop } = useCompletion({ | ||
api, | ||
onFinish: (_prompt, completion) => { | ||
value = completion.trim(); | ||
}, | ||
onError: (error) => log.error(error.message) | ||
}); | ||
// callbacks | ||
</script> | ||
|
||
<form | ||
class="flex flex-col items-center" | ||
on:submit={(e) => { | ||
handleSubmit(e); | ||
input.set(''); | ||
}} | ||
> | ||
<AutoResizeTextarea | ||
{...$$props} | ||
maxRows={100} | ||
minRows={4} | ||
aria-label="Text" | ||
value={$isLoading && $completion.length > 0 ? $completion.trim() : value} | ||
on:change={(event) => { | ||
if (!$isLoading) value = event.target?.value; | ||
console.log(value); | ||
}} | ||
/> | ||
<div class="z-10 -mt-5"> | ||
<div class="input-group input-group-divider grid-cols-[1fr_auto]"> | ||
<input | ||
type="search" | ||
placeholder="paraphrase it..." | ||
bind:value={$input} | ||
aria-label="Prompt" | ||
required | ||
/> | ||
<button type="submit" aria-label="Submit" class="variant-filled-secondary"> | ||
<svelte:component this={$isLoading ? LoaderIcon : Sparkles} /></button | ||
> | ||
</div> | ||
</div> | ||
<!-- <button type="button" class="btn variant-filled" on:click={stop} disabled={!$isLoading}>Stop</button> --> | ||
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { fail } from '@sveltejs/kit'; | ||
import { message, superValidate } from 'sveltekit-superforms'; | ||
import { zod } from 'sveltekit-superforms/adapters'; | ||
import { z } from 'zod'; | ||
import { Logger, sleep } from '@spectacular/utils'; | ||
|
||
const aiSchema = z.object({ | ||
commentOne: z | ||
.string({ required_error: 'First Comment is required' }) | ||
.min(10, { message: 'First Comment must contain at least 10 character(s)' }) | ||
.max(256) | ||
.trim(), | ||
commentTwo: z | ||
.string({ required_error: 'Second Comment is required' }) | ||
.min(10, { message: 'Second Name Comment contain at least 10 character(s)' }) | ||
.max(256) | ||
.trim() | ||
}); | ||
|
||
const log = new Logger('server:ai:ms'); | ||
|
||
export const load = async () => { | ||
const form = await superValidate(zod(aiSchema)); | ||
return { form }; | ||
}; | ||
|
||
export const actions = { | ||
default: async ({ request }) => { | ||
const form = await superValidate(request, zod(aiSchema)); | ||
|
||
await sleep(1000); | ||
|
||
if (!form.valid) return fail(400, { form }); | ||
|
||
const { commentOne, commentTwo } = form.data; | ||
log.debug({ commentOne, commentTwo }); | ||
return message(form, { type: 'success', message: 'AI sucessfull 😎' }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
<script lang="ts"> | ||
import SuperDebug, { superForm } from 'sveltekit-superforms'; | ||
import { DebugShell } from '@spectacular/skeleton/components'; | ||
import { getToastStore } from '@skeletonlabs/skeleton'; | ||
import { Logger } from '@spectacular/utils'; | ||
import { handleMessage } from '$lib/components/layout/toast-manager'; | ||
// import { MagicSpellTextarea } from '@spectacular/skeleton/components/magic-spell-textarea'; | ||
import { MagicSpellTextarea } from '$lib/components/magic-spell-textarea'; | ||
const log = new Logger('ai:ms:browser'); | ||
const toastStore = getToastStore(); | ||
export let data; | ||
const { | ||
form, | ||
delayed, | ||
timeout, | ||
enhance, | ||
errors, | ||
constraints, | ||
message, | ||
tainted, | ||
posted, | ||
submitting, | ||
formId, | ||
capture, | ||
restore | ||
} = superForm(data.form, { | ||
id: 'ai-form', | ||
dataType: 'json', | ||
taintedMessage: null, | ||
syncFlashMessage: false, | ||
delayMs: 100, | ||
timeoutMs: 4000, | ||
onError({ result }) { | ||
// TODO: | ||
// message.set(result.error.message) | ||
log.error('ai error:', { result }); | ||
}, | ||
onUpdated({ form }) { | ||
if (form.message) { | ||
handleMessage(form.message, toastStore); | ||
} | ||
} | ||
}); | ||
export const snapshot = { capture, restore }; | ||
</script> | ||
|
||
<div class="page-container"> | ||
<div class="page-section"> | ||
<header class="flex justify-between"> | ||
<h1 class="h1">Magic Spell</h1> | ||
</header> | ||
|
||
<form method="POST" use:enhance> | ||
<div class="flex flex-col space-y-4"> | ||
<label class="label" for="commentOne"> | ||
<span>Comment One</span> | ||
<MagicSpellTextarea | ||
id="commentOne" | ||
name="commentOne" | ||
bind:value={$form.commentOne} | ||
data-invalid={$errors.commentOne} | ||
placeholder="It was a dark and stormy night..." | ||
{...$constraints.commentOne} | ||
/> | ||
{#if $errors.commentOne} | ||
<small>{$errors.commentOne}</small> | ||
{/if} | ||
</label> | ||
<label class="label" for="commentTwo"> | ||
<span>Comment Two</span> | ||
<MagicSpellTextarea | ||
id="commentTwo" | ||
name="commentTwo" | ||
bind:value={$form.commentTwo} | ||
data-invalid={$errors.commentTwo} | ||
placeholder="It was a dark and stormy night..." | ||
{...$constraints.commentTwo} | ||
/> | ||
{#if $errors.commentTwo} | ||
<small>{$errors.commentTwo}</small> | ||
{/if} | ||
</label> | ||
<button type="submit" class="variant-filled-primary btn w-full">submit</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
|
||
<DebugShell> | ||
<SuperDebug | ||
label="AI Miscellaneous" | ||
status={false} | ||
data={{ | ||
message: $message, | ||
submitting: $submitting, | ||
delayed: $delayed, | ||
timeout: $timeout, | ||
posted: $posted | ||
}} | ||
/> | ||
<br /> | ||
<SuperDebug label="AI Form" data={$form} /> | ||
<br /> | ||
<SuperDebug label="Tainted" status={false} data={$tainted} /> | ||
<br /> | ||
<SuperDebug label="Errors" status={false} data={$errors} /> | ||
<br /> | ||
<SuperDebug label="Constraints" status={false} data={$constraints} /> | ||
<!-- <br /> | ||
<SuperDebug label="$page data" status={false} data={$page} /> --> | ||
<br /> | ||
<SuperDebug | ||
label="AI Miscellaneous" | ||
status={false} | ||
data={{ | ||
message: $message, | ||
submitting: $submitting, | ||
delayed: $delayed, | ||
timeout: $timeout, | ||
posted: $posted, | ||
formId: $formId | ||
}} | ||
/> | ||
<br /> | ||
<SuperDebug label="AI Form" data={$form} /> | ||
<br /> | ||
<SuperDebug label="AI Tainted" status={false} data={$tainted} /> | ||
<br /> | ||
<SuperDebug label="AI Errors" status={false} data={$errors} /> | ||
<br /> | ||
<SuperDebug label="AI Constraints" status={false} data={$constraints} /> | ||
</DebugShell> |
Oops, something went wrong.