UNPKG

@agentx-ai/agentx-js

Version:

Official JavaScript/TypeScript SDK for AgentX (https://www.agentx.so/)

233 lines (209 loc) 6.53 kB
import axios, { AxiosResponse } from "axios"; import { getHeaders } from "../util"; export interface ChatResponse { text: string | null; cot: string | null; botId: string; reference?: any; tasks?: any; } export interface Message { id: string; conversationId: string; role: "user" | "bot"; botId?: string; userId?: string; text: string | null; cot: string | null; createdAt: string; updatedAt: string; } export interface ConversationData { agent_id: string; id: string; title?: string; users: string[]; agents: string[]; createdAt?: string; updatedAt?: string; } export interface ContextMessage { user?: string; assistant?: string; } export class Conversation { public agent_id: string; public id: string; public title?: string; public users: string[]; public agents: string[]; public createdAt?: string; public updatedAt?: string; constructor(data: ConversationData) { this.agent_id = data.agent_id; this.id = data.id; this.title = data.title; this.users = data.users; this.agents = data.agents; this.createdAt = data.createdAt; this.updatedAt = data.updatedAt; } async listMessages(): Promise<Message[]> { const url = `https://api.agentx.so/api/v1/access/agents/${this.agent_id}/conversations/${this.id}`; const response: AxiosResponse = await axios.get(url, { headers: getHeaders(), }); if (response.status === 200) { const res = response.data; if (res.messages) { const messageList: Message[] = []; for (const message of res.messages) { if (message.bot) { message.role = "bot"; } else { message.role = "user"; } messageList.push(message); } return messageList; } else { throw new Error("No messages found in the conversation."); } } else { throw new Error( `Failed to retrieve agent details: ${response.status} - ${response.statusText}` ); } } async chat(message: string, context?: number): Promise<any> { const url = `https://api.agentx.so/api/v1/access/conversations/${this.id}/message`; const response: AxiosResponse = await axios.post( url, { message, context }, { headers: getHeaders() } ); return response.data; } async updateContext(messages: ContextMessage[]): Promise<void> { const url = `https://api.agentx.so/api/v1/access/conversations/${this.id}/update-context`; const response: AxiosResponse = await axios.put( url, { messages }, { headers: getHeaders() } ); if (response.status !== 200) { throw new Error( `Failed to update conversation context: ${response.status} - ${response.statusText}` ); } } async updateUserContext(message: string): Promise<void> { const url = `https://api.agentx.so/api/v1/access/conversations/${this.id}/update-user-context`; const response: AxiosResponse = await axios.put( url, { message }, { headers: getHeaders() } ); if (response.status !== 200) { throw new Error( `Failed to update user context: ${response.status} - ${response.statusText}` ); } } async *chatStream( message: string, context?: number ): AsyncGenerator<ChatResponse> { const url = `https://api.agentx.so/api/v1/access/conversations/${this.id}/jsonmessagesse`; const response: AxiosResponse = await axios.post( url, { message, context }, { headers: { ...getHeaders(), accept: "text/event-stream", }, responseType: "stream", } ); if (response.status === 200) { let buffer = ""; const stream = response.data; for await (const chunk of stream) { const chunkStr = chunk.toString(); buffer += chunkStr; // Process complete JSON objects from the buffer let braceCount = 0; let startIndex = -1; let processedLength = 0; for (let i = 0; i < buffer.length; i++) { if (buffer[i] === "{") { if (braceCount === 0) { startIndex = i; } braceCount++; } else if (buffer[i] === "}") { braceCount--; if (braceCount === 0 && startIndex !== -1) { // We have a complete JSON object const jsonStr = buffer.substring(startIndex, i + 1); try { const parsedJson = JSON.parse(jsonStr); // Only yield if this is a meaningful response (has text, cot, or other relevant data) if ( parsedJson.text !== undefined || parsedJson.cot !== undefined || parsedJson.tasks !== undefined ) { yield { text: parsedJson.text || null, cot: parsedJson.cot || null, botId: parsedJson.botId, reference: parsedJson.reference, tasks: parsedJson.tasks, }; } // Track the processed length processedLength = i + 1; startIndex = -1; } catch (jsonError) { // If JSON parsing fails, continue looking for valid JSON continue; } } } } // Remove processed JSON from buffer if (processedLength > 0) { buffer = buffer.substring(processedLength); } } // Handle any remaining data in buffer if (buffer.trim()) { try { const remainingJson = JSON.parse(buffer.trim()); if ( remainingJson.text !== undefined || remainingJson.cot !== undefined || remainingJson.tasks !== undefined ) { yield { text: remainingJson.text || null, cot: remainingJson.cot || null, botId: remainingJson.botId, reference: remainingJson.reference, tasks: remainingJson.tasks, }; } } catch (jsonError) { // If final parsing fails, ignore the remaining buffer console.warn("Failed to parse remaining buffer:", buffer); } } } else { throw new Error( `Failed to send message: ${response.status} - ${response.statusText}` ); } } }