UNPKG

skymel-adk-js-beta

Version:

Skymel Agent Development Kit using Javascript - A JavaScript SDK for creating and managing intelligent agents

187 lines (162 loc) 8.97 kB
import {CommonValidators} from "./common_validators.js"; import {SkymelECGraphNodeUtils} from "./skymel_ec_graph_node_utils.js"; import {SkymelECGraphNodeForDataProcessing} from "./skymel_ec_graph_node_for_data_processing.js"; import {RemoteApiCaller} from "./remote_api_caller.js"; import {SkymelECGraphUtils} from "./skymel_ec_graph_utils.js"; const addNodePrivateAttributesToFeedDict = function (feedDict, nodePrivateAttributeNamesToValuesMap) { if (CommonValidators.isEmpty(nodePrivateAttributeNamesToValuesMap) || !CommonValidators.isDict(nodePrivateAttributeNamesToValuesMap)) { return feedDict; } for (const keyName in nodePrivateAttributeNamesToValuesMap) { if (keyName in feedDict) { continue; } feedDict[keyName] = nodePrivateAttributeNamesToValuesMap[keyName]; } return feedDict; } const renameNodeInputNameToBackendInputName = function (feedDict, nodeInputNameToBackendInputNameMap) { if (CommonValidators.isEmpty(feedDict) || !CommonValidators.isDict(feedDict)) { return null; } if (CommonValidators.isEmpty(nodeInputNameToBackendInputNameMap) || !CommonValidators.isDict(nodeInputNameToBackendInputNameMap)) { return feedDict; } let outputDict = {}; for (const keyName in feedDict) { if (keyName in nodeInputNameToBackendInputNameMap) { outputDict[nodeInputNameToBackendInputNameMap[keyName]] = feedDict[keyName]; } else { outputDict[keyName] = feedDict[keyName]; } } return outputDict; } const renameBackendOutputNameToNodeOutputName = function (feedDict, backendOutputNameToNodeOutputNameMap) { return renameNodeInputNameToBackendInputName(feedDict, backendOutputNameToNodeOutputNameMap); } const updateNodePrivateAttributesFromExternalApiResponse = function (responseDict, nodeReference) { const nodePrivateAttributesAndValuesMap = nodeReference.getAllNodePrivateAttributesAndValuesMap(); if (CommonValidators.isEmpty(nodePrivateAttributesAndValuesMap) || !CommonValidators.isDict(nodePrivateAttributesAndValuesMap)) { return; } if (CommonValidators.isEmpty(responseDict) || !CommonValidators.isDict(responseDict)) { return; } for (const keyName in nodePrivateAttributesAndValuesMap) { if (keyName in responseDict) { console.log("Updating node private attribute '" + keyName + "' to value '" + responseDict[keyName] + "'"); nodeReference.setNodePrivateAttributeValue(keyName, responseDict[keyName]); } } } const callRemoteApiEndpoint = async function (graphReference, inputNodeResultsDict, nodeReference) { const nodeInputNames = nodeReference.getInputNames(); const keyNamesToDefaultValuesMap = nodeReference.getInputNamesToDefaultValueMap(); // Filter the node inputs to create the feedDict let feedDict = SkymelECGraphNodeUtils.getFilteredNameToValuesDict(inputNodeResultsDict, nodeInputNames, keyNamesToDefaultValuesMap, /*errorIfKeyNameIsMissing=*/true); console.log("Feed dict:", feedDict); let nodePrivateAttributes = nodeReference.getAllNodePrivateAttributesAndValuesMap(); // Now add all the node private attributes to the feed dict feedDict = addNodePrivateAttributesToFeedDict(feedDict, nodePrivateAttributes); let nodeInputNameToBackendInputNameMap = nodeReference.getNodeInputNameToBackendInputNameMap(); feedDict = renameNodeInputNameToBackendInputName(feedDict, nodeInputNameToBackendInputNameMap); const remoteApiCaller = nodeReference.getRemoteApiCaller(); let remoteApiCallResult = await remoteApiCaller.callExternalApiEndpointUrl(feedDict); if (CommonValidators.isEmpty(remoteApiCallResult)) { return null; } console.log("Remote API call result:", remoteApiCallResult); let remoteApiCallResultAsDict = SkymelECGraphNodeUtils.convertInferenceResponseProtoToDict(remoteApiCallResult, true); console.log("Remote API call result as dict:", remoteApiCallResultAsDict); let backendOutputNameToNodeOutputNameMap = nodeReference.getBackendOutputNameToNodeOutputNameMap(); remoteApiCallResultAsDict = renameBackendOutputNameToNodeOutputName(remoteApiCallResultAsDict, backendOutputNameToNodeOutputNameMap); if (!CommonValidators.isEmpty(remoteApiCallResultAsDict)) { updateNodePrivateAttributesFromExternalApiResponse(remoteApiCallResultAsDict, nodeReference); } console.log("Remote API call result as dict after renaming:", remoteApiCallResultAsDict); return remoteApiCallResultAsDict; } export class SkymelECGraphNodeForExternalApiCall extends SkymelECGraphNodeForDataProcessing { static isValidInitializationOptions(initializationOptions) { if (CommonValidators.isEmpty(initializationOptions) || !CommonValidators.isDict(initializationOptions)) { return false; } if (!('apiKey' in initializationOptions)) { return false; } return 'endpointUrl' in initializationOptions; } constructor(initializationOptions) { if (!SkymelECGraphNodeForExternalApiCall.isValidInitializationOptions(initializationOptions)) { throw new Error( "Invalid initialization options for SkymelECGraphNodeForExternalApiCall. " + "Expected initializationOptions to be a dict with keys 'endpointUrl', 'apiKey'." + "Got initializationOptions = " + JSON.stringify(initializationOptions) ); } initializationOptions['nodeSubroutine'] = callRemoteApiEndpoint; super(initializationOptions); this.apiKey = CommonValidators.getKeyValueFromDictIfKeyAbsentReturnDefault(initializationOptions, "apiKey", 'TESTER_API_KEY'); this.endpointUrl = CommonValidators.getKeyValueFromDictIfKeyAbsentReturnDefault(initializationOptions, "endpointUrl", null); this.nodePrivateAttributesAndValues = CommonValidators.getKeyValueFromDictIfKeyAbsentReturnDefault(initializationOptions, "nodePrivateAttributesAndValues", {}); this.nodeInputNameToBackendInputNameMap = CommonValidators.getKeyValueFromDictIfKeyAbsentReturnDefault(initializationOptions, "nodeInputNameToBackendInputNameMap", {}); this.backendOutputNameToNodeOutputNameMap = CommonValidators.getKeyValueFromDictIfKeyAbsentReturnDefault(initializationOptions, "backendOutputNameToNodeOutputNameMap", {}); this.isEndpointWebSocketUrl = CommonValidators.getKeyValueFromDictIfKeyAbsentReturnDefault(initializationOptions, "isEndpointWebSocketUrl", false); this.remoteApiCaller = null; } getNodeInputNameToBackendInputNameMap() { return this.nodeInputNameToBackendInputNameMap; } getBackendOutputNameToNodeOutputNameMap() { return this.backendOutputNameToNodeOutputNameMap; } getRemoteApiCallEndpointUrl() { return this.endpointUrl; } getNodeType() { return SkymelECGraphUtils.NODE_TYPE_EXTERNAL_API_CALLER; } getAllNodePrivateAttributesAndValuesMap() { return this.nodePrivateAttributesAndValues; } setAllNodePrivateAttributesAndValuesMap(nodePrivateAttributesAndValuesMap) { if (CommonValidators.isEmpty(nodePrivateAttributesAndValuesMap)) { return; } this.nodePrivateAttributesAndValues = nodePrivateAttributesAndValuesMap; } getNodePrivateAttributeValue(attributeName) { return CommonValidators.isNotEmptyDictAndHasKey(this.nodePrivateAttributesAndValues, attributeName, null); } setNodePrivateAttributeValue(attributeName, attributeValue) { this.nodePrivateAttributesAndValues[attributeName] = attributeValue; } removeNodePrivateAttributeByName(attributeName) { if (CommonValidators.isNotEmptyDictAndHasKey(this.nodePrivateAttributesAndValues, attributeName)) { delete this.nodePrivateAttributesAndValues[attributeName]; return true; } return false; } getRemoteApiCaller() { if (CommonValidators.isEmpty(this.remoteApiCaller)) { this.remoteApiCaller = new RemoteApiCaller({ endpointUrl: this.endpointUrl, isEndpointWebSocketUrl: this.isEndpointWebSocketUrl, apiKey: this.apiKey, }); } else if (this.remoteApiCaller instanceof RemoteApiCaller) { if (this.remoteApiCaller.getApiKey() !== this.apiKey) { this.remoteApiCaller.setApiKey(this.apiKey); } if (this.remoteApiCaller.getEndpointUrl() !== this.endpointUrl) { this.remoteApiCaller.setEndpointUrl(this.endpointUrl); } if (this.remoteApiCaller.getIsEndpointWebSocketUrl() !== this.isEndpointWebSocketUrl) { this.remoteApiCaller.setIsEndpointWebSocketUrl(this.isEndpointWebSocketUrl); } } return this.remoteApiCaller; } }