@future-agi/sdk
Version:
We help GenAI teams maintain high-accuracy for their Models in production.
478 lines • 21.1 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.KnowledgeBase = void 0;
const auth_1 = require("../api/auth");
const types_1 = require("../api/types");
const routes_1 = require("../utils/routes");
const types_2 = require("./types");
const errors_1 = require("../utils/errors");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
/**
* Response handler for Knowledge Base operations
*/
class KBResponseHandler extends auth_1.ResponseHandler {
/**
* Parse successful knowledge base response
*/
static _parseSuccess(response) {
var _a;
const data = response.data;
const method = (_a = response.config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase();
const url = response.config.url || '';
// Treat backend payloads with { status: false } as errors
if ((data === null || data === void 0 ? void 0 : data.status) === false) {
const msg = data.result || data.detail || 'Knowledge Base operation failed';
throw new errors_1.SDKException(msg);
}
if (method === types_1.HttpMethod.POST && url.includes(routes_1.Routes.knowledge_base)) {
return data.result;
}
if (method === types_1.HttpMethod.PATCH && url.includes(routes_1.Routes.knowledge_base)) {
return data.result;
}
if (method === types_1.HttpMethod.DELETE) {
return data;
}
return data;
}
/**
* Handle knowledge base operation errors
*/
static _handleError(response) {
if (response.status === 403) {
throw new errors_1.InvalidAuthError();
}
const extractMsg = () => {
var _a, _b, _c;
return (((_a = response.data) === null || _a === void 0 ? void 0 : _a.result) ||
((_b = response.data) === null || _b === void 0 ? void 0 : _b.detail) ||
((_c = response.data) === null || _c === void 0 ? void 0 : _c.message) ||
response.statusText);
};
if (response.status === 429) {
throw new errors_1.SDKException(extractMsg() || 'Rate limit exceeded.');
}
if (response.status >= 400 && response.status < 500) {
throw new errors_1.SDKException(extractMsg() || `Client error ${response.status}`);
}
if (response.status >= 500) {
throw new errors_1.SDKException(extractMsg() || 'Server encountered an error.');
}
// Fallback: throw generic error
throw new errors_1.SDKException('Knowledge base operation failed.');
}
}
/**
* Knowledge Base client for managing knowledge bases and file operations
*/
class KnowledgeBase extends auth_1.APIKeyAuth {
constructor(kbName, options = {}) {
super({
fiApiKey: options.fiApiKey,
fiSecretKey: options.fiSecretKey,
fiBaseUrl: options.fiBaseUrl,
timeout: options.timeout
});
this._validFilePaths = [];
this.kb = undefined;
if (kbName) {
// Resolve name → id at construction time
this._getKbFromName(kbName)
.then(foundKb => {
this.kb = foundKb;
})
.catch(() => {
throw new errors_1.SDKException(`Knowledge Base with name '${kbName}' not found. Please create it first.`);
});
}
}
/**
* Update name of Knowledge Base and/or add files to it
*/
updateKb(_a) {
return __awaiter(this, arguments, void 0, function* ({ kbName, newName, filePaths }) {
try {
// Resolve target KB by name if needed
if (!this.kb || this.kb.name !== kbName) {
this.kb = yield this._getKbFromName(kbName);
}
if (filePaths) {
try {
yield this._checkFilePaths(filePaths);
}
catch (error) {
if (error instanceof errors_1.FileNotFoundException || error instanceof errors_1.UnsupportedFileType) {
throw new errors_1.SDKException("Knowledge Base update failed due to a file processing issue.", error);
}
else if (error instanceof errors_1.SDKException) {
throw new errors_1.SDKException("Knowledge Base update failed due to invalid file path arguments.", error);
}
else {
throw new errors_1.SDKException("An unexpected error occurred during file path validation for update.", error);
}
}
}
const url = `${this.baseUrl}/${routes_1.Routes.knowledge_base}`;
// Prepare form fields
const bodyFields = {
name: newName !== null && newName !== void 0 ? newName : this.kb.name,
kb_id: this.kb.id
};
// Prepare files map for multipart upload (key uniqueness: file0, file1, ...)
const files = {};
this._validFilePaths.forEach((filePath, idx) => {
const fileName = path.basename(filePath);
const fileExt = path.extname(filePath).slice(1).toLowerCase();
// Validate supported types again (defensive)
if (!types_2.SUPPORTED_FILE_TYPES.includes(fileExt)) {
throw new errors_1.UnsupportedFileType(fileExt, fileName);
}
files[`file${idx}`] = fs.createReadStream(filePath);
});
const response = yield this.request({
method: types_1.HttpMethod.PATCH,
url,
data: bodyFields,
files,
timeout: 300000 // 5-min timeout similar to Python
}, KBResponseHandler);
// Check if server reported any files that failed to upload
if (response.notUploaded && response.notUploaded.length > 0) {
throw new errors_1.SDKException(`Server reported that some files were not uploaded successfully: ${response.notUploaded.join(', ')}`);
}
if (response && this.kb) {
if (response.id)
this.kb.id = response.id;
if (response.name)
this.kb.name = response.name;
if (response.files)
this.kb.files = response.files;
}
return this;
}
catch (error) {
if (error instanceof errors_1.SDKException) {
throw error;
}
throw new errors_1.SDKException("Failed to update the Knowledge Base due to an unexpected error.", error);
}
});
}
/**
* Delete files from the Knowledge Base
*/
deleteFilesFromKb(_a) {
return __awaiter(this, arguments, void 0, function* ({ kbName, fileNames }) {
try {
if (!this.kb || this.kb.name !== kbName) {
this.kb = yield this._getKbFromName(kbName);
}
if (!fileNames || fileNames.length === 0) {
throw new errors_1.SDKException("Files to be deleted not found or list is empty. Please provide correct File Names.");
}
const url = `${this.baseUrl}/${routes_1.Routes.knowledge_base_files}`;
const data = {
file_names: fileNames,
kb_id: this.kb.id
};
yield this.request({
method: types_1.HttpMethod.DELETE,
url,
json: data,
headers: { 'Content-Type': 'application/json' }
}, KBResponseHandler);
return this;
}
catch (error) {
if (error instanceof errors_1.SDKException) {
throw error;
}
throw new errors_1.SDKException("Failed to delete files from the Knowledge Base due to an unexpected error.", error);
}
});
}
/**
* Delete a Knowledge Base
*/
deleteKb() {
return __awaiter(this, arguments, void 0, function* ({ kbNames, kbIds } = {}) {
var _a;
try {
const resolvedIds = [];
// Resolve names first
if (kbNames) {
const namesArr = Array.isArray(kbNames) ? kbNames : [kbNames];
for (const n of namesArr) {
try {
const conf = yield this._getKbFromName(n);
resolvedIds.push(String(conf.id));
}
catch (_b) {
// ignore names that weren't found
}
}
if (resolvedIds.length === 0) {
throw new errors_1.SDKException('None of the provided Knowledge Base names could be resolved.');
}
}
// Legacy ids param
if (kbIds) {
if (typeof kbIds === 'string') {
resolvedIds.push(kbIds);
}
else if (Array.isArray(kbIds)) {
resolvedIds.push(...kbIds.map(id => String(id)));
}
else {
throw new errors_1.SDKException('kb_ids must be a string or a list of strings.');
}
}
// Fallback to cached KB
if (resolvedIds.length === 0 && ((_a = this.kb) === null || _a === void 0 ? void 0 : _a.id)) {
resolvedIds.push(this.kb.id);
}
if (resolvedIds.length === 0) {
throw new errors_1.SDKException('No Knowledge Base specified for deletion.');
}
const url = `${this.baseUrl}/${routes_1.Routes.knowledge_base}`;
const jsonPayload = { kb_ids: resolvedIds };
yield this.request({
method: types_1.HttpMethod.DELETE,
url,
json: jsonPayload,
headers: { 'Content-Type': 'application/json' }
}, KBResponseHandler);
// Clear current KB if it was deleted
if (this.kb && this.kb.id && resolvedIds.includes(this.kb.id)) {
this.kb = undefined;
}
return this;
}
catch (error) {
if (error instanceof errors_1.SDKException) {
throw error;
}
throw new errors_1.SDKException("Failed to delete Knowledge Base(s) due to an unexpected error.", error);
}
});
}
/**
* Create a Knowledge Base
*/
createKb(name_1) {
return __awaiter(this, arguments, void 0, function* (name, filePaths = []) {
var _a;
try {
const finalKbName = name || ((_a = this.kb) === null || _a === void 0 ? void 0 : _a.name) || "Unnamed KB";
const url = `${this.baseUrl}/${routes_1.Routes.knowledge_base}`;
// Prepare fields
const bodyFields = { name: finalKbName };
// Handle optional files
const files = {};
if (filePaths) {
yield this._checkFilePaths(filePaths);
this._validFilePaths.forEach((filePath, idx) => {
const fileName = path.basename(filePath);
const fileExt = path.extname(filePath).slice(1).toLowerCase();
if (!types_2.SUPPORTED_FILE_TYPES.includes(fileExt)) {
throw new errors_1.UnsupportedFileType(fileExt, fileName);
}
files[`file${idx}`] = fs.createReadStream(filePath);
});
}
const response = yield this.request({
method: types_1.HttpMethod.POST,
url,
data: bodyFields,
files: Object.keys(files).length > 0 ? files : undefined,
timeout: 300000
}, KBResponseHandler);
// Check if server reported any files that failed to upload during creation
if (response.notUploaded && response.notUploaded.length > 0) {
throw new errors_1.SDKException(`Server reported that some files were not uploaded during Knowledge Base creation: ${response.notUploaded.join(', ')}`);
}
this.kb = {
id: response.kbId,
name: response.kbName,
files: response.fileIds || []
};
return this;
}
catch (error) {
if (error instanceof errors_1.SDKException) {
throw error;
}
throw new errors_1.SDKException("Failed to create the Knowledge Base due to an unexpected error.", error);
}
});
}
/**
* List all knowledge bases
*/
listKbs(search) {
return __awaiter(this, void 0, void 0, function* () {
try {
const params = search ? { search } : {};
const response = yield this.request({
method: types_1.HttpMethod.GET,
url: `${this.baseUrl}/${routes_1.Routes.knowledge_base_list}`,
params
}, KBResponseHandler);
return response.result.tableData.map(item => ({
id: item.id,
name: item.name,
status: item.status,
files: item.files
}));
}
catch (error) {
if (error instanceof errors_1.SDKException) {
throw error;
}
throw new errors_1.SDKException("Failed to list Knowledge Bases due to an unexpected error.", error);
}
});
}
/**
* Get knowledge base by name
*/
_getKbFromName(kbName) {
return __awaiter(this, void 0, void 0, function* () {
const response = yield this.request({
method: types_1.HttpMethod.GET,
url: `${this.baseUrl}/${routes_1.Routes.knowledge_base_list}`,
params: { search: kbName }
}, KBResponseHandler);
const data = response.result.tableData;
if (!data || data.length === 0) {
throw new errors_1.SDKException(`Knowledge Base with name '${kbName}' not found.`);
}
return {
id: data[0].id,
name: data[0].name,
status: data[0].status,
files: data[0].files
};
});
}
/**
* Validate file paths
*/
_checkFilePaths(filePaths) {
return __awaiter(this, void 0, void 0, function* () {
this._validFilePaths = [];
if (typeof filePaths === 'string') {
try {
const stats = yield fs.promises.stat(filePaths);
if (stats.isDirectory()) {
const files = yield fs.promises.readdir(filePaths);
const allFiles = [];
for (const file of files) {
const fullPath = path.join(filePaths, file);
const fileStats = yield fs.promises.stat(fullPath);
if (fileStats.isFile()) {
allFiles.push(fullPath);
}
}
if (allFiles.length === 0) {
throw new errors_1.FileNotFoundException(filePaths, `The directory '${filePaths}' is empty or contains no files.`);
}
this._validFilePaths = allFiles;
return true;
}
else if (stats.isFile()) {
this._validFilePaths = [filePaths];
return true;
}
else {
throw new errors_1.FileNotFoundException(filePaths, `The provided path '${filePaths}' is not a valid file or directory.`);
}
}
catch (error) {
if (error instanceof errors_1.FileNotFoundException) {
throw error;
}
throw new errors_1.FileNotFoundException(filePaths, `The provided path '${filePaths}' does not exist or is not accessible.`);
}
}
else if (Array.isArray(filePaths)) {
if (filePaths.length === 0) {
throw new errors_1.FileNotFoundException(filePaths, "The provided list of file paths is empty.");
}
const validPaths = [];
const missingFiles = [];
for (const filePath of filePaths) {
try {
const stats = yield fs.promises.stat(filePath);
if (stats.isFile()) {
validPaths.push(filePath);
}
else {
missingFiles.push(filePath);
}
}
catch (_a) {
missingFiles.push(filePath);
}
}
if (missingFiles.length > 0) {
throw new errors_1.FileNotFoundException(missingFiles, `Some file paths are invalid, not files, or do not exist: ${missingFiles.join(', ')}`);
}
if (validPaths.length === 0) {
throw new errors_1.FileNotFoundException(filePaths, "No valid files found in the provided list.");
}
this._validFilePaths = validPaths;
return true;
}
else {
throw new errors_1.SDKException(`Unsupported type for file_paths: ${typeof filePaths}. Expected string or array.`);
}
});
}
}
exports.KnowledgeBase = KnowledgeBase;
exports.default = KnowledgeBase;
//# sourceMappingURL=client.js.map