Skip to content
This repository has been archived by the owner on Aug 30, 2022. It is now read-only.

Commit

Permalink
Merge pull request #181 from latitudegames/0.0.67
Browse files Browse the repository at this point in the history
0.0.67
  • Loading branch information
parzival418 authored May 2, 2022
2 parents 9c1f7b6 + 8836560 commit 85a21d4
Show file tree
Hide file tree
Showing 56 changed files with 783 additions and 175 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:3001",
"url": "http://localhost:3003",
"sourceMap": true,
"webRoot": "${workspaceFolder}/client",
"trace": true,
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ In the project directory, you can run:
### `yarn start`

Runs @thoth/client in the development mode.\
Open [http://localhost:3001](http://localhost:3001) to view it in the browser.
Open [http://localhost:3003](http://localhost:3003) to view it in the browser.

### `yarn build`

Expand Down
3 changes: 2 additions & 1 deletion client/.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ EXTEND_ESLINT = true

REACT_APP_SITE_ROOT_URL_PROD=https://thoth.latitude.io

REACT_APP_SITE_ROOT_URL=http://localhost:3001
REACT_APP_SITE_ROOT_URL=http://localhost:3003
REACT_APP_LAPI_ROOT_URL=http://localhost:8000

REACT_APP_LAPI_ROOT_URL_PROD=https://api.latitude.io
Expand All @@ -15,3 +15,4 @@ REACT_APP_SITE_STAGING=https://62264f21c3a9860ad1e5bdd3--optimistic-turing-def91
REACT_APP_OAUTH_CLIENT_ID=a6b51c87-7565-42ab-a4b0-38a07f3b6c56

REACT_APP_SHAREDB=false
REACT_APP_WEBSOCKETS=false
2 changes: 1 addition & 1 deletion client/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ EXTEND_ESLINT = true

# This prod site root assumes the netlify build context $URL is available, replace for other hosts
REACT_APP_SITE_ROOT_URL_PROD=$URL
REACT_APP_SITE_ROOT_URL=http://localhost:3001
REACT_APP_SITE_ROOT_URL=http://localhost:3003
REACT_APP_LAPI_ROOT_URL=http://localhost:8000
REACT_APP_LAPI_ROOT_URL_PROD=https://api.latitude.io
REACT_APP_SITE_STAGING=https://62264f21c3a9860ad1e5bdd3--optimistic-turing-def916.netlify.app/
Expand Down
2 changes: 1 addition & 1 deletion client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ In the project directory, you can run:
### `yarn start`

Runs the app in the development mode.\
Open [http://localhost:3001](http://localhost:3001) to view it in the browser.
Open [http://localhost:3003](http://localhost:3003) to view it in the browser.

The page will reload if you make edits.\
You will also see any lint errors in the console.
Expand Down
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"@callstack/async-storage": "^2.0.3",
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@latitudegames/thoth-core": "^0.0.66",
"@latitudegames/thoth-core": "^0.0.67",
"@monaco-editor/react": "^4.2.1",
"@mui/icons-material": "^5.5.1",
"@mui/material": "^5.5.3",
Expand Down
1 change: 1 addition & 0 deletions client/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export const appRootUrl =

// coercing this into a boolean
export const sharedb = process.env.REACT_APP_SHAREDB === 'true'
export const websockets = process.env.REACT_APP_WEBSOCKETS === 'true'
export const websocketUrl = 'ws://localhost:8080'
2 changes: 2 additions & 0 deletions client/src/contexts/AppProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import AuthProvider from './AuthProvider'
import PubSubProvider from './PubSubProvider'
import SharedbProvider from './SharedbProvider'
import ToastProvider from './ToastProvider'
import WebSocketProvider from './WebSocketProvider'

declare module '@mui/styles/defaultTheme' {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
Expand All @@ -28,6 +29,7 @@ const providers = [
[ThemeProvider, { theme: darkTheme }],
ToastProvider,
AuthProvider,
WebSocketProvider,
SharedbProvider,
]

Expand Down
1 change: 1 addition & 0 deletions client/src/contexts/PubSubProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const events = {
UPDATE_SUBSPELL: 'updateSubspell',
DELETE_SUBSPELL: 'deleteSubspell',
$SUBSPELL_UPDATED: spellId => `subspellUpdated:${spellId}`,
$TRIGGER: (tabId, nodeId) => `triggerNode:${tabId}:${nodeId}`,
$PLAYTEST_INPUT: tabId => `playtestInput:${tabId}`,
$PLAYTEST_PRINT: tabId => `playtestPrint:${tabId}`,
$DEBUG_PRINT: tabId => `debugPrint:${tabId}`,
Expand Down
13 changes: 4 additions & 9 deletions client/src/contexts/SharedbProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import { sharedb, websocketUrl } from '@/config'
import { sharedb } from '@/config'
import { useContext, createContext, useEffect, useState } from 'react'
import { Doc } from 'sharedb'

import ReconnectingWebSocket from 'reconnecting-websocket'
import client from 'sharedb/lib/client'
import { Socket } from 'sharedb/lib/sharedb'
import { Spell } from '@latitudegames/thoth-core/types'
import LoadingScreen from '@/components/LoadingScreen/LoadingScreen'
import { useWebSocket } from './WebSocketProvider'

const Connection = client.Connection

interface SharedbContext {
connection: client.Connection | null
socket: Socket | null
getSpellDoc: (spell: Spell) => Doc | null
}

const Context = createContext<SharedbContext>({
connection: null,
socket: null,
getSpellDoc: () => null,
})

Expand All @@ -28,14 +26,12 @@ export const docMap = new Map()

// Might want to namespace these
const SharedbProvider = ({ children }) => {
const [socket, setSocket] = useState<Socket | null>(null)
const { socket } = useWebSocket()
const [connection, setConnection] = useState<client.Connection | null>(null)

useEffect(() => {
const _socket = new ReconnectingWebSocket(websocketUrl)
const _connection = new Connection(_socket as Socket)
const _connection = new Connection(socket as Socket)
setConnection(_connection)
setSocket(_socket as Socket)
}, [])

const getSpellDoc = (spell: Spell) => {
Expand All @@ -61,7 +57,6 @@ const SharedbProvider = ({ children }) => {
}

const publicInterface: SharedbContext = {
socket,
connection,
getSpellDoc,
}
Expand Down
46 changes: 46 additions & 0 deletions client/src/contexts/WebSocketProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { websockets, websocketUrl } from '@/config'
import { useContext, createContext, useEffect, useState } from 'react'

import ReconnectingWebSocket from 'reconnecting-websocket'
import { Socket } from 'sharedb/lib/sharedb'
import LoadingScreen from '@/components/LoadingScreen/LoadingScreen'

interface SharedbContext {
socket: Socket | null
}

const Context = createContext<SharedbContext>({
socket: null,
})

export const useWebSocket = () => useContext(Context)

export const docMap = new Map()

// Might want to namespace these
const WebSocketProvider = ({ children }) => {
const [socket, setSocket] = useState<Socket | null>(null)

useEffect(() => {
const _socket = new ReconnectingWebSocket(websocketUrl)
setSocket(_socket as Socket)

_socket.send('testing')
}, [])

const publicInterface: SharedbContext = {
socket,
}

if (!socket) return <LoadingScreen />

return <Context.Provider value={publicInterface}>{children}</Context.Provider>
}

const ConditionalProvider = props => {
if (!websockets) return props.children

return <WebSocketProvider {...props} />
}

export default ConditionalProvider
18 changes: 17 additions & 1 deletion client/src/services/game-api/text.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import { latitudeApiRootUrl } from '@/config'
import { getAuthHeader } from '../../contexts/AuthProvider'

export const getModels = async () => {
try {
const response = await fetch(latitudeApiRootUrl + '/text/models', {
method: 'GET',
headers: {
...(await getAuthHeader()),
},
})
const result = await response.json()
return result
} catch (err) {
// eslint-disable-next-line no-console
console.warn('fetch error', err)
}
}

export const completion = async body => {
try {
const response = await fetch(latitudeApiRootUrl + '/text/completions_v2', {
Expand All @@ -9,7 +25,7 @@ export const completion = async body => {
'Content-Type': 'application/json',
...(await getAuthHeader()),
},
body: JSON.stringify({ ...body, prompt: body.prompt.trimEnd() }),
body: JSON.stringify({ ...body, prompt: body.prompt }),
})
const result = await response.json()
return result.completions[0].text
Expand Down
8 changes: 6 additions & 2 deletions client/src/state/api/spells.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface RunSpell {
spellId: string
version?: string
inputs: Record<string, any>
state?: Record<string, any>
}

export const spellApi = rootApi.injectEndpoints({
Expand All @@ -61,10 +62,13 @@ export const spellApi = rootApi.injectEndpoints({
},
}),
runSpell: builder.mutation<Record<string, any>, RunSpell>({
query: ({ spellId, version = 'latest', inputs }) => ({
query: ({ spellId, version = 'latest', inputs, state = {} }) => ({
url: `game/chains/${spellId}/${version}`,
method: 'POST',
body: inputs,
body: {
...inputs,
state,
},
}),
}),
saveDiff: builder.mutation<void, Diff>({
Expand Down
4 changes: 2 additions & 2 deletions client/src/workspaces/contexts/LayoutProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const LayoutProvider = ({ children, tab }) => {
}

const createOrFocus = (componentName, title) => {
if (!currentModelRef.current || !currentModel) return
if (!currentModelRef.current) return

// We are here using a provate variable, so TS isnt picking it up
// @ts-expect-error
Expand All @@ -129,7 +129,7 @@ const LayoutProvider = ({ children, tab }) => {
)

// the nodeId is stored in the zeroth index of the find
if (component) currentModel.doAction(Actions.selectTab(component[0]))
if (component) currentModel?.doAction(Actions.selectTab(component[0]))
if (!component) addWindow(componentName, title)
}

Expand Down
45 changes: 39 additions & 6 deletions client/src/workspaces/contexts/ThothInterfaceProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,19 @@ const ThothInterfaceProvider = ({ children, tab }) => {
UPDATE_SUBSPELL,
$SUBSPELL_UPDATED,
$PROCESS,
$TRIGGER,
} = events

const onTrigger = (node, callback) => {
let isDefault = node === 'default' ? 'default' : null
return subscribe($TRIGGER(tab.id, isDefault ?? node.id), (event, data) => {
publish($PROCESS(tab.id))
// weird hack. This staggers the process slightly to allow the published event to finish before the callback runs.
// No super elegant, but we need a better more centralised way to run the engine than these callbacks.
setTimeout(() => callback(data), 0)
})
}

const onInspector = (node, callback) => {
return subscribe($NODE_SET(tab.id, node.id), (event, data) => {
callback(data)
Expand Down Expand Up @@ -132,7 +143,7 @@ const ThothInterfaceProvider = ({ children, tab }) => {
return result.data
}

const processCode = (code, inputs, data) => {
const processCode = (code, inputs, data, state) => {
const flattenedInputs = Object.entries(inputs as ThothWorkerInputs).reduce(
(acc, [key, value]) => {
acc[key as string] = value[0]
Expand All @@ -141,15 +152,19 @@ const ThothInterfaceProvider = ({ children, tab }) => {
{} as Record<string, any>
)
// eslint-disable-next-line no-new-func
return Function('"use strict";return (' + code + ')')()(
const result = new Function('"use strict";return (' + code + ')')()(
flattenedInputs,
data
data,
state
)
if (result.state) {
updateCurrentGameState(result.state)
}
return result
}

const runSpell = async (inputs, spellId) => {
console.log('RUN SPELL')
const response = await _runSpell({ inputs, spellId })
const runSpell = async (inputs, spellId, state) => {
const response = await _runSpell({ inputs, spellId, state })

if ('error' in response) {
throw new Error(`Error running spell ${spellId}`)
Expand All @@ -168,6 +183,16 @@ const ThothInterfaceProvider = ({ children, tab }) => {
return spellRef.current?.gameState ?? {}
}

const setCurrentGameState = newState => {
if (!spellRef.current) return

const update = {
gameState: newState,
}

publish($SAVE_SPELL_DIFF(tab.id), update)
}

const updateCurrentGameState = _update => {
if (!spellRef.current) return
const spell = spellRef.current
Expand All @@ -184,10 +209,17 @@ const ThothInterfaceProvider = ({ children, tab }) => {
},
}

// Temporarily update the spell refs game state to account for multiple state writes in a spell run
spellRef.current = {
...spell,
...update,
}

publish($SAVE_SPELL_DIFF(tab.id), update)
}

const publicInterface = {
onTrigger,
onInspector,
onAddModule,
onUpdateModule,
Expand All @@ -204,6 +236,7 @@ const ThothInterfaceProvider = ({ children, tab }) => {
huggingface,
readFromImageCache,
getCurrentGameState,
setCurrentGameState,
updateCurrentGameState,
processCode,
runSpell,
Expand Down
2 changes: 2 additions & 0 deletions client/src/workspaces/spells/DataControls/DataControls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import InputGenerator from './InputGenerator'
import LongText from './LongTextControl'
import OutputGenerator from './OutputGenerator'
import DropdownSelect from './DropdownSelect'
import ModelSelect from './ModelSelect'
import SocketGenerator from './SocketGenerator'
import PlaytestControl from './PlaytestControl'
import SwitchControl from './SwitchControl'
Expand All @@ -30,6 +31,7 @@ const controlMap = {
playtest: PlaytestControl,
switch: SwitchControl,
dropdownSelect: DropdownSelect,
modelSelect: ModelSelect,
}

const DataControls = ({
Expand Down
Loading

0 comments on commit 85a21d4

Please sign in to comment.