Skip to content

Commit

Permalink
fix: ai stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
arpowers committed Mar 6, 2024
1 parent e031fed commit 5c5d402
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 68 deletions.
6 changes: 5 additions & 1 deletion @fiction/plugin-ai/endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,16 @@ export abstract class QueryAi extends Query<QueryAiSettings> {

const prompt = [
search,
`style: ${objectives.imageStyle}. No text. No logos. No watermarks. Minimal.`,
`Contraints: make SURE the image has no text, logos, or watermarks on it.`,
`style: ${objectives.imageStyle}.`,
`context: ${objectiveText || 'website'}`,
].join('\n')

const start = Date.now()
this.log.info('creating image', { data: { prompt, orientation, orgId, userId } })
const r = await this.settings.fictionAi.queries.AiImage.serve({ _action: 'createImage', prompt, orientation, orgId, userId }, { server: true })

this.log.info(`created image in ${Math.round((Date.now() - start) / 1000)}s`, { data: { r } })
return r.data?.url || ''
})

Expand Down
8 changes: 5 additions & 3 deletions @fiction/plugin-sites/card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ interface CardTemplateSettings<U extends string = string, T extends ComponentCon
export class CardTemplate<U extends string = string, T extends ComponentConstructor = ComponentConstructor> extends FictionObject<
CardTemplateSettings<U, T>
> {
jsonSchema = vue.computed(() => getOptionJsonSchema(this.settings.options))
// jsonSchema = vue.computed(() => getOptionJsonSchema(this.settings.options))
constructor(settings: CardTemplateSettings<U, T>) {
super('CardTemplate', { title: toLabel(settings.templateId), ...settings })
}
Expand Down Expand Up @@ -156,9 +156,11 @@ export class Card<
if (!this.site || !this.tpl.value)
throw new Error('site and template required')

this.log.info('RUNNING COMPLETION', { data: { jsonSchema: this.tpl.value.jsonSchema.value } })
const jsonSchema = getOptionJsonSchema(this.tpl.value.settings.options)

const c = await getCardCompletion({ runPrompt, outputFormat: this.tpl.value.jsonSchema.value, site: this.site })
this.log.info('RUNNING COMPLETION', { data: { jsonSchema } })

const c = await getCardCompletion({ runPrompt, outputFormat: jsonSchema, site: this.site })

this.log.info('COMPLETION RESULT', { data: c })

Expand Down
2 changes: 1 addition & 1 deletion @fiction/plugin-sites/cards/hero/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const templates = [
iconTheme: 'orange',
el: vue.defineAsyncComponent(() => import('./ElHero.vue')),
options: [
...optionSets.headers.toOptions({ refineOption: { } }),
...optionSets.headers.toOptions({ refine: { } }),
...optionSets.actionItems.toOptions(),
],
userConfig: { heading: 'Hero', subHeading: 'Subheading' },
Expand Down
17 changes: 10 additions & 7 deletions @fiction/plugin-sites/cards/inputSets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class InputSets {
export const inputSets = new InputSets()

export const headerOptionSet = new OptionSet<{
refineOption?: { heading?: Refinement, subHeading?: Refinement, superHeading?: Refinement }
refine?: { heading?: Refinement, subHeading?: Refinement, superHeading?: Refinement }
}> ({
basePath: 'userConfig',
inputOptions() {
Expand Down Expand Up @@ -269,7 +269,7 @@ export const headerOptionSet = new OptionSet<{
})

export const actionItemOptionSet = new OptionSet< {
refineOption?: { group?: Refinement | { name?: Refinement, desc?: Refinement, href?: Refinement, target?: Refinement }, title?: Refinement }
refine?: { group?: Refinement | { name?: Refinement, desc?: Refinement, href?: Refinement, target?: Refinement }, title?: Refinement }
}> ({
basePath: 'userConfig',
inputOptions: (args) => {
Expand Down Expand Up @@ -315,7 +315,7 @@ export const actionItemOptionSet = new OptionSet< {
})

export const navItemsOptionSet = new OptionSet<{
refineOption?: { group?: Refinement<{ name?: Refinement, desc?: Refinement, href?: Refinement, target?: Refinement }>, title?: Refinement }
refine?: { group?: Refinement<{ name?: Refinement, desc?: Refinement, href?: Refinement, target?: Refinement }>, title?: Refinement }
}> ({
basePath: 'userConfig',
inputOptions: (args) => {
Expand Down Expand Up @@ -367,6 +367,7 @@ export const navItemsOptionSet = new OptionSet<{
new InputOption({
aliasKey: 'group',
key: `${groupPath}`,
label,
input: 'InputList',
options: listOptions,
schema: ({ z, subSchema }) => z.array(subSchema),
Expand All @@ -379,7 +380,7 @@ export const navItemsOptionSet = new OptionSet<{

export const mediaItemsOptionSet = new OptionSet< {
formats?: { url?: boolean, html?: boolean }
refineOption?: { group?: Refinement<{ media?: Refinement, name?: Refinement, desc?: Refinement, href?: Refinement }> }
refine?: { group?: Refinement<{ media?: Refinement, name?: Refinement, desc?: Refinement, href?: Refinement }> }
}> ({
basePath: 'userConfig',
inputOptions: (args) => {
Expand Down Expand Up @@ -408,13 +409,14 @@ export const mediaItemsOptionSet = new OptionSet< {
input: 'InputList',
options,
schema: ({ z, subSchema }) => z.array(subSchema),
generation: { estimatedMs: 30000 },
}),
]
},
})

export const socialsOptionSet = new OptionSet< {
refineOption?: { group?: Refinement<{ name?: Refinement, desc?: Refinement, icon?: Refinement, href?: Refinement, target?: Refinement }>, title?: Refinement }
refine?: { group?: Refinement<{ name?: Refinement, desc?: Refinement, icon?: Refinement, href?: Refinement, target?: Refinement }>, title?: Refinement }
}> ({
basePath: 'userConfig',
defaultRefinement: { group: { refine: { icon: true, href: true } } },
Expand Down Expand Up @@ -487,6 +489,7 @@ export const socialsOptionSet = new OptionSet< {
aliasKey: 'group',
key: `${groupPath}`,
input: 'InputList',
label,
options,
schema: ({ z, subSchema }) => z.array(subSchema),
}),
Expand All @@ -509,7 +512,7 @@ type QuoteFilterKeys = {
sourceUrl?: Refinement
}

export const quoteOptionSet = new OptionSet<{ mode: 'single', refineOption: QuoteFilterKeys } | { mode: 'multi', refineOption: { group: Refinement<QuoteFilterKeys> } }>({
export const quoteOptionSet = new OptionSet<{ mode: 'single', refine: QuoteFilterKeys } | { mode: 'multi', refine: { group: Refinement<QuoteFilterKeys> } }>({
basePath: 'userConfig',
inputOptions: (args) => {
const label = args?.label || 'Quotes'
Expand Down Expand Up @@ -548,7 +551,7 @@ export const quoteOptionSet = new OptionSet<{ mode: 'single', refineOption: Quot
},
})

export const postOptionSet = new OptionSet< { refineOption?: { title?: boolean, authorName?: boolean, bodyMarkdown?: boolean } }> ({
export const postOptionSet = new OptionSet< { refine?: { title?: boolean, authorName?: boolean, bodyMarkdown?: boolean } }> ({
basePath: 'userConfig',
inputOptions: () => {
const options = [
Expand Down
65 changes: 47 additions & 18 deletions @fiction/plugin-sites/el/InputAi.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ElButton from '@fiction/ui/ElButton.vue'
import InputText from '@fiction/ui/InputText.vue'
import InputCheckbox from '@fiction/ui/InputCheckbox.vue'
import type { Site } from '@fiction/plugin-sites'
import type { InputOption, InputOptionSettings } from '@fiction/ui'
const props = defineProps({
modelValue: { type: String, default: '' },
Expand All @@ -23,27 +24,50 @@ const defaultGoal = vue.computed(() => {
const v = vue.computed(() => userGoal.value || defaultGoal.value)
const loading = vue.ref(false)
const card = vue.computed(() => props.site.activeCard.value)
const cardOptions = vue.computed(() => {
const getOptions = (opts: InputOption[]) => {
let out: InputOption[] = []
for (const opt of opts) {
if (opt.input.value === 'group')
out = [...out, ...getOptions(opt.settings.options || [])]
else
out.push(opt)
}
return out
}
return getOptions(card.value?.tpl.value?.settings.options || []).filter(_ => _.outputSchema.value)
})
const totalEstimatedTime = vue.computed(() => {
const total = cardOptions.value.filter(_ => !_.generation.value.isDisabled).reduce((acc, opt) => {
const time = opt.generation.value?.estimatedMs ?? 2000
return acc + time
}, 0)
return Math.round(total / 1000)
})
async function generateCard() {
loading.value = true
const runPrompt = v.value
if (!runPrompt)
return
await props.site.activeCard.value?.getCompletion({ runPrompt })
await card.value?.getCompletion({ runPrompt })
loading.value = false
}
const jsonSchema = vue.computed(() => {
const c = props.site.activeCard.value
return c?.tpl.value?.jsonSchema.value
})
const showAdvancedOptions = vue.ref(false)
function updateGeneration(opt: InputOption, value: InputOptionSettings['generation']) {
opt.generation.value = { ...opt.generation.value, ...value }
}
</script>

<template>
<ElForm v-if="jsonSchema" class="space-y-3" @submit="generateCard()">
<ElForm class="space-y-3" @submit="generateCard()">
<div class="flex justify-between">
<ElButton
type="submit"
Expand Down Expand Up @@ -77,21 +101,26 @@ const showAdvancedOptions = vue.ref(false)
placeholder="This section should..."
@update:model-value="userGoal = $event"
/>
<div class="space-y-2 mt-2 bg-theme-50 dark:bg-theme-700 rounded-md p-3">
<div class="text-xs font-bold text-theme-500/60 text-center">
Setting Generation Controls
<div v-if="cardOptions" class="space-y-2 mt-2 bg-theme-50 dark:bg-theme-700 rounded-md p-3">
<div class="flex justify-between">
<div class="text-xs font-bold text-theme-500/80 text-center">
Setting Prompts
</div>
<div class="text-xs font-bold text-theme-500/80">
{{ totalEstimatedTime }} seconds
</div>
</div>
<div v-for="(prop, i) in jsonSchema.properties" :key="i" class="text-[10px] space-y-1">
<div class="flex items-center">
<div class="w-6">
<InputCheckbox :model-value="true" input-class="bg-theme-0 dark:bg-theme-600" />
</div>
<div v-for="(opt, i) in cardOptions" :key="i" class="text-[10px] space-y-1">
<div class="flex items-center justify-between">
<div class="w-24 truncate font-semibold">
{{ toLabel(i.split('.').pop()) }}
{{ opt.label.value }}
</div>
<div class="">
<InputCheckbox :model-value="opt.generation.value.isDisabled" input-class="bg-theme-0 dark:bg-theme-600" text="Disable" @update:model-value="updateGeneration(opt, { isDisabled: $event })" />
</div>
</div>
<div class="grow w-full">
<InputText :model-value="prop.description" placeholder="Desired Output" />
<div v-if="!opt.generation.value.isDisabled" class="grow w-full">
<InputText :model-value="opt.generation.value.prompt" placeholder="Desired Output" @update:model-value="updateGeneration(opt, { prompt: $event })" />
</div>
</div>
</div>
Expand Down
9 changes: 6 additions & 3 deletions @fiction/plugin-sites/test/card.wip.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest'
import { waitFor } from '@fiction/core'
import { getOptionJsonSchema } from '@fiction/ui'
import { Card, CardTemplate } from '../card'
import { Site } from '../site'
import { createSiteTestUtils } from './siteTestUtils'
Expand Down Expand Up @@ -32,10 +33,12 @@ describe('cardTemplate', async () => {

expect(card.templateId.value).toBe('hero')

if (!card.tpl.value?.jsonSchema.value)
throw new Error('card.tpl.value?.schema.value is undefined')
const jsonSchema = getOptionJsonSchema(card.tpl.value?.settings.options)

expect(card.tpl.value?.jsonSchema.value).toMatchInlineSnapshot(`
if (!jsonSchema)
throw new Error('jsonSchema is undefined')

expect(jsonSchema).toMatchInlineSnapshot(`
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { describe, expect, it } from 'vitest'
import { getOptionJsonSchema } from '@fiction/ui'
import { templates } from '.'

describe('minimalProfile', async () => {
it('has correct schema', async () => {
expect(templates[0].jsonSchema.value).toMatchInlineSnapshot(`
const jsonSchema = getOptionJsonSchema(templates[0].settings.options)
expect(jsonSchema).toMatchInlineSnapshot(`
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ function options() {
const options = [
...optionSets.mediaItems.toOptions({
refine: {
group: {
refine: {
media: 'splash picture in portrait format',
},
},
group: 'splash picture in portrait format',
},
}),
...optionSets.headers.toOptions({ refine: {
Expand Down
6 changes: 3 additions & 3 deletions @fiction/ui/InputCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const classes = [
'focus:ring-0',
'focus:ring-offset-0',
// 'focus:ring-offset-transparent',
'bg-theme-100 hover:bg-theme-200 dark:bg-theme-800 dark:hover:bg-theme-500',
'bg-theme-100 hover:opacity-70 dark:bg-theme-800',
// 'text-theme-700 dark:text-theme-50',
]
Expand All @@ -45,7 +45,7 @@ export default {
</script>

<template>
<label class="text-input-size flex cursor-pointer items-center">
<label class="flex cursor-pointer items-center">
<input
v-bind="attrs"
type="checkbox"
Expand All @@ -54,7 +54,7 @@ export default {
@input="handleEmit($event.target)"
>

<span v-if=" text" class="checkbox-label text-theme-700 dark:text-theme-50 hover:text-theme-500 text-xs">
<span v-if=" text" class="checkbox-label text-theme-700 dark:text-theme-50 hover:text-theme-500 hover:opacity-70">
{{ text }}
</span>
</label>
Expand Down

0 comments on commit 5c5d402

Please sign in to comment.