// src/eliza-agent.ts
import {
AbstractAgent,
RunAgent,
RunAgentInput,
EventType,
BaseEvent,
RunStartedEventSchema,
TextMessageStartEventSchema,
TextMessageContentEventSchema,
TextMessageEndEventSchema,
RunFinishedEventSchema,
} from "@ag-ui/client"
import { Observable } from "rxjs"
import * as telnetlib from "telnetlib"
export class ElizaAgent extends AbstractAgent {
protected run(input: RunAgentInput): RunAgent {
// AG-UI calls `run` each time it wants to generate a response.
return () => {
// Extract user's latest message
const lastUserMessage =
[...input.messages].reverse().find((msg) => msg.role === "user")
?.content || "Hello, Eliza"
return new Observable<BaseEvent>((observer) => {
// 1) Emit RUN_STARTED
observer.next(
RunStartedEventSchema.parse({
type: EventType.RUN_STARTED,
threadId: input.threadId,
runId: input.runId,
})
)
// Create a new telnet client
const client = telnetlib.createConnection(
{
host: "127.0.0.1",
port: 2323,
},
() => {
console.log("Connected to Eliza telnet server")
}
)
// Wait for initial greeting and prompt
client.once("data", () => {
// Once we receive the greeting, send the user message
client.write(lastUserMessage + "\n")
// Wait for the response from Eliza
client.once("data", (data) => {
// Get the response, removing the prompt
let response = data.toString().trim()
// Strip the trailing prompt if present
if (response.endsWith(">")) {
response = response.substring(0, response.length - 1).trim()
}
// Generate a message ID
const messageId = Date.now().toString()
// Emit typical AG-UI message events
observer.next(
TextMessageStartEventSchema.parse({
type: EventType.TEXT_MESSAGE_START,
messageId,
})
)
observer.next(
TextMessageContentEventSchema.parse({
type: EventType.TEXT_MESSAGE_CONTENT,
messageId,
delta: response,
})
)
observer.next(
TextMessageEndEventSchema.parse({
type: EventType.TEXT_MESSAGE_END,
messageId,
})
)
// Emit RUN_FINISHED and complete
observer.next(
RunFinishedEventSchema.parse({
type: EventType.RUN_FINISHED,
threadId: input.threadId,
runId: input.runId,
})
)
// Close the telnet connection
client.end()
observer.complete()
})
})
// Handle errors
client.on("error", (err) => {
console.error("Telnet client error:", err)
observer.error(err)
})
// Return a cleanup function
return () => {
if (client) {
client.end()
}
}
})
}
}
}