Commit 6c4e2794 authored by wycers's avatar wycers
Browse files

lib

parent 4098e881
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
<script lang="ts">
	import * as Dialog from "$lib/components/ui/dialog";
	import { Button } from "$lib/components/ui/button";
</script>

<Dialog.Root>
	<Dialog.Trigger asChild let:builder>
		<Button variant="secondary" builders={[builder]}>View code</Button>
	</Dialog.Trigger>
	<Dialog.Content class="sm:max-w-[625px]">
		<Dialog.Header>
			<Dialog.Title>View code</Dialog.Title>
			<Dialog.Description>
				You can use the following code to start integrating your current prompt and settings
				into your application.
			</Dialog.Description>
		</Dialog.Header>
		<div class="grid gap-4">
			<div class="rounded-md bg-black p-6">
				<pre><code class="grid gap-1 text-sm text-muted-foreground [&_span]:h-4"
						><span><span class="text-sky-300">import</span> os</span><span
							><span class="text-sky-300">import</span> openai</span
						><span /><span
							>openai.api_key = os.getenv(<span class="text-green-300"
								>&quot;OPENAI_API_KEY&quot;</span
							>)</span
						><span /><span>response = openai.Completion.create(</span><span
							>{" "}model=<span class="text-green-300">&quot;davinci&quot;</span
							>,</span
						><span>{" "}prompt=<span class="text-amber-300">&quot;&quot;</span>,</span
						><span>{" "}temperature=<span class="text-amber-300">0.9</span>,</span><span
							>{" "}max_tokens=<span class="text-amber-300">5</span>,</span
						><span>{" "}top_p=<span class="text-amber-300">1</span>,</span><span
							>{" "}frequency_penalty=<span class="text-amber-300">0</span>,</span
						><span>{" "}presence_penalty=<span class="text-green-300">0</span>,</span
						><span>)</span></code
					></pre>
			</div>
			<div>
				<p class="text-sm text-muted-foreground">
					Your API Key can be found here. You should use environment variables or a secret
					management tool to expose your key to your applications.
				</p>
			</div>
		</div>
	</Dialog.Content>
</Dialog.Root>
+9 −0
Original line number Diff line number Diff line
export { default as CodeViewer } from "./code-viewer.svelte";
export { default as MaxLengthSelector } from "./max-length-selector.svelte";
export { default as ModelSelector } from "./model-selector.svelte";
export { default as PresetActions } from "./preset-actions.svelte";
export { default as PresetSave } from "./preset-save.svelte";
export { default as PresetSelector } from "./preset-selector.svelte";
export { default as PresetShare } from "./preset-share.svelte";
export { default as TemperatureSelector } from "./temperature-selector.svelte";
export { default as TopPSelector } from "./top-p-selector.svelte";
+37 −0
Original line number Diff line number Diff line
<script lang="ts">
	import type { Slider as SliderPrimitive } from "bits-ui";
	import * as HoverCard from "$lib/components/ui/hover-card";
	import { Slider } from "$lib/components/ui/slider";
	import { Label } from "$lib/components/ui/label";

	export let value: SliderPrimitive.Props["value"];
</script>

<div class="grid gap-2 pt-2">
	<HoverCard.Root openDelay={200} closeDelay={100}>
		<HoverCard.Trigger asChild let:builder>
			<div class="grid gap-4" {...builder} use:builder.action>
				<div class="flex items-center justify-between">
					<Label for="maxlength">Maximum Length</Label>
					<span
						class="w-12 rounded-md border border-transparent px-2 py-0.5 text-right text-sm text-muted-foreground hover:border-border"
					>
						{value}
					</span>
				</div>
				<Slider
					id="maxlength"
					max={4000}
					bind:value
					step={10}
					class="[&_[role=slider]]:h-4 [&_[role=slider]]:w-4"
					aria-label="Maximum Length"
				/>
			</div>
		</HoverCard.Trigger>
		<HoverCard.Content class="w-[260px] text-sm" side="left" align="start">
			The maximum number of tokens to generate. Requests can use up to 2,048 or 4,000 tokens,
			shared between prompt and completion. The exact limit varies by model.
		</HoverCard.Content>
	</HoverCard.Root>
</div>
+56 −0
Original line number Diff line number Diff line
<script lang="ts">
	import type { Command as CommandPrimitive } from "cmdk-sv";
	import * as Command from "$lib/components/ui/command/index.js";
	import type { Model } from "./models";
	import Check from "svelte-radix/Check.svelte";
	import { cn } from "$lib/utils";

	type $$Props = {
		model: Model;
		isSelected: boolean;
		onSelect: () => void;
		onPeek: (model: Model) => void;
	} & CommandPrimitive.ItemProps;

	export let model: $$Props["model"];
	export let isSelected: $$Props["isSelected"];
	export let onSelect: $$Props["onSelect"];
	export let onPeek: $$Props["onPeek"];

	function mutationObserverAction(node: HTMLElement) {
		const observer = new MutationObserver((mutations) => {
			for (const mutation of mutations) {
				if (mutation.type !== "attributes" || mutation.attributeName !== "aria-selected")
					continue;

				if (node.getAttribute("aria-selected") === "true") {
					onPeek(model);
				}
			}
		});

		observer.observe(node, {
			attributes: true,
		});
		return {
			destroy() {
				observer.disconnect();
			},
		};
	}
