diff --git a/actions/gptscript.tsx b/actions/gptscript.tsx index b3c576a0..e61ff6dd 100644 --- a/actions/gptscript.tsx +++ b/actions/gptscript.tsx @@ -1,6 +1,6 @@ 'use server'; -import { Tool, Block, Text } from '@gptscript-ai/gptscript'; +import { Tool, Block, Text, Program } from '@gptscript-ai/gptscript'; import { gpt } from '@/config/env'; export const rootTool = async (toolContent: string): Promise => { @@ -12,13 +12,24 @@ export const rootTool = async (toolContent: string): Promise => { return {} as Tool; }; -export const parse = async (toolContent: string): Promise => { +export const parseContent = async (toolContent: string): Promise => { const parsedTool = await gpt().parseContent(toolContent); return parsedTool.filter( (block) => block.type === 'tool' && !block.name?.startsWith('metadata') ) as Tool[]; }; +export const parse = async (file: string): Promise => { + const parsedTool = await gpt().parse(file); + return parsedTool.filter( + (block) => block.type === 'tool' && !block.name?.startsWith('metadata') + ) as Tool[]; +}; + +export const load = async (file: string): Promise => { + return (await gpt().load(file)).program; +}; + export const getTexts = async (toolContent: string): Promise => { const parsedTool = await gpt().parseContent(toolContent); return parsedTool.filter((block) => block.type === 'text') as Text[]; diff --git a/components/edit/configure/imports.tsx b/components/edit/configure/imports.tsx index 251aa379..c591d628 100644 --- a/components/edit/configure/imports.tsx +++ b/components/edit/configure/imports.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useContext } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { Button } from '@nextui-org/react'; import { GoBook, @@ -33,7 +33,14 @@ import { } from 'react-icons/pi'; import { EditContext } from '@/contexts/edit'; import CustomTool from '@/components/edit/configure/customTool'; -import { SiAmazoneks, SiGooglecloud, SiJson, SiSupabase } from 'react-icons/si'; +import { + SiAmazoneks, + SiGooglecloud, + SiJson, + SiMongodb, + SiNotion, + SiSupabase, +} from 'react-icons/si'; import { VscAzure } from 'react-icons/vsc'; import { BsClock, @@ -47,6 +54,8 @@ import { import { MdDeleteForever } from 'react-icons/md'; import PropTypes from 'prop-types'; +import { load } from '@/actions/gptscript'; + interface ImportsProps { tools: string[] | undefined; setTools: (tools: string[]) => void; @@ -62,143 +71,70 @@ const Imports: React.FC = ({ collapsed, enableLocal = 'true', }) => { - const [remoteTools, setRemoteTools] = useState([]); + // remoteTools contains a mapping of tool references to display names for + const [remoteTools, setRemoteTools] = useState>( + new Map() + ); const [localTools, setLocalTools] = useState([]); const { createNewTool, deleteLocalTool } = useContext(EditContext); + const updateRemoteTools = async (remoteRefs: string[]) => { + const updatedRemoteTools = new Map(remoteTools); + for (const ref of remoteRefs) { + if (updatedRemoteTools.has(ref)) { + // We've already the display name of this tool + continue; + } + updatedRemoteTools.set(ref, await getDisplayName(ref)); + } + + setRemoteTools(() => { + const newRemoteTools = new Map(); + updatedRemoteTools.forEach((value, key) => { + newRemoteTools.set(key, value); + }); + return newRemoteTools; + }); + }; + useEffect(() => { if (tools) { - setLocalTools( - tools.filter( - (t) => - !( - t.startsWith('https://') || - t.startsWith('http://') || - t.startsWith('sys.') || // not local, but considered remote for the purposes of this component - t.startsWith('github.com') - ) - ) - ); - setRemoteTools( - tools.filter( - (t) => - t.startsWith('https://') || - t.startsWith('http://') || - t.startsWith('sys.') || // not local, but considered remote for the purposes of this component - t.startsWith('github.com') - ) - ); + setLocalTools(tools.filter((t) => !isRemote(t))); + updateRemoteTools(tools.filter(isRemote)).catch((e) => { + console.error('failed to update remote tools', e); + }); } }, [tools]); - // note - I know this is a bit of a mess, but it's a quick way to get icons for tools - const iconForTool = (tool: string) => { - switch (tool.split('/').pop()?.replace(/-/g, ' ')) { - case 'gpt4 v vision': - return ; - case 'dalle image generation': - return ; - case 'answers from the internet': - return ; - case 'search website': - return ; - case 'browser': - return ; - case 'write': - return ; - case 'trello': - return ; - case 'manage': - return ; - case 'knowledge': - return ; - case 'structured data querier': - return ; - case 'json query': - return ; - case 'filesystem': - return ; - case 'workspace': - return ; - case 'github': - return ; - case 'aws': - return ; - case 'azure': - return ; - case 'digitalocean': - return ; - case 'eksctl': - return ; - case 'gcp': - return ; - case 'k8s': - return ; - case 'read-write': - return ; - case 'supabase': - return ; - case 'sys.append': - return ; - case 'sys.download': - return ; - case 'sys.exec': - return ; - case 'sys.find': - return ; - case 'sys.getenv': - return ; - case 'sys.http.html2text': - return ; - case 'sys.http.get': - return ; - case 'sys.http.post': - return ; - case 'sys.ls': - return ; - case 'sys.prompt': - return ; - case 'sys.read': - return ; - case 'sys.remove': - return ; - case 'sys.stat': - return ; - case 'sys.time.now': - return ; - case 'sys.write': - return ; - } - }; + const deleteRemoteTool = (tool: string) => { + // Remove the remote tool's display name mapping + setRemoteTools((prevRemoteTools) => { + const newRemoteTools = new Map(prevRemoteTools); + newRemoteTools.delete(tool); + return newRemoteTools; + }); - const handleDeleteTool = (tool: string) => { + // Remove the tool from the assistant setTools(tools!.filter((t) => t !== tool)); }; return (
- {remoteTools && remoteTools.length > 0 && ( + {remoteTools && remoteTools.size > 0 && (
- {remoteTools.map((tool, i) => ( + {Array.from(remoteTools.keys()).map((ref, i) => (
- {iconForTool(tool)} -

- {tool - .split('/') - .pop() - ?.replace(/-/g, ' ') - .replace('sys.', '') - .replace('.', ' ')} -

+ {iconForTool(ref)} +

{remoteTools.get(ref)!}

@@ -234,10 +170,16 @@ const Imports: React.FC = ({ > setTools([...(tools || []), tool])} - removeTool={(tool) => - setTools(tools?.filter((t) => t !== tool) || []) - } + addTool={(tool) => { + setTools([...(tools || []), tool]); + }} + removeTool={(tool) => { + if (isRemote(tool)) { + deleteRemoteTool(tool); + } else { + setTools(tools?.filter((t) => t !== tool) || []); + } + }} /> {enableLocal && (