diff --git a/packages/client/editor/src/components/workspaces/composer/composer.tsx b/packages/client/editor/src/components/workspaces/composer/composer.tsx
index 88129dbc97..581a46f3b0 100644
--- a/packages/client/editor/src/components/workspaces/composer/composer.tsx
+++ b/packages/client/editor/src/components/workspaces/composer/composer.tsx
@@ -220,10 +220,8 @@ export const Composer = ({ tab, theme, spellId }) => {
setApi(event.api)
}
- useEffect(() => {
- if (!api) return
-
- const unsubscribe = subscribe(events.$CREATE_TEXT_EDITOR(tab.id), () => {
+ const windowBarMap = {
+ [events.$CREATE_TEXT_EDITOR(tab.id)]: () => {
api.addPanel({
id: 'Text Editor',
component: 'TextEditor',
@@ -232,18 +230,63 @@ export const Composer = ({ tab, theme, spellId }) => {
tab,
spellId
},
+ position: { referencePanel: 'Composer', direction: 'left' },
+ })
+ },
+ [events.$CREATE_INSPECTOR(tab.id)]: () => {
+ api.addPanel({
+ id: 'Inspector',
+ component: 'Inspector',
+ params: {
+ title: 'Inspector',
+ tab,
+ spellId
+ },
+ position: { referencePanel: 'Composer', direction: 'left' },
+ })
+ },
+ [events.$CREATE_PLAYTEST(tab.id)]: () => {
+ api.addPanel({
+ id: 'Playtest',
+ component: 'Playtest',
+ params: {
+ title: 'Playtest',
+ tab,
+ spellId
+ },
+ position: { referencePanel: 'Composer', direction: 'below' },
})
+ },
+ [events.$CREATE_CONSOLE(tab.id)]: () => {
+ api.addPanel({
+ id: 'Console',
+ component: 'Console',
+ params: {
+ title: 'Console',
+ tab,
+ spellId
+ },
+ position: { referencePanel: 'Composer', direction: 'below' },
+ })
+ },
+ }
+
+ useEffect(() => {
+ if (!api) return
+
+ const windowBarSubscriptions = Object.entries(windowBarMap).map(([event, handler]) => {
+ return subscribe(event, handler)
})
- console.log('Setting up layout change listener')
api.onDidLayoutChange(() => {
const layout = api.toJSON()
-
saveLayoutToLocalStorage(spellId, layout)
})
return () => {
- unsubscribe()
+ windowBarSubscriptions.forEach(unsubscribe => {
+ unsubscribe()
+ })
}
}, [api])
diff --git a/packages/client/editor/src/components/workspaces/composer/index.tsx b/packages/client/editor/src/components/workspaces/composer/index.tsx
index 24fb7d7db9..4da347bd7f 100644
--- a/packages/client/editor/src/components/workspaces/composer/index.tsx
+++ b/packages/client/editor/src/components/workspaces/composer/index.tsx
@@ -4,37 +4,61 @@ import { Tab, useDockviewTheme } from 'client/state';
import { usePubSub } from '@magickml/providers';
import { Composer } from './composer';
-const DraggableElement = (props) => (
-
{
- if (event.dataTransfer) {
- event.dataTransfer.effectAllowed = 'move';
+const DraggableElement = (props) => {
+ const { tab } = props.params
+ const { publish, events } = usePubSub()
+ const windows = {
+ 'Console': () => {
+ publish(events.$CREATE_CONSOLE(tab.id))
+ },
+ 'TextEditor': () => {
+ publish(events.$CREATE_TEXT_EDITOR(tab.id))
+ },
+ 'Inspector': () => {
+ publish(events.$CREATE_INSPECTOR(tab.id))
+ },
+ 'Playtest': () => {
+ publish(events.$CREATE_PLAYTEST(tab.id))
+ }
+ }
- event.dataTransfer.setData('text/plain', 'nothing');
- event.dataTransfer.setData('component', props.window)
- event.dataTransfer.setData('title', props.title)
- }
- }}
- style={{
- padding: '8px',
- color: 'white',
- cursor: 'pointer',
- }}
- draggable={true}
- >
- {props.window}
-
-);
+ const handleClick = () => {
+ windows[props.window]()
+ }
+
+ return (
+ {
+ if (event.dataTransfer) {
+ event.dataTransfer.effectAllowed = 'move';
+
+ event.dataTransfer.setData('text/plain', 'nothing');
+ event.dataTransfer.setData('component', props.window)
+ event.dataTransfer.setData('title', props.title)
+ }
+ }}
+ style={{
+ padding: '8px',
+ color: 'white',
+ cursor: 'pointer',
+ }}
+ draggable={true}
+ onClick={handleClick}
+ >
+ {props.window}
+
+ )
+};
const composerLayoutComponents = {
WindowBar: (props: IGridviewPanelProps<{ title: string }>) => {
return (
-
-
-
-
+
+
+
+
)
},
@@ -53,6 +77,9 @@ const ComposerContainer = (props: IGridviewPanelProps<{ tab: Tab; theme: string,
component: 'WindowBar',
maximumHeight: 30,
minimumHeight: 30,
+ params: {
+ ...props.params
+ }
})
event.api.addPanel({
diff --git a/packages/client/editor/src/components/workspaces/composerv2/composer.tsx b/packages/client/editor/src/components/workspaces/composerv2/composer.tsx
index 4be879294d..017d763ce1 100644
--- a/packages/client/editor/src/components/workspaces/composerv2/composer.tsx
+++ b/packages/client/editor/src/components/workspaces/composerv2/composer.tsx
@@ -157,10 +157,8 @@ export const Composer = ({ tab, theme, spellId }) => {
setApi(event.api)
}
- useEffect(() => {
- if (!api) return
-
- const unsubscribe = subscribe(events.$CREATE_TEXT_EDITOR(tab.id), () => {
+ const windowBarMap = {
+ [events.$CREATE_TEXT_EDITOR(tab.id)]: () => {
api.addPanel({
id: 'Text Editor',
component: 'TextEditor',
@@ -169,7 +167,52 @@ export const Composer = ({ tab, theme, spellId }) => {
tab,
spellId
},
+ position: { referencePanel: 'Graph', direction: 'left' },
+ })
+ },
+ [events.$CREATE_INSPECTOR(tab.id)]: () => {
+ api.addPanel({
+ id: 'Inspector',
+ component: 'Inspector',
+ params: {
+ title: 'Inspector',
+ tab,
+ spellId
+ },
+ position: { referencePanel: 'Graph', direction: 'left' },
})
+ },
+ [events.$CREATE_PLAYTEST(tab.id)]: () => {
+ api.addPanel({
+ id: 'Chat',
+ component: 'Chat',
+ params: {
+ title: 'Chat',
+ tab,
+ spellId
+ },
+ position: { referencePanel: 'Graph', direction: 'below' },
+ })
+ },
+ [events.$CREATE_CONSOLE(tab.id)]: () => {
+ api.addPanel({
+ id: 'Console',
+ component: 'Console',
+ params: {
+ title: 'Console',
+ tab,
+ spellId
+ },
+ position: { referencePanel: 'Graph', direction: 'below' },
+ })
+ },
+ }
+
+ useEffect(() => {
+ if (!api) return
+
+ const windowBarSubscriptions = Object.entries(windowBarMap).map(([event, handler]) => {
+ return subscribe(event, handler)
})
api.onDidLayoutChange(() => {
@@ -179,7 +222,9 @@ export const Composer = ({ tab, theme, spellId }) => {
})
return () => {
- unsubscribe()
+ windowBarSubscriptions.forEach(unsubscribe => {
+ unsubscribe()
+ })
}
}, [api])
diff --git a/packages/client/editor/src/components/workspaces/composerv2/index.tsx b/packages/client/editor/src/components/workspaces/composerv2/index.tsx
index 74df0199fe..b27585475f 100644
--- a/packages/client/editor/src/components/workspaces/composerv2/index.tsx
+++ b/packages/client/editor/src/components/workspaces/composerv2/index.tsx
@@ -1,32 +1,56 @@
import { GridviewReact, IGridviewPanelProps, Orientation } from 'dockview';
import WorkspaceProvider from '../../../contexts/WorkspaceProvider'
-import { Tab, createStore, injectReducer, tabReducer, useDockviewTheme } from 'client/state';
+import { Tab, useDockviewTheme } from 'client/state';
import { usePubSub } from '@magickml/providers';
import { Composer } from './composer';
-import { useEffect } from 'react';
-const DraggableElement = (props) => (
- {
- if (event.dataTransfer) {
- event.dataTransfer.effectAllowed = 'move';
- event.dataTransfer.setData('text/plain', 'nothing');
- event.dataTransfer.setData('component', props.window)
- event.dataTransfer.setData('title', props.title)
- }
- }}
- style={{
- padding: '8px',
- color: 'white',
- cursor: 'pointer',
- }}
- draggable={true}
- >
- {props.window}
-
-);
+const DraggableElement = (props) => {
+ const { tab } = props.params
+ const { publish, events } = usePubSub()
+ const windows = {
+ 'Console': () => {
+ publish(events.$CREATE_CONSOLE(tab.id))
+ },
+ 'TextEditor': () => {
+ publish(events.$CREATE_TEXT_EDITOR(tab.id))
+ },
+ 'Inspector': () => {
+ publish(events.$CREATE_INSPECTOR(tab.id))
+ },
+ 'Playtest': () => {
+ publish(events.$CREATE_PLAYTEST(tab.id))
+ }
+ }
+
+ const handleClick = () => {
+ windows[props.window]()
+ }
+
+ return (
+ {
+ if (event.dataTransfer) {
+ event.dataTransfer.effectAllowed = 'move';
+
+ event.dataTransfer.setData('text/plain', 'nothing');
+ event.dataTransfer.setData('component', props.window)
+ event.dataTransfer.setData('title', props.title)
+ }
+ }}
+ onClick={handleClick}
+ style={{
+ padding: '8px',
+ color: 'white',
+ cursor: 'pointer',
+ }}
+ draggable={true}
+ >
+ {props.window}
+
+ )
+};
const composerLayoutComponents = {
WindowBar: (props: IGridviewPanelProps<{ title: string }>) => {
@@ -34,10 +58,10 @@ const composerLayoutComponents = {
Composer V2
-
-
-
-
+
+
+
+
)
@@ -48,7 +72,6 @@ const composerLayoutComponents = {
}
const ComposerContainer = (props: IGridviewPanelProps<{ tab: Tab; theme: string, spellId: string }>) => {
- const { tab } = props.params
const { theme } = useDockviewTheme()
const pubSub = usePubSub()
@@ -58,6 +81,9 @@ const ComposerContainer = (props: IGridviewPanelProps<{ tab: Tab; theme: string,
component: 'WindowBar',
maximumHeight: 30,
minimumHeight: 30,
+ params: {
+ ...props.params
+ }
})
event.api.addPanel({
diff --git a/packages/shared/nodeSpec/src/nodeSpec.json b/packages/shared/nodeSpec/src/nodeSpec.json
index 6578bbd999..5a51ae7414 100644
--- a/packages/shared/nodeSpec/src/nodeSpec.json
+++ b/packages/shared/nodeSpec/src/nodeSpec.json
@@ -49,6 +49,48 @@
],
"configuration": []
},
+ {
+ "type": "magick/fetch",
+ "category": "Action",
+ "label": "Fetch",
+ "inputs": [
+ {
+ "name": "flow",
+ "valueType": "flow"
+ },
+ {
+ "name": "method",
+ "valueType": "string",
+ "defaultValue": ""
+ },
+ {
+ "name": "headers",
+ "valueType": "string",
+ "defaultValue": ""
+ },
+ {
+ "name": "url",
+ "valueType": "string",
+ "defaultValue": ""
+ },
+ {
+ "name": "params",
+ "valueType": "string",
+ "defaultValue": ""
+ }
+ ],
+ "outputs": [
+ {
+ "name": "flow",
+ "valueType": "flow"
+ },
+ {
+ "name": "output",
+ "valueType": "string"
+ }
+ ],
+ "configuration": []
+ },
{
"type": "logic/string",
"category": "None",
diff --git a/plugins/core/src/lib/corePlugin.ts b/plugins/core/src/lib/corePlugin.ts
index f585f31ed7..b769896f00 100644
--- a/plugins/core/src/lib/corePlugin.ts
+++ b/plugins/core/src/lib/corePlugin.ts
@@ -12,6 +12,7 @@ import CoreEventClient from './services/coreEventClient'
import { RedisPubSub } from 'server/redis-pubsub'
import { CoreActionService } from './services/coreActionService'
import { sendMessage } from './nodes/actions/sendMessage'
+import { FetchNode } from './nodes/actions/Fetch'
import { Job } from 'bullmq'
import { SpellCaster } from 'server/grimoire'
@@ -23,7 +24,7 @@ const pluginName = 'Core'
export class CorePlugin extends CoreEventsPlugin {
override enabled = true
client: CoreEventClient
- nodes = [messageEvent, sendMessage]
+ nodes = [messageEvent, sendMessage, FetchNode.Description]
values = []
constructor(connection: Redis, agentId: string, pubSub: RedisPubSub) {
diff --git a/plugins/core/src/lib/nodes/actions/Fetch.ts b/plugins/core/src/lib/nodes/actions/Fetch.ts
new file mode 100644
index 0000000000..33f69da046
--- /dev/null
+++ b/plugins/core/src/lib/nodes/actions/Fetch.ts
@@ -0,0 +1,67 @@
+import {
+ Engine,
+ Socket,
+ NodeDescription,
+ NodeDescription2,
+ AsyncNode,
+ IGraph,
+ NodeCategory,
+} from '@magickml/behave-graph'
+import axios, { AxiosResponse } from 'axios'
+
+export class FetchNode extends AsyncNode {
+ public static Description = new NodeDescription2({
+ typeName: 'magick/fetch',
+ category: NodeCategory.Action,
+ label: 'Fetch',
+ factory: (description, graph) => new FetchNode(description, graph),
+ })
+
+ constructor(description: NodeDescription, graph: IGraph) {
+ super(
+ description,
+ graph,
+ [
+ new Socket('flow', 'flow'),
+ new Socket('string', 'method'),
+ new Socket('string', 'headers'),
+ new Socket('string', 'url'),
+ new Socket('string', 'params'),
+ ],
+ [new Socket('flow', 'flow'), new Socket('string', 'output')],
+ {},
+ 'FetchNode'
+ )
+ }
+
+ override async triggered(
+ engine: Engine,
+ triggeringSocketName: string,
+ finished: () => void
+ ): Promise {
+ const method = ((this.readInput('method') as string) || '')
+ .toLowerCase()
+ .trim()
+ const headers = (this.readInput('headers') as string) || {}
+ const url = (this.readInput('url') as string) || ''
+ const params = this.readInput('params') || {}
+
+ try {
+ const response: AxiosResponse = await axios({
+ url,
+ method,
+ data: params,
+ headers: headers,
+ })
+
+ const responseData = JSON.stringify(response.data)
+
+ this.writeOutput('output', responseData)
+ engine.commitToNewFiber(this, 'flow')
+ finished()
+ } catch (error) {
+ console.error('Request failed::::::::::::', error)
+ throw new Error(`Request failed with (${error})!`)
+ }
+ }
+}