</script>

<Command.Item value={model.name} asChild {onSelect} let:action let:attrs>
	<div
		{...attrs}
		use:mutationObserverAction
		use:action
		{...$$restProps}
		class="relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-primary aria-selected:text-primary-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
	>
		{model.name}
		{#if isSelected}
			<Check className={cn("ml-auto h-4 w-4")} />
		{/if}
	</div>
</Command.Item>
+154 −0
Original line number Diff line number Diff line
<script lang="ts">
	import * as HoverCard from "$lib/components/ui/hover-card";
	import { Label } from "$lib/components/ui/label";
	import type { ModelType, Model } from "../(data)/models";
	import { Button } from "$lib/components/ui/button";
	import * as Command from "$lib/components/ui/command";
	import CaretSort from "svelte-radix/CaretSort.svelte";
	import * as Popover from "$lib/components/ui/popover";
	import { tick } from "svelte";
	import ModelItem from "./model-item.svelte";

	export let types: ModelType[];
	export let models: Model[];

	let selectedModel = models[0];
	let peekedModel: Model | undefined = undefined;
	let open = false;

	let value = "";

	$: selectedValue = models.find((f) => f.id === value)?.name ?? "Select a model...";

	// We want to refocus the trigger button when the user selects
	// an item from the list so users can continue navigating the
	// rest of the form with the keyboard.
	function closeAndFocusTrigger(triggerId: string) {
		open = false;
		tick().then(() => {
			document.getElementById(triggerId)?.focus();
		});
	}

	function onPopoverOpenChange(open: boolean) {
		if (open) {
			peekedModel = selectedModel;
		} else {
			peekedModel = undefined;
		}
	}

	$: hoverCardIsOpen = open && peekedModel !== undefined;

	function handlePeek(model: Model) {
		console.log("current model", peekedModel?.name);
		console.log("incoming model", model.name);
		console.log("popover open", open);
		console.log("hovercard open ", hoverCardIsOpen);
		if (peekedModel === undefined) {
			if (!open) return;
			peekedModel = model;
			return;
		}
		peekedModel = model;
	}

	function onPopoverOutsideClick() {
		peekedModel = undefined;
	}
</script>

<div class="grid gap-2">
	<HoverCard.Root openDelay={200}>
		<HoverCard.Trigger asChild let:builder>
			<div use:builder.action {...builder}>
				<Label for="model">Model</Label>
			</div>
		</HoverCard.Trigger>
		<HoverCard.Content class="w-[260px] text-sm" align="start" side="left">
			The model which will generate the completion. Some models are suitable for natural
			language tasks, others specialize in code. Learn more.
		</HoverCard.Content>
	</HoverCard.Root>

	<Popover.Root
		bind:open
		let:ids
		onOutsideClick={onPopoverOutsideClick}
		onOpenChange={onPopoverOpenChange}
	>
		<Popover.Trigger asChild let:builder>
			<Button
				builders={[builder]}
				variant="outline"
				role="combobox"
				aria-expanded={open}
				class="w-[200px] justify-between "
			>
				{selectedValue}
				<CaretSort class="ml-2 h-4 w-4 shrink-0 opacity-50" />
			</Button>
		</Popover.Trigger>
		<Popover.Content class="w-[250px] p-0">
			<HoverCard.Root
				closeOnOutsideClick={false}
				open={hoverCardIsOpen}
				openDelay={0}
				portal={null}
			>
				<HoverCard.Content class="-ml-2 min-h-[280px]" side="left" align="start">
					{#if peekedModel && hoverCardIsOpen}
						<div class="grid gap-2">
							<h4 class="font-medium leading-none">
								{peekedModel.name}
							</h4>
							<div class="text-sm text-muted-foreground">
								{peekedModel.description}
							</div>
							{#if peekedModel.strengths}
								<div class="mt-4 grid gap-2">
									<h5 class="text-sm font-medium leading-none">Strengths</h5>
									<ul class="text-sm text-muted-foreground">
										{peekedModel.strengths}
									</ul>
								</div>
							{/if}
						</div>
					{/if}
				</HoverCard.Content>
				<Command.Root loop>
					<Command.Input placeholder="Search Models...." />
					<Command.List class="h-[var(--cmdk-list-height)] max-h-[400px]">
						<Command.Empty>No models found.</Command.Empty>
						{#each types as type}
							<Command.Group heading={type}>
								{#each models.filter((model) => model.type === type) as model}
									<HoverCard.Trigger asChild let:builder>
										<div
											use:builder.action
											{...builder}
											role="button"
											tabindex={0}
										>
											<ModelItem
												{model}
												onSelect={() => {
													value = model.id;
													closeAndFocusTrigger(ids.trigger);
												}}
												onPeek={() => {
													handlePeek(model);
												}}
												isSelected={value === model.id}
											/>
										</div>
									</HoverCard.Trigger>
								{/each}
							</Command.Group>
						{/each}
					</Command.List>
				</Command.Root>
			</HoverCard.Root>
		</Popover.Content>
	</Popover.Root>
</div>
Loading