Skip to content

Commit

Permalink
feat(console): adding ai sample
Browse files Browse the repository at this point in the history
  • Loading branch information
xmlking committed May 26, 2024
1 parent f271ca9 commit 9389090
Show file tree
Hide file tree
Showing 19 changed files with 916 additions and 92 deletions.
2 changes: 2 additions & 0 deletions .secrets.example
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ S3_ACCESS_KEY = 'storage-access-key-never-use-this-value'
S3_SECRET_KEY = 'storage-secret-key-never-use-this-value'

## AI
OPENAI_ORG_ID = ''
OPENAI_PROJECT_ID = ''
OPENAI_API_KEY = ''
GRAPHITE_WEBHOOK_SECRET = ''
4 changes: 0 additions & 4 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@
"eamodio.gitlens",
"github.github-vscode-theme",
"github.vscode-pull-request-github",
"esbenp.prettier-vscode",
"yzhang.markdown-all-in-one",
"EditorConfig.EditorConfig",
"humao.rest-client",
"PKief.material-icon-theme",
"hediet.vscode-drawio",
"mikestead.dotenv",
"vivaxy.vscode-conventional-commits",
"alberto-varela.monorepo-focus-workspace",
"biomejs.biome",
// inlang (i18n)
Expand All @@ -38,11 +36,9 @@
"codezombiech.gitignore",
"GitHub.vscode-github-actions",
"csstools.postcss",
"dbaeumer.vscode-eslint",
"ms-playwright.playwright",
"ms-vsliveshare.vsliveshare",
"streetsidesoftware.code-spell-checker",
"stylelint.vscode-stylelint",
"svelte.svelte-vscode",
"ardenivanov.svelte-intellisense",
"JakobKruse.svelte-kit-snippets",
Expand Down
4 changes: 4 additions & 0 deletions apps/console/.secrets.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
# https://generate-secret.vercel.app/64 to generate a secret.
# or copy (openssl rand -hex 64) output here
RATE_LIMIT_SECRET='fill-me-in'
## AI
OPENAI_ORG_ID = ''
OPENAI_PROJECT_ID = ''
OPENAI_API_KEY = ''
2 changes: 2 additions & 0 deletions apps/console/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"test:unit:ui": "dotenv-run -f .env -f .secrets -v -- vitest --ui"
},
"devDependencies": {
"@ai-sdk/openai": "0.0.14",
"@floating-ui/dom": "1.6.5",
"@fontsource-variable/inter": "5.0.18",
"@inlang/cli": "2.16.8",
Expand Down Expand Up @@ -60,6 +61,7 @@
"@vincjo/datatables": "1.14.5",
"@vitest/coverage-v8": "1.6.0",
"@xyflow/svelte": "0.1.3",
"ai": "3.1.14",
"autoprefixer": "10.4.19",
"d3-array": "3.2.4",
"d3-scale": "4.0.2",
Expand Down
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 apps/console/src/lib/components/magic-spell-textarea/index.ts
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';
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>
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>
9 changes: 7 additions & 2 deletions apps/console/src/lib/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ export const menuNavLinks: MenuNavLinks = {
},
{
title: 'Experiments',
list: [{ href: '/customers', label: 'Customers', keywords: 'customers, users' }]
},
{
title: 'AI',
list: [
{ href: '/customers', label: 'Customers', keywords: 'customers, users' },
{ href: '/play', label: 'Play', keywords: 'play, users' }
{ href: '/magic-spell', label: 'Magic Spell', keywords: 'magic-spell, ai, completion' },
{ href: '/assistants', label: 'Assistants', keywords: 'assistants, ai' },
{ href: '/chatbot', label: 'Chat Bot', keywords: 'chatbot, OpenAI' }
]
}
],
Expand Down
39 changes: 39 additions & 0 deletions apps/console/src/routes/(app)/magic-spell/+page.server.ts
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 😎' });
}
};
134 changes: 134 additions & 0 deletions apps/console/src/routes/(app)/magic-spell/+page.svelte
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>
Loading

0 comments on commit 9389090

Please sign in to comment.