Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: AI Powered Routines #46

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2c6536e
[feat] Automation workflows - wip
Sep 22, 2024
a7102c2
[feat] Automation workflows - wip
Sep 22, 2024
dc92b13
[feat] Layoutbuilder - wip
Sep 25, 2024
1e40724
[feat] Layout Builder
Sep 26, 2024
18cb097
Merge remote-tracking branch 'origin/feat/automation' into feat/autom…
Sep 26, 2024
4d6c79b
[feat] Automation workflows - wip
Sep 22, 2024
ba35aee
[feat] Layoutbuilder - wip
Sep 25, 2024
fda9749
[feat] Layout Builder
Sep 26, 2024
3fb837a
[feat] Automation workflows - wip
Sep 22, 2024
a53c4db
Merge remote-tracking branch 'origin/feat/automation' into feat/autom…
Sep 30, 2024
8b92da2
Merge remote-tracking branch 'origin/main' into feat/automation
Oct 1, 2024
bd1d968
[fix] hold - zod schema builder
Oct 3, 2024
4683917
[fix] Remove zod and use jsonSchema
Oct 3, 2024
76d514b
[fix] payload update and lexical schema optimization
Oct 8, 2024
91e6326
[fix] Disable row type fields[not supported yet for ai]
Oct 8, 2024
e298b8d
[fix] Improve upload media
Oct 8, 2024
79063df
[fix] Remove global fields map
Oct 8, 2024
435c6f6
[fix] useConfig hook to get server and api url
Oct 8, 2024
2c3f4d4
[chore] update package version to 3.0.0-beta.111
Oct 8, 2024
63dd0c5
Merge pull request #50 from ashbuilds/chore/remove-zod
ashbuilds Oct 8, 2024
8d48f60
[feat] Automation workflows - wip
Sep 22, 2024
12c729a
[feat] Layoutbuilder - wip
Sep 25, 2024
b5e62fd
[feat] Layout Builder
Sep 26, 2024
cbe06c0
[feat] Automation workflows - wip
Sep 22, 2024
9f4bd98
[feat] Automation workflows - wip
Sep 22, 2024
8e9c6e9
[fix] hold - zod schema builder
Oct 3, 2024
a8a2b6c
[chore] resolve conflicts
Oct 9, 2024
2984219
Merge remote-tracking branch 'origin/feat/automation' into feat/autom…
Oct 9, 2024
0993001
[chore] conflict fixes
Oct 9, 2024
c54bf06
[chore] conflict fixes
Oct 9, 2024
8c92cef
[feat] add automation collection to config
Oct 9, 2024
432ec61
[feat] automation improvements
Oct 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/ai/schemas/laxical.schemaMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { z } from 'zod'

const BaseNode = z.object({
type: z.string(),
children: z.array(z.lazy(() => Node)).optional(),
direction: z.enum(['ltr']).nullable().optional(),
format: z.string().optional(),
indent: z.number().optional(),
version: z.number().optional(),
})

export const LexicalSchemaMap = {
heading: BaseNode.extend({
type: z.literal('heading',{ description: 'Use to refer HTML heading tags, such as h1, h2, h3, h4 '}),
tag: z.enum(['h1', 'h2', 'h3', 'h4']),
}),
horizontalrule: BaseNode.extend({ type: z.literal('horizontalrule') }),
link: BaseNode.extend({
id: z.string(),
type: z.literal('link',{
description: 'Use to refer HTML anchor tag'
}),
fields: z.object({
linkType: z.string(),
newTab: z.boolean(),
url: z.string(),
}),
}),
paragraph: BaseNode.extend({ type: z.literal('paragraph') }),
quote: BaseNode.extend({ type: z.literal('quote') }),
text: BaseNode.extend({
type: z.literal('text'),
format: z.number().optional(),
text: z.string(),
}),
list: BaseNode.extend({
type: z.literal('list',{ description: 'Use to refer HTML unordered list and ordered list' }),
listType: z.enum(['check', 'number', 'bullet']),
start: z.number(),
tag: z.enum(['ul', 'ol']),
}),
listItem: BaseNode.extend({
type: z.literal('listitem',{description:'Use to refer HTML li(list item) tag'}),
checked: z.boolean().optional(),
value: z.number(),
})
}

