UNPKG

recallrai

Version:

Official Node.js SDK for RecallrAI - Revolutionary contextual memory system that enables AI assistants to form meaningful connections between conversations, just like human memory.

171 lines (170 loc) 8.13 kB
"use strict"; /** * Merge conflict management functionality for the RecallrAI SDK. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.MergeConflict = void 0; const models_1 = require("./models"); const errors_1 = require("./errors"); /** * Represents a merge conflict in the RecallrAI system. * * This class provides methods for inspecting and resolving merge conflicts * that occur when new memories conflict with existing ones. */ class MergeConflict { /** * Initialize a merge conflict. * * @param httpClient - HTTP client for API communication. * @param userId - User ID who owns this conflict. * @param conflictData - Merge conflict data model. */ constructor(httpClient, userId, conflictData) { this.http = httpClient; this.userId = userId; this.conflictData = conflictData; this.conflictId = conflictData.id; this.status = conflictData.status; this.proposedMemoryContent = conflictData.proposedMemoryContent; this.newMemories = conflictData.newMemories; this.conflictingMemories = conflictData.conflictingMemories; this.clarifyingQuestions = conflictData.clarifyingQuestions; this.createdAt = conflictData.createdAt; this.resolvedAt = conflictData.resolvedAt; this.resolutionData = conflictData.resolutionData; } /** * Resolve this merge conflict by providing answers to clarifying questions. * * @param answers - List of answers to the clarifying questions. * @throws {UserNotFoundError} If the user is not found. * @throws {MergeConflictNotFoundError} If the merge conflict is not found. * @throws {MergeConflictAlreadyResolvedError} If the conflict is already resolved. * @throws {MergeConflictInvalidQuestionsError} If the provided questions don't match the original questions. * @throws {MergeConflictMissingAnswersError} If not all required questions have been answered. * @throws {MergeConflictInvalidAnswerError} If an answer is not a valid option for its question. * @throws {ValidationError} If the answers are invalid. * @throws {AuthenticationError} If the API key or project ID is invalid. * @throws {InternalServerError} If the server encounters an error. * @throws {NetworkError} If there are network issues. * @throws {TimeoutError} If the request times out. * @throws {RecallrAIError} For other API-related errors. */ async resolve(answers) { if (this.status === models_1.MergeConflictStatus.RESOLVED || this.status === models_1.MergeConflictStatus.FAILED) { throw new errors_1.MergeConflictAlreadyResolvedError(`Merge conflict ${this.conflictId} is already resolved`, 400); } const answerData = { answers: { question_answers: answers.map((answer) => ({ question: answer.question, answer: answer.answer, message: answer.message, })), }, }; const response = await this.http.post(`/api/v1/users/${this.userId}/merge-conflicts/${this.conflictId}/resolve`, answerData); if (response.status === 404) { const detail = response.data?.detail || ""; if (detail.includes(`User ${this.userId} not found`)) { throw new errors_1.UserNotFoundError(detail, response.status); } else { throw new errors_1.MergeConflictNotFoundError(detail, response.status); } } else if (response.status === 400) { const detail = response.data?.detail || ""; if (detail.includes("already resolved")) { throw new errors_1.MergeConflictAlreadyResolvedError(detail, response.status); } else if (detail.includes("Invalid questions provided")) { throw new errors_1.MergeConflictInvalidQuestionsError(detail, response.status); } else if (detail.includes("Missing answers for the following questions")) { throw new errors_1.MergeConflictMissingAnswersError(detail, response.status); } else if (detail.includes("Invalid answer") && detail.includes("for question")) { throw new errors_1.MergeConflictInvalidAnswerError(detail, response.status); } else { throw new errors_1.RecallrAIError(detail, response.status); } } else if (response.status !== 200) { throw new errors_1.RecallrAIError(response.data?.detail || "Unknown error", response.status); } const updatedData = this.parseMergeConflictResponse(response.data); this.conflictData = updatedData; this.status = updatedData.status; this.resolvedAt = updatedData.resolvedAt; this.resolutionData = updatedData.resolutionData; } /** * Refresh this merge conflict's data from the API. * * @throws {UserNotFoundError} If the user is not found. * @throws {MergeConflictNotFoundError} If the merge conflict is not found. * @throws {AuthenticationError} If the API key or project ID is invalid. * @throws {InternalServerError} If the server encounters an error. * @throws {NetworkError} If there are network issues. * @throws {TimeoutError} If the request times out. * @throws {RecallrAIError} For other API-related errors. */ async refresh() { const response = await this.http.get(`/api/v1/users/${this.userId}/merge-conflicts/${this.conflictId}`); if (response.status === 404) { const detail = response.data?.detail || ""; if (detail.includes(`User ${this.userId} not found`)) { throw new errors_1.UserNotFoundError(detail, response.status); } else { throw new errors_1.MergeConflictNotFoundError(detail, response.status); } } else if (response.status !== 200) { throw new errors_1.RecallrAIError(response.data?.detail || "Unknown error", response.status); } const updatedData = this.parseMergeConflictResponse(response.data); this.conflictData = updatedData; this.status = updatedData.status; this.resolvedAt = updatedData.resolvedAt; this.resolutionData = updatedData.resolutionData; } parseMergeConflictResponse(data) { const conflictData = data.conflict || data; return { id: conflictData.id, projectUserSessionId: conflictData.project_user_session_id, proposedMemoryContent: conflictData.proposed_memory_content, newMemories: conflictData.new_memories?.map((mem) => ({ memoryId: mem.memory_id, content: mem.content, eventDateStart: new Date(mem.event_date_start), eventDateEnd: new Date(mem.event_date_end), createdAt: new Date(mem.created_at), })), conflictingMemories: conflictData.conflicting_memories.map((mem) => ({ memoryId: mem.memory_id, content: mem.content, reason: mem.reason, eventDateStart: new Date(mem.event_date_start), eventDateEnd: new Date(mem.event_date_end), createdAt: new Date(mem.created_at), })), clarifyingQuestions: conflictData.clarifying_questions.map((q) => ({ question: q.question, options: q.options, })), status: conflictData.status, resolutionData: conflictData.resolution_data, createdAt: new Date(conflictData.created_at), resolvedAt: conflictData.resolved_at ? new Date(conflictData.resolved_at) : undefined, }; } toString() { return `MergeConflict(id='${this.conflictId}', status='${this.status}', user_id='${this.userId}')`; } } exports.MergeConflict = MergeConflict;