Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
10 changes: 8 additions & 2 deletions src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface ApiConfig {
url: string;
localAgentUrl?: string;
serverPort: number;
network: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be an enum? "mainnet" | "testnet"?

}

interface ValidationResult {
Expand All @@ -41,6 +42,7 @@ const API_CONFIG: ApiConfig = {
process.env.BITTE_API_URL ||
"https://ai-runtime-446257178793.europe-west1.run.app",
serverPort: DEFAULT_PORT,
network: "mainnet",
};

async function fetchAndValidateSpec(url: string): Promise<ValidationResult> {
Expand All @@ -63,7 +65,7 @@ async function fetchAndValidateSpec(url: string): Promise<ValidationResult> {
} catch (error) {
console.error(
"Failed to validate OpenAPI spec:",
error instanceof Error ? error.message : "Unknown error",
error instanceof Error ? error.message : "Unknown error"
);
isValid = false;
accountId = undefined;
Expand Down Expand Up @@ -120,10 +122,14 @@ export const devCommand = new Command()
.option("-t, --testnet", "Use Testnet instead of Mainnet", false)
.action(async (options) => {
try {
// Set the network environment variable
process.env.NEXT_PUBLIC_NETWORK = options.testnet ? "testnet" : "mainnet";

const { port, serverPort } = await setupPorts(options);

API_CONFIG.serverPort = serverPort;
API_CONFIG.localAgentUrl = `http://localhost:${port}`;
API_CONFIG.network = options.testnet ? "testnet" : "mainnet";

const deployedUrl = getDeployedUrl(port);
if (!deployedUrl) {
Expand All @@ -134,7 +140,7 @@ export const devCommand = new Command()
try {
console.log(
"[Dev] Fetching and validating OpenAPI spec from:",
deployedUrl,
deployedUrl
);
const { spec } = await fetchAndValidateSpec(deployedUrl);
console.log("[Dev] OpenAPI spec validation successful");
Expand Down
69 changes: 21 additions & 48 deletions src/playground/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
"use client";

import { BitteAiChat, type BitteOpenAPISpec } from "@bitte-ai/chat";
import "@bitte-ai/chat/style.css";
import { type Wallet, useBitteWallet } from "@bitte-ai/react";
import { type BitteOpenAPISpec } from "@bitte-ai/chat";
import { BitteWalletContextProvider } from "@bitte-ai/react";
import { useEffect, useState } from "react";
import { useAccount, useSendTransaction, useSwitchChain } from "wagmi";

import { Header } from "./components/Header";
import { ChatContent } from "./components/ChatContent";
import "./shims";

type AppConfig = {
Expand All @@ -19,16 +18,15 @@ type AppConfig = {
environment: string;
bitteApiKey: string;
bitteApiUrl: string;
network: string;
};

// Main App component that fetches config and sets up the wallet provider
const Main: React.FC = (): JSX.Element => {
const { selector } = useBitteWallet();
const [wallet, setWallet] = useState<Wallet>();
const [config, setConfig] = useState<AppConfig>();

const { address } = useAccount();
const { data: hash, sendTransaction } = useSendTransaction();
const { switchChain } = useSwitchChain();
const { switchChainAsync } = useSwitchChain();

useEffect(() => {
const fetchConfig = async (): Promise<void> => {
Expand All @@ -43,51 +41,26 @@ const Main: React.FC = (): JSX.Element => {
fetchConfig();
}, []);

useEffect(() => {
const fetchWallet = async (): Promise<void> => {
const walletInstance = await selector.wallet();
setWallet(walletInstance);
};
if (selector) fetchWallet();
}, [selector]);

if (!config) {
return <div>Loading...</div>;
}

const BitteWalletSetup = {
network: config.network,
callbackUrl: typeof window !== "undefined" ? window.location.origin : "",
contractAddress: "",
};

return (
<main>
<Header />
<div id="ai-chat">
<BitteAiChat
options={{
agentImage: "/bitte.svg",
agentName: config.localAgent.spec["x-mb"]?.assistant?.name,
localAgent: config.localAgent,
}}
agentId={config.localAgent.pluginId}
wallet={{
near: { wallet },
evm: {
sendTransaction,
switchChain,
address,
hash,
},
}}
apiUrl={config.bitteApiUrl}
historyApiUrl="/api/history"
apiKey={config.bitteApiKey}
colors={{
generalBackground: "#18181A",
messageBackground: "#0A0A0A",
textColor: "#FAFAFA",
buttonColor: "#000000",
borderColor: "#334155",
}}
/>
</div>
</main>
<BitteWalletContextProvider {...BitteWalletSetup}>
<ChatContent
config={config}
address={address}
sendTransaction={sendTransaction}
switchChain={switchChainAsync}
hash={hash}
/>
</BitteWalletContextProvider>
);
};

Expand Down
76 changes: 76 additions & 0 deletions src/playground/src/components/ChatContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { BitteAiChat, type BitteOpenAPISpec } from "@bitte-ai/chat";
import "@bitte-ai/chat/style.css";
import { type Wallet } from "@bitte-ai/react";
import React from "react";

import { Header } from "./Header";
import { UseSendTransactionReturnType, UseSwitchChainReturnType } from "wagmi";

type AppConfig = {
localAgent: {
pluginId: string;
accountId: string;
spec: BitteOpenAPISpec;
};
serverStartTime: string;
environment: string;
bitteApiKey: string;
bitteApiUrl: string;
network: string;
};

interface ChatContentProps {
config: AppConfig;
wallet?: Wallet;
address?: string;
sendTransaction?: UseSendTransactionReturnType["sendTransaction"];
switchChain?: UseSwitchChainReturnType["switchChain"];
hash?: string;
}

export const ChatContent: React.FC<ChatContentProps> = ({
config,
wallet,
address,
sendTransaction,
switchChain,
hash,
}) => {
return (
<main>
<Header />
<div id="ai-chat">
<BitteAiChat
options={{
agentImage: "/bitte.svg",
agentName: config.localAgent.spec["x-mb"]?.assistant?.name,
localAgent: config.localAgent,
}}
agentId={config.localAgent.pluginId}
wallet={{
near: { wallet },
evm:
address && sendTransaction && switchChain
? {
address,
sendTransaction,
switchChain,
hash,
}
: undefined,
}}
apiUrl={config.bitteApiUrl}
historyApiUrl="/api/history"
apiKey={config.bitteApiKey}
colors={{
generalBackground: "#18181A",
messageBackground: "#0A0A0A",
textColor: "#FAFAFA",
buttonColor: "#000000",
borderColor: "#334155",
}}
/>
</div>
</main>
);
};
15 changes: 3 additions & 12 deletions src/playground/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { BitteWalletContextProvider } from "@bitte-ai/react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

Expand All @@ -7,18 +6,10 @@ import App from "./App.tsx";
import ContextProvider from "./context/index.tsx";
import "./index.css";

const BitteWalletSetup = {
network: "mainnet",
callbackUrl: typeof window !== "undefined" ? window.location.origin : "",
contractAddress: "",
};

createRoot(document.getElementById("root")!).render(
<StrictMode>
<BitteWalletContextProvider {...BitteWalletSetup}>
<ContextProvider>
<App />
</ContextProvider>
</BitteWalletContextProvider>
<ContextProvider>
<App />
</ContextProvider>
</StrictMode>
);
11 changes: 6 additions & 5 deletions src/services/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { type ApiConfig } from "../commands/dev";

export async function startUIServer(
apiConfig: ApiConfig,
agentSpec: unknown,
agentSpec: unknown
): Promise<ReturnType<typeof express.application.listen>> {
const app = express();

app.use(
express.json({
limit: "2mb",
}),
})
);

// Try multiple possible paths for the static files
Expand All @@ -26,7 +26,7 @@ export async function startUIServer(
"node_modules",
"make-agent",
"dist",
"playground",
"playground"
),
// When running from the node_modules/.bin directory
path.resolve(process.cwd(), "..", "make-agent", "dist", "playground"),
Expand Down Expand Up @@ -64,7 +64,7 @@ export async function startUIServer(
res.setHeader("Content-Type", "text/css");
}
},
}),
})
);

// Serve config endpoint
Expand All @@ -80,6 +80,7 @@ export async function startUIServer(
},
bitteApiKey: apiConfig.key,
bitteApiUrl: `${apiConfig.url}/chat`,
network: apiConfig.network,
};
res.json(serverConfig);
} catch (error) {
Expand Down Expand Up @@ -125,7 +126,7 @@ export async function startUIServer(
try {
const server = app.listen(apiConfig.serverPort, () => {
console.log(
`[Server] UI server listening http://localhost:${apiConfig.serverPort}`,
`[Server] UI server listening http://localhost:${apiConfig.serverPort}`
);
console.log("[Server] Ready to handle requests");
resolve(server);
Expand Down
Loading