const Node = z.union([
LexicalSchemaMap.text,
LexicalSchemaMap.link,
LexicalSchemaMap.list,
LexicalSchemaMap.listItem,
LexicalSchemaMap.heading,
LexicalSchemaMap.paragraph,
LexicalSchemaMap.quote,
LexicalSchemaMap.horizontalrule
])
214 changes: 214 additions & 0 deletions src/ai/schemas/schemaBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
import { z } from 'zod'

const BaseNode = z.object({
type: z.string(),
children: z.array(z.lazy(() => Node)).optional(),
description: z.string().optional(),
direction: z.enum(['ltr']).nullable().optional(),
format: z.string().optional(),
indent: z.number().optional(),
key: z.string().optional(),
title: z.string().optional(),
version: z.number().optional(),
})

const TextNode = BaseNode.extend({
type: z.literal('text'),
format: z.number().optional(),
text: z.string(),
})

const LinkNode = BaseNode.extend({
id: z.string(),
type: z.literal('link'),
fields: z.object({
linkType: z.string(),
newTab: z.boolean(),
url: z.string(),
}),
})

const ListItemNode = BaseNode.extend({
type: z.literal('listItem'),
})

const ListNode = BaseNode.extend({
type: z.literal('list'),
listType: z.enum(['check', 'number', 'bullet']).optional(),
start: z.number().optional(),
tag: z.enum(['ul', 'ol']).optional(),
})

const HeadingNode = BaseNode.extend({
type: z.literal('heading'),
tag: z.enum(['h1', 'h2', 'h3', 'h4']),
})

const QuoteNode = BaseNode.extend({
type: z.literal('quote'),
})

const HorizontalRuleNode = BaseNode.extend({
type: z.literal('horizontalrule'),
})

const ParagraphNode = BaseNode.extend({
type: z.literal('paragraph'),
})

const Node = z.union([
TextNode,
LinkNode,
ListItemNode,
ListNode,
HeadingNode,
QuoteNode,
HorizontalRuleNode,
ParagraphNode,
])
function reorganizeZodSchema(json: any): z.ZodType<any> {
function createNodeSchema(node: any): z.ZodType<any> {
const baseSchema = BaseNode

const childrenSchema = node.children
? z.array(z.lazy(() => z.union(node.children.map(createNodeSchema))))
: undefined

switch (node.type) {
case 'heading':
return baseSchema.extend({
children: childrenSchema,
tag: z.enum(['h1', 'h2', 'h3', 'h4']).optional(),
})
case 'paragraph':
return baseSchema.extend({
children: childrenSchema,
})
case 'horizontalrule':
return baseSchema
case 'list':
return baseSchema.extend({
children: childrenSchema,
listType: z.enum(['check', 'number', 'bullet']).optional(),
start: z.number().optional(),
tag: z.enum(['ul', 'ol']).optional(),
})
case 'listItem':
return baseSchema.extend({
checked: z.boolean().optional(),
children: childrenSchema,
value: z.number().optional(),
})
case 'quote':
return baseSchema.extend({
children: childrenSchema,
})
default:
return baseSchema.extend({
children: childrenSchema,
})
}
}

const rootSchema = z.array(z.lazy(() => z.union(json.map(createNodeSchema))))

return z.object({
root: z.object({
type: z.literal('root'),
children: rootSchema,
}),
})
}

export { reorganizeZodSchema }

