diff --git a/apps/dashboard/src/app/nebula-app/(app)/api/chat.ts b/apps/dashboard/src/app/nebula-app/(app)/api/chat.ts index b3b7fc6e177..e828f49333d 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/api/chat.ts +++ b/apps/dashboard/src/app/nebula-app/(app)/api/chat.ts @@ -2,42 +2,33 @@ import { NEXT_PUBLIC_NEBULA_URL } from "@/constants/env"; // TODO - copy the source of this library to dashboard import { stream } from "fetch-event-stream"; import type { NebulaTxData } from "../components/Chats"; -import type { ExecuteConfig } from "./types"; -export type ContextFilters = { - chainIds?: string[]; - contractAddresses?: string[]; - walletAddresses?: string[]; +export type NebulaContext = { + chainIds: string[] | null; + walletAddress: string | null; }; export async function promptNebula(params: { message: string; sessionId: string; - config: ExecuteConfig | null; authToken: string; handleStream: (res: ChatStreamedResponse) => void; abortController: AbortController; - contextFilters: undefined | ContextFilters; + context: undefined | NebulaContext; }) { const body: Record = { message: params.message, - user_id: "default-user", - session_id: params.sessionId, stream: true, + session_id: params.sessionId, }; - if (params.contextFilters) { - body.context_filter = { - chain_ids: params.contextFilters.chainIds || [], - contract_addresses: params.contextFilters.contractAddresses || [], - wallet_addresses: params.contextFilters.walletAddresses || [], + if (params.context) { + body.context = { + chain_ids: params.context.chainIds || [], + wallet_address: params.context.walletAddress, }; } - if (params.config) { - body.execute_config = params.config; - } - const events = await stream(`${NEXT_PUBLIC_NEBULA_URL}/chat`, { method: "POST", headers: { diff --git a/apps/dashboard/src/app/nebula-app/(app)/api/session.ts b/apps/dashboard/src/app/nebula-app/(app)/api/session.ts index 12052c24810..2f0cbf8f91a 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/api/session.ts +++ b/apps/dashboard/src/app/nebula-app/(app)/api/session.ts @@ -1,33 +1,23 @@ import { NEXT_PUBLIC_NEBULA_URL } from "@/constants/env"; import { fetchWithAuthToken } from "../../../../utils/fetchWithAuthToken"; -import type { ContextFilters } from "./chat"; +import type { NebulaContext } from "./chat"; import type { DeletedSessionInfo, - ExecuteConfig, SessionInfo, TruncatedSessionInfo, UpdatedSessionInfo, } from "./types"; -// TODO - get the spec for return types on /session POST and PUT - export async function createSession(params: { authToken: string; - config: ExecuteConfig | null; - contextFilters: ContextFilters | undefined; + context: NebulaContext | undefined; }) { - const body: Record = { - can_execute: !!params.config, - }; - if (params.config) { - body.execute_config = params.config; - } + const body: Record = {}; - if (params.contextFilters) { - body.context_filter = { - chain_ids: params.contextFilters.chainIds || [], - contract_addresses: params.contextFilters.contractAddresses || [], - wallet_addresses: params.contextFilters.walletAddresses || [], + if (params.context) { + body.context = { + chain_ids: params.context.chainIds || [], + wallet_address: params.context.walletAddress, }; } @@ -48,22 +38,15 @@ export async function createSession(params: { export async function updateSession(params: { authToken: string; - config: ExecuteConfig | null; sessionId: string; - contextFilters: ContextFilters | undefined; + contextFilters: NebulaContext | undefined; }) { - const body: Record = { - can_execute: !!params.config, - }; - if (params.config) { - body.execute_config = params.config; - } + const body: Record = {}; if (params.contextFilters) { - body.context_filter = { + body.context = { chain_ids: params.contextFilters.chainIds || [], - contract_addresses: params.contextFilters.contractAddresses || [], - wallet_addresses: params.contextFilters.walletAddresses || [], + wallet_address: params.contextFilters.walletAddress, }; } diff --git a/apps/dashboard/src/app/nebula-app/(app)/api/types.ts b/apps/dashboard/src/app/nebula-app/(app)/api/types.ts index d98af8e5719..ee6a2c83432 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/api/types.ts +++ b/apps/dashboard/src/app/nebula-app/(app)/api/types.ts @@ -1,28 +1,6 @@ -type EngineConfig = { - mode: "engine"; - engine_url: string; - engine_authorization_token: string; - engine_backend_wallet_address: string; -}; - -type SessionKeyConfig = { - mode: "session_key"; - smart_account_address: string; - smart_account_factory_address: string; - smart_account_session_key: string; -}; - -type ClientConfig = { - mode: "client"; - signer_wallet_address: string; -}; - -export type ExecuteConfig = EngineConfig | SessionKeyConfig | ClientConfig; - type SessionContextFilter = { chain_ids: string[] | null; - contract_addresses: string[] | null; - wallet_addresses: string[] | null; + wallet_address: string | null; }; export type SessionInfo = { @@ -31,7 +9,6 @@ export type SessionInfo = { modal_name: string; archive_at: string | null; can_execute: boolean; - execute_config: ExecuteConfig | null; created_at: string; deleted_at: string | null; history: Array<{ @@ -43,7 +20,7 @@ export type SessionInfo = { archived_at: string | null; title: string | null; is_public: boolean | null; - context_filter: SessionContextFilter | null; + context: SessionContextFilter | null; // memory // action: array | null; <-- type of this is not available on https://nebula-api.thirdweb-dev.com/docs#/default/get_session_session__session_id__get }; @@ -52,8 +29,7 @@ export type UpdatedSessionInfo = { title: string; modal_name: string; account_id: string; - execute_config: ExecuteConfig | null; - context_filter: SessionContextFilter | null; + context: SessionContextFilter | null; }; export type DeletedSessionInfo = { diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx index 04ebb5570aa..35689a06c91 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx @@ -12,11 +12,11 @@ import { useThirdwebClient } from "@/constants/thirdweb.client"; import type { Account } from "@3rdweb-sdk/react/hooks/useApi"; import { ArrowRightIcon } from "lucide-react"; import Link from "next/link"; -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { useActiveAccount, useActiveWalletChain } from "thirdweb/react"; -import { type ContextFilters, promptNebula } from "../api/chat"; +import { type NebulaContext, promptNebula } from "../api/chat"; import { createSession, updateSession } from "../api/session"; -import type { ExecuteConfig, SessionInfo } from "../api/types"; +import type { SessionInfo } from "../api/types"; import { newChatPageUrlStore, newSessionsStore } from "../stores"; import { ChatBar } from "./ChatBar"; import { type ChatMessage, Chats } from "./Chats"; @@ -81,27 +81,26 @@ export function ChatPageContent(props: { useState(false); const [contextFilters, _setContextFilters] = useState< - ContextFilters | undefined + NebulaContext | undefined >(() => { - const contextFilterRes = props.session?.context_filter; - const value: ContextFilters = { - chainIds: contextFilterRes?.chain_ids || undefined, - contractAddresses: contextFilterRes?.contract_addresses || undefined, - walletAddresses: contextFilterRes?.wallet_addresses || undefined, + const contextRes = props.session?.context; + const value: NebulaContext = { + chainIds: contextRes?.chain_ids || null, + walletAddress: contextRes?.wallet_address || null, }; return value; }); - const setContextFilters = useCallback((v: ContextFilters | undefined) => { + const setContextFilters = useCallback((v: NebulaContext | undefined) => { _setContextFilters(v); setHasUserUpdatedContextFilters(true); }, []); const isNewSession = !props.session; - // if this is a new session, user has not manually updated context filters - // update the context filters to the current user's wallet address and chain id + // if this is a new session, user has not manually updated context + // update the context to the current user's wallet address and chain id // eslint-disable-next-line no-restricted-syntax useEffect(() => { if (!isNewSession || hasUserUpdatedContextFilters) { @@ -109,11 +108,16 @@ export function ChatPageContent(props: { } _setContextFilters((_contextFilters) => { - const updatedContextFilters: ContextFilters = _contextFilters - ? { ..._contextFilters } - : {}; + const updatedContextFilters: NebulaContext = _contextFilters + ? { + ..._contextFilters, + } + : { + chainIds: [], + walletAddress: null, + }; - updatedContextFilters.walletAddresses = address ? [address] : []; + updatedContextFilters.walletAddress = address || null; updatedContextFilters.chainIds = activeChain ? [activeChain.id.toString()] : []; @@ -122,15 +126,6 @@ export function ChatPageContent(props: { }); }, [address, isNewSession, hasUserUpdatedContextFilters, activeChain]); - const config: ExecuteConfig | null = useMemo(() => { - return address - ? { - mode: "client", - signer_wallet_address: address, - } - : null; - }, [address]); - const [sessionId, _setSessionId] = useState( props.session?.id, ); @@ -163,12 +158,11 @@ export function ChatPageContent(props: { const initSession = useCallback(async () => { const session = await createSession({ authToken: props.authToken, - config, - contextFilters, + context: contextFilters, }); setSessionId(session.id); return session; - }, [config, contextFilters, props.authToken, setSessionId]); + }, [contextFilters, props.authToken, setSessionId]); const handleSendMessage = useCallback( async (message: string) => { @@ -221,7 +215,6 @@ export function ChatPageContent(props: { abortController, message: message, sessionId: currentSessionId, - config: config, authToken: props.authToken, handleStream(res) { if (abortController.signal.aborted) { @@ -308,7 +301,7 @@ export function ChatPageContent(props: { } } }, - contextFilters: contextFilters, + context: contextFilters, }); } catch (error) { if (abortController.signal.aborted) { @@ -338,7 +331,6 @@ export function ChatPageContent(props: { [ sessionId, contextFilters, - config, props.authToken, messages.length, initSession, @@ -363,13 +355,12 @@ export function ChatPageContent(props: { const showEmptyState = !userHasSubmittedMessage && messages.length === 0; const handleUpdateContextFilters = async ( - values: ContextFilters | undefined, + values: NebulaContext | undefined, ) => { - // if session is not yet created, don't need to update sessions - starting a chat will create a session with the context filters + // if session is not yet created, don't need to update sessions - starting a chat will create a session with the context if (sessionId) { await updateSession({ authToken: props.authToken, - config, sessionId, contextFilters: values, }); diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.stories.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.stories.tsx index f14a055342a..761366e5e51 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.stories.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.stories.tsx @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { useState } from "react"; import { Toaster } from "sonner"; import { BadgeContainer, mobileViewport } from "../../../../stories/utils"; -import type { ContextFilters } from "../api/chat"; +import type { NebulaContext } from "../api/chat"; import ContextFiltersButton from "./ContextFilters"; const meta = { @@ -37,6 +37,7 @@ function Story() { @@ -44,57 +45,25 @@ function Story() { - - - - - - @@ -103,10 +72,10 @@ function Story() { function Variant(props: { label: string; - contextFilters: ContextFilters | undefined; + contextFilters: NebulaContext | undefined; }) { const [contextFilters, setContextFilters] = useState< - ContextFilters | undefined + NebulaContext | undefined >(props.contextFilters); return ( @@ -114,7 +83,7 @@ function Variant(props: { contextFilters={contextFilters} setContextFilters={setContextFilters} updateContextFilters={async (values) => { - console.log("Updating context filters", values); + console.log("Updating context", values); await new Promise((resolve) => setTimeout(resolve, 1000)); }} /> diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx index e3d37897eab..6f7827c1f4b 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx @@ -21,7 +21,7 @@ import { FormLabel, FormMessage, } from "@/components/ui/form"; -import { AutoResizeTextarea } from "@/components/ui/textarea"; +import { Input } from "@/components/ui/input"; import { cn } from "@/lib/utils"; import { zodResolver } from "@hookform/resolvers/zod"; import { useMutation } from "@tanstack/react-query"; @@ -31,52 +31,34 @@ import { useForm } from "react-hook-form"; import { toast } from "sonner"; import { isAddress } from "thirdweb"; import { z } from "zod"; -import type { ContextFilters } from "../api/chat"; +import type { NebulaContext } from "../api/chat"; export default function ContextFiltersButton(props: { - contextFilters: ContextFilters | undefined; - setContextFilters: (filters: ContextFilters | undefined) => void; - updateContextFilters: (filters: ContextFilters | undefined) => Promise; + contextFilters: NebulaContext | undefined; + setContextFilters: (filters: NebulaContext | undefined) => void; + updateContextFilters: (filters: NebulaContext | undefined) => Promise; }) { const [isOpen, setIsOpen] = useState(false); const chainIds = props.contextFilters?.chainIds; - const contractAddresses = props.contextFilters?.contractAddresses; - const walletAddresses = props.contextFilters?.walletAddresses; + const walletAddress = props.contextFilters?.walletAddress; return (