diff --git a/agent/src/index.ts b/agent/src/index.ts index 10386e1b1f1..d02bc2f8c78 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -573,6 +573,11 @@ const startAgents = async () => { } catch (error) { elizaLogger.error("Error starting agents:", error); } + // upload some agent functionality into directClient + directClient.startAgent = async character => { + // wrap it so we don't have to inject directClient later + return startAgent(character, directClient) + }; function chat() { const agentId = characters[0].name ?? "Agent"; diff --git a/packages/client-direct/src/api.ts b/packages/client-direct/src/api.ts index 3b3394dd210..fe26cee8f3c 100644 --- a/packages/client-direct/src/api.ts +++ b/packages/client-direct/src/api.ts @@ -2,17 +2,25 @@ import express from "express"; import bodyParser from "body-parser"; import cors from "cors"; -import { AgentRuntime } from "@ai16z/eliza"; +import { + AgentRuntime, + elizaLogger, + validateCharacterConfig, +} from "@ai16z/eliza"; import { REST, Routes } from "discord.js"; -export function createApiRouter(agents: Map) { +export function createApiRouter(agents: Map, directClient) { const router = express.Router(); router.use(cors()); router.use(bodyParser.json()); router.use(bodyParser.urlencoded({ extended: true })); + router.get("/", (req, res) => { + res.send("Welcome, this is the REST API!"); + }); + router.get("/hello", (req, res) => { res.json({ message: "Hello World!" }); }); @@ -21,6 +29,7 @@ export function createApiRouter(agents: Map) { const agentsList = Array.from(agents.values()).map((agent) => ({ id: agent.agentId, name: agent.character.name, + clients: Object.keys(agent.clients), })); res.json({ agents: agentsList }); }); @@ -40,6 +49,43 @@ export function createApiRouter(agents: Map) { }); }); + router.post("/agents/:agentId/set", async (req, res) => { + const agentId = req.params.agentId; + console.log('agentId', agentId) + let agent:AgentRuntime = agents.get(agentId); + + // update character + if (agent) { + // stop agent + agent.stop() + directClient.unregisterAgent(agent) + // if it has a different name, the agentId will change + } + + // load character from body + const character = req.body + try { + validateCharacterConfig(character) + } catch(e) { + elizaLogger.error(`Error parsing character: ${e}`); + res.status(400).json({ + success: false, + message: e.message, + }); + return; + } + + // start it up (and register it) + agent = await directClient.startAgent(character) + elizaLogger.log(`${character.name} started`) + + res.json({ + id: character.id, + character: character, + }); + }); + + router.get("/agents/:agentId/channels", async (req, res) => { const agentId = req.params.agentId; const runtime = agents.get(agentId); diff --git a/packages/client-direct/src/index.ts b/packages/client-direct/src/index.ts index 08f75f595ba..1ec4275b89b 100644 --- a/packages/client-direct/src/index.ts +++ b/packages/client-direct/src/index.ts @@ -51,17 +51,11 @@ Note that {{agentName}} is capable of reading/seeing/hearing various forms of me # Instructions: Write the next message for {{agentName}}. ` + messageCompletionFooter; -export interface SimliClientConfig { - apiKey: string; - faceID: string; - handleSilence: boolean; - videoRef: any; - audioRef: any; -} export class DirectClient { public app: express.Application; - private agents: Map; + private agents: Map; // container management private server: any; // Store server instance + public startAgent: Function; // Store startAgent functor constructor() { elizaLogger.log("DirectClient constructor"); @@ -72,7 +66,7 @@ export class DirectClient { this.app.use(bodyParser.json()); this.app.use(bodyParser.urlencoded({ extended: true })); - const apiRouter = createApiRouter(this.agents); + const apiRouter = createApiRouter(this.agents, this); this.app.use(apiRouter); // Define an interface that extends the Express Request interface @@ -338,7 +332,7 @@ export class DirectClient { fileResponse.headers .get("content-disposition") ?.split("filename=")[1] - ?.replace(/"/g, "") || "default_name.txt"; + ?.replace(/"/g, /* " */ "") || "default_name.txt"; console.log("Saving as:", fileName); @@ -378,6 +372,7 @@ export class DirectClient { ); } + // agent/src/index.ts:startAgent calls this public registerAgent(runtime: AgentRuntime) { this.agents.set(runtime.agentId, runtime); } @@ -388,7 +383,7 @@ export class DirectClient { public start(port: number) { this.server = this.app.listen(port, () => { - elizaLogger.success(`Server running at http://localhost:${port}/`); + elizaLogger.success(`REST API bound to 0.0.0.0:${port}. If running locally, access it at http://localhost:${port}.`); }); // Handle graceful shutdown @@ -430,7 +425,7 @@ export const DirectClientInterface: Client = { client.start(serverPort); return client; }, - stop: async (_runtime: IAgentRuntime, client?: any) => { + stop: async (_runtime: IAgentRuntime, client?: Client) => { if (client instanceof DirectClient) { client.stop(); }