// The base schema for each node type
const schemas = {
heading: z.object({
type: z.literal('heading'),
children: z.array(z.lazy(() => NodeSchema)).optional(),
tag: z.enum(['h1', 'h2', 'h3', 'h4']),
description: z.string().optional(),
key: z.string().optional(),
title: z.string().optional(),
}),
paragraph: z.object({
type: z.literal('paragraph'),
children: z.array(z.lazy(() => NodeSchema)).optional(),
description: z.string().optional(),
key: z.string().optional(),
title: z.string().optional(),
}),
list: z.object({
type: z.literal('list'),
children: z.array(z.lazy(() => NodeSchema)).optional(),
listType: z.enum(['check', 'number', 'bullet']).optional(),
start: z.number().optional(),
tag: z.enum(['ul', 'ol']).optional(),
description: z.string().optional(),
key: z.string().optional(),
title: z.string().optional(),
}),
listItem: z.object({
type: z.literal('listItem'),
children: z.array(z.lazy(() => NodeSchema)).optional(),
description: z.string().optional(),
key: z.string().optional(),
title: z.string().optional(),
}),
horizontalrule: z.object({
type: z.literal('horizontalrule'),
description: z.string().optional(),
key: z.string().optional(),
title: z.string().optional(),
}),
quote: z.object({
type: z.literal('quote'),
children: z.array(z.lazy(() => NodeSchema)).optional(),
description: z.string().optional(),
key: z.string().optional(),
title: z.string().optional(),
}),
}

// Union of all node schemas
const NodeSchema = z.union([
schemas.heading,
schemas.paragraph,
schemas.list,
schemas.listItem,
schemas.horizontalrule,
schemas.quote,
])

// Root schema that holds all the nodes
const RootNodeSchema = z.array(NodeSchema);

// Recursive function to build schema from JSON
function createZodSchemaFromJson(json: any): z.ZodTypeAny {
if (Array.isArray(json)) {
// The root node is an array of NodeSchema
return RootNodeSchema.describe("Root node containing all child nodes");
}

// Select the schema based on the node type
const schema = schemas[json.type];

if (!schema) {
throw new Error(`Unknown node type: ${json.type}`);
}

// Recursively handle children and apply description if present
const nodeSchema = schema.describe(json.description || '');

if (json.children) {
const childrenSchema = z.array(createZodSchemaFromJson(json.children));
return nodeSchema.extend({
children: childrenSchema.optional(),
});
}

return nodeSchema;
}

export { createZodSchemaFromJson }
16 changes: 16 additions & 0 deletions src/fields/LayoutBuilder/Item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React, { memo } from 'react'

import styles from './menu.module.scss'

export const Item: React.FC<any> = memo(({ children, disabled, isActive, onClick, ...rest }) => (
<span
className={styles.generate_button + ' ' + (isActive ? styles.active : '')}
data-disabled={disabled}
onClick={!disabled ? onClick : null}
onKeyDown={!disabled ? onClick : null}
role="presentation"
{...rest}
>
{children}
</span>
))
87 changes: 87 additions & 0 deletions src/fields/LayoutBuilder/LayoutBuilder.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
.wrapper{
display: flex;
flex-direction: column;
align-items: center;
}

.builder {
//display: flex;
//flex-direction: column;
padding: 0.5rem 0;
margin: 0.5rem 0;
min-width: 400px;
//border: 1px solid #585858;
&:global(.btn--style-none) {

}
}

.inputWrapper {
display: flex;
gap: 8px;
margin-bottom: 2px;
align-items: center;
//justify-content: center;
}

.select {
//flex-grow: 1;
//width: 100%;

&:global(.react-select) :global(.rs__control) {
background-color: transparent;
//border: none;
}
}

.item {
width: 100%;
display: flex;
flex-direction: column;
position: relative;
}

.nodeType {
position: absolute;
background: #141414;
right: 10px;
top: -1rem;
border-radius: 3px;
padding: 0.2rem 0.4rem;
}

.input {
padding: 0.5rem;
}

.removeNodeButton{
margin: 0 !important;
}

.horizontalrule {
width: 200px;
}

.contentEditable {
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
min-height: 2rem;
outline: none;

min-width: 200px;


&:focus {
border-color: #007bff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
}


.nodeWrapper{
display: flex;
flex-direction: row;
gap: 8px;
align-items: center;
}
Loading