@restnfeel/agentc-starter-kit
Version:
한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템
186 lines (184 loc) • 6.58 kB
JavaScript
class ChatbotAPIError extends Error {
constructor(message, status, code) {
super(message);
this.status = status;
this.code = code;
this.name = "ChatbotAPIError";
}
}
class ChatbotAPI {
constructor(baseUrl = "/api/chatbot", apiKey) {
this.baseUrl = baseUrl;
this.apiKey = apiKey;
this.sessionId = this.generateSessionId();
}
generateSessionId() {
return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
async makeRequest(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const headers = {
"Content-Type": "application/json",
...options.headers,
};
if (this.apiKey) {
headers["Authorization"] = `Bearer ${this.apiKey}`;
}
try {
const response = await fetch(url, {
...options,
headers,
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new ChatbotAPIError(errorData.message ||
`HTTP ${response.status}: ${response.statusText}`, response.status, errorData.code);
}
return await response.json();
}
catch (error) {
if (error instanceof ChatbotAPIError) {
throw error;
}
if (error instanceof TypeError && error.message.includes("fetch")) {
throw new ChatbotAPIError("네트워크 연결을 확인해주세요", 0, "NETWORK_ERROR");
}
throw new ChatbotAPIError("API 요청 중 오류가 발생했습니다", 0, "UNKNOWN_ERROR");
}
}
async sendMessage(request) {
const response = await this.makeRequest("/chat", {
method: "POST",
body: JSON.stringify({
...request,
sessionId: request.sessionId || this.sessionId,
}),
});
return {
...response,
timestamp: new Date(response.timestamp),
};
}
async *streamMessage(request) {
var _a;
const url = `${this.baseUrl}/chat/stream`;
const headers = {
"Content-Type": "application/json",
Accept: "text/event-stream",
};
if (this.apiKey) {
headers["Authorization"] = `Bearer ${this.apiKey}`;
}
try {
const response = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify({
...request,
sessionId: request.sessionId || this.sessionId,
}),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new ChatbotAPIError(errorData.message ||
`HTTP ${response.status}: ${response.statusText}`, response.status, errorData.code);
}
const reader = (_a = response.body) === null || _a === void 0 ? void 0 : _a.getReader();
if (!reader) {
throw new ChatbotAPIError("스트림을 읽을 수 없습니다", 0, "STREAM_ERROR");
}
const decoder = new TextDecoder();
let buffer = "";
try {
while (true) {
const { done, value } = await reader.read();
if (done)
break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() || "";
for (const line of lines) {
if (line.startsWith("data: ")) {
const data = line.slice(6);
if (data === "[DONE]") {
return;
}
try {
const parsed = JSON.parse(data);
yield {
...parsed,
timestamp: new Date(parsed.timestamp),
};
}
catch (parseError) {
console.warn("Failed to parse streaming response:", parseError);
}
}
}
}
}
finally {
reader.releaseLock();
}
}
catch (error) {
if (error instanceof ChatbotAPIError) {
throw error;
}
throw new ChatbotAPIError("스트리밍 중 오류가 발생했습니다", 0, "STREAM_ERROR");
}
}
async getSessionHistory(sessionId) {
const id = sessionId || this.sessionId;
const response = await this.makeRequest(`/sessions/${id}/history`);
return response.messages.map((msg) => ({
...msg,
timestamp: new Date(msg.timestamp),
}));
}
async clearSession(sessionId) {
const id = sessionId || this.sessionId;
await this.makeRequest(`/sessions/${id}`, {
method: "DELETE",
});
}
getSessionId() {
return this.sessionId;
}
setSessionId(sessionId) {
this.sessionId = sessionId;
}
// Health check for the API
async healthCheck() {
const response = await this.makeRequest("/health");
return {
...response,
timestamp: new Date(response.timestamp),
};
}
}
// Retry mechanism for failed requests
async function withRetry(operation, maxRetries = 3, delay = 1000) {
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
}
catch (error) {
lastError = error;
// Don't retry on client errors (4xx)
if (error instanceof ChatbotAPIError &&
error.status &&
error.status >= 400 &&
error.status < 500) {
throw error;
}
if (attempt < maxRetries) {
await new Promise((resolve) => setTimeout(resolve, delay * attempt));
}
}
}
throw lastError;
}
export { ChatbotAPI, ChatbotAPIError, withRetry };
//# sourceMappingURL=chatbot-api.js.map