@dev-fastn-ai/ucl-sdk
Version:
Fastn UCL SDK - A robust TypeScript SDK for integrating AI agents with Fastn UCL
189 lines • 7.91 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UCLCore = void 0;
require("dotenv/config");
const api_client_1 = require("../services/api-client");
const analyzer_1 = require("./analyzer");
const errors_1 = require("../utils/errors");
const embedding_service_1 = require("../services/embedding-service");
const llm_service_1 = require("../services/llm-service");
const prompt_builder_1 = require("../services/prompt-builder");
const misc_1 = require("../utils/misc");
class UCLCore {
constructor(config) {
this.tools = [];
this.connectors = [];
this.initialized = false;
this.llmService = null;
this.validateConfig(config);
this.config = config;
this.apiClient = new api_client_1.FastnAPIClient(config);
this.toolAnalyzer = new analyzer_1.Analyzer([], [], new embedding_service_1.EmbeddingService({
provider: 'openai',
openaiApiKey: process.env['OPENAI_API_KEY'] || ''
}));
if (config.llmConfig) {
this.llmService = new llm_service_1.LLMService(config.llmConfig);
}
}
validateConfig(config) {
if (!config.authToken) {
throw new errors_1.ConfigurationError('authToken is required');
}
if (!config.spaceId) {
throw new errors_1.ConfigurationError('spaceId is required');
}
}
async initialize() {
try {
const [toolsResponse, connectorsResponse] = await Promise.all([
this.apiClient.getTools(),
this.apiClient.getConnectors()
]);
if (!toolsResponse.success) {
throw new errors_1.ConfigurationError(`Failed to fetch tools: ${toolsResponse.error}`);
}
if (!connectorsResponse.success) {
throw new errors_1.ConfigurationError(`Failed to fetch connectors: ${connectorsResponse.error}`);
}
this.tools = toolsResponse.data;
this.connectors = connectorsResponse.data;
console.log("Embedding tools and connectors");
await this.toolAnalyzer.updateTools(this.tools);
await this.toolAnalyzer.updateConnectors(this.connectors);
this.initialized = true;
}
catch (error) {
console.error("error", error);
throw new errors_1.ConfigurationError(`Initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async processMessage(message, _options = {
tenantId: '',
autoExecute: false
}) {
if (!this.initialized) {
throw new errors_1.ConfigurationError('Agent not initialized. Call initialize() first.');
}
try {
let analysis;
if (_options.tenantId && !this.toolAnalyzer.doesTenantConnectorsExist(_options.tenantId)) {
const tenantConnectors = await this.apiClient.getConnectors(_options.tenantId);
this.toolAnalyzer.updateTenantConnectors(_options.tenantId, tenantConnectors.data);
}
analysis = await this.toolAnalyzer.analyzeMessage(message, _options.tenantId);
// if analysis find a tool and connector is active
if (analysis.requiresTool && !analysis.requiresConnection && analysis.tool) {
analysis.llmPrompt = prompt_builder_1.PromptBuilder.buildGenerateParametersPrompt(message, analysis.tool);
}
if (!_options.autoExecute) {
return {
success: true,
analysis
};
}
if (!this.llmService) {
throw new errors_1.ConfigurationError('LLM service not initialized. Please provide a valid llmConfig in the config.');
}
// if analysis find a tool and connector is not active
if (analysis.requiresTool && analysis.requiresConnection && analysis.tool) {
return {
success: true,
analysis
};
}
// if analysis find a tool and connector is active too
if (analysis.requiresTool && !analysis.requiresConnection && analysis.tool) {
const response = await this.llmService.invoke(analysis.llmPrompt);
const { parameters = {}, missingParameters = [] } = (0, misc_1.safeParse)(response);
if (missingParameters.length > 0) {
return {
success: false,
analysis: {
requiresTool: true,
requiresConnection: false,
tool: analysis.tool,
message: `Please provide the following parameters to continue: ${missingParameters.join(', ')}`
}
};
}
analysis.parameters = parameters;
const toolExecutionResponse = await this.executeTool(analysis);
analysis.executeToolResponse = toolExecutionResponse;
analysis.llmPrompt = prompt_builder_1.PromptBuilder.prettifyExecuteToolResponse(message, toolExecutionResponse, analysis.tool, analysis.connector);
const llmResponse = await this.llmService.invoke(analysis.llmPrompt);
return {
success: true,
analysis: {
...analysis,
executeToolMessage: llmResponse
}
};
}
return {
success: true,
analysis
};
}
catch (error) {
return {
success: false,
analysis: {
requiresTool: false,
requiresConnection: false,
message: error instanceof Error ? error.message : 'Unknown error'
}
};
}
}
async executeTool(analysis) {
if (!analysis.tool) {
throw new errors_1.ToolNotFoundError('No tool specified for execution');
}
if (!analysis.parameters) {
throw new errors_1.MissingParametersError(['parameters']);
}
const response = await this.apiClient.executeTool({
actionId: analysis.tool.actionId,
parameters: analysis.parameters
});
if (!response.success) {
throw new Error(`Tool execution failed: ${response.error}`);
}
return response.data;
}
async refreshTools(refreshCache = false) {
const response = await this.apiClient.getTools();
if (!response.success) {
throw new Error(`Failed to refresh tools: ${response.error}`);
}
this.tools = response.data;
await this.toolAnalyzer.updateTools(this.tools, refreshCache);
}
async refreshConnectors(refreshCache = false) {
const response = await this.apiClient.getConnectors();
if (!response.success) {
throw new Error(`Failed to refresh connectors: ${response.error}`);
}
this.connectors = response.data;
await this.toolAnalyzer.updateConnectors(this.connectors, refreshCache);
}
async refreshEmbeddings(refreshCache = true) {
await this.toolAnalyzer.updateTools(this.tools, refreshCache);
await this.toolAnalyzer.updateConnectors(this.connectors, refreshCache);
}
getAvailableTools() {
return [...this.tools];
}
getAvailableConnectors() {
return [...this.connectors];
}
isInitialized() {
return this.initialized;
}
getConfig() {
return { ...this.config };
}
}
exports.UCLCore = UCLCore;
//# sourceMappingURL=ucl.js.map