Skip to content

Commit 747b5c2

Browse files
authored
Merge pull request #1052 from odilitime/rest-upgrade
feat: add/change change through REST api (client-direct)
2 parents 153d242 + b511c0e commit 747b5c2

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

agent/src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,11 @@ const startAgents = async () => {
578578
} catch (error) {
579579
elizaLogger.error("Error starting agents:", error);
580580
}
581+
// upload some agent functionality into directClient
582+
directClient.startAgent = async character => {
583+
// wrap it so we don't have to inject directClient later
584+
return startAgent(character, directClient)
585+
};
581586

582587
function chat() {
583588
const agentId = characters[0].name ?? "Agent";

packages/client-direct/src/api.ts

+48-2
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,25 @@ import express from "express";
22
import bodyParser from "body-parser";
33
import cors from "cors";
44

5-
import { AgentRuntime } from "@ai16z/eliza";
5+
import {
6+
AgentRuntime,
7+
elizaLogger,
8+
validateCharacterConfig,
9+
} from "@ai16z/eliza";
610

711
import { REST, Routes } from "discord.js";
812

9-
export function createApiRouter(agents: Map<string, AgentRuntime>) {
13+
export function createApiRouter(agents: Map<string, AgentRuntime>, directClient) {
1014
const router = express.Router();
1115

1216
router.use(cors());
1317
router.use(bodyParser.json());
1418
router.use(bodyParser.urlencoded({ extended: true }));
1519

20+
router.get("/", (req, res) => {
21+
res.send("Welcome, this is the REST API!");
22+
});
23+
1624
router.get("/hello", (req, res) => {
1725
res.json({ message: "Hello World!" });
1826
});
@@ -21,6 +29,7 @@ export function createApiRouter(agents: Map<string, AgentRuntime>) {
2129
const agentsList = Array.from(agents.values()).map((agent) => ({
2230
id: agent.agentId,
2331
name: agent.character.name,
32+
clients: Object.keys(agent.clients),
2433
}));
2534
res.json({ agents: agentsList });
2635
});
@@ -40,6 +49,43 @@ export function createApiRouter(agents: Map<string, AgentRuntime>) {
4049
});
4150
});
4251

52+
router.post("/agents/:agentId/set", async (req, res) => {
53+
const agentId = req.params.agentId;
54+
console.log('agentId', agentId)
55+
let agent:AgentRuntime = agents.get(agentId);
56+
57+
// update character
58+
if (agent) {
59+
// stop agent
60+
agent.stop()
61+
directClient.unregisterAgent(agent)
62+
// if it has a different name, the agentId will change
63+
}
64+
65+
// load character from body
66+
const character = req.body
67+
try {
68+
validateCharacterConfig(character)
69+
} catch(e) {
70+
elizaLogger.error(`Error parsing character: ${e}`);
71+
res.status(400).json({
72+
success: false,
73+
message: e.message,
74+
});
75+
return;
76+
}
77+
78+
// start it up (and register it)
79+
agent = await directClient.startAgent(character)
80+
elizaLogger.log(`${character.name} started`)
81+
82+
res.json({
83+
id: character.id,
84+
character: character,
85+
});
86+
});
87+
88+
4389
router.get("/agents/:agentId/channels", async (req, res) => {
4490
const agentId = req.params.agentId;
4591
const runtime = agents.get(agentId);

packages/client-direct/src/index.ts

+7-12
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,11 @@ Note that {{agentName}} is capable of reading/seeing/hearing various forms of me
5151
# Instructions: Write the next message for {{agentName}}.
5252
` + messageCompletionFooter;
5353

54-
export interface SimliClientConfig {
55-
apiKey: string;
56-
faceID: string;
57-
handleSilence: boolean;
58-
videoRef: any;
59-
audioRef: any;
60-
}
6154
export class DirectClient {
6255
public app: express.Application;
63-
private agents: Map<string, AgentRuntime>;
56+
private agents: Map<string, AgentRuntime>; // container management
6457
private server: any; // Store server instance
58+
public startAgent: Function; // Store startAgent functor
6559

6660
constructor() {
6761
elizaLogger.log("DirectClient constructor");
@@ -72,7 +66,7 @@ export class DirectClient {
7266
this.app.use(bodyParser.json());
7367
this.app.use(bodyParser.urlencoded({ extended: true }));
7468

75-
const apiRouter = createApiRouter(this.agents);
69+
const apiRouter = createApiRouter(this.agents, this);
7670
this.app.use(apiRouter);
7771

7872
// Define an interface that extends the Express Request interface
@@ -338,7 +332,7 @@ export class DirectClient {
338332
fileResponse.headers
339333
.get("content-disposition")
340334
?.split("filename=")[1]
341-
?.replace(/"/g, "") || "default_name.txt";
335+
?.replace(/"/g, /* " */ "") || "default_name.txt";
342336

343337
console.log("Saving as:", fileName);
344338

@@ -378,6 +372,7 @@ export class DirectClient {
378372
);
379373
}
380374

375+
// agent/src/index.ts:startAgent calls this
381376
public registerAgent(runtime: AgentRuntime) {
382377
this.agents.set(runtime.agentId, runtime);
383378
}
@@ -388,7 +383,7 @@ export class DirectClient {
388383

389384
public start(port: number) {
390385
this.server = this.app.listen(port, () => {
391-
elizaLogger.success(`Server running at http://localhost:${port}/`);
386+
elizaLogger.success(`REST API bound to 0.0.0.0:${port}. If running locally, access it at http://localhost:${port}.`);
392387
});
393388

394389
// Handle graceful shutdown
@@ -430,7 +425,7 @@ export const DirectClientInterface: Client = {
430425
client.start(serverPort);
431426
return client;
432427
},
433-
stop: async (_runtime: IAgentRuntime, client?: any) => {
428+
stop: async (_runtime: IAgentRuntime, client?: Client) => {
434429
if (client instanceof DirectClient) {
435430
client.stop();
436431
}

0 commit comments

Comments
 (0)